Fix crash at launch on Android O

This commit is contained in:
Erwan Croze 2017-08-25 16:10:04 +02:00
parent 07bce56251
commit 7bc0335d06
19 changed files with 131 additions and 53 deletions

View file

@ -7,5 +7,5 @@
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="25"/>
android:targetSdkVersion="26"/>
</manifest>

View file

@ -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']
}
}
}

View file

@ -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) {

View file

@ -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));
}
}

View file

@ -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);
}

View file

@ -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<ContentValues> data = new ArrayList<ContentValues>();
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<ContentValues> data = new ArrayList<ContentValues>();
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;
}

View file

@ -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

View file

@ -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) {

View file

@ -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) {

View file

@ -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;
}
}

View file

@ -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

View file

@ -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);

@ -1 +1 @@
Subproject commit 1256246ac90a750e8911e273ba14cf4a6517ee29
Subproject commit a37f4186b528d4e9b40e61b933dcf8df15735f64

@ -1 +1 @@
Subproject commit 7524da1a0548af6ee11ea910858af322161207c4
Subproject commit a9d91af675923cdc1bce3091e6ba828d9297de32

@ -1 +1 @@
Subproject commit f7dbb868d48b4ff7d0891618c60842dba73d2f14
Subproject commit bac70d8b6c787bc204ea9bd60f8b1d0263b36447

@ -1 +1 @@
Subproject commit c06b7e9eb1c46aa3ab2981a334e6961e5ed744db
Subproject commit 0773a40cfd475fa357fd1ffcf825e5e5b6e0b9d5

@ -1 +1 @@
Subproject commit 0399162c4c6e778c73e549e49aba7e364234d148
Subproject commit a96d04c7b4c112e3084a0ad1bd3bda7a11ff4ca4

@ -1 +1 @@
Subproject commit 98fa0c6c0da29b715b0db5e2e37a7c16567dec7b
Subproject commit 9cb2c3eaf0dd65d64c414090ffdbc2c913a16113

@ -1 +1 @@
Subproject commit 6e05a7f50f9f3acfbf634cddf8a0a1b4e95c378c
Subproject commit 8c8a83bc74c3547138eb48c27877ac90ab4a360b