Loading api/current.txt +12 −0 Original line number Diff line number Diff line Loading @@ -5291,8 +5291,19 @@ package android.app { method public android.os.Bundle getExtras(); method public android.graphics.drawable.Icon getIcon(); method public android.app.RemoteInput[] getRemoteInputs(); method public int getSemanticAction(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.Notification.Action> CREATOR; field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5 field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4 field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2 field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3 field public static final int SEMANTIC_ACTION_MUTE = 6; // 0x6 field public static final int SEMANTIC_ACTION_NONE = 0; // 0x0 field public static final int SEMANTIC_ACTION_REPLY = 1; // 0x1 field public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; // 0x9 field public static final int SEMANTIC_ACTION_THUMBS_UP = 8; // 0x8 field public static final int SEMANTIC_ACTION_UNMUTE = 7; // 0x7 field public android.app.PendingIntent actionIntent; field public deprecated int icon; field public java.lang.CharSequence title; Loading @@ -5308,6 +5319,7 @@ package android.app { method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Extender); method public android.os.Bundle getExtras(); method public android.app.Notification.Action.Builder setAllowGeneratedReplies(boolean); method public android.app.Notification.Action.Builder setSemanticAction(int); } public static abstract interface Notification.Action.Extender { core/java/android/app/Notification.java +121 −7 Original line number Diff line number Diff line Loading @@ -1268,10 +1268,67 @@ public class Notification implements Parcelable */ private static final String EXTRA_DATA_ONLY_INPUTS = "android.extra.DATA_ONLY_INPUTS"; /** * {@link }: No semantic action defined. */ public static final int SEMANTIC_ACTION_NONE = 0; /** * {@code SemanticAction}: Reply to a conversation, chat, group, or wherever replies * may be appropriate. */ public static final int SEMANTIC_ACTION_REPLY = 1; /** * {@code SemanticAction}: Mark content as read. */ public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; /** * {@code SemanticAction}: Mark content as unread. */ public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; /** * {@code SemanticAction}: Delete the content associated with the notification. This * could mean deleting an email, message, etc. */ public static final int SEMANTIC_ACTION_DELETE = 4; /** * {@code SemanticAction}: Archive the content associated with the notification. This * could mean archiving an email, message, etc. */ public static final int SEMANTIC_ACTION_ARCHIVE = 5; /** * {@code SemanticAction}: Mute the content associated with the notification. This could * mean silencing a conversation or currently playing media. */ public static final int SEMANTIC_ACTION_MUTE = 6; /** * {@code SemanticAction}: Unmute the content associated with the notification. This could * mean un-silencing a conversation or currently playing media. */ public static final int SEMANTIC_ACTION_UNMUTE = 7; /** * {@code SemanticAction}: Mark content with a thumbs up. */ public static final int SEMANTIC_ACTION_THUMBS_UP = 8; /** * {@code SemanticAction}: Mark content with a thumbs down. */ public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; private final Bundle mExtras; private Icon mIcon; private final RemoteInput[] mRemoteInputs; private boolean mAllowGeneratedReplies = true; private final @SemanticAction int mSemanticAction; /** * Small icon representing the action. Loading Loading @@ -1306,6 +1363,7 @@ public class Notification implements Parcelable mExtras = Bundle.setDefusable(in.readBundle(), true); mRemoteInputs = in.createTypedArray(RemoteInput.CREATOR); mAllowGeneratedReplies = in.readInt() == 1; mSemanticAction = in.readInt(); } /** Loading @@ -1313,12 +1371,14 @@ public class Notification implements Parcelable */ @Deprecated public Action(int icon, CharSequence title, PendingIntent intent) { this(Icon.createWithResource("", icon), title, intent, new Bundle(), null, true); this(Icon.createWithResource("", icon), title, intent, new Bundle(), null, true, SEMANTIC_ACTION_NONE); } /** Keep in sync with {@link Notification.Action.Builder#Builder(Action)}! */ private Action(Icon icon, CharSequence title, PendingIntent intent, Bundle extras, RemoteInput[] remoteInputs, boolean allowGeneratedReplies) { RemoteInput[] remoteInputs, boolean allowGeneratedReplies, @SemanticAction int semanticAction) { this.mIcon = icon; if (icon != null && icon.getType() == Icon.TYPE_RESOURCE) { this.icon = icon.getResId(); Loading @@ -1328,6 +1388,7 @@ public class Notification implements Parcelable this.mExtras = extras != null ? extras : new Bundle(); this.mRemoteInputs = remoteInputs; this.mAllowGeneratedReplies = allowGeneratedReplies; this.mSemanticAction = semanticAction; } /** Loading Loading @@ -1365,6 +1426,15 @@ public class Notification implements Parcelable return mRemoteInputs; } /** * Returns the {@code SemanticAction} associated with this {@link Action}. A * {@code SemanticAction} denotes what an {@link Action}'s {@link PendingIntent} will do * (eg. reply, mark as read, delete, etc). */ public @SemanticAction int getSemanticAction() { return mSemanticAction; } /** * Get the list of inputs to be collected from the user that ONLY accept data when this * action is sent. These remote inputs are guaranteed to return true on a call to Loading @@ -1389,6 +1459,7 @@ public class Notification implements Parcelable private boolean mAllowGeneratedReplies = true; private final Bundle mExtras; private ArrayList<RemoteInput> mRemoteInputs; private @SemanticAction int mSemanticAction; /** * Construct a new builder for {@link Action} object. Loading @@ -1408,7 +1479,7 @@ public class Notification implements Parcelable * @param intent the {@link PendingIntent} to fire when users trigger this action */ public Builder(Icon icon, CharSequence title, PendingIntent intent) { this(icon, title, intent, new Bundle(), null, true); this(icon, title, intent, new Bundle(), null, true, SEMANTIC_ACTION_NONE); } /** Loading @@ -1419,11 +1490,12 @@ public class Notification implements Parcelable public Builder(Action action) { this(action.getIcon(), action.title, action.actionIntent, new Bundle(action.mExtras), action.getRemoteInputs(), action.getAllowGeneratedReplies()); action.getAllowGeneratedReplies(), action.getSemanticAction()); } private Builder(Icon icon, CharSequence title, PendingIntent intent, Bundle extras, RemoteInput[] remoteInputs, boolean allowGeneratedReplies) { RemoteInput[] remoteInputs, boolean allowGeneratedReplies, @SemanticAction int semanticAction) { mIcon = icon; mTitle = title; mIntent = intent; Loading @@ -1433,6 +1505,7 @@ public class Notification implements Parcelable Collections.addAll(mRemoteInputs, remoteInputs); } mAllowGeneratedReplies = allowGeneratedReplies; mSemanticAction = semanticAction; } /** Loading Loading @@ -1487,6 +1560,19 @@ public class Notification implements Parcelable return this; } /** * Sets the {@code SemanticAction} for this {@link Action}. A * {@code SemanticAction} denotes what an {@link Action}'s * {@link PendingIntent} will do (eg. reply, mark as read, delete, etc). * @param semanticAction a SemanticAction defined within {@link Action} with * {@code SEMANTIC_ACTION_} prefixes * @return this object for method chaining */ public Builder setSemanticAction(@SemanticAction int semanticAction) { mSemanticAction = semanticAction; return this; } /** * Apply an extender to this action builder. Extenders may be used to add * metadata or change options on this builder. Loading Loading @@ -1528,7 +1614,7 @@ public class Notification implements Parcelable RemoteInput[] textInputsArr = textInputs.isEmpty() ? null : textInputs.toArray(new RemoteInput[textInputs.size()]); return new Action(mIcon, mTitle, mIntent, mExtras, textInputsArr, mAllowGeneratedReplies); mAllowGeneratedReplies, mSemanticAction); } } Loading @@ -1540,12 +1626,15 @@ public class Notification implements Parcelable actionIntent, // safe to alias mExtras == null ? new Bundle() : new Bundle(mExtras), getRemoteInputs(), getAllowGeneratedReplies()); getAllowGeneratedReplies(), getSemanticAction()); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel out, int flags) { final Icon ic = getIcon(); Loading @@ -1565,7 +1654,9 @@ public class Notification implements Parcelable out.writeBundle(mExtras); out.writeTypedArray(mRemoteInputs, flags); out.writeInt(mAllowGeneratedReplies ? 1 : 0); out.writeInt(mSemanticAction); } public static final Parcelable.Creator<Action> CREATOR = new Parcelable.Creator<Action>() { public Action createFromParcel(Parcel in) { Loading Loading @@ -1827,6 +1918,29 @@ public class Notification implements Parcelable return (mFlags & FLAG_HINT_DISPLAY_INLINE) != 0; } } /** * Provides meaning to an {@link Action} that hints at what the associated * {@link PendingIntent} will do. For example, an {@link Action} with a * {@link PendingIntent} that replies to a text message notification may have the * {@link #SEMANTIC_ACTION_REPLY} {@code SemanticAction} set within it. * * @hide */ @IntDef(prefix = { "SEMANTIC_ACTION_" }, value = { SEMANTIC_ACTION_NONE, SEMANTIC_ACTION_REPLY, SEMANTIC_ACTION_MARK_AS_READ, SEMANTIC_ACTION_MARK_AS_UNREAD, SEMANTIC_ACTION_DELETE, SEMANTIC_ACTION_ARCHIVE, SEMANTIC_ACTION_MUTE, SEMANTIC_ACTION_UNMUTE, SEMANTIC_ACTION_THUMBS_UP, SEMANTIC_ACTION_THUMBS_DOWN }) @Retention(RetentionPolicy.SOURCE) public @interface SemanticAction {} } /** Loading core/tests/coretests/src/android/app/NotificationTest.java +52 −0 Original line number Diff line number Diff line Loading @@ -18,11 +18,13 @@ package android.app; import static com.android.internal.util.NotificationColorUtil.satisfiesTextContrast; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import android.annotation.Nullable; import android.content.Context; import android.content.Intent; import android.graphics.BitmapFactory; Loading @@ -40,6 +42,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.function.Consumer; @RunWith(AndroidJUnit4.class) @SmallTest public class NotificationTest { Loading Loading @@ -281,6 +285,40 @@ public class NotificationTest { assertTrue(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION)); } @Test public void action_builder_hasDefault() { Notification.Action action = makeNotificationAction(null); assertEquals(Notification.Action.SEMANTIC_ACTION_NONE, action.getSemanticAction()); } @Test public void action_builder_setSemanticAction() { Notification.Action action = makeNotificationAction( builder -> builder.setSemanticAction(Notification.Action.SEMANTIC_ACTION_REPLY)); assertEquals(Notification.Action.SEMANTIC_ACTION_REPLY, action.getSemanticAction()); } @Test public void action_parcel() { Notification.Action action = writeAndReadParcelable( makeNotificationAction(builder -> { builder.setSemanticAction(Notification.Action.SEMANTIC_ACTION_ARCHIVE); builder.setAllowGeneratedReplies(true); })); assertEquals(Notification.Action.SEMANTIC_ACTION_ARCHIVE, action.getSemanticAction()); assertTrue(action.getAllowGeneratedReplies()); } @Test public void action_clone() { Notification.Action action = makeNotificationAction( builder -> builder.setSemanticAction(Notification.Action.SEMANTIC_ACTION_DELETE)); assertEquals( Notification.Action.SEMANTIC_ACTION_DELETE, action.clone().getSemanticAction()); } private Notification.Builder getMediaNotification() { MediaSession session = new MediaSession(mContext, "test"); return new Notification.Builder(mContext, "color") Loading @@ -300,4 +338,18 @@ public class NotificationTest { p.setDataPosition(0); return p.readParcelable(/* classLoader */ null); } /** * Creates a Notification.Action by mocking initial dependencies and then applying * transformations if they're defined. */ private Notification.Action makeNotificationAction( @Nullable Consumer<Notification.Action.Builder> transformation) { Notification.Action.Builder actionBuilder = new Notification.Action.Builder(null, "Test Title", null); if (transformation != null) { transformation.accept(actionBuilder); } return actionBuilder.build(); } } Loading
api/current.txt +12 −0 Original line number Diff line number Diff line Loading @@ -5291,8 +5291,19 @@ package android.app { method public android.os.Bundle getExtras(); method public android.graphics.drawable.Icon getIcon(); method public android.app.RemoteInput[] getRemoteInputs(); method public int getSemanticAction(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.Notification.Action> CREATOR; field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5 field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4 field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2 field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3 field public static final int SEMANTIC_ACTION_MUTE = 6; // 0x6 field public static final int SEMANTIC_ACTION_NONE = 0; // 0x0 field public static final int SEMANTIC_ACTION_REPLY = 1; // 0x1 field public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; // 0x9 field public static final int SEMANTIC_ACTION_THUMBS_UP = 8; // 0x8 field public static final int SEMANTIC_ACTION_UNMUTE = 7; // 0x7 field public android.app.PendingIntent actionIntent; field public deprecated int icon; field public java.lang.CharSequence title; Loading @@ -5308,6 +5319,7 @@ package android.app { method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Extender); method public android.os.Bundle getExtras(); method public android.app.Notification.Action.Builder setAllowGeneratedReplies(boolean); method public android.app.Notification.Action.Builder setSemanticAction(int); } public static abstract interface Notification.Action.Extender {
core/java/android/app/Notification.java +121 −7 Original line number Diff line number Diff line Loading @@ -1268,10 +1268,67 @@ public class Notification implements Parcelable */ private static final String EXTRA_DATA_ONLY_INPUTS = "android.extra.DATA_ONLY_INPUTS"; /** * {@link }: No semantic action defined. */ public static final int SEMANTIC_ACTION_NONE = 0; /** * {@code SemanticAction}: Reply to a conversation, chat, group, or wherever replies * may be appropriate. */ public static final int SEMANTIC_ACTION_REPLY = 1; /** * {@code SemanticAction}: Mark content as read. */ public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; /** * {@code SemanticAction}: Mark content as unread. */ public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; /** * {@code SemanticAction}: Delete the content associated with the notification. This * could mean deleting an email, message, etc. */ public static final int SEMANTIC_ACTION_DELETE = 4; /** * {@code SemanticAction}: Archive the content associated with the notification. This * could mean archiving an email, message, etc. */ public static final int SEMANTIC_ACTION_ARCHIVE = 5; /** * {@code SemanticAction}: Mute the content associated with the notification. This could * mean silencing a conversation or currently playing media. */ public static final int SEMANTIC_ACTION_MUTE = 6; /** * {@code SemanticAction}: Unmute the content associated with the notification. This could * mean un-silencing a conversation or currently playing media. */ public static final int SEMANTIC_ACTION_UNMUTE = 7; /** * {@code SemanticAction}: Mark content with a thumbs up. */ public static final int SEMANTIC_ACTION_THUMBS_UP = 8; /** * {@code SemanticAction}: Mark content with a thumbs down. */ public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; private final Bundle mExtras; private Icon mIcon; private final RemoteInput[] mRemoteInputs; private boolean mAllowGeneratedReplies = true; private final @SemanticAction int mSemanticAction; /** * Small icon representing the action. Loading Loading @@ -1306,6 +1363,7 @@ public class Notification implements Parcelable mExtras = Bundle.setDefusable(in.readBundle(), true); mRemoteInputs = in.createTypedArray(RemoteInput.CREATOR); mAllowGeneratedReplies = in.readInt() == 1; mSemanticAction = in.readInt(); } /** Loading @@ -1313,12 +1371,14 @@ public class Notification implements Parcelable */ @Deprecated public Action(int icon, CharSequence title, PendingIntent intent) { this(Icon.createWithResource("", icon), title, intent, new Bundle(), null, true); this(Icon.createWithResource("", icon), title, intent, new Bundle(), null, true, SEMANTIC_ACTION_NONE); } /** Keep in sync with {@link Notification.Action.Builder#Builder(Action)}! */ private Action(Icon icon, CharSequence title, PendingIntent intent, Bundle extras, RemoteInput[] remoteInputs, boolean allowGeneratedReplies) { RemoteInput[] remoteInputs, boolean allowGeneratedReplies, @SemanticAction int semanticAction) { this.mIcon = icon; if (icon != null && icon.getType() == Icon.TYPE_RESOURCE) { this.icon = icon.getResId(); Loading @@ -1328,6 +1388,7 @@ public class Notification implements Parcelable this.mExtras = extras != null ? extras : new Bundle(); this.mRemoteInputs = remoteInputs; this.mAllowGeneratedReplies = allowGeneratedReplies; this.mSemanticAction = semanticAction; } /** Loading Loading @@ -1365,6 +1426,15 @@ public class Notification implements Parcelable return mRemoteInputs; } /** * Returns the {@code SemanticAction} associated with this {@link Action}. A * {@code SemanticAction} denotes what an {@link Action}'s {@link PendingIntent} will do * (eg. reply, mark as read, delete, etc). */ public @SemanticAction int getSemanticAction() { return mSemanticAction; } /** * Get the list of inputs to be collected from the user that ONLY accept data when this * action is sent. These remote inputs are guaranteed to return true on a call to Loading @@ -1389,6 +1459,7 @@ public class Notification implements Parcelable private boolean mAllowGeneratedReplies = true; private final Bundle mExtras; private ArrayList<RemoteInput> mRemoteInputs; private @SemanticAction int mSemanticAction; /** * Construct a new builder for {@link Action} object. Loading @@ -1408,7 +1479,7 @@ public class Notification implements Parcelable * @param intent the {@link PendingIntent} to fire when users trigger this action */ public Builder(Icon icon, CharSequence title, PendingIntent intent) { this(icon, title, intent, new Bundle(), null, true); this(icon, title, intent, new Bundle(), null, true, SEMANTIC_ACTION_NONE); } /** Loading @@ -1419,11 +1490,12 @@ public class Notification implements Parcelable public Builder(Action action) { this(action.getIcon(), action.title, action.actionIntent, new Bundle(action.mExtras), action.getRemoteInputs(), action.getAllowGeneratedReplies()); action.getAllowGeneratedReplies(), action.getSemanticAction()); } private Builder(Icon icon, CharSequence title, PendingIntent intent, Bundle extras, RemoteInput[] remoteInputs, boolean allowGeneratedReplies) { RemoteInput[] remoteInputs, boolean allowGeneratedReplies, @SemanticAction int semanticAction) { mIcon = icon; mTitle = title; mIntent = intent; Loading @@ -1433,6 +1505,7 @@ public class Notification implements Parcelable Collections.addAll(mRemoteInputs, remoteInputs); } mAllowGeneratedReplies = allowGeneratedReplies; mSemanticAction = semanticAction; } /** Loading Loading @@ -1487,6 +1560,19 @@ public class Notification implements Parcelable return this; } /** * Sets the {@code SemanticAction} for this {@link Action}. A * {@code SemanticAction} denotes what an {@link Action}'s * {@link PendingIntent} will do (eg. reply, mark as read, delete, etc). * @param semanticAction a SemanticAction defined within {@link Action} with * {@code SEMANTIC_ACTION_} prefixes * @return this object for method chaining */ public Builder setSemanticAction(@SemanticAction int semanticAction) { mSemanticAction = semanticAction; return this; } /** * Apply an extender to this action builder. Extenders may be used to add * metadata or change options on this builder. Loading Loading @@ -1528,7 +1614,7 @@ public class Notification implements Parcelable RemoteInput[] textInputsArr = textInputs.isEmpty() ? null : textInputs.toArray(new RemoteInput[textInputs.size()]); return new Action(mIcon, mTitle, mIntent, mExtras, textInputsArr, mAllowGeneratedReplies); mAllowGeneratedReplies, mSemanticAction); } } Loading @@ -1540,12 +1626,15 @@ public class Notification implements Parcelable actionIntent, // safe to alias mExtras == null ? new Bundle() : new Bundle(mExtras), getRemoteInputs(), getAllowGeneratedReplies()); getAllowGeneratedReplies(), getSemanticAction()); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel out, int flags) { final Icon ic = getIcon(); Loading @@ -1565,7 +1654,9 @@ public class Notification implements Parcelable out.writeBundle(mExtras); out.writeTypedArray(mRemoteInputs, flags); out.writeInt(mAllowGeneratedReplies ? 1 : 0); out.writeInt(mSemanticAction); } public static final Parcelable.Creator<Action> CREATOR = new Parcelable.Creator<Action>() { public Action createFromParcel(Parcel in) { Loading Loading @@ -1827,6 +1918,29 @@ public class Notification implements Parcelable return (mFlags & FLAG_HINT_DISPLAY_INLINE) != 0; } } /** * Provides meaning to an {@link Action} that hints at what the associated * {@link PendingIntent} will do. For example, an {@link Action} with a * {@link PendingIntent} that replies to a text message notification may have the * {@link #SEMANTIC_ACTION_REPLY} {@code SemanticAction} set within it. * * @hide */ @IntDef(prefix = { "SEMANTIC_ACTION_" }, value = { SEMANTIC_ACTION_NONE, SEMANTIC_ACTION_REPLY, SEMANTIC_ACTION_MARK_AS_READ, SEMANTIC_ACTION_MARK_AS_UNREAD, SEMANTIC_ACTION_DELETE, SEMANTIC_ACTION_ARCHIVE, SEMANTIC_ACTION_MUTE, SEMANTIC_ACTION_UNMUTE, SEMANTIC_ACTION_THUMBS_UP, SEMANTIC_ACTION_THUMBS_DOWN }) @Retention(RetentionPolicy.SOURCE) public @interface SemanticAction {} } /** Loading
core/tests/coretests/src/android/app/NotificationTest.java +52 −0 Original line number Diff line number Diff line Loading @@ -18,11 +18,13 @@ package android.app; import static com.android.internal.util.NotificationColorUtil.satisfiesTextContrast; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import android.annotation.Nullable; import android.content.Context; import android.content.Intent; import android.graphics.BitmapFactory; Loading @@ -40,6 +42,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.function.Consumer; @RunWith(AndroidJUnit4.class) @SmallTest public class NotificationTest { Loading Loading @@ -281,6 +285,40 @@ public class NotificationTest { assertTrue(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION)); } @Test public void action_builder_hasDefault() { Notification.Action action = makeNotificationAction(null); assertEquals(Notification.Action.SEMANTIC_ACTION_NONE, action.getSemanticAction()); } @Test public void action_builder_setSemanticAction() { Notification.Action action = makeNotificationAction( builder -> builder.setSemanticAction(Notification.Action.SEMANTIC_ACTION_REPLY)); assertEquals(Notification.Action.SEMANTIC_ACTION_REPLY, action.getSemanticAction()); } @Test public void action_parcel() { Notification.Action action = writeAndReadParcelable( makeNotificationAction(builder -> { builder.setSemanticAction(Notification.Action.SEMANTIC_ACTION_ARCHIVE); builder.setAllowGeneratedReplies(true); })); assertEquals(Notification.Action.SEMANTIC_ACTION_ARCHIVE, action.getSemanticAction()); assertTrue(action.getAllowGeneratedReplies()); } @Test public void action_clone() { Notification.Action action = makeNotificationAction( builder -> builder.setSemanticAction(Notification.Action.SEMANTIC_ACTION_DELETE)); assertEquals( Notification.Action.SEMANTIC_ACTION_DELETE, action.clone().getSemanticAction()); } private Notification.Builder getMediaNotification() { MediaSession session = new MediaSession(mContext, "test"); return new Notification.Builder(mContext, "color") Loading @@ -300,4 +338,18 @@ public class NotificationTest { p.setDataPosition(0); return p.readParcelable(/* classLoader */ null); } /** * Creates a Notification.Action by mocking initial dependencies and then applying * transformations if they're defined. */ private Notification.Action makeNotificationAction( @Nullable Consumer<Notification.Action.Builder> transformation) { Notification.Action.Builder actionBuilder = new Notification.Action.Builder(null, "Test Title", null); if (transformation != null) { transformation.accept(actionBuilder); } return actionBuilder.build(); } }