Api updates
- Better documentation on DEFAULT_CHANNEL_ID
- Renaming getChannel/setChannel/getTimeout/setTimeout
- Add documentation to getShortcutId
- @hide parcel constructors
Test: make, make cts
Bug: 37672218
Change-Id: I695b2620c51638a84930e9d1c5fbfd6d85699b55
diff --git a/api/current.txt b/api/current.txt
index 7a01e1a..f647404 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5122,6 +5122,7 @@
method public int describeContents();
method public int getBadgeIconType();
method public java.lang.String getChannel();
+ method public java.lang.String getChannelId();
method public java.lang.String getGroup();
method public int getGroupAlertBehavior();
method public android.graphics.drawable.Icon getLargeIcon();
@@ -5130,6 +5131,7 @@
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
method public long getTimeout();
+ method public long getTimeoutAfter();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
field public static final int BADGE_ICON_LARGE = 2; // 0x2
@@ -5332,6 +5334,7 @@
method public android.app.Notification.Builder setBadgeIconType(int);
method public android.app.Notification.Builder setCategory(java.lang.String);
method public android.app.Notification.Builder setChannel(java.lang.String);
+ method public android.app.Notification.Builder setChannelId(java.lang.String);
method public android.app.Notification.Builder setChronometerCountDown(boolean);
method public android.app.Notification.Builder setColor(int);
method public android.app.Notification.Builder setColorized(boolean);
@@ -5376,6 +5379,7 @@
method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
method public android.app.Notification.Builder setTimeout(long);
+ method public android.app.Notification.Builder setTimeoutAfter(long);
method public android.app.Notification.Builder setUsesChronometer(boolean);
method public deprecated android.app.Notification.Builder setVibrate(long[]);
method public android.app.Notification.Builder setVisibility(int);
@@ -5537,7 +5541,6 @@
public final class NotificationChannel implements android.os.Parcelable {
ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
- ctor protected NotificationChannel(android.os.Parcel);
method public boolean canBypassDnd();
method public boolean canShowBadge();
method public int describeContents();
@@ -5572,7 +5575,6 @@
public final class NotificationChannelGroup implements android.os.Parcelable {
ctor public NotificationChannelGroup(java.lang.String, java.lang.CharSequence);
- ctor protected NotificationChannelGroup(android.os.Parcel);
method public android.app.NotificationChannelGroup clone();
method public int describeContents();
method public java.util.List<android.app.NotificationChannel> getChannels();
diff --git a/api/system-current.txt b/api/system-current.txt
index 450df40..b69df43 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5302,6 +5302,7 @@
method public int describeContents();
method public int getBadgeIconType();
method public java.lang.String getChannel();
+ method public java.lang.String getChannelId();
method public java.lang.String getGroup();
method public int getGroupAlertBehavior();
method public android.graphics.drawable.Icon getLargeIcon();
@@ -5311,6 +5312,7 @@
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
method public long getTimeout();
+ method public long getTimeoutAfter();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
field public static final int BADGE_ICON_LARGE = 2; // 0x2
@@ -5516,6 +5518,7 @@
method public android.app.Notification.Builder setBadgeIconType(int);
method public android.app.Notification.Builder setCategory(java.lang.String);
method public android.app.Notification.Builder setChannel(java.lang.String);
+ method public android.app.Notification.Builder setChannelId(java.lang.String);
method public android.app.Notification.Builder setChronometerCountDown(boolean);
method public android.app.Notification.Builder setColor(int);
method public android.app.Notification.Builder setColorized(boolean);
@@ -5560,6 +5563,7 @@
method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
method public android.app.Notification.Builder setTimeout(long);
+ method public android.app.Notification.Builder setTimeoutAfter(long);
method public android.app.Notification.Builder setUsesChronometer(boolean);
method public deprecated android.app.Notification.Builder setVibrate(long[]);
method public android.app.Notification.Builder setVisibility(int);
@@ -5664,10 +5668,12 @@
ctor public Notification.TvExtender(android.app.Notification);
method public android.app.Notification.Builder extend(android.app.Notification.Builder);
method public java.lang.String getChannel();
+ method public java.lang.String getChannelId();
method public android.app.PendingIntent getContentIntent();
method public android.app.PendingIntent getDeleteIntent();
method public boolean isAvailableOnTv();
method public android.app.Notification.TvExtender setChannel(java.lang.String);
+ method public android.app.Notification.TvExtender setChannelId(java.lang.String);
method public android.app.Notification.TvExtender setContentIntent(android.app.PendingIntent);
method public android.app.Notification.TvExtender setDeleteIntent(android.app.PendingIntent);
}
@@ -5734,7 +5740,6 @@
public final class NotificationChannel implements android.os.Parcelable {
ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
- ctor protected NotificationChannel(android.os.Parcel);
method public boolean canBypassDnd();
method public boolean canShowBadge();
method public int describeContents();
@@ -5774,7 +5779,6 @@
public final class NotificationChannelGroup implements android.os.Parcelable {
ctor public NotificationChannelGroup(java.lang.String, java.lang.CharSequence);
- ctor protected NotificationChannelGroup(android.os.Parcel);
method public android.app.NotificationChannelGroup clone();
method public int describeContents();
method public java.util.List<android.app.NotificationChannel> getChannels();
diff --git a/api/test-current.txt b/api/test-current.txt
index c00795d..d2e3f1d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5135,6 +5135,7 @@
method public int describeContents();
method public int getBadgeIconType();
method public java.lang.String getChannel();
+ method public java.lang.String getChannelId();
method public java.lang.String getGroup();
method public int getGroupAlertBehavior();
method public android.graphics.drawable.Icon getLargeIcon();
@@ -5143,6 +5144,7 @@
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
method public long getTimeout();
+ method public long getTimeoutAfter();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
field public static final int BADGE_ICON_LARGE = 2; // 0x2
@@ -5345,6 +5347,7 @@
method public android.app.Notification.Builder setBadgeIconType(int);
method public android.app.Notification.Builder setCategory(java.lang.String);
method public android.app.Notification.Builder setChannel(java.lang.String);
+ method public android.app.Notification.Builder setChannelId(java.lang.String);
method public android.app.Notification.Builder setChronometerCountDown(boolean);
method public android.app.Notification.Builder setColor(int);
method public android.app.Notification.Builder setColorized(boolean);
@@ -5389,6 +5392,7 @@
method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
method public android.app.Notification.Builder setTimeout(long);
+ method public android.app.Notification.Builder setTimeoutAfter(long);
method public android.app.Notification.Builder setUsesChronometer(boolean);
method public deprecated android.app.Notification.Builder setVibrate(long[]);
method public android.app.Notification.Builder setVisibility(int);
@@ -5550,7 +5554,6 @@
public final class NotificationChannel implements android.os.Parcelable {
ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
- ctor protected NotificationChannel(android.os.Parcel);
method public boolean canBypassDnd();
method public boolean canShowBadge();
method public int describeContents();
@@ -5585,7 +5588,6 @@
public final class NotificationChannelGroup implements android.os.Parcelable {
ctor public NotificationChannelGroup(java.lang.String, java.lang.CharSequence);
- ctor protected NotificationChannelGroup(android.os.Parcel);
method public android.app.NotificationChannelGroup clone();
method public int describeContents();
method public java.util.List<android.app.NotificationChannel> getChannels();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e53e3da..00a8f46 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2393,7 +2393,7 @@
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Notification(channel=");
- sb.append(getChannel());
+ sb.append(getChannelId());
sb.append(" pri=");
sb.append(priority);
sb.append(" contentView=");
@@ -2507,6 +2507,13 @@
}
/**
+ * Returns the id of the channel this notification posts to.
+ */
+ public String getChannelId() {
+ return mChannelId;
+ }
+
+ /**
* Returns the time at which this notification should be canceled by the system, if it's not
* canceled already.
*/
@@ -2515,6 +2522,14 @@
}
/**
+ * Returns the duration from posting after which this notification should be canceled by the
+ * system, if it's not canceled already.
+ */
+ public long getTimeoutAfter() {
+ return mTimeout;
+ }
+
+ /**
* Returns what icon should be shown for this notification if it is being displayed in a
* Launcher that supports badging. Will be one of {@link #BADGE_ICON_NONE},
* {@link #BADGE_ICON_SMALL}, or {@link #BADGE_ICON_LARGE}.
@@ -2525,6 +2540,9 @@
/**
* Returns the {@link ShortcutInfo#getId() id} that this notification supersedes, if any.
+ *
+ * <p>Used by some Launchers that display notification content to hide shortcuts that duplicate
+ * notifications.
*/
public String getShortcutId() {
return mShortcutId;
@@ -2770,8 +2788,8 @@
* {@link ShortcutInfo#getId() id} of the shortcut, in case the Launcher wants to hide
* the shortcut.
*
- * This field will be ignored by Launchers that don't support badging or
- * {@link android.content.pm.ShortcutManager shortcuts}.
+ * This field will be ignored by Launchers that don't support badging, don't show
+ * notification content, or don't show {@link android.content.pm.ShortcutManager shortcuts}.
*
* @param shortcutId the {@link ShortcutInfo#getId() id} of the shortcut this notification
* supersedes
@@ -2816,6 +2834,14 @@
}
/**
+ * Specifies the channel the notification should be delivered on.
+ */
+ public Builder setChannelId(String channelId) {
+ mN.mChannelId = channelId;
+ return this;
+ }
+
+ /**
* Specifies a duration in milliseconds after which this notification should be canceled,
* if it is not already canceled.
*/
@@ -2825,6 +2851,15 @@
}
/**
+ * Specifies a duration in milliseconds after which this notification should be canceled,
+ * if it is not already canceled.
+ */
+ public Builder setTimeoutAfter(long durationMs) {
+ mN.mTimeout = durationMs;
+ return this;
+ }
+
+ /**
* Add a timestamp pertaining to the notification (usually the time the event occurred).
*
* For apps targeting {@link android.os.Build.VERSION_CODES#N} and above, this time is not
@@ -7915,6 +7950,16 @@
}
/**
+ * Specifies the channel the notification should be delivered on when shown on TV.
+ * It can be different from the channel that the notification is delivered to when
+ * posting on a non-TV device.
+ */
+ public TvExtender setChannelId(String channelId) {
+ mChannelId = channelId;
+ return this;
+ }
+
+ /**
* Returns the id of the channel this notification posts to on TV.
*/
public String getChannel() {
@@ -7922,6 +7967,13 @@
}
/**
+ * Returns the id of the channel this notification posts to on TV.
+ */
+ public String getChannelId() {
+ return mChannelId;
+ }
+
+ /**
* Supplies a {@link PendingIntent} to be sent when the notification is selected on TV.
* If provided, it is used instead of the content intent specified
* at the level of Notification.
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 2dd3301..704e912 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -40,8 +40,9 @@
public final class NotificationChannel implements Parcelable {
/**
- * The id of the default channel for an app. All notifications posted without a notification
- * channel specified are posted to this channel.
+ * The id of the default channel for an app. This id is reserved by the system. All
+ * notifications posted from apps targeting {@link android.os.Build.VERSION_CODES#N_MR1} or
+ * earlier without a notification channel specified are posted to this channel.
*/
public static final String DEFAULT_CHANNEL_ID = "miscellaneous";
@@ -170,6 +171,9 @@
this.mImportance = importance;
}
+ /**
+ * @hide
+ */
protected NotificationChannel(Parcel in) {
if (in.readByte() != 0) {
mId = in.readString();
diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java
index 852af8a..7e8f191a 100644
--- a/core/java/android/app/NotificationChannelGroup.java
+++ b/core/java/android/app/NotificationChannelGroup.java
@@ -69,6 +69,9 @@
this.mName = name != null ? getTrimmedString(name.toString()) : null;
}
+ /**
+ * @hide
+ */
protected NotificationChannelGroup(Parcel in) {
if (in.readByte() != 0) {
mId = in.readString();
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 6a24aa4..31b2dcc 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -133,7 +133,7 @@
}
return user.getIdentifier() + "|" + pkg + "|" +
(group == null
- ? "c:" + notification.getChannel()
+ ? "c:" + notification.getChannelId()
: "g:" + group);
}
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index cffa475..42c405f 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -483,7 +483,7 @@
appInfo.packageName, 0, new UserHandle(userId));
Notification.Builder notiBuilder = new Notification.Builder(ctx,
- localForegroundNoti.getChannel());
+ localForegroundNoti.getChannelId());
// it's ugly, but it clearly identifies the app
notiBuilder.setSmallIcon(appInfo.icon);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 39585a1..c802179 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1167,7 +1167,7 @@
builder.setContentTitle(title);
builder.setContentText(body);
builder.setDefaults(Notification.DEFAULT_ALL);
- builder.setChannel(SystemNotificationChannels.NETWORK_ALERTS);
+ builder.setChannelId(SystemNotificationChannels.NETWORK_ALERTS);
final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
builder.setDeleteIntent(PendingIntent.getBroadcast(
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1e7d076..51cc391 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3172,9 +3172,9 @@
mUsageStats.registerEnqueuedByApp(pkg);
// setup local book-keeping
- String channelId = notification.getChannel();
- if (mIsTelevision && (new Notification.TvExtender(notification)).getChannel() != null) {
- channelId = (new Notification.TvExtender(notification)).getChannel();
+ String channelId = notification.getChannelId();
+ if (mIsTelevision && (new Notification.TvExtender(notification)).getChannelId() != null) {
+ channelId = (new Notification.TvExtender(notification)).getChannelId();
}
final NotificationChannel channel = mRankingHelper.getNotificationChannel(pkg,
notificationUid, channelId, false /* includeDeleted */);
@@ -3584,7 +3584,7 @@
@VisibleForTesting
void scheduleTimeoutLocked(NotificationRecord record) {
- if (record.getNotification().getTimeout() > 0) {
+ if (record.getNotification().getTimeoutAfter() > 0) {
final PendingIntent pi = PendingIntent.getBroadcast(getContext(),
REQUEST_CODE_TIMEOUT,
new Intent(ACTION_NOTIFICATION_TIMEOUT)
@@ -3594,7 +3594,7 @@
.putExtra(EXTRA_KEY, record.getKey()),
PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + record.getNotification().getTimeout(), pi);
+ SystemClock.elapsedRealtime() + record.getNotification().getTimeoutAfter(), pi);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index b48fd5c..b51a4d1 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -392,7 +392,8 @@
}
pw.println(prefix + "contentView=" + notification.contentView);
pw.println(prefix + String.format("color=0x%08x", notification.color));
- pw.println(prefix + "timeout=" + TimeUtils.formatForLogging(notification.getTimeout()));
+ pw.println(prefix + "timeout="
+ + TimeUtils.formatForLogging(notification.getTimeoutAfter()));
if (notification.actions != null && notification.actions.length > 0) {
pw.println(prefix + "actions={");
final int N = notification.actions.length;
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index 275b612..fbc9e56 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -660,7 +660,7 @@
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setCategory(Notification.CATEGORY_SYSTEM)
.extend(new Notification.TvExtender()
- .setChannel(TV_NOTIFICATION_CHANNEL_ID))
+ .setChannelId(TV_NOTIFICATION_CHANNEL_ID))
.build();
notification.flags |= Notification.FLAG_NO_CLEAR;
notificationMgr.notifyAsUser(null, SystemMessage.NOTE_LOW_STORAGE, notification,
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 92534a1..7dd3a62 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -419,7 +419,7 @@
anyString(), anyInt(), eq("foo"), anyBoolean())).thenReturn(
new NotificationChannel("foo", "foo", NotificationManager.IMPORTANCE_HIGH));
- Notification.TvExtender tv = new Notification.TvExtender().setChannel("foo");
+ Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
generateNotificationRecord(null, tv).getNotification(), 0);
verify(mRankingHelper, times(1)).getNotificationChannel(
@@ -435,7 +435,7 @@
anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
mTestNotificationChannel);
- Notification.TvExtender tv = new Notification.TvExtender().setChannel("foo");
+ Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
generateNotificationRecord(null, tv).getNotification(), 0);
verify(mRankingHelper, times(1)).getNotificationChannel(
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
index b2e6ef9..1c8ca84 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
@@ -150,7 +150,7 @@
builder.setDefaults(defaults);
if (!preO) {
- builder.setChannel(channelId);
+ builder.setChannelId(channelId);
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 3f6f8ec..6b07cb5 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -1076,7 +1076,7 @@
.setContentIntent(pi)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.extend(new Notification.TvExtender()
- .setChannel(ADB_NOTIFICATION_CHANNEL_ID_TV))
+ .setChannelId(ADB_NOTIFICATION_CHANNEL_ID_TV))
.build();
mAdbNotificationShown = true;
mNotificationManager.notifyAsUser(null, id, notification,
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index c49be88..93677e3 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -124,7 +124,6 @@
Notification n = new Notification.Builder(NotificationTestList.this,
"phone call")
.setSmallIcon(R.drawable.icon2)
- .setChannel(phoneCall.getId())
.setFullScreenIntent(makeIntent2(), true)
.build();
mNM.notify(7001, n);
@@ -366,7 +365,7 @@
Notification n = new Notification.Builder(NotificationTestList.this, "default")
.setSmallIcon(R.drawable.icon2)
.setContentTitle("timeout in a minute")
- .setTimeout(System.currentTimeMillis() + (1000 * 60))
+ .setTimeoutAfter(System.currentTimeMillis() + (1000 * 60))
.build();
mNM.notify("timeout_min", 7013, n);
}
@@ -378,7 +377,7 @@
.setSmallIcon(R.drawable.icon2)
.setContentTitle("RED IS BEST")
.setContentText("or is blue?")
- .setTimeout(System.currentTimeMillis() + (1000 * 60))
+ .setTimeoutAfter(System.currentTimeMillis() + (1000 * 60))
.setColor(Color.RED)
.setFlag(Notification.FLAG_ONGOING_EVENT, true)
.setColorized(true)