1818
1919import static com .google .common .base .Preconditions .checkArgument ;
2020
21- import com .google .api .client .util .Key ;
2221import com .google .common .base .Strings ;
22+ import com .google .common .collect .ImmutableMap ;
23+ import com .google .firebase .internal .NonNull ;
24+ import java .util .HashMap ;
25+ import java .util .Map ;
2326
2427/**
2528 * Represents the <a href="https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html">
2629 * aps dictionary</a> that is part of every APNS message.
2730 */
2831public class Aps {
2932
30- @ Key ("alert" )
31- private final Object alert ;
32-
33- @ Key ("badge" )
34- private final Integer badge ;
35-
36- @ Key ("sound" )
37- private final String sound ;
38-
39- @ Key ("content-available" )
40- private final Integer contentAvailable ;
41-
42- @ Key ("category" )
43- private final String category ;
44-
45- @ Key ("thread-id" )
46- private final String threadId ;
33+ private final Map <String , Object > fields ;
4734
4835 private Aps (Builder builder ) {
4936 checkArgument (Strings .isNullOrEmpty (builder .alertString ) || (builder .alert == null ),
5037 "Multiple alert specifications (string and ApsAlert) found." );
38+ ImmutableMap .Builder <String , Object > fields = ImmutableMap .builder ();
5139 if (builder .alert != null ) {
52- this .alert = builder .alert ;
53- } else {
54- this .alert = builder .alertString ;
55- }
56- this .badge = builder .badge ;
57- this .sound = builder .sound ;
58- this .contentAvailable = builder .contentAvailable ? 1 : null ;
59- this .category = builder .category ;
60- this .threadId = builder .threadId ;
40+ fields .put ("alert" , builder .alert );
41+ } else if (builder .alertString != null ) {
42+ fields .put ("alert" , builder .alertString );
43+ }
44+ if (builder .badge != null ) {
45+ fields .put ("badge" , builder .badge );
46+ }
47+ if (builder .sound != null ) {
48+ fields .put ("sound" , builder .sound );
49+ }
50+ if (builder .contentAvailable ) {
51+ fields .put ("content-available" , 1 );
52+ }
53+ if (builder .mutableContent ) {
54+ fields .put ("mutable-content" , 1 );
55+ }
56+ if (builder .category != null ) {
57+ fields .put ("category" , builder .category );
58+ }
59+ if (builder .threadId != null ) {
60+ fields .put ("thread-id" , builder .threadId );
61+ }
62+ fields .putAll (builder .customData );
63+ this .fields = fields .build ();
64+ }
65+
66+ Map <String , Object > getFields () {
67+ return this .fields ;
6168 }
6269
6370 /**
@@ -76,8 +83,10 @@ public static class Builder {
7683 private Integer badge ;
7784 private String sound ;
7885 private boolean contentAvailable ;
86+ private boolean mutableContent ;
7987 private String category ;
8088 private String threadId ;
89+ private final Map <String , Object > customData = new HashMap <>();
8190
8291 private Builder () {}
8392
@@ -137,6 +146,41 @@ public Builder setContentAvailable(boolean contentAvailable) {
137146 return this ;
138147 }
139148
149+ /**
150+ * Specifies whether to set the {@code mutable-content} property on the message, so the
151+ * clients can modify the notification via app extensions.
152+ *
153+ * @param mutableContent True to make the content mutable via app extensions.
154+ * @return This builder.
155+ */
156+ public Builder setMutableContent (boolean mutableContent ) {
157+ this .mutableContent = mutableContent ;
158+ return this ;
159+ }
160+
161+ /**
162+ * Puts a custom key-value pair to the aps dictionary.
163+ *
164+ * @param key A non-null key.
165+ * @param value A non-null, json-serializable value.
166+ * @return This builder.
167+ */
168+ public Builder putCustomData (@ NonNull String key , @ NonNull Object value ) {
169+ this .customData .put (key , value );
170+ return this ;
171+ }
172+
173+ /**
174+ * Puts all the key-value pairs in the specified map to the aps dictionary.
175+ *
176+ * @param fields A non-null map. Map must not contain null keys or values.
177+ * @return This builder.
178+ */
179+ public Builder putAllCustomData (@ NonNull Map <String , Object > fields ) {
180+ this .customData .putAll (fields );
181+ return this ;
182+ }
183+
140184 /**
141185 * Sets the notification type.
142186 *
@@ -159,6 +203,13 @@ public Builder setThreadId(String threadId) {
159203 return this ;
160204 }
161205
206+ /**
207+ * Builds a new {@link Aps} instance from the fields set on this builder.
208+ *
209+ * @return A non-null {@link Aps}.
210+ * @throws IllegalArgumentException If the alert is specified both as an object and a string.
211+ * Or if the same field is set both using a setter method, and as a custom field.
212+ */
162213 public Aps build () {
163214 return new Aps (this );
164215 }
0 commit comments