Continue upload file after app restart, bug fixes

This commit is contained in:
DrKLO 2014-08-27 01:26:25 +03:00
parent 8b73d93d1a
commit 2b15ac63f8
11 changed files with 257 additions and 207 deletions

View File

@ -80,7 +80,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 19 targetSdkVersion 19
versionCode 310 versionCode 311
versionName "1.8.0" versionName "1.8.0"
} }
} }

View File

@ -53,13 +53,6 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
/*SharedPreferences preferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
boolean globalEnabled = preferences.getBoolean("EnableAll", true);
if (!globalEnabled) {
FileLog.d("tmessages", "GCM disabled");
return;
}*/
ConnectionsManager.getInstance().resumeNetworkMaybe(); ConnectionsManager.getInstance().resumeNetworkMaybe();
} }
}); });

View File

@ -628,7 +628,7 @@ public class ImageLoader {
} }
} }
public BitmapDrawable getImageFromMemory(TLRPC.FileLocation url, String httpUrl, String filter) { public BitmapDrawable getImageFromMemory(TLRPC.FileLocation url, String httpUrl, String filter, ImageReceiver imageReceiver) {
if (url == null && httpUrl == null) { if (url == null && httpUrl == null) {
return null; return null;
} }
@ -641,6 +641,15 @@ public class ImageLoader {
if (filter != null) { if (filter != null) {
key += "@" + filter; key += "@" + filter;
} }
if (imageReceiver != null) {
Integer TAG = imageReceiver.getTag();
if (TAG != null) {
CacheImage alreadyLoadingImage = imageLoadingByTag.get(TAG);
if (alreadyLoadingImage != null) {
alreadyLoadingImage.removeImageView(imageReceiver);
}
}
}
return memCache.get(key); return memCache.get(key);
} }
@ -668,8 +677,8 @@ public class ImageLoader {
String url; String url;
String key; String key;
if (httpUrl != null) { if (httpUrl != null) {
url = httpUrl;
key = Utilities.MD5(httpUrl); key = Utilities.MD5(httpUrl);
url = key + ".jpg";
} else { } else {
key = fileLocation.volume_id + "_" + fileLocation.local_id; key = fileLocation.volume_id + "_" + fileLocation.local_id;
url = key + ".jpg"; url = key + ".jpg";

View File

@ -88,14 +88,14 @@ public class ImageReceiver {
if (currentImage != null) { if (currentImage != null) {
return; return;
} else { } else {
img = ImageLoader.getInstance().getImageFromMemory(fileLocation, httpUrl, filter); img = ImageLoader.getInstance().getImageFromMemory(fileLocation, httpUrl, filter, this);
} }
} else { } else {
img = ImageLoader.getInstance().getImageFromMemory(fileLocation, httpUrl, filter); img = ImageLoader.getInstance().getImageFromMemory(fileLocation, httpUrl, filter, this);
recycleBitmap(img); recycleBitmap(img);
} }
} }
img = ImageLoader.getInstance().getImageFromMemory(fileLocation, httpUrl, filter); img = ImageLoader.getInstance().getImageFromMemory(fileLocation, httpUrl, filter, this);
currentPath = key; currentPath = key;
last_path = fileLocation; last_path = fileLocation;
last_httpUrl = httpUrl; last_httpUrl = httpUrl;

View File

@ -963,7 +963,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
NotificationsController.getInstance().processReadMessages(null, did, 0, Integer.MAX_VALUE, false); NotificationsController.getInstance().processReadMessages(null, did, 0, Integer.MAX_VALUE, false);
HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>(); HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>();
dialogsToUpdate.put(did, 0); dialogsToUpdate.put(did, 0);
NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate, true); NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate);
} }
}); });
} }
@ -1395,7 +1395,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
currentDialog.unread_count = entry.getValue(); currentDialog.unread_count = entry.getValue();
} }
} }
NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate, true); NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
} }
}); });
@ -1491,7 +1491,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
dialogsServerOnly.add(d); dialogsServerOnly.add(d);
} }
} }
NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate, true); NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
} }
}); });
@ -1711,12 +1711,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter
NotificationsController.getInstance().processReadMessages(null, dialog_id, 0, max_positive_id, false); NotificationsController.getInstance().processReadMessages(null, dialog_id, 0, max_positive_id, false);
HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>(); HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>();
dialogsToUpdate.put(dialog_id, 0); dialogsToUpdate.put(dialog_id, 0);
NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate, true); NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate);
} else { } else {
NotificationsController.getInstance().processReadMessages(null, dialog_id, 0, max_positive_id, true); NotificationsController.getInstance().processReadMessages(null, dialog_id, 0, max_positive_id, true);
HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>(); HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>();
dialogsToUpdate.put(dialog_id, 2000001); dialogsToUpdate.put(dialog_id, -1);
NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate, false); NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate);
} }
} }
}); });
@ -1784,7 +1784,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} }
HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>(); HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>();
dialogsToUpdate.put(dialog_id, 0); dialogsToUpdate.put(dialog_id, 0);
NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate, true); NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate);
} }
}); });
} }
@ -3417,27 +3417,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
return false; return false;
} }
public void dialogsUnreadCountIncr(final HashMap<Long, Integer> values) {
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
for (HashMap.Entry<Long, Integer> entry : values.entrySet()) {
TLRPC.TL_dialog dialog = dialogs_dict.get(entry.getKey());
if (dialog != null) {
int value = entry.getValue();
if (value < 0) {
dialog.unread_count = -value;
} else {
dialog.unread_count += value;
}
}
}
NotificationsController.getInstance().processDialogsUpdateRead(values, false);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
}
});
}
protected void updateInterfaceWithMessages(long uid, ArrayList<MessageObject> messages) { protected void updateInterfaceWithMessages(long uid, ArrayList<MessageObject> messages) {
updateInterfaceWithMessages(uid, messages, false); updateInterfaceWithMessages(uid, messages, false);
} }
@ -3718,7 +3697,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
NotificationsController.getInstance().processReadMessages(null, did, 0, Integer.MAX_VALUE, false); NotificationsController.getInstance().processReadMessages(null, did, 0, Integer.MAX_VALUE, false);
HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>(); HashMap<Long, Integer> dialogsToUpdate = new HashMap<Long, Integer>();
dialogsToUpdate.put(did, 0); dialogsToUpdate.put(did, 0);
NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate, true); NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate);
} }
}); });
} }

View File

@ -133,42 +133,51 @@ public class MessagesStorage {
database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages ON messages(mid, send_state, date) WHERE mid < 0 AND send_state = 1;").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages ON messages(mid, send_state, date) WHERE mid < 0 AND send_state = 1;").stepThis().dispose();
database.executeFast("PRAGMA user_version = 3").stepThis().dispose(); database.executeFast("PRAGMA user_version = 3").stepThis().dispose();
} else { } else {
int version = database.executeInt("PRAGMA user_version"); try {
if (version < 3) { SQLiteCursor cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1");
SQLiteCursor cursor = database.queryFinalized("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='params'");
boolean create = false;
if (cursor.next()) { if (cursor.next()) {
int count = cursor.intValue(0); lastSeqValue = cursor.intValue(0);
if (count == 0) { lastPtsValue = cursor.intValue(1);
create = true; lastDateValue = cursor.intValue(2);
} lastQtsValue = cursor.intValue(3);
} else { lastSecretVersion = cursor.intValue(4);
create = true; secretG = cursor.intValue(5);
} if (cursor.isNull(6)) {
cursor.dispose(); secretPBytes = null;
if (create) { } else {
database.executeFast("CREATE TABLE params(id INTEGER PRIMARY KEY, seq INTEGER, pts INTEGER, date INTEGER, qts INTEGER, lsv INTEGER, sg INTEGER, pbytes BLOB)").stepThis().dispose(); secretPBytes = cursor.byteArrayValue(6);
database.executeFast("INSERT INTO params VALUES(1, 0, 0, 0, 0, 0, 0, NULL)").stepThis().dispose(); if (secretPBytes != null && secretPBytes.length == 1) {
} else {
cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1");
if (cursor.next()) {
lastSeqValue = cursor.intValue(0);
lastPtsValue = cursor.intValue(1);
lastDateValue = cursor.intValue(2);
lastQtsValue = cursor.intValue(3);
lastSecretVersion = cursor.intValue(4);
secretG = cursor.intValue(5);
if (cursor.isNull(6)) {
secretPBytes = null; secretPBytes = null;
} else {
secretPBytes = cursor.byteArrayValue(6);
if (secretPBytes != null && secretPBytes.length == 1) {
secretPBytes = null;
}
} }
} }
cursor.dispose();
} }
cursor.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
try {
database.executeFast("CREATE TABLE IF NOT EXISTS params(id INTEGER PRIMARY KEY, seq INTEGER, pts INTEGER, date INTEGER, qts INTEGER, lsv INTEGER, sg INTEGER, pbytes BLOB)").stepThis().dispose();
database.executeFast("INSERT INTO params VALUES(1, 0, 0, 0, 0, 0, 0, NULL)").stepThis().dispose();
} catch (Exception e2) {
FileLog.e("tmessages", e2);
}
}
int version = database.executeInt("PRAGMA user_version");
if (version < 3) {
updateDbToVersion3();
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
loadUnreadMessages(false);
}
public void updateDbToVersion3() {
storageQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
database.executeFast("CREATE TABLE IF NOT EXISTS user_photos(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose(); database.executeFast("CREATE TABLE IF NOT EXISTS user_photos(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_media ON media(mid);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_media ON media(mid);").stepThis().dispose();
@ -200,7 +209,12 @@ public class MessagesStorage {
database.executeFast("UPDATE messages SET send_state = 2 WHERE mid < 0 AND send_state = 1").stepThis().dispose(); database.executeFast("UPDATE messages SET send_state = 2 WHERE mid < 0 AND send_state = 1").stepThis().dispose();
database.executeFast("ALTER TABLE dialogs ADD COLUMN flags INTEGER NOT NULL default 0;").stepThis().dispose(); try {
database.executeFast("ALTER TABLE dialogs ADD COLUMN flags INTEGER NOT NULL default 0;").stepThis().dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
database.executeFast("CREATE INDEX IF NOT EXISTS unread_count_flags_idx_dialogs ON dialogs(unread_count, flags);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS unread_count_flags_idx_dialogs ON dialogs(unread_count, flags);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 3").stepThis().dispose(); database.executeFast("PRAGMA user_version = 3").stepThis().dispose();
@ -230,31 +244,11 @@ public class MessagesStorage {
} }
} }
}); });
} else { } catch (Exception e) {
SQLiteCursor cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1"); FileLog.e("tmessages", e);
if (cursor.next()) {
lastSeqValue = cursor.intValue(0);
lastPtsValue = cursor.intValue(1);
lastDateValue = cursor.intValue(2);
lastQtsValue = cursor.intValue(3);
lastSecretVersion = cursor.intValue(4);
secretG = cursor.intValue(5);
if (cursor.isNull(6)) {
secretPBytes = null;
} else {
secretPBytes = cursor.byteArrayValue(6);
if (secretPBytes != null && secretPBytes.length == 1) {
secretPBytes = null;
}
}
}
cursor.dispose();
} }
} }
} catch (Exception e) { });
FileLog.e("tmessages", e);
}
loadUnreadMessages(false);
} }
public void cleanUp(final boolean isLogin) { public void cleanUp(final boolean isLogin) {
@ -2416,36 +2410,24 @@ public class MessagesStorage {
SQLitePreparedStatement state4 = database.executeFast("REPLACE INTO download_queue VALUES(?, ?, ?, ?)"); SQLitePreparedStatement state4 = database.executeFast("REPLACE INTO download_queue VALUES(?, ?, ?, ?)");
for (TLRPC.Message message : messages) { for (TLRPC.Message message : messages) {
long dialog_id = 0; long dialog_id = message.dialog_id;
if (dialog_id == 0) {
if (message.to_id.chat_id != 0) {
dialog_id = -message.to_id.chat_id;
} else if (message.to_id.user_id != 0) {
dialog_id = message.to_id.user_id;
}
}
if (message.unread && !message.out) { if (message.unread && !message.out) {
if (messageIds.length() > 0) { if (messageIds.length() > 0) {
messageIds += ","; messageIds += ",";
} }
messageIds += message.id; messageIds += message.id;
dialog_id = message.dialog_id;
if (dialog_id == 0) {
if (message.to_id.chat_id != 0) {
dialog_id = -message.to_id.chat_id;
} else if (message.to_id.user_id != 0) {
dialog_id = message.to_id.user_id;
}
}
messagesIdsMap.put(message.id, dialog_id); messagesIdsMap.put(message.id, dialog_id);
} }
if (message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaPhoto) { if (message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaPhoto) {
if (dialog_id == 0) {
dialog_id = message.dialog_id;
if (dialog_id == 0) {
if (message.to_id.chat_id != 0) {
dialog_id = -message.to_id.chat_id;
} else if (message.to_id.user_id != 0) {
dialog_id = message.to_id.user_id;
}
}
}
if (messageMediaIds.length() > 0) { if (messageMediaIds.length() > 0) {
messageMediaIds += ","; messageMediaIds += ",";
} }
@ -2612,7 +2594,7 @@ public class MessagesStorage {
if (unread_count == null) { if (unread_count == null) {
unread_count = 0; unread_count = 0;
} else { } else {
messagesCounts.put(key, -(unread_count + old_unread_count)); messagesCounts.put(key, unread_count + old_unread_count);
} }
int messageId = value.id; int messageId = value.id;
if (value.local_id != 0) { if (value.local_id != 0) {
@ -2633,7 +2615,7 @@ public class MessagesStorage {
if (withTransaction) { if (withTransaction) {
database.commitTransaction(); database.commitTransaction();
} }
MessagesController.getInstance().dialogsUnreadCountIncr(messagesCounts); MessagesController.getInstance().processDialogsUpdateRead(messagesCounts);
if (!mediaCounts.isEmpty()) { if (!mediaCounts.isEmpty()) {
state = database.executeFast("REPLACE INTO media_counts VALUES(?, ?)"); state = database.executeFast("REPLACE INTO media_counts VALUES(?, ?)");
@ -2687,6 +2669,19 @@ public class MessagesStorage {
} }
} }
public void markMessageAsSendError(final int mid) {
storageQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
database.executeFast("UPDATE messages SET send_state = 2 WHERE mid = " + mid).stepThis().dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
private Integer updateMessageStateAndIdInternal(long random_id, Integer _oldId, int newId, int date) { private Integer updateMessageStateAndIdInternal(long random_id, Integer _oldId, int newId, int date) {
if (_oldId != null && _oldId == newId && date != 0) { if (_oldId != null && _oldId == newId && date != 0) {
SQLitePreparedStatement state = null; SQLitePreparedStatement state = null;

View File

@ -419,7 +419,7 @@ public class NotificationsController {
} }
if (photoPath != null) { if (photoPath != null) {
BitmapDrawable img = ImageLoader.getInstance().getImageFromMemory(photoPath, null, "50_50"); BitmapDrawable img = ImageLoader.getInstance().getImageFromMemory(photoPath, null, "50_50", null);
if (img != null) { if (img != null) {
mBuilder.setLargeIcon(img.getBitmap()); mBuilder.setLargeIcon(img.getBitmap());
} }
@ -596,50 +596,40 @@ public class NotificationsController {
} }
} }
public void processDialogsUpdateRead(final HashMap<Long, Integer> dialogsToUpdate, boolean replace) { public void processDialogsUpdateRead(final HashMap<Long, Integer> dialogsToUpdate) {
int old_unread_count = total_unread_count; int old_unread_count = total_unread_count;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
for (HashMap.Entry<Long, Integer> entry : dialogsToUpdate.entrySet()) { for (HashMap.Entry<Long, Integer> entry : dialogsToUpdate.entrySet()) {
long dialog_id = entry.getKey(); long dialog_id = entry.getKey();
int notify_override = preferences.getInt("notify2_" + dialog_id, 0); int notify_override = preferences.getInt("notify2_" + dialog_id, 0);
boolean isChat = (int)dialog_id < 0; boolean canAddValue = !(notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || ((int)dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0);
Integer currentCount = pushDialogs.get(dialog_id);
boolean canAddValue = !(notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || isChat && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0);
Integer currentCount = pushDialogs.get(dialog_id);
Integer newCount = entry.getValue(); Integer newCount = entry.getValue();
if (replace || newCount < 0) { if (newCount < 0) {
if (newCount < 0) { if (currentCount == null) {
newCount *= -1; continue;
} }
if (currentCount != null) { newCount = currentCount + newCount;
total_unread_count -= currentCount; }
} if (currentCount != null) {
if (newCount == 0) { total_unread_count -= currentCount;
pushDialogs.remove(dialog_id); }
for (int a = 0; a < pushMessages.size(); a++) { if (newCount == 0) {
MessageObject messageObject = pushMessages.get(a); pushDialogs.remove(dialog_id);
if (messageObject.getDialogId() == dialog_id) { for (int a = 0; a < pushMessages.size(); a++) {
pushMessages.remove(a); MessageObject messageObject = pushMessages.get(a);
a--; if (messageObject.getDialogId() == dialog_id) {
pushMessagesDict.remove(messageObject.messageOwner.id); pushMessages.remove(a);
popupMessages.remove(messageObject); a--;
} pushMessagesDict.remove(messageObject.messageOwner.id);
popupMessages.remove(messageObject);
} }
} else if (canAddValue) {
total_unread_count += newCount;
pushDialogs.put(dialog_id, newCount);
} }
} else if (canAddValue) { } else if (canAddValue) {
if (newCount > 2000000) {
newCount = 2000000 - newCount;
}
if (currentCount == null) {
currentCount = 0;
}
currentCount += newCount;
total_unread_count += newCount; total_unread_count += newCount;
pushDialogs.put(dialog_id, currentCount); pushDialogs.put(dialog_id, newCount);
} }
} }
if (old_unread_count != total_unread_count) { if (old_unread_count != total_unread_count) {

View File

@ -147,6 +147,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
for (int a = 0; a < arr.size(); a++) { for (int a = 0; a < arr.size(); a++) {
DelayedMessage obj = arr.get(a); DelayedMessage obj = arr.get(a);
if (enc && obj.sendEncryptedRequest != null || !enc && obj.sendRequest != null) { if (enc && obj.sendEncryptedRequest != null || !enc && obj.sendRequest != null) {
MessagesStorage.getInstance().markMessageAsSendError(obj.obj.messageOwner.id);
obj.obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; obj.obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
arr.remove(a); arr.remove(a);
a--; a--;
@ -392,6 +393,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
newMsg.from_id = UserConfig.getClientUserId(); newMsg.from_id = UserConfig.getClientUserId();
newMsg.out = true; newMsg.out = true;
newMsg.date = ConnectionsManager.getInstance().getCurrentTime(); newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
UserConfig.saveConfig(false);
} }
if (newMsg.random_id == 0) { if (newMsg.random_id == 0) {
newMsg.random_id = getNextRandomId(); newMsg.random_id = getNextRandomId();
@ -453,11 +455,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
newMsg.ttl = encryptedChat.ttl; newMsg.ttl = encryptedChat.ttl;
} }
UserConfig.saveConfig(false);
final MessageObject newMsgObj = new MessageObject(newMsg, null, 2); MessageObject newMsgObj = new MessageObject(newMsg, null, 2);
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
final ArrayList<MessageObject> objArr = new ArrayList<MessageObject>(); ArrayList<MessageObject> objArr = new ArrayList<MessageObject>();
objArr.add(newMsgObj); objArr.add(newMsgObj);
ArrayList<TLRPC.Message> arr = new ArrayList<TLRPC.Message>(); ArrayList<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
arr.add(newMsg); arr.add(newMsg);
@ -553,7 +555,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
delayedMessage.obj = newMsgObj; delayedMessage.obj = newMsgObj;
delayedMessage.documentLocation = document; delayedMessage.documentLocation = document;
delayedMessage.location = document.thumb.location; delayedMessage.location = document.thumb.location;
performSendDelayedMessage(delayedMessage);
} else { } else {
TLRPC.TL_inputMediaDocument media = new TLRPC.TL_inputMediaDocument(); TLRPC.TL_inputMediaDocument media = new TLRPC.TL_inputMediaDocument();
media.id = new TLRPC.TL_inputDocument(); media.id = new TLRPC.TL_inputDocument();
@ -889,6 +890,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} }
}); });
} else { } else {
MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.messageOwner.id);
AndroidUtilities.RunOnUIThread(new Runnable() { AndroidUtilities.RunOnUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -994,6 +996,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} }
}); });
} else { } else {
MessagesStorage.getInstance().markMessageAsSendError(newMsgObj.messageOwner.id);
AndroidUtilities.RunOnUIThread(new Runnable() { AndroidUtilities.RunOnUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {

View File

@ -988,7 +988,6 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
} }
} catch(Exception e) { } catch(Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
return true;
} }
return false; return false;
} }

View File

@ -37,6 +37,7 @@ public class FileUploadOperation {
private byte[] key; private byte[] key;
private byte[] iv; private byte[] iv;
private byte[] ivChange; private byte[] ivChange;
private boolean isEncrypted = false;
private int fingerprint = 0; private int fingerprint = 0;
private boolean isBigFile = false; private boolean isBigFile = false;
private String fileKey; private String fileKey;
@ -51,32 +52,7 @@ public class FileUploadOperation {
public FileUploadOperation(String location, boolean encrypted) { public FileUploadOperation(String location, boolean encrypted) {
uploadingFilePath = location; uploadingFilePath = location;
if (encrypted) { isEncrypted = encrypted;
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);
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("tmessages", e);
}
}
currentFileId = Utilities.random.nextLong();
try {
mdEnc = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
FileLog.e("tmessages", e);
}
} }
public void start() { public void start() {
@ -101,7 +77,13 @@ public class FileUploadOperation {
private void cleanup() { private void cleanup() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE);
preferences.edit().remove(fileKey + "_time").remove(fileKey + "_size").remove(fileKey + "_uploaded").commit(); preferences.edit().remove(fileKey + "_time").
remove(fileKey + "_size").
remove(fileKey + "_uploaded").
remove(fileKey + "_id").
remove(fileKey + "_iv").
remove(fileKey + "_key").
remove(fileKey + "_ivc").commit();
} }
private void startUploadRequest() { private void startUploadRequest() {
@ -118,6 +100,12 @@ public class FileUploadOperation {
totalFileSize = cacheFile.length(); totalFileSize = cacheFile.length();
if (totalFileSize > 10 * 1024 * 1024) { if (totalFileSize > 10 * 1024 * 1024) {
isBigFile = true; isBigFile = true;
} else {
try {
mdEnc = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
FileLog.e("tmessages", e);
}
} }
uploadChunkSize = (int) Math.max(32, Math.ceil(totalFileSize / (1024.0f * 3000))); uploadChunkSize = (int) Math.max(32, Math.ceil(totalFileSize / (1024.0f * 3000)));
@ -133,28 +121,72 @@ public class FileUploadOperation {
totalPartsCount = (int) Math.ceil((float) totalFileSize / (float) uploadChunkSize); totalPartsCount = (int) Math.ceil((float) totalFileSize / (float) uploadChunkSize);
readBuffer = new byte[uploadChunkSize]; readBuffer = new byte[uploadChunkSize];
fileKey = Utilities.MD5(uploadingFilePath); fileKey = Utilities.MD5(uploadingFilePath + (isEncrypted ? "enc" : ""));
/*SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE); TODO SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE);
long fileSize = preferences.getLong(fileKey + "_size", 0); long fileSize = preferences.getLong(fileKey + "_size", 0);
int currentTime = (int)(System.currentTimeMillis() / 1000); int currentTime = (int)(System.currentTimeMillis() / 1000);
boolean rewrite = false; boolean rewrite = false;
if (fileSize == totalFileSize) { if (fileSize == totalFileSize) {
currentFileId = preferences.getLong(fileKey + "_id", 0);
int date = preferences.getInt(fileKey + "_time", 0); int date = preferences.getInt(fileKey + "_time", 0);
long uploadedSize = preferences.getLong(fileKey + "_uploaded", 0); long uploadedSize = preferences.getLong(fileKey + "_uploaded", 0);
if (date != 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);
ivChange = new byte[32];
System.arraycopy(iv, 0, ivChange, 0, 32);
} else {
rewrite = true;
}
}
if (!rewrite && date != 0) {
if (isBigFile && date < currentTime - 60 * 60 * 24) { if (isBigFile && date < currentTime - 60 * 60 * 24) {
date = 0; date = 0;
} else if (!isBigFile && date < currentTime - 60 * 60 * 1.5f) { } else if (!isBigFile && date < currentTime - 60 * 60 * 1.5f) {
date = 0; date = 0;
} }
if (date != 0) { if (date != 0) {
if (isBigFile) {
uploadedSize = uploadedSize / (1024 * 1024) * (1024 * 1024);
}
if (uploadedSize > 0) { if (uploadedSize > 0) {
currentUploaded = uploadedSize; currentUploaded = uploadedSize;
stream.skip(uploadedSize);
currentPartNum = (int) (uploadedSize / uploadChunkSize); currentPartNum = (int) (uploadedSize / uploadChunkSize);
if (!isBigFile) {
for (int b = 0; b < currentUploaded / uploadChunkSize; b++) {
int read = stream.read(readBuffer);
int toAdd = 0;
if (isEncrypted && read % 16 != 0) {
toAdd += 16 - read % 16;
}
ByteBufferDesc sendBuffer = BuffersStorage.getInstance().getFreeBuffer(read + toAdd);
if (read != uploadChunkSize || totalPartsCount == currentPartNum + 1) {
isLastPart = true;
}
sendBuffer.writeRaw(readBuffer, 0, read);
if (isEncrypted) {
for (int a = 0; a < toAdd; a++) {
sendBuffer.writeByte(0);
}
Utilities.aesIgeEncryption(sendBuffer.buffer, key, ivChange, true, true, 0, read + toAdd);
}
sendBuffer.rewind();
mdEnc.update(sendBuffer.buffer);
BuffersStorage.getInstance().reuseFreeBuffer(sendBuffer);
}
} else {
stream.skip(uploadedSize);
if (isEncrypted) {
String ivcString = preferences.getString(fileKey + "_ivc", null);
if (ivcString != null) {
ivChange = Utilities.hexToBytes(ivcString);
} else {
rewrite = true;
currentUploaded = 0;
currentPartNum = 0;
}
}
}
} else { } else {
rewrite = true; rewrite = true;
} }
@ -166,34 +198,75 @@ public class FileUploadOperation {
rewrite = true; rewrite = true;
} }
if (rewrite) { if (rewrite) {
preferences.edit().putInt(fileKey + "_time", currentTime).putLong(fileKey + "_size", totalFileSize).commit(); 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();
SharedPreferences.Editor editor = preferences.edit();
editor.putInt(fileKey + "_time", currentTime);
editor.putLong(fileKey + "_size", totalFileSize);
editor.putLong(fileKey + "_id", currentFileId);
editor.remove(fileKey + "_uploaded");
if (isEncrypted) {
editor.putString(fileKey + "_iv", Utilities.bytesToHex(iv));
editor.putString(fileKey + "_ivc", Utilities.bytesToHex(ivChange));
editor.putString(fileKey + "_key", Utilities.bytesToHex(key));
}
editor.commit();
editor.putString(fileKey + "_key", Utilities.bytesToHex(key));
}
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("tmessages", e);
}
}
} else { } else {
/*if (saveInfoTimes >= 4) { if (saveInfoTimes >= 4) {
saveInfoTimes = 0; saveInfoTimes = 0;
} }
if (saveInfoTimes == 0) { if (isBigFile && currentUploaded % (1024 * 1024) == 0 || !isBigFile && saveInfoTimes == 0) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE);
preferences.edit().putLong(fileKey + "_uploaded", currentUploaded).commit(); SharedPreferences.Editor editor = preferences.edit();
editor.putLong(fileKey + "_uploaded", currentUploaded);
if (isEncrypted) {
editor.putString(fileKey + "_ivc", Utilities.bytesToHex(ivChange));
}
editor.commit();
} }
saveInfoTimes++;*/ saveInfoTimes++;
} }
int readed = stream.read(readBuffer); int read = stream.read(readBuffer);
int toAdd = 0; int toAdd = 0;
if (key != null && readed % 16 != 0) { if (isEncrypted && read % 16 != 0) {
toAdd += 16 - readed % 16; toAdd += 16 - read % 16;
} }
ByteBufferDesc sendBuffer = BuffersStorage.getInstance().getFreeBuffer(readed + toAdd); ByteBufferDesc sendBuffer = BuffersStorage.getInstance().getFreeBuffer(read + toAdd);
if (readed != uploadChunkSize || totalPartsCount == currentPartNum + 1) { if (read != uploadChunkSize || totalPartsCount == currentPartNum + 1) {
isLastPart = true; isLastPart = true;
} }
sendBuffer.writeRaw(readBuffer, 0, readed); sendBuffer.writeRaw(readBuffer, 0, read);
if (key != null) { if (isEncrypted) {
for (int a = 0; a < toAdd; a++) { for (int a = 0; a < toAdd; a++) {
sendBuffer.writeByte(0); sendBuffer.writeByte(0);
} }
Utilities.aesIgeEncryption(sendBuffer.buffer, key, ivChange, true, true, 0, readed + toAdd); Utilities.aesIgeEncryption(sendBuffer.buffer, key, ivChange, true, true, 0, read + toAdd);
} }
sendBuffer.rewind(); sendBuffer.rewind();
if (!isBigFile) { if (!isBigFile) {
@ -213,7 +286,7 @@ public class FileUploadOperation {
req.bytes = sendBuffer; req.bytes = sendBuffer;
finalRequest = req; finalRequest = req;
} }
currentUploaded += readed; currentUploaded += read;
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
delegate.didFailedUploadingFile(this); delegate.didFailedUploadingFile(this);

View File

@ -166,7 +166,7 @@ public class Utilities {
public static String bytesToHex(byte[] bytes) { public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2]; char[] hexChars = new char[bytes.length * 2];
int v; int v;
for ( int j = 0; j < bytes.length; j++ ) { for (int j = 0; j < bytes.length; j++) {
v = bytes[j] & 0xFF; v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4]; hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F]; hexChars[j * 2 + 1] = hexArray[v & 0x0F];
@ -174,6 +174,15 @@ public class Utilities {
return new String(hexChars); return new String(hexChars);
} }
public static byte[] hexToBytes(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16));
}
return data;
}
public static boolean isGoodPrime(byte[] prime, int g) { public static boolean isGoodPrime(byte[] prime, int g) {
if (!(g >= 2 && g <= 7)) { if (!(g >= 2 && g <= 7)) {
return false; return false;