Loading api/current.txt +24 −5 Original line number Diff line number Diff line Loading @@ -5245,8 +5245,8 @@ package android.app { method public android.app.Notification clone(); method public int describeContents(); method public boolean getAllowSystemGeneratedContextualActions(); method public android.app.PendingIntent getAppOverlayIntent(); method public int getBadgeIconType(); method public android.app.Notification.BubbleMetadata getBubbleMetadata(); method public java.lang.String getChannelId(); method public java.lang.String getGroup(); method public int getGroupAlertBehavior(); Loading Loading @@ -5459,6 +5459,25 @@ package android.app { method public android.app.Notification.BigTextStyle setSummaryText(java.lang.CharSequence); } public static final class Notification.BubbleMetadata implements android.os.Parcelable { method public int describeContents(); method public int getDesiredHeight(); method public android.graphics.drawable.Icon getIcon(); method public android.app.PendingIntent getIntent(); method public java.lang.CharSequence getTitle(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.Notification.BubbleMetadata> CREATOR; } public static class Notification.BubbleMetadata.Builder { ctor public Notification.BubbleMetadata.Builder(); method public android.app.Notification.BubbleMetadata build(); method public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int); method public android.app.Notification.BubbleMetadata.Builder setIcon(android.graphics.drawable.Icon); method public android.app.Notification.BubbleMetadata.Builder setIntent(android.app.PendingIntent); method public android.app.Notification.BubbleMetadata.Builder setTitle(java.lang.CharSequence); } public static class Notification.Builder { ctor public Notification.Builder(android.content.Context, java.lang.String); ctor public deprecated Notification.Builder(android.content.Context); Loading @@ -5478,9 +5497,9 @@ package android.app { method public static android.app.Notification.Builder recoverBuilder(android.content.Context, android.app.Notification); method public android.app.Notification.Builder setActions(android.app.Notification.Action...); method public android.app.Notification.Builder setAllowSystemGeneratedContextualActions(boolean); method public android.app.Notification.Builder setAppOverlayIntent(android.app.PendingIntent); method public android.app.Notification.Builder setAutoCancel(boolean); method public android.app.Notification.Builder setBadgeIconType(int); method public android.app.Notification.Builder setBubbleMetadata(android.app.Notification.BubbleMetadata); method public android.app.Notification.Builder setCategory(java.lang.String); method public android.app.Notification.Builder setChannelId(java.lang.String); method public android.app.Notification.Builder setChronometerCountDown(boolean); Loading Loading @@ -5695,8 +5714,8 @@ package android.app { public final class NotificationChannel implements android.os.Parcelable { ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int); method public boolean canBubble(); method public boolean canBypassDnd(); method public boolean canOverlayApps(); method public boolean canShowBadge(); method public int describeContents(); method public void enableLights(boolean); Loading @@ -5712,7 +5731,7 @@ package android.app { method public android.net.Uri getSound(); method public long[] getVibrationPattern(); method public boolean hasUserSetImportance(); method public void setAllowAppOverlay(boolean); method public void setAllowBubbles(boolean); method public void setBypassDnd(boolean); method public void setDescription(java.lang.String); method public void setGroup(java.lang.String); Loading Loading @@ -5746,7 +5765,7 @@ package android.app { public class NotificationManager { method public java.lang.String addAutomaticZenRule(android.app.AutomaticZenRule); method public boolean areAppOverlaysAllowed(); method public boolean areBubblesAllowed(); method public boolean areNotificationsEnabled(); method public boolean canNotifyAsPackage(java.lang.String); method public void cancel(int); core/java/android/app/INotificationManager.aidl +3 −3 Original line number Diff line number Diff line Loading @@ -65,9 +65,9 @@ interface INotificationManager boolean areNotificationsEnabled(String pkg); int getPackageImportance(String pkg); void setAppOverlaysAllowed(String pkg, int uid, boolean allowed); boolean areAppOverlaysAllowed(String pkg); boolean areAppOverlaysAllowedForPackage(String pkg, int uid); void setBubblesAllowed(String pkg, int uid, boolean allowed); boolean areBubblesAllowed(String pkg); boolean areBubblesAllowedForPackage(String pkg, int uid); void createNotificationChannelGroups(String pkg, in ParceledListSlice channelGroupList); void createNotificationChannels(String pkg, in ParceledListSlice channelsList); Loading core/java/android/app/Notification.java +198 −19 Original line number Diff line number Diff line Loading @@ -1276,7 +1276,7 @@ public class Notification implements Parcelable private String mShortcutId; private CharSequence mSettingsText; private PendingIntent mAppOverlayIntent; private BubbleMetadata mBubbleMetadata; /** @hide */ @IntDef(prefix = { "GROUP_ALERT_" }, value = { Loading Loading @@ -2278,7 +2278,7 @@ public class Notification implements Parcelable mGroupAlertBehavior = parcel.readInt(); if (parcel.readInt() != 0) { mAppOverlayIntent = PendingIntent.CREATOR.createFromParcel(parcel); mBubbleMetadata = BubbleMetadata.CREATOR.createFromParcel(parcel); } mAllowSystemGeneratedContextualActions = parcel.readBoolean(); Loading Loading @@ -2396,7 +2396,7 @@ public class Notification implements Parcelable that.mBadgeIcon = this.mBadgeIcon; that.mSettingsText = this.mSettingsText; that.mGroupAlertBehavior = this.mGroupAlertBehavior; that.mAppOverlayIntent = this.mAppOverlayIntent; that.mBubbleMetadata = this.mBubbleMetadata; that.mAllowSystemGeneratedContextualActions = this.mAllowSystemGeneratedContextualActions; if (!heavy) { Loading Loading @@ -2719,9 +2719,9 @@ public class Notification implements Parcelable parcel.writeInt(mGroupAlertBehavior); if (mAppOverlayIntent != null) { if (mBubbleMetadata != null) { parcel.writeInt(1); mAppOverlayIntent.writeToParcel(parcel, 0); mBubbleMetadata.writeToParcel(parcel, 0); } else { parcel.writeInt(0); } Loading Loading @@ -3141,11 +3141,11 @@ public class Notification implements Parcelable } /** * Returns the intent that will be used to display app content in a floating window over the * existing foreground activity. * Returns the bubble metadata that will be used to display app content in a floating window * over the existing foreground activity. */ public PendingIntent getAppOverlayIntent() { return mAppOverlayIntent; public BubbleMetadata getBubbleMetadata() { return mBubbleMetadata; } /** Loading Loading @@ -3508,19 +3508,18 @@ public class Notification implements Parcelable } /** * Sets the intent that will be used to display app content in a floating window * over the existing foreground activity. * Sets the {@link BubbleMetadata} that will be used to display app content in a floating * window over the existing foreground activity. * * <p>This intent will be ignored unless this notification is posted to a channel that * allows {@link NotificationChannel#canOverlayApps() app overlays}.</p> * <p>This data will be ignored unless the notification is posted to a channel that * allows {@link NotificationChannel#canBubble() bubbles}.</p> * * <p>Notifications with a valid and allowed app overlay intent will be displayed as * floating windows outside of the notification shade on unlocked devices. When a user * interacts with one of these windows, this app overlay intent will be invoked and * displayed.</p> * <b>Notifications with a valid and allowed bubble metadata will display in collapsed state * outside of the notification shade on unlocked devices. When a user interacts with the * collapsed state, the bubble intent will be invoked and displayed.</b> */ public Builder setAppOverlayIntent(PendingIntent intent) { mN.mAppOverlayIntent = intent; public Builder setBubbleMetadata(BubbleMetadata data) { mN.mBubbleMetadata = data; return this; } Loading Loading @@ -8422,6 +8421,186 @@ public class Notification implements Parcelable } } /** * Encapsulates the information needed to display a notification as a bubble. * * <p>A bubble is used to display app content in a floating window over the existing * foreground activity. A bubble has a collapsed state represented by an icon, * {@link BubbleMetadata.Builder#setIcon(Icon)} and an expanded state which is populated * via {@link BubbleMetadata.Builder#setIntent(PendingIntent)}.</p> * * <b>Notifications with a valid and allowed bubble will display in collapsed state * outside of the notification shade on unlocked devices. When a user interacts with the * collapsed bubble, the bubble intent will be invoked and displayed.</b> * * @see Notification.Builder#setBubbleMetadata(BubbleMetadata) */ public static final class BubbleMetadata implements Parcelable { private PendingIntent mPendingIntent; private CharSequence mTitle; private Icon mIcon; private int mDesiredHeight; private BubbleMetadata(PendingIntent intent, CharSequence title, Icon icon, int height) { mPendingIntent = intent; mTitle = title; mIcon = icon; mDesiredHeight = height; } private BubbleMetadata(Parcel in) { mPendingIntent = PendingIntent.CREATOR.createFromParcel(in); mTitle = in.readCharSequence(); mIcon = Icon.CREATOR.createFromParcel(in); mDesiredHeight = in.readInt(); } /** * @return the pending intent used to populate the floating window for this bubble. */ public PendingIntent getIntent() { return mPendingIntent; } /** * @return the title that will appear along with the app content defined by * {@link #getIntent()} for this bubble. */ public CharSequence getTitle() { return mTitle; } /** * @return the icon that will be displayed for this bubble when it is collapsed. */ public Icon getIcon() { return mIcon; } /** * @return the ideal height for the floating window that app content defined by * {@link #getIntent()} for this bubble. */ public int getDesiredHeight() { return mDesiredHeight; } public static final Parcelable.Creator<BubbleMetadata> CREATOR = new Parcelable.Creator<BubbleMetadata>() { @Override public BubbleMetadata createFromParcel(Parcel source) { return new BubbleMetadata(source); } @Override public BubbleMetadata[] newArray(int size) { return new BubbleMetadata[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel out, int flags) { mPendingIntent.writeToParcel(out, 0); out.writeCharSequence(mTitle); mIcon.writeToParcel(out, 0); out.writeInt(mDesiredHeight); } /** * Builder to construct a {@link BubbleMetadata} object. */ public static class Builder { private PendingIntent mPendingIntent; private CharSequence mTitle; private Icon mIcon; private int mDesiredHeight; /** * Constructs a new builder object. */ public Builder() { } /** * Sets the intent that will be used when the bubble is expanded. This will display the * app content in a floating window over the existing foreground activity. */ public BubbleMetadata.Builder setIntent(PendingIntent intent) { if (intent == null) { throw new IllegalArgumentException("Bubble requires non-null pending intent"); } mPendingIntent = intent; return this; } /** * Sets the title that will appear along with the app content for this bubble. * * <p>A title is required and should expect to fit on a single line and make sense when * shown with the content defined by {@link #setIntent(PendingIntent)}.</p> */ public BubbleMetadata.Builder setTitle(CharSequence title) { if (TextUtils.isEmpty(title)) { throw new IllegalArgumentException("Bubbles require non-null or empty title"); } mTitle = title; return this; } /** * Sets the icon that will represent the bubble when it is collapsed. * * <p>An icon is required and should be representative of the content within the bubble. * If your app produces multiple bubbles, the image should be unique for each of them. * </p> */ public BubbleMetadata.Builder setIcon(Icon icon) { if (icon == null) { throw new IllegalArgumentException("Bubbles require non-null icon"); } mIcon = icon; return this; } /** * Sets the desired height for the app content defined by * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not * enough space on the screen or if the provided height is too small to be useful. */ public BubbleMetadata.Builder setDesiredHeight(int height) { mDesiredHeight = Math.max(height, 0); return this; } /** * Creates the {@link BubbleMetadata} defined by this builder. * <p>Will throw {@link IllegalStateException} if required fields have not been set * on this builder.</p> */ public BubbleMetadata build() { if (mPendingIntent == null) { throw new IllegalStateException("Must supply pending intent to bubble"); } if (TextUtils.isEmpty(mTitle)) { throw new IllegalStateException("Must supply a title for the bubble"); } if (mIcon == null) { throw new IllegalStateException("Must supply an icon for the bubble"); } return new BubbleMetadata(mPendingIntent, mTitle, mIcon, mDesiredHeight); } } } // When adding a new Style subclass here, don't forget to update // Builder.getNotificationStyleClass. Loading core/java/android/app/NotificationChannel.java +25 −25 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public final class NotificationChannel implements Parcelable { private static final String ATT_FG_SERVICE_SHOWN = "fgservice"; private static final String ATT_GROUP = "group"; private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system"; private static final String ATT_ALLOW_APP_OVERLAY = "app_overlay"; private static final String ATT_ALLOW_BUBBLE = "allow_bubble"; private static final String DELIMITER = ","; /** Loading Loading @@ -121,7 +121,7 @@ public final class NotificationChannel implements Parcelable { /** * @hide */ public static final int USER_LOCKED_ALLOW_APP_OVERLAY = 0x00000100; public static final int USER_LOCKED_ALLOW_BUBBLE = 0x00000100; /** * @hide Loading @@ -134,7 +134,7 @@ public final class NotificationChannel implements Parcelable { USER_LOCKED_VIBRATION, USER_LOCKED_SOUND, USER_LOCKED_SHOW_BADGE, USER_LOCKED_ALLOW_APP_OVERLAY USER_LOCKED_ALLOW_BUBBLE }; private static final int DEFAULT_LIGHT_COLOR = 0; Loading @@ -144,7 +144,7 @@ public final class NotificationChannel implements Parcelable { NotificationManager.IMPORTANCE_UNSPECIFIED; private static final boolean DEFAULT_DELETED = false; private static final boolean DEFAULT_SHOW_BADGE = true; private static final boolean DEFAULT_ALLOW_APP_OVERLAY = true; private static final boolean DEFAULT_ALLOW_BUBBLE = true; @UnsupportedAppUsage private final String mId; Loading @@ -168,7 +168,7 @@ public final class NotificationChannel implements Parcelable { private AudioAttributes mAudioAttributes = Notification.AUDIO_ATTRIBUTES_DEFAULT; // If this is a blockable system notification channel. private boolean mBlockableSystem = false; private boolean mAllowAppOverlay = DEFAULT_ALLOW_APP_OVERLAY; private boolean mAllowBubbles = DEFAULT_ALLOW_BUBBLE; private boolean mImportanceLockedByOEM; /** Loading Loading @@ -231,7 +231,7 @@ public final class NotificationChannel implements Parcelable { mAudioAttributes = in.readInt() > 0 ? AudioAttributes.CREATOR.createFromParcel(in) : null; mLightColor = in.readInt(); mBlockableSystem = in.readBoolean(); mAllowAppOverlay = in.readBoolean(); mAllowBubbles = in.readBoolean(); mImportanceLockedByOEM = in.readBoolean(); } Loading Loading @@ -285,7 +285,7 @@ public final class NotificationChannel implements Parcelable { } dest.writeInt(mLightColor); dest.writeBoolean(mBlockableSystem); dest.writeBoolean(mAllowAppOverlay); dest.writeBoolean(mAllowBubbles); dest.writeBoolean(mImportanceLockedByOEM); } Loading Loading @@ -480,7 +480,7 @@ public final class NotificationChannel implements Parcelable { /** * Sets whether notifications posted to this channel can appear outside of the notification * shade, floating over other apps' content. * shade, floating over other apps' content as a bubble. * * <p>This value will be ignored for channels that aren't allowed to pop on screen (that is, * channels whose {@link #getImportance() importance} is < Loading @@ -488,10 +488,10 @@ public final class NotificationChannel implements Parcelable { * * <p>Only modifiable before the channel is submitted to * * {@link NotificationManager#createNotificationChannel(NotificationChannel)}.</p> * @see Notification#getAppOverlayIntent() * @see Notification#getBubbleMetadata() */ public void setAllowAppOverlay(boolean allowAppOverlay) { mAllowAppOverlay = allowAppOverlay; public void setAllowBubbles(boolean allowBubbles) { mAllowBubbles = allowBubbles; } /** Loading Loading @@ -610,16 +610,16 @@ public final class NotificationChannel implements Parcelable { * Returns whether notifications posted to this channel can display outside of the notification * shade, in a floating window on top of other apps. */ public boolean canOverlayApps() { return isAppOverlayAllowed() && getImportance() >= IMPORTANCE_HIGH; public boolean canBubble() { return isBubbleAllowed() && getImportance() >= IMPORTANCE_HIGH; } /** * Like {@link #canOverlayApps()}, but only checks the permission, not the importance. * Like {@link #canBubble()}, but only checks the permission, not the importance. * @hide */ public boolean isAppOverlayAllowed() { return mAllowAppOverlay; public boolean isBubbleAllowed() { return mAllowBubbles; } /** Loading Loading @@ -719,7 +719,7 @@ public final class NotificationChannel implements Parcelable { lockFields(safeInt(parser, ATT_USER_LOCKED, 0)); setFgServiceShown(safeBool(parser, ATT_FG_SERVICE_SHOWN, false)); setBlockableSystem(safeBool(parser, ATT_BLOCKABLE_SYSTEM, false)); setAllowAppOverlay(safeBool(parser, ATT_ALLOW_APP_OVERLAY, DEFAULT_ALLOW_APP_OVERLAY)); setAllowBubbles(safeBool(parser, ATT_ALLOW_BUBBLE, DEFAULT_ALLOW_BUBBLE)); } @Nullable Loading Loading @@ -838,8 +838,8 @@ public final class NotificationChannel implements Parcelable { if (isBlockableSystem()) { out.attribute(null, ATT_BLOCKABLE_SYSTEM, Boolean.toString(isBlockableSystem())); } if (canOverlayApps() != DEFAULT_ALLOW_APP_OVERLAY) { out.attribute(null, ATT_ALLOW_APP_OVERLAY, Boolean.toString(canOverlayApps())); if (canBubble() != DEFAULT_ALLOW_BUBBLE) { out.attribute(null, ATT_ALLOW_BUBBLE, Boolean.toString(canBubble())); } out.endTag(null, TAG_CHANNEL); Loading Loading @@ -883,7 +883,7 @@ public final class NotificationChannel implements Parcelable { record.put(ATT_DELETED, Boolean.toString(isDeleted())); record.put(ATT_GROUP, getGroup()); record.put(ATT_BLOCKABLE_SYSTEM, isBlockableSystem()); record.put(ATT_ALLOW_APP_OVERLAY, canOverlayApps()); record.put(ATT_ALLOW_BUBBLE, canBubble()); return record; } Loading Loading @@ -983,7 +983,7 @@ public final class NotificationChannel implements Parcelable { && mShowBadge == that.mShowBadge && isDeleted() == that.isDeleted() && isBlockableSystem() == that.isBlockableSystem() && mAllowAppOverlay == that.mAllowAppOverlay && mAllowBubbles == that.mAllowBubbles && Objects.equals(getId(), that.getId()) && Objects.equals(getName(), that.getName()) && Objects.equals(mDesc, that.mDesc) Loading @@ -1000,7 +1000,7 @@ public final class NotificationChannel implements Parcelable { getLockscreenVisibility(), getSound(), mLights, getLightColor(), getUserLockedFields(), isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(), getAudioAttributes(), isBlockableSystem(), mAllowAppOverlay, getAudioAttributes(), isBlockableSystem(), mAllowBubbles, mImportanceLockedByOEM); result = 31 * result + Arrays.hashCode(mVibration); return result; Loading Loading @@ -1028,7 +1028,7 @@ public final class NotificationChannel implements Parcelable { + ", mGroup='" + mGroup + '\'' + ", mAudioAttributes=" + mAudioAttributes + ", mBlockableSystem=" + mBlockableSystem + ", mAllowAppOverlay=" + mAllowAppOverlay + ", mAllowBubbles=" + mAllowBubbles + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM + '}'; pw.println(prefix + output); Loading @@ -1055,7 +1055,7 @@ public final class NotificationChannel implements Parcelable { + ", mGroup='" + mGroup + '\'' + ", mAudioAttributes=" + mAudioAttributes + ", mBlockableSystem=" + mBlockableSystem + ", mAllowAppOverlay=" + mAllowAppOverlay + ", mAllowBubbles=" + mAllowBubbles + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM + '}'; } Loading Loading @@ -1090,7 +1090,7 @@ public final class NotificationChannel implements Parcelable { mAudioAttributes.writeToProto(proto, NotificationChannelProto.AUDIO_ATTRIBUTES); } proto.write(NotificationChannelProto.IS_BLOCKABLE_SYSTEM, mBlockableSystem); proto.write(NotificationChannelProto.ALLOW_APP_OVERLAY, mAllowAppOverlay); proto.write(NotificationChannelProto.ALLOW_APP_OVERLAY, mAllowBubbles); proto.end(token); } Loading core/java/android/app/NotificationManager.java +4 −4 Original line number Diff line number Diff line Loading @@ -1080,14 +1080,14 @@ public class NotificationManager { * notification shade, floating over other apps' content. * * <p>This value will be ignored for notifications that are posted to channels that do not * allow app overlays ({@link NotificationChannel#canOverlayApps()}. * allow bubbles ({@link NotificationChannel#canBubble()}. * * @see Notification#getAppOverlayIntent() * @see Notification#getBubbleMetadata() */ public boolean areAppOverlaysAllowed() { public boolean areBubblesAllowed() { INotificationManager service = getService(); try { return service.areAppOverlaysAllowed(mContext.getPackageName()); return service.areBubblesAllowed(mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading
api/current.txt +24 −5 Original line number Diff line number Diff line Loading @@ -5245,8 +5245,8 @@ package android.app { method public android.app.Notification clone(); method public int describeContents(); method public boolean getAllowSystemGeneratedContextualActions(); method public android.app.PendingIntent getAppOverlayIntent(); method public int getBadgeIconType(); method public android.app.Notification.BubbleMetadata getBubbleMetadata(); method public java.lang.String getChannelId(); method public java.lang.String getGroup(); method public int getGroupAlertBehavior(); Loading Loading @@ -5459,6 +5459,25 @@ package android.app { method public android.app.Notification.BigTextStyle setSummaryText(java.lang.CharSequence); } public static final class Notification.BubbleMetadata implements android.os.Parcelable { method public int describeContents(); method public int getDesiredHeight(); method public android.graphics.drawable.Icon getIcon(); method public android.app.PendingIntent getIntent(); method public java.lang.CharSequence getTitle(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.Notification.BubbleMetadata> CREATOR; } public static class Notification.BubbleMetadata.Builder { ctor public Notification.BubbleMetadata.Builder(); method public android.app.Notification.BubbleMetadata build(); method public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int); method public android.app.Notification.BubbleMetadata.Builder setIcon(android.graphics.drawable.Icon); method public android.app.Notification.BubbleMetadata.Builder setIntent(android.app.PendingIntent); method public android.app.Notification.BubbleMetadata.Builder setTitle(java.lang.CharSequence); } public static class Notification.Builder { ctor public Notification.Builder(android.content.Context, java.lang.String); ctor public deprecated Notification.Builder(android.content.Context); Loading @@ -5478,9 +5497,9 @@ package android.app { method public static android.app.Notification.Builder recoverBuilder(android.content.Context, android.app.Notification); method public android.app.Notification.Builder setActions(android.app.Notification.Action...); method public android.app.Notification.Builder setAllowSystemGeneratedContextualActions(boolean); method public android.app.Notification.Builder setAppOverlayIntent(android.app.PendingIntent); method public android.app.Notification.Builder setAutoCancel(boolean); method public android.app.Notification.Builder setBadgeIconType(int); method public android.app.Notification.Builder setBubbleMetadata(android.app.Notification.BubbleMetadata); method public android.app.Notification.Builder setCategory(java.lang.String); method public android.app.Notification.Builder setChannelId(java.lang.String); method public android.app.Notification.Builder setChronometerCountDown(boolean); Loading Loading @@ -5695,8 +5714,8 @@ package android.app { public final class NotificationChannel implements android.os.Parcelable { ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int); method public boolean canBubble(); method public boolean canBypassDnd(); method public boolean canOverlayApps(); method public boolean canShowBadge(); method public int describeContents(); method public void enableLights(boolean); Loading @@ -5712,7 +5731,7 @@ package android.app { method public android.net.Uri getSound(); method public long[] getVibrationPattern(); method public boolean hasUserSetImportance(); method public void setAllowAppOverlay(boolean); method public void setAllowBubbles(boolean); method public void setBypassDnd(boolean); method public void setDescription(java.lang.String); method public void setGroup(java.lang.String); Loading Loading @@ -5746,7 +5765,7 @@ package android.app { public class NotificationManager { method public java.lang.String addAutomaticZenRule(android.app.AutomaticZenRule); method public boolean areAppOverlaysAllowed(); method public boolean areBubblesAllowed(); method public boolean areNotificationsEnabled(); method public boolean canNotifyAsPackage(java.lang.String); method public void cancel(int);
core/java/android/app/INotificationManager.aidl +3 −3 Original line number Diff line number Diff line Loading @@ -65,9 +65,9 @@ interface INotificationManager boolean areNotificationsEnabled(String pkg); int getPackageImportance(String pkg); void setAppOverlaysAllowed(String pkg, int uid, boolean allowed); boolean areAppOverlaysAllowed(String pkg); boolean areAppOverlaysAllowedForPackage(String pkg, int uid); void setBubblesAllowed(String pkg, int uid, boolean allowed); boolean areBubblesAllowed(String pkg); boolean areBubblesAllowedForPackage(String pkg, int uid); void createNotificationChannelGroups(String pkg, in ParceledListSlice channelGroupList); void createNotificationChannels(String pkg, in ParceledListSlice channelsList); Loading
core/java/android/app/Notification.java +198 −19 Original line number Diff line number Diff line Loading @@ -1276,7 +1276,7 @@ public class Notification implements Parcelable private String mShortcutId; private CharSequence mSettingsText; private PendingIntent mAppOverlayIntent; private BubbleMetadata mBubbleMetadata; /** @hide */ @IntDef(prefix = { "GROUP_ALERT_" }, value = { Loading Loading @@ -2278,7 +2278,7 @@ public class Notification implements Parcelable mGroupAlertBehavior = parcel.readInt(); if (parcel.readInt() != 0) { mAppOverlayIntent = PendingIntent.CREATOR.createFromParcel(parcel); mBubbleMetadata = BubbleMetadata.CREATOR.createFromParcel(parcel); } mAllowSystemGeneratedContextualActions = parcel.readBoolean(); Loading Loading @@ -2396,7 +2396,7 @@ public class Notification implements Parcelable that.mBadgeIcon = this.mBadgeIcon; that.mSettingsText = this.mSettingsText; that.mGroupAlertBehavior = this.mGroupAlertBehavior; that.mAppOverlayIntent = this.mAppOverlayIntent; that.mBubbleMetadata = this.mBubbleMetadata; that.mAllowSystemGeneratedContextualActions = this.mAllowSystemGeneratedContextualActions; if (!heavy) { Loading Loading @@ -2719,9 +2719,9 @@ public class Notification implements Parcelable parcel.writeInt(mGroupAlertBehavior); if (mAppOverlayIntent != null) { if (mBubbleMetadata != null) { parcel.writeInt(1); mAppOverlayIntent.writeToParcel(parcel, 0); mBubbleMetadata.writeToParcel(parcel, 0); } else { parcel.writeInt(0); } Loading Loading @@ -3141,11 +3141,11 @@ public class Notification implements Parcelable } /** * Returns the intent that will be used to display app content in a floating window over the * existing foreground activity. * Returns the bubble metadata that will be used to display app content in a floating window * over the existing foreground activity. */ public PendingIntent getAppOverlayIntent() { return mAppOverlayIntent; public BubbleMetadata getBubbleMetadata() { return mBubbleMetadata; } /** Loading Loading @@ -3508,19 +3508,18 @@ public class Notification implements Parcelable } /** * Sets the intent that will be used to display app content in a floating window * over the existing foreground activity. * Sets the {@link BubbleMetadata} that will be used to display app content in a floating * window over the existing foreground activity. * * <p>This intent will be ignored unless this notification is posted to a channel that * allows {@link NotificationChannel#canOverlayApps() app overlays}.</p> * <p>This data will be ignored unless the notification is posted to a channel that * allows {@link NotificationChannel#canBubble() bubbles}.</p> * * <p>Notifications with a valid and allowed app overlay intent will be displayed as * floating windows outside of the notification shade on unlocked devices. When a user * interacts with one of these windows, this app overlay intent will be invoked and * displayed.</p> * <b>Notifications with a valid and allowed bubble metadata will display in collapsed state * outside of the notification shade on unlocked devices. When a user interacts with the * collapsed state, the bubble intent will be invoked and displayed.</b> */ public Builder setAppOverlayIntent(PendingIntent intent) { mN.mAppOverlayIntent = intent; public Builder setBubbleMetadata(BubbleMetadata data) { mN.mBubbleMetadata = data; return this; } Loading Loading @@ -8422,6 +8421,186 @@ public class Notification implements Parcelable } } /** * Encapsulates the information needed to display a notification as a bubble. * * <p>A bubble is used to display app content in a floating window over the existing * foreground activity. A bubble has a collapsed state represented by an icon, * {@link BubbleMetadata.Builder#setIcon(Icon)} and an expanded state which is populated * via {@link BubbleMetadata.Builder#setIntent(PendingIntent)}.</p> * * <b>Notifications with a valid and allowed bubble will display in collapsed state * outside of the notification shade on unlocked devices. When a user interacts with the * collapsed bubble, the bubble intent will be invoked and displayed.</b> * * @see Notification.Builder#setBubbleMetadata(BubbleMetadata) */ public static final class BubbleMetadata implements Parcelable { private PendingIntent mPendingIntent; private CharSequence mTitle; private Icon mIcon; private int mDesiredHeight; private BubbleMetadata(PendingIntent intent, CharSequence title, Icon icon, int height) { mPendingIntent = intent; mTitle = title; mIcon = icon; mDesiredHeight = height; } private BubbleMetadata(Parcel in) { mPendingIntent = PendingIntent.CREATOR.createFromParcel(in); mTitle = in.readCharSequence(); mIcon = Icon.CREATOR.createFromParcel(in); mDesiredHeight = in.readInt(); } /** * @return the pending intent used to populate the floating window for this bubble. */ public PendingIntent getIntent() { return mPendingIntent; } /** * @return the title that will appear along with the app content defined by * {@link #getIntent()} for this bubble. */ public CharSequence getTitle() { return mTitle; } /** * @return the icon that will be displayed for this bubble when it is collapsed. */ public Icon getIcon() { return mIcon; } /** * @return the ideal height for the floating window that app content defined by * {@link #getIntent()} for this bubble. */ public int getDesiredHeight() { return mDesiredHeight; } public static final Parcelable.Creator<BubbleMetadata> CREATOR = new Parcelable.Creator<BubbleMetadata>() { @Override public BubbleMetadata createFromParcel(Parcel source) { return new BubbleMetadata(source); } @Override public BubbleMetadata[] newArray(int size) { return new BubbleMetadata[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel out, int flags) { mPendingIntent.writeToParcel(out, 0); out.writeCharSequence(mTitle); mIcon.writeToParcel(out, 0); out.writeInt(mDesiredHeight); } /** * Builder to construct a {@link BubbleMetadata} object. */ public static class Builder { private PendingIntent mPendingIntent; private CharSequence mTitle; private Icon mIcon; private int mDesiredHeight; /** * Constructs a new builder object. */ public Builder() { } /** * Sets the intent that will be used when the bubble is expanded. This will display the * app content in a floating window over the existing foreground activity. */ public BubbleMetadata.Builder setIntent(PendingIntent intent) { if (intent == null) { throw new IllegalArgumentException("Bubble requires non-null pending intent"); } mPendingIntent = intent; return this; } /** * Sets the title that will appear along with the app content for this bubble. * * <p>A title is required and should expect to fit on a single line and make sense when * shown with the content defined by {@link #setIntent(PendingIntent)}.</p> */ public BubbleMetadata.Builder setTitle(CharSequence title) { if (TextUtils.isEmpty(title)) { throw new IllegalArgumentException("Bubbles require non-null or empty title"); } mTitle = title; return this; } /** * Sets the icon that will represent the bubble when it is collapsed. * * <p>An icon is required and should be representative of the content within the bubble. * If your app produces multiple bubbles, the image should be unique for each of them. * </p> */ public BubbleMetadata.Builder setIcon(Icon icon) { if (icon == null) { throw new IllegalArgumentException("Bubbles require non-null icon"); } mIcon = icon; return this; } /** * Sets the desired height for the app content defined by * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not * enough space on the screen or if the provided height is too small to be useful. */ public BubbleMetadata.Builder setDesiredHeight(int height) { mDesiredHeight = Math.max(height, 0); return this; } /** * Creates the {@link BubbleMetadata} defined by this builder. * <p>Will throw {@link IllegalStateException} if required fields have not been set * on this builder.</p> */ public BubbleMetadata build() { if (mPendingIntent == null) { throw new IllegalStateException("Must supply pending intent to bubble"); } if (TextUtils.isEmpty(mTitle)) { throw new IllegalStateException("Must supply a title for the bubble"); } if (mIcon == null) { throw new IllegalStateException("Must supply an icon for the bubble"); } return new BubbleMetadata(mPendingIntent, mTitle, mIcon, mDesiredHeight); } } } // When adding a new Style subclass here, don't forget to update // Builder.getNotificationStyleClass. Loading
core/java/android/app/NotificationChannel.java +25 −25 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public final class NotificationChannel implements Parcelable { private static final String ATT_FG_SERVICE_SHOWN = "fgservice"; private static final String ATT_GROUP = "group"; private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system"; private static final String ATT_ALLOW_APP_OVERLAY = "app_overlay"; private static final String ATT_ALLOW_BUBBLE = "allow_bubble"; private static final String DELIMITER = ","; /** Loading Loading @@ -121,7 +121,7 @@ public final class NotificationChannel implements Parcelable { /** * @hide */ public static final int USER_LOCKED_ALLOW_APP_OVERLAY = 0x00000100; public static final int USER_LOCKED_ALLOW_BUBBLE = 0x00000100; /** * @hide Loading @@ -134,7 +134,7 @@ public final class NotificationChannel implements Parcelable { USER_LOCKED_VIBRATION, USER_LOCKED_SOUND, USER_LOCKED_SHOW_BADGE, USER_LOCKED_ALLOW_APP_OVERLAY USER_LOCKED_ALLOW_BUBBLE }; private static final int DEFAULT_LIGHT_COLOR = 0; Loading @@ -144,7 +144,7 @@ public final class NotificationChannel implements Parcelable { NotificationManager.IMPORTANCE_UNSPECIFIED; private static final boolean DEFAULT_DELETED = false; private static final boolean DEFAULT_SHOW_BADGE = true; private static final boolean DEFAULT_ALLOW_APP_OVERLAY = true; private static final boolean DEFAULT_ALLOW_BUBBLE = true; @UnsupportedAppUsage private final String mId; Loading @@ -168,7 +168,7 @@ public final class NotificationChannel implements Parcelable { private AudioAttributes mAudioAttributes = Notification.AUDIO_ATTRIBUTES_DEFAULT; // If this is a blockable system notification channel. private boolean mBlockableSystem = false; private boolean mAllowAppOverlay = DEFAULT_ALLOW_APP_OVERLAY; private boolean mAllowBubbles = DEFAULT_ALLOW_BUBBLE; private boolean mImportanceLockedByOEM; /** Loading Loading @@ -231,7 +231,7 @@ public final class NotificationChannel implements Parcelable { mAudioAttributes = in.readInt() > 0 ? AudioAttributes.CREATOR.createFromParcel(in) : null; mLightColor = in.readInt(); mBlockableSystem = in.readBoolean(); mAllowAppOverlay = in.readBoolean(); mAllowBubbles = in.readBoolean(); mImportanceLockedByOEM = in.readBoolean(); } Loading Loading @@ -285,7 +285,7 @@ public final class NotificationChannel implements Parcelable { } dest.writeInt(mLightColor); dest.writeBoolean(mBlockableSystem); dest.writeBoolean(mAllowAppOverlay); dest.writeBoolean(mAllowBubbles); dest.writeBoolean(mImportanceLockedByOEM); } Loading Loading @@ -480,7 +480,7 @@ public final class NotificationChannel implements Parcelable { /** * Sets whether notifications posted to this channel can appear outside of the notification * shade, floating over other apps' content. * shade, floating over other apps' content as a bubble. * * <p>This value will be ignored for channels that aren't allowed to pop on screen (that is, * channels whose {@link #getImportance() importance} is < Loading @@ -488,10 +488,10 @@ public final class NotificationChannel implements Parcelable { * * <p>Only modifiable before the channel is submitted to * * {@link NotificationManager#createNotificationChannel(NotificationChannel)}.</p> * @see Notification#getAppOverlayIntent() * @see Notification#getBubbleMetadata() */ public void setAllowAppOverlay(boolean allowAppOverlay) { mAllowAppOverlay = allowAppOverlay; public void setAllowBubbles(boolean allowBubbles) { mAllowBubbles = allowBubbles; } /** Loading Loading @@ -610,16 +610,16 @@ public final class NotificationChannel implements Parcelable { * Returns whether notifications posted to this channel can display outside of the notification * shade, in a floating window on top of other apps. */ public boolean canOverlayApps() { return isAppOverlayAllowed() && getImportance() >= IMPORTANCE_HIGH; public boolean canBubble() { return isBubbleAllowed() && getImportance() >= IMPORTANCE_HIGH; } /** * Like {@link #canOverlayApps()}, but only checks the permission, not the importance. * Like {@link #canBubble()}, but only checks the permission, not the importance. * @hide */ public boolean isAppOverlayAllowed() { return mAllowAppOverlay; public boolean isBubbleAllowed() { return mAllowBubbles; } /** Loading Loading @@ -719,7 +719,7 @@ public final class NotificationChannel implements Parcelable { lockFields(safeInt(parser, ATT_USER_LOCKED, 0)); setFgServiceShown(safeBool(parser, ATT_FG_SERVICE_SHOWN, false)); setBlockableSystem(safeBool(parser, ATT_BLOCKABLE_SYSTEM, false)); setAllowAppOverlay(safeBool(parser, ATT_ALLOW_APP_OVERLAY, DEFAULT_ALLOW_APP_OVERLAY)); setAllowBubbles(safeBool(parser, ATT_ALLOW_BUBBLE, DEFAULT_ALLOW_BUBBLE)); } @Nullable Loading Loading @@ -838,8 +838,8 @@ public final class NotificationChannel implements Parcelable { if (isBlockableSystem()) { out.attribute(null, ATT_BLOCKABLE_SYSTEM, Boolean.toString(isBlockableSystem())); } if (canOverlayApps() != DEFAULT_ALLOW_APP_OVERLAY) { out.attribute(null, ATT_ALLOW_APP_OVERLAY, Boolean.toString(canOverlayApps())); if (canBubble() != DEFAULT_ALLOW_BUBBLE) { out.attribute(null, ATT_ALLOW_BUBBLE, Boolean.toString(canBubble())); } out.endTag(null, TAG_CHANNEL); Loading Loading @@ -883,7 +883,7 @@ public final class NotificationChannel implements Parcelable { record.put(ATT_DELETED, Boolean.toString(isDeleted())); record.put(ATT_GROUP, getGroup()); record.put(ATT_BLOCKABLE_SYSTEM, isBlockableSystem()); record.put(ATT_ALLOW_APP_OVERLAY, canOverlayApps()); record.put(ATT_ALLOW_BUBBLE, canBubble()); return record; } Loading Loading @@ -983,7 +983,7 @@ public final class NotificationChannel implements Parcelable { && mShowBadge == that.mShowBadge && isDeleted() == that.isDeleted() && isBlockableSystem() == that.isBlockableSystem() && mAllowAppOverlay == that.mAllowAppOverlay && mAllowBubbles == that.mAllowBubbles && Objects.equals(getId(), that.getId()) && Objects.equals(getName(), that.getName()) && Objects.equals(mDesc, that.mDesc) Loading @@ -1000,7 +1000,7 @@ public final class NotificationChannel implements Parcelable { getLockscreenVisibility(), getSound(), mLights, getLightColor(), getUserLockedFields(), isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(), getAudioAttributes(), isBlockableSystem(), mAllowAppOverlay, getAudioAttributes(), isBlockableSystem(), mAllowBubbles, mImportanceLockedByOEM); result = 31 * result + Arrays.hashCode(mVibration); return result; Loading Loading @@ -1028,7 +1028,7 @@ public final class NotificationChannel implements Parcelable { + ", mGroup='" + mGroup + '\'' + ", mAudioAttributes=" + mAudioAttributes + ", mBlockableSystem=" + mBlockableSystem + ", mAllowAppOverlay=" + mAllowAppOverlay + ", mAllowBubbles=" + mAllowBubbles + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM + '}'; pw.println(prefix + output); Loading @@ -1055,7 +1055,7 @@ public final class NotificationChannel implements Parcelable { + ", mGroup='" + mGroup + '\'' + ", mAudioAttributes=" + mAudioAttributes + ", mBlockableSystem=" + mBlockableSystem + ", mAllowAppOverlay=" + mAllowAppOverlay + ", mAllowBubbles=" + mAllowBubbles + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM + '}'; } Loading Loading @@ -1090,7 +1090,7 @@ public final class NotificationChannel implements Parcelable { mAudioAttributes.writeToProto(proto, NotificationChannelProto.AUDIO_ATTRIBUTES); } proto.write(NotificationChannelProto.IS_BLOCKABLE_SYSTEM, mBlockableSystem); proto.write(NotificationChannelProto.ALLOW_APP_OVERLAY, mAllowAppOverlay); proto.write(NotificationChannelProto.ALLOW_APP_OVERLAY, mAllowBubbles); proto.end(token); } Loading
core/java/android/app/NotificationManager.java +4 −4 Original line number Diff line number Diff line Loading @@ -1080,14 +1080,14 @@ public class NotificationManager { * notification shade, floating over other apps' content. * * <p>This value will be ignored for notifications that are posted to channels that do not * allow app overlays ({@link NotificationChannel#canOverlayApps()}. * allow bubbles ({@link NotificationChannel#canBubble()}. * * @see Notification#getAppOverlayIntent() * @see Notification#getBubbleMetadata() */ public boolean areAppOverlaysAllowed() { public boolean areBubblesAllowed() { INotificationManager service = getService(); try { return service.areAppOverlaysAllowed(mContext.getPackageName()); return service.areBubblesAllowed(mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading