Commit 458517e4 authored by DrKLO's avatar DrKLO

Improved files download speed

parent 70882c5d
...@@ -81,7 +81,7 @@ android { ...@@ -81,7 +81,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 19 targetSdkVersion 19
versionCode 262 versionCode 264
versionName "1.5.7" versionName "1.5.7"
} }
} }
...@@ -17,6 +17,7 @@ public class BuffersStorage { ...@@ -17,6 +17,7 @@ public class BuffersStorage {
private final ArrayList<ByteBufferDesc> freeBuffers4096; private final ArrayList<ByteBufferDesc> freeBuffers4096;
private final ArrayList<ByteBufferDesc> freeBuffers16384; private final ArrayList<ByteBufferDesc> freeBuffers16384;
private final ArrayList<ByteBufferDesc> freeBuffers32768; private final ArrayList<ByteBufferDesc> freeBuffers32768;
private final ArrayList<ByteBufferDesc> freeBuffersBig;
private static volatile BuffersStorage Instance = null; private static volatile BuffersStorage Instance = null;
public static BuffersStorage getInstance() { public static BuffersStorage getInstance() {
...@@ -38,6 +39,7 @@ public class BuffersStorage { ...@@ -38,6 +39,7 @@ public class BuffersStorage {
freeBuffers4096 = new ArrayList<ByteBufferDesc>(); freeBuffers4096 = new ArrayList<ByteBufferDesc>();
freeBuffers16384 = new ArrayList<ByteBufferDesc>(); freeBuffers16384 = new ArrayList<ByteBufferDesc>();
freeBuffers32768 = new ArrayList<ByteBufferDesc>(); freeBuffers32768 = new ArrayList<ByteBufferDesc>();
freeBuffersBig = new ArrayList<ByteBufferDesc>();
for (int a = 0; a < 5; a++) { for (int a = 0; a < 5; a++) {
freeBuffers128.add(new ByteBufferDesc(128)); freeBuffers128.add(new ByteBufferDesc(128));
...@@ -113,6 +115,17 @@ public class BuffersStorage { ...@@ -113,6 +115,17 @@ public class BuffersStorage {
buffer = new ByteBufferDesc(40000); buffer = new ByteBufferDesc(40000);
FileLog.e("tmessages", "create new 40000 buffer"); FileLog.e("tmessages", "create new 40000 buffer");
} }
} else if (size <= 280000) {
synchronized (freeBuffersBig) {
if (freeBuffersBig.size() > 0) {
buffer = freeBuffersBig.get(0);
freeBuffersBig.remove(0);
}
}
if (buffer == null) {
buffer = new ByteBufferDesc(280000);
FileLog.e("tmessages", "create new big buffer");
}
} else { } else {
buffer = new ByteBufferDesc(size); buffer = new ByteBufferDesc(size);
} }
...@@ -154,6 +167,12 @@ public class BuffersStorage { ...@@ -154,6 +167,12 @@ public class BuffersStorage {
freeBuffers32768.add(buffer); freeBuffers32768.add(buffer);
} }
} }
} else if (buffer.buffer.capacity() == 280000) {
synchronized (freeBuffersBig) {
if (freeBuffersBig.size() < 4) {
freeBuffersBig.add(buffer);
}
}
} }
} }
} }
...@@ -35,8 +35,8 @@ public class Datacenter { ...@@ -35,8 +35,8 @@ public class Datacenter {
private volatile int currentAddressNum = 0; private volatile int currentAddressNum = 0;
public TcpConnection connection; public TcpConnection connection;
public TcpConnection downloadConnection; private ArrayList<TcpConnection> downloadConnections = new ArrayList<TcpConnection>();
public TcpConnection uploadConnection; private TcpConnection uploadConnection;
public TcpConnection pushConnection; public TcpConnection pushConnection;
private ArrayList<ServerSalt> authServerSaltSet = new ArrayList<ServerSalt>(); private ArrayList<ServerSalt> authServerSaltSet = new ArrayList<ServerSalt>();
...@@ -319,4 +319,81 @@ public class Datacenter { ...@@ -319,4 +319,81 @@ public class Datacenter {
} }
return false; return false;
} }
public void suspendConnections() {
if (connection != null) {
connection.suspendConnection(true);
}
if (uploadConnection != null) {
uploadConnection.suspendConnection(true);
}
for (TcpConnection downloadConnection : downloadConnections) {
downloadConnection.suspendConnection(true);
}
}
public void getSessions(ArrayList<Long> sessions) {
if (connection != null) {
sessions.add(connection.getSissionId());
}
if (uploadConnection != null) {
sessions.add(uploadConnection.getSissionId());
}
for (TcpConnection downloadConnection : downloadConnections) {
sessions.add(downloadConnection.getSissionId());
}
}
public void recreateSessions() {
if (connection != null) {
connection.recreateSession();
}
if (uploadConnection != null) {
uploadConnection.recreateSession();
}
for (TcpConnection downloadConnection : downloadConnections) {
downloadConnection.recreateSession();
}
}
public TcpConnection getDownloadConnection(int num, TcpConnection.TcpConnectionDelegate delegate) {
if (num >= 0 && authKey != null) {
TcpConnection downloadConnection = null;
if (num < downloadConnections.size()) {
downloadConnection = downloadConnections.get(num);
} else {
downloadConnection = new TcpConnection(datacenterId);
downloadConnection.delegate = delegate;
downloadConnection.transportRequestClass = RPCRequest.RPCRequestClassDownloadMedia;
downloadConnections.add(downloadConnection);
}
downloadConnection.connect();
return downloadConnection;
}
return null;
}
public TcpConnection getUploadConnection(TcpConnection.TcpConnectionDelegate delegate) {
if (authKey != null) {
if (uploadConnection == null) {
uploadConnection = new TcpConnection(datacenterId);
uploadConnection.delegate = delegate;
uploadConnection.transportRequestClass = RPCRequest.RPCRequestClassUploadMedia;
}
uploadConnection.connect();
}
return uploadConnection;
}
public TcpConnection getGenericConnection(TcpConnection.TcpConnectionDelegate delegate) {
if (authKey != null) {
if (connection == null) {
connection = new TcpConnection(datacenterId);
connection.delegate = delegate;
connection.transportRequestClass = RPCRequest.RPCRequestClassGeneric;
}
connection.connect();
}
return connection;
}
} }
...@@ -25,7 +25,7 @@ import java.nio.channels.FileChannel; ...@@ -25,7 +25,7 @@ import java.nio.channels.FileChannel;
import java.util.Scanner; import java.util.Scanner;
public class FileLoadOperation { public class FileLoadOperation {
private int downloadChunkSize = 1024 * 32; private int downloadChunkSize = 1024 * 256;
public int datacenter_id; public int datacenter_id;
public TLRPC.InputFileLocation location; public TLRPC.InputFileLocation location;
...@@ -38,6 +38,13 @@ public class FileLoadOperation { ...@@ -38,6 +38,13 @@ public class FileLoadOperation {
private byte[] key; private byte[] key;
private byte[] iv; private byte[] iv;
private long requestToken = 0; private long requestToken = 0;
private long requestToken2 = 0;
private int requestProgress = 0;
private int requestProgress2 = 0;
private int nextDownloadOffset = 0;
private TLRPC.TL_upload_file delayedRes = null;
private int delayedResOffset = 0;
private int delayedResTokenNum = 0;
private File cacheFileTemp; private File cacheFileTemp;
private File cacheFileFinal; private File cacheFileFinal;
...@@ -335,7 +342,7 @@ public class FileLoadOperation { ...@@ -335,7 +342,7 @@ public class FileLoadOperation {
cacheFileTemp = new File(Utilities.getCacheDir(), fileNameTemp); cacheFileTemp = new File(Utilities.getCacheDir(), fileNameTemp);
if (cacheFileTemp.exists()) { if (cacheFileTemp.exists()) {
downloadedBytes = (int)cacheFileTemp.length(); downloadedBytes = (int)cacheFileTemp.length();
downloadedBytes = downloadedBytes / 1024 * 1024; nextDownloadOffset = downloadedBytes = downloadedBytes / 1024 * 1024;
} }
if (fileNameIv != null) { if (fileNameIv != null) {
cacheIvTemp = new File(Utilities.getCacheDir(), fileNameIv); cacheIvTemp = new File(Utilities.getCacheDir(), fileNameIv);
...@@ -387,8 +394,9 @@ public class FileLoadOperation { ...@@ -387,8 +394,9 @@ public class FileLoadOperation {
} }
state = 2; state = 2;
cleanup(); cleanup();
if (httpUrl == null && requestToken != 0) { if (httpUrl == null) {
ConnectionsManager.getInstance().cancelRpc(requestToken, true); ConnectionsManager.getInstance().cancelRpc(requestToken, true);
ConnectionsManager.getInstance().cancelRpc(requestToken2, true);
} }
delegate.didFailedLoadingFile(FileLoadOperation.this); delegate.didFailedLoadingFile(FileLoadOperation.this);
} }
...@@ -422,6 +430,12 @@ public class FileLoadOperation { ...@@ -422,6 +430,12 @@ public class FileLoadOperation {
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
if (delayedRes != null) {
delayedRes.disableFree = false;
delayedRes.freeResources();
delayedRes = null;
}
} }
} }
...@@ -593,26 +607,26 @@ public class FileLoadOperation { ...@@ -593,26 +607,26 @@ public class FileLoadOperation {
} }
} }
private void startDownloadRequest() { private void processRequestResult(TLRPC.TL_upload_file res, TLRPC.TL_error error, int dowloadOffset, int tokenNum) {
if (state != 1) {
return;
}
TLRPC.TL_upload_getFile req = new TLRPC.TL_upload_getFile();
req.location = location;
//if (totalBytesCount == -1) {
// req.offset = 0;
// req.limit = 0;
//} else {
req.offset = downloadedBytes;
req.limit = downloadChunkSize;
//}
requestToken = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
requestToken = 0;
if (error == null) { if (error == null) {
TLRPC.TL_upload_file res = (TLRPC.TL_upload_file)response;
try { try {
if (downloadedBytes != dowloadOffset) {
if (delayedRes != null) {
FileLog.e("tmessages", "something went wrong!");
}
delayedRes = res;
delayedRes.disableFree = true;
delayedResOffset = dowloadOffset;
delayedResTokenNum = tokenNum;
return;
} else {
if (tokenNum == 0) {
requestToken = 0;
} else if (tokenNum == 1) {
requestToken2 = 0;
}
}
if (res.bytes.limit() == 0) { if (res.bytes.limit() == 0) {
onFinishLoadingFile(); onFinishLoadingFile();
return; return;
...@@ -629,9 +643,20 @@ public class FileLoadOperation { ...@@ -629,9 +643,20 @@ public class FileLoadOperation {
fiv.write(iv); fiv.write(iv);
} }
downloadedBytes += res.bytes.limit(); downloadedBytes += res.bytes.limit();
if (totalBytesCount > 0) { if (totalBytesCount > 0 && state == 1) {
delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float)downloadedBytes / (float)totalBytesCount)); delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float)downloadedBytes / (float)totalBytesCount));
} }
if(delayedRes != null && res != delayedRes) {
TLRPC.TL_upload_file temp = delayedRes;
processRequestResult(temp, null, delayedResOffset, delayedResTokenNum);
if (delayedRes != null) {
delayedRes.disableFree = false;
delayedRes.freeResources();
delayedRes = null;
}
}
if (downloadedBytes % downloadChunkSize == 0 || totalBytesCount > 0 && totalBytesCount != downloadedBytes) { if (downloadedBytes % downloadChunkSize == 0 || totalBytesCount > 0 && totalBytesCount != downloadedBytes) {
startDownloadRequest(); startDownloadRequest();
} else { } else {
...@@ -658,6 +683,7 @@ public class FileLoadOperation { ...@@ -658,6 +683,7 @@ public class FileLoadOperation {
delegate.didFailedLoadingFile(FileLoadOperation.this); delegate.didFailedLoadingFile(FileLoadOperation.this);
} else { } else {
datacenter_id = val; datacenter_id = val;
nextDownloadOffset = 0;
startDownloadRequest(); startDownloadRequest();
} }
} else if (error.text.contains("OFFSET_INVALID")) { } else if (error.text.contains("OFFSET_INVALID")) {
...@@ -682,15 +708,70 @@ public class FileLoadOperation { ...@@ -682,15 +708,70 @@ public class FileLoadOperation {
} }
} }
} }
private void processRequestProgress() {
delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float) (downloadedBytes + requestProgress + requestProgress2) / (float) totalBytesCount));
}
private void startDownloadRequest() {
if (state != 1) {
return;
}
if (requestToken == 0) {
requestProgress = 0;
if (totalBytesCount > 0 && nextDownloadOffset >= totalBytesCount) {
return;
}
final TLRPC.TL_upload_getFile req = new TLRPC.TL_upload_getFile();
req.location = location;
req.offset = nextDownloadOffset;
req.limit = downloadChunkSize;
nextDownloadOffset += downloadChunkSize;
final long time = System.currentTimeMillis();
requestToken = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
processRequestResult((TLRPC.TL_upload_file) response, error, req.offset, 0);
}
}, new RPCRequest.RPCProgressDelegate() { }, new RPCRequest.RPCProgressDelegate() {
@Override @Override
public void progress(int length, int progress) { public void progress(int length, int progress) {
if (totalBytesCount > 0) { if (state == 1) {
delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float)(downloadedBytes + progress) / (float)totalBytesCount)); requestProgress = progress;
} else if (totalBytesCount == -1) { if (totalBytesCount == -1) {
delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float)(progress) / (float)length)); delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float) (progress) / (float) length));
} else if (totalBytesCount > 0) {
processRequestProgress();
}
} }
} }
}, null, true, RPCRequest.RPCRequestClassDownloadMedia, datacenter_id); }, null, true, RPCRequest.RPCRequestClassDownloadMedia, datacenter_id);
} }
if (totalBytesCount > 0 && requestToken2 == 0) {
requestProgress2 = 0;
if (totalBytesCount > 0 && nextDownloadOffset >= totalBytesCount) {
return;
}
final long time = System.currentTimeMillis();
final TLRPC.TL_upload_getFile req = new TLRPC.TL_upload_getFile();
req.location = location;
req.offset = nextDownloadOffset;
req.limit = downloadChunkSize;
nextDownloadOffset += downloadChunkSize;
requestToken2 = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
processRequestResult((TLRPC.TL_upload_file) response, error, req.offset, 1);
}
}, new RPCRequest.RPCProgressDelegate() {
@Override
public void progress(int length, int progress) {
if (state == 1) {
requestProgress2 = progress;
processRequestProgress();
}
}
}, null, true, RPCRequest.RPCRequestClassDownloadMedia | RPCRequest.RPCRequestClassDownloadMedia2, datacenter_id);
}
}
} }
...@@ -52,9 +52,9 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti ...@@ -52,9 +52,9 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
void beginHandshake(boolean dropConnection) { void beginHandshake(boolean dropConnection) {
if (datacenter.connection == null) { if (datacenter.connection == null) {
datacenter.connection = new TcpConnection(datacenter.datacenterId); datacenter.connection = new TcpConnection(datacenter.datacenterId);
datacenter.connection.delegate = this;
datacenter.connection.transportRequestClass = RPCRequest.RPCRequestClassGeneric; datacenter.connection.transportRequestClass = RPCRequest.RPCRequestClassGeneric;
} }
datacenter.connection.delegate = this;
processedMessageIds = new ArrayList<Long>(); processedMessageIds = new ArrayList<Long>();
authNonce = null; authNonce = null;
...@@ -566,8 +566,14 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti ...@@ -566,8 +566,14 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
} }
@Override @Override
public void tcpConnectionClosed(TcpConnection connection) { public void tcpConnectionClosed(final TcpConnection connection) {
wasDisconnect = true; wasDisconnect = true;
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
connection.connect();
}
}, 1000);
} }
@Override @Override
...@@ -591,9 +597,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti ...@@ -591,9 +597,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
@Override @Override
public void tcpConnectionReceivedData(TcpConnection connection, ByteBufferDesc data, int length) { public void tcpConnectionReceivedData(TcpConnection connection, ByteBufferDesc data, int length) {
long keyId = data.readInt64(); long keyId = data.readInt64();
if (keyId == 0) { if (keyId == 0) {
long messageId = data.readInt64(); long messageId = data.readInt64();
if (processedMessageIds.contains(messageId)) { if (processedMessageIds.contains(messageId)) {
......
...@@ -29,6 +29,7 @@ public class RPCRequest { ...@@ -29,6 +29,7 @@ public class RPCRequest {
public static int RPCRequestClassCanCompress = 32; public static int RPCRequestClassCanCompress = 32;
public static int RPCRequestClassPush = 64; public static int RPCRequestClassPush = 64;
public static int RPCRequestClassWithoutLogin = 128; public static int RPCRequestClassWithoutLogin = 128;
public static int RPCRequestClassDownloadMedia2 = 256;
static int RPCRequestClassTransportMask = (RPCRequestClassGeneric | RPCRequestClassDownloadMedia | RPCRequestClassUploadMedia); static int RPCRequestClassTransportMask = (RPCRequestClassGeneric | RPCRequestClassDownloadMedia | RPCRequestClassUploadMedia);
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
package org.telegram.messenger; package org.telegram.messenger;
public class TLObject { public class TLObject {
public boolean disableFree = false;
public TLObject () { public TLObject () {
} }
......
...@@ -8136,6 +8136,9 @@ public class TLRPC { ...@@ -8136,6 +8136,9 @@ public class TLRPC {
@Override @Override
public void freeResources() { public void freeResources() {
if (disableFree) {
return;
}
if (bytes != null) { if (bytes != null) {
BuffersStorage.getInstance().reuseFreeBuffer(bytes); BuffersStorage.getInstance().reuseFreeBuffer(bytes);
bytes = null; bytes = null;
...@@ -8287,6 +8290,9 @@ public class TLRPC { ...@@ -8287,6 +8290,9 @@ public class TLRPC {
@Override @Override
public void freeResources() { public void freeResources() {
if (disableFree) {
return;
}
if (result != null) { if (result != null) {
result.freeResources(); result.freeResources();
} }
...@@ -9171,6 +9177,9 @@ public class TLRPC { ...@@ -9171,6 +9177,9 @@ public class TLRPC {
@Override @Override
public void freeResources() { public void freeResources() {
if (disableFree) {
return;
}
if (bytes != null) { if (bytes != null) {
BuffersStorage.getInstance().reuseFreeBuffer(bytes); BuffersStorage.getInstance().reuseFreeBuffer(bytes);
bytes = null; bytes = null;
...@@ -9198,6 +9207,9 @@ public class TLRPC { ...@@ -9198,6 +9207,9 @@ public class TLRPC {
@Override @Override
public void freeResources() { public void freeResources() {
if (disableFree) {
return;
}
if (bytes != null) { if (bytes != null) {
BuffersStorage.getInstance().reuseFreeBuffer(bytes); BuffersStorage.getInstance().reuseFreeBuffer(bytes);
bytes = null; bytes = null;
......
...@@ -40,7 +40,6 @@ import org.telegram.messenger.ScreenReceiver; ...@@ -40,7 +40,6 @@ import org.telegram.messenger.ScreenReceiver;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import java.util.Calendar;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
public class ApplicationLoader extends Application { public class ApplicationLoader extends Application {
...@@ -151,10 +150,14 @@ public class ApplicationLoader extends Application { ...@@ -151,10 +150,14 @@ public class ApplicationLoader extends Application {
applicationContext.startService(new Intent(applicationContext, NotificationsService.class)); applicationContext.startService(new Intent(applicationContext, NotificationsService.class));
if (android.os.Build.VERSION.SDK_INT >= 19) { if (android.os.Build.VERSION.SDK_INT >= 19) {
Calendar cal = Calendar.getInstance(); // Calendar cal = Calendar.getInstance();
// PendingIntent pintent = PendingIntent.getService(applicationContext, 0, new Intent(applicationContext, NotificationsService.class), 0);
// AlarmManager alarm = (AlarmManager) applicationContext.getSystemService(Context.ALARM_SERVICE);
// alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30000, pintent);
PendingIntent pintent = PendingIntent.getService(applicationContext, 0, new Intent(applicationContext, NotificationsService.class), 0); PendingIntent pintent = PendingIntent.getService(applicationContext, 0, new Intent(applicationContext, NotificationsService.class), 0);
AlarmManager alarm = (AlarmManager) applicationContext.getSystemService(Context.ALARM_SERVICE); AlarmManager alarm = (AlarmManager)applicationContext.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30000, pintent); alarm.cancel(pintent);
} }
} else { } else {
stopPushService(); stopPushService();
......
...@@ -1624,7 +1624,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat ...@@ -1624,7 +1624,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
currentPathObject = null; currentPathObject = null;
currentThumb = null; currentThumb = null;
centerImage.setImageBitmap((Bitmap)null); centerImage.setImageBitmap((Bitmap)null);
leftImage.setImageBitmap((Bitmap) null); leftImage.setImageBitmap((Bitmap)null);
rightImage.setImageBitmap((Bitmap)null); rightImage.setImageBitmap((Bitmap)null);
if (android.os.Build.VERSION.SDK_INT >= 11 && object != null) { if (android.os.Build.VERSION.SDK_INT >= 11 && object != null) {
object.imageReceiver.setVisible(true, true); object.imageReceiver.setVisible(true, true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment