• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.recommendation.app;
18 
19 import android.app.Notification;
20 import android.os.Bundle;
21 
22 /**
23  * <p>
24  * Helper class to add content info extensions to notifications. To create a notification with
25  * content info extensions:
26  * <ol>
27  * <li>Create an {@link Notification.Builder}, setting any desired properties.
28  * <li>Create a {@link RecommendationExtender}.
29  * <li>Set content info specific properties using the {@code add} and {@code set} methods of
30  * {@link RecommendationExtender}.
31  * <li>Call {@link android.app.Notification.Builder#extend(Notification.Extender)
32  * Notification.Builder.extend(Notification.Extender)} to apply the extensions to a notification.
33  * </ol>
34  *
35  * <pre class="prettyprint">Notification notification = new Notification.Builder(context) * ... * .extend(new RecommendationExtender() * .set*(...)) * .build(); * </pre>
36  * <p>
37  * Content info extensions can be accessed on an existing notification by using the
38  * {@code RecommendationExtender(Notification)} constructor, and then using the {@code get} methods
39  * to access values.
40  */
41 public final class RecommendationExtender implements Notification.Extender {
42     private static final String TAG = "RecommendationExtender";
43 
44     // Key for the Content info extensions bundle in the main Notification extras bundle
45     private static final String EXTRA_CONTENT_INFO_EXTENDER = "android.CONTENT_INFO_EXTENSIONS";
46 
47     // Keys within EXTRA_CONTENT_INFO_EXTENDER for individual content info options.
48 
49     private static final String KEY_CONTENT_TYPE = "android.contentType";
50 
51     private static final String KEY_CONTENT_GENRES = "android.contentGenre";
52 
53     private static final String KEY_CONTENT_PRICING_TYPE = "android.contentPricing.type";
54 
55     private static final String KEY_CONTENT_PRICING_VALUE = "android.contentPricing.value";
56 
57     private static final String KEY_CONTENT_STATUS = "android.contentStatus";
58 
59     private static final String KEY_CONTENT_MATURITY_RATING = "android.contentMaturity";
60 
61     private static final String KEY_CONTENT_RUN_LENGTH = "android.contentLength";
62 
63     private String[] mTypes;
64     private String[] mGenres;
65     private String mPricingType;
66     private String mPricingValue;
67     private int mContentStatus = -1;
68     private String mMaturityRating;
69     private long mRunLength = -1;
70 
71     /**
72      * Create a {@link RecommendationExtender} with default options.
73      */
RecommendationExtender()74     public RecommendationExtender() {
75     }
76 
77     /**
78      * Create a {@link RecommendationExtender} from the RecommendationExtender options of an
79      * existing Notification.
80      *
81      * @param notif The notification from which to copy options.
82      */
RecommendationExtender(Notification notif)83     public RecommendationExtender(Notification notif) {
84         Bundle contentBundle = notif.extras == null ?
85                 null : notif.extras.getBundle(EXTRA_CONTENT_INFO_EXTENDER);
86         if (contentBundle != null) {
87             mTypes = contentBundle.getStringArray(KEY_CONTENT_TYPE);
88             mGenres = contentBundle.getStringArray(KEY_CONTENT_GENRES);
89             mPricingType = contentBundle.getString(KEY_CONTENT_PRICING_TYPE);
90             mPricingValue = contentBundle.getString(KEY_CONTENT_PRICING_VALUE);
91             mContentStatus = contentBundle.getInt(KEY_CONTENT_STATUS, -1);
92             mMaturityRating = contentBundle.getString(KEY_CONTENT_MATURITY_RATING);
93             mRunLength = contentBundle.getLong(KEY_CONTENT_RUN_LENGTH, -1);
94         }
95     }
96 
97     /**
98      * Apply content extensions to a notification that is being built. This is typically called by
99      * the {@link android.app.Notification.Builder#extend(Notification.Extender)
100      * Notification.Builder.extend(Notification.Extender)} method of {@link Notification.Builder}.
101      */
102     @Override
extend(Notification.Builder builder)103     public Notification.Builder extend(Notification.Builder builder) {
104         Bundle contentBundle = new Bundle();
105 
106         if (mTypes != null) {
107             contentBundle.putStringArray(KEY_CONTENT_TYPE, mTypes);
108         }
109         if (mGenres != null) {
110             contentBundle.putStringArray(KEY_CONTENT_GENRES, mGenres);
111         }
112         if (mPricingType != null) {
113             contentBundle.putString(KEY_CONTENT_PRICING_TYPE, mPricingType);
114         }
115         if (mPricingValue != null) {
116             contentBundle.putString(KEY_CONTENT_PRICING_VALUE, mPricingValue);
117         }
118         if (mContentStatus != -1) {
119             contentBundle.putInt(KEY_CONTENT_STATUS, mContentStatus);
120         }
121         if (mMaturityRating != null) {
122             contentBundle.putString(KEY_CONTENT_MATURITY_RATING, mMaturityRating);
123         }
124         if (mRunLength > 0) {
125             contentBundle.putLong(KEY_CONTENT_RUN_LENGTH, mRunLength);
126         }
127 
128         builder.getExtras().putBundle(EXTRA_CONTENT_INFO_EXTENDER, contentBundle);
129         return builder;
130     }
131 
132     /**
133      * Sets the content types associated with the notification content. The first tag entry will be
134      * considered the primary type for the content and will be used for ranking purposes. Other
135      * secondary type tags may be provided, if applicable, and may be used for filtering purposes.
136      *
137      * @param types Array of predefined type tags (see the <code>CONTENT_TYPE_*</code> constants)
138      *            that describe the content referred to by a notification.
139      */
setContentTypes(String[] types)140     public RecommendationExtender setContentTypes(String[] types) {
141         mTypes = types;
142         return this;
143     }
144 
145     /**
146      * Returns an array containing the content types that describe the content associated with the
147      * notification. The first tag entry is considered the primary type for the content, and is used
148      * for content ranking purposes.
149      *
150      * @return An array of predefined type tags (see the <code>CONTENT_TYPE_*</code> constants) that
151      *         describe the content associated with the notification.
152      * @see RecommendationExtender#setContentTypes
153      */
getContentTypes()154     public String[] getContentTypes() {
155         return mTypes;
156     }
157 
158     /**
159      * Returns the primary content type tag for the content associated with the notification.
160      *
161      * @return A predefined type tag (see the <code>CONTENT_TYPE_*</code> constants) indicating the
162      *         primary type for the content associated with the notification.
163      * @see RecommendationExtender#setContentTypes
164      */
getPrimaryContentType()165     public String getPrimaryContentType() {
166         if (mTypes == null || mTypes.length == 0) {
167             return null;
168         }
169         return mTypes[0];
170     }
171 
172     /**
173      * Sets the content genres associated with the notification content. These genres may be used
174      * for content ranking. Genres are open ended String tags.
175      * <p>
176      * Some examples: "comedy", "action", "dance", "electronica", "racing", etc.
177      *
178      * @param genres Array of genre string tags that describe the content referred to by a
179      *            notification.
180      */
setGenres(String[] genres)181     public RecommendationExtender setGenres(String[] genres) {
182         mGenres = genres;
183         return this;
184     }
185 
186     /**
187      * Returns an array containing the content genres that describe the content associated with the
188      * notification.
189      *
190      * @return An array of genre tags that describe the content associated with the notification.
191      * @see RecommendationExtender#setGenres
192      */
getGenres()193     public String[] getGenres() {
194         return mGenres;
195     }
196 
197     /**
198      * Sets the pricing and availability information for the content associated with the
199      * notification. The provided information will indicate the access model for the content (free,
200      * rental, purchase or subscription) and the price value (if not free).
201      *
202      * @param priceType Pricing type for this content. Must be one of the predefined pricing type
203      *            tags (see the <code>CONTENT_PRICING_*</code> constants).
204      * @param priceValue A string containing a representation of the content price in the current
205      *            locale and currency.
206      * @return This object for method chaining.
207      */
setPricingInformation( @ontentRecommendation.ContentPricing String priceType, String priceValue)208     public RecommendationExtender setPricingInformation(
209             @ContentRecommendation.ContentPricing String priceType, String priceValue) {
210         mPricingType = priceType;
211         mPricingValue = priceValue;
212         return this;
213     }
214 
215     /**
216      * Gets the pricing type for the content associated with the notification.
217      *
218      * @return A predefined tag indicating the pricing type for the content (see the <code> CONTENT_PRICING_*</code>
219      *         constants).
220      * @see RecommendationExtender#setPricingInformation
221      */
getPricingType()222     public String getPricingType() {
223         return mPricingType;
224     }
225 
226     /**
227      * Gets the price value (when applicable) for the content associated with a notification. The
228      * value will be provided as a String containing the price in the appropriate currency for the
229      * current locale.
230      *
231      * @return A string containing a representation of the content price in the current locale and
232      *         currency.
233      * @see RecommendationExtender#setPricingInformation
234      */
getPricingValue()235     public String getPricingValue() {
236         if (mPricingType == null) {
237             return null;
238         }
239         return mPricingValue;
240     }
241 
242     /**
243      * Sets the availability status for the content associated with the notification. This status
244      * indicates whether the referred content is ready to be consumed on the device, or if the user
245      * must first purchase, rent, subscribe to, or download the content.
246      *
247      * @param contentStatus The status value for this content. Must be one of the predefined content
248      *            status values (see the <code>CONTENT_STATUS_*</code> constants).
249      */
setStatus( @ontentRecommendation.ContentStatus int contentStatus)250     public RecommendationExtender setStatus(
251             @ContentRecommendation.ContentStatus int contentStatus) {
252         mContentStatus = contentStatus;
253         return this;
254     }
255 
256     /**
257      * Returns status value for the content associated with the notification. This status indicates
258      * whether the referred content is ready to be consumed on the device, or if the user must first
259      * purchase, rent, subscribe to, or download the content.
260      *
261      * @return The status value for this content, or -1 is a valid status has not been specified
262      *         (see the <code>CONTENT_STATUS_*</code> for the defined valid status values).
263      * @see RecommendationExtender#setStatus
264      */
getStatus()265     public int getStatus() {
266         return mContentStatus;
267     }
268 
269     /**
270      * Sets the maturity level rating for the content associated with the notification.
271      *
272      * @param maturityRating A tag indicating the maturity level rating for the content. This tag
273      *            must be one of the predefined maturity rating tags (see the <code> CONTENT_MATURITY_*</code>
274      *            constants).
275      */
setMaturityRating( @ontentRecommendation.ContentMaturity String maturityRating)276     public RecommendationExtender setMaturityRating(
277             @ContentRecommendation.ContentMaturity String maturityRating) {
278         mMaturityRating = maturityRating;
279         return this;
280     }
281 
282     /**
283      * Returns the maturity level rating for the content associated with the notification.
284      *
285      * @return returns a predefined tag indicating the maturity level rating for the content (see
286      *         the <code>CONTENT_MATURITY_*</code> constants).
287      * @see RecommendationExtender#setMaturityRating
288      */
getMaturityRating()289     public String getMaturityRating() {
290         return mMaturityRating;
291     }
292 
293     /**
294      * Sets the running time (when applicable) for the content associated with the notification.
295      *
296      * @param length The runing time, in seconds, of the content associated with the notification.
297      */
setRunningTime(long length)298     public RecommendationExtender setRunningTime(long length) {
299         if (length < 0) {
300             throw new IllegalArgumentException("Invalid value for Running Time");
301         }
302         mRunLength = length;
303         return this;
304     }
305 
306     /**
307      * Returns the running time for the content associated with the notification.
308      *
309      * @return The running time, in seconds, of the content associated with the notification.
310      * @see RecommendationExtender#setRunningTime
311      */
getRunningTime()312     public long getRunningTime() {
313         return mRunLength;
314     }
315 }
316