Merge "Change the API for setting Notification Actions to be contextual."
diff --git a/api/current.txt b/api/current.txt
index 13311d4..b11e6cd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5385,11 +5385,11 @@
method public android.graphics.drawable.Icon getIcon();
method public android.app.RemoteInput[] getRemoteInputs();
method public int getSemanticAction();
+ method public boolean isContextual();
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_CALL = 10; // 0xa
- field public static final int SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION = 11; // 0xb
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
@@ -5414,6 +5414,7 @@
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 setContextual(boolean);
method public android.app.Notification.Action.Builder setSemanticAction(int);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e066f06..b657a91 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1427,18 +1427,13 @@
*/
public static final int SEMANTIC_ACTION_CALL = 10;
- /**
- * {@code SemanticAction}: Contextual action - dependent on the current notification. E.g.
- * open a Map application with an address shown in the notification.
- */
- public static final int SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION = 11;
-
private final Bundle mExtras;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private Icon mIcon;
private final RemoteInput[] mRemoteInputs;
private boolean mAllowGeneratedReplies = true;
private final @SemanticAction int mSemanticAction;
+ private final boolean mIsContextual;
/**
* Small icon representing the action.
@@ -1474,6 +1469,7 @@
mRemoteInputs = in.createTypedArray(RemoteInput.CREATOR);
mAllowGeneratedReplies = in.readInt() == 1;
mSemanticAction = in.readInt();
+ mIsContextual = in.readInt() == 1;
}
/**
@@ -1482,13 +1478,13 @@
@Deprecated
public Action(int icon, CharSequence title, PendingIntent intent) {
this(Icon.createWithResource("", icon), title, intent, new Bundle(), null, true,
- SEMANTIC_ACTION_NONE);
+ SEMANTIC_ACTION_NONE, false /* isContextual */);
}
/** Keep in sync with {@link Notification.Action.Builder#Builder(Action)}! */
private Action(Icon icon, CharSequence title, PendingIntent intent, Bundle extras,
RemoteInput[] remoteInputs, boolean allowGeneratedReplies,
- @SemanticAction int semanticAction) {
+ @SemanticAction int semanticAction, boolean isContextual) {
this.mIcon = icon;
if (icon != null && icon.getType() == Icon.TYPE_RESOURCE) {
this.icon = icon.getResId();
@@ -1499,6 +1495,7 @@
this.mRemoteInputs = remoteInputs;
this.mAllowGeneratedReplies = allowGeneratedReplies;
this.mSemanticAction = semanticAction;
+ this.mIsContextual = isContextual;
}
/**
@@ -1546,6 +1543,15 @@
}
/**
+ * Returns whether this is a contextual Action, i.e. whether the action is dependent on the
+ * notification message body. An example of a contextual action could be an action opening a
+ * map application with an address shown in the notification.
+ */
+ public boolean isContextual() {
+ return mIsContextual;
+ }
+
+ /**
* 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
* {@link RemoteInput#isDataOnly}.
@@ -1570,6 +1576,7 @@
private final Bundle mExtras;
private ArrayList<RemoteInput> mRemoteInputs;
private @SemanticAction int mSemanticAction;
+ private boolean mIsContextual;
/**
* Construct a new builder for {@link Action} object.
@@ -1684,6 +1691,16 @@
}
/**
+ * Sets whether this {@link Action} is a contextual action, i.e. whether the action is
+ * dependent on the notification message body. An example of a contextual action could
+ * be an action opening a map application with an address shown in the notification.
+ */
+ public Builder setContextual(boolean isContextual) {
+ mIsContextual = isContextual;
+ return this;
+ }
+
+ /**
* Apply an extender to this action builder. Extenders may be used to add
* metadata or change options on this builder.
*/
@@ -1697,7 +1714,7 @@
* necessary to display the action.
*/
private void checkContextualActionNullFields() {
- if (mSemanticAction != SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) return;
+ if (!mIsContextual) return;
if (mIcon == null) {
throw new NullPointerException("Contextual Actions must contain a valid icon");
@@ -1743,7 +1760,7 @@
RemoteInput[] textInputsArr = textInputs.isEmpty()
? null : textInputs.toArray(new RemoteInput[textInputs.size()]);
return new Action(mIcon, mTitle, mIntent, mExtras, textInputsArr,
- mAllowGeneratedReplies, mSemanticAction);
+ mAllowGeneratedReplies, mSemanticAction, mIsContextual);
}
}
@@ -1756,7 +1773,8 @@
mExtras == null ? new Bundle() : new Bundle(mExtras),
getRemoteInputs(),
getAllowGeneratedReplies(),
- getSemanticAction());
+ getSemanticAction(),
+ isContextual());
}
@Override
@@ -1784,6 +1802,7 @@
out.writeTypedArray(mRemoteInputs, flags);
out.writeInt(mAllowGeneratedReplies ? 1 : 0);
out.writeInt(mSemanticAction);
+ out.writeInt(mIsContextual ? 1 : 0);
}
public static final Parcelable.Creator<Action> CREATOR =
@@ -2073,8 +2092,7 @@
SEMANTIC_ACTION_UNMUTE,
SEMANTIC_ACTION_THUMBS_UP,
SEMANTIC_ACTION_THUMBS_DOWN,
- SEMANTIC_ACTION_CALL,
- SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION
+ SEMANTIC_ACTION_CALL
})
@Retention(RetentionPolicy.SOURCE)
public @interface SemanticAction {}
@@ -3230,8 +3248,7 @@
}
/**
- * Returns the actions that are contextual (marked as SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) out
- * of the actions in this notification.
+ * Returns the actions that are contextual out of the actions in this notification.
*
* @hide
*/
@@ -3240,8 +3257,7 @@
List<Notification.Action> contextualActions = new ArrayList<>();
for (Notification.Action action : actions) {
- if (action.getSemanticAction()
- == Notification.Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) {
+ if (action.isContextual()) {
contextualActions.add(action);
}
}
@@ -5062,8 +5078,7 @@
List<Notification.Action> actions) {
List<Notification.Action> nonContextualActions = new ArrayList<>();
for (Notification.Action action : actions) {
- if (action.getSemanticAction()
- != Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION) {
+ if (!action.isContextual()) {
nonContextualActions.add(action);
}
}
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
index 56c4158..f2db2da 100644
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
@@ -383,8 +383,7 @@
remoteAction.getIcon(),
remoteAction.getTitle(),
remoteAction.getActionIntent())
- .setSemanticAction(
- Notification.Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION)
+ .setContextual(true)
.addExtras(Bundle.forPair(KEY_ACTION_TYPE, classification.getEntity(0)))
.build();
actions.add(action);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
index 871ff89..6f4de1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
@@ -400,8 +400,7 @@
Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
title,
PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0))
- .setSemanticAction(
- Notification.Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION)
+ .setContextual(true)
.build();
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c2c8825..66dd7a3 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -765,8 +765,7 @@
.addTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX, nv.rank)
.addTaggedData(MetricsEvent.NOTIFICATION_SHADE_COUNT, nv.count)
.addTaggedData(MetricsEvent.NOTIFICATION_ACTION_IS_SMART,
- (Notification.Action.SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION
- == action.getSemanticAction()) ? 1 : 0)
+ action.isContextual() ? 1 : 0)
.addTaggedData(
MetricsEvent.NOTIFICATION_SMART_SUGGESTION_ASSISTANT_GENERATED,
generatedByAssistant ? 1 : 0));
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index e2c64ca..d19fbfaa 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -165,7 +165,7 @@
private String mChannelIdLogTag;
/**
* This list contains system generated smart actions from NAS, app-generated smart actions are
- * stored in Notification.actions marked as SEMANTIC_ACTION_CONTEXTUAL_SUGGESTION.
+ * stored in Notification.actions with isContextual() set to true.
*/
private ArrayList<Notification.Action> mSystemGeneratedSmartActions;
private ArrayList<CharSequence> mSmartReplies;