Search in sources :

Example 11 with LongSparseIntArray

use of org.telegram.messenger.support.LongSparseIntArray in project Telegram-FOSS by Telegram-FOSS-Team.

the class MessagesStorage method processPendingRead.

public void processPendingRead(long dialogId, int maxPositiveId, int maxNegativeId, int scheduledCount) {
    int maxDate = lastSavedDate;
    storageQueue.postRunnable(() -> {
        try {
            int currentMaxId = 0;
            int unreadCount = 0;
            long last_mid = 0;
            int prevUnreadCount = 0;
            SQLiteCursor cursor = database.queryFinalized("SELECT unread_count, inbox_max, last_mid FROM dialogs WHERE did = " + dialogId);
            if (cursor.next()) {
                prevUnreadCount = unreadCount = cursor.intValue(0);
                currentMaxId = cursor.intValue(1);
                last_mid = cursor.longValue(2);
            }
            cursor.dispose();
            database.beginTransaction();
            SQLitePreparedStatement state;
            if (!DialogObject.isEncryptedDialog(dialogId)) {
                currentMaxId = Math.max(currentMaxId, maxPositiveId);
                state = database.executeFast("UPDATE messages_v2 SET read_state = read_state | 1 WHERE uid = ? AND mid <= ? AND read_state IN(0,2) AND out = 0");
                state.requery();
                state.bindLong(1, dialogId);
                state.bindInteger(2, currentMaxId);
                state.step();
                state.dispose();
                if (currentMaxId >= last_mid) {
                    unreadCount = 0;
                } else {
                    int updatedCount = 0;
                    cursor = database.queryFinalized("SELECT changes()");
                    if (cursor.next()) {
                        updatedCount = cursor.intValue(0) + scheduledCount;
                    }
                    cursor.dispose();
                    unreadCount = Math.max(0, unreadCount - updatedCount);
                }
                state = database.executeFast("DELETE FROM unread_push_messages WHERE uid = ? AND mid <= ?");
                state.requery();
                state.bindLong(1, dialogId);
                state.bindInteger(2, currentMaxId);
                state.step();
                state.dispose();
                state = database.executeFast("DELETE FROM unread_push_messages WHERE uid = ? AND date <= ?");
                state.requery();
                state.bindLong(1, dialogId);
                state.bindInteger(2, maxDate);
                state.step();
                state.dispose();
            } else {
                currentMaxId = maxNegativeId;
                state = database.executeFast("UPDATE messages_v2 SET read_state = read_state | 1 WHERE uid = ? AND mid >= ? AND read_state IN(0,2) AND out = 0");
                state.requery();
                state.bindLong(1, dialogId);
                state.bindInteger(2, currentMaxId);
                state.step();
                state.dispose();
                if (currentMaxId <= last_mid) {
                    unreadCount = 0;
                } else {
                    int updatedCount = 0;
                    cursor = database.queryFinalized("SELECT changes()");
                    if (cursor.next()) {
                        updatedCount = cursor.intValue(0) + scheduledCount;
                    }
                    cursor.dispose();
                    unreadCount = Math.max(0, unreadCount - updatedCount);
                }
            }
            state = database.executeFast("UPDATE dialogs SET unread_count = ?, inbox_max = ? WHERE did = ?");
            state.requery();
            state.bindInteger(1, unreadCount);
            state.bindInteger(2, currentMaxId);
            state.bindLong(3, dialogId);
            state.step();
            state.dispose();
            database.commitTransaction();
            if (prevUnreadCount != 0 && unreadCount == 0) {
                LongSparseIntArray dialogsToUpdate = new LongSparseIntArray();
                dialogsToUpdate.put(dialogId, unreadCount);
                updateFiltersReadCounter(dialogsToUpdate, null, true);
            }
            updateWidgets(dialogId);
        } catch (Exception e) {
            FileLog.e(e);
        }
    });
}
Also used : LongSparseIntArray(org.telegram.messenger.support.LongSparseIntArray) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException) SQLitePreparedStatement(org.telegram.SQLite.SQLitePreparedStatement)

Example 12 with LongSparseIntArray

use of org.telegram.messenger.support.LongSparseIntArray in project Telegram-FOSS by Telegram-FOSS-Team.

the class MessagesStorage method updateDialogsWithReadMessagesInternal.

private void updateDialogsWithReadMessagesInternal(ArrayList<Integer> messages, LongSparseIntArray inbox, LongSparseIntArray outbox, LongSparseArray<ArrayList<Integer>> mentions) {
    try {
        LongSparseIntArray dialogsToUpdate = new LongSparseIntArray();
        LongSparseIntArray dialogsToUpdateMentions = new LongSparseIntArray();
        ArrayList<Long> channelMentionsToReload = new ArrayList<>();
        if (!isEmpty(messages)) {
            String ids = TextUtils.join(",", messages);
            SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, read_state, out FROM messages_v2 WHERE mid IN(%s) AND is_channel = 0", ids));
            while (cursor.next()) {
                int out = cursor.intValue(2);
                if (out != 0) {
                    continue;
                }
                int read_state = cursor.intValue(1);
                if (read_state != 0) {
                    continue;
                }
                long uid = cursor.longValue(0);
                int currentCount = dialogsToUpdate.get(uid);
                if (currentCount == 0) {
                    dialogsToUpdate.put(uid, 1);
                } else {
                    dialogsToUpdate.put(uid, currentCount + 1);
                }
            }
            cursor.dispose();
        } else {
            if (!isEmpty(inbox)) {
                for (int b = 0; b < inbox.size(); b++) {
                    long key = inbox.keyAt(b);
                    int messageId = inbox.get(key);
                    SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM messages_v2 WHERE uid = %d AND mid > %d AND read_state IN(0,2) AND out = 0", key, messageId));
                    if (cursor.next()) {
                        dialogsToUpdate.put(key, cursor.intValue(0));
                    }
                    cursor.dispose();
                    SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET inbox_max = max((SELECT inbox_max FROM dialogs WHERE did = ?), ?) WHERE did = ?");
                    state.requery();
                    state.bindLong(1, key);
                    state.bindInteger(2, messageId);
                    state.bindLong(3, key);
                    state.step();
                    state.dispose();
                }
            }
            if (!isEmpty(mentions)) {
                for (int b = 0, N = mentions.size(); b < N; b++) {
                    ArrayList<Integer> arrayList = mentions.valueAt(b);
                    ArrayList<Integer> notFoundMentions = new ArrayList<>(arrayList);
                    String ids = TextUtils.join(",", arrayList);
                    long channelId = 0;
                    SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, read_state, out, mention, mid, is_channel FROM messages_v2 WHERE mid IN(%s)", ids));
                    while (cursor.next()) {
                        long did = cursor.longValue(0);
                        notFoundMentions.remove((Integer) cursor.intValue(4));
                        if (cursor.intValue(1) < 2 && cursor.intValue(2) == 0 && cursor.intValue(3) == 1) {
                            int unread_count = dialogsToUpdateMentions.get(did, -1);
                            if (unread_count < 0) {
                                SQLiteCursor cursor2 = database.queryFinalized("SELECT unread_count_i FROM dialogs WHERE did = " + did);
                                int old_mentions_count = 0;
                                if (cursor2.next()) {
                                    old_mentions_count = cursor2.intValue(0);
                                }
                                cursor2.dispose();
                                dialogsToUpdateMentions.put(did, Math.max(0, old_mentions_count - 1));
                            } else {
                                dialogsToUpdateMentions.put(did, Math.max(0, unread_count - 1));
                            }
                        }
                        channelId = cursor.longValue(5);
                    }
                    cursor.dispose();
                    if (!notFoundMentions.isEmpty() && channelId != 0) {
                        if (!channelMentionsToReload.contains(channelId)) {
                            channelMentionsToReload.add(channelId);
                        }
                    }
                }
            }
            if (!isEmpty(outbox)) {
                for (int b = 0; b < outbox.size(); b++) {
                    long key = outbox.keyAt(b);
                    int messageId = outbox.get(key);
                    SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET outbox_max = max((SELECT outbox_max FROM dialogs WHERE did = ?), ?) WHERE did = ?");
                    state.requery();
                    state.bindLong(1, key);
                    state.bindInteger(2, messageId);
                    state.bindLong(3, key);
                    state.step();
                    state.dispose();
                }
            }
        }
        if (dialogsToUpdate.size() > 0 || dialogsToUpdateMentions.size() > 0) {
            database.beginTransaction();
            if (dialogsToUpdate.size() > 0) {
                ArrayList<Long> dids = new ArrayList<>();
                SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET unread_count = ? WHERE did = ?");
                for (int a = 0; a < dialogsToUpdate.size(); a++) {
                    long did = dialogsToUpdate.keyAt(a);
                    int prevUnreadCount = 0;
                    int newCount = dialogsToUpdate.valueAt(a);
                    SQLiteCursor cursor = database.queryFinalized("SELECT unread_count FROM dialogs WHERE did = " + did);
                    if (cursor.next()) {
                        prevUnreadCount = cursor.intValue(0);
                    }
                    cursor.dispose();
                    if (prevUnreadCount == newCount) {
                        dialogsToUpdate.removeAt(a);
                        a--;
                        continue;
                    }
                    state.requery();
                    state.bindInteger(1, newCount);
                    state.bindLong(2, did);
                    state.step();
                    dids.add(did);
                }
                state.dispose();
                updateWidgets(dids);
            }
            if (dialogsToUpdateMentions.size() > 0) {
                SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET unread_count_i = ? WHERE did = ?");
                for (int a = 0; a < dialogsToUpdateMentions.size(); a++) {
                    state.requery();
                    state.bindInteger(1, dialogsToUpdateMentions.valueAt(a));
                    state.bindLong(2, dialogsToUpdateMentions.keyAt(a));
                    state.step();
                }
                state.dispose();
            }
            database.commitTransaction();
        }
        updateFiltersReadCounter(dialogsToUpdate, dialogsToUpdateMentions, true);
        getMessagesController().processDialogsUpdateRead(dialogsToUpdate, dialogsToUpdateMentions);
        if (!channelMentionsToReload.isEmpty()) {
            getMessagesController().reloadMentionsCountForChannels(channelMentionsToReload);
        }
    } catch (Exception e) {
        FileLog.e(e);
    }
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) ArrayList(java.util.ArrayList) LongSparseIntArray(org.telegram.messenger.support.LongSparseIntArray) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException) SQLitePreparedStatement(org.telegram.SQLite.SQLitePreparedStatement)

Example 13 with LongSparseIntArray

use of org.telegram.messenger.support.LongSparseIntArray in project Telegram-FOSS by Telegram-FOSS-Team.

the class MessagesStorage method resetMentionsCount.

public void resetMentionsCount(long did, int count) {
    storageQueue.postRunnable(() -> {
        try {
            int prevUnreadCount = 0;
            SQLiteCursor cursor = database.queryFinalized("SELECT unread_count_i FROM dialogs WHERE did = " + did);
            if (cursor.next()) {
                prevUnreadCount = cursor.intValue(0);
            }
            cursor.dispose();
            if (prevUnreadCount != 0 || count != 0) {
                if (count == 0) {
                    database.executeFast(String.format(Locale.US, "UPDATE messages_v2 SET read_state = read_state | 2 WHERE uid = %d AND mention = 1 AND read_state IN(0, 1)", did)).stepThis().dispose();
                }
                database.executeFast(String.format(Locale.US, "UPDATE dialogs SET unread_count_i = %d WHERE did = %d", count, did)).stepThis().dispose();
                LongSparseIntArray sparseArray = new LongSparseIntArray(1);
                sparseArray.put(did, count);
                getMessagesController().processDialogsUpdateRead(null, sparseArray);
                if (count == 0) {
                    updateFiltersReadCounter(null, sparseArray, true);
                }
            }
        } catch (Exception e) {
            FileLog.e(e);
        }
    });
}
Also used : LongSparseIntArray(org.telegram.messenger.support.LongSparseIntArray) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException)

Example 14 with LongSparseIntArray

use of org.telegram.messenger.support.LongSparseIntArray in project Telegram-FOSS by Telegram-FOSS-Team.

the class NotificationsController method removeNotificationsForDialog.

public void removeNotificationsForDialog(long did) {
    processReadMessages(null, did, 0, Integer.MAX_VALUE, false);
    LongSparseIntArray dialogsToUpdate = new LongSparseIntArray();
    dialogsToUpdate.put(did, 0);
    processDialogsUpdateRead(dialogsToUpdate);
}
Also used : LongSparseIntArray(org.telegram.messenger.support.LongSparseIntArray)

Example 15 with LongSparseIntArray

use of org.telegram.messenger.support.LongSparseIntArray in project Telegram-FOSS by Telegram-FOSS-Team.

the class SecretChatHelper method processDecryptedObject.

public TLRPC.Message processDecryptedObject(TLRPC.EncryptedChat chat, TLRPC.EncryptedFile file, int date, TLObject object, boolean new_key_used) {
    if (object != null) {
        long from_id = chat.admin_id;
        if (from_id == getUserConfig().getClientUserId()) {
            from_id = chat.participant_id;
        }
        if (chat.exchange_id == 0 && chat.future_key_fingerprint == 0 && chat.key_use_count_in >= 120) {
            requestNewSecretChatKey(chat);
        }
        if (chat.exchange_id == 0 && chat.future_key_fingerprint != 0 && !new_key_used) {
            chat.future_auth_key = new byte[256];
            chat.future_key_fingerprint = 0;
            getMessagesStorage().updateEncryptedChat(chat);
        } else if (chat.exchange_id != 0 && new_key_used) {
            chat.key_fingerprint = chat.future_key_fingerprint;
            chat.auth_key = chat.future_auth_key;
            chat.key_create_date = getConnectionsManager().getCurrentTime();
            chat.future_auth_key = new byte[256];
            chat.future_key_fingerprint = 0;
            chat.key_use_count_in = 0;
            chat.key_use_count_out = 0;
            chat.exchange_id = 0;
            getMessagesStorage().updateEncryptedChat(chat);
        }
        if (object instanceof TLRPC.TL_decryptedMessage) {
            TLRPC.TL_decryptedMessage decryptedMessage = (TLRPC.TL_decryptedMessage) object;
            TLRPC.TL_message newMessage;
            newMessage = new TLRPC.TL_message_secret();
            newMessage.ttl = decryptedMessage.ttl;
            newMessage.entities = decryptedMessage.entities;
            newMessage.message = decryptedMessage.message;
            newMessage.date = date;
            newMessage.local_id = newMessage.id = getUserConfig().getNewMessageId();
            newMessage.silent = decryptedMessage.silent;
            getUserConfig().saveConfig(false);
            newMessage.from_id = new TLRPC.TL_peerUser();
            newMessage.from_id.user_id = from_id;
            newMessage.peer_id = new TLRPC.TL_peerUser();
            newMessage.peer_id.user_id = getUserConfig().getClientUserId();
            newMessage.random_id = decryptedMessage.random_id;
            newMessage.unread = true;
            newMessage.flags = TLRPC.MESSAGE_FLAG_HAS_MEDIA | TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
            if (decryptedMessage.via_bot_name != null && decryptedMessage.via_bot_name.length() > 0) {
                newMessage.via_bot_name = decryptedMessage.via_bot_name;
                newMessage.flags |= TLRPC.MESSAGE_FLAG_HAS_BOT_ID;
            }
            if (decryptedMessage.grouped_id != 0) {
                newMessage.grouped_id = decryptedMessage.grouped_id;
                newMessage.flags |= 131072;
            }
            newMessage.dialog_id = DialogObject.makeEncryptedDialogId(chat.id);
            if (decryptedMessage.reply_to_random_id != 0) {
                newMessage.reply_to = new TLRPC.TL_messageReplyHeader();
                newMessage.reply_to.reply_to_random_id = decryptedMessage.reply_to_random_id;
                newMessage.flags |= TLRPC.MESSAGE_FLAG_REPLY;
            }
            if (decryptedMessage.media == null || decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) {
                newMessage.media = new TLRPC.TL_messageMediaEmpty();
            } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaWebPage) {
                newMessage.media = new TLRPC.TL_messageMediaWebPage();
                newMessage.media.webpage = new TLRPC.TL_webPageUrlPending();
                newMessage.media.webpage.url = decryptedMessage.media.url;
            } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaContact) {
                newMessage.media = new TLRPC.TL_messageMediaContact();
                newMessage.media.last_name = decryptedMessage.media.last_name;
                newMessage.media.first_name = decryptedMessage.media.first_name;
                newMessage.media.phone_number = decryptedMessage.media.phone_number;
                newMessage.media.user_id = decryptedMessage.media.user_id;
                newMessage.media.vcard = "";
            } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaGeoPoint) {
                newMessage.media = new TLRPC.TL_messageMediaGeo();
                newMessage.media.geo = new TLRPC.TL_geoPoint();
                newMessage.media.geo.lat = decryptedMessage.media.lat;
                newMessage.media.geo._long = decryptedMessage.media._long;
            } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaPhoto) {
                if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) {
                    return null;
                }
                newMessage.media = new TLRPC.TL_messageMediaPhoto();
                newMessage.media.flags |= 3;
                if (TextUtils.isEmpty(newMessage.message)) {
                    newMessage.message = decryptedMessage.media.caption != null ? decryptedMessage.media.caption : "";
                }
                newMessage.media.photo = new TLRPC.TL_photo();
                newMessage.media.photo.file_reference = new byte[0];
                newMessage.media.photo.date = newMessage.date;
                byte[] thumb = ((TLRPC.TL_decryptedMessageMediaPhoto) decryptedMessage.media).thumb;
                if (thumb != null && thumb.length != 0 && thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
                    TLRPC.TL_photoCachedSize small = new TLRPC.TL_photoCachedSize();
                    small.w = decryptedMessage.media.thumb_w;
                    small.h = decryptedMessage.media.thumb_h;
                    small.bytes = thumb;
                    small.type = "s";
                    small.location = new TLRPC.TL_fileLocationUnavailable();
                    newMessage.media.photo.sizes.add(small);
                }
                if (newMessage.ttl != 0) {
                    newMessage.media.ttl_seconds = newMessage.ttl;
                    newMessage.media.flags |= 4;
                }
                TLRPC.TL_photoSize big = new TLRPC.TL_photoSize_layer127();
                big.w = decryptedMessage.media.w;
                big.h = decryptedMessage.media.h;
                big.type = "x";
                big.size = file.size;
                big.location = new TLRPC.TL_fileEncryptedLocation();
                big.location.key = decryptedMessage.media.key;
                big.location.iv = decryptedMessage.media.iv;
                big.location.dc_id = file.dc_id;
                big.location.volume_id = file.id;
                big.location.secret = file.access_hash;
                big.location.local_id = file.key_fingerprint;
                newMessage.media.photo.sizes.add(big);
            } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaVideo) {
                if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) {
                    return null;
                }
                newMessage.media = new TLRPC.TL_messageMediaDocument();
                newMessage.media.flags |= 3;
                newMessage.media.document = new TLRPC.TL_documentEncrypted();
                newMessage.media.document.key = decryptedMessage.media.key;
                newMessage.media.document.iv = decryptedMessage.media.iv;
                newMessage.media.document.dc_id = file.dc_id;
                if (TextUtils.isEmpty(newMessage.message)) {
                    newMessage.message = decryptedMessage.media.caption != null ? decryptedMessage.media.caption : "";
                }
                newMessage.media.document.date = date;
                newMessage.media.document.size = file.size;
                newMessage.media.document.id = file.id;
                newMessage.media.document.access_hash = file.access_hash;
                newMessage.media.document.mime_type = decryptedMessage.media.mime_type;
                if (newMessage.media.document.mime_type == null) {
                    newMessage.media.document.mime_type = "video/mp4";
                }
                byte[] thumb = ((TLRPC.TL_decryptedMessageMediaVideo) decryptedMessage.media).thumb;
                TLRPC.PhotoSize photoSize;
                if (thumb != null && thumb.length != 0 && thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
                    photoSize = new TLRPC.TL_photoCachedSize();
                    photoSize.bytes = thumb;
                    photoSize.w = decryptedMessage.media.thumb_w;
                    photoSize.h = decryptedMessage.media.thumb_h;
                    photoSize.type = "s";
                    photoSize.location = new TLRPC.TL_fileLocationUnavailable();
                } else {
                    photoSize = new TLRPC.TL_photoSizeEmpty();
                    photoSize.type = "s";
                }
                newMessage.media.document.thumbs.add(photoSize);
                newMessage.media.document.flags |= 1;
                TLRPC.TL_documentAttributeVideo attributeVideo = new TLRPC.TL_documentAttributeVideo();
                attributeVideo.w = decryptedMessage.media.w;
                attributeVideo.h = decryptedMessage.media.h;
                attributeVideo.duration = decryptedMessage.media.duration;
                attributeVideo.supports_streaming = false;
                newMessage.media.document.attributes.add(attributeVideo);
                if (newMessage.ttl != 0) {
                    newMessage.media.ttl_seconds = newMessage.ttl;
                    newMessage.media.flags |= 4;
                }
                if (newMessage.ttl != 0) {
                    newMessage.ttl = Math.max(decryptedMessage.media.duration + 1, newMessage.ttl);
                }
            } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaDocument) {
                if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) {
                    return null;
                }
                newMessage.media = new TLRPC.TL_messageMediaDocument();
                newMessage.media.flags |= 3;
                if (TextUtils.isEmpty(newMessage.message)) {
                    newMessage.message = decryptedMessage.media.caption != null ? decryptedMessage.media.caption : "";
                }
                newMessage.media.document = new TLRPC.TL_documentEncrypted();
                newMessage.media.document.id = file.id;
                newMessage.media.document.access_hash = file.access_hash;
                newMessage.media.document.date = date;
                newMessage.media.document.mime_type = decryptedMessage.media.mime_type;
                if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaDocument_layer8) {
                    TLRPC.TL_documentAttributeFilename fileName = new TLRPC.TL_documentAttributeFilename();
                    fileName.file_name = decryptedMessage.media.file_name;
                    newMessage.media.document.attributes.add(fileName);
                } else {
                    newMessage.media.document.attributes = decryptedMessage.media.attributes;
                }
                if (newMessage.ttl > 0) {
                    for (int a = 0, N = newMessage.media.document.attributes.size(); a < N; a++) {
                        TLRPC.DocumentAttribute attribute = newMessage.media.document.attributes.get(a);
                        if (attribute instanceof TLRPC.TL_documentAttributeAudio || attribute instanceof TLRPC.TL_documentAttributeVideo) {
                            newMessage.ttl = Math.max(attribute.duration + 1, newMessage.ttl);
                            break;
                        }
                    }
                    newMessage.ttl = Math.max(decryptedMessage.media.duration + 1, newMessage.ttl);
                }
                newMessage.media.document.size = decryptedMessage.media.size != 0 ? Math.min(decryptedMessage.media.size, file.size) : file.size;
                newMessage.media.document.key = decryptedMessage.media.key;
                newMessage.media.document.iv = decryptedMessage.media.iv;
                if (newMessage.media.document.mime_type == null) {
                    newMessage.media.document.mime_type = "";
                } else if ("application/x-tgsticker".equals(newMessage.media.document.mime_type) || "application/x-tgsdice".equals(newMessage.media.document.mime_type)) {
                    newMessage.media.document.mime_type = "application/x-bad_tgsticker";
                }
                byte[] thumb = ((TLRPC.TL_decryptedMessageMediaDocument) decryptedMessage.media).thumb;
                TLRPC.PhotoSize photoSize;
                if (thumb != null && thumb.length != 0 && thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
                    photoSize = new TLRPC.TL_photoCachedSize();
                    photoSize.bytes = thumb;
                    photoSize.w = decryptedMessage.media.thumb_w;
                    photoSize.h = decryptedMessage.media.thumb_h;
                    photoSize.type = "s";
                    photoSize.location = new TLRPC.TL_fileLocationUnavailable();
                } else {
                    photoSize = new TLRPC.TL_photoSizeEmpty();
                    photoSize.type = "s";
                }
                newMessage.media.document.thumbs.add(photoSize);
                newMessage.media.document.flags |= 1;
                newMessage.media.document.dc_id = file.dc_id;
                if (MessageObject.isVoiceMessage(newMessage) || MessageObject.isRoundVideoMessage(newMessage)) {
                    newMessage.media_unread = true;
                }
            } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaExternalDocument) {
                newMessage.media = new TLRPC.TL_messageMediaDocument();
                newMessage.media.flags |= 3;
                newMessage.message = "";
                newMessage.media.document = new TLRPC.TL_document();
                newMessage.media.document.id = decryptedMessage.media.id;
                newMessage.media.document.access_hash = decryptedMessage.media.access_hash;
                newMessage.media.document.file_reference = new byte[0];
                newMessage.media.document.date = decryptedMessage.media.date;
                newMessage.media.document.attributes = decryptedMessage.media.attributes;
                newMessage.media.document.mime_type = decryptedMessage.media.mime_type;
                newMessage.media.document.dc_id = decryptedMessage.media.dc_id;
                newMessage.media.document.size = decryptedMessage.media.size;
                newMessage.media.document.thumbs.add(((TLRPC.TL_decryptedMessageMediaExternalDocument) decryptedMessage.media).thumb);
                newMessage.media.document.flags |= 1;
                if (newMessage.media.document.mime_type == null) {
                    newMessage.media.document.mime_type = "";
                }
                if (MessageObject.isAnimatedStickerMessage(newMessage)) {
                    newMessage.stickerVerified = 0;
                    getMediaDataController().verifyAnimatedStickerMessage(newMessage, true);
                }
            } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaAudio) {
                if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) {
                    return null;
                }
                newMessage.media = new TLRPC.TL_messageMediaDocument();
                newMessage.media.flags |= 3;
                newMessage.media.document = new TLRPC.TL_documentEncrypted();
                newMessage.media.document.key = decryptedMessage.media.key;
                newMessage.media.document.iv = decryptedMessage.media.iv;
                newMessage.media.document.id = file.id;
                newMessage.media.document.access_hash = file.access_hash;
                newMessage.media.document.date = date;
                newMessage.media.document.size = file.size;
                newMessage.media.document.dc_id = file.dc_id;
                newMessage.media.document.mime_type = decryptedMessage.media.mime_type;
                if (TextUtils.isEmpty(newMessage.message)) {
                    newMessage.message = decryptedMessage.media.caption != null ? decryptedMessage.media.caption : "";
                }
                if (newMessage.media.document.mime_type == null) {
                    newMessage.media.document.mime_type = "audio/ogg";
                }
                TLRPC.TL_documentAttributeAudio attributeAudio = new TLRPC.TL_documentAttributeAudio();
                attributeAudio.duration = decryptedMessage.media.duration;
                attributeAudio.voice = true;
                newMessage.media.document.attributes.add(attributeAudio);
                if (newMessage.ttl != 0) {
                    newMessage.ttl = Math.max(decryptedMessage.media.duration + 1, newMessage.ttl);
                }
                if (newMessage.media.document.thumbs.isEmpty()) {
                    TLRPC.PhotoSize thumb = new TLRPC.TL_photoSizeEmpty();
                    thumb.type = "s";
                    newMessage.media.document.thumbs.add(thumb);
                }
            } else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaVenue) {
                newMessage.media = new TLRPC.TL_messageMediaVenue();
                newMessage.media.geo = new TLRPC.TL_geoPoint();
                newMessage.media.geo.lat = decryptedMessage.media.lat;
                newMessage.media.geo._long = decryptedMessage.media._long;
                newMessage.media.title = decryptedMessage.media.title;
                newMessage.media.address = decryptedMessage.media.address;
                newMessage.media.provider = decryptedMessage.media.provider;
                newMessage.media.venue_id = decryptedMessage.media.venue_id;
                newMessage.media.venue_type = "";
            } else {
                return null;
            }
            if (newMessage.ttl != 0 && newMessage.media.ttl_seconds == 0) {
                newMessage.media.ttl_seconds = newMessage.ttl;
                newMessage.media.flags |= 4;
            }
            if (newMessage.message != null) {
                newMessage.message = newMessage.message.replace('\u202E', ' ');
            }
            return newMessage;
        } else if (object instanceof TLRPC.TL_decryptedMessageService) {
            TLRPC.TL_decryptedMessageService serviceMessage = (TLRPC.TL_decryptedMessageService) object;
            if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL || serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) {
                TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService();
                if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
                    newMessage.action = new TLRPC.TL_messageEncryptedAction();
                    if (serviceMessage.action.ttl_seconds < 0 || serviceMessage.action.ttl_seconds > 60 * 60 * 24 * 365) {
                        serviceMessage.action.ttl_seconds = 60 * 60 * 24 * 365;
                    }
                    chat.ttl = serviceMessage.action.ttl_seconds;
                    newMessage.action.encryptedAction = serviceMessage.action;
                    getMessagesStorage().updateEncryptedChatTTL(chat);
                } else {
                    newMessage.action = new TLRPC.TL_messageEncryptedAction();
                    newMessage.action.encryptedAction = serviceMessage.action;
                }
                newMessage.local_id = newMessage.id = getUserConfig().getNewMessageId();
                getUserConfig().saveConfig(false);
                newMessage.unread = true;
                newMessage.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
                newMessage.date = date;
                newMessage.from_id = new TLRPC.TL_peerUser();
                newMessage.from_id.user_id = from_id;
                newMessage.peer_id = new TLRPC.TL_peerUser();
                newMessage.peer_id.user_id = getUserConfig().getClientUserId();
                newMessage.dialog_id = DialogObject.makeEncryptedDialogId(chat.id);
                return newMessage;
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionFlushHistory) {
                long did = DialogObject.makeEncryptedDialogId(chat.id);
                AndroidUtilities.runOnUIThread(() -> {
                    TLRPC.Dialog dialog = getMessagesController().dialogs_dict.get(did);
                    if (dialog != null) {
                        dialog.unread_count = 0;
                        getMessagesController().dialogMessage.remove(dialog.id);
                    }
                    getMessagesStorage().getStorageQueue().postRunnable(() -> AndroidUtilities.runOnUIThread(() -> {
                        getNotificationsController().processReadMessages(null, did, 0, Integer.MAX_VALUE, false);
                        LongSparseIntArray dialogsToUpdate = new LongSparseIntArray(1);
                        dialogsToUpdate.put(did, 0);
                        getNotificationsController().processDialogsUpdateRead(dialogsToUpdate);
                    }));
                    getMessagesStorage().deleteDialog(did, 1);
                    getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
                    getNotificationCenter().postNotificationName(NotificationCenter.removeAllMessagesFromDialog, did, false, null);
                });
                return null;
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionDeleteMessages) {
                if (!serviceMessage.action.random_ids.isEmpty()) {
                    pendingEncMessagesToDelete.addAll(serviceMessage.action.random_ids);
                }
                return null;
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionReadMessages) {
                if (!serviceMessage.action.random_ids.isEmpty()) {
                    int time = getConnectionsManager().getCurrentTime();
                    getMessagesStorage().createTaskForSecretChat(chat.id, time, time, 1, serviceMessage.action.random_ids);
                }
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) {
                applyPeerLayer(chat, serviceMessage.action.layer);
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionRequestKey) {
                if (chat.exchange_id != 0) {
                    if (chat.exchange_id > serviceMessage.action.exchange_id) {
                        if (BuildVars.LOGS_ENABLED) {
                            FileLog.d("we already have request key with higher exchange_id");
                        }
                        return null;
                    } else {
                        // TODO don't send?
                        sendAbortKeyMessage(chat, null, chat.exchange_id);
                    }
                }
                byte[] salt = new byte[256];
                Utilities.random.nextBytes(salt);
                BigInteger p = new BigInteger(1, getMessagesStorage().getSecretPBytes());
                BigInteger g_b = BigInteger.valueOf(getMessagesStorage().getSecretG());
                g_b = g_b.modPow(new BigInteger(1, salt), p);
                BigInteger g_a = new BigInteger(1, serviceMessage.action.g_a);
                if (!Utilities.isGoodGaAndGb(g_a, p)) {
                    sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id);
                    return null;
                }
                byte[] g_b_bytes = g_b.toByteArray();
                if (g_b_bytes.length > 256) {
                    byte[] correctedAuth = new byte[256];
                    System.arraycopy(g_b_bytes, 1, correctedAuth, 0, 256);
                    g_b_bytes = correctedAuth;
                }
                g_a = g_a.modPow(new BigInteger(1, salt), p);
                byte[] authKey = g_a.toByteArray();
                if (authKey.length > 256) {
                    byte[] correctedAuth = new byte[256];
                    System.arraycopy(authKey, authKey.length - 256, correctedAuth, 0, 256);
                    authKey = correctedAuth;
                } else if (authKey.length < 256) {
                    byte[] correctedAuth = new byte[256];
                    System.arraycopy(authKey, 0, correctedAuth, 256 - authKey.length, authKey.length);
                    for (int a = 0; a < 256 - authKey.length; a++) {
                        correctedAuth[a] = 0;
                    }
                    authKey = correctedAuth;
                }
                byte[] authKeyHash = Utilities.computeSHA1(authKey);
                byte[] authKeyId = new byte[8];
                System.arraycopy(authKeyHash, authKeyHash.length - 8, authKeyId, 0, 8);
                chat.exchange_id = serviceMessage.action.exchange_id;
                chat.future_auth_key = authKey;
                chat.future_key_fingerprint = Utilities.bytesToLong(authKeyId);
                chat.g_a_or_b = g_b_bytes;
                getMessagesStorage().updateEncryptedChat(chat);
                sendAcceptKeyMessage(chat, null);
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionAcceptKey) {
                if (chat.exchange_id == serviceMessage.action.exchange_id) {
                    BigInteger p = new BigInteger(1, getMessagesStorage().getSecretPBytes());
                    BigInteger i_authKey = new BigInteger(1, serviceMessage.action.g_b);
                    if (!Utilities.isGoodGaAndGb(i_authKey, p)) {
                        chat.future_auth_key = new byte[256];
                        chat.future_key_fingerprint = 0;
                        chat.exchange_id = 0;
                        getMessagesStorage().updateEncryptedChat(chat);
                        sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id);
                        return null;
                    }
                    i_authKey = i_authKey.modPow(new BigInteger(1, chat.a_or_b), p);
                    byte[] authKey = i_authKey.toByteArray();
                    if (authKey.length > 256) {
                        byte[] correctedAuth = new byte[256];
                        System.arraycopy(authKey, authKey.length - 256, correctedAuth, 0, 256);
                        authKey = correctedAuth;
                    } else if (authKey.length < 256) {
                        byte[] correctedAuth = new byte[256];
                        System.arraycopy(authKey, 0, correctedAuth, 256 - authKey.length, authKey.length);
                        for (int a = 0; a < 256 - authKey.length; a++) {
                            correctedAuth[a] = 0;
                        }
                        authKey = correctedAuth;
                    }
                    byte[] authKeyHash = Utilities.computeSHA1(authKey);
                    byte[] authKeyId = new byte[8];
                    System.arraycopy(authKeyHash, authKeyHash.length - 8, authKeyId, 0, 8);
                    long fingerprint = Utilities.bytesToLong(authKeyId);
                    if (serviceMessage.action.key_fingerprint == fingerprint) {
                        chat.future_auth_key = authKey;
                        chat.future_key_fingerprint = fingerprint;
                        getMessagesStorage().updateEncryptedChat(chat);
                        sendCommitKeyMessage(chat, null);
                    } else {
                        chat.future_auth_key = new byte[256];
                        chat.future_key_fingerprint = 0;
                        chat.exchange_id = 0;
                        getMessagesStorage().updateEncryptedChat(chat);
                        sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id);
                    }
                } else {
                    chat.future_auth_key = new byte[256];
                    chat.future_key_fingerprint = 0;
                    chat.exchange_id = 0;
                    getMessagesStorage().updateEncryptedChat(chat);
                    sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id);
                }
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionCommitKey) {
                if (chat.exchange_id == serviceMessage.action.exchange_id && chat.future_key_fingerprint == serviceMessage.action.key_fingerprint) {
                    long old_fingerprint = chat.key_fingerprint;
                    byte[] old_key = chat.auth_key;
                    chat.key_fingerprint = chat.future_key_fingerprint;
                    chat.auth_key = chat.future_auth_key;
                    chat.key_create_date = getConnectionsManager().getCurrentTime();
                    chat.future_auth_key = old_key;
                    chat.future_key_fingerprint = old_fingerprint;
                    chat.key_use_count_in = 0;
                    chat.key_use_count_out = 0;
                    chat.exchange_id = 0;
                    getMessagesStorage().updateEncryptedChat(chat);
                    sendNoopMessage(chat, null);
                } else {
                    chat.future_auth_key = new byte[256];
                    chat.future_key_fingerprint = 0;
                    chat.exchange_id = 0;
                    getMessagesStorage().updateEncryptedChat(chat);
                    sendAbortKeyMessage(chat, null, serviceMessage.action.exchange_id);
                }
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionAbortKey) {
                if (chat.exchange_id == serviceMessage.action.exchange_id) {
                    chat.future_auth_key = new byte[256];
                    chat.future_key_fingerprint = 0;
                    chat.exchange_id = 0;
                    getMessagesStorage().updateEncryptedChat(chat);
                }
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionNoop) {
            // do nothing
            } else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionResend) {
                if (serviceMessage.action.end_seq_no < chat.in_seq_no || serviceMessage.action.end_seq_no < serviceMessage.action.start_seq_no) {
                    return null;
                }
                if (serviceMessage.action.start_seq_no < chat.in_seq_no) {
                    serviceMessage.action.start_seq_no = chat.in_seq_no;
                }
                resendMessages(serviceMessage.action.start_seq_no, serviceMessage.action.end_seq_no, chat);
            } else {
                return null;
            }
        } else {
            if (BuildVars.LOGS_ENABLED) {
                FileLog.e("unknown message " + object);
            }
        }
    } else {
        if (BuildVars.LOGS_ENABLED) {
            FileLog.e("unknown TLObject");
        }
    }
    return null;
}
Also used : LongSparseIntArray(org.telegram.messenger.support.LongSparseIntArray) TLRPC(org.telegram.tgnet.TLRPC) BigInteger(java.math.BigInteger)

Aggregations

LongSparseIntArray (org.telegram.messenger.support.LongSparseIntArray)16 TLRPC (org.telegram.tgnet.TLRPC)11 ArrayList (java.util.ArrayList)9 SQLiteCursor (org.telegram.SQLite.SQLiteCursor)9 SQLiteException (org.telegram.SQLite.SQLiteException)9 LongSparseArray (androidx.collection.LongSparseArray)7 AtomicLong (java.util.concurrent.atomic.AtomicLong)6 SQLitePreparedStatement (org.telegram.SQLite.SQLitePreparedStatement)4 SparseArray (android.util.SparseArray)3 SparseIntArray (android.util.SparseIntArray)3 AlertDialog (org.telegram.ui.ActionBar.AlertDialog)3 Intent (android.content.Intent)2 SharedPreferences (android.content.SharedPreferences)2 SpannableStringBuilder (android.text.SpannableStringBuilder)2 HashMap (java.util.HashMap)2 Manifest (android.Manifest)1 Animator (android.animation.Animator)1 AnimatorListenerAdapter (android.animation.AnimatorListenerAdapter)1 AnimatorSet (android.animation.AnimatorSet)1 ObjectAnimator (android.animation.ObjectAnimator)1