Home | History | Annotate | Download | only in app
      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      */
     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      */
     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
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    312     public long getRunningTime() {
    313         return mRunLength;
    314     }
    315 }
    316