diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java b/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java index 2f76cc69a..18efe1497 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java @@ -135,6 +135,7 @@ public class PgpDecryptionService { } private void executeApi(Message message) { + boolean skipNotificationPush = false; synchronized (message) { Intent params = userInteractionResult != null ? userInteractionResult : new Intent(); params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY); @@ -209,8 +210,9 @@ public class PgpDecryptionService { mXmppConnectionService.getFileBackend().updateFileParams(message, url); message.setEncryption(Message.ENCRYPTION_DECRYPTED); inputFile.delete(); - mXmppConnectionService.getFileBackend().updateMediaScanner(outputFile); mXmppConnectionService.updateMessage(message); + skipNotificationPush = true; + mXmppConnectionService.getFileBackend().updateMediaScanner(outputFile, () -> notifyIfPending(message)); break; case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: synchronized (PgpDecryptionService.this) { @@ -231,7 +233,9 @@ public class PgpDecryptionService { } } } - notifyIfPending(message); + if (!skipNotificationPush) { + notifyIfPending(message); + } } private synchronized void notifyIfPending(Message message) { diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index a00bf9ceb..ec99a44ac 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -140,7 +140,6 @@ public class HttpDownloadConnection implements Transferable { } private void finish() { - mXmppConnectionService.getFileBackend().updateMediaScanner(file); message.setTransferable(null); mHttpConnectionManager.finishConnection(this); boolean notify = acceptedAutomatically && !message.isRead(); @@ -148,9 +147,12 @@ public class HttpDownloadConnection implements Transferable { notify = message.getConversation().getAccount().getPgpDecryptionService().decrypt(message, notify); } mHttpConnectionManager.updateConversationUi(true); - if (notify) { - mXmppConnectionService.getNotificationService().push(message); - } + final boolean notifyAfterScan = notify; + mXmppConnectionService.getFileBackend().updateMediaScanner(file, () -> { + if (notifyAfterScan) { + mXmppConnectionService.getNotificationService().push(message); + } + }); } private void changeStatus(int status) { diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 16412c985..9bdcc0a18 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -13,6 +13,7 @@ import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RectF; import android.media.MediaMetadataRetriever; +import android.media.MediaScannerConnection; import android.net.Uri; import android.os.Build; import android.os.Environment; @@ -406,14 +407,56 @@ public class FileBackend { } } + public static Uri getMediaUri(Context context, File file) { + final String filePath = file.getAbsolutePath(); + final Cursor cursor = context.getContentResolver().query( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + new String[] { MediaStore.Images.Media._ID }, + MediaStore.Images.Media.DATA + "=? ", + new String[] { filePath }, null); + if (cursor != null && cursor.moveToFirst()) { + final int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); + cursor.close(); + return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(id)); + } else { + return null; + } + } + public void updateMediaScanner(File file) { + updateMediaScanner(file, null); + } + + public void updateMediaScanner(File file, final Runnable callback) { if (!isInDirectoryThatShouldNotBeScanned(mXmppConnectionService, file)) { - Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + MediaScannerConnection.scanFile(mXmppConnectionService, new String[]{file.getAbsolutePath()}, null, new MediaScannerConnection.MediaScannerConnectionClient() { + @Override + public void onMediaScannerConnected() { + + } + + @Override + public void onScanCompleted(String path, Uri uri) { + if (callback != null && file.getAbsolutePath().equals(path)) { + callback.run(); + } else { + Log.d(Config.LOGTAG,"media scanner scanned wrong file"); + if (callback != null) { + callback.run(); + } + } + } + }); + return; + /*Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); intent.setData(Uri.fromFile(file)); - mXmppConnectionService.sendBroadcast(intent); + mXmppConnectionService.sendBroadcast(intent);*/ } else if (file.getAbsolutePath().startsWith(getAppMediaDirectory(mXmppConnectionService))) { createNoMedia(file.getParentFile()); } + if (callback != null) { + callback.run(); + } } public boolean deleteFile(Message message) { diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 6af7037fd..ceff578f8 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -519,7 +519,7 @@ public class NotificationService { } else { Message message; //TODO starting with Android 9 we might want to put images in MessageStyle - if ((message = getImage(messages)) != null) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P && (message = getImage(messages)) != null) { modifyForImage(mBuilder, mUnreadBuilder, message, messages); } else { modifyForTextOnly(mBuilder, mUnreadBuilder, messages); @@ -656,7 +656,16 @@ public class NotificationService { } for (Message message : messages) { final Person sender = message.getStatus() == Message.STATUS_RECEIVED ? getPerson(message) : null; - messagingStyle.addMessage(UIHelper.getMessagePreview(mXmppConnectionService, message).first, message.getTimeSent(), sender); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && isImageMessage(message)) { + final Uri dataUri = FileBackend.getMediaUri(mXmppConnectionService,mXmppConnectionService.getFileBackend().getFile(message)); + NotificationCompat.MessagingStyle.Message imageMessage = new NotificationCompat.MessagingStyle.Message(UIHelper.getMessagePreview(mXmppConnectionService, message).first, message.getTimeSent(), sender); + if (dataUri != null) { + imageMessage.setData(message.getMimeType(), dataUri); + } + messagingStyle.addMessage(imageMessage); + } else { + messagingStyle.addMessage(UIHelper.getMessagePreview(mXmppConnectionService, message).first, message.getTimeSent(), sender); + } } messagingStyle.setGroupConversation(multiple); builder.setStyle(messagingStyle); @@ -703,16 +712,20 @@ public class NotificationService { if (message.getStatus() != Message.STATUS_RECEIVED) { return null; } - if (message.getType() != Message.TYPE_TEXT - && message.getTransferable() == null - && message.getEncryption() != Message.ENCRYPTION_PGP - && message.getFileParams().height > 0) { + if (isImageMessage(message)) { image = message; } } return image; } + private static boolean isImageMessage(Message message) { + return message.getType() != Message.TYPE_TEXT + && message.getTransferable() == null + && message.getEncryption() != Message.ENCRYPTION_PGP + && message.getFileParams().height > 0; + } + private Message getFirstDownloadableMessage(final Iterable messages) { for (final Message message : messages) { if (message.getTransferable() != null || (message.getType() == Message.TYPE_TEXT && message.treatAsDownloadable())) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index c96be3134..da01ab086 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -122,8 +122,11 @@ public class JingleConnection implements Transferable { if (message.getEncryption() == Message.ENCRYPTION_PGP) { account.getPgpDecryptionService().decrypt(message, true); } else { - JingleConnection.this.mXmppConnectionService.getNotificationService().push(message); + mXmppConnectionService.getFileBackend().updateMediaScanner(file, () -> JingleConnection.this.mXmppConnectionService.getNotificationService().push(message)); + } + Log.d(Config.LOGTAG,"successfully transmitted file:" + file.getAbsolutePath()+" ("+ CryptoHelper.bytesToHex(file.getSha1Sum())+")"); + return; } } else { if (ftVersion == Content.Version.FT_5) { //older Conversations will break when receiving a session-info