Do not longer start incoming call activity from Service, instead use fullscreen intent in incoming call notification

This commit is contained in:
Sylvain Berfini 2019-08-28 12:35:13 +02:00
parent d1b921f4f0
commit 9776c4cd50
9 changed files with 122 additions and 85 deletions

View file

@ -23,6 +23,7 @@ Group changes to describe their impact on the project, as follows:
## Changed
- Call statistics are now available for each call & conference
- Added our own devices in LIME encrypted chatrooms' security view
- No longer display incoming call activity from Service, instead use incoming call notification with full screen intent
## [4.1.0] - 2019-05-03

View file

@ -47,6 +47,8 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Needed to get the current Do Not Disturb policy -->
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<!-- Needed for full screen intent in notifications -->
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<supports-screens
android:anyDensity="true"

View file

@ -154,7 +154,9 @@ public final class LinphoneService extends Service {
if (state == Call.State.IncomingReceived
|| state == State.IncomingEarlyMedia) {
if (!mLinphoneManager.getCallGsmON()) onIncomingReceived();
// Now we rely on the fullscreen intent of the call incoming
// notification
// if (!mLinphoneManager.getCallGsmON()) onIncomingReceived();
} else if (state == State.OutgoingInit) {
onOutgoingStarted();
} else if (state == State.End

View file

@ -119,6 +119,7 @@ class ApiTwentyFourPlus {
.addAction(getCallDeclineAction(context, callId));
if (showAnswerAction) {
builder.setFullScreenIntent(intent, true);
builder.addAction(getCallAnswerAction(context, callId));
}

View file

@ -75,28 +75,36 @@ class ApiTwentyOnePlus {
public static Notification createInCallNotification(
Context context,
boolean isIncoming,
String msg,
int iconID,
Bitmap contactIcon,
String contactName,
PendingIntent intent) {
return new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setLights(
ContextCompat.getColor(context, R.color.notification_led_color),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setShowWhen(true)
.build();
Notification.Builder builder =
new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setOngoing(true)
.setLights(
ContextCompat.getColor(context, R.color.notification_led_color),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setShowWhen(true);
if (isIncoming) {
builder.setFullScreenIntent(intent, true);
}
return builder.build();
}
public static Notification createNotification(

View file

@ -143,7 +143,7 @@ class ApiTwentySixPlus {
public static Notification createInCallNotification(
Context context,
int callId,
boolean showAnswerAction,
boolean isIncoming,
String msg,
int iconID,
Bitmap contactIcon,
@ -153,7 +153,10 @@ class ApiTwentySixPlus {
Notification.Builder builder =
new Notification.Builder(
context,
context.getString(R.string.notification_service_channel_id))
isIncoming
? context.getString(R.string.notification_channel_id)
: context.getString(
R.string.notification_service_channel_id))
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
@ -162,14 +165,16 @@ class ApiTwentySixPlus {
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setPriority(
isIncoming ? Notification.PRIORITY_HIGH : Notification.PRIORITY_LOW)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setOngoing(true)
.setColor(context.getColor(R.color.notification_led_color))
.addAction(ApiTwentyFourPlus.getCallDeclineAction(context, callId));
if (showAnswerAction) {
if (isIncoming) {
builder.setFullScreenIntent(intent, true);
builder.addAction(ApiTwentyFourPlus.getCallAnswerAction(context, callId));
}
return builder.build();

View file

@ -73,14 +73,6 @@ public class Compatibility {
return ApiTwentyOnePlus.createSimpleNotification(context, title, text, intent);
}
public static Notification createMissedCallNotification(
Context context, String title, String text, PendingIntent intent) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createMissedCallNotification(context, title, text, intent);
}
return ApiTwentyOnePlus.createMissedCallNotification(context, title, text, intent);
}
public static Notification createMessageNotification(
Context context,
Notifiable notif,
@ -109,10 +101,18 @@ public class Compatibility {
return null;
}
public static Notification createMissedCallNotification(
Context context, String title, String text, PendingIntent intent) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createMissedCallNotification(context, title, text, intent);
}
return ApiTwentyOnePlus.createMissedCallNotification(context, title, text, intent);
}
public static Notification createInCallNotification(
Context context,
int callId,
boolean showAnswerAction,
boolean isIncoming,
String msg,
int iconID,
Bitmap contactIcon,
@ -120,27 +120,13 @@ public class Compatibility {
PendingIntent intent) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createInCallNotification(
context,
callId,
showAnswerAction,
msg,
iconID,
contactIcon,
contactName,
intent);
context, callId, isIncoming, msg, iconID, contactIcon, contactName, intent);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.createInCallNotification(
context,
callId,
showAnswerAction,
msg,
iconID,
contactIcon,
contactName,
intent);
context, callId, isIncoming, msg, iconID, contactIcon, contactName, intent);
}
return ApiTwentyOnePlus.createInCallNotification(
context, msg, iconID, contactIcon, contactName, intent);
context, isIncoming, msg, iconID, contactIcon, contactName, intent);
}
public static Notification createNotification(

View file

@ -29,15 +29,15 @@ public class Notifiable {
private String mGroupTitle;
private String mLocalIdentity;
private String mMyself;
private int iconId;
private int textId;
private int mIconId;
private int mTextId;
public Notifiable(int id) {
mNotificationId = id;
mMessages = new ArrayList<>();
mIsGroup = false;
iconId = 0;
textId = 0;
mIconId = 0;
mTextId = 0;
}
public int getNotificationId() {
@ -89,18 +89,29 @@ public class Notifiable {
}
public int getIconResourceId() {
return iconId;
return mIconId;
}
public void setIconResourceId(int id) {
iconId = id;
mIconId = id;
}
public int getTextResourceId() {
return textId;
return mTextId;
}
public void setTextResourceId(int id) {
textId = id;
mTextId = id;
}
public String toString() {
return "Id: "
+ mNotificationId
+ ", local identity: "
+ mLocalIdentity
+ ", myself: "
+ mMyself
+ ", isGrouped: "
+ mIsGroup;
}
}

View file

@ -54,6 +54,7 @@ import org.linphone.core.Reason;
import org.linphone.core.tools.Log;
import org.linphone.history.HistoryActivity;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.DeviceUtils;
import org.linphone.utils.FileUtils;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
@ -114,6 +115,8 @@ public class NotificationsManager {
true);
if (isServiceNotificationDisplayed()) {
Log.i(
"[Notifications Manager] Background service mode enabled, displaying notification");
startForeground();
}
@ -219,6 +222,7 @@ public class NotificationsManager {
// When a message is received by a push, it will create a LinphoneService
// but it might be getting killed quite quickly after that
// causing the notification to be missed by the user...
Log.i("[Notifications Manager] Getting destroyed, clearing Service & Call notifications");
if (mCurrentForegroundServiceNotification > 0) {
mNM.cancel(mCurrentForegroundServiceNotification);
@ -239,16 +243,19 @@ public class NotificationsManager {
}
public void startForeground() {
Log.i("[Notifications Manager] Starting Service as foreground");
LinphoneService.instance().startForeground(SERVICE_NOTIF_ID, mServiceNotification);
mCurrentForegroundServiceNotification = SERVICE_NOTIF_ID;
}
private void startForeground(Notification notification, int id) {
Log.i("[Notifications Manager] Starting Service as foreground while in call");
LinphoneService.instance().startForeground(id, notification);
mCurrentForegroundServiceNotification = id;
}
public void stopForeground() {
Log.i("[Notifications Manager] Stopping Service as foreground");
LinphoneService.instance().stopForeground(true);
mCurrentForegroundServiceNotification = 0;
}
@ -256,6 +263,8 @@ public class NotificationsManager {
public void removeForegroundServiceNotificationIfPossible() {
if (mCurrentForegroundServiceNotification == SERVICE_NOTIF_ID
&& !isServiceNotificationDisplayed()) {
Log.i(
"[Notifications Manager] Linphone has started after device boot, stopping Service as foreground");
stopForeground();
}
}
@ -268,9 +277,15 @@ public class NotificationsManager {
}
public void sendNotification(int id, Notification notif) {
Log.i("[Notifications Manager] Notifying " + id);
mNM.notify(id, notif);
}
public void dismissNotification(int notifId) {
Log.i("[Notifications Manager] Dismissing " + notifId);
mNM.cancel(notifId);
}
public void resetMessageNotifCount(String address) {
Notifiable notif = mChatNotifMap.get(address);
if (notif != null) {
@ -312,6 +327,7 @@ public class NotificationsManager {
mLastNotificationId += 1;
mChatNotifMap.put(conferenceAddress, notif);
}
Log.i("[Notifications Manager] Creating group chat message notifiable " + notif);
notifMessage.setSenderBitmap(bm);
notif.addMessage(notifMessage);
@ -367,6 +383,7 @@ public class NotificationsManager {
mLastNotificationId += 1;
mChatNotifMap.put(fromSipUri, notif);
}
Log.i("[Notifications Manager] Creating chat message notifiable " + notif);
notifMessage.setSenderBitmap(bm);
notif.addMessage(notifMessage);
@ -409,6 +426,7 @@ public class NotificationsManager {
body =
mContext.getString(R.string.missed_calls_notif_body)
.replace("%i", String.valueOf(missedCallCount));
Log.i("[Notifications Manager] Creating missed calls notification");
} else {
Address address = call.getRemoteAddress();
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
@ -420,6 +438,7 @@ public class NotificationsManager {
body = address.asStringUriOnly();
}
}
Log.i("[Notifications Manager] Creating missed call notification");
}
Notification notif =
@ -434,18 +453,17 @@ public class NotificationsManager {
public void displayCallNotification(Call call) {
if (call == null) return;
Intent callNotifIntent;
Class callNotifIntentClass = CallActivity.class;
if (call.getState() == Call.State.IncomingReceived
|| call.getState() == Call.State.IncomingEarlyMedia) {
callNotifIntent = new Intent(mContext, CallIncomingActivity.class);
callNotifIntentClass = CallIncomingActivity.class;
} else if (call.getState() == Call.State.OutgoingInit
|| call.getState() == Call.State.OutgoingProgress
|| call.getState() == Call.State.OutgoingRinging
|| call.getState() == Call.State.OutgoingEarlyMedia) {
callNotifIntent = new Intent(mContext, CallOutgoingActivity.class);
} else {
callNotifIntent = new Intent(mContext, CallActivity.class);
callNotifIntentClass = CallOutgoingActivity.class;
}
Intent callNotifIntent = new Intent(mContext, callNotifIntentClass);
callNotifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent =
@ -467,6 +485,8 @@ public class NotificationsManager {
case Released:
case End:
if (mCurrentForegroundServiceNotification == notif.getNotificationId()) {
Log.i(
"[Notifications Manager] Call ended, stopping notification used to keep service alive");
// Call is released, remove service notification to allow for an other call to
// be service notification
stopForeground();
@ -507,39 +527,59 @@ public class NotificationsManager {
&& notif.getTextResourceId() == notificationTextId) {
// Notification hasn't changed, do not "update" it to avoid blinking
return;
} else if (notif.getTextResourceId() == R.string.incall_notif_incoming) {
// If previous notif was incoming call, as we will switch channels, dismiss it first
dismissNotification(notif.getNotificationId());
}
notif.setIconResourceId(iconId);
notif.setTextResourceId(notificationTextId);
Log.i(
"[Notifications Manager] Call notification notifiable is "
+ notif
+ ", pending intent "
+ callNotifIntentClass);
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
Uri pictureUri = contact != null ? contact.getPhotoUri() : null;
Bitmap bm = ImageUtils.getRoundBitmapFromUri(mContext, pictureUri);
String name = LinphoneUtils.getAddressDisplayName(address);
boolean isIncoming = callNotifIntentClass == CallIncomingActivity.class;
boolean showAnswerAction =
call.getState() == Call.State.IncomingReceived
|| call.getState() == Call.State.IncomingEarlyMedia;
Notification notification =
Compatibility.createInCallNotification(
mContext,
notif.getNotificationId(),
showAnswerAction,
isIncoming,
mContext.getString(notificationTextId),
iconId,
bm,
name,
pendingIntent);
if (!isServiceNotificationDisplayed()) {
// Don't use incoming call notification as foreground service notif !
if (!isServiceNotificationDisplayed() && !isIncoming) {
if (call.getCore().getCallsNb() == 0) {
Log.i(
"[Notifications Manager] Foreground service mode is disabled, stopping call notification used to keep it alive");
stopForeground();
} else {
if (mCurrentForegroundServiceNotification == 0) {
startForeground(notification, notif.getNotificationId());
if (DeviceUtils.isAppUserRestricted(mContext)) {
Log.w(
"[Notifications Manager] App has been restricted, can't use call notification to keep service alive !");
sendNotification(notif.getNotificationId(), notification);
} else {
Log.i(
"[Notifications Manager] Foreground service mode is disabled, using call notification to keep it alive");
startForeground(notification, notif.getNotificationId());
}
} else {
sendNotification(notif.getNotificationId(), notification);
}
}
} else {
sendNotification(notif.getNotificationId(), notification);
}
}
@ -552,25 +592,6 @@ public class NotificationsManager {
return null;
}
/*public void displayInappNotification(String message) {
Intent notifIntent = new Intent(mContext, InAppPurchaseActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext, IN_APP_NOTIF_ID, 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);
}*/
public void dismissNotification(int notifId) {
mNM.cancel(notifId);
}
private void createNotification(
ChatRoom cr,
LinphoneContact contact,