Home | History | Annotate | Download | only in notification
      1 /*
      2  * Copyright (C) 2017 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 com.android.launcher3.notification;
     18 
     19 import android.app.ActivityOptions;
     20 import android.app.Notification;
     21 import android.app.PendingIntent;
     22 import android.content.Context;
     23 import android.graphics.drawable.BitmapDrawable;
     24 import android.graphics.drawable.Drawable;
     25 import android.graphics.drawable.Icon;
     26 import android.os.Bundle;
     27 import android.service.notification.StatusBarNotification;
     28 import android.view.View;
     29 
     30 import com.android.launcher3.Launcher;
     31 import com.android.launcher3.LauncherAppState;
     32 import com.android.launcher3.graphics.IconPalette;
     33 import com.android.launcher3.popup.PopupContainerWithArrow;
     34 import com.android.launcher3.util.PackageUserKey;
     35 
     36 /**
     37  * An object that contains relevant information from a {@link StatusBarNotification}. This should
     38  * only be created when we need to show the notification contents on the UI; until then, a
     39  * {@link com.android.launcher3.badge.BadgeInfo} with only the notification key should
     40  * be passed around, and then this can be constructed using the StatusBarNotification from
     41  * {@link NotificationListener#getNotificationsForKeys(java.util.List)}.
     42  */
     43 public class NotificationInfo implements View.OnClickListener {
     44 
     45     public final PackageUserKey packageUserKey;
     46     public final String notificationKey;
     47     public final CharSequence title;
     48     public final CharSequence text;
     49     public final PendingIntent intent;
     50     public final boolean autoCancel;
     51     public final boolean dismissable;
     52 
     53     private int mBadgeIcon;
     54     private Drawable mIconDrawable;
     55     private int mIconColor;
     56     private boolean mIsIconLarge;
     57 
     58     /**
     59      * Extracts the data that we need from the StatusBarNotification.
     60      */
     61     public NotificationInfo(Context context, StatusBarNotification statusBarNotification) {
     62         packageUserKey = PackageUserKey.fromNotification(statusBarNotification);
     63         notificationKey = statusBarNotification.getKey();
     64         Notification notification = statusBarNotification.getNotification();
     65         title = notification.extras.getCharSequence(Notification.EXTRA_TITLE);
     66         text = notification.extras.getCharSequence(Notification.EXTRA_TEXT);
     67 
     68         mBadgeIcon = notification.getBadgeIconType();
     69         // Load the icon. Since it is backed by ashmem, we won't copy the entire bitmap
     70         // into our process as long as we don't touch it and it exists in systemui.
     71         Icon icon = mBadgeIcon == Notification.BADGE_ICON_SMALL ? null : notification.getLargeIcon();
     72         if (icon == null) {
     73             // Use the small icon.
     74             icon = notification.getSmallIcon();
     75             mIconDrawable = icon.loadDrawable(context);
     76             mIconColor = statusBarNotification.getNotification().color;
     77             mIsIconLarge = false;
     78         } else {
     79             // Use the large icon.
     80             mIconDrawable = icon.loadDrawable(context);
     81             mIsIconLarge = true;
     82         }
     83         if (mIconDrawable == null) {
     84             mIconDrawable = new BitmapDrawable(context.getResources(), LauncherAppState
     85                     .getInstance(context).getIconCache()
     86                     .getDefaultIcon(statusBarNotification.getUser()));
     87             mBadgeIcon = Notification.BADGE_ICON_NONE;
     88         }
     89         intent = notification.contentIntent;
     90         autoCancel = (notification.flags & Notification.FLAG_AUTO_CANCEL) != 0;
     91         dismissable = (notification.flags & Notification.FLAG_ONGOING_EVENT) == 0;
     92     }
     93 
     94     @Override
     95     public void onClick(View view) {
     96         final Launcher launcher = Launcher.getLauncher(view.getContext());
     97         Bundle activityOptions = ActivityOptions.makeClipRevealAnimation(
     98                 view, 0, 0, view.getWidth(), view.getHeight()).toBundle();
     99         try {
    100             intent.send(null, 0, null, null, null, null, activityOptions);
    101             launcher.getUserEventDispatcher().logNotificationLaunch(view, intent);
    102         } catch (PendingIntent.CanceledException e) {
    103             e.printStackTrace();
    104         }
    105         if (autoCancel) {
    106             launcher.getPopupDataProvider().cancelNotification(notificationKey);
    107         }
    108         PopupContainerWithArrow.getOpen(launcher).close(true);
    109     }
    110 
    111     public Drawable getIconForBackground(Context context, int background) {
    112         if (mIsIconLarge) {
    113             // Only small icons should be tinted.
    114             return mIconDrawable;
    115         }
    116         mIconColor = IconPalette.resolveContrastColor(context, mIconColor, background);
    117         Drawable icon = mIconDrawable.mutate();
    118         // DrawableContainer ignores the color filter if it's already set, so clear it first to
    119         // get it set and invalidated properly.
    120         icon.setTintList(null);
    121         icon.setTint(mIconColor);
    122         return icon;
    123     }
    124 
    125     public boolean isIconLarge() {
    126         return mIsIconLarge;
    127     }
    128 
    129     public boolean shouldShowIconInBadge() {
    130         // If the icon we're using for this notification matches what the Notification
    131         // specified should show in the badge, then return true.
    132         return mIsIconLarge && mBadgeIcon == Notification.BADGE_ICON_LARGE
    133                 || !mIsIconLarge && mBadgeIcon == Notification.BADGE_ICON_SMALL;
    134     }
    135 }
    136