NotificationCompatApi20.java revision 2bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7
1b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen/*
2b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen * Copyright (C) 2014 The Android Open Source Project
3b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen *
4b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen * Licensed under the Apache License, Version 2.0 (the "License");
5b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen * you may not use this file except in compliance with the License.
6b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen * You may obtain a copy of the License at
7b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen *
8b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen *      http://www.apache.org/licenses/LICENSE-2.0
9b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen *
10b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen * Unless required by applicable law or agreed to in writing, software
11b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen * distributed under the License is distributed on an "AS IS" BASIS,
12b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen * See the License for the specific language governing permissions and
14b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen * limitations under the License.
15b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen */
16b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen
17b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazenpackage android.support.v4.app;
18b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen
19b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazenimport android.app.Notification;
20b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazenimport android.app.PendingIntent;
21ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazenimport android.app.RemoteInput;
22b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazenimport android.content.Context;
23b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazenimport android.graphics.Bitmap;
24b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazenimport android.os.Bundle;
252bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazenimport android.os.Parcelable;
26b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazenimport android.widget.RemoteViews;
27b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen
282bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazenimport java.util.ArrayList;
292bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen
30b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazenclass NotificationCompatApi20 {
31b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen    public static class Builder implements NotificationBuilderWithBuilderAccessor,
32b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen            NotificationBuilderWithActions {
33b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        private Notification.Builder b;
34b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen
35b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        public Builder(Context context, Notification n,
36b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
37b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                RemoteViews tickerView, int number,
38b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon,
39b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                int mProgressMax, int mProgress, boolean mProgressIndeterminate,
40ab78e9b2a147c8de7b5cf231b97aad9d8c4f106cGriff Hazen                boolean useChronometer, int priority, CharSequence subText, boolean localOnly,
41ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                Bundle extras, String groupKey, boolean groupSummary, String sortKey) {
42b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen            b = new Notification.Builder(context)
43b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setWhen(n.when)
44b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setSmallIcon(n.icon, n.iconLevel)
45b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setContent(n.contentView)
46b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setTicker(n.tickerText, tickerView)
47b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setSound(n.sound, n.audioStreamType)
48b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setVibrate(n.vibrate)
49b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setLights(n.ledARGB, n.ledOnMS, n.ledOffMS)
50b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setOngoing((n.flags & Notification.FLAG_ONGOING_EVENT) != 0)
51b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setOnlyAlertOnce((n.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)
52b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setAutoCancel((n.flags & Notification.FLAG_AUTO_CANCEL) != 0)
53b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setDefaults(n.defaults)
54b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setContentTitle(contentTitle)
55b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setContentText(contentText)
56b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setSubText(subText)
57b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setContentInfo(contentInfo)
58b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setContentIntent(contentIntent)
59b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setDeleteIntent(n.deleteIntent)
60b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setFullScreenIntent(fullScreenIntent,
61b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                        (n.flags & Notification.FLAG_HIGH_PRIORITY) != 0)
62b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setLargeIcon(largeIcon)
63b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setNumber(number)
64b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setUsesChronometer(useChronometer)
65b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setPriority(priority)
66b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen                .setProgress(mProgressMax, mProgress, mProgressIndeterminate)
67ab78e9b2a147c8de7b5cf231b97aad9d8c4f106cGriff Hazen                .setLocalOnly(localOnly)
68ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                .setExtras(extras)
69ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                .setGroup(groupKey)
70ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                .setGroupSummary(groupSummary)
71ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                .setSortKey(sortKey);
72b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        }
73b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen
74b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        @Override
75ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen        public void addAction(NotificationCompatBase.Action action) {
76300ad7c234a0ccfc41ae7fdbdcdd57faece2a8e0Griff Hazen            Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
77ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                    action.getIcon(), action.getTitle(), action.getActionIntent());
78ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen            if (action.getRemoteInputs() != null) {
79ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                for (RemoteInput remoteInput : RemoteInputCompatApi20.fromCompat(
80ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                        action.getRemoteInputs())) {
81ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                    actionBuilder.addRemoteInput(remoteInput);
82ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                }
83ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen            }
84ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen            if (action.getExtras() != null) {
85ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                actionBuilder.addExtras(action.getExtras());
86300ad7c234a0ccfc41ae7fdbdcdd57faece2a8e0Griff Hazen            }
87300ad7c234a0ccfc41ae7fdbdcdd57faece2a8e0Griff Hazen            b.addAction(actionBuilder.build());
88b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        }
89b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen
90b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        @Override
91b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        public Notification.Builder getBuilder() {
92b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen            return b;
93b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        }
94b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen
95b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        public Notification build() {
96b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen            return b.build();
97b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        }
98b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen    }
99b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen
100ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen    public static NotificationCompatBase.Action getAction(Notification notif,
1012bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            int actionIndex, NotificationCompatBase.Action.Factory actionFactory,
1022bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
1032bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        return getActionCompatFromAction(notif.actions[actionIndex], actionFactory, remoteInputFactory);
1042bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    }
1052bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen
1062bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    private static NotificationCompatBase.Action getActionCompatFromAction(
1072bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            Notification.Action action, NotificationCompatBase.Action.Factory actionFactory,
108ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen            RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
109ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen        RemoteInputCompatBase.RemoteInput[] remoteInputs = RemoteInputCompatApi20.toCompat(
110ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                action.getRemoteInputs(), remoteInputFactory);
1112bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        return actionFactory.build(action.icon, action.title, action.actionIntent,
112ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen                action.getExtras(), remoteInputs);
113300ad7c234a0ccfc41ae7fdbdcdd57faece2a8e0Griff Hazen    }
114300ad7c234a0ccfc41ae7fdbdcdd57faece2a8e0Griff Hazen
1152bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    private static Notification.Action getActionFromActionCompat(
1162bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            NotificationCompatBase.Action actionCompat) {
1172bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
1182bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen                actionCompat.getIcon(), actionCompat.getTitle(), actionCompat.getActionIntent())
1192bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen                .addExtras(actionCompat.getExtras());
1202bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        RemoteInputCompatBase.RemoteInput[] remoteInputCompats = actionCompat.getRemoteInputs();
1212bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        if (remoteInputCompats != null) {
1222bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            RemoteInput[] remoteInputs = RemoteInputCompatApi20.fromCompat(remoteInputCompats);
1232bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            for (RemoteInput remoteInput : remoteInputs) {
1242bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen                actionBuilder.addRemoteInput(remoteInput);
1252bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            }
1262bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        }
1272bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        return actionBuilder.build();
1282bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    }
1292bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen
1302bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    /**
1312bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen     * Get a list of notification compat actions by parsing actions stored within a list of
1322bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen     * parcelables using the {@link Bundle#getParcelableArrayList} function in the same
1332bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen     * manner that framework code would do so. In API20, Using Action parcelable directly
1342bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen     * is correct.
1352bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen     */
1362bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    public static NotificationCompatBase.Action[] getActionsFromParcelableArrayList(
1372bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            ArrayList<Parcelable> parcelables,
1382bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            NotificationCompatBase.Action.Factory actionFactory,
1392bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
1402bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        if (parcelables == null) {
1412bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            return null;
1422bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        }
1432bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        NotificationCompatBase.Action[] actions = actionFactory.newArray(parcelables.size());
1442bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        for (int i = 0; i < actions.length; i++) {
1452bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            Notification.Action action = (Notification.Action) parcelables.get(i);
1462bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            actions[i] = getActionCompatFromAction(action, actionFactory, remoteInputFactory);
1472bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        }
1482bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        return actions;
1492bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    }
1502bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen
1512bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    /**
1522bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen     * Get an array list of parcelables, suitable for {@link Bundle#putParcelableArrayList},
1532bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen     * that matches what framework code would do to store an actions list in this way. In API20,
1542bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen     * action parcelables were directly placed as entries in the array list.
1552bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen     */
1562bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    public static ArrayList<Parcelable> getParcelableArrayListForActions(
1572bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            NotificationCompatBase.Action[] actions) {
1582bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        if (actions == null) {
1592bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            return null;
1602bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        }
1612bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        ArrayList<Parcelable> parcelables = new ArrayList<Parcelable>(actions.length);
1622bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        for (NotificationCompatBase.Action action : actions) {
1632bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen            parcelables.add(getActionFromActionCompat(action));
1642bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        }
1652bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen        return parcelables;
1662bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen    }
1672bb98d48fdaf79a2bbd9d247da81a2bb9834dfc7Griff Hazen
168b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen    public static boolean getLocalOnly(Notification notif) {
169b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen        return (notif.flags & Notification.FLAG_LOCAL_ONLY) != 0;
170b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen    }
171ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen
172ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen    public static String getGroup(Notification notif) {
173ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen        return notif.getGroup();
174ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen    }
175ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen
176ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen    public static boolean isGroupSummary(Notification notif) {
177ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen        return (notif.flags & Notification.FLAG_GROUP_SUMMARY) != 0;
178ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen    }
179ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen
180ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen    public static String getSortKey(Notification notif) {
181ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen        return notif.getSortKey();
182ce16e4276c2f61109a23b3f6707cfcd87b07c735Griff Hazen    }
183b56de0d1a113c71a2808303009ab4d9708ed6e84Griff Hazen}
184