Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 1 | /** |
| 2 | * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr) |
Alexandre Lision | c1024c0 | 2014-01-06 11:12:53 -0500 | [diff] [blame] | 3 | * Copyright (C) 2004-2014 Savoir-Faire Linux Inc. |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 4 | * |
| 5 | * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com> |
| 6 | * Adrien BĂ©raud <adrien.beraud@gmail.com> |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 3 of the License, or |
| 11 | * (at your option) any later version. |
| 12 | * |
| 13 | * This program is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | * GNU General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU General Public License |
| 19 | * along with this program; if not, write to the Free Software |
| 20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 21 | * |
| 22 | * Additional permission under GNU GPL version 3 section 7: |
| 23 | * |
| 24 | * If you modify this program, or any covered work, by linking or |
| 25 | * combining it with the OpenSSL project's OpenSSL library (or a |
| 26 | * modified version of that library), containing parts covered by the |
| 27 | * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. |
| 28 | * grants you additional permission to convey the resulting work. |
| 29 | * Corresponding Source for a non-source form of such a combination |
| 30 | * shall include the source code for the parts of OpenSSL used as well |
| 31 | * as that of the covered work. |
| 32 | */ |
| 33 | |
| 34 | package org.sflphone.utils; |
| 35 | |
Alexandre Lision | f02190d | 2013-12-12 17:26:12 -0500 | [diff] [blame] | 36 | import java.util.HashMap; |
| 37 | import java.util.Random; |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 38 | |
Alexandre Lision | 81ef750 | 2013-12-11 17:29:49 -0500 | [diff] [blame] | 39 | import org.sflphone.R; |
| 40 | import org.sflphone.client.HomeActivity; |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 41 | import org.sflphone.model.SipCall; |
| 42 | |
| 43 | import android.app.Notification; |
| 44 | import android.app.NotificationManager; |
Alexandre Lision | 81ef750 | 2013-12-11 17:29:49 -0500 | [diff] [blame] | 45 | import android.app.PendingIntent; |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 46 | import android.content.Context; |
Alexandre Lision | 81ef750 | 2013-12-11 17:29:49 -0500 | [diff] [blame] | 47 | import android.content.Intent; |
| 48 | import android.graphics.BitmapFactory; |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 49 | import android.graphics.Typeface; |
| 50 | import android.net.sip.SipProfile; |
Alexandre Lision | 81ef750 | 2013-12-11 17:29:49 -0500 | [diff] [blame] | 51 | import android.support.v4.app.NotificationCompat; |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 52 | import android.support.v4.app.NotificationCompat.Builder; |
| 53 | import android.text.Spannable; |
| 54 | import android.text.SpannableString; |
| 55 | import android.text.TextUtils; |
| 56 | import android.text.style.StyleSpan; |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 57 | |
| 58 | public class SipNotifications { |
| 59 | |
| 60 | private final NotificationManager notificationManager; |
| 61 | private final Context context; |
Alexandre Lision | 81ef750 | 2013-12-11 17:29:49 -0500 | [diff] [blame] | 62 | |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 63 | public static final String NOTIF_CREATION = "notif_creation"; |
| 64 | public static final String NOTIF_DELETION = "notif_deletion"; |
| 65 | |
Alexandre Lision | f02190d | 2013-12-12 17:26:12 -0500 | [diff] [blame] | 66 | private final int NOTIFICATION_ID = new Random().nextInt(1000); |
| 67 | |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 68 | public static final int REGISTER_NOTIF_ID = 1; |
| 69 | public static final int CALL_NOTIF_ID = REGISTER_NOTIF_ID + 1; |
| 70 | public static final int CALLLOG_NOTIF_ID = REGISTER_NOTIF_ID + 2; |
| 71 | public static final int MESSAGE_NOTIF_ID = REGISTER_NOTIF_ID + 3; |
| 72 | public static final int VOICEMAIL_NOTIF_ID = REGISTER_NOTIF_ID + 4; |
| 73 | |
| 74 | private static boolean isInit = false; |
| 75 | |
| 76 | public SipNotifications(Context aContext) { |
| 77 | context = aContext; |
| 78 | notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); |
| 79 | |
| 80 | if (!isInit) { |
| 81 | cancelAll(); |
| 82 | cancelCalls(); |
| 83 | isInit = true; |
| 84 | } |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 85 | |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 86 | } |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 87 | |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 88 | public void onServiceCreate() { |
Alexandre Lision | f02190d | 2013-12-12 17:26:12 -0500 | [diff] [blame] | 89 | |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 90 | } |
| 91 | |
| 92 | public void onServiceDestroy() { |
| 93 | // Make sure our notification is gone. |
| 94 | cancelAll(); |
| 95 | cancelCalls(); |
| 96 | } |
| 97 | |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 98 | // Calls |
| 99 | public void showNotificationForCall(SipCall callInfo) { |
Alexandre Lision | 81ef750 | 2013-12-11 17:29:49 -0500 | [diff] [blame] | 100 | // TODO |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | public void showNotificationForVoiceMail(SipProfile acc, int numberOfMessages) { |
Alexandre Lision | 81ef750 | 2013-12-11 17:29:49 -0500 | [diff] [blame] | 104 | // TODO |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 105 | } |
| 106 | |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 107 | protected static CharSequence buildTickerMessage(Context context, String address, String body) { |
| 108 | String displayAddress = address; |
| 109 | |
| 110 | StringBuilder buf = new StringBuilder(displayAddress == null ? "" : displayAddress.replace('\n', ' ').replace('\r', ' ')); |
| 111 | buf.append(':').append(' '); |
| 112 | |
| 113 | int offset = buf.length(); |
| 114 | |
| 115 | if (!TextUtils.isEmpty(body)) { |
| 116 | body = body.replace('\n', ' ').replace('\r', ' '); |
| 117 | buf.append(body); |
| 118 | } |
| 119 | |
| 120 | SpannableString spanText = new SpannableString(buf.toString()); |
| 121 | spanText.setSpan(new StyleSpan(Typeface.BOLD), 0, offset, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); |
| 122 | |
| 123 | return spanText; |
| 124 | } |
| 125 | |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 126 | public final void cancelCalls() { |
| 127 | notificationManager.cancel(CALL_NOTIF_ID); |
| 128 | } |
| 129 | |
| 130 | public final void cancelMissedCalls() { |
| 131 | notificationManager.cancel(CALLLOG_NOTIF_ID); |
| 132 | } |
| 133 | |
| 134 | public final void cancelMessages() { |
| 135 | notificationManager.cancel(MESSAGE_NOTIF_ID); |
| 136 | } |
| 137 | |
| 138 | public final void cancelVoicemails() { |
| 139 | notificationManager.cancel(VOICEMAIL_NOTIF_ID); |
| 140 | } |
| 141 | |
| 142 | public final void cancelAll() { |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 143 | cancelMessages(); |
| 144 | cancelMissedCalls(); |
| 145 | cancelVoicemails(); |
| 146 | } |
| 147 | |
Alexandre Lision | 81ef750 | 2013-12-11 17:29:49 -0500 | [diff] [blame] | 148 | public void publishMissedCallNotification(SipCall sipCall) { |
| 149 | |
| 150 | CharSequence tickerText = context.getString(R.string.notif_missed_call_title); |
| 151 | long when = System.currentTimeMillis(); |
| 152 | |
| 153 | Builder nb = new NotificationCompat.Builder(context); |
| 154 | nb.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher)); |
| 155 | nb.setSmallIcon(R.drawable.ic_action_call); |
| 156 | |
| 157 | nb.setTicker(tickerText); |
| 158 | nb.setWhen(when); |
| 159 | nb.setContentTitle(context.getString(R.string.notif_missed_call_title)); |
| 160 | nb.setContentText(context.getString(R.string.notif_missed_call_content, sipCall.getContact().getmDisplayName())); |
| 161 | Intent notificationIntent = new Intent(context, HomeActivity.class); |
Alexandre Lision | f02190d | 2013-12-12 17:26:12 -0500 | [diff] [blame] | 162 | notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); |
Alexandre Lision | 81ef750 | 2013-12-11 17:29:49 -0500 | [diff] [blame] | 163 | PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
| 164 | |
| 165 | // notification.setLatestEventInfo(context, contentTitle, |
| 166 | // contentText, contentIntent); |
| 167 | nb.setOnlyAlertOnce(true); |
| 168 | nb.setContentIntent(contentIntent); |
| 169 | |
| 170 | Notification notification = nb.build(); |
| 171 | // We have to re-write content view because getNotification setLatestEventInfo implicitly |
| 172 | // notification.contentView = contentView; |
| 173 | |
| 174 | // startForegroundCompat(CALL_NOTIF_ID, notification); |
| 175 | notificationManager.notify(CALL_NOTIF_ID, notification); |
| 176 | } |
Alexandre Lision | f02190d | 2013-12-12 17:26:12 -0500 | [diff] [blame] | 177 | |
| 178 | public void makeNotification(HashMap<String, SipCall> calls) { |
| 179 | if (calls.size() == 0) { |
| 180 | return; |
| 181 | } |
| 182 | Intent notificationIntent = new Intent(context, HomeActivity.class); |
| 183 | PendingIntent contentIntent = PendingIntent.getActivity(context, 007, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
| 184 | |
| 185 | NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); |
| 186 | nm.cancel(NOTIFICATION_ID); // clear previous notifications. |
| 187 | |
| 188 | NotificationCompat.Builder builder = new NotificationCompat.Builder(context); |
| 189 | |
| 190 | builder.setContentIntent(contentIntent).setOngoing(true).setSmallIcon(R.drawable.ic_launcher) |
| 191 | .setContentTitle(calls.size() + " ongoing calls").setTicker("Pending calls").setWhen(System.currentTimeMillis()).setAutoCancel(false); |
| 192 | builder.setPriority(NotificationCompat.PRIORITY_MAX); |
| 193 | Notification n = builder.build(); |
| 194 | |
| 195 | nm.notify(NOTIFICATION_ID, n); |
| 196 | } |
| 197 | |
| 198 | public void removeNotification() { |
| 199 | NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); |
| 200 | nm.cancel(NOTIFICATION_ID); |
| 201 | } |
Alexandre Lision | 1edb147 | 2013-10-24 14:18:05 -0400 | [diff] [blame] | 202 | } |