From 7bc0335d06077651790007bfe6518cbe174dcd5a Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Fri, 25 Aug 2017 16:10:04 +0200 Subject: [PATCH] Fix crash at launch on Android O --- AndroidManifestLibrary.xml | 2 +- build.gradle | 14 +++-- src/android/org/linphone/ContactsManager.java | 13 +++- src/android/org/linphone/LinphoneManager.java | 11 ++-- src/android/org/linphone/LinphoneService.java | 5 +- .../linphone/compatibility/ApiElevenPlus.java | 24 +++---- .../compatibility/ApiNineteenPlus.java | 2 +- .../compatibility/ApiSixteenPlus.java | 12 ++-- .../compatibility/ApiTwentyOnePlus.java | 14 ++--- .../compatibility/ApiTwentySixPlus.java | 63 +++++++++++++++++++ .../compatibility/ApiTwentyThreePlus.java | 2 +- .../linphone/compatibility/Compatibility.java | 8 ++- submodules/bctoolbox | 2 +- submodules/belcard | 2 +- submodules/belle-sip | 2 +- submodules/cmake-builder | 2 +- submodules/linphone | 2 +- submodules/mediastreamer2 | 2 +- submodules/oRTP | 2 +- 19 files changed, 131 insertions(+), 53 deletions(-) create mode 100644 src/android/org/linphone/compatibility/ApiTwentySixPlus.java diff --git a/AndroidManifestLibrary.xml b/AndroidManifestLibrary.xml index 3ad8e2de1..4de7ac7a3 100755 --- a/AndroidManifestLibrary.xml +++ b/AndroidManifestLibrary.xml @@ -7,5 +7,5 @@ + android:targetSdkVersion="26"/> diff --git a/build.gradle b/build.gradle index a5e482eb9..2b8327b64 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ dependencies { androidTestCompile 'junit:junit:4.12' compile group: 'org.apache.commons', name: 'commons-compress', version: '1.14' if (firebaseEnable()) { - compile 'com.google.firebase:firebase-messaging:11.0.2' + compile 'com.google.firebase:firebase-messaging:11.0.4' } else { compile fileTree(include: 'gcm.jar', dir: 'libs') compile 'com.android.support:support-v4:+' @@ -183,10 +183,12 @@ android.applicationVariants.all { variant -> }) } -task runApplication << { - def result = exec { - executable = android.getAdbExecutable().toString() - ignoreExitValue true - args = ['shell', 'monkey', '-p', getPackageName(), '-c', 'android.intent.category.LAUNCHER', '1'] +task runApplication { + doLast { + def result = exec { + executable = android.getAdbExecutable().toString() + ignoreExitValue true + args = ['shell', 'monkey', '-p', getPackageName(), '-c', 'android.intent.category.LAUNCHER', '1'] + } } } diff --git a/src/android/org/linphone/ContactsManager.java b/src/android/org/linphone/ContactsManager.java index ee5830c3e..25d4b956b 100644 --- a/src/android/org/linphone/ContactsManager.java +++ b/src/android/org/linphone/ContactsManager.java @@ -19,6 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package org.linphone; +import android.*; +import android.Manifest; import android.accounts.Account; import android.accounts.AccountManager; import android.content.ContentProviderOperation; @@ -42,6 +44,7 @@ import org.linphone.core.LinphoneFriend; import org.linphone.core.LinphoneFriendImpl; import org.linphone.core.LinphoneProxyConfig; import org.linphone.mediastream.Log; +import org.linphone.mediastream.Version; import java.util.ArrayList; import java.util.Collections; @@ -171,9 +174,15 @@ public class ContactsManager extends ContentObserver { public boolean hasContactsAccess() { if (context == null) return false; - int contacts = context.getPackageManager().checkPermission(android.Manifest.permission.READ_CONTACTS, context.getPackageName()); + boolean contactsR = (PackageManager.PERMISSION_GRANTED == + context.getPackageManager().checkPermission(android.Manifest.permission.READ_CONTACTS, context.getPackageName())); + boolean contactsW = true; context.getPackageManager(); - return contacts == PackageManager.PERMISSION_GRANTED && !context.getResources().getBoolean(R.bool.force_use_of_linphone_friends); + if (Version.sdkAboveOrEqual(Version.API26_O_80)) { + contactsW = (PackageManager.PERMISSION_GRANTED == + context.getPackageManager().checkPermission(Manifest.permission.WRITE_CONTACTS, context.getPackageName())); + } + return contactsW && contactsR && !context.getResources().getBoolean(R.bool.force_use_of_linphone_friends); } public void setLinphoneContactsPrefered(boolean isPrefered) { diff --git a/src/android/org/linphone/LinphoneManager.java b/src/android/org/linphone/LinphoneManager.java index e12b79e92..ab72b1432 100644 --- a/src/android/org/linphone/LinphoneManager.java +++ b/src/android/org/linphone/LinphoneManager.java @@ -751,7 +751,6 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag mTimer.schedule(lTask, 0, 20); } catch (Exception e) { - Log.e(e); Log.e(e, "Cannot start linphone"); } } @@ -1180,6 +1179,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag } LinphoneAddress from = message.getFrom(); + String to = message.getTo().asString(); String textMessage = (message.getFileTransferInformation() != null) ? getString(R.string.content_description_incoming_file) : message.getText(); @@ -1187,9 +1187,9 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(from); if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat_message_notification)) { if (contact != null) { - LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(), contact.getFullName(), textMessage); + LinphoneService.instance().displayMessageNotification(to, from.asStringUriOnly(), contact.getFullName(), textMessage); } else { - LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(), from.getUserName(), textMessage); + LinphoneService.instance().displayMessageNotification(to, from.asStringUriOnly(), from.getUserName(), textMessage); } } } catch (Exception e) { @@ -1205,15 +1205,16 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag } final LinphoneAddress from = message.getFrom(); + String to = message.getTo().asString(); try { final LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(from); if (LinphoneActivity.instance().isOnBackground()) { if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat_message_notification)) { if (contact != null) { - LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(), contact.getFullName() + LinphoneService.instance().displayMessageNotification(to, from.asStringUriOnly(), contact.getFullName() , getString(R.string.message_cant_be_decrypted_notif)); } else { - LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(), from.getUserName() + LinphoneService.instance().displayMessageNotification(to, from.asStringUriOnly(), from.getUserName() , getString(R.string.message_cant_be_decrypted_notif)); } } diff --git a/src/android/org/linphone/LinphoneService.java b/src/android/org/linphone/LinphoneService.java index 7a853ca44..ad9f5ec3f 100644 --- a/src/android/org/linphone/LinphoneService.java +++ b/src/android/org/linphone/LinphoneService.java @@ -431,6 +431,7 @@ public final class LinphoneService extends Service { Log.e(e, "Couldn't find startForeground or stopForeground"); } + getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, ContactsManager.getInstance()); if (displayServiceNotification()) { @@ -586,7 +587,7 @@ public final class LinphoneService extends Service { resetIntentLaunchedOnNotificationClick(); } - public void displayMessageNotification(String fromSipUri, String fromName, String message) { + public void displayMessageNotification(String to, String fromSipUri, String fromName, String message) { Intent notifIntent = new Intent(this, LinphoneActivity.class); notifIntent.putExtra("GoToChat", true); notifIntent.putExtra("ChatContactSipUri", fromSipUri); @@ -622,7 +623,7 @@ public final class LinphoneService extends Service { } else { bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar); } - mMsgNotif = Compatibility.createMessageNotification(getApplicationContext(), mMsgNotifCount, fromName, message, bm, notifContentIntent); + mMsgNotif = Compatibility.createMessageNotification(getApplicationContext(), mMsgNotifCount, to, fromName, message, bm, notifContentIntent); notifyWrapper(MESSAGE_NOTIF_ID, mMsgNotif); } diff --git a/src/android/org/linphone/compatibility/ApiElevenPlus.java b/src/android/org/linphone/compatibility/ApiElevenPlus.java index 9dda22251..a5fef0d1b 100644 --- a/src/android/org/linphone/compatibility/ApiElevenPlus.java +++ b/src/android/org/linphone/compatibility/ApiElevenPlus.java @@ -22,7 +22,7 @@ import android.widget.TextView; /* ApiElevenPlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 @@ -85,14 +85,14 @@ public class ApiElevenPlus { .setWhen(System.currentTimeMillis()) .setLargeIcon(contactIcon).getNotification(); notif.flags |= Notification.FLAG_ONGOING_EVENT; - + return notif; } - + @SuppressWarnings("deprecation") public static Notification createNotification(Context context, String title, String message, int icon, int level, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent) { Notification notif; - + if (largeIcon != null) { notif = new Notification.Builder(context) .setContentTitle(title) @@ -114,40 +114,40 @@ public class ApiElevenPlus { if (isOngoingEvent) { notif.flags |= Notification.FLAG_ONGOING_EVENT; } - + return notif; } - + public static Intent prepareAddContactIntent(String displayName, String sipUri) { Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI); intent.putExtra(ContactsContract.Intents.Insert.NAME, displayName); - + if (sipUri != null && sipUri.startsWith("sip:")) { sipUri = sipUri.substring(4); } - + ArrayList data = new ArrayList(); ContentValues sipAddressRow = new ContentValues(); sipAddressRow.put(Contacts.Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE); sipAddressRow.put(SipAddress.SIP_ADDRESS, sipUri); data.add(sipAddressRow); intent.putParcelableArrayListExtra(Insert.DATA, data); - + return intent; } - + public static Intent prepareEditContactIntentWithSipAddress(int id, String sipUri) { Intent intent = new Intent(Intent.ACTION_EDIT, Contacts.CONTENT_URI); Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, id); intent.setData(contactUri); - + ArrayList data = new ArrayList(); ContentValues sipAddressRow = new ContentValues(); sipAddressRow.put(Contacts.Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE); sipAddressRow.put(SipAddress.SIP_ADDRESS, sipUri); data.add(sipAddressRow); intent.putParcelableArrayListExtra(Insert.DATA, data); - + return intent; } diff --git a/src/android/org/linphone/compatibility/ApiNineteenPlus.java b/src/android/org/linphone/compatibility/ApiNineteenPlus.java index 4f958f16b..ad6253c73 100644 --- a/src/android/org/linphone/compatibility/ApiNineteenPlus.java +++ b/src/android/org/linphone/compatibility/ApiNineteenPlus.java @@ -5,7 +5,7 @@ import android.app.AlarmManager; import android.app.PendingIntent; /*ApiNineteenPlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 diff --git a/src/android/org/linphone/compatibility/ApiSixteenPlus.java b/src/android/org/linphone/compatibility/ApiSixteenPlus.java index 1bee2257e..5305ed09e 100644 --- a/src/android/org/linphone/compatibility/ApiSixteenPlus.java +++ b/src/android/org/linphone/compatibility/ApiSixteenPlus.java @@ -11,7 +11,7 @@ import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; /* ApiSixteenPlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 @@ -74,13 +74,13 @@ public class ApiSixteenPlus { .setWhen(System.currentTimeMillis()) .setLargeIcon(contactIcon).build(); notif.flags |= Notification.FLAG_ONGOING_EVENT; - + return notif; } - + public static Notification createNotification(Context context, String title, String message, int icon, int level, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent,int priority) { Notification notif; - + if (largeIcon != null) { notif = new Notification.Builder(context) .setContentTitle(title) @@ -104,12 +104,12 @@ public class ApiSixteenPlus { if (isOngoingEvent) { notif.flags |= Notification.FLAG_ONGOING_EVENT; } - + return notif; } public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { - viewTreeObserver.removeOnGlobalLayoutListener(keyboardListener); + viewTreeObserver.removeOnGlobalLayoutListener(keyboardListener); } public static Notification createMissedCallNotification(Context context, String title, String text, PendingIntent intent) { diff --git a/src/android/org/linphone/compatibility/ApiTwentyOnePlus.java b/src/android/org/linphone/compatibility/ApiTwentyOnePlus.java index ff6431a5b..82b5d6ac3 100644 --- a/src/android/org/linphone/compatibility/ApiTwentyOnePlus.java +++ b/src/android/org/linphone/compatibility/ApiTwentyOnePlus.java @@ -11,7 +11,7 @@ import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; /* ApiTwentyOnePlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 @@ -43,7 +43,7 @@ public class ApiTwentyOnePlus { } else { title = context.getString(R.string.unread_messages).replace("%i", String.valueOf(msgCount)); } - + Notification notif = new Notification.Builder(context) .setContentTitle(title) .setContentText(msg) @@ -75,13 +75,13 @@ public class ApiTwentyOnePlus { .setVisibility(Notification.VISIBILITY_PUBLIC) .setPriority(Notification.PRIORITY_HIGH) .build(); - + return notif; } - + public static Notification createNotification(Context context, String title, String message, int icon, int level, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent,int priority) { Notification notif; - + if (largeIcon != null) { notif = new Notification.Builder(context) .setContentTitle(title) @@ -104,12 +104,12 @@ public class ApiTwentyOnePlus { .setPriority(priority) .build(); } - + return notif; } public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { - viewTreeObserver.removeOnGlobalLayoutListener(keyboardListener); + viewTreeObserver.removeOnGlobalLayoutListener(keyboardListener); } public static Notification createMissedCallNotification(Context context, String title, String text, PendingIntent intent) { diff --git a/src/android/org/linphone/compatibility/ApiTwentySixPlus.java b/src/android/org/linphone/compatibility/ApiTwentySixPlus.java new file mode 100644 index 000000000..9f9ea9aa5 --- /dev/null +++ b/src/android/org/linphone/compatibility/ApiTwentySixPlus.java @@ -0,0 +1,63 @@ +package org.linphone.compatibility; + +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.TextView; +import android.annotation.TargetApi; + +import org.linphone.R; + +/* +ApiTwentyThreePlus.java +Copyright (C) 2017 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. +*/ +/** + * @author Erwan Croze + */ +@TargetApi(26) +public class ApiTwentySixPlus { + public static Notification createMessageNotification(Context context, + 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)); + } + + Notification notif = new Notification.Builder(context) + .setContentTitle(title) + .setContentText(msg) + .setSmallIcon(R.drawable.topbar_chat_notification) + .setAutoCancel(true) + .setContentIntent(intent) + .setDefaults( + Notification.DEFAULT_LIGHTS + | Notification.DEFAULT_SOUND + | Notification.DEFAULT_VIBRATE) + .setWhen(System.currentTimeMillis()) + .setLargeIcon(contactIcon) + .setNumber(msgCount) + .build(); + + return notif; + } +} diff --git a/src/android/org/linphone/compatibility/ApiTwentyThreePlus.java b/src/android/org/linphone/compatibility/ApiTwentyThreePlus.java index 8e0f7ef42..9de44cae7 100644 --- a/src/android/org/linphone/compatibility/ApiTwentyThreePlus.java +++ b/src/android/org/linphone/compatibility/ApiTwentyThreePlus.java @@ -5,7 +5,7 @@ import android.annotation.TargetApi; /* ApiTwentyThreePlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 diff --git a/src/android/org/linphone/compatibility/Compatibility.java b/src/android/org/linphone/compatibility/Compatibility.java index 71b5452ba..552c06683 100644 --- a/src/android/org/linphone/compatibility/Compatibility.java +++ b/src/android/org/linphone/compatibility/Compatibility.java @@ -1,7 +1,7 @@ package org.linphone.compatibility; /* Compatibility.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France +Copyright (C) 2017 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 @@ -59,9 +59,11 @@ public class Compatibility { return notif; } - public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) { + public static Notification createMessageNotification(Context context, int msgCount,String to, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) { Notification notif = null; - if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { + if (Version.sdkAboveOrEqual(Version.API26_O_80)) { + + } else if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { return ApiTwentyOnePlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { notif = ApiSixteenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); diff --git a/submodules/bctoolbox b/submodules/bctoolbox index 1256246ac..a37f4186b 160000 --- a/submodules/bctoolbox +++ b/submodules/bctoolbox @@ -1 +1 @@ -Subproject commit 1256246ac90a750e8911e273ba14cf4a6517ee29 +Subproject commit a37f4186b528d4e9b40e61b933dcf8df15735f64 diff --git a/submodules/belcard b/submodules/belcard index 7524da1a0..a9d91af67 160000 --- a/submodules/belcard +++ b/submodules/belcard @@ -1 +1 @@ -Subproject commit 7524da1a0548af6ee11ea910858af322161207c4 +Subproject commit a9d91af675923cdc1bce3091e6ba828d9297de32 diff --git a/submodules/belle-sip b/submodules/belle-sip index f7dbb868d..bac70d8b6 160000 --- a/submodules/belle-sip +++ b/submodules/belle-sip @@ -1 +1 @@ -Subproject commit f7dbb868d48b4ff7d0891618c60842dba73d2f14 +Subproject commit bac70d8b6c787bc204ea9bd60f8b1d0263b36447 diff --git a/submodules/cmake-builder b/submodules/cmake-builder index c06b7e9eb..0773a40cf 160000 --- a/submodules/cmake-builder +++ b/submodules/cmake-builder @@ -1 +1 @@ -Subproject commit c06b7e9eb1c46aa3ab2981a334e6961e5ed744db +Subproject commit 0773a40cfd475fa357fd1ffcf825e5e5b6e0b9d5 diff --git a/submodules/linphone b/submodules/linphone index 0399162c4..a96d04c7b 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 0399162c4c6e778c73e549e49aba7e364234d148 +Subproject commit a96d04c7b4c112e3084a0ad1bd3bda7a11ff4ca4 diff --git a/submodules/mediastreamer2 b/submodules/mediastreamer2 index 98fa0c6c0..9cb2c3eaf 160000 --- a/submodules/mediastreamer2 +++ b/submodules/mediastreamer2 @@ -1 +1 @@ -Subproject commit 98fa0c6c0da29b715b0db5e2e37a7c16567dec7b +Subproject commit 9cb2c3eaf0dd65d64c414090ffdbc2c913a16113 diff --git a/submodules/oRTP b/submodules/oRTP index 6e05a7f50..8c8a83bc7 160000 --- a/submodules/oRTP +++ b/submodules/oRTP @@ -1 +1 @@ -Subproject commit 6e05a7f50f9f3acfbf634cddf8a0a1b4e95c378c +Subproject commit 8c8a83bc74c3547138eb48c27877ac90ab4a360b