Search in sources :

Example 56 with NativeByteBuffer

use of org.telegram.tgnet.NativeByteBuffer in project Telegram-FOSS by Telegram-FOSS-Team.

the class CacheControlActivity method clearDatabase.

private void clearDatabase() {
    AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
    builder.setTitle(LocaleController.getString("LocalDatabaseClearTextTitle", R.string.LocalDatabaseClearTextTitle));
    builder.setMessage(LocaleController.getString("LocalDatabaseClearText", R.string.LocalDatabaseClearText));
    builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
    builder.setPositiveButton(LocaleController.getString("CacheClear", R.string.CacheClear), (dialogInterface, i) -> {
        if (getParentActivity() == null) {
            return;
        }
        final AlertDialog progressDialog = new AlertDialog(getParentActivity(), 3);
        progressDialog.setCanCacnel(false);
        progressDialog.showDelayed(500);
        MessagesController.getInstance(currentAccount).clearQueryTime();
        MessagesStorage.getInstance(currentAccount).getStorageQueue().postRunnable(() -> {
            try {
                SQLiteDatabase database = MessagesStorage.getInstance(currentAccount).getDatabase();
                ArrayList<Long> dialogsToCleanup = new ArrayList<>();
                database.executeFast("DELETE FROM reaction_mentions").stepThis().dispose();
                database.executeFast("DELETE FROM reaction_mentions").stepThis().dispose();
                SQLiteCursor cursor = database.queryFinalized("SELECT did FROM dialogs WHERE 1");
                StringBuilder ids = new StringBuilder();
                while (cursor.next()) {
                    long did = cursor.longValue(0);
                    if (!DialogObject.isEncryptedDialog(did)) {
                        dialogsToCleanup.add(did);
                    }
                }
                cursor.dispose();
                SQLitePreparedStatement state5 = database.executeFast("REPLACE INTO messages_holes VALUES(?, ?, ?)");
                SQLitePreparedStatement state6 = database.executeFast("REPLACE INTO media_holes_v2 VALUES(?, ?, ?, ?)");
                database.beginTransaction();
                for (int a = 0; a < dialogsToCleanup.size(); a++) {
                    Long did = dialogsToCleanup.get(a);
                    int messagesCount = 0;
                    cursor = database.queryFinalized("SELECT COUNT(mid) FROM messages_v2 WHERE uid = " + did);
                    if (cursor.next()) {
                        messagesCount = cursor.intValue(0);
                    }
                    cursor.dispose();
                    if (messagesCount <= 2) {
                        continue;
                    }
                    cursor = database.queryFinalized("SELECT last_mid_i, last_mid FROM dialogs WHERE did = " + did);
                    int messageId = -1;
                    if (cursor.next()) {
                        long last_mid_i = cursor.longValue(0);
                        long last_mid = cursor.longValue(1);
                        SQLiteCursor cursor2 = database.queryFinalized("SELECT data FROM messages_v2 WHERE uid = " + did + " AND mid IN (" + last_mid_i + "," + last_mid + ")");
                        try {
                            while (cursor2.next()) {
                                NativeByteBuffer data = cursor2.byteBufferValue(0);
                                if (data != null) {
                                    TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                                    if (message != null) {
                                        messageId = message.id;
                                        message.readAttachPath(data, UserConfig.getInstance(currentAccount).clientUserId);
                                    }
                                    data.reuse();
                                }
                            }
                        } catch (Exception e) {
                            FileLog.e(e);
                        }
                        cursor2.dispose();
                        database.executeFast("DELETE FROM messages_v2 WHERE uid = " + did + " AND mid != " + last_mid_i + " AND mid != " + last_mid).stepThis().dispose();
                        database.executeFast("DELETE FROM messages_holes WHERE uid = " + did).stepThis().dispose();
                        database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose();
                        database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + did).stepThis().dispose();
                        database.executeFast("DELETE FROM media_v4 WHERE uid = " + did).stepThis().dispose();
                        database.executeFast("DELETE FROM media_holes_v2 WHERE uid = " + did).stepThis().dispose();
                        MediaDataController.getInstance(currentAccount).clearBotKeyboard(did, null);
                        if (messageId != -1) {
                            MessagesStorage.createFirstHoles(did, state5, state6, messageId);
                        }
                    }
                    cursor.dispose();
                }
                state5.dispose();
                state6.dispose();
                database.commitTransaction();
                database.executeFast("PRAGMA journal_size_limit = 0").stepThis().dispose();
                database.executeFast("VACUUM").stepThis().dispose();
                database.executeFast("PRAGMA journal_size_limit = -1").stepThis().dispose();
            } catch (Exception e) {
                FileLog.e(e);
            } finally {
                AndroidUtilities.runOnUIThread(() -> {
                    try {
                        progressDialog.dismiss();
                    } catch (Exception e) {
                        FileLog.e(e);
                    }
                    if (listAdapter != null) {
                        databaseSize = MessagesStorage.getInstance(currentAccount).getDatabaseSize();
                        listAdapter.notifyDataSetChanged();
                    }
                    NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.didClearDatabase);
                });
            }
        });
    });
    AlertDialog alertDialog = builder.create();
    showDialog(alertDialog);
    TextView button = (TextView) alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
    if (button != null) {
        button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2));
    }
}
Also used : AlertDialog(org.telegram.ui.ActionBar.AlertDialog) ArrayList(java.util.ArrayList) NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) TLRPC(org.telegram.tgnet.TLRPC) SQLitePreparedStatement(org.telegram.SQLite.SQLitePreparedStatement) SQLiteDatabase(org.telegram.SQLite.SQLiteDatabase) TextView(android.widget.TextView)

Example 57 with NativeByteBuffer

use of org.telegram.tgnet.NativeByteBuffer in project Telegram-FOSS by Telegram-FOSS-Team.

the class FileUploadOperation method startUploadRequest.

private void startUploadRequest() {
    if (state != 1) {
        return;
    }
    final TLObject finalRequest;
    final int currentRequestPartNum;
    final int currentRequestBytes;
    final byte[] currentRequestIv;
    try {
        started = true;
        if (stream == null) {
            File cacheFile = new File(uploadingFilePath);
            if (AndroidUtilities.isInternalUri(Uri.fromFile(cacheFile))) {
                throw new Exception("trying to upload internal file");
            }
            stream = new RandomAccessFile(cacheFile, "r");
            boolean isInternalFile = false;
            try {
                @SuppressLint("DiscouragedPrivateApi") Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$");
                int fdint = (Integer) getInt.invoke(stream.getFD());
                if (AndroidUtilities.isInternalUri(fdint)) {
                    isInternalFile = true;
                }
            } catch (Throwable e) {
                FileLog.e(e);
            }
            if (isInternalFile) {
                throw new Exception("trying to upload internal file");
            }
            if (estimatedSize != 0) {
                totalFileSize = estimatedSize;
            } else {
                totalFileSize = cacheFile.length();
            }
            if (!forceSmallFile && totalFileSize > 10 * 1024 * 1024) {
                isBigFile = true;
            }
            uploadChunkSize = (int) Math.max(slowNetwork ? minUploadChunkSlowNetworkSize : minUploadChunkSize, (totalFileSize + 1024 * maxUploadParts - 1) / (1024 * maxUploadParts));
            if (1024 % uploadChunkSize != 0) {
                int chunkSize = 64;
                while (uploadChunkSize > chunkSize) {
                    chunkSize *= 2;
                }
                uploadChunkSize = chunkSize;
            }
            maxRequestsCount = Math.max(1, (slowNetwork ? maxUploadingSlowNetworkKBytes : maxUploadingKBytes) / uploadChunkSize);
            if (isEncrypted) {
                freeRequestIvs = new ArrayList<>(maxRequestsCount);
                for (int a = 0; a < maxRequestsCount; a++) {
                    freeRequestIvs.add(new byte[32]);
                }
            }
            uploadChunkSize *= 1024;
            calcTotalPartsCount();
            readBuffer = new byte[uploadChunkSize];
            fileKey = Utilities.MD5(uploadingFilePath + (isEncrypted ? "enc" : ""));
            long fileSize = preferences.getLong(fileKey + "_size", 0);
            uploadStartTime = (int) (System.currentTimeMillis() / 1000);
            boolean rewrite = false;
            if (!uploadFirstPartLater && !nextPartFirst && estimatedSize == 0 && fileSize == totalFileSize) {
                currentFileId = preferences.getLong(fileKey + "_id", 0);
                int date = preferences.getInt(fileKey + "_time", 0);
                long uploadedSize = preferences.getLong(fileKey + "_uploaded", 0);
                if (isEncrypted) {
                    String ivString = preferences.getString(fileKey + "_iv", null);
                    String keyString = preferences.getString(fileKey + "_key", null);
                    if (ivString != null && keyString != null) {
                        key = Utilities.hexToBytes(keyString);
                        iv = Utilities.hexToBytes(ivString);
                        if (key != null && iv != null && key.length == 32 && iv.length == 32) {
                            ivChange = new byte[32];
                            System.arraycopy(iv, 0, ivChange, 0, 32);
                        } else {
                            rewrite = true;
                        }
                    } else {
                        rewrite = true;
                    }
                }
                if (!rewrite && date != 0) {
                    if (isBigFile && date < uploadStartTime - 60 * 60 * 24) {
                        date = 0;
                    } else if (!isBigFile && date < uploadStartTime - 60 * 60 * 1.5f) {
                        date = 0;
                    }
                    if (date != 0) {
                        if (uploadedSize > 0) {
                            readBytesCount = uploadedSize;
                            currentPartNum = (int) (uploadedSize / uploadChunkSize);
                            if (!isBigFile) {
                                for (int b = 0; b < readBytesCount / uploadChunkSize; b++) {
                                    int bytesRead = stream.read(readBuffer);
                                    int toAdd = 0;
                                    if (isEncrypted && bytesRead % 16 != 0) {
                                        toAdd += 16 - bytesRead % 16;
                                    }
                                    NativeByteBuffer sendBuffer = new NativeByteBuffer(bytesRead + toAdd);
                                    if (bytesRead != uploadChunkSize || totalPartsCount == currentPartNum + 1) {
                                        isLastPart = true;
                                    }
                                    sendBuffer.writeBytes(readBuffer, 0, bytesRead);
                                    if (isEncrypted) {
                                        for (int a = 0; a < toAdd; a++) {
                                            sendBuffer.writeByte(0);
                                        }
                                        Utilities.aesIgeEncryption(sendBuffer.buffer, key, ivChange, true, true, 0, bytesRead + toAdd);
                                    }
                                    sendBuffer.reuse();
                                }
                            } else {
                                stream.seek(uploadedSize);
                                if (isEncrypted) {
                                    String ivcString = preferences.getString(fileKey + "_ivc", null);
                                    if (ivcString != null) {
                                        ivChange = Utilities.hexToBytes(ivcString);
                                        if (ivChange == null || ivChange.length != 32) {
                                            rewrite = true;
                                            readBytesCount = 0;
                                            currentPartNum = 0;
                                        }
                                    } else {
                                        rewrite = true;
                                        readBytesCount = 0;
                                        currentPartNum = 0;
                                    }
                                }
                            }
                        } else {
                            rewrite = true;
                        }
                    }
                } else {
                    rewrite = true;
                }
            } else {
                rewrite = true;
            }
            if (rewrite) {
                if (isEncrypted) {
                    iv = new byte[32];
                    key = new byte[32];
                    ivChange = new byte[32];
                    Utilities.random.nextBytes(iv);
                    Utilities.random.nextBytes(key);
                    System.arraycopy(iv, 0, ivChange, 0, 32);
                }
                currentFileId = Utilities.random.nextLong();
                if (!nextPartFirst && !uploadFirstPartLater && estimatedSize == 0) {
                    storeFileUploadInfo();
                }
            }
            if (isEncrypted) {
                try {
                    java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
                    byte[] arr = new byte[64];
                    System.arraycopy(key, 0, arr, 0, 32);
                    System.arraycopy(iv, 0, arr, 32, 32);
                    byte[] digest = md.digest(arr);
                    for (int a = 0; a < 4; a++) {
                        fingerprint |= ((digest[a] ^ digest[a + 4]) & 0xFF) << (a * 8);
                    }
                } catch (Exception e) {
                    FileLog.e(e);
                }
            }
            uploadedBytesCount = readBytesCount;
            lastSavedPartNum = currentPartNum;
            if (uploadFirstPartLater) {
                if (isBigFile) {
                    stream.seek(uploadChunkSize);
                    readBytesCount = uploadChunkSize;
                } else {
                    stream.seek(1024);
                    readBytesCount = 1024;
                }
                currentPartNum = 1;
            }
        }
        if (estimatedSize != 0) {
            if (readBytesCount + uploadChunkSize > availableSize) {
                return;
            }
        }
        if (nextPartFirst) {
            stream.seek(0);
            if (isBigFile) {
                currentRequestBytes = stream.read(readBuffer);
            } else {
                currentRequestBytes = stream.read(readBuffer, 0, 1024);
            }
            currentPartNum = 0;
        } else {
            currentRequestBytes = stream.read(readBuffer);
        }
        if (currentRequestBytes == -1) {
            return;
        }
        int toAdd = 0;
        if (isEncrypted && currentRequestBytes % 16 != 0) {
            toAdd += 16 - currentRequestBytes % 16;
        }
        NativeByteBuffer sendBuffer = new NativeByteBuffer(currentRequestBytes + toAdd);
        if (nextPartFirst || currentRequestBytes != uploadChunkSize || estimatedSize == 0 && totalPartsCount == currentPartNum + 1) {
            if (uploadFirstPartLater) {
                nextPartFirst = true;
                uploadFirstPartLater = false;
            } else {
                isLastPart = true;
            }
        }
        sendBuffer.writeBytes(readBuffer, 0, currentRequestBytes);
        if (isEncrypted) {
            for (int a = 0; a < toAdd; a++) {
                sendBuffer.writeByte(0);
            }
            Utilities.aesIgeEncryption(sendBuffer.buffer, key, ivChange, true, true, 0, currentRequestBytes + toAdd);
            currentRequestIv = freeRequestIvs.get(0);
            System.arraycopy(ivChange, 0, currentRequestIv, 0, 32);
            freeRequestIvs.remove(0);
        } else {
            currentRequestIv = null;
        }
        if (isBigFile) {
            TLRPC.TL_upload_saveBigFilePart req = new TLRPC.TL_upload_saveBigFilePart();
            req.file_part = currentRequestPartNum = currentPartNum;
            req.file_id = currentFileId;
            if (estimatedSize != 0) {
                req.file_total_parts = -1;
            } else {
                req.file_total_parts = totalPartsCount;
            }
            req.bytes = sendBuffer;
            finalRequest = req;
        } else {
            TLRPC.TL_upload_saveFilePart req = new TLRPC.TL_upload_saveFilePart();
            req.file_part = currentRequestPartNum = currentPartNum;
            req.file_id = currentFileId;
            req.bytes = sendBuffer;
            finalRequest = req;
        }
        if (isLastPart && nextPartFirst) {
            nextPartFirst = false;
            currentPartNum = totalPartsCount - 1;
            stream.seek(totalFileSize);
        }
        readBytesCount += currentRequestBytes;
    } catch (Exception e) {
        FileLog.e(e);
        state = 4;
        delegate.didFailedUploadingFile(this);
        cleanup();
        return;
    }
    currentPartNum++;
    currentUploadRequetsCount++;
    final int requestNumFinal = requestNum++;
    final long currentRequestBytesOffset = currentRequestPartNum + currentRequestBytes;
    final int requestSize = finalRequest.getObjectSize() + 4;
    final int currentOperationGuid = operationGuid;
    int connectionType;
    if (slowNetwork) {
        connectionType = ConnectionsManager.ConnectionTypeUpload;
    } else {
        connectionType = ConnectionsManager.ConnectionTypeUpload | ((requestNumFinal % 4) << 16);
    }
    int requestToken = ConnectionsManager.getInstance(currentAccount).sendRequest(finalRequest, (response, error) -> {
        if (currentOperationGuid != operationGuid) {
            return;
        }
        int networkType = response != null ? response.networkType : ApplicationLoader.getCurrentNetworkType();
        if (currentType == ConnectionsManager.FileTypeAudio) {
            StatsController.getInstance(currentAccount).incrementSentBytesCount(networkType, StatsController.TYPE_AUDIOS, requestSize);
        } else if (currentType == ConnectionsManager.FileTypeVideo) {
            StatsController.getInstance(currentAccount).incrementSentBytesCount(networkType, StatsController.TYPE_VIDEOS, requestSize);
        } else if (currentType == ConnectionsManager.FileTypePhoto) {
            StatsController.getInstance(currentAccount).incrementSentBytesCount(networkType, StatsController.TYPE_PHOTOS, requestSize);
        } else if (currentType == ConnectionsManager.FileTypeFile) {
            StatsController.getInstance(currentAccount).incrementSentBytesCount(networkType, StatsController.TYPE_FILES, requestSize);
        }
        if (currentRequestIv != null) {
            freeRequestIvs.add(currentRequestIv);
        }
        requestTokens.delete(requestNumFinal);
        if (response instanceof TLRPC.TL_boolTrue) {
            if (state != 1) {
                return;
            }
            uploadedBytesCount += currentRequestBytes;
            long size;
            if (estimatedSize != 0) {
                size = Math.max(availableSize, estimatedSize);
            } else {
                size = totalFileSize;
            }
            delegate.didChangedUploadProgress(FileUploadOperation.this, uploadedBytesCount, size);
            currentUploadRequetsCount--;
            if (isLastPart && currentUploadRequetsCount == 0 && state == 1) {
                state = 3;
                if (key == null) {
                    TLRPC.InputFile result;
                    if (isBigFile) {
                        result = new TLRPC.TL_inputFileBig();
                    } else {
                        result = new TLRPC.TL_inputFile();
                        result.md5_checksum = "";
                    }
                    result.parts = currentPartNum;
                    result.id = currentFileId;
                    result.name = uploadingFilePath.substring(uploadingFilePath.lastIndexOf("/") + 1);
                    delegate.didFinishUploadingFile(FileUploadOperation.this, result, null, null, null);
                    cleanup();
                } else {
                    TLRPC.InputEncryptedFile result;
                    if (isBigFile) {
                        result = new TLRPC.TL_inputEncryptedFileBigUploaded();
                    } else {
                        result = new TLRPC.TL_inputEncryptedFileUploaded();
                        result.md5_checksum = "";
                    }
                    result.parts = currentPartNum;
                    result.id = currentFileId;
                    result.key_fingerprint = fingerprint;
                    delegate.didFinishUploadingFile(FileUploadOperation.this, null, result, key, iv);
                    cleanup();
                }
                if (currentType == ConnectionsManager.FileTypeAudio) {
                    StatsController.getInstance(currentAccount).incrementSentItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_AUDIOS, 1);
                } else if (currentType == ConnectionsManager.FileTypeVideo) {
                    StatsController.getInstance(currentAccount).incrementSentItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_VIDEOS, 1);
                } else if (currentType == ConnectionsManager.FileTypePhoto) {
                    StatsController.getInstance(currentAccount).incrementSentItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_PHOTOS, 1);
                } else if (currentType == ConnectionsManager.FileTypeFile) {
                    StatsController.getInstance(currentAccount).incrementSentItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_FILES, 1);
                }
            } else if (currentUploadRequetsCount < maxRequestsCount) {
                if (estimatedSize == 0 && !uploadFirstPartLater && !nextPartFirst) {
                    if (saveInfoTimes >= 4) {
                        saveInfoTimes = 0;
                    }
                    if (currentRequestPartNum == lastSavedPartNum) {
                        lastSavedPartNum++;
                        long offsetToSave = currentRequestBytesOffset;
                        byte[] ivToSave = currentRequestIv;
                        UploadCachedResult result;
                        while ((result = cachedResults.get(lastSavedPartNum)) != null) {
                            offsetToSave = result.bytesOffset;
                            ivToSave = result.iv;
                            cachedResults.remove(lastSavedPartNum);
                            lastSavedPartNum++;
                        }
                        if (isBigFile && offsetToSave % (1024 * 1024) == 0 || !isBigFile && saveInfoTimes == 0) {
                            SharedPreferences.Editor editor = preferences.edit();
                            editor.putLong(fileKey + "_uploaded", offsetToSave);
                            if (isEncrypted) {
                                editor.putString(fileKey + "_ivc", Utilities.bytesToHex(ivToSave));
                            }
                            editor.commit();
                        }
                    } else {
                        UploadCachedResult result = new UploadCachedResult();
                        result.bytesOffset = currentRequestBytesOffset;
                        if (currentRequestIv != null) {
                            result.iv = new byte[32];
                            System.arraycopy(currentRequestIv, 0, result.iv, 0, 32);
                        }
                        cachedResults.put(currentRequestPartNum, result);
                    }
                    saveInfoTimes++;
                }
                startUploadRequest();
            }
        } else {
            state = 4;
            delegate.didFailedUploadingFile(FileUploadOperation.this);
            cleanup();
        }
    }, null, () -> Utilities.stageQueue.postRunnable(() -> {
        if (currentUploadRequetsCount < maxRequestsCount) {
            startUploadRequest();
        }
    }), forceSmallFile ? ConnectionsManager.RequestFlagCanCompress : 0, ConnectionsManager.DEFAULT_DATACENTER_ID, connectionType, true);
    requestTokens.put(requestNumFinal, requestToken);
}
Also used : TLRPC(org.telegram.tgnet.TLRPC) Method(java.lang.reflect.Method) NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) SuppressLint(android.annotation.SuppressLint) RandomAccessFile(java.io.RandomAccessFile) TLObject(org.telegram.tgnet.TLObject) SuppressLint(android.annotation.SuppressLint) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File)

Example 58 with NativeByteBuffer

use of org.telegram.tgnet.NativeByteBuffer in project Telegram-FOSS by Telegram-FOSS-Team.

the class MediaDataController method putStickersToCache.

private void putStickersToCache(int type, ArrayList<TLRPC.TL_messages_stickerSet> stickers, int date, long hash) {
    ArrayList<TLRPC.TL_messages_stickerSet> stickersFinal = stickers != null ? new ArrayList<>(stickers) : null;
    getMessagesStorage().getStorageQueue().postRunnable(() -> {
        try {
            if (stickersFinal != null) {
                SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO stickers_v2 VALUES(?, ?, ?, ?)");
                state.requery();
                int size = 4;
                for (int a = 0; a < stickersFinal.size(); a++) {
                    size += stickersFinal.get(a).getObjectSize();
                }
                NativeByteBuffer data = new NativeByteBuffer(size);
                data.writeInt32(stickersFinal.size());
                for (int a = 0; a < stickersFinal.size(); a++) {
                    stickersFinal.get(a).serializeToStream(data);
                }
                state.bindInteger(1, type + 1);
                state.bindByteBuffer(2, data);
                state.bindInteger(3, date);
                state.bindLong(4, hash);
                state.step();
                data.reuse();
                state.dispose();
            } else {
                SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("UPDATE stickers_v2 SET date = ?");
                state.requery();
                state.bindLong(1, date);
                state.step();
                state.dispose();
            }
        } catch (Exception e) {
            FileLog.e(e);
        }
    });
}
Also used : NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) Paint(android.graphics.Paint) SQLiteException(org.telegram.SQLite.SQLiteException) SQLitePreparedStatement(org.telegram.SQLite.SQLitePreparedStatement)

Example 59 with NativeByteBuffer

use of org.telegram.tgnet.NativeByteBuffer in project Telegram-FOSS by Telegram-FOSS-Team.

the class LocationController method loadSharingLocations.

private void loadSharingLocations() {
    getMessagesStorage().getStorageQueue().postRunnable(() -> {
        final ArrayList<SharingLocationInfo> result = new ArrayList<>();
        final ArrayList<TLRPC.User> users = new ArrayList<>();
        final ArrayList<TLRPC.Chat> chats = new ArrayList<>();
        try {
            ArrayList<Long> usersToLoad = new ArrayList<>();
            ArrayList<Long> chatsToLoad = new ArrayList<>();
            SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized("SELECT uid, mid, date, period, message, proximity FROM sharing_locations WHERE 1");
            while (cursor.next()) {
                SharingLocationInfo info = new SharingLocationInfo();
                info.did = cursor.longValue(0);
                info.mid = cursor.intValue(1);
                info.stopTime = cursor.intValue(2);
                info.period = cursor.intValue(3);
                info.proximityMeters = cursor.intValue(5);
                info.account = currentAccount;
                NativeByteBuffer data = cursor.byteBufferValue(4);
                if (data != null) {
                    info.messageObject = new MessageObject(currentAccount, TLRPC.Message.TLdeserialize(data, data.readInt32(false), false), false, false);
                    MessagesStorage.addUsersAndChatsFromMessage(info.messageObject.messageOwner, usersToLoad, chatsToLoad);
                    data.reuse();
                }
                result.add(info);
                if (DialogObject.isChatDialog(info.did)) {
                    if (!chatsToLoad.contains(-info.did)) {
                        chatsToLoad.add(-info.did);
                    }
                } else if (DialogObject.isUserDialog(info.did)) {
                    if (!usersToLoad.contains(info.did)) {
                        usersToLoad.add(info.did);
                    }
                }
            }
            cursor.dispose();
            if (!chatsToLoad.isEmpty()) {
                getMessagesStorage().getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
            }
            if (!usersToLoad.isEmpty()) {
                getMessagesStorage().getUsersInternal(TextUtils.join(",", usersToLoad), users);
            }
        } catch (Exception e) {
            FileLog.e(e);
        }
        if (!result.isEmpty()) {
            AndroidUtilities.runOnUIThread(() -> {
                getMessagesController().putUsers(users, true);
                getMessagesController().putChats(chats, true);
                Utilities.stageQueue.postRunnable(() -> {
                    sharingLocations.addAll(result);
                    for (int a = 0; a < sharingLocations.size(); a++) {
                        SharingLocationInfo info = sharingLocations.get(a);
                        sharingLocationsMap.put(info.did, info);
                    }
                    AndroidUtilities.runOnUIThread(() -> {
                        sharingLocationsUI.addAll(result);
                        for (int a = 0; a < result.size(); a++) {
                            SharingLocationInfo info = result.get(a);
                            sharingLocationsMapUI.put(info.did, info);
                        }
                        startService();
                        NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.liveLocationsChanged);
                    });
                });
            });
        }
    });
}
Also used : ArrayList(java.util.ArrayList) NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SuppressLint(android.annotation.SuppressLint)

Example 60 with NativeByteBuffer

use of org.telegram.tgnet.NativeByteBuffer in project Telegram-FOSS by Telegram-FOSS-Team.

the class MessagesStorage method getMessagesInternal.

public Runnable getMessagesInternal(long dialogId, long mergeDialogId, int count, int max_id, int offset_date, int minDate, int classGuid, int load_type, boolean scheduled, int replyMessageId, int loadIndex, boolean processMessages) {
    TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages();
    long currentUserId = getUserConfig().clientUserId;
    int count_unread = 0;
    int mentions_unread = 0;
    int count_query = count;
    int offset_query = 0;
    int min_unread_id = 0;
    int last_message_id = 0;
    boolean queryFromServer = false;
    int max_unread_date = 0;
    int messageMaxId = max_id;
    int max_id_query = max_id;
    boolean unreadCountIsLocal = false;
    int max_id_override = max_id;
    boolean isEnd = false;
    int num = dialogId == 777000 ? 10 : 1;
    int messagesCount = 0;
    long startLoadTime = SystemClock.elapsedRealtime();
    try {
        ArrayList<Long> usersToLoad = new ArrayList<>();
        ArrayList<Long> chatsToLoad = new ArrayList<>();
        LongSparseArray<SparseArray<ArrayList<TLRPC.Message>>> replyMessageOwners = new LongSparseArray<>();
        LongSparseArray<ArrayList<Integer>> dialogReplyMessagesIds = new LongSparseArray<>();
        LongSparseArray<ArrayList<TLRPC.Message>> replyMessageRandomOwners = new LongSparseArray<>();
        ArrayList<Long> replyMessageRandomIds = new ArrayList<>();
        SQLiteCursor cursor;
        String messageSelect = "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl, m.mention, m.imp, m.forwards, m.replies_data FROM messages_v2 as m LEFT JOIN randoms_v2 as r ON r.mid = m.mid AND r.uid = m.uid";
        if (scheduled) {
            isEnd = true;
            cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.ttl FROM scheduled_messages_v2 as m LEFT JOIN randoms_v2 as r ON r.mid = m.mid AND r.uid = m.uid WHERE m.uid = %d ORDER BY m.date DESC", dialogId));
            while (cursor.next()) {
                NativeByteBuffer data = cursor.byteBufferValue(0);
                if (data != null) {
                    TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                    message.send_state = cursor.intValue(1);
                    message.id = cursor.intValue(2);
                    if (message.id > 0 && message.send_state != 0 && message.send_state != 3) {
                        message.send_state = 0;
                    }
                    if (dialogId == currentUserId) {
                        message.out = true;
                        message.unread = false;
                    } else {
                        message.unread = true;
                    }
                    message.readAttachPath(data, currentUserId);
                    data.reuse();
                    message.date = cursor.intValue(3);
                    message.dialog_id = dialogId;
                    if (message.ttl == 0) {
                        message.ttl = cursor.intValue(6);
                    }
                    res.messages.add(message);
                    addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
                    if (message.reply_to != null && (message.reply_to.reply_to_msg_id != 0 || message.reply_to.reply_to_random_id != 0)) {
                        if (!cursor.isNull(5)) {
                            data = cursor.byteBufferValue(5);
                            if (data != null) {
                                message.replyMessage = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                                message.replyMessage.readAttachPath(data, currentUserId);
                                data.reuse();
                                if (message.replyMessage != null) {
                                    addUsersAndChatsFromMessage(message.replyMessage, usersToLoad, chatsToLoad);
                                }
                            }
                        }
                        if (message.replyMessage == null) {
                            if (message.reply_to.reply_to_msg_id != 0) {
                                addReplyMessages(message, replyMessageOwners, dialogReplyMessagesIds);
                            } else {
                                ArrayList<TLRPC.Message> messages = replyMessageRandomOwners.get(message.reply_to.reply_to_random_id);
                                if (messages == null) {
                                    messages = new ArrayList<>();
                                    replyMessageRandomOwners.put(message.reply_to.reply_to_random_id, messages);
                                }
                                if (!replyMessageRandomIds.contains(message.reply_to.reply_to_random_id)) {
                                    replyMessageRandomIds.add(message.reply_to.reply_to_random_id);
                                }
                                messages.add(message);
                            }
                        }
                    }
                }
            }
            cursor.dispose();
        } else {
            if (!DialogObject.isEncryptedDialog(dialogId)) {
                if (load_type == 3 && minDate == 0) {
                    cursor = database.queryFinalized("SELECT inbox_max, unread_count, date, unread_count_i FROM dialogs WHERE did = " + dialogId);
                    if (cursor.next()) {
                        min_unread_id = Math.max(1, cursor.intValue(0)) + 1;
                        count_unread = cursor.intValue(1);
                        max_unread_date = cursor.intValue(2);
                        mentions_unread = cursor.intValue(3);
                    }
                    cursor.dispose();
                } else if (load_type != 1 && load_type != 3 && load_type != 4 && minDate == 0) {
                    if (load_type == 2) {
                        cursor = database.queryFinalized("SELECT inbox_max, unread_count, date, unread_count_i FROM dialogs WHERE did = " + dialogId);
                        if (cursor.next()) {
                            messageMaxId = max_id_query = min_unread_id = Math.max(1, cursor.intValue(0));
                            count_unread = cursor.intValue(1);
                            max_unread_date = cursor.intValue(2);
                            mentions_unread = cursor.intValue(3);
                            queryFromServer = true;
                            if (dialogId == currentUserId) {
                                count_unread = 0;
                            }
                        }
                        cursor.dispose();
                        if (!queryFromServer) {
                            cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid), max(date) FROM messages_v2 WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid > 0", dialogId));
                            if (cursor.next()) {
                                min_unread_id = cursor.intValue(0);
                                max_unread_date = cursor.intValue(1);
                            }
                            cursor.dispose();
                            if (min_unread_id != 0) {
                                cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages_v2 WHERE uid = %d AND mid >= %d AND out = 0 AND read_state IN(0,2)", dialogId, min_unread_id));
                                if (cursor.next()) {
                                    count_unread = cursor.intValue(0);
                                }
                                cursor.dispose();
                            }
                        } else if (max_id_query == 0) {
                            int existingUnreadCount = 0;
                            cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages_v2 WHERE uid = %d AND mid > 0 AND out = 0 AND read_state IN(0,2)", dialogId));
                            if (cursor.next()) {
                                existingUnreadCount = cursor.intValue(0);
                            }
                            cursor.dispose();
                            if (existingUnreadCount == count_unread) {
                                cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages_v2 WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid > 0", dialogId));
                                if (cursor.next()) {
                                    messageMaxId = max_id_query = min_unread_id = cursor.intValue(0);
                                }
                                cursor.dispose();
                            }
                        } else {
                            cursor = database.queryFinalized(String.format(Locale.US, "SELECT start, end FROM messages_holes WHERE uid = %d AND start < %d AND end > %d", dialogId, max_id_query, max_id_query));
                            boolean containMessage = !cursor.next();
                            cursor.dispose();
                            if (containMessage) {
                                cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages_v2 WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid > %d", dialogId, max_id_query));
                                if (cursor.next()) {
                                    messageMaxId = max_id_query = cursor.intValue(0);
                                }
                                cursor.dispose();
                            }
                        }
                    }
                    if (count_query > count_unread || count_unread < num) {
                        count_query = Math.max(count_query, count_unread + 10);
                        if (count_unread < num) {
                            count_unread = 0;
                            min_unread_id = 0;
                            messageMaxId = 0;
                            last_message_id = 0;
                            queryFromServer = false;
                        }
                    } else {
                        offset_query = count_unread - count_query;
                        count_query += 10;
                    }
                }
                cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM messages_holes WHERE uid = %d AND start IN (0, 1)", dialogId));
                if (cursor.next()) {
                    isEnd = cursor.intValue(0) == 1;
                } else {
                    cursor.dispose();
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages_v2 WHERE uid = %d AND mid > 0", dialogId));
                    if (cursor.next()) {
                        int mid = cursor.intValue(0);
                        if (mid != 0) {
                            SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages_holes VALUES(?, ?, ?)");
                            state.requery();
                            state.bindLong(1, dialogId);
                            state.bindInteger(2, 0);
                            state.bindInteger(3, mid);
                            state.step();
                            state.dispose();
                        }
                    }
                }
                cursor.dispose();
                if (load_type == 3 || load_type == 4 || queryFromServer && load_type == 2) {
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid) FROM messages_v2 WHERE uid = %d AND mid > 0", dialogId));
                    if (cursor.next()) {
                        last_message_id = cursor.intValue(0);
                    }
                    cursor.dispose();
                    if (load_type == 4 && offset_date != 0) {
                        int startMid;
                        int endMid;
                        cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid) FROM messages_v2 WHERE uid = %d AND date <= %d AND mid > 0", dialogId, offset_date));
                        if (cursor.next()) {
                            startMid = cursor.intValue(0);
                        } else {
                            startMid = -1;
                        }
                        cursor.dispose();
                        cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages_v2 WHERE uid = %d AND date >= %d AND mid > 0", dialogId, offset_date));
                        if (cursor.next()) {
                            endMid = cursor.intValue(0);
                        } else {
                            endMid = -1;
                        }
                        cursor.dispose();
                        if (startMid != -1 && endMid != -1) {
                            if (startMid == endMid) {
                                max_id_query = startMid;
                            } else {
                                cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM messages_holes WHERE uid = %d AND start <= %d AND end > %d", dialogId, startMid, startMid));
                                if (cursor.next()) {
                                    startMid = -1;
                                }
                                cursor.dispose();
                                if (startMid != -1) {
                                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM messages_holes WHERE uid = %d AND start <= %d AND end > %d", dialogId, endMid, endMid));
                                    if (cursor.next()) {
                                        endMid = -1;
                                    }
                                    cursor.dispose();
                                    if (endMid != -1) {
                                        max_id_override = endMid;
                                        messageMaxId = max_id_query = endMid;
                                    }
                                }
                            }
                        }
                    }
                    boolean containMessage = max_id_query != 0;
                    if (containMessage) {
                        cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM messages_holes WHERE uid = %d AND start < %d AND end > %d", dialogId, max_id_query, max_id_query));
                        if (cursor.next()) {
                            containMessage = false;
                        }
                        cursor.dispose();
                    }
                    if (containMessage) {
                        int holeMessageMaxId = 0;
                        int holeMessageMinId = 1;
                        cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM messages_holes WHERE uid = %d AND start >= %d ORDER BY start ASC LIMIT 1", dialogId, max_id_query));
                        if (cursor.next()) {
                            holeMessageMaxId = cursor.intValue(0);
                        }
                        cursor.dispose();
                        cursor = database.queryFinalized(String.format(Locale.US, "SELECT end FROM messages_holes WHERE uid = %d AND end <= %d ORDER BY end DESC LIMIT 1", dialogId, max_id_query));
                        if (cursor.next()) {
                            holeMessageMinId = cursor.intValue(0);
                        }
                        cursor.dispose();
                        if (holeMessageMaxId != 0 || holeMessageMinId != 1) {
                            if (holeMessageMaxId == 0) {
                                holeMessageMaxId = 1000000000;
                            }
                            cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (" + messageSelect + " WHERE m.uid = %d AND m.mid <= %d AND (m.mid >= %d OR m.mid < 0) ORDER BY m.date DESC, m.mid DESC LIMIT %d) UNION " + "SELECT * FROM (" + messageSelect + " WHERE m.uid = %d AND m.mid > %d AND (m.mid <= %d OR m.mid < 0) ORDER BY m.date ASC, m.mid ASC LIMIT %d)", dialogId, messageMaxId, holeMessageMinId, count_query / 2, dialogId, messageMaxId, holeMessageMaxId, count_query / 2));
                        } else {
                            cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (" + messageSelect + " WHERE m.uid = %d AND m.mid <= %d ORDER BY m.date DESC, m.mid DESC LIMIT %d) UNION " + "SELECT * FROM (" + messageSelect + " WHERE m.uid = %d AND m.mid > %d ORDER BY m.date ASC, m.mid ASC LIMIT %d)", dialogId, messageMaxId, count_query / 2, dialogId, messageMaxId, count_query / 2));
                        }
                    } else {
                        if (load_type == 2) {
                            int existingUnreadCount = 0;
                            cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages_v2 WHERE uid = %d AND mid != 0 AND out = 0 AND read_state IN(0,2)", dialogId));
                            if (cursor.next()) {
                                existingUnreadCount = cursor.intValue(0);
                            }
                            cursor.dispose();
                            if (existingUnreadCount == count_unread) {
                                unreadCountIsLocal = true;
                                cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (" + messageSelect + " WHERE m.uid = %d AND m.mid <= %d ORDER BY m.date DESC, m.mid DESC LIMIT %d) UNION " + "SELECT * FROM (" + messageSelect + " WHERE m.uid = %d AND m.mid > %d ORDER BY m.date ASC, m.mid ASC LIMIT %d)", dialogId, messageMaxId, count_query / 2, dialogId, messageMaxId, count_query / 2));
                            } else {
                                cursor = null;
                            }
                        } else {
                            cursor = null;
                        }
                    }
                } else if (load_type == 1) {
                    int holeMessageId = 0;
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT start, end FROM messages_holes WHERE uid = %d AND (start >= %d AND start != 1 AND end != 1 OR start < %d AND end > %d) ORDER BY start ASC LIMIT 1", dialogId, max_id, max_id, max_id));
                    if (cursor.next()) {
                        holeMessageId = cursor.intValue(0);
                    }
                    cursor.dispose();
                    if (holeMessageId != 0) {
                        cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d AND m.date >= %d AND m.mid > %d AND m.mid <= %d ORDER BY m.date ASC, m.mid ASC LIMIT %d", dialogId, minDate, messageMaxId, holeMessageId, count_query));
                    } else {
                        cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d AND m.date >= %d AND m.mid > %d ORDER BY m.date ASC, m.mid ASC LIMIT %d", dialogId, minDate, messageMaxId, count_query));
                    }
                } else if (minDate != 0) {
                    if (messageMaxId != 0) {
                        int holeMessageId = 0;
                        cursor = database.queryFinalized(String.format(Locale.US, "SELECT end FROM messages_holes WHERE uid = %d AND end <= %d ORDER BY end DESC LIMIT 1", dialogId, max_id));
                        if (cursor.next()) {
                            holeMessageId = cursor.intValue(0);
                        }
                        cursor.dispose();
                        if (holeMessageId != 0) {
                            cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d AND m.date <= %d AND m.mid < %d AND (m.mid >= %d OR m.mid < 0) ORDER BY m.date DESC, m.mid DESC LIMIT %d", dialogId, minDate, messageMaxId, holeMessageId, count_query));
                        } else {
                            cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d AND m.date <= %d AND m.mid < %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", dialogId, minDate, messageMaxId, count_query));
                        }
                    } else {
                        cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d AND m.date <= %d ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialogId, minDate, offset_query, count_query));
                    }
                } else {
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid) FROM messages_v2 WHERE uid = %d AND mid > 0", dialogId));
                    if (cursor.next()) {
                        last_message_id = cursor.intValue(0);
                    }
                    cursor.dispose();
                    int holeMessageId = 0;
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(end) FROM messages_holes WHERE uid = %d", dialogId));
                    if (cursor.next()) {
                        holeMessageId = cursor.intValue(0);
                    }
                    cursor.dispose();
                    if (holeMessageId != 0) {
                        cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d AND (m.mid >= %d OR m.mid < 0) ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialogId, holeMessageId, offset_query, count_query));
                    } else {
                        cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialogId, offset_query, count_query));
                    }
                }
            } else {
                isEnd = true;
                if (load_type == 3 && minDate == 0) {
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages_v2 WHERE uid = %d AND mid < 0", dialogId));
                    if (cursor.next()) {
                        min_unread_id = cursor.intValue(0);
                    }
                    cursor.dispose();
                    int min_unread_id2 = 0;
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid), max(date) FROM messages_v2 WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid < 0", dialogId));
                    if (cursor.next()) {
                        min_unread_id2 = cursor.intValue(0);
                        max_unread_date = cursor.intValue(1);
                    }
                    cursor.dispose();
                    if (min_unread_id2 != 0) {
                        min_unread_id = min_unread_id2;
                        cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages_v2 WHERE uid = %d AND mid <= %d AND out = 0 AND read_state IN(0,2)", dialogId, min_unread_id2));
                        if (cursor.next()) {
                            count_unread = cursor.intValue(0);
                        }
                        cursor.dispose();
                    }
                }
                if (load_type == 3 || load_type == 4) {
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages_v2 WHERE uid = %d AND mid < 0", dialogId));
                    if (cursor.next()) {
                        last_message_id = cursor.intValue(0);
                    }
                    cursor.dispose();
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (" + messageSelect + " WHERE m.uid = %d AND m.mid <= %d ORDER BY m.mid DESC LIMIT %d) UNION " + "SELECT * FROM (" + messageSelect + " WHERE m.uid = %d AND m.mid > %d ORDER BY m.mid ASC LIMIT %d)", dialogId, messageMaxId, count_query / 2, dialogId, messageMaxId, count_query / 2));
                } else if (load_type == 1) {
                    cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d AND m.mid < %d ORDER BY m.mid DESC LIMIT %d", dialogId, max_id, count_query));
                } else if (minDate != 0) {
                    if (max_id != 0) {
                        cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d AND m.mid > %d ORDER BY m.mid ASC LIMIT %d", dialogId, max_id, count_query));
                    } else {
                        cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d AND m.date <= %d ORDER BY m.mid ASC LIMIT %d,%d", dialogId, minDate, offset_query, count_query));
                    }
                } else {
                    if (load_type == 2) {
                        cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages_v2 WHERE uid = %d AND mid < 0", dialogId));
                        if (cursor.next()) {
                            last_message_id = cursor.intValue(0);
                        }
                        cursor.dispose();
                        cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid), max(date) FROM messages_v2 WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid < 0", dialogId));
                        if (cursor.next()) {
                            min_unread_id = cursor.intValue(0);
                            max_unread_date = cursor.intValue(1);
                        }
                        cursor.dispose();
                        if (min_unread_id != 0) {
                            cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages_v2 WHERE uid = %d AND mid <= %d AND out = 0 AND read_state IN(0,2)", dialogId, min_unread_id));
                            if (cursor.next()) {
                                count_unread = cursor.intValue(0);
                            }
                            cursor.dispose();
                        }
                    }
                    if (count_query > count_unread || count_unread < num) {
                        count_query = Math.max(count_query, count_unread + 10);
                        if (count_unread < num) {
                            count_unread = 0;
                            min_unread_id = 0;
                            last_message_id = 0;
                        }
                    } else {
                        offset_query = count_unread - count_query;
                        count_query += 10;
                    }
                    cursor = database.queryFinalized(String.format(Locale.US, "" + messageSelect + " WHERE m.uid = %d ORDER BY m.mid ASC LIMIT %d,%d", dialogId, offset_query, count_query));
                }
            }
            int minId = Integer.MAX_VALUE;
            int maxId = Integer.MIN_VALUE;
            ArrayList<Long> messageIdsToFix = null;
            if (cursor != null) {
                while (cursor.next()) {
                    messagesCount++;
                    if (!processMessages) {
                        continue;
                    }
                    NativeByteBuffer data = cursor.byteBufferValue(1);
                    if (data != null) {
                        TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                        message.send_state = cursor.intValue(2);
                        long fullMid = cursor.longValue(3);
                        message.id = (int) fullMid;
                        if ((fullMid & 0xffffffff00000000L) == 0xffffffff00000000L && message.id > 0) {
                            if (messageIdsToFix == null) {
                                messageIdsToFix = new ArrayList<>();
                            }
                            messageIdsToFix.add(fullMid);
                        }
                        if (message.id > 0 && message.send_state != 0 && message.send_state != 3) {
                            message.send_state = 0;
                        }
                        if (dialogId == currentUserId) {
                            message.out = true;
                        }
                        message.readAttachPath(data, currentUserId);
                        data.reuse();
                        MessageObject.setUnreadFlags(message, cursor.intValue(0));
                        if (message.id > 0) {
                            minId = Math.min(message.id, minId);
                            maxId = Math.max(message.id, maxId);
                        }
                        message.date = cursor.intValue(4);
                        message.dialog_id = dialogId;
                        if ((message.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
                            message.views = cursor.intValue(7);
                            message.forwards = cursor.intValue(11);
                        }
                        NativeByteBuffer repliesData = cursor.byteBufferValue(12);
                        if (repliesData != null) {
                            TLRPC.MessageReplies replies = TLRPC.MessageReplies.TLdeserialize(repliesData, repliesData.readInt32(false), false);
                            if (replies != null) {
                                message.replies = replies;
                            }
                            repliesData.reuse();
                        }
                        if (!DialogObject.isEncryptedDialog(dialogId) && message.ttl == 0) {
                            message.ttl = cursor.intValue(8);
                        }
                        if (cursor.intValue(9) != 0) {
                            message.mentioned = true;
                        }
                        int flags = cursor.intValue(10);
                        if ((flags & 1) != 0) {
                            message.stickerVerified = 0;
                        } else if ((flags & 2) != 0) {
                            message.stickerVerified = 2;
                        }
                        res.messages.add(message);
                        addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
                        if (message.reply_to != null && (message.reply_to.reply_to_msg_id != 0 || message.reply_to.reply_to_random_id != 0)) {
                            if (!cursor.isNull(6)) {
                                data = cursor.byteBufferValue(6);
                                if (data != null) {
                                    message.replyMessage = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                                    message.replyMessage.readAttachPath(data, currentUserId);
                                    data.reuse();
                                    if (message.replyMessage != null) {
                                        addUsersAndChatsFromMessage(message.replyMessage, usersToLoad, chatsToLoad);
                                    }
                                }
                            }
                            if (message.replyMessage == null) {
                                if (message.reply_to.reply_to_msg_id != 0) {
                                    addReplyMessages(message, replyMessageOwners, dialogReplyMessagesIds);
                                } else {
                                    ArrayList<TLRPC.Message> messages = replyMessageRandomOwners.get(message.reply_to.reply_to_random_id);
                                    if (messages == null) {
                                        messages = new ArrayList<>();
                                        replyMessageRandomOwners.put(message.reply_to.reply_to_random_id, messages);
                                    }
                                    if (!replyMessageRandomIds.contains(message.reply_to.reply_to_random_id)) {
                                        replyMessageRandomIds.add(message.reply_to.reply_to_random_id);
                                    }
                                    messages.add(message);
                                }
                            }
                        }
                        if (DialogObject.isEncryptedDialog(dialogId) && !cursor.isNull(5)) {
                            message.random_id = cursor.longValue(5);
                        }
                        if (MessageObject.isSecretMedia(message)) {
                            try {
                                SQLiteCursor cursor2 = database.queryFinalized(String.format(Locale.US, "SELECT date FROM enc_tasks_v4 WHERE mid = %d AND uid = %d AND media = 1", message.id, MessageObject.getDialogId(message)));
                                if (cursor2.next()) {
                                    message.destroyTime = cursor2.intValue(0);
                                }
                                cursor2.dispose();
                            } catch (Exception e) {
                                FileLog.e(e);
                            }
                        }
                    }
                }
                cursor.dispose();
            }
            Collections.sort(res.messages, (lhs, rhs) -> {
                if (lhs.id > 0 && rhs.id > 0) {
                    if (lhs.id > rhs.id) {
                        return -1;
                    } else if (lhs.id < rhs.id) {
                        return 1;
                    }
                } else if (lhs.id < 0 && rhs.id < 0) {
                    if (lhs.id < rhs.id) {
                        return -1;
                    } else if (lhs.id > rhs.id) {
                        return 1;
                    }
                } else {
                    if (lhs.date > rhs.date) {
                        return -1;
                    } else if (lhs.date < rhs.date) {
                        return 1;
                    }
                }
                return 0;
            });
            if (!DialogObject.isEncryptedDialog(dialogId)) {
                if ((load_type == 3 || load_type == 4 || load_type == 2 && queryFromServer && !unreadCountIsLocal) && !res.messages.isEmpty()) {
                    if (!(minId <= max_id_query && maxId >= max_id_query)) {
                        usersToLoad.clear();
                        chatsToLoad.clear();
                        res.messages.clear();
                    }
                }
                if ((load_type == 4 || load_type == 3) && res.messages.size() == 1) {
                    res.messages.clear();
                }
            }
            if (mentions_unread != 0) {
                cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM messages_v2 WHERE uid = %d AND mention = 1 AND read_state IN(0, 1)", dialogId));
                if (cursor.next()) {
                    if (mentions_unread != cursor.intValue(0)) {
                        mentions_unread *= -1;
                    }
                } else {
                    mentions_unread *= -1;
                }
                cursor.dispose();
            }
        }
        if (!replyMessageRandomOwners.isEmpty()) {
            cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, m.date, r.random_id FROM randoms_v2 as r INNER JOIN messages_v2 as m ON r.mid = m.mid AND r.uid = m.uid WHERE r.random_id IN(%s)", TextUtils.join(",", replyMessageRandomIds)));
            while (cursor.next()) {
                NativeByteBuffer data = cursor.byteBufferValue(0);
                if (data != null) {
                    TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                    message.readAttachPath(data, currentUserId);
                    data.reuse();
                    message.id = cursor.intValue(1);
                    message.date = cursor.intValue(2);
                    message.dialog_id = dialogId;
                    addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
                    long value = cursor.longValue(3);
                    ArrayList<TLRPC.Message> arrayList = replyMessageRandomOwners.get(value);
                    replyMessageRandomOwners.remove(value);
                    if (arrayList != null) {
                        for (int a = 0; a < arrayList.size(); a++) {
                            TLRPC.Message object = arrayList.get(a);
                            object.replyMessage = message;
                            if (object.reply_to != null) {
                                object.reply_to.reply_to_msg_id = message.id;
                            }
                        }
                    }
                }
            }
            cursor.dispose();
            for (int b = 0, N = replyMessageRandomOwners.size(); b < N; b++) {
                ArrayList<TLRPC.Message> arrayList = replyMessageRandomOwners.valueAt(b);
                for (int a = 0, N2 = arrayList.size(); a < N2; a++) {
                    TLRPC.Message message = arrayList.get(a);
                    if (message.reply_to != null) {
                        message.reply_to.reply_to_random_id = 0;
                    }
                }
            }
        } else {
            loadReplyMessages(replyMessageOwners, dialogReplyMessagesIds, usersToLoad, chatsToLoad);
        }
        if (!usersToLoad.isEmpty()) {
            getUsersInternal(TextUtils.join(",", usersToLoad), res.users);
        }
        if (!chatsToLoad.isEmpty()) {
            getChatsInternal(TextUtils.join(",", chatsToLoad), res.chats);
        }
    } catch (Exception e) {
        res.messages.clear();
        res.chats.clear();
        res.users.clear();
        FileLog.e(e);
    }
    if (BuildVars.LOGS_ENABLED) {
        FileLog.d("messages load time = " + (SystemClock.elapsedRealtime() - startLoadTime) + " for dialog = " + dialogId);
    }
    int countQueryFinal = count_query;
    int maxIdOverrideFinal = max_id_override;
    int minUnreadIdFinal = min_unread_id;
    int lastMessageIdFinal = last_message_id;
    boolean isEndFinal = isEnd;
    boolean queryFromServerFinal = queryFromServer;
    int mentionsUnreadFinal = mentions_unread;
    int countUnreadFinal = count_unread;
    int maxUnreadDateFinal = max_unread_date;
    /*if (!scheduled && mergeDialogId != 0 && res.messages.size() < count && isEnd && load_type == 2) { TODO fix if end not reached
            Runnable runnable = getMessagesInternal(mergeDialogId, 0, count, Integer.MAX_VALUE, 0, 0, classGuid, 0, false, false, loadIndex);
            return () -> {
                getMessagesController().processLoadedMessages(res, dialogId, mergeDialogId, countQueryFinal, maxIdOverrideFinal, offset_date, true, classGuid, minUnreadIdFinal, lastMessageIdFinal, countUnreadFinal, maxUnreadDateFinal, load_type, isChannel, isEndFinal, scheduled, -loadIndex, queryFromServerFinal, mentionsUnreadFinal);
                runnable.run();
            };
        } else {*/
    int finalMessagesCount = scheduled ? res.messages.size() : messagesCount;
    return () -> getMessagesController().processLoadedMessages(res, finalMessagesCount, dialogId, mergeDialogId, countQueryFinal, maxIdOverrideFinal, offset_date, true, classGuid, minUnreadIdFinal, lastMessageIdFinal, countUnreadFinal, maxUnreadDateFinal, load_type, isEndFinal, scheduled ? 1 : 0, replyMessageId, loadIndex, queryFromServerFinal, mentionsUnreadFinal, processMessages);
// }
}
Also used : LongSparseArray(androidx.collection.LongSparseArray) ArrayList(java.util.ArrayList) NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) TLRPC(org.telegram.tgnet.TLRPC) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException) SQLitePreparedStatement(org.telegram.SQLite.SQLitePreparedStatement) LongSparseArray(androidx.collection.LongSparseArray) SparseArray(android.util.SparseArray) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Aggregations

NativeByteBuffer (org.telegram.tgnet.NativeByteBuffer)108 TLRPC (org.telegram.tgnet.TLRPC)92 SQLiteException (org.telegram.SQLite.SQLiteException)91 SQLiteCursor (org.telegram.SQLite.SQLiteCursor)68 SQLitePreparedStatement (org.telegram.SQLite.SQLitePreparedStatement)54 ArrayList (java.util.ArrayList)47 Paint (android.graphics.Paint)19 LongSparseArray (androidx.collection.LongSparseArray)18 SparseArray (android.util.SparseArray)12 File (java.io.File)11 AtomicLong (java.util.concurrent.atomic.AtomicLong)11 TLObject (org.telegram.tgnet.TLObject)11 CountDownLatch (java.util.concurrent.CountDownLatch)8 SpannableStringBuilder (android.text.SpannableStringBuilder)7 SharedPreferences (android.content.SharedPreferences)6 Pair (android.util.Pair)6 HashMap (java.util.HashMap)6 SparseIntArray (android.util.SparseIntArray)5 SQLiteDatabase (org.telegram.SQLite.SQLiteDatabase)5 LongSparseIntArray (org.telegram.messenger.support.LongSparseIntArray)5