1 /*
2  * Copyright (C) 2014 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 android.support.v4.app;
18 
19 import android.app.Notification;
20 import android.app.PendingIntent;
21 import android.app.RemoteInput;
22 import android.content.Context;
23 import android.graphics.Bitmap;
24 import android.os.Bundle;
25 import android.os.Parcelable;
26 import android.widget.RemoteViews;
27 
28 import java.util.ArrayList;
29 
30 class NotificationCompatApi20 {
31     public static class Builder implements NotificationBuilderWithBuilderAccessor,
32             NotificationBuilderWithActions {
33         private Notification.Builder b;
34         private Bundle mExtras;
35 
Builder(Context context, Notification n, CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo, RemoteViews tickerView, int number, PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon, int progressMax, int progress, boolean progressIndeterminate, boolean showWhen, boolean useChronometer, int priority, CharSequence subText, boolean localOnly, ArrayList<String> people, Bundle extras, String groupKey, boolean groupSummary, String sortKey)36         public Builder(Context context, Notification n,
37                 CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
38                 RemoteViews tickerView, int number,
39                 PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon,
40                 int progressMax, int progress, boolean progressIndeterminate, boolean showWhen,
41                 boolean useChronometer, int priority, CharSequence subText, boolean localOnly,
42                 ArrayList<String> people, Bundle extras, String groupKey, boolean groupSummary,
43                 String sortKey) {
44             b = new Notification.Builder(context)
45                 .setWhen(n.when)
46                 .setShowWhen(showWhen)
47                 .setSmallIcon(n.icon, n.iconLevel)
48                 .setContent(n.contentView)
49                 .setTicker(n.tickerText, tickerView)
50                 .setSound(n.sound, n.audioStreamType)
51                 .setVibrate(n.vibrate)
52                 .setLights(n.ledARGB, n.ledOnMS, n.ledOffMS)
53                 .setOngoing((n.flags & Notification.FLAG_ONGOING_EVENT) != 0)
54                 .setOnlyAlertOnce((n.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)
55                 .setAutoCancel((n.flags & Notification.FLAG_AUTO_CANCEL) != 0)
56                 .setDefaults(n.defaults)
57                 .setContentTitle(contentTitle)
58                 .setContentText(contentText)
59                 .setSubText(subText)
60                 .setContentInfo(contentInfo)
61                 .setContentIntent(contentIntent)
62                 .setDeleteIntent(n.deleteIntent)
63                 .setFullScreenIntent(fullScreenIntent,
64                         (n.flags & Notification.FLAG_HIGH_PRIORITY) != 0)
65                 .setLargeIcon(largeIcon)
66                 .setNumber(number)
67                 .setUsesChronometer(useChronometer)
68                 .setPriority(priority)
69                 .setProgress(progressMax, progress, progressIndeterminate)
70                 .setLocalOnly(localOnly)
71                 .setGroup(groupKey)
72                 .setGroupSummary(groupSummary)
73                 .setSortKey(sortKey);
74             mExtras = new Bundle();
75             if (extras != null) {
76                 mExtras.putAll(extras);
77             }
78             if (people != null && !people.isEmpty()) {
79                 mExtras.putStringArray(Notification.EXTRA_PEOPLE,
80                         people.toArray(new String[people.size()]));
81             }
82         }
83 
84         @Override
addAction(NotificationCompatBase.Action action)85         public void addAction(NotificationCompatBase.Action action) {
86             NotificationCompatApi20.addAction(b, action);
87         }
88 
89         @Override
getBuilder()90         public Notification.Builder getBuilder() {
91             return b;
92         }
93 
94         @Override
build()95         public Notification build() {
96             b.setExtras(mExtras);
97             return b.build();
98         }
99     }
100 
addAction(Notification.Builder b, NotificationCompatBase.Action action)101     public static void addAction(Notification.Builder b, NotificationCompatBase.Action action) {
102         Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
103                 action.getIcon(), action.getTitle(), action.getActionIntent());
104         if (action.getRemoteInputs() != null) {
105             for (RemoteInput remoteInput : RemoteInputCompatApi20.fromCompat(
106                     action.getRemoteInputs())) {
107                 actionBuilder.addRemoteInput(remoteInput);
108             }
109         }
110         if (action.getExtras() != null) {
111             actionBuilder.addExtras(action.getExtras());
112         }
113         b.addAction(actionBuilder.build());
114     }
115 
getAction(Notification notif, int actionIndex, NotificationCompatBase.Action.Factory actionFactory, RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory)116     public static NotificationCompatBase.Action getAction(Notification notif,
117             int actionIndex, NotificationCompatBase.Action.Factory actionFactory,
118             RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
119         return getActionCompatFromAction(notif.actions[actionIndex], actionFactory, remoteInputFactory);
120     }
121 
getActionCompatFromAction( Notification.Action action, NotificationCompatBase.Action.Factory actionFactory, RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory)122     private static NotificationCompatBase.Action getActionCompatFromAction(
123             Notification.Action action, NotificationCompatBase.Action.Factory actionFactory,
124             RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
125         RemoteInputCompatBase.RemoteInput[] remoteInputs = RemoteInputCompatApi20.toCompat(
126                 action.getRemoteInputs(), remoteInputFactory);
127         return actionFactory.build(action.icon, action.title, action.actionIntent,
128                 action.getExtras(), remoteInputs);
129     }
130 
getActionFromActionCompat( NotificationCompatBase.Action actionCompat)131     private static Notification.Action getActionFromActionCompat(
132             NotificationCompatBase.Action actionCompat) {
133         Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
134                 actionCompat.getIcon(), actionCompat.getTitle(), actionCompat.getActionIntent())
135                 .addExtras(actionCompat.getExtras());
136         RemoteInputCompatBase.RemoteInput[] remoteInputCompats = actionCompat.getRemoteInputs();
137         if (remoteInputCompats != null) {
138             RemoteInput[] remoteInputs = RemoteInputCompatApi20.fromCompat(remoteInputCompats);
139             for (RemoteInput remoteInput : remoteInputs) {
140                 actionBuilder.addRemoteInput(remoteInput);
141             }
142         }
143         return actionBuilder.build();
144     }
145 
146     /**
147      * Get a list of notification compat actions by parsing actions stored within a list of
148      * parcelables using the {@link Bundle#getParcelableArrayList} function in the same
149      * manner that framework code would do so. In API20, Using Action parcelable directly
150      * is correct.
151      */
getActionsFromParcelableArrayList( ArrayList<Parcelable> parcelables, NotificationCompatBase.Action.Factory actionFactory, RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory)152     public static NotificationCompatBase.Action[] getActionsFromParcelableArrayList(
153             ArrayList<Parcelable> parcelables,
154             NotificationCompatBase.Action.Factory actionFactory,
155             RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
156         if (parcelables == null) {
157             return null;
158         }
159         NotificationCompatBase.Action[] actions = actionFactory.newArray(parcelables.size());
160         for (int i = 0; i < actions.length; i++) {
161             Notification.Action action = (Notification.Action) parcelables.get(i);
162             actions[i] = getActionCompatFromAction(action, actionFactory, remoteInputFactory);
163         }
164         return actions;
165     }
166 
167     /**
168      * Get an array list of parcelables, suitable for {@link Bundle#putParcelableArrayList},
169      * that matches what framework code would do to store an actions list in this way. In API20,
170      * action parcelables were directly placed as entries in the array list.
171      */
getParcelableArrayListForActions( NotificationCompatBase.Action[] actions)172     public static ArrayList<Parcelable> getParcelableArrayListForActions(
173             NotificationCompatBase.Action[] actions) {
174         if (actions == null) {
175             return null;
176         }
177         ArrayList<Parcelable> parcelables = new ArrayList<Parcelable>(actions.length);
178         for (NotificationCompatBase.Action action : actions) {
179             parcelables.add(getActionFromActionCompat(action));
180         }
181         return parcelables;
182     }
183 
getLocalOnly(Notification notif)184     public static boolean getLocalOnly(Notification notif) {
185         return (notif.flags & Notification.FLAG_LOCAL_ONLY) != 0;
186     }
187 
getGroup(Notification notif)188     public static String getGroup(Notification notif) {
189         return notif.getGroup();
190     }
191 
isGroupSummary(Notification notif)192     public static boolean isGroupSummary(Notification notif) {
193         return (notif.flags & Notification.FLAG_GROUP_SUMMARY) != 0;
194     }
195 
getSortKey(Notification notif)196     public static String getSortKey(Notification notif) {
197         return notif.getSortKey();
198     }
199 }
200