From f9a8586701d874b6875731ad3e60f11b4d0942b7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 28 Nov 2018 14:08:27 +0100 Subject: [PATCH] Fixed crash if more than 2 cameras and a front one has id > 2 + added incoming files images to notifications if automatically downloaded --- .../java/org/linphone/LinphoneManager.java | 71 ++++++++++++++----- .../linphone/chat/ChatMessagesFragment.java | 4 +- .../compatibility/ApiTwentyEightPlus.java | 6 +- .../compatibility/ApiTwentyFourPlus.java | 7 +- .../compatibility/ApiTwentySixPlus.java | 6 +- .../notifications/NotifiableMessage.java | 15 +++- .../notifications/NotificationsManager.java | 8 +-- .../java/org/linphone/utils/FileUtils.java | 11 ++- .../linphone/utils/LinphoneMediaScanner.java | 15 ++-- .../linphone/utils/MediaScannerListener.java | 7 ++ 10 files changed, 115 insertions(+), 35 deletions(-) create mode 100644 app/src/main/java/org/linphone/utils/MediaScannerListener.java diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index 23262f666..a62ac70f1 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -111,8 +111,10 @@ import org.linphone.receivers.KeepAliveReceiver; import org.linphone.receivers.NetworkManager; import org.linphone.receivers.OutgoingCallReceiver; import org.linphone.settings.LinphonePreferences; +import org.linphone.utils.FileUtils; import org.linphone.utils.LinphoneMediaScanner; import org.linphone.utils.LinphoneUtils; +import org.linphone.utils.MediaScannerListener; import java.io.File; import java.io.FileInputStream; @@ -482,10 +484,19 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou int camId = 0; AndroidCamera[] cameras = AndroidCameraConfiguration.retrieveCameras(); for (AndroidCamera androidCamera : cameras) { - if (androidCamera.frontFacing == useFrontCam) + if (androidCamera.frontFacing == useFrontCam) { camId = androidCamera.id; + break; + } } String[] devices = getLc().getVideoDevicesList(); + if (devices.length != cameras.length) { + Log.w("Be careful, there are more cameras available than 2 !"); + } + if (camId >= devices.length) { + Log.e("Trying to use a camera that's not in the first two, will crash so use 0 one !"); + camId = 0; + } String newDevice = devices[camId]; LinphoneManager.getLc().setVideoDevice(newDevice); } @@ -1022,7 +1033,7 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou } @Override - public void onMessageReceived(Core lc, ChatRoom cr, ChatMessage message) { + public void onMessageReceived(Core lc, final ChatRoom cr, final ChatMessage message) { if (mServiceContext.getResources().getBoolean(R.bool.disable_chat)) { return; } @@ -1044,24 +1055,46 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou increaseUnreadCountForChatRoom(cr); - Address from = message.getFromAddress(); - LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(from); - String textMessage = (message.getFileTransferInformation() != null) ? getString(R.string.content_description_incoming_file) : message.getTextContent(); + if (mServiceContext.getResources().getBoolean(R.bool.disable_chat_message_notification) || message.isOutgoing()) { + return; + } - if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat_message_notification) && !message.isOutgoing()) { - if (cr.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) { - if (contact != null) { - LinphoneService.instance().getNotificationManager().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress(), message.getTime()); - } else { - LinphoneService.instance().getNotificationManager().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress(), message.getTime()); - } + final Address from = message.getFromAddress(); + final LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(from); + final String textMessage = (message.hasTextContent()) ? message.getTextContent() : getString(R.string.content_description_incoming_file); + + String file = null; + for (Content c : message.getContents()) { + if (c.isFile()) { + file = c.getFilePath(); + getMediaScanner().scanFile(new File(file), new MediaScannerListener() { + @Override + public void onMediaScanned(String path, Uri uri) { + createNotification(cr, contact, from, textMessage, message.getTime(), uri, FileUtils.getMimeFromFile(path)); + } + }); + break; + } + } + + if (file == null) { + createNotification(cr, contact, from, textMessage, message.getTime(), null, null); + } + } + + private void createNotification(ChatRoom cr, LinphoneContact contact, Address from, String textMessage, long time, Uri file, String mime) { + if (cr.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) { + if (contact != null) { + LinphoneService.instance().getNotificationManager().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress(), time, file, mime); } else { - String subject = cr.getSubject(); - if (contact != null) { - LinphoneService.instance().getNotificationManager().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress(), message.getTime()); - } else { - LinphoneService.instance().getNotificationManager().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress(), message.getTime()); - } + LinphoneService.instance().getNotificationManager().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress(), time, file, mime); + } + } else { + String subject = cr.getSubject(); + if (contact != null) { + LinphoneService.instance().getNotificationManager().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress(), time, file, mime); + } else { + LinphoneService.instance().getNotificationManager().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress(), time, file, mime); } } } @@ -1516,7 +1549,7 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou cancel.setText(getString(R.string.maybe_later)); dialog.findViewById(R.id.dialog_do_not_ask_again_layout).setVisibility(View.VISIBLE); - final CheckBox doNotAskAgain = dialog.findViewById(R.id.dialog_do_not_ask_again_layout); + final CheckBox doNotAskAgain = dialog.findViewById(R.id.doNotAskAgain); dialog.findViewById(R.id.doNotAskAgainLabel).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java b/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java index e1e964f69..2b9c5b3a2 100644 --- a/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java @@ -989,10 +989,10 @@ public class ChatMessagesFragment extends Fragment implements ChatRoomListener, if (!getResources().getBoolean(R.bool.disable_chat_message_notification)) { if (contact != null) { LinphoneService.instance().getNotificationManager().displayMessageNotification(from.asStringUriOnly(), - contact.getFullName(), contact.getThumbnailUri(), getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress(), msg.getTime()); + contact.getFullName(), contact.getThumbnailUri(), getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress(), msg.getTime(), null, null); } else { LinphoneService.instance().getNotificationManager().displayMessageNotification(from.asStringUriOnly(), - from.getUsername(), null, getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress(), msg.getTime()); + from.getUsername(), null, getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress(), msg.getTime(), null, null); } } } else if (LinphoneManager.getLc().limeEnabled() == LimeState.Mandatory) { diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyEightPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyEightPlus.java index 71a8e54ba..7f8e621db 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentyEightPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyEightPlus.java @@ -28,12 +28,14 @@ import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.Icon; +import android.net.Uri; import org.linphone.R; import org.linphone.mediastream.Log; import org.linphone.notifications.Notifiable; import org.linphone.notifications.NotifiableMessage; import org.linphone.notifications.NotificationBroadcastReceiver; +import org.linphone.utils.FileUtils; import static org.linphone.compatibility.Compatibility.CHAT_NOTIFICATIONS_GROUP; import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY; @@ -66,7 +68,9 @@ public class ApiTwentyEightPlus { for (NotifiableMessage message : notif.getMessages()) { Icon userIcon = Icon.createWithBitmap(message.getSenderBitmap()); Person user = new Person.Builder().setName(message.getSender()).setIcon(userIcon).build(); - style.addMessage(message.getMessage(), message.getTime(), user); + Notification.MessagingStyle.Message msg = new Notification.MessagingStyle.Message(message.getMessage(), message.getTime(), user); + if (message.getFilePath() != null) msg.setData(message.getFileMime(), message.getFilePath()); + style.addMessage(msg); } if (notif.isGroup()) { style.setConversationTitle(notif.getGroupTitle()); diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java index 2817abbc3..324578072 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java @@ -26,11 +26,14 @@ import android.app.RemoteInput; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; +import android.net.Uri; import org.linphone.R; +import org.linphone.mediastream.Log; import org.linphone.notifications.Notifiable; import org.linphone.notifications.NotifiableMessage; import org.linphone.notifications.NotificationBroadcastReceiver; +import org.linphone.utils.FileUtils; import static org.linphone.compatibility.Compatibility.CHAT_NOTIFICATIONS_GROUP; import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION; @@ -70,7 +73,9 @@ public class ApiTwentyFourPlus { Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself()); for (NotifiableMessage message : notif.getMessages()) { - style.addMessage(message.getMessage(), message.getTime(), message.getSender()); + Notification.MessagingStyle.Message msg = new Notification.MessagingStyle.Message(message.getMessage(), message.getTime(), message.getSender()); + if (message.getFilePath() != null) msg.setData(message.getFileMime(), message.getFilePath()); + style.addMessage(msg); } if (notif.isGroup()) { style.setConversationTitle(notif.getGroupTitle()); diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java index 1ee451106..6573fc2c3 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java @@ -29,11 +29,13 @@ import android.app.RemoteInput; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; +import android.net.Uri; import org.linphone.R; import org.linphone.notifications.Notifiable; import org.linphone.notifications.NotifiableMessage; import org.linphone.notifications.NotificationBroadcastReceiver; +import org.linphone.utils.FileUtils; import static org.linphone.compatibility.Compatibility.CHAT_NOTIFICATIONS_GROUP; import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION; @@ -103,7 +105,9 @@ public class ApiTwentySixPlus { Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself()); for (NotifiableMessage message : notif.getMessages()) { - style.addMessage(message.getMessage(), message.getTime(), message.getSender()); + Notification.MessagingStyle.Message msg = new Notification.MessagingStyle.Message(message.getMessage(), message.getTime(), message.getSender()); + if (message.getFilePath() != null) msg.setData(message.getFileMime(), message.getFilePath()); + style.addMessage(msg); } if (notif.isGroup()) { style.setConversationTitle(notif.getGroupTitle()); diff --git a/app/src/main/java/org/linphone/notifications/NotifiableMessage.java b/app/src/main/java/org/linphone/notifications/NotifiableMessage.java index 8650316c3..47b21e552 100644 --- a/app/src/main/java/org/linphone/notifications/NotifiableMessage.java +++ b/app/src/main/java/org/linphone/notifications/NotifiableMessage.java @@ -20,17 +20,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import android.graphics.Bitmap; +import android.net.Uri; public class NotifiableMessage { String mMessage; String mSender; long mTime; Bitmap mSenderBitmap; + Uri mFilePath; + String mFileMime; - public NotifiableMessage(String message, String sender, long time) { + public NotifiableMessage(String message, String sender, long time, Uri filePath, String fileMime) { mMessage = message; mSender = sender; mTime = time; + mFilePath = filePath; + mFileMime = fileMime; } public String getMessage() { @@ -52,4 +57,12 @@ public class NotifiableMessage { public void setSenderBitmap(Bitmap bm) { mSenderBitmap = bm; } + + public Uri getFilePath() { + return mFilePath; + } + + public String getFileMime() { + return mFileMime; + } } diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.java b/app/src/main/java/org/linphone/notifications/NotificationsManager.java index 89a6c507b..092f43bc2 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.java +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.java @@ -130,7 +130,7 @@ public class NotificationsManager { return null; } - public void displayGroupChatMessageNotification(String subject, String conferenceAddress, String fromName, Uri fromPictureUri, String message, Address localIdentity, long timestamp) { + public void displayGroupChatMessageNotification(String subject, String conferenceAddress, String fromName, Uri fromPictureUri, String message, Address localIdentity, long timestamp, Uri filePath, String fileMime) { Intent notifIntent = new Intent(mContext, LinphoneActivity.class); notifIntent.putExtra("GoToChat", true); notifIntent.putExtra("ChatContactSipUri", conferenceAddress); @@ -138,7 +138,7 @@ public class NotificationsManager { Bitmap bm = ImageUtils.getRoundBitmapFromUri(mContext, fromPictureUri); Notifiable notif = mChatNotifMap.get(conferenceAddress); - NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, timestamp); + NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, timestamp, filePath, fileMime); if (notif == null) { notif = new Notifiable(mLastNotificationId); mLastNotificationId += 1; @@ -157,7 +157,7 @@ public class NotificationsManager { sendNotification(notif.getNotificationId(), notification); } - public void displayMessageNotification(String fromSipUri, String fromName, Uri fromPictureUri, String message, Address localIdentity, long timestamp) { + public void displayMessageNotification(String fromSipUri, String fromName, Uri fromPictureUri, String message, Address localIdentity, long timestamp, Uri filePath, String fileMime) { Intent notifIntent = new Intent(mContext, LinphoneActivity.class); notifIntent.putExtra("GoToChat", true); notifIntent.putExtra("ChatContactSipUri", fromSipUri); @@ -169,7 +169,7 @@ public class NotificationsManager { Bitmap bm = ImageUtils.getRoundBitmapFromUri(mContext, fromPictureUri); Notifiable notif = mChatNotifMap.get(fromSipUri); - NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, timestamp); + NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, timestamp, filePath, fileMime); if (notif == null) { notif = new Notifiable(mLastNotificationId); mLastNotificationId += 1; diff --git a/app/src/main/java/org/linphone/utils/FileUtils.java b/app/src/main/java/org/linphone/utils/FileUtils.java index 7249b2cab..4a5ec57f6 100644 --- a/app/src/main/java/org/linphone/utils/FileUtils.java +++ b/app/src/main/java/org/linphone/utils/FileUtils.java @@ -192,7 +192,7 @@ public class FileUtils { if (!file.isDirectory() || !file.exists()) { Log.w("Directory " + file + " doesn't seem to exists yet, let's create it"); file.mkdirs(); - LinphoneManager.getInstance().getMediaScanner().scanFile(file); + LinphoneManager.getInstance().getMediaScanner().scanFile(file, null); } return storageDir; } @@ -206,7 +206,7 @@ public class FileUtils { } } } - LinphoneManager.getInstance().getMediaScanner().scanFile(new File(appData)); + LinphoneManager.getInstance().getMediaScanner().scanFile(new File(appData), null); } private static Uri createCvsFromString(String vcardString) { @@ -241,4 +241,11 @@ public class FileUtils { return new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); } } + + public static String getMimeFromFile(String path) { + if (isExtensionImage(path)) { + return "image/" + getExtensionFromFileName(path); + } + return "file/" + getExtensionFromFileName(path); + } } diff --git a/app/src/main/java/org/linphone/utils/LinphoneMediaScanner.java b/app/src/main/java/org/linphone/utils/LinphoneMediaScanner.java index 9f9a9f444..5d59e4587 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneMediaScanner.java +++ b/app/src/main/java/org/linphone/utils/LinphoneMediaScanner.java @@ -12,6 +12,7 @@ public class LinphoneMediaScanner implements MediaScannerConnection.MediaScanner private MediaScannerConnection mMediaConnection; private boolean mIsConnected; private File mFileWaitingForScan; + private MediaScannerListener mListener; public LinphoneMediaScanner(Context context) { mIsConnected = false; @@ -25,21 +26,24 @@ public class LinphoneMediaScanner implements MediaScannerConnection.MediaScanner mIsConnected = true; Log.i("[MediaScanner] Connected"); if (mFileWaitingForScan != null) { - scanFile(mFileWaitingForScan); + scanFile(mFileWaitingForScan, null); mFileWaitingForScan = null; } } - public void scanFile(File file) { - scanFile(file, null); + public void scanFile(File file, MediaScannerListener listener) { + scanFile(file, FileUtils.getMimeFromFile(file.getAbsolutePath()), listener); } - public void scanFile(File file, String mime) { + public void scanFile(File file, String mime, MediaScannerListener listener) { + mListener = listener; + if (!mIsConnected) { Log.w("[MediaScanner] Not connected yet..."); mFileWaitingForScan = file; return; } + Log.i("[MediaScanner] Scanning file " + file.getAbsolutePath() + " with MIME " + mime); mMediaConnection.scanFile(file.getAbsolutePath(), mime); } @@ -47,6 +51,9 @@ public class LinphoneMediaScanner implements MediaScannerConnection.MediaScanner @Override public void onScanCompleted(String path, Uri uri) { Log.i("[MediaScanner] Scan completed : " + path + " => " + uri); + if (mListener != null) { + mListener.onMediaScanned(path, uri); + } } public void destroy() { diff --git a/app/src/main/java/org/linphone/utils/MediaScannerListener.java b/app/src/main/java/org/linphone/utils/MediaScannerListener.java new file mode 100644 index 000000000..1e5512ca3 --- /dev/null +++ b/app/src/main/java/org/linphone/utils/MediaScannerListener.java @@ -0,0 +1,7 @@ +package org.linphone.utils; + +import android.net.Uri; + +public interface MediaScannerListener { + void onMediaScanned(String path, Uri uri); +}