Merge "Notification Channels come to SystemUI's own notifications."

This commit is contained in:
TreeHugger Robot
2017-01-26 06:57:14 +00:00
committed by Android (Google) Code Review
10 changed files with 172 additions and 15 deletions

View File

@@ -51,6 +51,9 @@ public class PluginInstanceManager<T extends Plugin> {
private static final String TAG = "PluginInstanceManager";
private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
// must be one of the channels created in NotificationChannels.java
private static final String NOTIFICATION_CHANNEL_ID = "ALR";
private final Context mContext;
private final PluginListener<T> mListener;
private final String mAction;
@@ -312,7 +315,7 @@ public class PluginInstanceManager<T extends Plugin> {
.setSmallIcon(icon)
.setWhen(0)
.setShowWhen(false)
.setPriority(Notification.PRIORITY_MAX)
.setChannel(NOTIFICATION_CHANNEL_ID)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setColor(mContext.getColor(color));
String label = cls;

View File

@@ -1800,4 +1800,15 @@
<!-- SysUI Tuner: Switch to control if device gets unlocked [CHAR LIMIT=60] -->
<string name="lockscreen_unlock">Prompt for password</string>
<!-- Title for the notification channel containing important alerts like low battery. [CHAR LIMIT=NONE] -->
<string name="notification_channel_alerts">Alerts</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 urgent security issues. [CHAR LIMIT=NONE] -->
<string name="notification_channel_security">Security</string>
<!-- Title for the notification channel containing multi-user status information. [CHAR LIMIT=NONE] -->
<string name="notification_channel_user_status">User status</string>
<!-- Title for the notification channel for problems with storage (i.e. low disk). [CHAR LIMIT=NONE] -->
<string name="notification_channel_storage">Storage</string>
</resources>

View File

@@ -46,6 +46,7 @@ import com.android.systemui.statusbar.SystemBars;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.usb.StorageNotification;
import com.android.systemui.util.NotificationChannels;
import com.android.systemui.volume.VolumeUI;
import java.util.HashMap;
@@ -66,6 +67,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
Dependency.class,
FragmentService.class,
TunerService.class,
NotificationChannels.class,
CommandQueue.CommandQueueStart.class,
KeyguardViewMediator.class,
Recents.class,

View File

@@ -43,6 +43,7 @@ import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.util.NotificationChannels;
import java.io.PrintWriter;
import java.text.NumberFormat;
@@ -151,8 +152,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
.setOngoing(true)
.setContentTitle(mContext.getString(R.string.invalid_charger_title))
.setContentText(mContext.getString(R.string.invalid_charger_text))
.setPriority(Notification.PRIORITY_MAX)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setChannel(NotificationChannels.ALERTS)
.setColor(mContext.getColor(
com.android.internal.R.color.system_notification_accent_color));
SystemUI.overrideNotificationAppName(mContext, nb);
@@ -173,7 +173,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
.setContentText(mContext.getString(textRes, percentage))
.setOnlyAlertOnce(true)
.setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
.setPriority(Notification.PRIORITY_MAX)
.setChannel(NotificationChannels.ALERTS)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setColor(mContext.getColor(
com.android.internal.R.color.battery_saver_mode_color));
@@ -241,7 +241,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
.setShowWhen(false)
.setContentTitle(mContext.getString(R.string.high_temp_title))
.setContentText(mContext.getString(R.string.high_temp_notif_message))
.setPriority(Notification.PRIORITY_HIGH)
.setChannel(NotificationChannels.ALERTS)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setContentIntent(pendingBroadcast(ACTION_CLICKED_TEMP_WARNING))
.setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_TEMP_WARNING))

View File

@@ -62,6 +62,7 @@ import android.widget.ImageView;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.util.NotificationChannels;
import java.io.File;
import java.io.FileOutputStream;
@@ -178,6 +179,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
// The public notification will show similar info but with the actual screenshot omitted
mPublicNotificationBuilder = new Notification.Builder(context)
.setChannel(NotificationChannels.SCREENSHOTS)
.setContentTitle(r.getString(R.string.screenshot_saving_title))
.setContentText(r.getString(R.string.screenshot_saving_text))
.setSmallIcon(R.drawable.stat_notify_image)
@@ -189,6 +191,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
SystemUI.overrideNotificationAppName(context, mPublicNotificationBuilder);
mNotificationBuilder = new Notification.Builder(context)
.setChannel(NotificationChannels.SCREENSHOTS)
.setTicker(r.getString(R.string.screenshot_saving_ticker)
+ (mTickerAddSpace ? " " : ""))
.setContentTitle(r.getString(R.string.screenshot_saving_title))
@@ -332,6 +335,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
// Update the text and the icon for the existing notification
mPublicNotificationBuilder
.setChannel(NotificationChannels.SCREENSHOTS)
.setContentTitle(r.getString(R.string.screenshot_saved_title))
.setContentText(r.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0))
@@ -340,6 +344,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
.setColor(context.getColor(
com.android.internal.R.color.system_notification_accent_color));
mNotificationBuilder
.setChannel(NotificationChannels.SCREENSHOTS)
.setContentTitle(r.getString(R.string.screenshot_saved_title))
.setContentText(r.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0))

View File

@@ -117,6 +117,7 @@ import com.android.systemui.statusbar.policy.PreviewInflater;
import com.android.systemui.statusbar.policy.RemoteInputView;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.util.NotificationChannels;
import java.util.ArrayList;
import java.util.Collections;
@@ -882,7 +883,7 @@ public abstract class BaseStatusBar extends SystemUI implements
.setSmallIcon(R.drawable.ic_android)
.setContentTitle(mContext.getString(R.string.hidden_notifications_title))
.setContentText(mContext.getString(R.string.hidden_notifications_text))
.setPriority(Notification.PRIORITY_HIGH)
.setChannel(NotificationChannels.SECURITY)
.setOngoing(true)
.setColor(mContext.getColor(colorRes))
.setContentIntent(setupIntent)

View File

@@ -61,6 +61,7 @@ import com.android.systemui.plugins.qs.QS.DetailAdapter;
import com.android.systemui.qs.tiles.UserDetailView;
import com.android.systemui.ActivityStarter;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.util.NotificationChannels;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -561,7 +562,7 @@ public class UserSwitcherController {
0, new Intent(ACTION_LOGOUT_USER), 0, UserHandle.SYSTEM);
Notification.Builder builder = new Notification.Builder(mContext)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(Notification.PRIORITY_MIN)
.setChannel(NotificationChannels.USER)
.setSmallIcon(R.drawable.ic_person)
.setContentTitle(mContext.getString(R.string.user_logout_notification_title))
.setContentText(mContext.getString(R.string.user_logout_notification_text))
@@ -585,7 +586,7 @@ public class UserSwitcherController {
Notification.Builder builder = new Notification.Builder(mContext)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(Notification.PRIORITY_MIN)
.setChannel(NotificationChannels.USER)
.setSmallIcon(R.drawable.ic_person)
.setContentTitle(mContext.getString(R.string.guest_notification_title))
.setContentText(mContext.getString(R.string.guest_notification_text))

View File

@@ -43,6 +43,7 @@ import android.util.SparseArray;
import com.android.internal.R;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.SystemUI;
import com.android.systemui.util.NotificationChannels;
import java.util.List;
@@ -206,6 +207,7 @@ public class StorageNotification extends SystemUI {
.setStyle(new Notification.BigTextStyle().bigText(text))
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setLocalOnly(true)
.setChannel(NotificationChannels.STORAGE)
.setCategory(Notification.CATEGORY_SYSTEM)
.setDeleteIntent(buildSnoozeIntent(fsUuid));
SystemUI.overrideNotificationAppName(mContext, builder);
@@ -225,6 +227,7 @@ public class StorageNotification extends SystemUI {
R.string.ext_media_unsupported_notification_message, disk.getDescription());
Notification.Builder builder = new Notification.Builder(mContext)
.setChannel(NotificationChannels.STORAGE)
.setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE))
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)
@@ -331,7 +334,6 @@ public class StorageNotification extends SystemUI {
return buildNotificationBuilder(vol, title, text)
.setCategory(Notification.CATEGORY_PROGRESS)
.setPriority(Notification.PRIORITY_LOW)
.setOngoing(true)
.build();
}
@@ -360,7 +362,6 @@ public class StorageNotification extends SystemUI {
buildUnmountPendingIntent(vol)))
.setContentIntent(initIntent)
.setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()))
.setCategory(Notification.CATEGORY_SYSTEM)
.build();
} else {
@@ -377,8 +378,7 @@ public class StorageNotification extends SystemUI {
mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
.setContentIntent(browseIntent)
.setCategory(Notification.CATEGORY_SYSTEM)
.setPriority(Notification.PRIORITY_LOW);
.setCategory(Notification.CATEGORY_SYSTEM);
// Non-adoptable disks can't be snoozed.
if (disk.isAdoptable()) {
builder.setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()));
@@ -402,7 +402,6 @@ public class StorageNotification extends SystemUI {
return buildNotificationBuilder(vol, title, text)
.setCategory(Notification.CATEGORY_PROGRESS)
.setPriority(Notification.PRIORITY_LOW)
.setOngoing(true)
.build();
}
@@ -485,8 +484,8 @@ public class StorageNotification extends SystemUI {
.setStyle(new Notification.BigTextStyle().bigText(text))
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setLocalOnly(true)
.setChannel(NotificationChannels.STORAGE)
.setCategory(Notification.CATEGORY_PROGRESS)
.setPriority(Notification.PRIORITY_LOW)
.setProgress(100, status, false)
.setOngoing(true);
SystemUI.overrideNotificationAppName(mContext, builder);
@@ -537,7 +536,7 @@ public class StorageNotification extends SystemUI {
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setLocalOnly(true)
.setCategory(Notification.CATEGORY_SYSTEM)
.setPriority(Notification.PRIORITY_LOW)
.setChannel(NotificationChannels.STORAGE)
.setAutoCancel(true);
SystemUI.overrideNotificationAppName(mContext, builder);
@@ -564,6 +563,7 @@ public class StorageNotification extends SystemUI {
private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title,
CharSequence text) {
Notification.Builder builder = new Notification.Builder(mContext)
.setChannel(NotificationChannels.STORAGE)
.setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.android.systemui.util;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
import java.util.Arrays;
public class NotificationChannels extends SystemUI {
public static String ALERTS = "ALR";
public static String SCREENSHOTS = "SCN";
public static String SECURITY = "SEC";
public static String USER = "USR";
public static String STORAGE = "DSK";
@VisibleForTesting
static void createAll(Context context) {
final NotificationManager nm = context.getSystemService(NotificationManager.class);
nm.createNotificationChannels(Arrays.asList(
new NotificationChannel(
ALERTS,
context.getString(R.string.notification_channel_alerts),
NotificationManager.IMPORTANCE_HIGH),
new NotificationChannel(
SCREENSHOTS,
context.getString(R.string.notification_channel_screenshot),
NotificationManager.IMPORTANCE_DEFAULT),
new NotificationChannel(
SECURITY,
context.getString(R.string.notification_channel_security),
NotificationManager.IMPORTANCE_HIGH),
new NotificationChannel(
USER,
context.getString(R.string.notification_channel_user_status),
NotificationManager.IMPORTANCE_MIN),
new NotificationChannel(
STORAGE,
context.getString(R.string.notification_channel_storage),
NotificationManager.IMPORTANCE_LOW)
));
}
@Override
public void start() {
createAll(mContext);
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.android.systemui.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.ArraySet;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.util.NotificationChannels;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ChannelsTest extends SysuiTestCase {
private final NotificationManager mMockNotificationManager = mock(NotificationManager.class);
@Before
public void setup() throws Exception {
mContext.addMockSystemService(Context.NOTIFICATION_SERVICE, mMockNotificationManager);
}
@Test
public void testChannelSetup() {
Set<String> ALL_CHANNELS = new ArraySet<>(Arrays.asList(
NotificationChannels.ALERTS,
NotificationChannels.SCREENSHOTS,
NotificationChannels.SECURITY,
NotificationChannels.USER,
NotificationChannels.STORAGE
));
NotificationChannels.createAll(mContext);
ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
verify(mMockNotificationManager).createNotificationChannels(captor.capture());
final List<NotificationChannel> list = captor.getValue();
assertEquals(ALL_CHANNELS.size(), list.size());
list.forEach((chan) -> assertTrue(ALL_CHANNELS.contains(chan.getId())));
}
}