diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e4fd0163f..2f5423881 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -294,7 +294,7 @@
diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java
index de18518a6..e22d66d7c 100644
--- a/app/src/main/java/org/linphone/LinphoneManager.java
+++ b/app/src/main/java/org/linphone/LinphoneManager.java
@@ -504,7 +504,7 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou
if (call != null) {
call.enableCamera(enable);
if (mServiceContext.getResources().getBoolean(R.bool.enable_call_notification))
- LinphoneService.instance().displayCallNotification(mLc.getCurrentCall());
+ LinphoneService.instance().getNotificationManager().displayCallNotification(mLc.getCurrentCall());
}
}
@@ -1075,16 +1075,16 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou
if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat_message_notification) && !message.isOutgoing()) {
if (cr.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
if (contact != null) {
- LinphoneService.instance().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress().asString());
+ LinphoneService.instance().getNotificationManager().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress());
} else {
- LinphoneService.instance().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress().asString());
+ LinphoneService.instance().getNotificationManager().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress());
}
} else {
String subject = cr.getSubject();
if (contact != null) {
- LinphoneService.instance().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress().asString());
+ LinphoneService.instance().getNotificationManager().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress());
} else {
- LinphoneService.instance().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress().asString());
+ LinphoneService.instance().getNotificationManager().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress());
}
}
}
diff --git a/app/src/main/java/org/linphone/LinphoneService.java b/app/src/main/java/org/linphone/LinphoneService.java
index 5634a311d..a7f71420e 100644
--- a/app/src/main/java/org/linphone/LinphoneService.java
+++ b/app/src/main/java/org/linphone/LinphoneService.java
@@ -23,31 +23,22 @@ import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.Application;
-import android.app.Notification;
-import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.provider.ContactsContract;
-import android.provider.MediaStore;
import android.view.WindowManager;
import org.linphone.activities.LinphoneActivity;
-import org.linphone.compatibility.Compatibility;
import org.linphone.contacts.ContactsManager;
-import org.linphone.contacts.LinphoneContact;
-import org.linphone.core.Address;
import org.linphone.core.Call;
import org.linphone.core.Call.State;
import org.linphone.core.Core;
@@ -58,14 +49,12 @@ import org.linphone.core.ProxyConfig;
import org.linphone.core.RegistrationState;
import org.linphone.mediastream.Log;
import org.linphone.mediastream.Version;
+import org.linphone.notifications.NotificationsManager;
import org.linphone.receivers.BluetoothManager;
import org.linphone.receivers.KeepAliveReceiver;
import org.linphone.ui.LinphoneOverlay;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.HashMap;
/**
* Linphone service, reacting to Incoming calls, ...
@@ -81,14 +70,9 @@ public final class LinphoneService extends Service {
* setLatestEventInfo and startActivity() which needs a context.
*/
public static final String START_LINPHONE_LOGS = " ==== Phone information dump ====";
- public static final int IC_LEVEL_ORANGE = 0;
private static LinphoneService instance;
- private final static int NOTIF_ID = 1;
- private final static int CUSTOM_NOTIF_ID = 4;
- private final static int MISSED_NOTIF_ID = 5;
-
public static boolean isReady() {
return instance != null && instance.mTestDelayElapsed;
}
@@ -106,38 +90,28 @@ public final class LinphoneService extends Service {
// private boolean mTestDelayElapsed; // add a timer for testing
private boolean mTestDelayElapsed = true; // no timer
- private NotificationManager mNM;
- private Notification mNotif;
- private Notification mCustomNotif;
- private PendingIntent mNotifContentIntent;
- private String mNotificationTitle;
- private boolean mDisableRegistrationStatus;
private CoreListenerStub mListener;
- public static int notifcationsPriority = (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41) ? Notification.PRIORITY_MIN : 0);
private WindowManager mWindowManager;
private LinphoneOverlay mOverlay;
private Application.ActivityLifecycleCallbacks activityCallbacks;
- private class Notified {
- int notificationId;
- int numberOfUnreadMessage;
+ private NotificationsManager mNotificationManager;
+
+ public NotificationsManager getNotificationManager() {
+ return mNotificationManager;
}
- private HashMap mChatNotifMap, mCallNotifMap;
- private int mLastNotificationId;
+ private String incomingReceivedActivityName;
+ private Class extends Activity> incomingReceivedActivity = LinphoneActivity.class;
+
+ public Class extends Activity> getIncomingReceivedActivity() {
+ return incomingReceivedActivity;
+ }
public void setCurrentlyDisplayedChatRoom(String address) {
if (address != null) {
- resetMessageNotifCount(address);
- }
- }
-
- private void resetMessageNotifCount(String address) {
- Notified notif = mChatNotifMap.get(address);
- if (notif != null) {
- notif.numberOfUnreadMessage = 0;
- mNM.cancel(notif.notificationId);
+ mNotificationManager.resetMessageNotifCount(address);
}
}
@@ -169,8 +143,6 @@ public final class LinphoneService extends Service {
}
}
- ;
-
private InactivityChecker mLastChecker;
@Override
@@ -275,31 +247,6 @@ public final class LinphoneService extends Service {
getApplication().registerActivityLifecycleCallbacks(activityCallbacks = new ActivityMonitor());
}
- public boolean displayServiceNotification() {
- return LinphonePreferences.instance().getServiceNotificationVisibility();
- }
-
- public void showServiceNotification() {
- startForegroundCompat(NOTIF_ID, mNotif);
-
- Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
- if (lc == null) return;
- ProxyConfig lpc = lc.getDefaultProxyConfig();
- if (lpc != null) {
- if (lpc.getState() == RegistrationState.Ok) {
- sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
- } else {
- sendNotification(IC_LEVEL_ORANGE, R.string.notification_register_failure);
- }
- } else {
- sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
- }
- }
-
- public void hideServiceNotification() {
- stopForegroundCompat(NOTIF_ID);
- }
-
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
@@ -309,9 +256,10 @@ public final class LinphoneService extends Service {
return START_REDELIVER_INTENT;
}
- LinphoneManager.createAndStart(LinphoneService.this);
+ LinphoneManager.createAndStart(this);
instance = this; // instance is ready once linphone manager has been created
+ mNotificationManager = new NotificationsManager(this);
LinphoneManager.getLc().addListener(mListener = new CoreListenerStub() {
@Override
public void onCallStateChanged(Core lc, Call call, Call.State state, String message) {
@@ -321,7 +269,7 @@ public final class LinphoneService extends Service {
}
if (getResources().getBoolean(R.bool.enable_call_notification)) {
- displayCallNotification(call);
+ mNotificationManager.displayCallNotification(call);
}
if (state == Call.State.IncomingReceived) {
@@ -339,58 +287,23 @@ public final class LinphoneService extends Service {
}
if (state == State.End && call.getCallLog().getStatus() == Call.Status.Missed) {
- int missedCallCount = LinphoneManager.getLcIfManagerNotDestroyedOrNull().getMissedCallsCount();
- String body;
- if (missedCallCount > 1) {
- body = getString(R.string.missed_calls_notif_body).replace("%i", String.valueOf(missedCallCount));
- } else {
- Address address = call.getRemoteAddress();
- LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
- if (c != null) {
- body = c.getFullName();
- } else {
- body = address.getDisplayName();
- if (body == null) {
- body = address.asStringUriOnly();
- }
- }
- }
-
- Intent missedCallNotifIntent = new Intent(LinphoneService.this, incomingReceivedActivity);
- missedCallNotifIntent.putExtra("GoToHistory", true);
- PendingIntent intent = PendingIntent.getActivity(LinphoneService.this, 0, missedCallNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- Notification notif = Compatibility.createMissedCallNotification(instance, getString(R.string.missed_calls_notif_title), body, intent);
- notifyWrapper(MISSED_NOTIF_ID, notif);
+ mNotificationManager.displayMissedCallNotification(call);
}
}
@Override
public void onGlobalStateChanged(Core lc, GlobalState state, String message) {
- if (!mDisableRegistrationStatus && state == GlobalState.On && displayServiceNotification()) {
- sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
- }
+ //TODO global state if ON
}
@Override
public void onRegistrationStateChanged(Core lc, ProxyConfig cfg, RegistrationState state, String smessage) {
- if (!mDisableRegistrationStatus) {
- if (displayServiceNotification() && state == RegistrationState.Ok && LinphoneManager.getLc().getDefaultProxyConfig() != null && LinphoneManager.getLc().getDefaultProxyConfig().getState() == RegistrationState.Ok) {
- sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
- }
-
- if (displayServiceNotification() && (state == RegistrationState.Failed || state == RegistrationState.Cleared) && (LinphoneManager.getLc().getDefaultProxyConfig() == null || !(LinphoneManager.getLc().getDefaultProxyConfig().getState() == RegistrationState.Ok))) {
- sendNotification(IC_LEVEL_ORANGE, R.string.notification_register_failure);
- }
-
- if (displayServiceNotification() && state == RegistrationState.None) {
- sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
- }
- }
+ //TODO registration status
}
});
- if (displayServiceNotification() || (Version.sdkAboveOrEqual(Version.API26_O_80) && intent.getBooleanExtra("ForceStartForeground", false))) {
- startForegroundCompat(NOTIF_ID, mNotif);
+ if (Version.sdkAboveOrEqual(Version.API26_O_80) && intent.getBooleanExtra("ForceStartForeground", false)) {
+ mNotificationManager.startForeground();
}
if (!Version.sdkAboveOrEqual(Version.API26_O_80)
@@ -426,13 +339,8 @@ public final class LinphoneService extends Service {
@Override
public void onCreate() {
super.onCreate();
- mLastNotificationId = 8; // To not interfere with other notifs ids
- mChatNotifMap = new HashMap<>();
- mCallNotifMap = new HashMap<>();
setupActivityMonitor();
- // In case restart after a crash. Main in LinphoneActivity
- mNotificationTitle = getString(R.string.service_name);
// Needed in order for the two next calls to succeed, libraries must have been loaded first
LinphonePreferences.instance().setContext(getBaseContext());
@@ -445,27 +353,6 @@ public final class LinphoneService extends Service {
dumpDeviceInformation();
dumpInstalledLinphoneInformation();
- //Disable service notification for Android O
- if ((Version.sdkAboveOrEqual(Version.API26_O_80))) {
- LinphonePreferences.instance().setServiceNotificationVisibility(false);
- mDisableRegistrationStatus = true;
- }
-
- mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
- mNM.cancelAll();
- Compatibility.createNotificationChannels(this);
-
- Intent notifIntent = new Intent(this, incomingReceivedActivity);
- notifIntent.putExtra("Notification", true);
- mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-
- Bitmap bm = null;
- try {
- bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
- } catch (Exception e) {
- }
- mNotif = Compatibility.createNotification(this, mNotificationTitle, "", R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, mNotifContentIntent, true, notifcationsPriority);
-
incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived();
try {
incomingReceivedActivity = (Class extends Activity>) Class.forName(incomingReceivedActivityName);
@@ -473,13 +360,6 @@ public final class LinphoneService extends Service {
Log.e(e);
}
- try {
- mStartForeground = getClass().getMethod("startForeground", mStartFgSign);
- mStopForeground = getClass().getMethod("stopForeground", mStopFgSign);
- } catch (NoSuchMethodException e) {
- Log.e(e, "Couldn't find startForeground or stopForeground");
- }
-
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
}
@@ -504,249 +384,6 @@ public final class LinphoneService extends Service {
mOverlay = null;
}
- public void displayCallNotification(Call call) {
- if (call == null) return;
-
- Address address = call.getRemoteAddress();
- String addressAsString = address.asStringUriOnly();
- Notified notif = mCallNotifMap.get(addressAsString);
- if (notif == null) {
- notif = new Notified();
- notif.notificationId = mLastNotificationId;
- mLastNotificationId += 1;
- mCallNotifMap.put(addressAsString, notif);
- }
-
- if (!displayServiceNotification()) {
- if (call.getCore().getCallsNb() == 0) {
- hideServiceNotification();
- } else {
- showServiceNotification();
- }
- }
-
- int notificationTextId;
- int iconId;
- switch (call.getState()) {
- case Released:
- case End:
- mNM.cancel(notif.notificationId);
- mCallNotifMap.remove(addressAsString);
- return;
- case Paused:
- case PausedByRemote:
- case Pausing:
- iconId = R.drawable.topbar_call_notification;
- notificationTextId = R.string.incall_notif_paused;
- break;
- default:
- if (call.getCurrentParams().videoEnabled()) {
- iconId = R.drawable.topbar_videocall_notification;
- notificationTextId = R.string.incall_notif_video;
- } else {
- iconId = R.drawable.topbar_call_notification;
- notificationTextId = R.string.incall_notif_active;
- }
- break;
- }
-
- LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
- Uri pictureUri = contact != null ? contact.getPhotoUri() : null;
- Bitmap bm;
- try {
- bm = MediaStore.Images.Media.getBitmap(getContentResolver(), pictureUri);
- } catch (Exception e) {
- bm = BitmapFactory.decodeResource(getResources(), R.drawable.avatar);
- }
- String name = LinphoneUtils.getAddressDisplayName(address);
-
- boolean showAnswerAction = call.getState() == State.IncomingReceived || call.getState() == State.IncomingEarlyMedia;
- Intent notifIntent = new Intent(this, incomingReceivedActivity);
- notifIntent.putExtra("Notification", true);
- mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- Notification notification = Compatibility.createInCallNotification(getApplicationContext(), notif.notificationId, showAnswerAction, mNotificationTitle, getString(notificationTextId), iconId, bm, name, mNotifContentIntent);
-
- notifyWrapper(notif.notificationId, notification);
- }
-
- public String getSipUriForCallNotificationId(int notificationId) {
- for (String addr : mCallNotifMap.keySet()) {
- if (mCallNotifMap.get(addr).notificationId == notificationId) {
- return addr;
- }
- }
- return null;
- }
-
- @Deprecated
- public void addNotification(Intent onClickIntent, int iconResourceID, String title, String message) {
- addCustomNotification(onClickIntent, iconResourceID, title, message, true);
- }
-
- public void addCustomNotification(Intent onClickIntent, int iconResourceID, String title, String message, boolean isOngoingEvent) {
- PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-
- Bitmap bm = null;
- try {
- bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
- } catch (Exception e) {
- }
- mCustomNotif = Compatibility.createNotification(this, title, message, iconResourceID, 0, bm, notifContentIntent, isOngoingEvent, notifcationsPriority);
-
- mCustomNotif.defaults |= Notification.DEFAULT_VIBRATE;
- mCustomNotif.defaults |= Notification.DEFAULT_SOUND;
- mCustomNotif.defaults |= Notification.DEFAULT_LIGHTS;
-
- notifyWrapper(CUSTOM_NOTIF_ID, mCustomNotif);
- }
-
- public void displayGroupChatMessageNotification(String subject, String conferenceAddress, String fromName, Uri fromPictureUri, String message, String localIdentity) {
- Intent notifIntent = new Intent(this, LinphoneActivity.class);
- notifIntent.putExtra("GoToChat", true);
- notifIntent.putExtra("ChatContactSipUri", conferenceAddress);
- notifIntent.putExtra("LocalIdentity", localIdentity);
-
- PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-
- Notified notif = mChatNotifMap.get(conferenceAddress);
- if (notif != null) {
- notif.numberOfUnreadMessage += 1;
- } else {
- notif = new Notified();
- notif.numberOfUnreadMessage = 1;
- notif.notificationId = mLastNotificationId;
- mLastNotificationId += 1;
- mChatNotifMap.put(conferenceAddress, notif);
- }
-
- Bitmap bm;
- if (fromPictureUri != null) {
- try {
- bm = MediaStore.Images.Media.getBitmap(getContentResolver(), fromPictureUri);
- } catch (Exception e) {
- bm = BitmapFactory.decodeResource(getResources(), R.drawable.chat_group_avatar);
- }
- } else {
- bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
- }
- Notification notification = Compatibility.createMessageNotification(getApplicationContext(), notif.notificationId, notif.numberOfUnreadMessage, subject,
- getString(R.string.group_chat_notif).replace("%1", fromName).replace("%2", message), bm, notifContentIntent);
-
- notifyWrapper(notif.notificationId, notification);
- }
-
- public void displayMessageNotification(String fromSipUri, String fromName, Uri fromPictureUri, String message, String localIdentity) {
- Intent notifIntent = new Intent(this, LinphoneActivity.class);
- notifIntent.putExtra("GoToChat", true);
- notifIntent.putExtra("ChatContactSipUri", fromSipUri);
- notifIntent.putExtra("LocalIdentity", localIdentity);
- PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-
- if (fromName == null) {
- fromName = fromSipUri;
- }
-
- Notified notif = mChatNotifMap.get(fromSipUri);
- if (notif != null) {
- notif.numberOfUnreadMessage += 1;
- } else {
- notif = new Notified();
- notif.numberOfUnreadMessage = 1;
- notif.notificationId = mLastNotificationId;
- mLastNotificationId += 1;
- mChatNotifMap.put(fromSipUri, notif);
- }
-
- Bitmap bm;
- if (fromPictureUri != null) {
- try {
- bm = MediaStore.Images.Media.getBitmap(getContentResolver(), fromPictureUri);
- } catch (Exception e) {
- bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
- }
- } else {
- bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
- }
- Notification notification = Compatibility.createMessageNotification(getApplicationContext(), notif.notificationId, notif.numberOfUnreadMessage, fromName, message, bm, notifContentIntent);
-
- notifyWrapper(notif.notificationId, notification);
- }
-
- public void sendNotification(Notification notif, int notificationId) {
- notifyWrapper(notificationId, notif);
- }
-
- public String getSipUriForNotificationId(int notificationId) {
- for (String addr : mChatNotifMap.keySet()) {
- if (mChatNotifMap.get(addr).notificationId == notificationId) {
- return addr;
- }
- }
- return null;
- }
-
- public void displayInappNotification(String message) {
- Intent notifIntent = new Intent(this, LinphoneActivity.class);
- notifIntent.putExtra("GoToInapp", true);
-
- PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- mNotif = Compatibility.createSimpleNotification(getApplicationContext(), getString(R.string.inapp_notification_title), message, notifContentIntent);
-
- notifyWrapper(NOTIF_ID, mNotif);
- }
-
- private static final Class>[] mSetFgSign = new Class[]{boolean.class};
- private static final Class>[] mStartFgSign = new Class[]{
- int.class, Notification.class};
- private static final Class>[] mStopFgSign = new Class[]{boolean.class};
-
- private Method mStartForeground;
- private Method mStopForeground;
- private Object[] mSetForegroundArgs = new Object[1];
- private Object[] mStartForegroundArgs = new Object[2];
- private Object[] mStopForegroundArgs = new Object[1];
- private String incomingReceivedActivityName;
- private Class extends Activity> incomingReceivedActivity = LinphoneActivity.class;
-
- void invokeMethod(Method method, Object[] args) {
- try {
- method.invoke(this, args);
- } catch (InvocationTargetException e) {
- // Should not happen.
- Log.w(e, "Unable to invoke method");
- } catch (IllegalAccessException e) {
- // Should not happen.
- Log.w(e, "Unable to invoke method");
- }
- }
-
- /**
- * This is a wrapper around the new startForeground method, using the older
- * APIs if it is not available.
- */
- void startForegroundCompat(int id, Notification notification) {
- // If we have the new startForeground API, then use it.
- if (mStartForeground != null) {
- mStartForegroundArgs[0] = Integer.valueOf(id);
- mStartForegroundArgs[1] = notification;
- invokeMethod(mStartForeground, mStartForegroundArgs);
- return;
- }
- }
-
- /**
- * This is a wrapper around the new stopForeground method, using the older
- * APIs if it is not available.
- */
- void stopForegroundCompat(int id) {
- // If we have the new stopForeground API, then use it.
- if (mStopForeground != null) {
- mStopForegroundArgs[0] = Boolean.TRUE;
- invokeMethod(mStopForeground, mStopForegroundArgs);
- return;
- }
- }
-
private void dumpDeviceInformation() {
StringBuilder sb = new StringBuilder();
sb.append("DEVICE=").append(Build.DEVICE).append("\n");
@@ -775,38 +412,6 @@ public final class LinphoneService extends Service {
}
}
- private synchronized void sendNotification(int level, int textId) {
- String text = getString(textId);
- if (text.contains("%s") && LinphoneManager.getLc() != null) {
- // Test for null lc is to avoid a NPE when Android mess up badly with the String resources.
- ProxyConfig lpc = LinphoneManager.getLc().getDefaultProxyConfig();
- String id = lpc != null ? lpc.getIdentityAddress().asString() : "";
- text = String.format(text, id);
- }
-
- Bitmap bm = null;
- try {
- bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
- } catch (Exception e) {
- }
- mNotif = Compatibility.createNotification(this, mNotificationTitle, text, R.drawable.status_level, 0, bm, mNotifContentIntent, true, notifcationsPriority);
- notifyWrapper(NOTIF_ID, mNotif);
- }
-
- /**
- * Wrap notifier to avoid setting the linphone icons while the service
- * is stopping. When the (rare) bug is triggered, the linphone icon is
- * present despite the service is not running. To trigger it one could
- * stop linphone as soon as it is started. Transport configured with TLS.
- */
- private synchronized void notifyWrapper(int id, Notification notification) {
- if (instance != null && notification != null) {
- mNM.notify(id, notification);
- } else {
- Log.i("Service not ready, discarding notification");
- }
- }
-
@Override
public IBinder onBind(Intent intent) {
return null;
@@ -849,8 +454,7 @@ public final class LinphoneService extends Service {
LinphoneManager.destroy();
// Make sure our notification is gone.
- stopForegroundCompat(NOTIF_ID);
- mNM.cancelAll();
+ mNotificationManager.destroy();
// This will prevent the app from crashing if the service gets killed in background mode
if (LinphoneActivity.isInstanciated()) {
@@ -875,8 +479,8 @@ public final class LinphoneService extends Service {
protected void onIncomingReceived() {
//wakeup linphone
startActivity(new Intent()
- .setClass(this, incomingReceivedActivity)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ .setClass(this, incomingReceivedActivity)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}
diff --git a/app/src/main/java/org/linphone/activities/LinphoneActivity.java b/app/src/main/java/org/linphone/activities/LinphoneActivity.java
index 2aa9da1ef..412b4ffd1 100644
--- a/app/src/main/java/org/linphone/activities/LinphoneActivity.java
+++ b/app/src/main/java/org/linphone/activities/LinphoneActivity.java
@@ -698,10 +698,9 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
changeCurrentFragment(FragmentsAvailable.CREATE_CHAT, extras);
}
- public void goToChat(String sipUri, Bundle shareInfos, String localIdentity) {
+ public void goToChat(String sipUri, Bundle shareInfos) {
Bundle extras = new Bundle();
extras.putString("SipUri", sipUri);
- extras.putString("LocalIdentity", localIdentity);
if (shareInfos != null) {
if (shareInfos.getString("fileSharedUri") != null)
@@ -1382,9 +1381,6 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (lc != null) {
lc.addListener(mListener);
- if (!LinphoneService.instance().displayServiceNotification()) {
- lc.refreshRegisters();
- }
}
if (isTablet()) {
@@ -1483,12 +1479,11 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
Bundle extras = intent.getExtras();
if (extras != null && extras.getBoolean("GoToChat", false)) {
String sipUri = extras.getString("ChatContactSipUri");
- String localIdentity = extras.getString("LocalIdentity");
intent.putExtra("DoNotGoToCallActivity", true);
if (sipUri == null) {
goToChatList();
} else {
- goToChat(sipUri, extras, localIdentity);
+ goToChat(sipUri, extras);
}
} else if (extras != null && extras.getBoolean("GoToHistory", false)) {
intent.putExtra("DoNotGoToCallActivity", true);
@@ -1496,7 +1491,7 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
} else if (extras != null && extras.getBoolean("GoToInapp", false)) {
intent.putExtra("DoNotGoToCallActivity", true);
displayInapp();
- } else if (extras != null && extras.getBoolean("Notification", false)) {
+ } else if (extras != null && extras.getBoolean("Notifiable", false)) {
if (LinphoneManager.getLc().getCallsNb() > 0) {
startIncallActivity();
}
@@ -1840,9 +1835,9 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
LinphonePreferences.instance().setInappPopupTime(String.valueOf(newDate));
}
if (isTrialAccount) {
- LinphoneService.instance().displayInappNotification(String.format(getString(R.string.inapp_notification_trial_expire), date));
+ LinphoneService.instance().getNotificationManager().displayInappNotification(String.format(getString(R.string.inapp_notification_trial_expire), date));
} else {
- LinphoneService.instance().displayInappNotification(String.format(getString(R.string.inapp_notification_account_expire), date));
+ LinphoneService.instance().getNotificationManager().displayInappNotification(String.format(getString(R.string.inapp_notification_account_expire), date));
}
}
diff --git a/app/src/main/java/org/linphone/chat/ChatCreationFragment.java b/app/src/main/java/org/linphone/chat/ChatCreationFragment.java
index c009c73e3..6afce5a1c 100644
--- a/app/src/main/java/org/linphone/chat/ChatCreationFragment.java
+++ b/app/src/main/java/org/linphone/chat/ChatCreationFragment.java
@@ -213,7 +213,7 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
- LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos, cr.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
@@ -468,7 +468,7 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
if (createEncryptedChatRoom && lpc != null && lpc.getConferenceFactoryUri() != null) {
mChatRoom = lc.findOneToOneChatRoom(lpc.getIdentityAddress(), ca.getAddress(), true);
if (mChatRoom != null) {
- LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos, mChatRoom.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
} else {
mChatRoom = lc.createClientGroupChatRoom(getString(R.string.dummy_group_chat_subject), !createEncryptedChatRoom, createEncryptedChatRoom);
mChatRoom.addListener(mChatRoomCreationListener);
@@ -487,11 +487,11 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
participants[0] = ca.getAddress();
mChatRoom.addParticipants(participants);
} else {
- LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos, mChatRoom.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
}
} else {
ChatRoom chatRoom = lc.getChatRoom(ca.getAddress());
- LinphoneActivity.instance().goToChat(chatRoom.getPeerAddress().asStringUriOnly(), mShareInfos, chatRoom.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(chatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
}
}
} else {
diff --git a/app/src/main/java/org/linphone/chat/ChatListFragment.java b/app/src/main/java/org/linphone/chat/ChatListFragment.java
index e727c158a..c748ba155 100644
--- a/app/src/main/java/org/linphone/chat/ChatListFragment.java
+++ b/app/src/main/java/org/linphone/chat/ChatListFragment.java
@@ -161,7 +161,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
mChatRoomsAdapter.toggleSelection(position);
} else {
ChatRoom room = (ChatRoom) mChatRoomsAdapter.getItem(position);
- LinphoneActivity.instance().goToChat(room.getPeerAddress().asString(), null, room.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(room.getPeerAddress().asString(), null);
}
}
@@ -183,7 +183,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter();
if (adapter != null && adapter.getItemCount() > 0) {
ChatRoom room = (ChatRoom) adapter.getItem(0);
- LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
} else {
LinphoneActivity.instance().displayEmptyFragment();
}
diff --git a/app/src/main/java/org/linphone/chat/DevicesFragment.java b/app/src/main/java/org/linphone/chat/DevicesFragment.java
index ebf378d60..7fb66d548 100644
--- a/app/src/main/java/org/linphone/chat/DevicesFragment.java
+++ b/app/src/main/java/org/linphone/chat/DevicesFragment.java
@@ -106,7 +106,7 @@ public class DevicesFragment extends Fragment {
@Override
public void onClick(View view) {
if (LinphoneActivity.instance().isTablet()) {
- LinphoneActivity.instance().goToChat(mRoomUri, null, mRoom.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(mRoomUri, null);
} else {
LinphoneActivity.instance().onBackPressed();
}
diff --git a/app/src/main/java/org/linphone/chat/GroupChatFragment.java b/app/src/main/java/org/linphone/chat/GroupChatFragment.java
index 6be74f3fe..b007f6b07 100644
--- a/app/src/main/java/org/linphone/chat/GroupChatFragment.java
+++ b/app/src/main/java/org/linphone/chat/GroupChatFragment.java
@@ -951,11 +951,11 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
if (LinphoneActivity.instance().isOnBackground()) {
if (!getResources().getBoolean(R.bool.disable_chat_message_notification)) {
if (contact != null) {
- LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(),
- contact.getFullName(), contact.getThumbnailUri(), getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress().asString());
+ LinphoneService.instance().getNotificationManager().displayMessageNotification(from.asStringUriOnly(),
+ contact.getFullName(), contact.getThumbnailUri(), getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress());
} else {
- LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(),
- from.getUsername(), null, getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress().asString());
+ LinphoneService.instance().getNotificationManager().displayMessageNotification(from.asStringUriOnly(),
+ from.getUsername(), null, getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress());
}
}
} else if (LinphoneManager.getLc().limeEnabled() == LimeState.Mandatory) {
diff --git a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java
index 3c677c61d..f4a2c564c 100644
--- a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java
+++ b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java
@@ -159,7 +159,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
public void onClick(View view) {
if (mIsAlreadyCreatedGroup) {
if (LinphoneActivity.instance().isTablet()) {
- LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asStringUriOnly(), mShareInfos, mChatRoom.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asStringUriOnly(), mShareInfos);
} else {
getFragmentManager().popBackStack();
}
@@ -185,7 +185,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
public void onClick(View view) {
if (mChatRoom != null) {
mChatRoom.leave();
- LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null, mChatRoom.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null);
} else {
Log.e("Can't leave, chatRoom for address " + mGroupChatRoomAddress.asString() + " is null...");
}
@@ -251,7 +251,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
// This will remove both the creation fragment and the group info fragment from the back stack
getFragmentManager().popBackStack();
getFragmentManager().popBackStack();
- LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos, cr.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
@@ -322,7 +322,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
toAdd.toArray(participantsToAdd);
mChatRoom.addParticipants(participantsToAdd);
- LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null, mChatRoom.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null);
}
}
});
diff --git a/app/src/main/java/org/linphone/chat/ImdnFragment.java b/app/src/main/java/org/linphone/chat/ImdnFragment.java
index 2221cc487..8e0a7a984 100644
--- a/app/src/main/java/org/linphone/chat/ImdnFragment.java
+++ b/app/src/main/java/org/linphone/chat/ImdnFragment.java
@@ -85,7 +85,7 @@ public class ImdnFragment extends Fragment {
@Override
public void onClick(View view) {
if (LinphoneActivity.instance().isTablet()) {
- LinphoneActivity.instance().goToChat(mRoomUri, null, mRoom.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(mRoomUri, null);
} else {
LinphoneActivity.instance().onBackPressed();
}
diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java
index 2d98b393b..6215851dd 100644
--- a/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java
+++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java
@@ -2,23 +2,22 @@ package org.linphone.compatibility;
import android.annotation.TargetApi;
-import android.app.FragmentTransaction;
import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
-import android.view.ViewTreeObserver;
import org.linphone.R;
-import org.linphone.receivers.NotificationBroadcastReceiver;
+import org.linphone.notifications.Notifiable;
+import org.linphone.notifications.NotifiableMessage;
+import org.linphone.notifications.NotificationBroadcastReceiver;
import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_CALL_ID;
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
+import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
@@ -52,23 +51,17 @@ public class ApiTwentyFourPlus {
.build();
}
- public static Notification createMessageNotification(Context context, int notificationId, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
- String title;
- if (msgCount == 1) {
- title = msgSender;
- } else {
- title = context.getString(R.string.unread_messages).replace("%i", String.valueOf(msgCount));
- }
-
+ public static Notification createMessageNotification(Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
- replyIntent.putExtra(INTENT_NOTIF_ID, notificationId);
+ replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
+ replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
- notificationId, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ notif.getNotificationId(), replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label), replyPendingIntent)
@@ -76,9 +69,13 @@ public class ApiTwentyFourPlus {
.setAllowGeneratedReplies(true)
.build();
+ Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself());
+ for (NotifiableMessage message : notif.getMessages()) {
+ style.addMessage(message.getMessage(), message.getTime(), message.getSender());
+ }
+ style.setConversationTitle(notif.getGroupTitle());
+
return new Notification.Builder(context)
- .setContentTitle(title)
- .setContentText(msg)
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
@@ -87,10 +84,11 @@ public class ApiTwentyFourPlus {
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
- .setNumber(msgCount)
+ .setNumber(notif.getMessages().size())
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
+ .setStyle(style)
.addAction(action)
.build();
}
diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java
index 4dd09122f..47655c317 100644
--- a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java
+++ b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java
@@ -11,15 +11,16 @@ import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
-import android.view.ViewTreeObserver;
import org.linphone.R;
-import org.linphone.mediastream.Log;
-import org.linphone.receivers.NotificationBroadcastReceiver;
+import org.linphone.notifications.Notifiable;
+import org.linphone.notifications.NotifiableMessage;
+import org.linphone.notifications.NotificationBroadcastReceiver;
import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_CALL_ID;
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
+import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
@@ -83,23 +84,17 @@ public class ApiTwentySixPlus {
notificationManager.createNotificationChannel(channel);
}
- public static Notification createMessageNotification(Context context, int notificationId, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
- String title;
- if (msgCount == 1) {
- title = msgSender;
- } else {
- title = context.getString(R.string.unread_messages).replace("%i", String.valueOf(msgCount));
- }
-
+ public static Notification createMessageNotification(Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
- replyIntent.putExtra(INTENT_NOTIF_ID, notificationId);
+ replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
+ replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
- notificationId, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ notif.getNotificationId(), replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label), replyPendingIntent)
@@ -107,9 +102,13 @@ public class ApiTwentySixPlus {
.setAllowGeneratedReplies(true)
.build();
+ Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself());
+ for (NotifiableMessage message : notif.getMessages()) {
+ style.addMessage(message.getMessage(), message.getTime(), message.getSender());
+ }
+ style.setConversationTitle(notif.getGroupTitle());
+
return new Notification.Builder(context, context.getString(R.string.notification_channel_id))
- .setContentTitle(title)
- .setContentText(msg)
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
@@ -118,10 +117,11 @@ public class ApiTwentySixPlus {
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
- .setNumber(msgCount)
+ .setNumber(notif.getMessages().size())
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
+ .setStyle(style)
.addAction(action)
.build();
}
diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.java b/app/src/main/java/org/linphone/compatibility/Compatibility.java
index 7ac5c6d41..5c14ba86a 100644
--- a/app/src/main/java/org/linphone/compatibility/Compatibility.java
+++ b/app/src/main/java/org/linphone/compatibility/Compatibility.java
@@ -18,7 +18,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import android.app.AlarmManager;
import android.app.FragmentTransaction;
import android.app.Notification;
import android.app.PendingIntent;
@@ -26,15 +25,11 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Build;
-import android.os.PowerManager;
import android.provider.Settings;
-import android.text.Html;
-import android.text.Spanned;
-import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.TextView;
import org.linphone.mediastream.Version;
+import org.linphone.notifications.Notifiable;
public class Compatibility {
public static final String KEY_TEXT_REPLY = "key_text_reply";
@@ -43,6 +38,7 @@ public class Compatibility {
public static final String INTENT_REPLY_NOTIF_ACTION = "org.linphone.REPLY_ACTION";
public static final String INTENT_HANGUP_CALL_NOTIF_ACTION = "org.linphone.HANGUP_CALL_ACTION";
public static final String INTENT_ANSWER_CALL_NOTIF_ACTION = "org.linphone.ANSWER_CALL_ACTION";
+ public static final String INTENT_LOCAL_IDENTITY = "LOCAL_IDENTITY";
public static void createNotificationChannels(Context context) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
@@ -65,13 +61,13 @@ public class Compatibility {
return ApiTwentyOnePlus.createMissedCallNotification(context, title, text, intent);
}
- public static Notification createMessageNotification(Context context, int notificationId, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
+ public static Notification createMessageNotification(Context context, Notifiable notif, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
- return ApiTwentySixPlus.createMessageNotification(context, notificationId, msgCount, msgSender, msg, contactIcon, intent);
+ return ApiTwentySixPlus.createMessageNotification(context, notif, contactIcon, intent);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
- return ApiTwentyFourPlus.createMessageNotification(context, notificationId, msgCount, msgSender, msg, contactIcon, intent);
+ return ApiTwentyFourPlus.createMessageNotification(context, notif, contactIcon, intent);
}
- return ApiTwentyOnePlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
+ return ApiTwentyOnePlus.createMessageNotification(context, notif.getMessages().size(), msgSender, msg, contactIcon, intent);
}
public static Notification createRepliedNotification(Context context, String reply) {
diff --git a/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java b/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java
index 54bbbc1bd..732532aa0 100644
--- a/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java
+++ b/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java
@@ -85,7 +85,7 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
if (defaultProxyConfig != null) {
ChatRoom room = lc.findOneToOneChatRoom(defaultProxyConfig.getContact(), participant, isSecured);
if (room != null) {
- LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
} else {
if (defaultProxyConfig.getConferenceFactoryUri() != null && (isSecured || !LinphonePreferences.instance().useBasicChatRoomFor1To1())) {
mWaitLayout.setVisibility(View.VISIBLE);
@@ -96,7 +96,7 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
mChatRoom.addParticipants(participants);
} else {
room = lc.getChatRoom(participant);
- LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
}
}
}
@@ -144,7 +144,7 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
- LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null, cr.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
diff --git a/app/src/main/java/org/linphone/firebase/FirebaseIdService.java b/app/src/main/java/org/linphone/firebase/FirebaseIdService.java
index 9841e9dd4..e4087faff 100644
--- a/app/src/main/java/org/linphone/firebase/FirebaseIdService.java
+++ b/app/src/main/java/org/linphone/firebase/FirebaseIdService.java
@@ -30,7 +30,7 @@ public class FirebaseIdService extends FirebaseInstanceIdService {
public void onTokenRefresh() {
// Get updated InstanceID token.
final String refreshedToken = FirebaseInstanceId.getInstance().getToken();
- android.util.Log.i("FirebaseIdService", "[Push Notification] Refreshed token: " + refreshedToken);
+ android.util.Log.i("FirebaseIdService", "[Push Notifiable] Refreshed token: " + refreshedToken);
LinphoneUtils.dispatchOnUIThread(new Runnable() {
@Override
diff --git a/app/src/main/java/org/linphone/firebase/FirebaseMessaging.java b/app/src/main/java/org/linphone/firebase/FirebaseMessaging.java
index 16b4d6225..31041c2fe 100644
--- a/app/src/main/java/org/linphone/firebase/FirebaseMessaging.java
+++ b/app/src/main/java/org/linphone/firebase/FirebaseMessaging.java
@@ -36,10 +36,10 @@ public class FirebaseMessaging extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
- android.util.Log.i("FirebaseMessaging", "[Push Notification] Received");
+ android.util.Log.i("FirebaseMessaging", "[Push Notifiable] Received");
if (!LinphoneService.isReady()) {
- android.util.Log.i("FirebaseMessaging", "[Push Notification] Starting Service");
+ android.util.Log.i("FirebaseMessaging", "[Push Notifiable] Starting Service");
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
} else if (LinphoneManager.isInstanciated() && LinphoneManager.getLc().getCallsNb() == 0) {
LinphoneUtils.dispatchOnUIThread(new Runnable() {
diff --git a/app/src/main/java/org/linphone/fragments/HistoryDetailFragment.java b/app/src/main/java/org/linphone/fragments/HistoryDetailFragment.java
index e20e9becf..0ca1406ff 100644
--- a/app/src/main/java/org/linphone/fragments/HistoryDetailFragment.java
+++ b/app/src/main/java/org/linphone/fragments/HistoryDetailFragment.java
@@ -109,7 +109,7 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
- LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null, cr.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
@@ -198,7 +198,7 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
Address participant = Factory.instance().createAddress(sipUri);
ChatRoom room = lc.findOneToOneChatRoom(lc.getDefaultProxyConfig().getContact(), participant, false);
if (room != null) {
- LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
} else {
ProxyConfig lpc = lc.getDefaultProxyConfig();
if (lpc != null && lpc.getConferenceFactoryUri() != null && !LinphonePreferences.instance().useBasicChatRoomFor1To1()) {
@@ -208,7 +208,7 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
mChatRoom.addParticipant(participant);
} else {
room = lc.getChatRoom(participant);
- LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
+ LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
}
}
} else if (id == R.id.add_contact) {
diff --git a/app/src/main/java/org/linphone/fragments/SettingsFragment.java b/app/src/main/java/org/linphone/fragments/SettingsFragment.java
index 26c2919b8..34577b5ec 100644
--- a/app/src/main/java/org/linphone/fragments/SettingsFragment.java
+++ b/app/src/main/java/org/linphone/fragments/SettingsFragment.java
@@ -1362,9 +1362,9 @@ public class SettingsFragment extends PreferencesListFragment {
boolean value = (Boolean) newValue;
mPrefs.setServiceNotificationVisibility(value);
if (value) {
- LinphoneService.instance().showServiceNotification();
+ LinphoneService.instance().getNotificationManager().startForeground();
} else {
- LinphoneService.instance().hideServiceNotification();
+ LinphoneService.instance().getNotificationManager().stopForeground();
}
return true;
}
diff --git a/app/src/main/java/org/linphone/notifications/Notifiable.java b/app/src/main/java/org/linphone/notifications/Notifiable.java
new file mode 100644
index 000000000..b0d6f675c
--- /dev/null
+++ b/app/src/main/java/org/linphone/notifications/Notifiable.java
@@ -0,0 +1,86 @@
+package org.linphone.notifications;
+
+/*
+Notifiable.java
+Copyright (C) 2018 Belledonne Communications, Grenoble, France
+
+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 2
+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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Notifiable {
+ int mNotificationId;
+ List mMessages;
+ boolean mIsGroup;
+ String mGroupTitle;
+ String mLocalIdentity;
+ String mMyself;
+
+ public Notifiable(int id) {
+ mNotificationId = id;
+ mMessages = new ArrayList<>();
+ mIsGroup = false;
+ }
+
+ public int getNotificationId() {
+ return mNotificationId;
+ }
+
+ public void resetMessages() {
+ mMessages = new ArrayList<>();
+ }
+
+ public void addMessage(NotifiableMessage notifMessage) {
+ mMessages.add(notifMessage);
+ }
+
+ public List getMessages() {
+ return mMessages;
+ }
+
+ public boolean isGroup() {
+ return mIsGroup;
+ }
+
+ public void setIsGroup(boolean isGroup) {
+ mIsGroup = isGroup;
+ }
+
+ public String getGroupTitle() {
+ return mGroupTitle;
+ }
+
+ public void setGroupTitle(String title) {
+ mGroupTitle = title;
+ }
+
+ public String getMyself() {
+ return mMyself;
+ }
+
+ public void setMyself(String myself) {
+ mMyself = myself;
+ }
+
+ public String getLocalIdentity() {
+ return mLocalIdentity;
+ }
+
+ public void setLocalIdentity(String localIdentity) {
+ mLocalIdentity = localIdentity;
+ }
+}
diff --git a/app/src/main/java/org/linphone/notifications/NotifiableMessage.java b/app/src/main/java/org/linphone/notifications/NotifiableMessage.java
new file mode 100644
index 000000000..20639379e
--- /dev/null
+++ b/app/src/main/java/org/linphone/notifications/NotifiableMessage.java
@@ -0,0 +1,44 @@
+package org.linphone.notifications;
+
+/*
+NotifiableMessage.java
+Copyright (C) 2018 Belledonne Communications, Grenoble, France
+
+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 2
+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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+public class NotifiableMessage {
+ String mMessage;
+ String mSender;
+ long mTime;
+
+ public NotifiableMessage(String message, String sender, long time) {
+ mMessage = message;
+ mSender = sender;
+ mTime = time;
+ }
+
+ public String getMessage() {
+ return mMessage;
+ }
+
+ public String getSender() {
+ return mSender;
+ }
+
+ public long getTime() {
+ return mTime;
+ }
+}
diff --git a/app/src/main/java/org/linphone/receivers/NotificationBroadcastReceiver.java b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.java
similarity index 52%
rename from app/src/main/java/org/linphone/receivers/NotificationBroadcastReceiver.java
rename to app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.java
index 0bdb3f336..31e560f6d 100644
--- a/app/src/main/java/org/linphone/receivers/NotificationBroadcastReceiver.java
+++ b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.java
@@ -1,4 +1,4 @@
-package org.linphone.receivers;
+package org.linphone.notifications;
/*
NotificationBroadcastReceiver.java
@@ -29,48 +29,82 @@ import android.os.Bundle;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneService;
+import org.linphone.R;
import org.linphone.activities.LinphoneActivity;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.Address;
import org.linphone.core.Call;
import org.linphone.core.ChatMessage;
+import org.linphone.core.ChatMessageListenerStub;
import org.linphone.core.ChatRoom;
import org.linphone.core.Core;
import org.linphone.core.ProxyConfig;
-import org.linphone.core.Reason;
+import org.linphone.mediastream.Log;
public class NotificationBroadcastReceiver extends BroadcastReceiver {
@Override
- public void onReceive(Context context, Intent intent) {
+ public void onReceive(final Context context, Intent intent) {
+ final int notifId = intent.getIntExtra(Compatibility.INTENT_NOTIF_ID, 0);
+ final String localyIdentity = intent.getStringExtra(Compatibility.INTENT_LOCAL_IDENTITY);
+
if (intent.getAction() == Compatibility.INTENT_REPLY_NOTIF_ACTION) {
- String reply = getMessageText(intent).toString();
- if (reply == null) return;
- Notification replied = Compatibility.createRepliedNotification(context, reply);
- if (replied == null) return;
- int notifId = intent.getIntExtra(Compatibility.INTENT_NOTIF_ID, 0);
- String remoteSipAddr = LinphoneService.instance().getSipUriForNotificationId(notifId);
+ final String reply = getMessageText(intent).toString();
+ if (reply == null) {
+ Log.e("Couldn't get reply text");
+ onError(context, notifId);
+ return;
+ }
+ String remoteSipAddr = LinphoneService.instance().getNotificationManager().getSipUriForNotificationId(notifId);
Core core = LinphoneManager.getLc();
- if (core == null) return;
- ProxyConfig proxyConfig = core.getDefaultProxyConfig();
- if (proxyConfig == null) return;
- Address localAddr = proxyConfig.getIdentityAddress();
+ if (core == null) {
+ Log.e("Couldn't get Core instance");
+ onError(context, notifId);
+ return;
+ }
+
Address remoteAddr = core.interpretUrl(remoteSipAddr);
- if (localAddr == null || remoteAddr == null) return;
+ if (remoteAddr == null) {
+ Log.e("Couldn't interpret remote address " + remoteSipAddr);
+ onError(context, notifId);
+ return;
+ }
+
+ Address localAddr = core.interpretUrl(localyIdentity);
+ if (localAddr == null) {
+ Log.e("Couldn't interpret local address " + localyIdentity);
+ onError(context, notifId);
+ return;
+ }
+
ChatRoom room = core.findChatRoom(remoteAddr, localAddr);
- if (room == null) return;
+ if (room == null) {
+ Log.e("Couldn't find chat room for remote address " + remoteSipAddr + " and local address " + localyIdentity);
+ onError(context, notifId);
+ return;
+ }
room.markAsRead();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().displayMissedChats(LinphoneManager.getInstance().getUnreadMessageCount());
}
+
ChatMessage msg = room.createMessage(reply);
msg.send();
-
- LinphoneService.instance().sendNotification(replied, notifId);
+ msg.setListener(new ChatMessageListenerStub() {
+ @Override
+ public void onMsgStateChanged(ChatMessage msg, ChatMessage.State state) {
+ if (state == ChatMessage.State.Delivered) {
+ Notification replied = Compatibility.createRepliedNotification(context, reply);
+ LinphoneService.instance().getNotificationManager().sendNotification(notifId, replied);
+ } else if (state == ChatMessage.State.NotDelivered) {
+ Log.e("Couldn't send reply, message is not delivered");
+ onError(context, notifId);
+ }
+ }
+ });
} else if (intent.getAction() == Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION || intent.getAction() == Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION) {
- int callId = intent.getIntExtra(Compatibility.INTENT_CALL_ID, 0);
- String remoteAddr = LinphoneService.instance().getSipUriForCallNotificationId(callId);
+ String remoteAddr = LinphoneService.instance().getNotificationManager().getSipUriForCallNotificationId(notifId);
Core core = LinphoneManager.getLc();
if (core == null) return;
@@ -85,6 +119,11 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver {
}
}
+ private void onError(Context context, int notifId) {
+ Notification replyError = Compatibility.createRepliedNotification(context, context.getString(R.string.error));
+ LinphoneService.instance().getNotificationManager().sendNotification(notifId, replyError);
+ }
+
@TargetApi(20)
private CharSequence getMessageText(Intent intent) {
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.java b/app/src/main/java/org/linphone/notifications/NotificationsManager.java
new file mode 100644
index 000000000..34dfa6256
--- /dev/null
+++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.java
@@ -0,0 +1,308 @@
+package org.linphone.notifications;
+
+/*
+NotificationsManager.java
+Copyright (C) 2018 Belledonne Communications, Grenoble, France
+
+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 2
+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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.provider.MediaStore;
+
+import org.linphone.LinphoneManager;
+import org.linphone.LinphonePreferences;
+import org.linphone.LinphoneService;
+import org.linphone.LinphoneUtils;
+import org.linphone.R;
+import org.linphone.activities.LinphoneActivity;
+import org.linphone.compatibility.Compatibility;
+import org.linphone.contacts.ContactsManager;
+import org.linphone.contacts.LinphoneContact;
+import org.linphone.core.Address;
+import org.linphone.core.Call;
+import org.linphone.mediastream.Version;
+
+import java.util.HashMap;
+
+import static android.content.Context.NOTIFICATION_SERVICE;
+
+public class NotificationsManager {
+ private static final int SERVICE_NOTIF_ID = 1;
+ private static final int MISSED_CALLS_NOTIF_ID = 2;
+ private static final int IN_APP_NOTIF_ID = 3;
+
+ private Context mContext;
+ private NotificationManager mNM;
+ private HashMap mChatNotifMap, mCallNotifMap;
+ private int mLastNotificationId;
+ private PendingIntent mPendingIntent;
+ private Notification mServiceNotification;
+
+ public NotificationsManager(Context context) {
+ mContext = context;
+ mChatNotifMap = new HashMap<>();
+ mCallNotifMap = new HashMap<>();
+
+ mNM = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
+ mNM.cancelAll();
+
+ mLastNotificationId = 5; // Do not conflict with hardcoded notifications ids !
+
+ Compatibility.createNotificationChannels(mContext);
+
+ Intent notifIntent = new Intent(mContext, LinphoneService.instance().getIncomingReceivedActivity());
+ notifIntent.putExtra("Notifiable", true);
+ mPendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ //Disable service notification for Android O
+ if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
+ LinphonePreferences.instance().setServiceNotificationVisibility(false);
+ }
+
+ Bitmap bm = null;
+ try {
+ bm = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_launcher);
+ } catch (Exception e) {
+ }
+ mServiceNotification = Compatibility.createNotification(mContext, mContext.getString(R.string.service_name), "",
+ R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, mPendingIntent, true,
+ Notification.PRIORITY_MIN);
+
+ if (isServiceNotificationDisplayed()) {
+ startForeground();
+ }
+ }
+
+ public void destroy() {
+ mNM.cancelAll();
+ }
+
+ public void startForeground() {
+ LinphoneService.instance().startForeground(SERVICE_NOTIF_ID, mServiceNotification);
+ }
+
+ public void stopForeground() {
+ LinphoneService.instance().stopForeground(true);
+ }
+
+ public void sendNotification(int id, Notification notif) {
+ mNM.notify(id, notif);
+ }
+
+ public void resetMessageNotifCount(String address) {
+ Notifiable notif = mChatNotifMap.get(address);
+ if (notif != null) {
+ notif.resetMessages();
+ mNM.cancel(notif.getNotificationId());
+ }
+ }
+
+ public boolean isServiceNotificationDisplayed() {
+ return LinphonePreferences.instance().getServiceNotificationVisibility();
+ }
+
+ public String getSipUriForNotificationId(int notificationId) {
+ for (String addr : mChatNotifMap.keySet()) {
+ if (mChatNotifMap.get(addr).getNotificationId() == notificationId) {
+ return addr;
+ }
+ }
+ return null;
+ }
+
+ public void displayGroupChatMessageNotification(String subject, String conferenceAddress, String fromName, Uri fromPictureUri, String message, Address localIdentity) {
+ Intent notifIntent = new Intent(mContext, LinphoneActivity.class);
+ notifIntent.putExtra("GoToChat", true);
+ notifIntent.putExtra("ChatContactSipUri", conferenceAddress);
+ PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ Notifiable notif = mChatNotifMap.get(conferenceAddress);
+ NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, 0);
+ if (notif == null) {
+ notif = new Notifiable(mLastNotificationId);
+ mLastNotificationId += 1;
+ mChatNotifMap.put(conferenceAddress, notif);
+ }
+ notif.addMessage(notifMessage);
+ notif.setIsGroup(true);
+ notif.setGroupTitle(subject);
+ notif.setMyself(LinphoneUtils.getAddressDisplayName(localIdentity));
+ notif.setLocalIdentity(localIdentity.asString());
+
+ Bitmap bm;
+ if (fromPictureUri != null) {
+ try {
+ bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), fromPictureUri);
+ } catch (Exception e) {
+ bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.chat_group_avatar);
+ }
+ } else {
+ bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.topbar_avatar);
+ }
+ Notification notification = Compatibility.createMessageNotification(mContext, notif, subject,
+ mContext.getString(R.string.group_chat_notif).replace("%1", fromName).replace("%2", message), bm, pendingIntent);
+ sendNotification(notif.getNotificationId(), notification);
+ }
+
+ public void displayMessageNotification(String fromSipUri, String fromName, Uri fromPictureUri, String message, Address localIdentity) {
+ Intent notifIntent = new Intent(mContext, LinphoneActivity.class);
+ notifIntent.putExtra("GoToChat", true);
+ notifIntent.putExtra("ChatContactSipUri", fromSipUri);
+ PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ if (fromName == null) {
+ fromName = fromSipUri;
+ }
+
+ Notifiable notif = mChatNotifMap.get(fromSipUri);
+ NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, 0);
+ if (notif == null) {
+ notif = new Notifiable(mLastNotificationId);
+ mLastNotificationId += 1;
+ mChatNotifMap.put(fromSipUri, notif);
+ }
+ notif.addMessage(notifMessage);
+ notif.setIsGroup(false);
+ notif.setMyself(LinphoneUtils.getAddressDisplayName(localIdentity));
+ notif.setLocalIdentity(localIdentity.asString());
+
+ Bitmap bm;
+ if (fromPictureUri != null) {
+ try {
+ bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), fromPictureUri);
+ } catch (Exception e) {
+ bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.topbar_avatar);
+ }
+ } else {
+ bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.topbar_avatar);
+ }
+ Notification notification = Compatibility.createMessageNotification(mContext, notif, fromName, message, bm, pendingIntent);
+ sendNotification(notif.getNotificationId(), notification);
+ }
+
+ public void displayMissedCallNotification(Call call) {
+ Intent missedCallNotifIntent = new Intent(mContext, LinphoneService.instance().getIncomingReceivedActivity());
+ missedCallNotifIntent.putExtra("GoToHistory", true);
+ PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, missedCallNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ int missedCallCount = LinphoneManager.getLcIfManagerNotDestroyedOrNull().getMissedCallsCount();
+ String body;
+ if (missedCallCount > 1) {
+ body = mContext.getString(R.string.missed_calls_notif_body).replace("%i", String.valueOf(missedCallCount));
+ } else {
+ Address address = call.getRemoteAddress();
+ LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
+ if (c != null) {
+ body = c.getFullName();
+ } else {
+ body = address.getDisplayName();
+ if (body == null) {
+ body = address.asStringUriOnly();
+ }
+ }
+ }
+ Notification notif = Compatibility.createMissedCallNotification(mContext, mContext.getString(R.string.missed_calls_notif_title), body, pendingIntent);
+ sendNotification(MISSED_CALLS_NOTIF_ID, notif);
+ }
+
+ public void displayCallNotification(Call call) {
+ if (call == null) return;
+
+ Address address = call.getRemoteAddress();
+ String addressAsString = address.asStringUriOnly();
+ Notifiable notif = mCallNotifMap.get(addressAsString);
+ if (notif == null) {
+ notif = new Notifiable(mLastNotificationId);
+ mLastNotificationId += 1;
+ mCallNotifMap.put(addressAsString, notif);
+ }
+
+ if (!isServiceNotificationDisplayed()) {
+ if (call.getCore().getCallsNb() == 0) {
+ stopForeground();
+ } else {
+ startForeground();
+ }
+ }
+
+ int notificationTextId;
+ int iconId;
+ switch (call.getState()) {
+ case Released:
+ case End:
+ mNM.cancel(notif.getNotificationId());
+ mCallNotifMap.remove(addressAsString);
+ return;
+ case Paused:
+ case PausedByRemote:
+ case Pausing:
+ iconId = R.drawable.topbar_call_notification;
+ notificationTextId = R.string.incall_notif_paused;
+ break;
+ default:
+ if (call.getCurrentParams().videoEnabled()) {
+ iconId = R.drawable.topbar_videocall_notification;
+ notificationTextId = R.string.incall_notif_video;
+ } else {
+ iconId = R.drawable.topbar_call_notification;
+ notificationTextId = R.string.incall_notif_active;
+ }
+ break;
+ }
+
+ LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
+ Uri pictureUri = contact != null ? contact.getPhotoUri() : null;
+ Bitmap bm;
+ try {
+ bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), pictureUri);
+ } catch (Exception e) {
+ bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.avatar);
+ }
+ String name = LinphoneUtils.getAddressDisplayName(address);
+
+ boolean showAnswerAction = call.getState() == Call.State.IncomingReceived || call.getState() == Call.State.IncomingEarlyMedia;
+ Notification notification = Compatibility.createInCallNotification(mContext, notif.getNotificationId(),
+ showAnswerAction, mContext.getString(R.string.service_name),
+ mContext.getString(notificationTextId), iconId, bm, name, mPendingIntent);
+
+ sendNotification(notif.getNotificationId(), notification);
+ }
+
+ public String getSipUriForCallNotificationId(int notificationId) {
+ for (String addr : mCallNotifMap.keySet()) {
+ if (mCallNotifMap.get(addr).getNotificationId() == notificationId) {
+ return addr;
+ }
+ }
+ return null;
+ }
+
+ public void displayInappNotification(String message) {
+ Intent notifIntent = new Intent(mContext, LinphoneActivity.class);
+ notifIntent.putExtra("GoToInapp", true);
+ PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ Notification notif = Compatibility.createSimpleNotification(mContext, mContext.getString(R.string.inapp_notification_title), message, pendingIntent);
+
+ sendNotification(IN_APP_NOTIF_ID, notif);
+ }
+}