Search in sources :

Example 6 with Message

use of eu.siacs.conversations.entities.Message in project Conversations by siacs.

the class XmppConnectionService method loadMoreMessages.

public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) {
    if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation, callback)) {
        return;
    } else if (timestamp == 0) {
        return;
    }
    Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp));
    Runnable runnable = new Runnable() {

        @Override
        public void run() {
            final Account account = conversation.getAccount();
            List<Message> messages = databaseBackend.getMessages(conversation, 50, timestamp);
            if (messages.size() > 0) {
                conversation.addAll(0, messages);
                checkDeletedFiles(conversation);
                callback.onMoreMessagesLoaded(messages.size(), conversation);
            } else if (conversation.hasMessagesLeftOnServer() && account.isOnlineAndConnected() && conversation.getLastClearHistory() == 0) {
                if ((conversation.getMode() == Conversation.MODE_SINGLE && account.getXmppConnection().getFeatures().mam()) || (conversation.getMode() == Conversation.MODE_MULTI && conversation.getMucOptions().mamSupport())) {
                    MessageArchiveService.Query query = getMessageArchiveService().query(conversation, 0, timestamp);
                    if (query != null) {
                        query.setCallback(callback);
                        callback.informUser(R.string.fetching_history_from_server);
                    } else {
                        callback.informUser(R.string.not_fetching_history_retention_period);
                    }
                }
            }
        }
    };
    mDatabaseExecutor.execute(runnable);
}
Also used : Account(eu.siacs.conversations.entities.Account) XmppAxolotlMessage(eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage) Message(eu.siacs.conversations.entities.Message)

Example 7 with Message

use of eu.siacs.conversations.entities.Message in project Conversations by siacs.

the class XmppConnectionService method attachFileToConversation.

public void attachFileToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) {
    if (FileBackend.weOwnFile(this, uri)) {
        Log.d(Config.LOGTAG, "trying to attach file that belonged to us");
        callback.error(R.string.security_error_invalid_file_access, null);
        return;
    }
    final Message message;
    if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
        message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED);
    } else {
        message = new Message(conversation, "", conversation.getNextEncryption());
    }
    message.setCounterpart(conversation.getNextCounterpart());
    message.setType(Message.TYPE_FILE);
    mFileAddingExecutor.execute(new Runnable() {

        private void processAsFile() {
            final String path = getFileBackend().getOriginalPath(uri);
            if (path != null) {
                message.setRelativeFilePath(path);
                getFileBackend().updateFileParams(message);
                if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
                    getPgpEngine().encrypt(message, callback);
                } else {
                    callback.success(message);
                }
            } else {
                try {
                    getFileBackend().copyFileToPrivateStorage(message, uri);
                    getFileBackend().updateFileParams(message);
                    if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
                        final PgpEngine pgpEngine = getPgpEngine();
                        if (pgpEngine != null) {
                            pgpEngine.encrypt(message, callback);
                        } else if (callback != null) {
                            callback.error(R.string.unable_to_connect_to_keychain, null);
                        }
                    } else {
                        callback.success(message);
                    }
                } catch (FileBackend.FileCopyException e) {
                    callback.error(e.getResId(), message);
                }
            }
        }

        private void processAsVideo() throws FileNotFoundException {
            Log.d(Config.LOGTAG, "processing file as video");
            message.setRelativeFilePath(message.getUuid() + ".mp4");
            final DownloadableFile file = getFileBackend().getFile(message);
            file.getParentFile().mkdirs();
            ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r");
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
            final ArrayList<Integer> progressTracker = new ArrayList<>();
            final UiInformableCallback<Message> informableCallback;
            if (callback instanceof UiInformableCallback) {
                informableCallback = (UiInformableCallback<Message>) callback;
            } else {
                informableCallback = null;
            }
            MediaTranscoder.Listener listener = new MediaTranscoder.Listener() {

                @Override
                public void onTranscodeProgress(double progress) {
                    int p = ((int) Math.round(progress * 100) / 20) * 20;
                    if (!progressTracker.contains(p) && p != 100 && p != 0) {
                        progressTracker.add(p);
                        if (informableCallback != null) {
                            informableCallback.inform(getString(R.string.transcoding_video_progress, p));
                        }
                    }
                }

                @Override
                public void onTranscodeCompleted() {
                    if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
                        getPgpEngine().encrypt(message, callback);
                    } else {
                        callback.success(message);
                    }
                }

                @Override
                public void onTranscodeCanceled() {
                    processAsFile();
                }

                @Override
                public void onTranscodeFailed(Exception e) {
                    Log.d(Config.LOGTAG, "video transcoding failed " + e.getMessage());
                    processAsFile();
                }
            };
            MediaTranscoder.getInstance().transcodeVideo(fileDescriptor, file.getAbsolutePath(), MediaFormatStrategyPresets.createAndroid720pStrategy(), listener);
        }

        @Override
        public void run() {
            final String mimeType = MimeUtils.guessMimeTypeFromUri(XmppConnectionService.this, uri);
            if (mimeType != null && mimeType.startsWith("video/") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                try {
                    processAsVideo();
                } catch (Throwable e) {
                    processAsFile();
                }
            } else {
                processAsFile();
            }
        }
    });
}
Also used : OnPhoneContactsLoadedListener(eu.siacs.conversations.utils.OnPhoneContactsLoadedListener) OnBindListener(eu.siacs.conversations.xmpp.OnBindListener) OnRenameListener(eu.siacs.conversations.entities.MucOptions.OnRenameListener) XmppAxolotlMessage(eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage) Message(eu.siacs.conversations.entities.Message) FileNotFoundException(java.io.FileNotFoundException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) PgpEngine(eu.siacs.conversations.crypto.PgpEngine) MediaTranscoder(net.ypresto.androidtranscoder.MediaTranscoder) ParcelFileDescriptor(android.os.ParcelFileDescriptor) FileDescriptor(java.io.FileDescriptor) UiInformableCallback(eu.siacs.conversations.ui.UiInformableCallback) OtrException(net.java.otr4j.OtrException) FileNotFoundException(java.io.FileNotFoundException) InvalidJidException(eu.siacs.conversations.xmpp.jid.InvalidJidException) CertificateException(java.security.cert.CertificateException) ParcelFileDescriptor(android.os.ParcelFileDescriptor) DownloadableFile(eu.siacs.conversations.entities.DownloadableFile)

Example 8 with Message

use of eu.siacs.conversations.entities.Message in project Conversations by siacs.

the class XmppConnectionService method restoreFromDatabase.

private void restoreFromDatabase() {
    synchronized (this.conversations) {
        final Map<String, Account> accountLookupTable = new Hashtable<>();
        for (Account account : this.accounts) {
            accountLookupTable.put(account.getUuid(), account);
        }
        this.conversations.addAll(databaseBackend.getConversations(Conversation.STATUS_AVAILABLE));
        for (Conversation conversation : this.conversations) {
            Account account = accountLookupTable.get(conversation.getAccountUuid());
            conversation.setAccount(account);
        }
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                long deletionDate = getAutomaticMessageDeletionDate();
                mLastExpiryRun.set(SystemClock.elapsedRealtime());
                if (deletionDate > 0) {
                    Log.d(Config.LOGTAG, "deleting messages that are older than " + AbstractGenerator.getTimestamp(deletionDate));
                    databaseBackend.expireOldMessages(deletionDate);
                }
                Log.d(Config.LOGTAG, "restoring roster");
                for (Account account : accounts) {
                    databaseBackend.readRoster(account.getRoster());
                    //roster needs to be loaded at this stage
                    account.initAccountServices(XmppConnectionService.this);
                }
                getBitmapCache().evictAll();
                loadPhoneContacts();
                Log.d(Config.LOGTAG, "restoring messages");
                for (Conversation conversation : conversations) {
                    conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
                    checkDeletedFiles(conversation);
                    conversation.findUnsentTextMessages(new Conversation.OnMessageFound() {

                        @Override
                        public void onMessageFound(Message message) {
                            markMessage(message, Message.STATUS_WAITING);
                        }
                    });
                    conversation.findUnreadMessages(new Conversation.OnMessageFound() {

                        @Override
                        public void onMessageFound(Message message) {
                            mNotificationService.pushFromBacklog(message);
                        }
                    });
                }
                mNotificationService.finishBacklog(false);
                mRestoredFromDatabase = true;
                Log.d(Config.LOGTAG, "restored all messages");
                updateConversationUi();
            }
        };
        mDatabaseExecutor.execute(runnable);
    }
}
Also used : Account(eu.siacs.conversations.entities.Account) XmppAxolotlMessage(eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage) Message(eu.siacs.conversations.entities.Message) Hashtable(java.util.Hashtable) Conversation(eu.siacs.conversations.entities.Conversation)

Example 9 with Message

use of eu.siacs.conversations.entities.Message in project Conversations by siacs.

the class XmppConnectionService method sendReadMarker.

public void sendReadMarker(final Conversation conversation) {
    final Message markable = conversation.getLatestMarkableMessage();
    if (this.markRead(conversation)) {
        updateConversationUi();
    }
    if (confirmMessages() && markable != null && markable.trusted() && markable.getRemoteMsgId() != null) {
        Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid() + ": sending read marker to " + markable.getCounterpart().toString());
        Account account = conversation.getAccount();
        final Jid to = markable.getCounterpart();
        MessagePacket packet = mMessageGenerator.confirm(account, to, markable.getRemoteMsgId());
        this.sendMessagePacket(conversation.getAccount(), packet);
    }
}
Also used : MessagePacket(eu.siacs.conversations.xmpp.stanzas.MessagePacket) Account(eu.siacs.conversations.entities.Account) XmppAxolotlMessage(eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage) Message(eu.siacs.conversations.entities.Message) Jid(eu.siacs.conversations.xmpp.jid.Jid)

Example 10 with Message

use of eu.siacs.conversations.entities.Message in project Conversations by siacs.

the class NotificationService method buildMultipleConversation.

private Builder buildMultipleConversation() {
    final Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService);
    final NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle();
    style.setBigContentTitle(notifications.size() + " " + mXmppConnectionService.getString(R.string.unread_conversations));
    final StringBuilder names = new StringBuilder();
    Conversation conversation = null;
    for (final ArrayList<Message> messages : notifications.values()) {
        if (messages.size() > 0) {
            conversation = messages.get(0).getConversation();
            final String name = conversation.getName();
            SpannableString styledString;
            if (Config.HIDE_MESSAGE_TEXT_IN_NOTIFICATION) {
                int count = messages.size();
                styledString = new SpannableString(name + ": " + mXmppConnectionService.getResources().getQuantityString(R.plurals.x_messages, count, count));
                styledString.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), 0);
                style.addLine(styledString);
            } else {
                styledString = new SpannableString(name + ": " + UIHelper.getMessagePreview(mXmppConnectionService, messages.get(0)).first);
                styledString.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), 0);
                style.addLine(styledString);
            }
            names.append(name);
            names.append(", ");
        }
    }
    if (names.length() >= 2) {
        names.delete(names.length() - 2, names.length());
    }
    mBuilder.setContentTitle(notifications.size() + " " + mXmppConnectionService.getString(R.string.unread_conversations));
    mBuilder.setContentText(names.toString());
    mBuilder.setStyle(style);
    if (conversation != null) {
        mBuilder.setContentIntent(createContentIntent(conversation));
    }
    mBuilder.setGroupSummary(true);
    mBuilder.setGroup(CONVERSATIONS_GROUP);
    mBuilder.setDeleteIntent(createDeleteIntent(null));
    mBuilder.setSmallIcon(R.drawable.ic_notification);
    return mBuilder;
}
Also used : SpannableString(android.text.SpannableString) Message(eu.siacs.conversations.entities.Message) Builder(android.support.v4.app.NotificationCompat.Builder) StyleSpan(android.text.style.StyleSpan) NotificationCompat(android.support.v4.app.NotificationCompat) Conversation(eu.siacs.conversations.entities.Conversation) SpannableString(android.text.SpannableString)

Aggregations

Message (eu.siacs.conversations.entities.Message)39 XmppAxolotlMessage (eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage)16 Conversation (eu.siacs.conversations.entities.Conversation)12 Account (eu.siacs.conversations.entities.Account)9 Jid (eu.siacs.conversations.xmpp.jid.Jid)7 PendingIntent (android.app.PendingIntent)5 InvalidJidException (eu.siacs.conversations.xmpp.jid.InvalidJidException)5 MessagePacket (eu.siacs.conversations.xmpp.stanzas.MessagePacket)5 ArrayList (java.util.ArrayList)5 SuppressLint (android.annotation.SuppressLint)4 SpannableString (android.text.SpannableString)4 NotificationCompat (android.support.v4.app.NotificationCompat)3 StyleSpan (android.text.style.StyleSpan)3 View (android.view.View)3 TextView (android.widget.TextView)3 PgpEngine (eu.siacs.conversations.crypto.PgpEngine)3 Contact (eu.siacs.conversations.entities.Contact)3 Element (eu.siacs.conversations.xml.Element)3 Cursor (android.database.Cursor)2 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)2