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
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
85        public void addAction(NotificationCompatBase.Action action) {
86            NotificationCompatApi20.addAction(b, action);
87        }
88
89        @Override
90        public Notification.Builder getBuilder() {
91            return b;
92        }
93
94        public Notification build() {
95            b.setExtras(mExtras);
96            return b.build();
97        }
98    }
99
100    public static void addAction(Notification.Builder b, NotificationCompatBase.Action action) {
101        Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
102                action.getIcon(), action.getTitle(), action.getActionIntent());
103        if (action.getRemoteInputs() != null) {
104            for (RemoteInput remoteInput : RemoteInputCompatApi20.fromCompat(
105                    action.getRemoteInputs())) {
106                actionBuilder.addRemoteInput(remoteInput);
107            }
108        }
109        if (action.getExtras() != null) {
110            actionBuilder.addExtras(action.getExtras());
111        }
112        b.addAction(actionBuilder.build());
113    }
114
115    public static NotificationCompatBase.Action getAction(Notification notif,
116            int actionIndex, NotificationCompatBase.Action.Factory actionFactory,
117            RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
118        return getActionCompatFromAction(notif.actions[actionIndex], actionFactory, remoteInputFactory);
119    }
120
121    private static NotificationCompatBase.Action getActionCompatFromAction(
122            Notification.Action action, NotificationCompatBase.Action.Factory actionFactory,
123            RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
124        RemoteInputCompatBase.RemoteInput[] remoteInputs = RemoteInputCompatApi20.toCompat(
125                action.getRemoteInputs(), remoteInputFactory);
126        return actionFactory.build(action.icon, action.title, action.actionIntent,
127                action.getExtras(), remoteInputs);
128    }
129
130    private static Notification.Action getActionFromActionCompat(
131            NotificationCompatBase.Action actionCompat) {
132        Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
133                actionCompat.getIcon(), actionCompat.getTitle(), actionCompat.getActionIntent())
134                .addExtras(actionCompat.getExtras());
135        RemoteInputCompatBase.RemoteInput[] remoteInputCompats = actionCompat.getRemoteInputs();
136        if (remoteInputCompats != null) {
137            RemoteInput[] remoteInputs = RemoteInputCompatApi20.fromCompat(remoteInputCompats);
138            for (RemoteInput remoteInput : remoteInputs) {
139                actionBuilder.addRemoteInput(remoteInput);
140            }
141        }
142        return actionBuilder.build();
143    }
144
145    /**
146     * Get a list of notification compat actions by parsing actions stored within a list of
147     * parcelables using the {@link Bundle#getParcelableArrayList} function in the same
148     * manner that framework code would do so. In API20, Using Action parcelable directly
149     * is correct.
150     */
151    public static NotificationCompatBase.Action[] getActionsFromParcelableArrayList(
152            ArrayList<Parcelable> parcelables,
153            NotificationCompatBase.Action.Factory actionFactory,
154            RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
155        if (parcelables == null) {
156            return null;
157        }
158        NotificationCompatBase.Action[] actions = actionFactory.newArray(parcelables.size());
159        for (int i = 0; i < actions.length; i++) {
160            Notification.Action action = (Notification.Action) parcelables.get(i);
161            actions[i] = getActionCompatFromAction(action, actionFactory, remoteInputFactory);
162        }
163        return actions;
164    }
165
166    /**
167     * Get an array list of parcelables, suitable for {@link Bundle#putParcelableArrayList},
168     * that matches what framework code would do to store an actions list in this way. In API20,
169     * action parcelables were directly placed as entries in the array list.
170     */
171    public static ArrayList<Parcelable> getParcelableArrayListForActions(
172            NotificationCompatBase.Action[] actions) {
173        if (actions == null) {
174            return null;
175        }
176        ArrayList<Parcelable> parcelables = new ArrayList<Parcelable>(actions.length);
177        for (NotificationCompatBase.Action action : actions) {
178            parcelables.add(getActionFromActionCompat(action));
179        }
180        return parcelables;
181    }
182
183    public static boolean getLocalOnly(Notification notif) {
184        return (notif.flags & Notification.FLAG_LOCAL_ONLY) != 0;
185    }
186
187    public static String getGroup(Notification notif) {
188        return notif.getGroup();
189    }
190
191    public static boolean isGroupSummary(Notification notif) {
192        return (notif.flags & Notification.FLAG_GROUP_SUMMARY) != 0;
193    }
194
195    public static String getSortKey(Notification notif) {
196        return notif.getSortKey();
197    }
198}
199