blob: 429c92863658ff6169da3e7d25c55aadf650a7e4 [file] [log] [blame]
/*
* Copyright (C) 2004-2018 Savoir-faire Linux Inc.
*
* Author: Aline Bonnet <aline.bonnet@savoirfairelinux.com>
* Author: Adrien BĂ©raud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package cx.ring.services;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.media.AudioAttributes;
import android.media.RingtoneManager;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.app.RemoteInput;
import androidx.core.content.res.ResourcesCompat;
import android.util.SparseArray;
import com.bumptech.glide.Glide;
import java.io.File;
import java.util.Collection;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import javax.inject.Inject;
import cx.ring.R;
import cx.ring.client.HomeActivity;
import cx.ring.contactrequests.ContactRequestsFragment;
import cx.ring.contacts.AvatarFactory;
import cx.ring.fragments.ConversationFragment;
import cx.ring.model.Account;
import cx.ring.model.CallContact;
import cx.ring.model.Conference;
import cx.ring.model.Conversation;
import cx.ring.model.DataTransfer;
import cx.ring.model.DataTransferEventCode;
import cx.ring.model.SipCall;
import cx.ring.model.TextMessage;
import cx.ring.model.Uri;
import cx.ring.service.DRingService;
import cx.ring.utils.FileUtils;
import cx.ring.utils.Log;
import cx.ring.utils.ResourceMapper;
public class NotificationServiceImpl implements NotificationService {
private static final String TAG = NotificationServiceImpl.class.getSimpleName();
private static final String NOTIF_MSG = "MESSAGE";
private static final String NOTIF_TRUST_REQUEST = "TRUST REQUEST";
private static final String NOTIF_FILE_TRANSFER = "FILE_TRANSFER";
private static final String NOTIF_MISSED_CALL = "MISSED_CALL";
private static final String NOTIF_CHANNEL_CALL = "call";
private static final String NOTIF_CHANNEL_MESSAGE = "messages";
private static final String NOTIF_CHANNEL_REQUEST = "requests";
private static final String NOTIF_CHANNEL_FILE_TRANSFER = "file_transfer";
private static final String NOTIF_CHANNEL_MISSED_CALL = "missed_call";
private static final String NOTIF_CHANNEL_SERVICE = "service";
private final SparseArray<NotificationCompat.Builder> mNotificationBuilders = new SparseArray<>();
@Inject
protected Context mContext;
@Inject
protected AccountService mAccountService;
@Inject
protected PreferencesService mPreferencesService;
@Inject
protected HistoryService mHistoryService;
@Inject
protected DeviceRuntimeService mDeviceRuntimeService;
private NotificationManagerCompat notificationManager;
private final Random random = new Random();
@SuppressLint("CheckResult")
public void initHelper() {
if (notificationManager == null) {
notificationManager = NotificationManagerCompat.from(mContext);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
registerNotificationChannels();
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void registerNotificationChannels() {
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager == null)
return;
// Call channel
NotificationChannel callChannel = new NotificationChannel(NOTIF_CHANNEL_CALL, mContext.getString(R.string.notif_channel_calls), NotificationManager.IMPORTANCE_HIGH);
callChannel.enableVibration(true);
callChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
notificationManager.createNotificationChannel(callChannel);
// Text messages channel
AudioAttributes soundAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT)
.build();
NotificationChannel messageChannel = new NotificationChannel(NOTIF_CHANNEL_MESSAGE, mContext.getString(R.string.notif_channel_messages), NotificationManager.IMPORTANCE_HIGH);
messageChannel.enableVibration(true);
messageChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
messageChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), soundAttributes);
notificationManager.createNotificationChannel(messageChannel);
// Contact requests
NotificationChannel requestsChannel = new NotificationChannel(NOTIF_CHANNEL_REQUEST, mContext.getString(R.string.notif_channel_requests), NotificationManager.IMPORTANCE_DEFAULT);
requestsChannel.enableVibration(true);
requestsChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
requestsChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), soundAttributes);
notificationManager.createNotificationChannel(requestsChannel);
// File transfer requests
NotificationChannel fileTransferChannel = new NotificationChannel(NOTIF_CHANNEL_FILE_TRANSFER, mContext.getString(R.string.notif_channel_file_transfer), NotificationManager.IMPORTANCE_DEFAULT);
fileTransferChannel.enableVibration(true);
fileTransferChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
fileTransferChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), soundAttributes);
notificationManager.createNotificationChannel(fileTransferChannel);
// Missed calls channel
NotificationChannel missedCallsChannel = new NotificationChannel(NOTIF_CHANNEL_MISSED_CALL, mContext.getString(R.string.notif_channel_missed_calls), NotificationManager.IMPORTANCE_DEFAULT);
missedCallsChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
missedCallsChannel.setSound(null, null);
notificationManager.createNotificationChannel(missedCallsChannel);
// Background service channel
NotificationChannel backgroundChannel = new NotificationChannel(NOTIF_CHANNEL_SERVICE, mContext.getString(R.string.notif_channel_background_service), NotificationManager.IMPORTANCE_LOW);
backgroundChannel.setDescription(mContext.getString(R.string.notif_channel_background_service_descr));
backgroundChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
backgroundChannel.enableLights(false);
backgroundChannel.enableVibration(false);
backgroundChannel.setShowBadge(false);
notificationManager.createNotificationChannel(backgroundChannel);
}
@Override
public void showCallNotification(Conference conference) {
if (conference == null || conference.getParticipants().isEmpty() || !(conference.isOnGoing() || conference.isRinging())) {
return;
}
SipCall call = conference.getParticipants().get(0);
CallContact contact = call.getContact();
final int notificationId = call.getCallId().hashCode();
notificationManager.cancel(notificationId);
PendingIntent gotoIntent = PendingIntent.getService(mContext,
random.nextInt(),
new Intent(DRingService.ACTION_CALL_VIEW)
.setClass(mContext, DRingService.class)
.putExtra(KEY_CALL_ID, call.getCallId()), 0);
NotificationCompat.Builder messageNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIF_CHANNEL_CALL);
if (conference.isOnGoing()) {
messageNotificationBuilder.setContentTitle(mContext.getString(R.string.notif_current_call_title, contact.getRingUsername()))
.setContentText(mContext.getText(R.string.notif_current_call))
.setContentIntent(gotoIntent)
.addAction(R.drawable.ic_call_end_white_24dp, mContext.getText(R.string.action_call_hangup),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_CALL_END)
.setClass(mContext, DRingService.class)
.putExtra(KEY_CALL_ID, call.getCallId()),
PendingIntent.FLAG_ONE_SHOT));
} else if (conference.isRinging()) {
if (conference.isIncoming()) {
Bundle extras = new Bundle();
messageNotificationBuilder.setContentTitle(mContext.getString(R.string.notif_incoming_call_title, contact.getRingUsername()))
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentText(mContext.getText(R.string.notif_incoming_call))
.setContentIntent(gotoIntent)
.setFullScreenIntent(gotoIntent, true)
.addAction(R.drawable.ic_call_end_white_24dp, mContext.getText(R.string.action_call_decline),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_CALL_REFUSE)
.setClass(mContext, DRingService.class)
.putExtra(KEY_CALL_ID, call.getCallId()),
PendingIntent.FLAG_ONE_SHOT))
.addAction(R.drawable.ic_action_accept, mContext.getText(R.string.action_call_accept),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_CALL_ACCEPT)
.setClass(mContext, DRingService.class)
.putExtra(KEY_CALL_ID, call.getCallId()),
PendingIntent.FLAG_ONE_SHOT))
.addExtras(extras);
} else {
messageNotificationBuilder.setContentTitle(mContext.getString(R.string.notif_outgoing_call_title, contact.getRingUsername()))
.setContentText(mContext.getText(R.string.notif_outgoing_call))
.setContentIntent(gotoIntent)
.addAction(R.drawable.ic_call_end_white_24dp, mContext.getText(R.string.action_call_hangup),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_CALL_END)
.setClass(mContext, DRingService.class)
.putExtra(KEY_CALL_ID, call.getCallId()),
PendingIntent.FLAG_ONE_SHOT));
}
}
messageNotificationBuilder.setOngoing(true)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setSmallIcon(R.drawable.ic_ring_logo_white);
setContactPicture(contact, messageNotificationBuilder);
messageNotificationBuilder.setColor(ResourcesCompat.getColor(mContext.getResources(),
R.color.color_primary_dark, null));
notificationManager.notify(notificationId, messageNotificationBuilder.build());
mNotificationBuilders.put(notificationId, messageNotificationBuilder);
}
@Override
public void showTextNotification(String accountId, Conversation conversation) {
TreeMap<Long, TextMessage> texts = conversation.getUnreadTextMessages();
CallContact contact = conversation.getContact();
if (texts.isEmpty() || conversation.isVisible()) {
cancelTextNotification(contact.getPrimaryUri());
return;
}
if (texts.lastEntry().getValue().isNotified()) {
return;
}
Uri contactUri = contact.getPrimaryUri();
if (texts.isEmpty()) {
cancelTextNotification(contactUri);
return;
}
TextMessage last = texts.lastEntry().getValue();
String contactId = contactUri.getRawUriString();
Intent intentConversation = new Intent(DRingService.ACTION_CONV_ACCEPT)
.setClass(mContext, DRingService.class)
.putExtra(ConversationFragment.KEY_ACCOUNT_ID, accountId)
.putExtra(ConversationFragment.KEY_CONTACT_RING_ID, contactId);
Intent intentDelete = new Intent(DRingService.ACTION_CONV_DISMISS)
.setClass(mContext, DRingService.class)
.putExtra(ConversationFragment.KEY_ACCOUNT_ID, accountId)
.putExtra(ConversationFragment.KEY_CONTACT_RING_ID, contactId);
NotificationCompat.Builder messageNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIF_CHANNEL_MESSAGE)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setPriority(Notification.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.ic_ring_logo_white)
.setContentTitle(contact.getDisplayName())
.setContentText(last.getMessage())
.setWhen(last.getDate())
.setContentIntent(PendingIntent.getService(mContext, random.nextInt(), intentConversation, 0))
.setDeleteIntent(PendingIntent.getService(mContext, random.nextInt(), intentDelete, 0))
.setAutoCancel(true)
.setColor(ResourcesCompat.getColor(mContext.getResources(), R.color.color_primary_dark, null));
setContactPicture(contact, messageNotificationBuilder);
if (texts.size() == 1) {
last.setNotified(true);
messageNotificationBuilder.setStyle(null);
} else {
NotificationCompat.MessagingStyle history = new NotificationCompat.MessagingStyle(contact.getDisplayName());
for (TextMessage textMessage : texts.values()) {
history.addMessage(new NotificationCompat.MessagingStyle.Message(
textMessage.getMessage(),
textMessage.getDate(),
textMessage.isIncoming() ? contact.getDisplayName() : "You"));
}
messageNotificationBuilder.setStyle(history);
}
CharSequence replyLabel = mContext.getText(R.string.notif_reply);
RemoteInput remoteInput = new RemoteInput.Builder(DRingService.KEY_TEXT_REPLY)
.setLabel(replyLabel)
.build();
Intent intentReply = new Intent(DRingService.ACTION_CONV_REPLY_INLINE)
.setClass(mContext, DRingService.class)
.putExtra(ConversationFragment.KEY_ACCOUNT_ID, accountId)
.putExtra(ConversationFragment.KEY_CONTACT_RING_ID, contactId);
PendingIntent replyPendingIntent = PendingIntent.getService(mContext, random.nextInt(),
intentReply,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action action =
new NotificationCompat.Action.Builder(R.drawable.baseline_reply_black_24,
replyLabel, replyPendingIntent)
.addRemoteInput(remoteInput)
.build();
messageNotificationBuilder.addAction(action);
Intent intentRead = new Intent(DRingService.ACTION_CONV_READ)
.setClass(mContext, DRingService.class)
.putExtra(ConversationFragment.KEY_ACCOUNT_ID, accountId)
.putExtra(ConversationFragment.KEY_CONTACT_RING_ID, contactId);
messageNotificationBuilder.addAction(0, mContext.getString(R.string.notif_mark_as_read), PendingIntent.getService(mContext, Long.valueOf(System.currentTimeMillis()).intValue(), intentRead, 0));
int notificationId = getTextNotificationId(contactUri);
notificationManager.notify(notificationId, messageNotificationBuilder.build());
mNotificationBuilders.put(notificationId, messageNotificationBuilder);
}
@Override
public void showIncomingTrustRequestNotification(final Account account) {
int notificationId = getIncomingTrustNotificationId(account.getAccountID());
NotificationCompat.Builder messageNotificationBuilder;
Set<String> notifiedRequests = mPreferencesService.loadRequestsPreferences(account.getAccountID());
Collection<Conversation> requests = account.getPending();
if (requests.isEmpty()) {
return;
} else if (requests.size() == 1) {
Conversation request = requests.iterator().next();
CallContact contact = request.getContact();
String contactKey = contact.getPrimaryUri().getRawRingId();
if (notifiedRequests.contains(contactKey)) {
return;
}
mPreferencesService.saveRequestPreferences(account.getAccountID(), contactKey);
messageNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIF_CHANNEL_REQUEST);
Bundle info = new Bundle();
info.putString(TRUST_REQUEST_NOTIFICATION_ACCOUNT_ID, account.getAccountID());
info.putString(TRUST_REQUEST_NOTIFICATION_FROM, contact.getPrimaryNumber());
messageNotificationBuilder.setContentText(contact.getRingUsername())
.addAction(R.drawable.ic_action_accept, mContext.getText(R.string.accept),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_TRUST_REQUEST_ACCEPT)
.setClass(mContext, DRingService.class)
.putExtras(info),
PendingIntent.FLAG_ONE_SHOT))
.addAction(R.drawable.ic_delete_white_24dp, mContext.getText(R.string.refuse),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_TRUST_REQUEST_REFUSE)
.setClass(mContext, DRingService.class)
.putExtras(info),
PendingIntent.FLAG_ONE_SHOT))
.addAction(R.drawable.ic_close_white, mContext.getText(R.string.block),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_TRUST_REQUEST_BLOCK)
.setClass(mContext, DRingService.class)
.putExtras(info),
PendingIntent.FLAG_ONE_SHOT));
/*List<Photo> photos = contact.vcard == null ? null : contact.vcard.getPhotos();
byte[] data = null;
if (photos != null && !photos.isEmpty()) {
data = photos.get(0).getData();
}*/
setContactPicture(contact, messageNotificationBuilder);
} else {
messageNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIF_CHANNEL_REQUEST);
boolean newRequest = false;
for (Conversation request : requests) {
CallContact contact = request.getContact();
String contactKey = contact.getPrimaryUri().getRawRingId();
if (!notifiedRequests.contains(contactKey)) {
newRequest = true;
mPreferencesService.saveRequestPreferences(account.getAccountID(), contactKey);
}
}
if (!newRequest)
return;
messageNotificationBuilder.setContentText(String.format(mContext.getString(R.string.contact_request_msg), Integer.toString(requests.size())));
messageNotificationBuilder.setLargeIcon(null);
messageNotificationBuilder.mActions.clear();
}
messageNotificationBuilder
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_ring_logo_white)
.setCategory(NotificationCompat.CATEGORY_SOCIAL)
.setContentTitle(mContext.getString(R.string.contact_request_title));
Intent intentOpenTrustRequestFragment = new Intent(HomeActivity.ACTION_PRESENT_TRUST_REQUEST_FRAGMENT)
.setClass(mContext, HomeActivity.class)
.putExtra(ContactRequestsFragment.ACCOUNT_ID, account.getAccountID());
messageNotificationBuilder.setContentIntent(PendingIntent.getActivity(mContext,
random.nextInt(), intentOpenTrustRequestFragment, PendingIntent.FLAG_ONE_SHOT));
messageNotificationBuilder.setColor(ResourcesCompat.getColor(mContext.getResources(),
R.color.color_primary_dark, null));
mNotificationBuilders.put(notificationId, messageNotificationBuilder);
notificationManager.notify(notificationId, messageNotificationBuilder.build());
}
@Override
public void showFileTransferNotification(DataTransfer info, CallContact contact) {
if (info == null) {
return;
}
DataTransferEventCode event = info.getEventCode();
if (event == null) {
return;
}
long dataTransferId = info.getDataTransferId();
int notificationId = getFileTransferNotificationId(dataTransferId);
String contactUri = new Uri(info.getPeerId()).getRawUriString();
Intent intentConversation = new Intent(DRingService.ACTION_CONV_ACCEPT)
.setClass(mContext, DRingService.class)
.putExtra(ConversationFragment.KEY_ACCOUNT_ID, mAccountService.getCurrentAccount().getAccountID())
.putExtra(ConversationFragment.KEY_CONTACT_RING_ID, contactUri);
if (event.isOver()) {
notificationManager.cancel(notificationId);
mNotificationBuilders.delete(notificationId);
if (!info.isOutgoing() && info.showPicture()) {
File path = mDeviceRuntimeService.getConversationPath(info.getPeerId(), info.getStoragePath());
Bitmap img;
try {
BitmapDrawable d = (BitmapDrawable) Glide.with(mContext)
.load(path)
.submit()
.get();
img = d.getBitmap();
} catch (Exception e) {
Log.w(TAG, "Can't load image for notification", e);
return;
}
NotificationCompat.Builder notif = new NotificationCompat.Builder(mContext, NOTIF_CHANNEL_FILE_TRANSFER)
.setContentTitle(mContext.getString(R.string.notif_incoming_picture, contact.getDisplayName()))
.setSmallIcon(R.drawable.ic_ring_logo_white)
.setContentIntent(PendingIntent.getService(mContext, random.nextInt(), intentConversation, 0))
.setAutoCancel(true)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(img));
setContactPicture(contact, notif);
notificationManager.notify(random.nextInt(), notif.build());
}
return;
}
NotificationCompat.Builder messageNotificationBuilder = mNotificationBuilders.get(notificationId);
if (messageNotificationBuilder == null) {
messageNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIF_CHANNEL_FILE_TRANSFER);
}
boolean ongoing = event == DataTransferEventCode.CREATED || event == DataTransferEventCode.ONGOING;
String titleMessage = mContext.getString(info.isOutgoing() ? R.string.notif_outgoing_file_transfer_title : R.string.notif_incoming_file_transfer_title, contact.getDisplayName());
messageNotificationBuilder.setContentTitle(titleMessage)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setAutoCancel(false)
.setOngoing(ongoing)
.setSmallIcon(R.drawable.ic_ring_logo_white)
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
.setOnlyAlertOnce(true)
.setContentText(event == DataTransferEventCode.ONGOING ?
FileUtils.readableFileProgress(info.getBytesProgress(), info.getTotalSize()) :
info.getDisplayName() + ": " + ResourceMapper.getReadableFileTransferStatus(mContext, event))
.setContentIntent(PendingIntent.getService(mContext, random.nextInt(), intentConversation, 0))
.setColor(ResourcesCompat.getColor(mContext.getResources(), R.color.color_primary_dark, null));
setContactPicture(contact, messageNotificationBuilder);
if (event.isOver()) {
messageNotificationBuilder.setProgress(0, 0, false);
} else if (ongoing) {
messageNotificationBuilder.setProgress((int)info.getTotalSize(), (int)info.getBytesProgress(), false);
} else {
messageNotificationBuilder.setProgress(0, 0, true);
}
if (event == DataTransferEventCode.CREATED) {
messageNotificationBuilder.setDefaults(NotificationCompat.DEFAULT_VIBRATE);
} else {
messageNotificationBuilder.setDefaults(NotificationCompat.DEFAULT_LIGHTS);
}
messageNotificationBuilder.mActions.clear();
if (event == DataTransferEventCode.WAIT_HOST_ACCEPTANCE) {
messageNotificationBuilder
.addAction(R.drawable.ic_call_received_black_24dp, mContext.getText(R.string.accept),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_FILE_ACCEPT)
.setClass(mContext, DRingService.class)
.putExtra(DRingService.KEY_TRANSFER_ID, dataTransferId),
PendingIntent.FLAG_ONE_SHOT))
.addAction(R.drawable.baseline_cancel_black_24, mContext.getText(R.string.refuse),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_FILE_CANCEL)
.setClass(mContext, DRingService.class)
.putExtra(DRingService.KEY_TRANSFER_ID, dataTransferId),
PendingIntent.FLAG_ONE_SHOT));
} else if (!event.isOver()) {
messageNotificationBuilder
.addAction(R.drawable.baseline_cancel_black_24, mContext.getText(android.R.string.cancel),
PendingIntent.getService(mContext, random.nextInt(),
new Intent(DRingService.ACTION_FILE_CANCEL)
.setClass(mContext, DRingService.class)
.putExtra(DRingService.KEY_TRANSFER_ID, dataTransferId),
PendingIntent.FLAG_ONE_SHOT));
}
mNotificationBuilders.put(notificationId, messageNotificationBuilder);
notificationManager.notify(notificationId, messageNotificationBuilder.build());
}
@Override
public void showMissedCallNotification(SipCall call) {
final int notificationId = call.getCallId().hashCode();
NotificationCompat.Builder messageNotificationBuilder = mNotificationBuilders.get(notificationId);
if (messageNotificationBuilder == null) {
messageNotificationBuilder = new NotificationCompat.Builder(mContext, NOTIF_CHANNEL_MISSED_CALL);
}
String contactUri = call.getNumberUri().getRawUriString();
Intent intentConversation = new Intent(DRingService.ACTION_CONV_ACCEPT)
.setClass(mContext, DRingService.class)
.putExtra(ConversationFragment.KEY_ACCOUNT_ID, mAccountService.getCurrentAccount().getAccountID())
.putExtra(ConversationFragment.KEY_CONTACT_RING_ID, contactUri);
messageNotificationBuilder.setContentTitle(mContext.getText(R.string.notif_missed_incoming_call))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.baseline_call_missed_white_24)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setOnlyAlertOnce(true)
.setAutoCancel(true)
.setContentText(call.getContact().getDisplayName())
.setContentIntent(PendingIntent.getService(mContext, random.nextInt(), intentConversation, 0))
.setColor(ResourcesCompat.getColor(mContext.getResources(), R.color.color_primary_dark, null));
setContactPicture(call.getContact(), messageNotificationBuilder);
notificationManager.notify(notificationId, messageNotificationBuilder.build());
}
@Override
public Object getServiceNotification() {
Intent intentHome = new Intent(Intent.ACTION_VIEW)
.setClass(mContext, HomeActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendIntent = PendingIntent.getActivity(mContext, 0, intentHome, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder messageNotificationBuilder = new NotificationCompat.Builder(mContext, NotificationServiceImpl.NOTIF_CHANNEL_SERVICE);
messageNotificationBuilder
.setContentTitle(mContext.getText(R.string.app_name))
.setContentText(mContext.getText(R.string.notif_background_service))
.setSmallIcon(R.drawable.ic_ring_logo_white)
.setContentIntent(pendIntent)
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
.setPriority(NotificationCompat.PRIORITY_MIN)
.setOngoing(true)
.setCategory(NotificationCompat.CATEGORY_SERVICE);
return messageNotificationBuilder.build();
}
@Override
public void cancelTextNotification(Uri contact) {
if (contact == null) {
return;
}
int notificationId = getTextNotificationId(contact);
notificationManager.cancel(notificationId);
mNotificationBuilders.remove(notificationId);
}
public void cancelTextNotification(String ringId) {
int notificationId = (NOTIF_MSG + ringId).hashCode();
notificationManager.cancel(notificationId);
mNotificationBuilders.remove(notificationId);
}
@Override
public void cancelTrustRequestNotification(String accountID) {
if (accountID == null) {
return;
}
int notificationId = getIncomingTrustNotificationId(accountID);
notificationManager.cancel(notificationId);
mNotificationBuilders.remove(notificationId);
}
@Override
public void cancelCallNotification(int notificationId) {
notificationManager.cancel(notificationId);
mNotificationBuilders.remove(notificationId);
}
@Override
public void cancelFileNotification(long fileId) {
int nId = getFileTransferNotificationId(fileId);
notificationManager.cancel(nId);
mNotificationBuilders.remove(nId);
}
@Override
public void cancelAll() {
notificationManager.cancelAll();
mNotificationBuilders.clear();
}
private int getIncomingTrustNotificationId(String accountId) {
return (NOTIF_TRUST_REQUEST + accountId).hashCode();
}
private int getTextNotificationId(Uri contact) {
return (NOTIF_MSG + contact.toString()).hashCode();
}
private int getFileTransferNotificationId(long dataTransferId) {
return (NOTIF_FILE_TRANSFER + dataTransferId).hashCode();
}
private void setContactPicture(CallContact contact, NotificationCompat.Builder messageNotificationBuilder) {
int size = (int) (mContext.getResources().getDisplayMetrics().density * AvatarFactory.SIZE_NOTIF);
messageNotificationBuilder.setLargeIcon(AvatarFactory.getBitmapAvatar(mContext, contact, size).blockingGet());
}
}