Low battery notification has unique sound.

Change-Id: I51c8e099da04d4bf1a55d081c9fce7fc8fb90bd1
Fixes: 63853037
Test: runtest systemui
This commit is contained in:
Beverly
2017-07-31 10:37:17 -04:00
parent d05ac9caf2
commit 334bc5fc77
6 changed files with 35 additions and 54 deletions

View File

@@ -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] -->

View File

@@ -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;
@@ -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;
@@ -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)
@@ -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);
mPlaySound = false;
}
nb.setOnlyAlertOnce(!mPlaySound);
mPlaySound = false;
SystemUI.overrideNotificationAppName(mContext, nb);
final Notification n = nb.build();
mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_BAD_CHARGER, UserHandle.ALL);
@@ -335,43 +336,12 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
public void showLowBatteryWarning(boolean playSound) {
Slog.i(TAG,
"show low battery warning: level=" + mBatteryLevel
+ " [" + mBucket + "] playSound=" + playSound);
+ " [" + mBucket + "] playSound=" + playSound);
mPlaySound = playSound;
mWarning = true;
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();

View File

@@ -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);

View File

@@ -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;
@@ -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,
@@ -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

View File

@@ -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;
@@ -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

View File

@@ -56,7 +56,8 @@ public class ChannelsTest extends SysuiTestCase {
NotificationChannels.ALERTS,
NotificationChannels.SCREENSHOTS,
NotificationChannels.STORAGE,
NotificationChannels.GENERAL
NotificationChannels.GENERAL,
NotificationChannels.BATTERY
));
NotificationChannels.createAll(mContext);
ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);