Commit 74def222 authored by DrKLO's avatar DrKLO

Update to 3.3.1

parent 496c336d
...@@ -7,22 +7,16 @@ repositories { ...@@ -7,22 +7,16 @@ repositories {
dependencies { dependencies {
compile 'com.android.support:support-v4:23.1.+' compile 'com.android.support:support-v4:23.1.+'
compile 'com.google.android.gms:play-services:3.2.+' compile 'com.google.android.gms:play-services:3.2.+'
compile 'net.hockeyapp.android:HockeySDK:3.5.+' compile 'net.hockeyapp.android:HockeySDK:3.6.+'
compile 'com.googlecode.mp4parser:isoparser:1.0.+' compile 'com.googlecode.mp4parser:isoparser:1.0.+'
compile 'org.apache.httpcomponents:httpmime:4.2.1'
} }
android { android {
compileSdkVersion 23 compileSdkVersion 23
buildToolsVersion '23.0.1' buildToolsVersion '23.0.2'
useLibrary 'org.apache.http.legacy' useLibrary 'org.apache.http.legacy'
packagingOptions {
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
}
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7 sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7
...@@ -30,7 +24,10 @@ android { ...@@ -30,7 +24,10 @@ android {
signingConfigs { signingConfigs {
debug { debug {
storeFile file("config/debug.keystore") storeFile file("config/release.keystore")
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
} }
release { release {
...@@ -46,6 +43,7 @@ android { ...@@ -46,6 +43,7 @@ android {
debuggable true debuggable true
jniDebuggable true jniDebuggable true
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
applicationIdSuffix ".beta"
} }
release { release {
...@@ -81,7 +79,7 @@ android { ...@@ -81,7 +79,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 23 targetSdkVersion 23
versionCode 654 versionCode 685
versionName "3.2.6" versionName "3.3.1"
} }
} }
...@@ -21,13 +21,13 @@ ...@@ -21,13 +21,13 @@
<application <application
android:allowBackup="false" android:allowBackup="false"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/AppName" android:label="@string/AppNameBeta"
android:theme="@style/Theme.TMessages.Start" android:theme="@style/Theme.TMessages.Start"
android:name=".ApplicationLoader" android:name=".ApplicationLoader"
android:hardwareAccelerated="@bool/useHardwareAcceleration" android:hardwareAccelerated="@bool/useHardwareAcceleration"
android:largeHeap="true"> android:largeHeap="true">
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyCTNmNqbWovP9ETcAob98YlrfOQEAC0CJ4" /> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyA-t0jLPjUt2FxrA8VPK2EiYHcYcboIR6k" />
<activity android:name="net.hockeyapp.android.UpdateActivity" /> <activity android:name="net.hockeyapp.android.UpdateActivity" />
......
...@@ -187,7 +187,7 @@ include $(CLEAR_VARS) ...@@ -187,7 +187,7 @@ include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false LOCAL_PRELINK_MODULE := false
LOCAL_STATIC_LIBRARIES := webp sqlite tgnet breakpad LOCAL_STATIC_LIBRARIES := webp sqlite tgnet breakpad
LOCAL_MODULE := tmessages.14 LOCAL_MODULE := tmessages.15
LOCAL_CFLAGS := -w -std=c11 -Os -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 LOCAL_CFLAGS := -w -std=c11 -Os -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno
LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math
......
...@@ -96,7 +96,7 @@ void sendRequest(JNIEnv *env, jclass c, jint object, jobject onComplete, jobject ...@@ -96,7 +96,7 @@ void sendRequest(JNIEnv *env, jclass c, jint object, jobject onComplete, jobject
if (onQuickAck != nullptr) { if (onQuickAck != nullptr) {
jniEnv->CallVoidMethod(onQuickAck, jclass_QuickAckDelegate_run); jniEnv->CallVoidMethod(onQuickAck, jclass_QuickAckDelegate_run);
} }
}), flags, datacenterId, (ConnectionType) connetionType, immediate, onComplete, onQuickAck); }), flags, datacenterId, (ConnectionType) connetionType, immediate, token, onComplete, onQuickAck);
} }
void cancelRequest(JNIEnv *env, jclass c, jint token, jboolean notifyServer) { void cancelRequest(JNIEnv *env, jclass c, jint token, jboolean notifyServer) {
......
This diff is collapsed.
This diff is collapsed.
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Copyright Nikolai Kudashov, 2015. * Copyright Nikolai Kudashov, 2015.
*/ */
#include <sys/stat.h>
#include "Config.h" #include "Config.h"
#include "ConnectionsManager.h" #include "ConnectionsManager.h"
#include "FileLog.h" #include "FileLog.h"
...@@ -16,9 +17,10 @@ Config::Config(std::string fileName) { ...@@ -16,9 +17,10 @@ Config::Config(std::string fileName) {
backupPath = configPath + ".bak"; backupPath = configPath + ".bak";
FILE *backup = fopen(backupPath.c_str(), "rb"); FILE *backup = fopen(backupPath.c_str(), "rb");
if (backup != nullptr) { if (backup != nullptr) {
DEBUG_D("Config(%p, %s) backup file found %s", this, configPath.c_str(), backupPath.c_str());
fclose(backup);
remove(configPath.c_str()); remove(configPath.c_str());
rename(backupPath.c_str(), configPath.c_str()); rename(backupPath.c_str(), configPath.c_str());
fclose(backup);
} }
} }
...@@ -28,10 +30,14 @@ NativeByteBuffer *Config::readConfig() { ...@@ -28,10 +30,14 @@ NativeByteBuffer *Config::readConfig() {
if (file != nullptr) { if (file != nullptr) {
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
long fileSize = ftell(file); long fileSize = ftell(file);
fseek(file, 0, SEEK_SET); if (fseek(file, 0, SEEK_SET)) {
DEBUG_E("Config(%p, %s) failed fseek to begin, reopen it", this, configPath.c_str());
fclose(file);
file = fopen(configPath.c_str(), "rb");
}
uint32_t size = 0; uint32_t size = 0;
int bytesRead = fread(&size, sizeof(uint32_t), 1, file); int bytesRead = fread(&size, sizeof(uint32_t), 1, file);
DEBUG_D("Config(%p, %s) load, size = %u", this, configPath.c_str(), size); DEBUG_D("Config(%p, %s) load, size = %u, fileSize = %u", this, configPath.c_str(), size, (uint32_t) fileSize);
if (bytesRead > 0 && size > 0 && (int32_t) size < fileSize) { if (bytesRead > 0 && size > 0 && (int32_t) size < fileSize) {
buffer = BuffersStorage::getInstance().getFreeBuffer(size); buffer = BuffersStorage::getInstance().getFreeBuffer(size);
if (fread(buffer->bytes(), sizeof(uint8_t), size, file) != size) { if (fread(buffer->bytes(), sizeof(uint8_t), size, file) != size) {
...@@ -45,6 +51,7 @@ NativeByteBuffer *Config::readConfig() { ...@@ -45,6 +51,7 @@ NativeByteBuffer *Config::readConfig() {
} }
void Config::writeConfig(NativeByteBuffer *buffer) { void Config::writeConfig(NativeByteBuffer *buffer) {
DEBUG_D("Config(%p, %s) start write config", this, configPath.c_str());
FILE *file = fopen(configPath.c_str(), "rb"); FILE *file = fopen(configPath.c_str(), "rb");
FILE *backup = fopen(backupPath.c_str(), "rb"); FILE *backup = fopen(backupPath.c_str(), "rb");
bool error = false; bool error = false;
...@@ -65,21 +72,53 @@ void Config::writeConfig(NativeByteBuffer *buffer) { ...@@ -65,21 +72,53 @@ void Config::writeConfig(NativeByteBuffer *buffer) {
return; return;
} }
file = fopen(configPath.c_str(), "wb"); file = fopen(configPath.c_str(), "wb");
if (chmod(configPath.c_str(), 0660)) {
DEBUG_E("Config(%p, %s) chmod failed", this, configPath.c_str());
}
if (file == nullptr) { if (file == nullptr) {
DEBUG_E("Config(%p, %s) unable to open file for writing", this, configPath.c_str());
return; return;
} }
uint32_t size = buffer->position(); uint32_t size = buffer->position();
if (fwrite(&size, sizeof(uint32_t), 1, file) == 1) { if (fwrite(&size, sizeof(uint32_t), 1, file) == 1) {
if (fwrite(buffer->bytes(), sizeof(uint8_t), size, file) != size) { if (fwrite(buffer->bytes(), sizeof(uint8_t), size, file) != size) {
DEBUG_E("Config(%p, %s) failed to write config data to file", this, configPath.c_str());
error = true; error = true;
} }
} else { } else {
DEBUG_E("Config(%p, %s) failed to write config size to file", this, configPath.c_str());
error = true;
}
if (fflush(file)) {
DEBUG_E("Config(%p, %s) fflush failed", this, configPath.c_str());
error = true;
}
int fd = fileno(file);
if (fd == -1) {
DEBUG_E("Config(%p, %s) fileno failed", this, configPath.c_str());
error = true;
} else {
DEBUG_D("Config(%p, %s) fileno = %d", this, configPath.c_str(), fd);
}
if (fd != -1 && fsync(fd) == -1) {
DEBUG_E("Config(%p, %s) fsync failed", this, configPath.c_str());
error = true;
}
if (fclose(file)) {
DEBUG_E("Config(%p, %s) fclose failed", this, configPath.c_str());
error = true; error = true;
} }
fclose(file);
if (error) { if (error) {
remove(configPath.c_str()); DEBUG_E("Config(%p, %s) failed to write config", this, configPath.c_str());
if (remove(configPath.c_str())) {
DEBUG_E("Config(%p, %s) remove config failed", this, configPath.c_str());
}
} else { } else {
remove(backupPath.c_str()); if (remove(backupPath.c_str())) {
DEBUG_E("Config(%p, %s) remove backup failed failed", this, configPath.c_str());
}
}
if (!error) {
DEBUG_D("Config(%p, %s) config write ok", this, configPath.c_str());
} }
} }
...@@ -220,7 +220,7 @@ void ConnectionsManager::select() { ...@@ -220,7 +220,7 @@ void ConnectionsManager::select() {
return; return;
} else { } else {
lastPauseTime = now; lastPauseTime = now;
DEBUG_D("don't sleep 10 seconds because of salt, upload or download request"); DEBUG_D("don't sleep 30 seconds because of salt, upload or download request");
} }
} }
if (networkPaused) { if (networkPaused) {
...@@ -595,7 +595,7 @@ void ConnectionsManager::onConnectionConnected(Connection *connection) { ...@@ -595,7 +595,7 @@ void ConnectionsManager::onConnectionConnected(Connection *connection) {
} else { } else {
if (networkPaused && lastPauseTime != 0) { if (networkPaused && lastPauseTime != 0) {
lastPauseTime = getCurrentTimeMillis(); lastPauseTime = getCurrentTimeMillis();
nextSleepTimeout = 10000; nextSleepTimeout = 30000;
} }
processRequestQueue(connection->getConnectionType(), datacenter->getDatacenterId()); processRequestQueue(connection->getConnectionType(), datacenter->getDatacenterId());
} }
...@@ -821,6 +821,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag ...@@ -821,6 +821,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
Request *request = iter->get(); Request *request = iter->get();
Datacenter *requestDatacenter = getDatacenterWithId(request->datacenterId); Datacenter *requestDatacenter = getDatacenterWithId(request->datacenterId);
if (request->messageId < response->first_msg_id && request->connectionType & connection->getConnectionType() && requestDatacenter != nullptr && requestDatacenter->getDatacenterId() == datacenter->getDatacenterId()) { if (request->messageId < response->first_msg_id && request->connectionType & connection->getConnectionType() && requestDatacenter != nullptr && requestDatacenter->getDatacenterId() == datacenter->getDatacenterId()) {
DEBUG_D("clear request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
request->clear(true); request->clear(true);
} }
} }
...@@ -943,6 +944,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag ...@@ -943,6 +944,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
for (requestsIter iter = runningRequests.begin(); iter != runningRequests.end(); iter++) { for (requestsIter iter = runningRequests.begin(); iter != runningRequests.end(); iter++) {
Request *request = iter->get(); Request *request = iter->get();
if (request->respondsToMessageId(resultMid)) { if (request->respondsToMessageId(resultMid)) {
DEBUG_D("got response for request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
bool discardResponse = false; bool discardResponse = false;
bool isError = false; bool isError = false;
bool allowInitConnection = true; bool allowInitConnection = true;
...@@ -984,8 +986,16 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag ...@@ -984,8 +986,16 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
} }
discardResponse = true; discardResponse = true;
request->failedByFloodWait = true; request->failedByFloodWait = waitTime;
request->startTime = 0;
request->minStartTime = (int32_t) (getCurrentTimeMillis() / 1000 + waitTime); request->minStartTime = (int32_t) (getCurrentTimeMillis() / 1000 + waitTime);
} else if (error->error_code == 400) {
static std::string waitFailed = "MSG_WAIT_FAILED";
if (error->error_message.find(waitFailed) != std::string::npos) {
discardResponse = true;
request->minStartTime = (int32_t) (getCurrentTimeMillis() / 1000 + 1);
request->startTime = 0;
}
} }
} }
if (!discardResponse) { if (!discardResponse) {
...@@ -1124,10 +1134,10 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag ...@@ -1124,10 +1134,10 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
if ((request->connectionType & ConnectionTypeDownload) == 0) { if ((request->connectionType & ConnectionTypeDownload) == 0) {
continue; continue;
} }
if (request->respondsToMessageId(resultMid)) { Datacenter *requestDatacenter = getDatacenterWithId(request->datacenterId);
if (requestDatacenter != nullptr && requestDatacenter->getDatacenterId() == datacenter->getDatacenterId()) {
request->retryCount = 0; request->retryCount = 0;
request->failedBySalt = true; request->failedBySalt = true;
break;
} }
} }
} }
...@@ -1208,7 +1218,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag ...@@ -1208,7 +1218,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
} else if (connection->connectionType == ConnectionTypePush && typeInfo == typeid(TL_updatesTooLong)) { } else if (connection->connectionType == ConnectionTypePush && typeInfo == typeid(TL_updatesTooLong)) {
if (networkPaused) { if (networkPaused) {
lastPauseTime = getCurrentTimeMillis(); lastPauseTime = getCurrentTimeMillis();
nextSleepTimeout = 10000; nextSleepTimeout = 30000;
DEBUG_D("received internal push: wakeup network in background"); DEBUG_D("received internal push: wakeup network in background");
} else if (lastPauseTime != 0) { } else if (lastPauseTime != 0) {
lastPauseTime = getCurrentTimeMillis(); lastPauseTime = getCurrentTimeMillis();
...@@ -1364,12 +1374,6 @@ void ConnectionsManager::sendRequest(TLObject *object, onCompleteFunc onComplete ...@@ -1364,12 +1374,6 @@ void ConnectionsManager::sendRequest(TLObject *object, onCompleteFunc onComplete
} }
#ifdef ANDROID #ifdef ANDROID
int32_t ConnectionsManager::sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, jobject ptr1, jobject ptr2) {
int32_t requestToken = lastRequestToken++;
sendRequest(object, onComplete, onQuickAck, flags, datacenterId, connetionType, immediate, requestToken, ptr1, ptr2);
return requestToken;
}
void ConnectionsManager::sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, int32_t requestToken, jobject ptr1, jobject ptr2) { void ConnectionsManager::sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, int32_t requestToken, jobject ptr1, jobject ptr2) {
if (!currentUserId && !(flags & RequestFlagWithoutLogin)) { if (!currentUserId && !(flags & RequestFlagWithoutLogin)) {
DEBUG_D("can't do request without login %s", typeid(*object).name()); DEBUG_D("can't do request without login %s", typeid(*object).name());
...@@ -1489,7 +1493,7 @@ void ConnectionsManager::cancelRequestInternal(int32_t token, bool notifyServer, ...@@ -1489,7 +1493,7 @@ void ConnectionsManager::cancelRequestInternal(int32_t token, bool notifyServer,
Request *request = iter->get(); Request *request = iter->get();
if (request->requestToken == token) { if (request->requestToken == token) {
request->cancelled = true; request->cancelled = true;
DEBUG_D("cancelled queued rpc request %s", typeid(*request->rawRequest).name()); DEBUG_D("cancelled queued rpc request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
requestsQueue.erase(iter); requestsQueue.erase(iter);
if (removeFromClass) { if (removeFromClass) {
removeRequestFromGuid(token); removeRequestFromGuid(token);
...@@ -1507,7 +1511,7 @@ void ConnectionsManager::cancelRequestInternal(int32_t token, bool notifyServer, ...@@ -1507,7 +1511,7 @@ void ConnectionsManager::cancelRequestInternal(int32_t token, bool notifyServer,
sendRequest(dropAnswer, nullptr, nullptr, RequestFlagEnableUnauthorized | RequestFlagWithoutLogin | RequestFlagFailOnServerErrors, request->datacenterId, request->connectionType, true); sendRequest(dropAnswer, nullptr, nullptr, RequestFlagEnableUnauthorized | RequestFlagWithoutLogin | RequestFlagFailOnServerErrors, request->datacenterId, request->connectionType, true);
} }
request->cancelled = true; request->cancelled = true;
DEBUG_D("cancelled running rpc request %s", typeid(*request->rawRequest).name()); DEBUG_D("cancelled running rpc request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
runningRequests.erase(iter); runningRequests.erase(iter);
if (removeFromClass) { if (removeFromClass) {
removeRequestFromGuid(token); removeRequestFromGuid(token);
...@@ -1795,7 +1799,12 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t ...@@ -1795,7 +1799,12 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
forceThisRequest = false; forceThisRequest = false;
} }
if (forceThisRequest || (abs(currentTime - request->startTime) > maxTimeout && (currentTime > request->minStartTime || abs(currentTime - request->minStartTime) > 60))) { if (forceThisRequest || (abs(currentTime - request->startTime) > maxTimeout &&
(currentTime >= request->minStartTime ||
(request->failedByFloodWait != 0 && (request->minStartTime - currentTime) > request->failedByFloodWait) ||
(request->failedByFloodWait == 0 && abs(currentTime - request->minStartTime) >= 60))
)
) {
if (!forceThisRequest && request->connectionToken > 0) { if (!forceThisRequest && request->connectionToken > 0) {
if (request->connectionType & ConnectionTypeGeneric && request->connectionToken == connection->getConnectionToken()) { if (request->connectionType & ConnectionTypeGeneric && request->connectionToken == connection->getConnectionToken()) {
DEBUG_D("request token is valid, not retrying %s", typeInfo.name()); DEBUG_D("request token is valid, not retrying %s", typeInfo.name());
...@@ -1816,7 +1825,8 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t ...@@ -1816,7 +1825,8 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
request->retryCount++; request->retryCount++;
if (!request->failedBySalt && request->connectionType & ConnectionTypeDownload) { if (!request->failedBySalt) {
if (request->connectionType & ConnectionTypeDownload) {
uint32_t retryMax = 10; uint32_t retryMax = 10;
if (!(request->requestFlags & RequestFlagForceDownload)) { if (!(request->requestFlags & RequestFlagForceDownload)) {
if (request->failedByFloodWait) { if (request->failedByFloodWait) {
...@@ -1836,6 +1846,9 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t ...@@ -1836,6 +1846,9 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
continue; continue;
} }
} }
} else {
request->failedBySalt = false;
}
if (request->messageSeqNo == 0) { if (request->messageSeqNo == 0) {
request->messageSeqNo = connection->generateMessageSeqNo(true); request->messageSeqNo = connection->generateMessageSeqNo(true);
...@@ -2103,9 +2116,11 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t ...@@ -2103,9 +2116,11 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
TL_invokeAfterMsg *request = new TL_invokeAfterMsg(); TL_invokeAfterMsg *request = new TL_invokeAfterMsg();
request->msg_id = lastSentMessageRpcId; request->msg_id = lastSentMessageRpcId;
if (message->outgoingBody != nullptr) { if (message->outgoingBody != nullptr) {
DEBUG_D("wrap outgoingBody(%p, %s) to TL_invokeAfterMsg", message->outgoingBody, typeid(*message->outgoingBody).name());
request->outgoingQuery = message->outgoingBody; request->outgoingQuery = message->outgoingBody;
message->outgoingBody = nullptr; message->outgoingBody = nullptr;
} else { } else {
DEBUG_D("wrap body(%p, %s) to TL_invokeAfterMsg", message->body.get(), typeid(*message->body.get()).name());
request->query = std::move(message->body); request->query = std::move(message->body);
} }
message->body = std::unique_ptr<TLObject>(request); message->body = std::unique_ptr<TLObject>(request);
...@@ -2407,7 +2422,7 @@ void ConnectionsManager::resumeNetwork(bool partial) { ...@@ -2407,7 +2422,7 @@ void ConnectionsManager::resumeNetwork(bool partial) {
if (partial) { if (partial) {
if (networkPaused) { if (networkPaused) {
lastPauseTime = getCurrentTimeMillis(); lastPauseTime = getCurrentTimeMillis();
nextSleepTimeout = 10000; nextSleepTimeout = 30000;
networkPaused = false; networkPaused = false;
DEBUG_D("wakeup network in background"); DEBUG_D("wakeup network in background");
} else if (lastPauseTime != 0) { } else if (lastPauseTime != 0) {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <functional> #include <functional>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <map> #include <map>
#include <atomic>
#include <bits/unique_ptr.h> #include <bits/unique_ptr.h>
#include "Defines.h" #include "Defines.h"
...@@ -63,7 +64,6 @@ public: ...@@ -63,7 +64,6 @@ public:
void updateDcSettings(uint32_t datacenterId); void updateDcSettings(uint32_t datacenterId);
#ifdef ANDROID #ifdef ANDROID
int32_t sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, jobject ptr1, jobject ptr2);
void sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, int32_t requestToken, jobject ptr1, jobject ptr2); void sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, int32_t requestToken, jobject ptr1, jobject ptr2);
static void useJavaVM(JavaVM *vm, bool useJavaByteBuffers); static void useJavaVM(JavaVM *vm, bool useJavaByteBuffers);
#endif #endif
...@@ -120,7 +120,7 @@ private: ...@@ -120,7 +120,7 @@ private:
std::map<int32_t, std::vector<std::int32_t>> quickAckIdToRequestIds; std::map<int32_t, std::vector<std::int32_t>> quickAckIdToRequestIds;
int32_t pingTime; int32_t pingTime;
bool testBackend = false; bool testBackend = false;
volatile uint32_t lastRequestToken = 1; std::atomic<uint32_t> lastRequestToken{1};
uint32_t currentDatacenterId = 0; uint32_t currentDatacenterId = 0;
uint32_t movingToDatacenterId = DEFAULT_DATACENTER_ID; uint32_t movingToDatacenterId = DEFAULT_DATACENTER_ID;
int64_t pushSessionId = 0; int64_t pushSessionId = 0;
......
...@@ -668,9 +668,7 @@ void Datacenter::onHandshakeConnectionConnected(Connection *connection) { ...@@ -668,9 +668,7 @@ void Datacenter::onHandshakeConnectionConnected(Connection *connection) {
if (handshakeState == 0 || !needResendData) { if (handshakeState == 0 || !needResendData) {
return; return;
} }
if (handshakeRequest != nullptr) { beginHandshake(false);
sendRequestData(handshakeRequest, true);
}
} }
inline uint64_t gcd(uint64_t a, uint64_t b) { inline uint64_t gcd(uint64_t a, uint64_t b) {
...@@ -1383,6 +1381,7 @@ NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<Net ...@@ -1383,6 +1381,7 @@ NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<Net
int64_t currentTime = ConnectionsManager::getInstance().getCurrentTimeMillis() + (int64_t) timeDifference * 1000; int64_t currentTime = ConnectionsManager::getInstance().getCurrentTimeMillis() + (int64_t) timeDifference * 1000;
if (messageTime < currentTime - 30000 || messageTime > currentTime + 25000) { if (messageTime < currentTime - 30000 || messageTime > currentTime + 25000) {
DEBUG_D("wrap message in container");
TL_msg_container *messageContainer = new TL_msg_container(); TL_msg_container *messageContainer = new TL_msg_container();
messageContainer->messages.push_back(std::move(networkMessage->message)); messageContainer->messages.push_back(std::move(networkMessage->message));
...@@ -1395,6 +1394,7 @@ NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<Net ...@@ -1395,6 +1394,7 @@ NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<Net
messageSeqNo = networkMessage->message->seqno; messageSeqNo = networkMessage->message->seqno;
} }
} else { } else {
DEBUG_D("start write messages to container");
TL_msg_container *messageContainer = new TL_msg_container(); TL_msg_container *messageContainer = new TL_msg_container();
size_t count = requests.size(); size_t count = requests.size();
for (uint32_t a = 0; a < count; a++) { for (uint32_t a = 0; a < count; a++) {
......
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
FILE *logFile = nullptr; FILE *logFile = nullptr;
void FileLog::init(std::string path) { void FileLog::init(std::string path) {
if (path.size() > 0) {
logFile = fopen(path.c_str(), "w"); logFile = fopen(path.c_str(), "w");
}
} }
void FileLog::e(const char *message, ...) { void FileLog::e(const char *message, ...) {
......
...@@ -931,7 +931,7 @@ void TL_config::readParams(NativeByteBuffer *stream, bool &error) { ...@@ -931,7 +931,7 @@ void TL_config::readParams(NativeByteBuffer *stream, bool &error) {
dc_options.push_back(std::unique_ptr<TL_dcOption>(object)); dc_options.push_back(std::unique_ptr<TL_dcOption>(object));
} }
chat_size_max = stream->readInt32(&error); chat_size_max = stream->readInt32(&error);
broadcast_size_max = stream->readInt32(&error); megagroup_size_max = stream->readInt32(&error);
forwarded_count_max = stream->readInt32(&error); forwarded_count_max = stream->readInt32(&error);
online_update_period_ms = stream->readInt32(&error); online_update_period_ms = stream->readInt32(&error);
offline_blur_timeout_ms = stream->readInt32(&error); offline_blur_timeout_ms = stream->readInt32(&error);
...@@ -971,7 +971,7 @@ void TL_config::serializeToStream(NativeByteBuffer *stream) { ...@@ -971,7 +971,7 @@ void TL_config::serializeToStream(NativeByteBuffer *stream) {
dc_options[a]->serializeToStream(stream); dc_options[a]->serializeToStream(stream);
} }
stream->writeInt32(chat_size_max); stream->writeInt32(chat_size_max);
stream->writeInt32(broadcast_size_max); stream->writeInt32(megagroup_size_max);
stream->writeInt32(forwarded_count_max); stream->writeInt32(forwarded_count_max);
stream->writeInt32(online_update_period_ms); stream->writeInt32(online_update_period_ms);
stream->writeInt32(offline_blur_timeout_ms); stream->writeInt32(offline_blur_timeout_ms);
......
...@@ -657,7 +657,7 @@ public: ...@@ -657,7 +657,7 @@ public:
class TL_config : public TLObject { class TL_config : public TLObject {
public: public:
static const uint32_t constructor = 0x4e32b894; static const uint32_t constructor = 0x6cb6e65e;
int32_t date; int32_t date;
int32_t expires; int32_t expires;
...@@ -665,7 +665,7 @@ public: ...@@ -665,7 +665,7 @@ public:
int32_t this_dc; int32_t this_dc;
std::vector<std::unique_ptr<TL_dcOption>> dc_options; std::vector<std::unique_ptr<TL_dcOption>> dc_options;
int32_t chat_size_max; int32_t chat_size_max;
int32_t broadcast_size_max; int32_t megagroup_size_max;
int32_t forwarded_count_max; int32_t forwarded_count_max;
int32_t online_update_period_ms; int32_t online_update_period_ms;
int32_t offline_blur_timeout_ms; int32_t offline_blur_timeout_ms;
......
...@@ -34,7 +34,7 @@ public: ...@@ -34,7 +34,7 @@ public:
int32_t requestToken; int32_t requestToken;
uint32_t retryCount = 0; uint32_t retryCount = 0;
bool failedBySalt = false; bool failedBySalt = false;
bool failedByFloodWait = false; int32_t failedByFloodWait = 0;
ConnectionType connectionType; ConnectionType connectionType;
uint32_t requestFlags; uint32_t requestFlags;
bool completed = false; bool completed = false;
......
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
android:allowBackup="false" android:allowBackup="false"
android:hardwareAccelerated="@bool/useHardwareAcceleration" android:hardwareAccelerated="@bool/useHardwareAcceleration"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/AppName"
android:largeHeap="true" android:largeHeap="true"
android:theme="@style/Theme.TMessages.Start"> android:theme="@style/Theme.TMessages.Start">
...@@ -159,7 +158,7 @@ ...@@ -159,7 +158,7 @@
</service> </service>
<service <service
android:name=".TgChooserTargetService" android:name="org.telegram.messenger.TgChooserTargetService"
android:label="@string/AppName" android:label="@string/AppName"
android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE"> android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
<intent-filter> <intent-filter>
......
1876;JM;Jamaica 1876;JM;Jamaica;XXX XXXX
1869;KN;Saint Kitts & Nevis 1869;KN;Saint Kitts & Nevis;XXX XXXX
1868;TT;Trinidad & Tobago 1868;TT;Trinidad & Tobago;XXX XXXX
1784;VC;Saint Vincent & the Grenadines 1784;VC;Saint Vincent & the Grenadines;XXX XXXX
1767;DM;Dominica 1767;DM;Dominica;XXX XXXX
1758;LC;Saint Lucia 1758;LC;Saint Lucia;XXX XXXX
1721;SX;Sint Maarten 1721;SX;Sint Maarten;XXX XXXX
1684;AS;American Samoa 1684;AS;American Samoa;XXX XXXX
1671;GU;Guam 1671;GU;Guam;XXX XXXX
1670;MP;Northern Mariana Islands 1670;MP;Northern Mariana Islands;XXX XXXX
1664;MS;Montserrat 1664;MS;Montserrat;XXX XXXX
1649;TC;Turks & Caicos Islands 1649;TC;Turks & Caicos Islands;XXX XXXX
1473;GD;Grenada 1473;GD;Grenada;XXX XXXX
1441;BM;Bermuda 1441;BM;Bermuda;XXX XXXX
1345;KY;Cayman Islands 1345;KY;Cayman Islands;XXX XXXX
1340;VI;US Virgin Islands 1340;VI;US Virgin Islands;XXX XXXX
1284;VG;British Virgin Islands 1284;VG;British Virgin Islands;XXX XXXX
1268;AG;Antigua & Barbuda 1268;AG;Antigua & Barbuda;XXX XXXX
1264;AI;Anguilla 1264;AI;Anguilla;XXX XXXX
1246;BB;Barbados 1246;BB;Barbados;XXX XXXX
1242;BS;Bahamas 1242;BS;Bahamas;XXX XXXX
998;UZ;Uzbekistan 998;UZ;Uzbekistan;XX XXXXXXX
996;KG;Kyrgyzstan 996;KG;Kyrgyzstan;XXX XXXXXX
995;GE;Georgia 995;GE;Georgia;XXX XXX XXX
994;AZ;Azerbaijan 994;AZ;Azerbaijan;XX XXX XXXX
993;TM;Turkmenistan 993;TM;Turkmenistan;XX XXXXXX
992;TJ;Tajikistan 992;TJ;Tajikistan;XX XXX XXXX
977;NP;Nepal 977;NP;Nepal;XX XXXX XXXX
976;MN;Mongolia 976;MN;Mongolia;XX XX XXXX
975;BT;Bhutan 975;BT;Bhutan;XX XXX XXX
974;QA;Qatar 974;QA;Qatar;XX XXX XXX
973;BH;Bahrain 973;BH;Bahrain;XXXX XXXX
972;IL;Israel 972;IL;Israel;XX XXX XXXX
971;AE;United Arab Emirates 971;AE;United Arab Emirates;XX XXX XXXX
970;PS;Palestine 970;PS;Palestine;XXX XX XXXX
968;OM;Oman 968;OM;Oman;XXXX XXXX
967;YE;Yemen 967;YE;Yemen;XXX XXX XXX
966;SA;Saudi Arabia 966;SA;Saudi Arabia;XX XXX XXXX
965;KW;Kuwait 965;KW;Kuwait;XXXX XXXX
964;IQ;Iraq 964;IQ;Iraq;XXX XXX XXXX
963;SY;Syrian Arab Republic 963;SY;Syria;XXX XXX XXX
962;JO;Jordan 962;JO;Jordan;X XXXX XXXX
961;LB;Lebanon 961;LB;Lebanon
960;MV;Maldives 960;MV;Maldives;XXX XXXX
886;TW;Taiwan 886;TW;Taiwan;XXX XXX XXX
880;BD;Bangladesh 880;BD;Bangladesh
856;LA;Laos 856;LA;Laos;XX XX XXX XXX
855;KH;Cambodia 855;KH;Cambodia
853;MO;Macau 853;MO;Macau;XXXX XXXX
852;HK;Hong Kong 852;HK;Hong Kong;X XXX XXXX
850;KP;North Korea 850;KP;North Korea
692;MH;Marshall Islands 692;MH;Marshall Islands
691;FM;Micronesia 691;FM;Micronesia
...@@ -67,166 +67,166 @@ ...@@ -67,166 +67,166 @@
676;TO;Tonga 676;TO;Tonga
675;PG;Papua New Guinea 675;PG;Papua New Guinea
674;NR;Nauru 674;NR;Nauru
673;BN;Brunei Darussalam 673;BN;Brunei Darussalam;XXX XXXX
672;NF;Norfolk Island 672;NF;Norfolk Island
670;TL;Timor-Leste 670;TL;Timor-Leste
599;BQ;Bonaire, Sint Eustatius & Saba 599;BQ;Bonaire, Sint Eustatius & Saba
599;CW;Curaçao 599;CW;Curaçao
598;UY;Uruguay 598;UY;Uruguay;X XXX XXXX
597;SR;Suriname 597;SR;Suriname;XXX XXXX
596;MQ;Martinique 596;MQ;Martinique
595;PY;Paraguay 595;PY;Paraguay;XXX XXX XXX
594;GF;French Guiana 594;GF;French Guiana
593;EC;Ecuador 593;EC;Ecuador;XX XXX XXXX
592;GY;Guyana 592;GY;Guyana
591;BO;Bolivia 591;BO;Bolivia;X XXX XXXX
590;GP;Guadeloupe 590;GP;Guadeloupe;XXX XX XX XX
509;HT;Haiti 509;HT;Haiti
508;PM;Saint Pierre & Miquelon 508;PM;Saint Pierre & Miquelon
507;PA;Panama 507;PA;Panama;XXXX XXXX
506;CR;Costa Rica 506;CR;Costa Rica;XXXX XXXX
505;NI;Nicaragua 505;NI;Nicaragua;XXXX XXXX
504;HN;Honduras 504;HN;Honduras;XXXX XXXX
503;SV;El Salvador 503;SV;El Salvador;XXXX XXXX
502;GT;Guatemala 502;GT;Guatemala;X XXX XXXX
501;BZ;Belize 501;BZ;Belize
500;FK;Falkland Islands 500;FK;Falkland Islands
423;LI;Liechtenstein 423;LI;Liechtenstein
421;SK;Slovakia 421;SK;Slovakia;XXX XXX XXX
420;CZ;Czech Republic 420;CZ;Czech Republic;XXX XXX XXX
389;MK;Macedonia 389;MK;Macedonia;XX XXX XXX
387;BA;Bosnia & Herzegovina 387;BA;Bosnia & Herzegovina;XX XXX XXX
386;SI;Slovenia 386;SI;Slovenia;XX XXX XXX
385;HR;Croatia 385;HR;Croatia
382;ME;Montenegro 382;ME;Montenegro
381;RS;Serbia 381;RS;Serbia;XX XXX XXXX
380;UA;Ukraine 380;UA;Ukraine;XX XXX XX XX
378;SM;San Marino 378;SM;San Marino;XXX XXX XXXX
377;MC;Monaco 377;MC;Monaco;XXXX XXXX
376;AD;Andorra 376;AD;Andorra;XX XX XX
375;BY;Belarus 375;BY;Belarus;XX XXX XXXX
374;AM;Armenia 374;AM;Armenia;XX XXX XXX
373;MD;Moldova 373;MD;Moldova;XX XXX XXX
372;EE;Estonia 372;EE;Estonia
371;LV;Latvia 371;LV;Latvia;XXX XXXXX
370;LT;Lithuania 370;LT;Lithuania;XXX XXXXX
359;BG;Bulgaria 359;BG;Bulgaria
358;FI;Finland 358;FI;Finland
357;CY;Cyprus 357;CY;Cyprus;XXXX XXXX
356;MT;Malta 356;MT;Malta;XX XX XX XX
355;AL;Albania 355;AL;Albania;XX XXX XXXX
354;IS;Iceland 354;IS;Iceland;XXX XXXX
353;IE;Ireland 353;IE;Ireland;XX XXX XXXX
352;LU;Luxembourg 352;LU;Luxembourg
351;PT;Portugal 351;PT;Portugal;X XXXX XXXX
350;GI;Gibraltar 350;GI;Gibraltar;XXXX XXXX
299;GL;Greenland 299;GL;Greenland;XXX XXX
298;FO;Faroe Islands 298;FO;Faroe Islands;XXX XXX
297;AW;Aruba 297;AW;Aruba;XXX XXXX
291;ER;Eritrea 291;ER;Eritrea;X XXX XXX
290;SH;Saint Helena 290;SH;Saint Helena;XX XXX
269;KM;Comoros 269;KM;Comoros;XXX XXXX
268;SZ;Swaziland 268;SZ;Swaziland;XXXX XXXX
267;BW;Botswana 267;BW;Botswana;XX XXX XXX
266;LS;Lesotho 266;LS;Lesotho;XX XXX XXX
265;MW;Malawi 265;MW;Malawi;77 XXX XXXX
264;NA;Namibia 264;NA;Namibia;XX XXX XXXX
263;ZW;Zimbabwe 263;ZW;Zimbabwe;XX XXX XXXX
262;RE;Réunion 262;RE;Réunion;XXX XXX XXX
261;MG;Madagascar 261;MG;Madagascar;XX XX XXX XX
260;ZM;Zambia 260;ZM;Zambia;XX XXX XXXX
258;MZ;Mozambique 258;MZ;Mozambique;XX XXX XXXX
257;BI;Burundi 257;BI;Burundi;XX XX XXXX
256;UG;Uganda 256;UG;Uganda;XX XXX XXXX
255;TZ;Tanzania 255;TZ;Tanzania;XX XXX XXXX
254;KE;Kenya 254;KE;Kenya;XXX XXX XXX
253;DJ;Djibouti 253;DJ;Djibouti;XX XX XX XX
252;SO;Somalia 252;SO;Somalia;XX XXX XXX
251;ET;Ethiopia 251;ET;Ethiopia;XX XXX XXXX
250;RW;Rwanda 250;RW;Rwanda;XXX XXX XXX
249;SD;Sudan 249;SD;Sudan;XX XXX XXXX
248;SC;Seychelles 248;SC;Seychelles;X XX XX XX
247;SH;Saint Helena 247;SH;Saint Helena;XXXX
246;IO;Diego Garcia 246;IO;Diego Garcia;XXX XXXX
245;GW;Guinea-Bissau 245;GW;Guinea-Bissau;XXX XXXX
244;AO;Angola 244;AO;Angola;XXX XXX XXX
243;CD;Congo (Dem. Rep.) 243;CD;Congo (Dem. Rep.);XX XXX XXXX
242;CG;Congo (Rep.) 242;CG;Congo (Rep.);XX XXX XXXX
241;GA;Gabon 241;GA;Gabon;X XX XX XX
240;GQ;Equatorial Guinea 240;GQ;Equatorial Guinea;XXX XXX XXX
239;ST;São Tomé & Príncipe 239;ST;São Tomé & Príncipe;XX XXXXX
238;CV;Cape Verde 238;CV;Cape Verde;XXX XXXX
237;CM;Cameroon 237;CM;Cameroon;XXXX XXXX
236;CF;Central African Rep. 236;CF;Central African Rep.;XX XX XX XX
235;TD;Chad 235;TD;Chad;XX XX XX XX
234;NG;Nigeria 234;NG;Nigeria
233;GH;Ghana 233;GH;Ghana
232;SL;Sierra Leone 232;SL;Sierra Leone;XX XXX XXX
231;LR;Liberia 231;LR;Liberia
230;MU;Mauritius 230;MU;Mauritius
229;BJ;Benin 229;BJ;Benin;XX XXX XXX
228;TG;Togo 228;TG;Togo;XX XXX XXX
227;NE;Niger 227;NE;Niger;XX XX XX XX
226;BF;Burkina Faso 226;BF;Burkina Faso;XX XX XX XX
225;CI;Côte d`Ivoire 225;CI;Côte d`Ivoire;XX XXX XXX
224;GN;Guinea 224;GN;Guinea;XXX XXX XXX
223;ML;Mali 223;ML;Mali;XXXX XXXX
222;MR;Mauritania 222;MR;Mauritania;XXXX XXXX
221;SN;Senegal 221;SN;Senegal;XX XXX XXXX
220;GM;Gambia 220;GM;Gambia;XXX XXXX
218;LY;Libya 218;LY;Libya;XX XXX XXXX
216;TN;Tunisia 216;TN;Tunisia;XX XXX XXX
213;DZ;Algeria 213;DZ;Algeria;XXX XX XX XX
212;MA;Morocco 212;MA;Morocco;XX XXX XXXX
211;SS;South Sudan 211;SS;South Sudan;XX XXX XXXX
98;IR;Iran 98;IR;Iran;XXX XXX XXXX
95;MM;Myanmar 95;MM;Myanmar
94;LK;Sri Lanka 94;LK;Sri Lanka;XX XXX XXXX
93;AF;Afghanistan 93;AF;Afghanistan;XXX XXX XXX
92;PK;Pakistan 92;PK;Pakistan;XXX XXX XXXX
91;IN;India 91;IN;India;XXXXX XXXXX
90;TR;Turkey 90;TR;Turkey;XXX XXX XXXX
86;CN;China 86;CN;China;XXX XXXX XXXX
84;VN;Vietnam 84;VN;Vietnam
82;KR;South Korea 82;KR;South Korea
81;JP;Japan 81;JP;Japan;XX XXXX XXXX
66;TH;Thailand 66;TH;Thailand;X XXXX XXXX
65;SG;Singapore 65;SG;Singapore;XXXX XXXX
64;NZ;New Zealand 64;NZ;New Zealand
63;PH;Philippines 63;PH;Philippines;XXX XXX XXXX
62;ID;Indonesia 62;ID;Indonesia
61;AU;Australia 61;AU;Australia;XXX XXX XXX
60;MY;Malaysia 60;MY;Malaysia
58;VE;Venezuela 58;VE;Venezuela;XXX XXX XXXX
57;CO;Colombia 57;CO;Colombia;XXX XXX XXXX
56;CL;Chile 56;CL;Chile;X XXXX XXXX
55;BR;Brazil 55;BR;Brazil;XX XXXXX XXXX
54;AR;Argentina 54;AR;Argentina
53;CU;Cuba 53;CU;Cuba;XXXX XXXX
52;MX;Mexico 52;MX;Mexico
51;PE;Peru 51;PE;Peru;XXX XXX XXX
49;DE;Germany 49;DE;Germany
48;PL;Poland 48;PL;Poland;XX XXX XXXX
47;NO;Norway 47;NO;Norway;XXXX XXXX
46;SE;Sweden 46;SE;Sweden;XX XXX XXXX
45;DK;Denmark 45;DK;Denmark;XXXX XXXX
44;GB;United Kingdom 44;GB;United Kingdom;XXXX XXXXXX
43;AT;Austria 43;AT;Austria
42;YL;Y-land 42;YL;Y-land
41;CH;Switzerland 41;CH;Switzerland;XX XXX XXXX
40;RO;Romania 40;RO;Romania;XXX XXX XXX
39;IT;Italy 39;IT;Italy
36;HU;Hungary 36;HU;Hungary;XXX XXX XXX
34;ES;Spain 34;ES;Spain;XXX XXX XXX
33;FR;France 33;FR;France;X XX XX XX XX
32;BE;Belgium 32;BE;Belgium;XXX XX XX XX
31;NL;Netherlands 31;NL;Netherlands;X XX XX XX XX
30;GR;Greece 30;GR;Greece;XXX XXX XXXX
27;ZA;South Africa 27;ZA;South Africa;XX XXX XXXX
20;EG;Egypt 20;EG;Egypt;XX XXXX XXXX
7;KZ;Kazakhstan 7;KZ;Kazakhstan;XXX XXX XX XX
7;RU;Russian Federation 7;RU;Russian Federation;XXX XXX XXXX
1;PR;Puerto Rico 1;PR;Puerto Rico;XXX XXX XXXX
1;DO;Dominican Rep. 1;DO;Dominican Rep.;XXX XXX XXXX
1;CA;Canada 1;CA;Canada;XXX XXX XXXX
1;US;USA 1;US;USA;XXX XXX XXXX
\ No newline at end of file \ No newline at end of file
...@@ -75,6 +75,7 @@ import java.util.ArrayList; ...@@ -75,6 +75,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Locale; import java.util.Locale;
import java.util.regex.Pattern;
public class AndroidUtilities { public class AndroidUtilities {
...@@ -93,6 +94,36 @@ public class AndroidUtilities { ...@@ -93,6 +94,36 @@ public class AndroidUtilities {
private static Boolean isTablet = null; private static Boolean isTablet = null;
private static int adjustOwnerClassGuid = 0; private static int adjustOwnerClassGuid = 0;
public static Pattern WEB_URL = null;
static {
try {
final String GOOD_IRI_CHAR = "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
final Pattern IP_ADDRESS = Pattern.compile(
"((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ "|[1-9][0-9]|[0-9]))");
final String IRI = "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}";
final String GOOD_GTLD_CHAR = "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}";
final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;
final Pattern DOMAIN_NAME = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");
WEB_URL = Pattern.compile(
"((?:(http|https|Http|Https):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ "(?:" + DOMAIN_NAME + ")"
+ "(?:\\:\\d{1,5})?)" // plus option port number
+ "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
+ "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
+ "(?:\\b|$)");
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
static { static {
density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
leftBaseline = isTablet() ? 80 : 72; leftBaseline = isTablet() ? 80 : 72;
...@@ -735,7 +766,7 @@ public class AndroidUtilities { ...@@ -735,7 +766,7 @@ public class AndroidUtilities {
}*/ }*/
public static void checkForCrashes(Activity context) { public static void checkForCrashes(Activity context) {
CrashManager.register(context, BuildVars.HOCKEY_APP_HASH, new CrashManagerListener() { CrashManager.register(context, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH, new CrashManagerListener() {
@Override @Override
public boolean includeDeviceData() { public boolean includeDeviceData() {
return true; return true;
...@@ -745,7 +776,7 @@ public class AndroidUtilities { ...@@ -745,7 +776,7 @@ public class AndroidUtilities {
public static void checkForUpdates(Activity context) { public static void checkForUpdates(Activity context) {
if (BuildVars.DEBUG_VERSION) { if (BuildVars.DEBUG_VERSION) {
UpdateManager.register(context, BuildVars.HOCKEY_APP_HASH); UpdateManager.register(context, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH);
} }
} }
......
...@@ -327,8 +327,11 @@ public class ApplicationLoader extends Application { ...@@ -327,8 +327,11 @@ public class ApplicationLoader extends Application {
} }
private void initPlayServices() { private void initPlayServices() {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (checkPlayServices()) { if (checkPlayServices()) {
gcm = GoogleCloudMessaging.getInstance(this); gcm = GoogleCloudMessaging.getInstance(ApplicationLoader.this);
regid = getRegistrationId(); regid = getRegistrationId();
if (regid.length() == 0) { if (regid.length() == 0) {
...@@ -340,6 +343,8 @@ public class ApplicationLoader extends Application { ...@@ -340,6 +343,8 @@ public class ApplicationLoader extends Application {
FileLog.d("tmessages", "No valid Google Play Services APK found."); FileLog.d("tmessages", "No valid Google Play Services APK found.");
} }
} }
}, 1000);
}
private boolean checkPlayServices() { private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
......
...@@ -21,6 +21,6 @@ public class AutoMessageHeardReceiver extends BroadcastReceiver { ...@@ -21,6 +21,6 @@ public class AutoMessageHeardReceiver extends BroadcastReceiver {
if (dialog_id == 0 || max_id == 0) { if (dialog_id == 0 || max_id == 0) {
return; return;
} }
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false); MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
} }
} }
...@@ -32,6 +32,6 @@ public class AutoMessageReplyReceiver extends BroadcastReceiver { ...@@ -32,6 +32,6 @@ public class AutoMessageReplyReceiver extends BroadcastReceiver {
return; return;
} }
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false); SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false);
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false); MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
} }
} }
...@@ -10,10 +10,11 @@ package org.telegram.messenger; ...@@ -10,10 +10,11 @@ package org.telegram.messenger;
public class BuildVars { public class BuildVars {
public static boolean DEBUG_VERSION = false; public static boolean DEBUG_VERSION = false;
public static int BUILD_VERSION = 654; public static int BUILD_VERSION = 685;
public static int APP_ID = 0; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id public static int APP_ID = 0; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id
public static String APP_HASH = ""; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id public static String APP_HASH = ""; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id
public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here"; public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here";
public static String HOCKEY_APP_HASH_DEBUG = "your-hockeyapp-api-key-here";
public static String GCM_SENDER_ID = "760348033672"; public static String GCM_SENDER_ID = "760348033672";
public static String SEND_LOGS_EMAIL = "email@gmail.com"; public static String SEND_LOGS_EMAIL = "email@gmail.com";
public static String BING_SEARCH_KEY = ""; //obtain your own KEY at https://www.bing.com/dev/en-us/dev-center public static String BING_SEARCH_KEY = ""; //obtain your own KEY at https://www.bing.com/dev/en-us/dev-center
......
...@@ -16,17 +16,18 @@ public class ChatObject { ...@@ -16,17 +16,18 @@ public class ChatObject {
public static final int CHAT_TYPE_BROADCAST = 1; public static final int CHAT_TYPE_BROADCAST = 1;
public static final int CHAT_TYPE_CHANNEL = 2; public static final int CHAT_TYPE_CHANNEL = 2;
public static final int CHAT_TYPE_USER = 3; public static final int CHAT_TYPE_USER = 3;
public static final int CHAT_TYPE_MEGAGROUP = 4;
public static boolean isLeftFromChat(TLRPC.Chat chat) { public static boolean isLeftFromChat(TLRPC.Chat chat) {
return chat == null || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || (chat.flags & TLRPC.CHAT_FLAG_USER_LEFT) != 0; return chat == null || chat instanceof TLRPC.TL_chatEmpty || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || chat.left || chat.deactivated;
} }
public static boolean isKickedFromChat(TLRPC.Chat chat) { public static boolean isKickedFromChat(TLRPC.Chat chat) {
return chat == null || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || (chat.flags & TLRPC.CHAT_FLAG_USER_KICKED) != 0; return chat == null || chat instanceof TLRPC.TL_chatEmpty || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || chat.kicked || chat.deactivated;
} }
public static boolean isNotInChat(TLRPC.Chat chat) { public static boolean isNotInChat(TLRPC.Chat chat) {
return chat == null || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || (chat.flags & TLRPC.CHAT_FLAG_USER_LEFT) != 0 || (chat.flags & TLRPC.CHAT_FLAG_USER_KICKED) != 0; return chat == null || chat instanceof TLRPC.TL_chatEmpty || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || chat.left || chat.kicked || chat.deactivated;
} }
public static boolean isChannel(TLRPC.Chat chat) { public static boolean isChannel(TLRPC.Chat chat) {
...@@ -40,11 +41,11 @@ public class ChatObject { ...@@ -40,11 +41,11 @@ public class ChatObject {
public static boolean isCanWriteToChannel(int chatId) { public static boolean isCanWriteToChannel(int chatId) {
TLRPC.Chat chat = MessagesController.getInstance().getChat(chatId); TLRPC.Chat chat = MessagesController.getInstance().getChat(chatId);
return chat != null && ((chat.flags & TLRPC.CHAT_FLAG_ADMIN) != 0 || (chat.flags & TLRPC.CHAT_FLAG_USER_IS_EDITOR) != 0); return chat != null && (chat.creator || chat.editor || chat.megagroup);
} }
public static boolean canWriteToChat(TLRPC.Chat chat) { public static boolean canWriteToChat(TLRPC.Chat chat) {
return !isChannel(chat) || (chat.flags & TLRPC.CHAT_FLAG_ADMIN) != 0 || (chat.flags & TLRPC.CHAT_FLAG_USER_IS_EDITOR) != 0 || (chat.flags & TLRPC.CHAT_FLAG_IS_BROADCAST) == 0; return !isChannel(chat) || chat.creator || chat.editor || !chat.broadcast;
} }
public static TLRPC.Chat getChatByDialog(long did) { public static TLRPC.Chat getChatByDialog(long did) {
......
...@@ -208,8 +208,8 @@ public class ContactsController { ...@@ -208,8 +208,8 @@ public class ContactsController {
try { try {
accounts = am.getAccountsByType("org.telegram.account"); accounts = am.getAccountsByType("org.telegram.account");
if (accounts != null && accounts.length > 0) { if (accounts != null && accounts.length > 0) {
for (Account c : accounts) { for (int a = 0; a < accounts.length; a++) {
am.removeAccount(c, null, null); am.removeAccount(accounts[a], null, null);
} }
} }
} catch (Exception e) { } catch (Exception e) {
...@@ -221,7 +221,7 @@ public class ContactsController { ...@@ -221,7 +221,7 @@ public class ContactsController {
if (UserConfig.isClientActivated()) { if (UserConfig.isClientActivated()) {
if (accounts.length == 1) { if (accounts.length == 1) {
Account acc = accounts[0]; Account acc = accounts[0];
if (!acc.name.equals(UserConfig.getCurrentUser().phone)) { if (!acc.name.equals("" + UserConfig.getClientUserId())) {
recreateAccount = true; recreateAccount = true;
} else { } else {
currentAccount = acc; currentAccount = acc;
...@@ -236,12 +236,16 @@ public class ContactsController { ...@@ -236,12 +236,16 @@ public class ContactsController {
} }
} }
if (recreateAccount) { if (recreateAccount) {
for (Account c : accounts) { try {
am.removeAccount(c, null, null); for (int a = 0; a < accounts.length; a++) {
am.removeAccount(accounts[a], null, null);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
if (UserConfig.isClientActivated()) { if (UserConfig.isClientActivated()) {
try { try {
currentAccount = new Account(UserConfig.getCurrentUser().phone, "org.telegram.messenger"); currentAccount = new Account("" + UserConfig.getClientUserId(), "org.telegram.messenger");
am.addAccountExplicitly(currentAccount, "", null); am.addAccountExplicitly(currentAccount, "", null);
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
...@@ -254,8 +258,8 @@ public class ContactsController { ...@@ -254,8 +258,8 @@ public class ContactsController {
try { try {
AccountManager am = AccountManager.get(ApplicationLoader.applicationContext); AccountManager am = AccountManager.get(ApplicationLoader.applicationContext);
Account[] accounts = am.getAccountsByType("org.telegram.messenger"); Account[] accounts = am.getAccountsByType("org.telegram.messenger");
for (Account c : accounts) { for (int a = 0; a < accounts.length; a++) {
am.removeAccount(c, null, null); am.removeAccount(accounts[a], null, null);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
...@@ -277,7 +281,7 @@ public class ContactsController { ...@@ -277,7 +281,7 @@ public class ContactsController {
private boolean checkContactsInternal() { private boolean checkContactsInternal() {
boolean reload = false; boolean reload = false;
try { try {
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { if (!hasContactsPermission()) {
return false; return false;
} }
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver(); ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
...@@ -334,7 +338,7 @@ public class ContactsController { ...@@ -334,7 +338,7 @@ public class ContactsController {
private HashMap<Integer, Contact> readContactsFromPhoneBook() { private HashMap<Integer, Contact> readContactsFromPhoneBook() {
HashMap<Integer, Contact> contactsMap = new HashMap<>(); HashMap<Integer, Contact> contactsMap = new HashMap<>();
try { try {
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { if (!hasContactsPermission()) {
return contactsMap; return contactsMap;
} }
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver(); ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
...@@ -1044,7 +1048,7 @@ public class ContactsController { ...@@ -1044,7 +1048,7 @@ public class ContactsController {
sortedSectionsArray.add(key); sortedSectionsArray.add(key);
} }
arr.add(value); arr.add(value);
if ((user.flags & TLRPC.USER_FLAG_MUTUAL_CONTACT) != 0) { if (user.mutual_contact) {
arr = sectionsDictMutual.get(key); arr = sectionsDictMutual.get(key);
if (arr == null) { if (arr == null) {
arr = new ArrayList<>(); arr = new ArrayList<>();
...@@ -1280,9 +1284,34 @@ public class ContactsController { ...@@ -1280,9 +1284,34 @@ public class ContactsController {
sortedUsersSectionsArray = sortedSectionsArray; sortedUsersSectionsArray = sortedSectionsArray;
} }
private boolean hasContactsPermission() {
if (Build.VERSION.SDK_INT >= 23) {
return ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
}
Cursor cursor = null;
try {
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projectionPhones, null, null, null);
if (cursor == null || cursor.getCount() == 0) {
return false;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
try {
if (cursor != null) {
cursor.close();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
return true;
}
private void performWriteContactsToPhoneBookInternal(ArrayList<TLRPC.TL_contact> contactsArray) { private void performWriteContactsToPhoneBookInternal(ArrayList<TLRPC.TL_contact> contactsArray) {
try { try {
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { if (!hasContactsPermission()) {
return; return;
} }
Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, currentAccount.name).appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, currentAccount.type).build(); Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, currentAccount.name).appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, currentAccount.type).build();
...@@ -1294,7 +1323,8 @@ public class ContactsController { ...@@ -1294,7 +1323,8 @@ public class ContactsController {
} }
c1.close(); c1.close();
for (TLRPC.TL_contact u : contactsArray) { for (int a = 0; a < contactsArray.size(); a++) {
TLRPC.TL_contact u = contactsArray.get(a);
if (!bookContacts.containsKey(u.user_id)) { if (!bookContacts.containsKey(u.user_id)) {
TLRPC.User user = MessagesController.getInstance().getUser(u.user_id); TLRPC.User user = MessagesController.getInstance().getUser(u.user_id);
addContactToPhoneBook(user, false); addContactToPhoneBook(user, false);
...@@ -1486,7 +1516,7 @@ public class ContactsController { ...@@ -1486,7 +1516,7 @@ public class ContactsController {
if (currentAccount == null || user == null || user.phone == null || user.phone.length() == 0) { if (currentAccount == null || user == null || user.phone == null || user.phone.length() == 0) {
return -1; return -1;
} }
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { if (!hasContactsPermission()) {
return -1; return -1;
} }
long res = -1; long res = -1;
...@@ -1536,7 +1566,9 @@ public class ContactsController { ...@@ -1536,7 +1566,9 @@ public class ContactsController {
query.add(builder.build()); query.add(builder.build());
try { try {
ContentProviderResult[] result = contentResolver.applyBatch(ContactsContract.AUTHORITY, query); ContentProviderResult[] result = contentResolver.applyBatch(ContactsContract.AUTHORITY, query);
if (result != null && result.length > 0 && result[0].uri != null) {
res = Long.parseLong(result[0].uri.getLastPathSegment()); res = Long.parseLong(result[0].uri.getLastPathSegment());
}
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
...@@ -1547,7 +1579,7 @@ public class ContactsController { ...@@ -1547,7 +1579,7 @@ public class ContactsController {
} }
private void deleteContactFromPhoneBook(int uid) { private void deleteContactFromPhoneBook(int uid) {
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { if (!hasContactsPermission()) {
return; return;
} }
synchronized (observerLock) { synchronized (observerLock) {
......
...@@ -12,9 +12,12 @@ import android.os.Handler; ...@@ -12,9 +12,12 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import java.util.concurrent.CountDownLatch;
public class DispatchQueue extends Thread { public class DispatchQueue extends Thread {
public volatile Handler handler = null;
private final Object handlerSyncObject = new Object(); private volatile Handler handler = null;
private CountDownLatch syncLatch = new CountDownLatch(1);
public DispatchQueue(final String threadName) { public DispatchQueue(final String threadName) {
setName(threadName); setName(threadName);
...@@ -22,40 +25,24 @@ public class DispatchQueue extends Thread { ...@@ -22,40 +25,24 @@ public class DispatchQueue extends Thread {
} }
private void sendMessage(Message msg, int delay) { private void sendMessage(Message msg, int delay) {
if (handler == null) {
try { try {
synchronized (handlerSyncObject) { syncLatch.await();
handlerSyncObject.wait();
}
} catch (Throwable t) {
t.printStackTrace();
}
}
if (handler != null) {
if (delay <= 0) { if (delay <= 0) {
handler.sendMessage(msg); handler.sendMessage(msg);
} else { } else {
handler.sendMessageDelayed(msg, delay); handler.sendMessageDelayed(msg, delay);
} }
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
} }
public void cancelRunnable(Runnable runnable) { public void cancelRunnable(Runnable runnable) {
if (handler == null) {
synchronized (handlerSyncObject) {
if (handler == null) {
try { try {
handlerSyncObject.wait(); syncLatch.await();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
if (handler != null) {
handler.removeCallbacks(runnable); handler.removeCallbacks(runnable);
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
} }
...@@ -64,39 +51,32 @@ public class DispatchQueue extends Thread { ...@@ -64,39 +51,32 @@ public class DispatchQueue extends Thread {
} }
public void postRunnable(Runnable runnable, long delay) { public void postRunnable(Runnable runnable, long delay) {
if (handler == null) {
synchronized (handlerSyncObject) {
if (handler == null) {
try { try {
handlerSyncObject.wait(); syncLatch.await();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
if (handler != null) {
if (delay <= 0) { if (delay <= 0) {
handler.post(runnable); handler.post(runnable);
} else { } else {
handler.postDelayed(runnable, delay); handler.postDelayed(runnable, delay);
} }
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
} }
public void cleanupQueue() { public void cleanupQueue() {
if (handler != null) { try {
syncLatch.await();
handler.removeCallbacksAndMessages(null); handler.removeCallbacksAndMessages(null);
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
} }
@Override
public void run() { public void run() {
Looper.prepare(); Looper.prepare();
synchronized (handlerSyncObject) {
handler = new Handler(); handler = new Handler();
handlerSyncObject.notify(); syncLatch.countDown();
}
Looper.loop(); Looper.loop();
} }
} }
...@@ -266,10 +266,7 @@ public class Emoji { ...@@ -266,10 +266,7 @@ public class Emoji {
} }
if (!canvas.quickReject(b.left, b.top, b.right, b.bottom, Canvas.EdgeType.AA)) { if (!canvas.quickReject(b.left, b.top, b.right, b.bottom, Canvas.EdgeType.AA)) {
canvas.save(); canvas.drawBitmap(emojiBmp[info.page][info.page2], info.rect, b, paint);
canvas.clipRect(b);
canvas.drawBitmap(emojiBmp[info.page][info.page2], info.rect, b, fullSize ? null : paint);
canvas.restore();
} }
} }
......
...@@ -468,7 +468,7 @@ public class FileLoadOperation { ...@@ -468,7 +468,7 @@ public class FileLoadOperation {
delegate.didFailedLoadingFile(FileLoadOperation.this, 2); delegate.didFailedLoadingFile(FileLoadOperation.this, 2);
} else { } else {
if (location != null) { if (location != null) {
FileLog.e("tmessages", "" + location + " id = " + location.id + " access_hash = " + location.access_hash + " volume_id = " + location.local_id + " secret = " + location.secret); FileLog.e("tmessages", "" + location + " id = " + location.id + " local_id = " + location.local_id + " access_hash = " + location.access_hash + " volume_id = " + location.volume_id + " secret = " + location.secret);
} }
cleanup(); cleanup();
delegate.didFailedLoadingFile(FileLoadOperation.this, 0); delegate.didFailedLoadingFile(FileLoadOperation.this, 0);
......
...@@ -753,7 +753,8 @@ public class FileLoader { ...@@ -753,7 +753,8 @@ public class FileLoader {
fileLoaderQueue.postRunnable(new Runnable() { fileLoaderQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
for (File file : files) { for (int a = 0; a < files.size(); a++) {
File file = files.get(a);
if (file.exists()) { if (file.exists()) {
try { try {
if (!file.delete()) { if (!file.delete()) {
...@@ -763,6 +764,16 @@ public class FileLoader { ...@@ -763,6 +764,16 @@ public class FileLoader {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
} }
try {
File qFile = new File(file.getPath(), "q_" + file.getName());
if (qFile.exists()) {
if (!file.delete()) {
file.deleteOnExit();
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
} }
} }
}); });
......
...@@ -67,6 +67,9 @@ public class FileLog { ...@@ -67,6 +67,9 @@ public class FileLog {
} }
public static String getNetworkLogPath() { public static String getNetworkLogPath() {
if (!BuildVars.DEBUG_VERSION) {
return "";
}
try { try {
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null); File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
if (sdCard == null) { if (sdCard == null) {
......
...@@ -75,7 +75,7 @@ public class ImageLoader { ...@@ -75,7 +75,7 @@ public class ImageLoader {
private HashMap<String, Runnable> retryHttpsTasks = new HashMap<>(); private HashMap<String, Runnable> retryHttpsTasks = new HashMap<>();
private int currentHttpFileLoadTasksCount = 0; private int currentHttpFileLoadTasksCount = 0;
protected VMRuntimeHack runtimeHack = null; public VMRuntimeHack runtimeHack = null;
private String ignoreRemoval = null; private String ignoreRemoval = null;
private volatile long lastCacheOutTime = 0; private volatile long lastCacheOutTime = 0;
...@@ -1162,7 +1162,18 @@ public class ImageLoader { ...@@ -1162,7 +1162,18 @@ public class ImageLoader {
FileLog.e("tmessages", "file system changed"); FileLog.e("tmessages", "file system changed");
Runnable r = new Runnable() { Runnable r = new Runnable() {
public void run() { public void run() {
FileLoader.getInstance().setMediaDirs(createMediaPaths()); cacheOutQueue.postRunnable(new Runnable() {
@Override
public void run() {
final HashMap<Integer, File> paths = createMediaPaths();
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
FileLoader.getInstance().setMediaDirs(paths);
}
});
}
});
} }
}; };
if (Intent.ACTION_MEDIA_UNMOUNTED.equals(intent.getAction())) { if (Intent.ACTION_MEDIA_UNMOUNTED.equals(intent.getAction())) {
...@@ -1186,7 +1197,35 @@ public class ImageLoader { ...@@ -1186,7 +1197,35 @@ public class ImageLoader {
filter.addDataScheme("file"); filter.addDataScheme("file");
ApplicationLoader.applicationContext.registerReceiver(receiver, filter); ApplicationLoader.applicationContext.registerReceiver(receiver, filter);
FileLoader.getInstance().setMediaDirs(createMediaPaths()); HashMap<Integer, File> mediaDirs = new HashMap<>();
File cachePath = AndroidUtilities.getCacheDir();
if (!cachePath.isDirectory()) {
try {
cachePath.mkdirs();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
try {
new File(cachePath, ".nomedia").createNewFile();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
FileLoader.getInstance().setMediaDirs(mediaDirs);
cacheOutQueue.postRunnable(new Runnable() {
@Override
public void run() {
final HashMap<Integer, File> paths = createMediaPaths();
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
FileLoader.getInstance().setMediaDirs(paths);
}
});
}
});
} }
public HashMap<Integer, File> createMediaPaths() { public HashMap<Integer, File> createMediaPaths() {
......
...@@ -46,14 +46,14 @@ public class LocaleController { ...@@ -46,14 +46,14 @@ public class LocaleController {
public static boolean isRTL = false; public static boolean isRTL = false;
public static int nameDisplayOrder = 1; public static int nameDisplayOrder = 1;
private static boolean is24HourFormat = false; private static boolean is24HourFormat = false;
public static FastDateFormat formatterDay; public FastDateFormat formatterDay;
public static FastDateFormat formatterWeek; public FastDateFormat formatterWeek;
public static FastDateFormat formatterMonth; public FastDateFormat formatterMonth;
public static FastDateFormat formatterYear; public FastDateFormat formatterYear;
public static FastDateFormat formatterMonthYear; public FastDateFormat formatterMonthYear;
public static FastDateFormat formatterYearMax; public FastDateFormat formatterYearMax;
public static FastDateFormat chatDate; public FastDateFormat chatDate;
public static FastDateFormat chatFullDate; public FastDateFormat chatFullDate;
private HashMap<String, PluralRules> allRules = new HashMap<>(); private HashMap<String, PluralRules> allRules = new HashMap<>();
...@@ -671,9 +671,9 @@ public class LocaleController { ...@@ -671,9 +671,9 @@ public class LocaleController {
int dateYear = rightNow.get(Calendar.YEAR); int dateYear = rightNow.get(Calendar.YEAR);
if (year == dateYear) { if (year == dateYear) {
return chatDate.format(date * 1000); return getInstance().chatDate.format(date * 1000);
} }
return chatFullDate.format(date * 1000); return getInstance().chatFullDate.format(date * 1000);
} }
public static String formatDate(long date) { public static String formatDate(long date) {
...@@ -686,13 +686,13 @@ public class LocaleController { ...@@ -686,13 +686,13 @@ public class LocaleController {
int dateYear = rightNow.get(Calendar.YEAR); int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) { if (dateDay == day && year == dateYear) {
return formatterDay.format(new Date(date * 1000)); return getInstance().formatterDay.format(new Date(date * 1000));
} else if (dateDay + 1 == day && year == dateYear) { } else if (dateDay + 1 == day && year == dateYear) {
return getString("Yesterday", R.string.Yesterday); return getString("Yesterday", R.string.Yesterday);
} else if (year == dateYear) { } else if (year == dateYear) {
return formatterMonth.format(new Date(date * 1000)); return getInstance().formatterMonth.format(new Date(date * 1000));
} else { } else {
return formatterYear.format(new Date(date * 1000)); return getInstance().formatterYear.format(new Date(date * 1000));
} }
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
...@@ -710,7 +710,7 @@ public class LocaleController { ...@@ -710,7 +710,7 @@ public class LocaleController {
int dateYear = rightNow.get(Calendar.YEAR); int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) { if (dateDay == day && year == dateYear) {
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("TodayAt", R.string.TodayAt), formatterDay.format(new Date(date * 1000))); return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("TodayAt", R.string.TodayAt), getInstance().formatterDay.format(new Date(date * 1000)));
/*int diff = (int) (ConnectionsManager.getInstance().getCurrentTime() - date) / 60; /*int diff = (int) (ConnectionsManager.getInstance().getCurrentTime() - date) / 60;
if (diff < 1) { if (diff < 1) {
return LocaleController.getString("LastSeenNow", R.string.LastSeenNow); return LocaleController.getString("LastSeenNow", R.string.LastSeenNow);
...@@ -720,12 +720,12 @@ public class LocaleController { ...@@ -720,12 +720,12 @@ public class LocaleController {
return LocaleController.formatPluralString("LastSeenHours", (int) Math.ceil(diff / 60.0f)); return LocaleController.formatPluralString("LastSeenHours", (int) Math.ceil(diff / 60.0f));
}*/ }*/
} else if (dateDay + 1 == day && year == dateYear) { } else if (dateDay + 1 == day && year == dateYear) {
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("YesterdayAt", R.string.YesterdayAt), formatterDay.format(new Date(date * 1000))); return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("YesterdayAt", R.string.YesterdayAt), getInstance().formatterDay.format(new Date(date * 1000)));
} else if (year == dateYear) { } else if (year == dateYear) {
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, formatterMonth.format(new Date(date * 1000)), formatterDay.format(new Date(date * 1000))); String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterMonth.format(new Date(date * 1000)), getInstance().formatterDay.format(new Date(date * 1000)));
return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format); return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format);
} else { } else {
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, formatterYear.format(new Date(date * 1000)), formatterDay.format(new Date(date * 1000))); String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterYear.format(new Date(date * 1000)), getInstance().formatterDay.format(new Date(date * 1000)));
return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format); return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format);
} }
} catch (Exception e) { } catch (Exception e) {
...@@ -780,15 +780,15 @@ public class LocaleController { ...@@ -780,15 +780,15 @@ public class LocaleController {
int dateYear = rightNow.get(Calendar.YEAR); int dateYear = rightNow.get(Calendar.YEAR);
if (year != dateYear) { if (year != dateYear) {
return formatterYear.format(new Date(date * 1000)); return getInstance().formatterYear.format(new Date(date * 1000));
} else { } else {
int dayDiff = dateDay - day; int dayDiff = dateDay - day;
if(dayDiff == 0 || dayDiff == -1 && (int)(System.currentTimeMillis() / 1000) - date < 60 * 60 * 8) { if(dayDiff == 0 || dayDiff == -1 && (int)(System.currentTimeMillis() / 1000) - date < 60 * 60 * 8) {
return formatterDay.format(new Date(date * 1000)); return getInstance().formatterDay.format(new Date(date * 1000));
} else if(dayDiff > -7 && dayDiff <= -1) { } else if(dayDiff > -7 && dayDiff <= -1) {
return formatterWeek.format(new Date(date * 1000)); return getInstance().formatterWeek.format(new Date(date * 1000));
} else { } else {
return formatterMonth.format(new Date(date * 1000)); return getInstance().formatterMonth.format(new Date(date * 1000));
} }
} }
} catch (Exception e) { } catch (Exception e) {
......
...@@ -542,13 +542,18 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -542,13 +542,18 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
shuffleMusic = preferences.getBoolean("shuffleMusic", false); shuffleMusic = preferences.getBoolean("shuffleMusic", false);
repeatMode = preferences.getInt("repeatMode", 0); repeatMode = preferences.getInt("repeatMode", 0);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad); AndroidUtilities.runOnUIThread(new Runnable() {
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidLoaded); @Override
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileLoadProgressChanged); public void run() {
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileUploadProgressChanged); NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileDidFailedLoad);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesDeleted); NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileDidLoaded);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.removeAllMessagesFromDialog); NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileLoadProgressChanged);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.musicDidLoaded); NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileUploadProgressChanged);
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.messagesDeleted);
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.removeAllMessagesFromDialog);
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.musicDidLoaded);
}
});
BroadcastReceiver networkStateReceiver = new BroadcastReceiver() { BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
@Override @Override
...@@ -1117,7 +1122,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -1117,7 +1122,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
try { try {
ArrayList<SendMessagesHelper.DelayedMessage> delayedMessages = SendMessagesHelper.getInstance().getDelayedMessages(fileName); ArrayList<SendMessagesHelper.DelayedMessage> delayedMessages = SendMessagesHelper.getInstance().getDelayedMessages(fileName);
if (delayedMessages != null) { if (delayedMessages != null) {
for (SendMessagesHelper.DelayedMessage delayedMessage : delayedMessages) { for (int a = 0; a < delayedMessages.size(); a++) {
SendMessagesHelper.DelayedMessage delayedMessage = delayedMessages.get(a);
if (delayedMessage.encryptedChat == null) { if (delayedMessage.encryptedChat == null) {
long dialog_id = delayedMessage.obj.getDialogId(); long dialog_id = delayedMessage.obj.getDialogId();
Long lastTime = typingTimes.get(dialog_id); Long lastTime = typingTimes.get(dialog_id);
...@@ -2477,7 +2483,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -2477,7 +2483,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
Cursor cursor = null; Cursor cursor = null;
try { try {
if (Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projectionPhotos, "", null, MediaStore.Images.Media.DATE_TAKEN + " DESC"); cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projectionPhotos, null, null, MediaStore.Images.Media.DATE_TAKEN + " DESC");
if (cursor != null) { if (cursor != null) {
int imageIdColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID); int imageIdColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID);
int bucketIdColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID); int bucketIdColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID);
...@@ -2540,7 +2546,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -2540,7 +2546,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
if (Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
albums.clear(); albums.clear();
AlbumEntry allVideosAlbum = null; AlbumEntry allVideosAlbum = null;
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projectionVideo, "", null, MediaStore.Video.Media.DATE_TAKEN + " DESC"); cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projectionVideo, null, null, MediaStore.Video.Media.DATE_TAKEN + " DESC");
if (cursor != null) { if (cursor != null) {
int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID); int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID);
int bucketIdColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID); int bucketIdColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
package org.telegram.messenger; package org.telegram.messenger;
import android.app.Activity; import android.app.Activity;
import android.net.Uri;
import android.util.Log; import android.util.Log;
import net.hockeyapp.android.Constants; import net.hockeyapp.android.Constants;
import net.hockeyapp.android.utils.SimpleMultipartEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date; import java.util.Date;
import java.util.UUID; import java.util.UUID;
...@@ -24,7 +25,7 @@ public class NativeCrashManager { ...@@ -24,7 +25,7 @@ public class NativeCrashManager {
for (String dumpFilename : filenames) { for (String dumpFilename : filenames) {
String logFilename = createLogFile(); String logFilename = createLogFile();
if (logFilename != null) { if (logFilename != null) {
uploadDumpAndLog(activity, BuildVars.HOCKEY_APP_HASH, dumpFilename, logFilename); uploadDumpAndLog(activity, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH, dumpFilename, logFilename);
} }
} }
} }
...@@ -61,17 +62,29 @@ public class NativeCrashManager { ...@@ -61,17 +62,29 @@ public class NativeCrashManager {
@Override @Override
public void run() { public void run() {
try { try {
DefaultHttpClient httpClient = new DefaultHttpClient(); SimpleMultipartEntity entity = new SimpleMultipartEntity();
HttpPost httpPost = new HttpPost("https://rink.hockeyapp.net/api/2/apps/" + identifier + "/crashes/upload"); entity.writeFirstBoundaryIfNeeds();
MultipartEntity entity = new MultipartEntity();
File dumpFile = new File(Constants.FILES_PATH, dumpFilename); Uri attachmentUri = Uri.fromFile(new File(Constants.FILES_PATH, dumpFilename));
entity.addPart("attachment0", new FileBody(dumpFile)); InputStream input = activity.getContentResolver().openInputStream(attachmentUri);
File logFile = new File(Constants.FILES_PATH, logFilename); entity.addPart("attachment0", attachmentUri.getLastPathSegment(), input, false);
entity.addPart("log", new FileBody(logFile));
httpPost.setEntity(entity); attachmentUri = Uri.fromFile(new File(Constants.FILES_PATH, logFilename));
httpClient.execute(httpPost); input = activity.getContentResolver().openInputStream(attachmentUri);
} catch (Exception e) { entity.addPart("log", attachmentUri.getLastPathSegment(), input, false);
FileLog.e("tmessages", e);
entity.writeLastBoundaryIfNeeds();
HttpURLConnection urlConnection = (HttpURLConnection) new URL("https://rink.hockeyapp.net/api/2/apps/" + identifier + "/crashes/upload").openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", entity.getContentType());
urlConnection.setRequestProperty("Content-Length", String.valueOf(entity.getContentLength()));
urlConnection.getOutputStream().write(entity.getOutputStream().toByteArray());
urlConnection.connect();
} catch (IOException e) {
e.printStackTrace();
} finally { } finally {
activity.deleteFile(logFilename); activity.deleteFile(logFilename);
activity.deleteFile(dumpFilename); activity.deleteFile(dumpFilename);
......
...@@ -23,7 +23,7 @@ import java.util.zip.ZipFile; ...@@ -23,7 +23,7 @@ import java.util.zip.ZipFile;
public class NativeLoader { public class NativeLoader {
private final static int LIB_VERSION = 14; private final static int LIB_VERSION = 15;
private final static String LIB_NAME = "tmessages." + LIB_VERSION; private final static String LIB_NAME = "tmessages." + LIB_VERSION;
private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so"; private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so";
private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so"; private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so";
......
...@@ -80,7 +80,9 @@ public class SecretChatHelper { ...@@ -80,7 +80,9 @@ public class SecretChatHelper {
newMsg.action.encryptedAction = decryptedMessage; newMsg.action.encryptedAction = decryptedMessage;
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId(); newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
newMsg.from_id = UserConfig.getClientUserId(); newMsg.from_id = UserConfig.getClientUserId();
newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT | TLRPC.MESSAGE_FLAG_HAS_FROM_ID; newMsg.unread = true;
newMsg.out = true;
newMsg.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
newMsg.dialog_id = ((long) encryptedChat.id) << 32; newMsg.dialog_id = ((long) encryptedChat.id) << 32;
newMsg.to_id = new TLRPC.TL_peerUser(); newMsg.to_id = new TLRPC.TL_peerUser();
newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING; newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
...@@ -869,7 +871,8 @@ public class SecretChatHelper { ...@@ -869,7 +871,8 @@ public class SecretChatHelper {
newMessage.to_id = new TLRPC.TL_peerUser(); newMessage.to_id = new TLRPC.TL_peerUser();
newMessage.random_id = random_id; newMessage.random_id = random_id;
newMessage.to_id.user_id = UserConfig.getClientUserId(); newMessage.to_id.user_id = UserConfig.getClientUserId();
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_HAS_MEDIA | TLRPC.MESSAGE_FLAG_HAS_FROM_ID; newMessage.unread = true;
newMessage.flags = TLRPC.MESSAGE_FLAG_HAS_MEDIA | TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
newMessage.dialog_id = ((long) chat.id) << 32; newMessage.dialog_id = ((long) chat.id) << 32;
if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) { if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) {
newMessage.media = new TLRPC.TL_messageMediaEmpty(); newMessage.media = new TLRPC.TL_messageMediaEmpty();
...@@ -1043,7 +1046,8 @@ public class SecretChatHelper { ...@@ -1043,7 +1046,8 @@ public class SecretChatHelper {
} }
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId(); newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
UserConfig.saveConfig(false); UserConfig.saveConfig(false);
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_HAS_FROM_ID; newMessage.unread = true;
newMessage.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
newMessage.date = date; newMessage.date = date;
newMessage.from_id = from_id; newMessage.from_id = from_id;
newMessage.to_id = new TLRPC.TL_peerUser(); newMessage.to_id = new TLRPC.TL_peerUser();
......
...@@ -61,7 +61,7 @@ public class TgChooserTargetService extends ChooserTargetService { ...@@ -61,7 +61,7 @@ public class TgChooserTargetService extends ChooserTargetService {
ArrayList<Integer> usersToLoad = new ArrayList<>(); ArrayList<Integer> usersToLoad = new ArrayList<>();
usersToLoad.add(UserConfig.getClientUserId()); usersToLoad.add(UserConfig.getClientUserId());
ArrayList<Integer> chatsToLoad = new ArrayList<>(); ArrayList<Integer> chatsToLoad = new ArrayList<>();
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT did FROM dialogs ORDER BY date DESC LIMIT %d,%d", 0, 20)); SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT did FROM dialogs ORDER BY date DESC LIMIT %d,%d", 0, 30));
while (cursor.next()) { while (cursor.next()) {
long id = cursor.longValue(0); long id = cursor.longValue(0);
...@@ -109,11 +109,13 @@ public class TgChooserTargetService extends ChooserTargetService { ...@@ -109,11 +109,13 @@ public class TgChooserTargetService extends ChooserTargetService {
for (int b = 0; b < users.size(); b++) { for (int b = 0; b < users.size(); b++) {
TLRPC.User user = users.get(b); TLRPC.User user = users.get(b);
if (user.id == id) { if (user.id == id) {
if (!user.bot) {
extras.putLong("dialogId", (long) id); extras.putLong("dialogId", (long) id);
if (user.photo != null && user.photo.photo_small != null) { if (user.photo != null && user.photo.photo_small != null) {
icon = createRoundBitmap(FileLoader.getPathToAttach(user.photo.photo_small, true)); icon = createRoundBitmap(FileLoader.getPathToAttach(user.photo.photo_small, true));
} }
name = ContactsController.formatName(user.first_name, user.last_name); name = ContactsController.formatName(user.first_name, user.last_name);
}
break; break;
} }
} }
...@@ -121,11 +123,13 @@ public class TgChooserTargetService extends ChooserTargetService { ...@@ -121,11 +123,13 @@ public class TgChooserTargetService extends ChooserTargetService {
for (int b = 0; b < chats.size(); b++) { for (int b = 0; b < chats.size(); b++) {
TLRPC.Chat chat = chats.get(b); TLRPC.Chat chat = chats.get(b);
if (chat.id == -id) { if (chat.id == -id) {
if (!ChatObject.isNotInChat(chat) && (!ChatObject.isChannel(chat) || chat.megagroup)) {
extras.putLong("dialogId", (long) id); extras.putLong("dialogId", (long) id);
if (chat.photo != null && chat.photo.photo_small != null) { if (chat.photo != null && chat.photo.photo_small != null) {
icon = createRoundBitmap(FileLoader.getPathToAttach(chat.photo.photo_small, true)); icon = createRoundBitmap(FileLoader.getPathToAttach(chat.photo.photo_small, true));
} }
name = chat.title; name = chat.title;
}
break; break;
} }
} }
......
...@@ -41,7 +41,13 @@ public class UserConfig { ...@@ -41,7 +41,13 @@ public class UserConfig {
public static boolean useFingerprint = true; public static boolean useFingerprint = true;
public static int lastUpdateVersion; public static int lastUpdateVersion;
public static int lastContactsSyncTime; public static int lastContactsSyncTime;
public static boolean channelsLoaded = false;
public static int migrateOffsetId = -1;
public static int migrateOffsetDate = -1;
public static int migrateOffsetUserId = -1;
public static int migrateOffsetChatId = -1;
public static int migrateOffsetChannelId = -1;
public static long migrateOffsetAccess = -1;
public static int getNewMessageId() { public static int getNewMessageId() {
int id; int id;
...@@ -79,9 +85,17 @@ public class UserConfig { ...@@ -79,9 +85,17 @@ public class UserConfig {
editor.putInt("lastPauseTime", lastPauseTime); editor.putInt("lastPauseTime", lastPauseTime);
editor.putInt("lastUpdateVersion", lastUpdateVersion); editor.putInt("lastUpdateVersion", lastUpdateVersion);
editor.putInt("lastContactsSyncTime", lastContactsSyncTime); editor.putInt("lastContactsSyncTime", lastContactsSyncTime);
editor.putBoolean("channelsLoaded", channelsLoaded);
editor.putBoolean("useFingerprint", useFingerprint); editor.putBoolean("useFingerprint", useFingerprint);
editor.putInt("migrateOffsetId", migrateOffsetId);
if (migrateOffsetId != -1) {
editor.putInt("migrateOffsetDate", migrateOffsetDate);
editor.putInt("migrateOffsetUserId", migrateOffsetUserId);
editor.putInt("migrateOffsetChatId", migrateOffsetChatId);
editor.putInt("migrateOffsetChannelId", migrateOffsetChannelId);
editor.putLong("migrateOffsetAccess", migrateOffsetAccess);
}
if (currentUser != null) { if (currentUser != null) {
if (withFile) { if (withFile) {
SerializedData data = new SerializedData(); SerializedData data = new SerializedData();
...@@ -212,7 +226,16 @@ public class UserConfig { ...@@ -212,7 +226,16 @@ public class UserConfig {
useFingerprint = preferences.getBoolean("useFingerprint", true); useFingerprint = preferences.getBoolean("useFingerprint", true);
lastUpdateVersion = preferences.getInt("lastUpdateVersion", 511); lastUpdateVersion = preferences.getInt("lastUpdateVersion", 511);
lastContactsSyncTime = preferences.getInt("lastContactsSyncTime", (int) (System.currentTimeMillis() / 1000) - 23 * 60 * 60); lastContactsSyncTime = preferences.getInt("lastContactsSyncTime", (int) (System.currentTimeMillis() / 1000) - 23 * 60 * 60);
channelsLoaded = preferences.getBoolean("channelsLoaded", false);
migrateOffsetId = preferences.getInt("migrateOffsetId", 0);
if (migrateOffsetId != -1) {
migrateOffsetDate = preferences.getInt("migrateOffsetDate", 0);
migrateOffsetUserId = preferences.getInt("migrateOffsetUserId", 0);
migrateOffsetChatId = preferences.getInt("migrateOffsetChatId", 0);
migrateOffsetChannelId = preferences.getInt("migrateOffsetChannelId", 0);
migrateOffsetAccess = preferences.getLong("migrateOffsetAccess", 0);
}
String user = preferences.getString("user", null); String user = preferences.getString("user", null);
if (user != null) { if (user != null) {
byte[] userBytes = Base64.decode(user, Base64.DEFAULT); byte[] userBytes = Base64.decode(user, Base64.DEFAULT);
...@@ -277,7 +300,12 @@ public class UserConfig { ...@@ -277,7 +300,12 @@ public class UserConfig {
lastBroadcastId = -1; lastBroadcastId = -1;
saveIncomingPhotos = false; saveIncomingPhotos = false;
blockedUsersLoaded = false; blockedUsersLoaded = false;
channelsLoaded = false; migrateOffsetId = -1;
migrateOffsetDate = -1;
migrateOffsetUserId = -1;
migrateOffsetChatId = -1;
migrateOffsetChannelId = -1;
migrateOffsetAccess = -1;
appLocked = false; appLocked = false;
passcodeType = 0; passcodeType = 0;
passcodeHash = ""; passcodeHash = "";
......
...@@ -14,15 +14,15 @@ import org.telegram.tgnet.TLRPC; ...@@ -14,15 +14,15 @@ import org.telegram.tgnet.TLRPC;
public class UserObject { public class UserObject {
public static boolean isDeleted(TLRPC.User user) { public static boolean isDeleted(TLRPC.User user) {
return user == null || user instanceof TLRPC.TL_userDeleted_old2 || user instanceof TLRPC.TL_userEmpty || (user.flags & TLRPC.USER_FLAG_DELETED) != 0; return user == null || user instanceof TLRPC.TL_userDeleted_old2 || user instanceof TLRPC.TL_userEmpty || user.deleted;
} }
public static boolean isContact(TLRPC.User user) { public static boolean isContact(TLRPC.User user) {
return user instanceof TLRPC.TL_userContact_old2 || (user.flags & TLRPC.USER_FLAG_CONTACT) != 0 || (user.flags & TLRPC.USER_FLAG_MUTUAL_CONTACT) != 0; return user instanceof TLRPC.TL_userContact_old2 || user.contact || user.mutual_contact;
} }
public static boolean isUserSelf(TLRPC.User user) { public static boolean isUserSelf(TLRPC.User user) {
return user instanceof TLRPC.TL_userSelf_old3 || (user.flags & TLRPC.USER_FLAG_SELF) != 0; return user instanceof TLRPC.TL_userSelf_old3 || user.self;
} }
public static String getUserName(TLRPC.User user) { public static String getUserName(TLRPC.User user) {
......
...@@ -32,6 +32,6 @@ public class WearReplyReceiver extends BroadcastReceiver { ...@@ -32,6 +32,6 @@ public class WearReplyReceiver extends BroadcastReceiver {
return; return;
} }
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false); SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false);
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false); MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
} }
} }
...@@ -20,18 +20,19 @@ import org.telegram.tgnet.TLRPC; ...@@ -20,18 +20,19 @@ import org.telegram.tgnet.TLRPC;
import java.util.ArrayList; import java.util.ArrayList;
@SuppressWarnings("unchecked")
public class MessagesSearchQuery { public class MessagesSearchQuery {
private static int reqId; private static int reqId;
private static int lastReqId; private static int lastReqId;
private static boolean messagesSearchEndReached; private static boolean messagesSearchEndReached[] = new boolean[] {false, false};
private static ArrayList<MessageObject> searchResultMessages = new ArrayList<>(); private static ArrayList<MessageObject> searchResultMessages = new ArrayList<>();
private static String lastSearchQuery; private static String lastSearchQuery;
private static int lastReturnedNum; private static int lastReturnedNum;
private static int getMask() { private static int getMask() {
int mask = 0; int mask = 0;
if (lastReturnedNum < searchResultMessages.size() - 1) { if (lastReturnedNum < searchResultMessages.size() - 1 || !messagesSearchEndReached[0] || !messagesSearchEndReached[1]) {
mask |= 1; mask |= 1;
} }
if (lastReturnedNum > 0) { if (lastReturnedNum > 0) {
...@@ -40,25 +41,37 @@ public class MessagesSearchQuery { ...@@ -40,25 +41,37 @@ public class MessagesSearchQuery {
return mask; return mask;
} }
public static void searchMessagesInChat(String query, long dialog_id, final int guid, int direction) { public static void searchMessagesInChat(String query, final long dialog_id, final long mergeDialogId, final int guid, int direction) {
if (reqId != 0) { if (reqId != 0) {
ConnectionsManager.getInstance().cancelRequest(reqId, true); ConnectionsManager.getInstance().cancelRequest(reqId, true);
reqId = 0; reqId = 0;
} }
int max_id = 0; int max_id = 0;
long queryWithDialog = dialog_id;
if (query == null || query.length() == 0) { if (query == null || query.length() == 0) {
if (direction == 1) { if (direction == 1) {
lastReturnedNum++; lastReturnedNum++;
if (lastReturnedNum < searchResultMessages.size()) { if (lastReturnedNum < searchResultMessages.size()) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask()); MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId());
return; return;
} else { } else {
if (messagesSearchEndReached) { if (messagesSearchEndReached[0] && mergeDialogId == 0 || messagesSearchEndReached[1]) {
lastReturnedNum--; lastReturnedNum--;
return; return;
} }
query = lastSearchQuery; query = lastSearchQuery;
max_id = searchResultMessages.get(searchResultMessages.size() - 1).getId(); MessageObject messageObject = searchResultMessages.get(searchResultMessages.size() - 1);
if (messageObject.getDialogId() == dialog_id && !messagesSearchEndReached[0]) {
max_id = messageObject.getId();
queryWithDialog = dialog_id;
} else {
if (messageObject.getDialogId() == mergeDialogId) {
max_id = messageObject.getId();
}
queryWithDialog = mergeDialogId;
messagesSearchEndReached[1] = false;
}
} }
} else if (direction == 2) { } else if (direction == 2) {
lastReturnedNum--; lastReturnedNum--;
...@@ -66,15 +79,22 @@ public class MessagesSearchQuery { ...@@ -66,15 +79,22 @@ public class MessagesSearchQuery {
lastReturnedNum = 0; lastReturnedNum = 0;
return; return;
} }
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask()); if (lastReturnedNum >= searchResultMessages.size()) {
lastReturnedNum = searchResultMessages.size() - 1;
}
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId());
return; return;
} else { } else {
return; return;
} }
} }
if (messagesSearchEndReached[0] && !messagesSearchEndReached[1] && mergeDialogId != 0) {
queryWithDialog = mergeDialogId;
}
final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search(); final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
req.limit = 21; req.limit = 21;
int lower_part = (int) dialog_id; int lower_part = (int) queryWithDialog;
req.peer = MessagesController.getInputPeer(lower_part); req.peer = MessagesController.getInputPeer(lower_part);
if (req.peer == null) { if (req.peer == null) {
return; return;
...@@ -84,19 +104,21 @@ public class MessagesSearchQuery { ...@@ -84,19 +104,21 @@ public class MessagesSearchQuery {
req.filter = new TLRPC.TL_inputMessagesFilterEmpty(); req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
final int currentReqId = ++lastReqId; final int currentReqId = ++lastReqId;
lastSearchQuery = query; lastSearchQuery = query;
final long queryWithDialogFinal = queryWithDialog;
reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() { reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override @Override
public void run(final TLObject response, final TLRPC.TL_error error) { public void run(final TLObject response, final TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() { AndroidUtilities.runOnUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
reqId = 0;
if (currentReqId == lastReqId) { if (currentReqId == lastReqId) {
if (error == null) { if (error == null) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response; TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true); MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true);
MessagesController.getInstance().putUsers(res.users, false); MessagesController.getInstance().putUsers(res.users, false);
MessagesController.getInstance().putChats(res.chats, false); MessagesController.getInstance().putChats(res.chats, false);
if (req.max_id == 0) { if (req.max_id == 0 && queryWithDialogFinal == dialog_id) {
lastReturnedNum = 0; lastReturnedNum = 0;
searchResultMessages.clear(); searchResultMessages.clear();
} }
...@@ -106,17 +128,27 @@ public class MessagesSearchQuery { ...@@ -106,17 +128,27 @@ public class MessagesSearchQuery {
added = true; added = true;
searchResultMessages.add(new MessageObject(message, null, false)); searchResultMessages.add(new MessageObject(message, null, false));
} }
messagesSearchEndReached = res.messages.size() != 21; messagesSearchEndReached[queryWithDialogFinal == dialog_id ? 0 : 1] = res.messages.size() != 21;
if (mergeDialogId == 0) {
messagesSearchEndReached[1] = messagesSearchEndReached[0];
}
if (searchResultMessages.isEmpty()) { if (searchResultMessages.isEmpty()) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask()); NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), (long) 0);
} else { } else {
if (added) { if (added) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask()); if (lastReturnedNum >= searchResultMessages.size()) {
lastReturnedNum = searchResultMessages.size() - 1;
} }
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId());
}
}
if (queryWithDialogFinal == dialog_id && messagesSearchEndReached[0] && mergeDialogId != 0) {
messagesSearchEndReached[1] = false;
searchMessagesInChat(lastSearchQuery, dialog_id, mergeDialogId, guid, 0);
} }
} }
} }
reqId = 0;
} }
}); });
} }
......
...@@ -82,39 +82,7 @@ public class ReplyMessageQuery { ...@@ -82,39 +82,7 @@ public class ReplyMessageQuery {
message.id = cursor.intValue(1); message.id = cursor.intValue(1);
message.date = cursor.intValue(2); message.date = cursor.intValue(2);
message.dialog_id = dialog_id; message.dialog_id = dialog_id;
if (message.from_id > 0) { MessagesStorage.addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
if (!usersToLoad.contains(message.from_id)) {
usersToLoad.add(message.from_id);
}
} else {
if (!chatsToLoad.contains(-message.from_id)) {
chatsToLoad.add(-message.from_id);
}
}
if (message.action != null && message.action.user_id != 0) {
if (!usersToLoad.contains(message.action.user_id)) {
usersToLoad.add(message.action.user_id);
}
}
if (message.media != null && message.media.user_id != 0) {
if (!usersToLoad.contains(message.media.user_id)) {
usersToLoad.add(message.media.user_id);
}
}
if (message.media != null && message.media.audio != null && message.media.audio.user_id != 0) {
if (!usersToLoad.contains(message.media.audio.user_id)) {
usersToLoad.add(message.media.audio.user_id);
}
}
if (message.fwd_from_id instanceof TLRPC.TL_peerUser) {
if (!usersToLoad.contains(message.fwd_from_id.user_id)) {
usersToLoad.add(message.fwd_from_id.user_id);
}
} else if (message.fwd_from_id instanceof TLRPC.TL_peerChannel) {
if (!chatsToLoad.contains(message.fwd_from_id.channel_id)) {
chatsToLoad.add(message.fwd_from_id.channel_id);
}
}
result.add(message); result.add(message);
replyMessages.remove((Integer) message.id); replyMessages.remove((Integer) message.id);
} }
...@@ -206,9 +174,15 @@ public class ReplyMessageQuery { ...@@ -206,9 +174,15 @@ public class ReplyMessageQuery {
} }
private static void broadcastReplyMessages(final ArrayList<TLRPC.Message> result, final HashMap<Integer, ArrayList<MessageObject>> replyMessageOwners, final ArrayList<TLRPC.User> users, final ArrayList<TLRPC.Chat> chats, final long dialog_id, final boolean isCache) { private static void broadcastReplyMessages(final ArrayList<TLRPC.Message> result, final HashMap<Integer, ArrayList<MessageObject>> replyMessageOwners, final ArrayList<TLRPC.User> users, final ArrayList<TLRPC.Chat> chats, final long dialog_id, final boolean isCache) {
final HashMap<Integer, TLRPC.User> usersHashMap = new HashMap<>(); final HashMap<Integer, TLRPC.User> usersDict = new HashMap<>();
for (TLRPC.User user : users) { for (int a = 0; a < users.size(); a++) {
usersHashMap.put(user.id, user); TLRPC.User user = users.get(a);
usersDict.put(user.id, user);
}
final HashMap<Integer, TLRPC.Chat> chatsDict = new HashMap<>();
for (int a = 0; a < chats.size(); a++) {
TLRPC.Chat chat = chats.get(a);
chatsDict.put(chat.id, chat);
} }
AndroidUtilities.runOnUIThread(new Runnable() { AndroidUtilities.runOnUIThread(new Runnable() {
@Override @Override
...@@ -216,11 +190,13 @@ public class ReplyMessageQuery { ...@@ -216,11 +190,13 @@ public class ReplyMessageQuery {
MessagesController.getInstance().putUsers(users, isCache); MessagesController.getInstance().putUsers(users, isCache);
MessagesController.getInstance().putChats(chats, isCache); MessagesController.getInstance().putChats(chats, isCache);
boolean changed = false; boolean changed = false;
for (TLRPC.Message message : result) { for (int a = 0; a < result.size(); a++) {
TLRPC.Message message = result.get(a);
ArrayList<MessageObject> arrayList = replyMessageOwners.get(message.id); ArrayList<MessageObject> arrayList = replyMessageOwners.get(message.id);
if (arrayList != null) { if (arrayList != null) {
MessageObject messageObject = new MessageObject(message, usersHashMap, false); MessageObject messageObject = new MessageObject(message, usersDict, chatsDict, false);
for (MessageObject m : arrayList) { for (int b = 0; b < arrayList.size(); b++) {
MessageObject m = arrayList.get(b);
m.replyMessageObject = messageObject; m.replyMessageObject = messageObject;
} }
changed = true; changed = true;
......
...@@ -197,13 +197,15 @@ public class SharedMediaQuery { ...@@ -197,13 +197,15 @@ public class SharedMediaQuery {
putMediaDatabase(uid, type, res.messages, max_id, topReached); putMediaDatabase(uid, type, res.messages, max_id, topReached);
} }
final HashMap<Integer, TLRPC.User> usersLocal = new HashMap<>(); final HashMap<Integer, TLRPC.User> usersDict = new HashMap<>();
for (TLRPC.User u : res.users) { for (int a = 0; a < res.users.size(); a++) {
usersLocal.put(u.id, u); TLRPC.User u = res.users.get(a);
usersDict.put(u.id, u);
} }
final ArrayList<MessageObject> objects = new ArrayList<>(); final ArrayList<MessageObject> objects = new ArrayList<>();
for (TLRPC.Message message : res.messages) { for (int a = 0; a < res.messages.size(); a++) {
objects.add(new MessageObject(message, usersLocal, true)); TLRPC.Message message = res.messages.get(a);
objects.add(new MessageObject(message, usersDict, true));
} }
AndroidUtilities.runOnUIThread(new Runnable() { AndroidUtilities.runOnUIThread(new Runnable() {
...@@ -273,37 +275,6 @@ public class SharedMediaQuery { ...@@ -273,37 +275,6 @@ public class SharedMediaQuery {
} }
cursor.dispose(); cursor.dispose();
/*cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, send_state, date FROM messages WHERE uid = %d ORDER BY mid ASC LIMIT %d", uid, 1000));
ArrayList<TLRPC.Message> photos = new ArrayList<>();
ArrayList<TLRPC.Message> docs = new ArrayList<>();
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (data != null && cursor.byteBufferValue(1, data) != 0) {
TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
MessageObject.setIsUnread(message, cursor.intValue(0) != 1);
message.date = cursor.intValue(2);
message.send_state = cursor.intValue(1);
message.dialog_id = uid;
if (message.ttl > 60 && message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaVideo) {
photos.add(message);
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
docs.add(message);
}
}
data.reuse();
}
cursor.dispose();
if (!photos.isEmpty() || !docs.isEmpty()) {
MessagesStorage.getInstance().getDatabase().beginTransaction();
if (!photos.isEmpty()) {
putMediaDatabaseInternal(uid, MEDIA_PHOTOVIDEO, photos);
}
if (docs.isEmpty()) {
putMediaDatabaseInternal(uid, MEDIA_FILE, docs);
}
MessagesStorage.getInstance().getDatabase().commitTransaction();
}*/
if (count != -1) { if (count != -1) {
putMediaCountDatabase(uid, type, count); putMediaCountDatabase(uid, type, count);
} }
......
...@@ -74,7 +74,7 @@ public class StickersQuery { ...@@ -74,7 +74,7 @@ public class StickersQuery {
if (document != null) { if (document != null) {
long setId = getStickerSetId(document); long setId = getStickerSetId(document);
TLRPC.TL_messages_stickerSet stickerSet = stickerSetsById.get(setId); TLRPC.TL_messages_stickerSet stickerSet = stickerSetsById.get(setId);
if (stickerSet != null && (stickerSet.set.flags & 2) != 0) { if (stickerSet != null && stickerSet.set.disabled) {
return null; return null;
} }
} }
...@@ -156,7 +156,9 @@ public class StickersQuery { ...@@ -156,7 +156,9 @@ public class StickersQuery {
TLRPC.TL_messages_stickerSet oldSet = stickerSetsById.get(stickerSet.id); TLRPC.TL_messages_stickerSet oldSet = stickerSetsById.get(stickerSet.id);
if (oldSet != null && oldSet.set.hash == stickerSet.hash) { if (oldSet != null && oldSet.set.hash == stickerSet.hash) {
oldSet.set.flags = stickerSet.flags; oldSet.set.disabled = stickerSet.disabled;
oldSet.set.installed = stickerSet.installed;
oldSet.set.official = stickerSet.official;
newStickerSets.put(oldSet.set.id, oldSet); newStickerSets.put(oldSet.set.id, oldSet);
newStickerArray.add(oldSet); newStickerArray.add(oldSet);
...@@ -206,6 +208,7 @@ public class StickersQuery { ...@@ -206,6 +208,7 @@ public class StickersQuery {
@Override @Override
public void run() { public void run() {
try { try {
if (stickers != null) {
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO stickers_v2 VALUES(?, ?, ?, ?)"); SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO stickers_v2 VALUES(?, ?, ?, ?)");
state.requery(); state.requery();
int size = 4; int size = 4;
...@@ -224,6 +227,13 @@ public class StickersQuery { ...@@ -224,6 +227,13 @@ public class StickersQuery {
state.step(); state.step();
data.reuse(); data.reuse();
state.dispose(); state.dispose();
} else {
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("UPDATE stickers_v2 SET date = ?");
state.requery();
state.bindInteger(1, date);
state.step();
state.dispose();
}
} catch (Exception e) { } catch (Exception e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
...@@ -291,7 +301,7 @@ public class StickersQuery { ...@@ -291,7 +301,7 @@ public class StickersQuery {
} }
stickersByIdNew.put(document.id, document); stickersByIdNew.put(document.id, document);
} }
if ((stickerSet.set.flags & 2) == 0) { if (!stickerSet.set.disabled) {
for (int b = 0; b < stickerSet.packs.size(); b++) { for (int b = 0; b < stickerSet.packs.size(); b++) {
TLRPC.TL_stickerPack stickerPack = stickerSet.packs.get(b); TLRPC.TL_stickerPack stickerPack = stickerSet.packs.get(b);
if (stickerPack == null || stickerPack.emoticon == null) { if (stickerPack == null || stickerPack.emoticon == null) {
...@@ -333,6 +343,14 @@ public class StickersQuery { ...@@ -333,6 +343,14 @@ public class StickersQuery {
} catch (Throwable e) { } catch (Throwable e) {
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
} else if (!cache) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadDate = date;
}
});
putStickersToCache(null, date, null);
} }
} }
}); });
...@@ -433,11 +451,7 @@ public class StickersQuery { ...@@ -433,11 +451,7 @@ public class StickersQuery {
stickerSetID.access_hash = stickerSet.access_hash; stickerSetID.access_hash = stickerSet.access_hash;
stickerSetID.id = stickerSet.id; stickerSetID.id = stickerSet.id;
if (hide != 0) { if (hide != 0) {
if (hide == 1) { stickerSet.disabled = hide == 1;
stickerSet.flags |= 2;
} else {
stickerSet.flags &= ~2;
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded); NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded);
TLRPC.TL_messages_installStickerSet req = new TLRPC.TL_messages_installStickerSet(); TLRPC.TL_messages_installStickerSet req = new TLRPC.TL_messages_installStickerSet();
req.stickerset = stickerSetID; req.stickerset = stickerSetID;
......
...@@ -27,6 +27,7 @@ import java.net.InterfaceAddress; ...@@ -27,6 +27,7 @@ import java.net.InterfaceAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class ConnectionsManager { public class ConnectionsManager {
...@@ -57,7 +58,7 @@ public class ConnectionsManager { ...@@ -57,7 +58,7 @@ public class ConnectionsManager {
private int lastClassGuid = 1; private int lastClassGuid = 1;
private boolean isUpdating = false; private boolean isUpdating = false;
private int connectionState = native_getConnectionState(); private int connectionState = native_getConnectionState();
private volatile int lastRequestToken = 1; private AtomicInteger lastRequestToken = new AtomicInteger(1);
private PowerManager.WakeLock wakeLock = null; private PowerManager.WakeLock wakeLock = null;
private static volatile ConnectionsManager Instance = null; private static volatile ConnectionsManager Instance = null;
...@@ -114,11 +115,11 @@ public class ConnectionsManager { ...@@ -114,11 +115,11 @@ public class ConnectionsManager {
} }
public int sendRequest(final TLObject object, final RequestDelegate onComplete, final QuickAckDelegate onQuickAck, final int flags, final int datacenterId, final int connetionType, final boolean immediate) { public int sendRequest(final TLObject object, final RequestDelegate onComplete, final QuickAckDelegate onQuickAck, final int flags, final int datacenterId, final int connetionType, final boolean immediate) {
final int requestToken = lastRequestToken++; final int requestToken = lastRequestToken.getAndIncrement();
Utilities.stageQueue.postRunnable(new Runnable() { Utilities.stageQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
FileLog.d("tmessages", "send request " + object); FileLog.d("tmessages", "send request " + object + " with token = " + requestToken);
NativeByteBuffer buffer = new NativeByteBuffer(object.getObjectSize()); NativeByteBuffer buffer = new NativeByteBuffer(object.getObjectSize());
object.serializeToStream(buffer); object.serializeToStream(buffer);
object.freeResources(); object.freeResources();
......
...@@ -288,7 +288,6 @@ public class ActionBarMenuItem extends FrameLayoutFixed { ...@@ -288,7 +288,6 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
} }
if (popupWindow == null) { if (popupWindow == null) {
popupWindow = new ActionBarPopupWindow(popupLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT); popupWindow = new ActionBarPopupWindow(popupLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
//popupWindow.setBackgroundDrawable(new BitmapDrawable());
if (Build.VERSION.SDK_INT >= 19) { if (Build.VERSION.SDK_INT >= 19) {
popupWindow.setAnimationStyle(0); popupWindow.setAnimationStyle(0);
} else { } else {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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