Loading packages/SystemUI/res/values/strings.xml +3 −1 Original line number Diff line number Diff line Loading @@ -1987,8 +1987,10 @@ <!-- SysUI Tuner: App subheading for shortcut selection [CHAR LIMIT=60] --> <string name="tuner_app"><xliff:g id="app">%1$s</xliff:g> app</string> <!-- Title for the notification channel containing important alerts like low battery. [CHAR LIMIT=NONE] --> <!-- Title for the notification channel containing important alerts. [CHAR LIMIT=NONE] --> <string name="notification_channel_alerts">Alerts</string> <!-- Title for the notification channel for battery warnings (i.e. < 15%). [CHAR LIMIT=NONE] --> <string name="notification_channel_battery">Battery</string> <!-- Title for the notification channel dedicated to screenshot progress. [CHAR LIMIT=NONE] --> <string name="notification_channel_screenshot">Screenshots</string> <!-- Title for the notification channel for miscellaneous notices. [CHAR LIMIT=NONE] --> Loading packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +7 −37 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.power; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; Loading @@ -40,6 +41,7 @@ import android.support.annotation.VisibleForTesting; import android.util.Slog; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.SystemUI; Loading Loading @@ -173,8 +175,9 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { private void showWarningNotification() { final int textRes = R.string.battery_low_percent_format; final String percentage = NumberFormat.getPercentInstance().format((double) mBatteryLevel / 100.0); final Notification.Builder nb = new Notification.Builder(mContext, NotificationChannels.ALERTS) new Notification.Builder(mContext, NotificationChannels.BATTERY) .setSmallIcon(R.drawable.ic_power_low) // Bump the notification when the bucket dropped. .setWhen(mBucketDroppedNegativeTimeMs) Loading @@ -191,10 +194,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { nb.addAction(0, mContext.getString(R.string.battery_saver_start_action), pendingBroadcast(ACTION_START_SAVER)); if (mPlaySound) { attachLowBatterySound(nb); nb.setOnlyAlertOnce(!mPlaySound); mPlaySound = false; } SystemUI.overrideNotificationAppName(mContext, nb); final Notification n = nb.build(); mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_BAD_CHARGER, UserHandle.ALL); Loading Loading @@ -341,37 +342,6 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { updateNotification(); } private void attachLowBatterySound(Notification.Builder b) { final ContentResolver cr = mContext.getContentResolver(); final int silenceAfter = Settings.Global.getInt(cr, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0); final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime; if (silenceAfter > 0 && mScreenOffTime > 0 && offTime > silenceAfter) { Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter + "ms): not waking up the user with low battery sound"); return; } if (DEBUG) { Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated } if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) { final String soundPath = Settings.Global.getString(cr, Settings.Global.LOW_BATTERY_SOUND); if (soundPath != null) { final Uri soundUri = Uri.parse("file://" + soundPath); if (soundUri != null) { b.setSound(soundUri, AUDIO_ATTRIBUTES); if (DEBUG) Slog.d(TAG, "playing sound " + soundUri); } } } } @Override public void dismissInvalidChargerWarning() { dismissInvalidChargerNotification(); Loading packages/SystemUI/src/com/android/systemui/power/PowerUI.java +1 −0 Original line number Diff line number Diff line Loading @@ -231,6 +231,7 @@ public class PowerUI extends SystemUI { && (bucket < oldBucket || oldPlugged) && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN && bucket < 0) { // only play SFX when the dialog comes up or the bucket changes final boolean playSound = bucket != oldBucket || oldPlugged; mWarnings.showLowBatteryWarning(playSound); Loading packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java +19 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ import android.app.NotificationManager; import android.content.Context; import android.content.pm.PackageManager; import android.media.AudioAttributes; import android.net.Uri; import android.provider.Settings; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.SystemUI; Loading @@ -31,11 +35,21 @@ public class NotificationChannels extends SystemUI { public static String GENERAL = "GEN"; public static String STORAGE = "DSK"; public static String TVPIP = "TPP"; public static String BATTERY = "BAT"; @VisibleForTesting static void createAll(Context context) { final NotificationManager nm = context.getSystemService(NotificationManager.class); NotificationChannel batteryChannel = new NotificationChannel(BATTERY, context.getString(R.string.notification_channel_battery), NotificationManager.IMPORTANCE_MAX); final String soundPath = Settings.Global.getString(context.getContentResolver(), Settings.Global.LOW_BATTERY_SOUND); batteryChannel.setSound(Uri.parse("file://" + soundPath), new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT) .build()); nm.createNotificationChannels(Arrays.asList( new NotificationChannel( ALERTS, Loading @@ -54,8 +68,10 @@ public class NotificationChannels extends SystemUI { context.getString(R.string.notification_channel_storage), isTv(context) ? NotificationManager.IMPORTANCE_DEFAULT : NotificationManager.IMPORTANCE_LOW) : NotificationManager.IMPORTANCE_LOW), batteryChannel )); if (isTv(context)) { // TV specific notification channel for TV PIP controls. // Importance should be {@link NotificationManager#IMPORTANCE_MAX} to have the highest Loading packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java +3 −12 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.NotificationChannels; import org.junit.Before; import org.junit.Test; Loading Loading @@ -108,23 +109,13 @@ public class PowerNotificationWarningsTest extends SysuiTestCase { } @Test public void testShowLowBatteryNotification_Silent() { mPowerNotificationWarnings.showLowBatteryWarning(false); ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); verify(mMockNotificationManager) .notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW), captor.capture(), any()); assertEquals(null, captor.getValue().sound); } @Test public void testShowLowBatteryNotification_Sound() { public void testShowLowBatteryNotification_BatteryChannel() { mPowerNotificationWarnings.showLowBatteryWarning(true); ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); verify(mMockNotificationManager) .notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW), captor.capture(), any()); assertNotEqual(null, captor.getValue().sound); assertTrue(captor.getValue().getChannelId() == NotificationChannels.BATTERY); } @Test Loading Loading
packages/SystemUI/res/values/strings.xml +3 −1 Original line number Diff line number Diff line Loading @@ -1987,8 +1987,10 @@ <!-- SysUI Tuner: App subheading for shortcut selection [CHAR LIMIT=60] --> <string name="tuner_app"><xliff:g id="app">%1$s</xliff:g> app</string> <!-- Title for the notification channel containing important alerts like low battery. [CHAR LIMIT=NONE] --> <!-- Title for the notification channel containing important alerts. [CHAR LIMIT=NONE] --> <string name="notification_channel_alerts">Alerts</string> <!-- Title for the notification channel for battery warnings (i.e. < 15%). [CHAR LIMIT=NONE] --> <string name="notification_channel_battery">Battery</string> <!-- Title for the notification channel dedicated to screenshot progress. [CHAR LIMIT=NONE] --> <string name="notification_channel_screenshot">Screenshots</string> <!-- Title for the notification channel for miscellaneous notices. [CHAR LIMIT=NONE] --> Loading
packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +7 −37 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.power; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; Loading @@ -40,6 +41,7 @@ import android.support.annotation.VisibleForTesting; import android.util.Slog; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.SystemUI; Loading Loading @@ -173,8 +175,9 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { private void showWarningNotification() { final int textRes = R.string.battery_low_percent_format; final String percentage = NumberFormat.getPercentInstance().format((double) mBatteryLevel / 100.0); final Notification.Builder nb = new Notification.Builder(mContext, NotificationChannels.ALERTS) new Notification.Builder(mContext, NotificationChannels.BATTERY) .setSmallIcon(R.drawable.ic_power_low) // Bump the notification when the bucket dropped. .setWhen(mBucketDroppedNegativeTimeMs) Loading @@ -191,10 +194,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { nb.addAction(0, mContext.getString(R.string.battery_saver_start_action), pendingBroadcast(ACTION_START_SAVER)); if (mPlaySound) { attachLowBatterySound(nb); nb.setOnlyAlertOnce(!mPlaySound); mPlaySound = false; } SystemUI.overrideNotificationAppName(mContext, nb); final Notification n = nb.build(); mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_BAD_CHARGER, UserHandle.ALL); Loading Loading @@ -341,37 +342,6 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { updateNotification(); } private void attachLowBatterySound(Notification.Builder b) { final ContentResolver cr = mContext.getContentResolver(); final int silenceAfter = Settings.Global.getInt(cr, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0); final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime; if (silenceAfter > 0 && mScreenOffTime > 0 && offTime > silenceAfter) { Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter + "ms): not waking up the user with low battery sound"); return; } if (DEBUG) { Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated } if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) { final String soundPath = Settings.Global.getString(cr, Settings.Global.LOW_BATTERY_SOUND); if (soundPath != null) { final Uri soundUri = Uri.parse("file://" + soundPath); if (soundUri != null) { b.setSound(soundUri, AUDIO_ATTRIBUTES); if (DEBUG) Slog.d(TAG, "playing sound " + soundUri); } } } } @Override public void dismissInvalidChargerWarning() { dismissInvalidChargerNotification(); Loading
packages/SystemUI/src/com/android/systemui/power/PowerUI.java +1 −0 Original line number Diff line number Diff line Loading @@ -231,6 +231,7 @@ public class PowerUI extends SystemUI { && (bucket < oldBucket || oldPlugged) && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN && bucket < 0) { // only play SFX when the dialog comes up or the bucket changes final boolean playSound = bucket != oldBucket || oldPlugged; mWarnings.showLowBatteryWarning(playSound); Loading
packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java +19 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ import android.app.NotificationManager; import android.content.Context; import android.content.pm.PackageManager; import android.media.AudioAttributes; import android.net.Uri; import android.provider.Settings; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.SystemUI; Loading @@ -31,11 +35,21 @@ public class NotificationChannels extends SystemUI { public static String GENERAL = "GEN"; public static String STORAGE = "DSK"; public static String TVPIP = "TPP"; public static String BATTERY = "BAT"; @VisibleForTesting static void createAll(Context context) { final NotificationManager nm = context.getSystemService(NotificationManager.class); NotificationChannel batteryChannel = new NotificationChannel(BATTERY, context.getString(R.string.notification_channel_battery), NotificationManager.IMPORTANCE_MAX); final String soundPath = Settings.Global.getString(context.getContentResolver(), Settings.Global.LOW_BATTERY_SOUND); batteryChannel.setSound(Uri.parse("file://" + soundPath), new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT) .build()); nm.createNotificationChannels(Arrays.asList( new NotificationChannel( ALERTS, Loading @@ -54,8 +68,10 @@ public class NotificationChannels extends SystemUI { context.getString(R.string.notification_channel_storage), isTv(context) ? NotificationManager.IMPORTANCE_DEFAULT : NotificationManager.IMPORTANCE_LOW) : NotificationManager.IMPORTANCE_LOW), batteryChannel )); if (isTv(context)) { // TV specific notification channel for TV PIP controls. // Importance should be {@link NotificationManager#IMPORTANCE_MAX} to have the highest Loading
packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java +3 −12 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.NotificationChannels; import org.junit.Before; import org.junit.Test; Loading Loading @@ -108,23 +109,13 @@ public class PowerNotificationWarningsTest extends SysuiTestCase { } @Test public void testShowLowBatteryNotification_Silent() { mPowerNotificationWarnings.showLowBatteryWarning(false); ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); verify(mMockNotificationManager) .notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW), captor.capture(), any()); assertEquals(null, captor.getValue().sound); } @Test public void testShowLowBatteryNotification_Sound() { public void testShowLowBatteryNotification_BatteryChannel() { mPowerNotificationWarnings.showLowBatteryWarning(true); ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); verify(mMockNotificationManager) .notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW), captor.capture(), any()); assertNotEqual(null, captor.getValue().sound); assertTrue(captor.getValue().getChannelId() == NotificationChannels.BATTERY); } @Test Loading