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