Commit 74def222 authored by DrKLO's avatar DrKLO

Update to 3.3.1

parent 496c336d
......@@ -7,22 +7,16 @@ repositories {
dependencies {
compile 'com.android.support:support-v4:23.1.+'
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 'org.apache.httpcomponents:httpmime:4.2.1'
}
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
buildToolsVersion '23.0.2'
useLibrary 'org.apache.http.legacy'
packagingOptions {
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
......@@ -30,7 +24,10 @@ android {
signingConfigs {
debug {
storeFile file("config/debug.keystore")
storeFile file("config/release.keystore")
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
release {
......@@ -46,6 +43,7 @@ android {
debuggable true
jniDebuggable true
signingConfig signingConfigs.debug
applicationIdSuffix ".beta"
}
release {
......@@ -81,7 +79,7 @@ android {
defaultConfig {
minSdkVersion 8
targetSdkVersion 23
versionCode 654
versionName "3.2.6"
versionCode 685
versionName "3.3.1"
}
}
......@@ -21,13 +21,13 @@
<application
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:label="@string/AppName"
android:label="@string/AppNameBeta"
android:theme="@style/Theme.TMessages.Start"
android:name=".ApplicationLoader"
android:hardwareAccelerated="@bool/useHardwareAcceleration"
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" />
......
......@@ -187,7 +187,7 @@ include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
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 += -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
......
......@@ -96,7 +96,7 @@ void sendRequest(JNIEnv *env, jclass c, jint object, jobject onComplete, jobject
if (onQuickAck != nullptr) {
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) {
......
This diff is collapsed.
This diff is collapsed.
......@@ -6,6 +6,7 @@
* Copyright Nikolai Kudashov, 2015.
*/
#include <sys/stat.h>
#include "Config.h"
#include "ConnectionsManager.h"
#include "FileLog.h"
......@@ -16,9 +17,10 @@ Config::Config(std::string fileName) {
backupPath = configPath + ".bak";
FILE *backup = fopen(backupPath.c_str(), "rb");
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());
rename(backupPath.c_str(), configPath.c_str());
fclose(backup);
}
}
......@@ -28,10 +30,14 @@ NativeByteBuffer *Config::readConfig() {
if (file != nullptr) {
fseek(file, 0, SEEK_END);
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;
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) {
buffer = BuffersStorage::getInstance().getFreeBuffer(size);
if (fread(buffer->bytes(), sizeof(uint8_t), size, file) != size) {
......@@ -45,6 +51,7 @@ NativeByteBuffer *Config::readConfig() {
}
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 *backup = fopen(backupPath.c_str(), "rb");
bool error = false;
......@@ -65,21 +72,53 @@ void Config::writeConfig(NativeByteBuffer *buffer) {
return;
}
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) {
DEBUG_E("Config(%p, %s) unable to open file for writing", this, configPath.c_str());
return;
}
uint32_t size = buffer->position();
if (fwrite(&size, sizeof(uint32_t), 1, file) == 1) {
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;
}
} 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;
}
fclose(file);
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 {
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());
}
}
......@@ -14,6 +14,7 @@
#include <functional>
#include <sys/epoll.h>
#include <map>
#include <atomic>
#include <bits/unique_ptr.h>
#include "Defines.h"
......@@ -63,7 +64,6 @@ public:
void updateDcSettings(uint32_t datacenterId);
#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);
static void useJavaVM(JavaVM *vm, bool useJavaByteBuffers);
#endif
......@@ -120,7 +120,7 @@ private:
std::map<int32_t, std::vector<std::int32_t>> quickAckIdToRequestIds;
int32_t pingTime;
bool testBackend = false;
volatile uint32_t lastRequestToken = 1;
std::atomic<uint32_t> lastRequestToken{1};
uint32_t currentDatacenterId = 0;
uint32_t movingToDatacenterId = DEFAULT_DATACENTER_ID;
int64_t pushSessionId = 0;
......
......@@ -668,9 +668,7 @@ void Datacenter::onHandshakeConnectionConnected(Connection *connection) {
if (handshakeState == 0 || !needResendData) {
return;
}
if (handshakeRequest != nullptr) {
sendRequestData(handshakeRequest, true);
}
beginHandshake(false);
}
inline uint64_t gcd(uint64_t a, uint64_t b) {
......@@ -1383,6 +1381,7 @@ NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<Net
int64_t currentTime = ConnectionsManager::getInstance().getCurrentTimeMillis() + (int64_t) timeDifference * 1000;
if (messageTime < currentTime - 30000 || messageTime > currentTime + 25000) {
DEBUG_D("wrap message in container");
TL_msg_container *messageContainer = new TL_msg_container();
messageContainer->messages.push_back(std::move(networkMessage->message));
......@@ -1395,6 +1394,7 @@ NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<Net
messageSeqNo = networkMessage->message->seqno;
}
} else {
DEBUG_D("start write messages to container");
TL_msg_container *messageContainer = new TL_msg_container();
size_t count = requests.size();
for (uint32_t a = 0; a < count; a++) {
......
......@@ -18,7 +18,9 @@
FILE *logFile = nullptr;
void FileLog::init(std::string path) {
logFile = fopen(path.c_str(), "w");
if (path.size() > 0) {
logFile = fopen(path.c_str(), "w");
}
}
void FileLog::e(const char *message, ...) {
......
......@@ -931,7 +931,7 @@ void TL_config::readParams(NativeByteBuffer *stream, bool &error) {
dc_options.push_back(std::unique_ptr<TL_dcOption>(object));
}
chat_size_max = stream->readInt32(&error);
broadcast_size_max = stream->readInt32(&error);
megagroup_size_max = stream->readInt32(&error);
forwarded_count_max = stream->readInt32(&error);
online_update_period_ms = stream->readInt32(&error);
offline_blur_timeout_ms = stream->readInt32(&error);
......@@ -971,7 +971,7 @@ void TL_config::serializeToStream(NativeByteBuffer *stream) {
dc_options[a]->serializeToStream(stream);
}
stream->writeInt32(chat_size_max);
stream->writeInt32(broadcast_size_max);
stream->writeInt32(megagroup_size_max);
stream->writeInt32(forwarded_count_max);
stream->writeInt32(online_update_period_ms);
stream->writeInt32(offline_blur_timeout_ms);
......
......@@ -657,7 +657,7 @@ public:
class TL_config : public TLObject {
public:
static const uint32_t constructor = 0x4e32b894;
static const uint32_t constructor = 0x6cb6e65e;
int32_t date;
int32_t expires;
......@@ -665,7 +665,7 @@ public:
int32_t this_dc;
std::vector<std::unique_ptr<TL_dcOption>> dc_options;
int32_t chat_size_max;
int32_t broadcast_size_max;
int32_t megagroup_size_max;
int32_t forwarded_count_max;
int32_t online_update_period_ms;
int32_t offline_blur_timeout_ms;
......
......@@ -34,7 +34,7 @@ public:
int32_t requestToken;
uint32_t retryCount = 0;
bool failedBySalt = false;
bool failedByFloodWait = false;
int32_t failedByFloodWait = 0;
ConnectionType connectionType;
uint32_t requestFlags;
bool completed = false;
......
......@@ -43,7 +43,6 @@
android:allowBackup="false"
android:hardwareAccelerated="@bool/useHardwareAcceleration"
android:icon="@drawable/ic_launcher"
android:label="@string/AppName"
android:largeHeap="true"
android:theme="@style/Theme.TMessages.Start">
......@@ -159,7 +158,7 @@
</service>
<service
android:name=".TgChooserTargetService"
android:name="org.telegram.messenger.TgChooserTargetService"
android:label="@string/AppName"
android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
<intent-filter>
......
1876;JM;Jamaica
1869;KN;Saint Kitts & Nevis
1868;TT;Trinidad & Tobago
1784;VC;Saint Vincent & the Grenadines
1767;DM;Dominica
1758;LC;Saint Lucia
1721;SX;Sint Maarten
1684;AS;American Samoa
1671;GU;Guam
1670;MP;Northern Mariana Islands
1664;MS;Montserrat
1649;TC;Turks & Caicos Islands
1473;GD;Grenada
1441;BM;Bermuda
1345;KY;Cayman Islands
1340;VI;US Virgin Islands
1284;VG;British Virgin Islands
1268;AG;Antigua & Barbuda
1264;AI;Anguilla
1246;BB;Barbados
1242;BS;Bahamas
998;UZ;Uzbekistan
996;KG;Kyrgyzstan
995;GE;Georgia
994;AZ;Azerbaijan
993;TM;Turkmenistan
992;TJ;Tajikistan
977;NP;Nepal
976;MN;Mongolia
975;BT;Bhutan
974;QA;Qatar
973;BH;Bahrain
972;IL;Israel
971;AE;United Arab Emirates
970;PS;Palestine
968;OM;Oman
967;YE;Yemen
966;SA;Saudi Arabia
965;KW;Kuwait
964;IQ;Iraq
963;SY;Syrian Arab Republic
962;JO;Jordan
1876;JM;Jamaica;XXX XXXX
1869;KN;Saint Kitts & Nevis;XXX XXXX
1868;TT;Trinidad & Tobago;XXX XXXX
1784;VC;Saint Vincent & the Grenadines;XXX XXXX
1767;DM;Dominica;XXX XXXX
1758;LC;Saint Lucia;XXX XXXX
1721;SX;Sint Maarten;XXX XXXX
1684;AS;American Samoa;XXX XXXX
1671;GU;Guam;XXX XXXX
1670;MP;Northern Mariana Islands;XXX XXXX
1664;MS;Montserrat;XXX XXXX
1649;TC;Turks & Caicos Islands;XXX XXXX
1473;GD;Grenada;XXX XXXX
1441;BM;Bermuda;XXX XXXX
1345;KY;Cayman Islands;XXX XXXX
1340;VI;US Virgin Islands;XXX XXXX
1284;VG;British Virgin Islands;XXX XXXX
1268;AG;Antigua & Barbuda;XXX XXXX
1264;AI;Anguilla;XXX XXXX
1246;BB;Barbados;XXX XXXX
1242;BS;Bahamas;XXX XXXX
998;UZ;Uzbekistan;XX XXXXXXX
996;KG;Kyrgyzstan;XXX XXXXXX
995;GE;Georgia;XXX XXX XXX
994;AZ;Azerbaijan;XX XXX XXXX
993;TM;Turkmenistan;XX XXXXXX
992;TJ;Tajikistan;XX XXX XXXX
977;NP;Nepal;XX XXXX XXXX
976;MN;Mongolia;XX XX XXXX
975;BT;Bhutan;XX XXX XXX
974;QA;Qatar;XX XXX XXX
973;BH;Bahrain;XXXX XXXX
972;IL;Israel;XX XXX XXXX
971;AE;United Arab Emirates;XX XXX XXXX
970;PS;Palestine;XXX XX XXXX
968;OM;Oman;XXXX XXXX
967;YE;Yemen;XXX XXX XXX
966;SA;Saudi Arabia;XX XXX XXXX
965;KW;Kuwait;XXXX XXXX
964;IQ;Iraq;XXX XXX XXXX
963;SY;Syria;XXX XXX XXX
962;JO;Jordan;X XXXX XXXX
961;LB;Lebanon
960;MV;Maldives
886;TW;Taiwan
960;MV;Maldives;XXX XXXX
886;TW;Taiwan;XXX XXX XXX
880;BD;Bangladesh
856;LA;Laos
856;LA;Laos;XX XX XXX XXX
855;KH;Cambodia
853;MO;Macau
852;HK;Hong Kong
853;MO;Macau;XXXX XXXX
852;HK;Hong Kong;X XXX XXXX
850;KP;North Korea
692;MH;Marshall Islands
691;FM;Micronesia
......@@ -67,166 +67,166 @@
676;TO;Tonga
675;PG;Papua New Guinea
674;NR;Nauru
673;BN;Brunei Darussalam
673;BN;Brunei Darussalam;XXX XXXX
672;NF;Norfolk Island
670;TL;Timor-Leste
599;BQ;Bonaire, Sint Eustatius & Saba
599;CW;Curaçao
598;UY;Uruguay
597;SR;Suriname
598;UY;Uruguay;X XXX XXXX
597;SR;Suriname;XXX XXXX
596;MQ;Martinique
595;PY;Paraguay
595;PY;Paraguay;XXX XXX XXX
594;GF;French Guiana
593;EC;Ecuador
593;EC;Ecuador;XX XXX XXXX
592;GY;Guyana
591;BO;Bolivia
590;GP;Guadeloupe
591;BO;Bolivia;X XXX XXXX
590;GP;Guadeloupe;XXX XX XX XX
509;HT;Haiti
508;PM;Saint Pierre & Miquelon
507;PA;Panama
506;CR;Costa Rica
505;NI;Nicaragua
504;HN;Honduras
503;SV;El Salvador
502;GT;Guatemala
507;PA;Panama;XXXX XXXX
506;CR;Costa Rica;XXXX XXXX
505;NI;Nicaragua;XXXX XXXX
504;HN;Honduras;XXXX XXXX
503;SV;El Salvador;XXXX XXXX
502;GT;Guatemala;X XXX XXXX
501;BZ;Belize
500;FK;Falkland Islands
423;LI;Liechtenstein
421;SK;Slovakia
420;CZ;Czech Republic
389;MK;Macedonia
387;BA;Bosnia & Herzegovina
386;SI;Slovenia
421;SK;Slovakia;XXX XXX XXX
420;CZ;Czech Republic;XXX XXX XXX
389;MK;Macedonia;XX XXX XXX
387;BA;Bosnia & Herzegovina;XX XXX XXX
386;SI;Slovenia;XX XXX XXX
385;HR;Croatia
382;ME;Montenegro
381;RS;Serbia
380;UA;Ukraine
378;SM;San Marino
377;MC;Monaco
376;AD;Andorra
375;BY;Belarus
374;AM;Armenia
373;MD;Moldova
381;RS;Serbia;XX XXX XXXX
380;UA;Ukraine;XX XXX XX XX
378;SM;San Marino;XXX XXX XXXX
377;MC;Monaco;XXXX XXXX
376;AD;Andorra;XX XX XX
375;BY;Belarus;XX XXX XXXX
374;AM;Armenia;XX XXX XXX
373;MD;Moldova;XX XXX XXX
372;EE;Estonia
371;LV;Latvia
370;LT;Lithuania
371;LV;Latvia;XXX XXXXX
370;LT;Lithuania;XXX XXXXX
359;BG;Bulgaria
358;FI;Finland
357;CY;Cyprus
356;MT;Malta
355;AL;Albania
354;IS;Iceland
353;IE;Ireland
357;CY;Cyprus;XXXX XXXX
356;MT;Malta;XX XX XX XX
355;AL;Albania;XX XXX XXXX
354;IS;Iceland;XXX XXXX
353;IE;Ireland;XX XXX XXXX
352;LU;Luxembourg
351;PT;Portugal
350;GI;Gibraltar
299;GL;Greenland
298;FO;Faroe Islands
297;AW;Aruba
291;ER;Eritrea
290;SH;Saint Helena
269;KM;Comoros
268;SZ;Swaziland
267;BW;Botswana
266;LS;Lesotho
265;MW;Malawi
264;NA;Namibia
263;ZW;Zimbabwe
262;RE;Réunion
261;MG;Madagascar
260;ZM;Zambia
258;MZ;Mozambique
257;BI;Burundi
256;UG;Uganda
255;TZ;Tanzania
254;KE;Kenya
253;DJ;Djibouti
252;SO;Somalia
251;ET;Ethiopia
250;RW;Rwanda
249;SD;Sudan
248;SC;Seychelles
247;SH;Saint Helena
246;IO;Diego Garcia
245;GW;Guinea-Bissau
244;AO;Angola
243;CD;Congo (Dem. Rep.)
242;CG;Congo (Rep.)
241;GA;Gabon
240;GQ;Equatorial Guinea
239;ST;São Tomé & Príncipe
238;CV;Cape Verde
237;CM;Cameroon
236;CF;Central African Rep.
235;TD;Chad
351;PT;Portugal;X XXXX XXXX
350;GI;Gibraltar;XXXX XXXX
299;GL;Greenland;XXX XXX
298;FO;Faroe Islands;XXX XXX
297;AW;Aruba;XXX XXXX
291;ER;Eritrea;X XXX XXX
290;SH;Saint Helena;XX XXX
269;KM;Comoros;XXX XXXX
268;SZ;Swaziland;XXXX XXXX
267;BW;Botswana;XX XXX XXX
266;LS;Lesotho;XX XXX XXX
265;MW;Malawi;77 XXX XXXX
264;NA;Namibia;XX XXX XXXX
263;ZW;Zimbabwe;XX XXX XXXX
262;RE;Réunion;XXX XXX XXX
261;MG;Madagascar;XX XX XXX XX
260;ZM;Zambia;XX XXX XXXX
258;MZ;Mozambique;XX XXX XXXX
257;BI;Burundi;XX XX XXXX
256;UG;Uganda;XX XXX XXXX
255;TZ;Tanzania;XX XXX XXXX
254;KE;Kenya;XXX XXX XXX
253;DJ;Djibouti;XX XX XX XX
252;SO;Somalia;XX XXX XXX
251;ET;Ethiopia;XX XXX XXXX
250;RW;Rwanda;XXX XXX XXX
249;SD;Sudan;XX XXX XXXX
248;SC;Seychelles;X XX XX XX
247;SH;Saint Helena;XXXX
246;IO;Diego Garcia;XXX XXXX
245;GW;Guinea-Bissau;XXX XXXX
244;AO;Angola;XXX XXX XXX
243;CD;Congo (Dem. Rep.);XX XXX XXXX
242;CG;Congo (Rep.);XX XXX XXXX
241;GA;Gabon;X XX XX XX
240;GQ;Equatorial Guinea;XXX XXX XXX
239;ST;São Tomé & Príncipe;XX XXXXX
238;CV;Cape Verde;XXX XXXX
237;CM;Cameroon;XXXX XXXX
236;CF;Central African Rep.;XX XX XX XX
235;TD;Chad;XX XX XX XX
234;NG;Nigeria
233;GH;Ghana
232;SL;Sierra Leone
232;SL;Sierra Leone;XX XXX XXX
231;LR;Liberia
230;MU;Mauritius
229;BJ;Benin
228;TG;Togo
227;NE;Niger
226;BF;Burkina Faso
225;CI;Côte d`Ivoire
224;GN;Guinea
223;ML;Mali
222;MR;Mauritania
221;SN;Senegal
220;GM;Gambia
218;LY;Libya
216;TN;Tunisia
213;DZ;Algeria
212;MA;Morocco
211;SS;South Sudan
98;IR;Iran
229;BJ;Benin;XX XXX XXX
228;TG;Togo;XX XXX XXX
227;NE;Niger;XX XX XX XX
226;BF;Burkina Faso;XX XX XX XX
225;CI;Côte d`Ivoire;XX XXX XXX
224;GN;Guinea;XXX XXX XXX
223;ML;Mali;XXXX XXXX
222;MR;Mauritania;XXXX XXXX
221;SN;Senegal;XX XXX XXXX
220;GM;Gambia;XXX XXXX
218;LY;Libya;XX XXX XXXX
216;TN;Tunisia;XX XXX XXX
213;DZ;Algeria;XXX XX XX XX
212;MA;Morocco;XX XXX XXXX
211;SS;South Sudan;XX XXX XXXX
98;IR;Iran;XXX XXX XXXX
95;MM;Myanmar
94;LK;Sri Lanka
93;AF;Afghanistan
92;PK;Pakistan
91;IN;India
90;TR;Turkey
86;CN;China
94;LK;Sri Lanka;XX XXX XXXX
93;AF;Afghanistan;XXX XXX XXX
92;PK;Pakistan;XXX XXX XXXX
91;IN;India;XXXXX XXXXX
90;TR;Turkey;XXX XXX XXXX
86;CN;China;XXX XXXX XXXX
84;VN;Vietnam
82;KR;South Korea
81;JP;Japan
66;TH;Thailand
65;SG;Singapore
81;JP;Japan;XX XXXX XXXX
66;TH;Thailand;X XXXX XXXX
65;SG;Singapore;XXXX XXXX
64;NZ;New Zealand
63;PH;Philippines
63;PH;Philippines;XXX XXX XXXX
62;ID;Indonesia
61;AU;Australia
61;AU;Australia;XXX XXX XXX
60;MY;Malaysia
58;VE;Venezuela
57;CO;Colombia
56;CL;Chile
55;BR;Brazil
58;VE;Venezuela;XXX XXX XXXX
57;CO;Colombia;XXX XXX XXXX
56;CL;Chile;X XXXX XXXX
55;BR;Brazil;XX XXXXX XXXX
54;AR;Argentina
53;CU;Cuba
53;CU;Cuba;XXXX XXXX
52;MX;Mexico
51;PE;Peru
51;PE;Peru;XXX XXX XXX
49;DE;Germany
48;PL;Poland
47;NO;Norway
46;SE;Sweden
45;DK;Denmark
44;GB;United Kingdom
48;PL;Poland;XX XXX XXXX
47;NO;Norway;XXXX XXXX
46;SE;Sweden;XX XXX XXXX
45;DK;Denmark;XXXX XXXX
44;GB;United Kingdom;XXXX XXXXXX
43;AT;Austria
42;YL;Y-land
41;CH;Switzerland
40;RO;Romania
41;CH;Switzerland;XX XXX XXXX
40;RO;Romania;XXX XXX XXX
39;IT;Italy
36;HU;Hungary
34;ES;Spain
33;FR;France
32;BE;Belgium
31;NL;Netherlands
30;GR;Greece
27;ZA;South Africa
20;EG;Egypt
7;KZ;Kazakhstan
7;RU;Russian Federation
1;PR;Puerto Rico
1;DO;Dominican Rep.
1;CA;Canada
1;US;USA
\ No newline at end of file
36;HU;Hungary;XXX XXX XXX
34;ES;Spain;XXX XXX XXX
33;FR;France;X XX XX XX XX
32;BE;Belgium;XXX XX XX XX
31;NL;Netherlands;X XX XX XX XX
30;GR;Greece;XXX XXX XXXX
27;ZA;South Africa;XX XXX XXXX
20;EG;Egypt;XX XXXX XXXX
7;KZ;Kazakhstan;XXX XXX XX XX
7;RU;Russian Federation;XXX XXX XXXX
1;PR;Puerto Rico;XXX XXX XXXX
1;DO;Dominican Rep.;XXX XXX XXXX
1;CA;Canada;XXX XXX XXXX
1;US;USA;XXX XXX XXXX
\ No newline at end of file
......@@ -75,6 +75,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Locale;
import java.util.regex.Pattern;
public class AndroidUtilities {
......@@ -93,6 +94,36 @@ public class AndroidUtilities {
private static Boolean isTablet = null;
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 {
density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
leftBaseline = isTablet() ? 80 : 72;
......@@ -735,7 +766,7 @@ public class AndroidUtilities {
}*/
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
public boolean includeDeviceData() {
return true;
......@@ -745,7 +776,7 @@ public class AndroidUtilities {
public static void checkForUpdates(Activity context) {
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,18 +327,23 @@ public class ApplicationLoader extends Application {
}
private void initPlayServices() {
if (checkPlayServices()) {
gcm = GoogleCloudMessaging.getInstance(this);
regid = getRegistrationId();
if (regid.length() == 0) {
registerInBackground();
} else {
sendRegistrationIdToBackend(false);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (checkPlayServices()) {
gcm = GoogleCloudMessaging.getInstance(ApplicationLoader.this);
regid = getRegistrationId();
if (regid.length() == 0) {
registerInBackground();
} else {
sendRegistrationIdToBackend(false);
}
} else {
FileLog.d("tmessages", "No valid Google Play Services APK found.");
}
}
} else {
FileLog.d("tmessages", "No valid Google Play Services APK found.");
}
}, 1000);
}
private boolean checkPlayServices() {
......
......@@ -21,6 +21,6 @@ public class AutoMessageHeardReceiver extends BroadcastReceiver {
if (dialog_id == 0 || max_id == 0) {
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 {
return;
}
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;
public class BuildVars {
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 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_DEBUG = "your-hockeyapp-api-key-here";
public static String GCM_SENDER_ID = "760348033672";
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
......
......@@ -16,17 +16,18 @@ public class ChatObject {
public static final int CHAT_TYPE_BROADCAST = 1;
public static final int CHAT_TYPE_CHANNEL = 2;
public static final int CHAT_TYPE_USER = 3;
public static final int CHAT_TYPE_MEGAGROUP = 4;
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) {
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) {
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) {
......@@ -40,11 +41,11 @@ public class ChatObject {
public static boolean isCanWriteToChannel(int 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) {
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) {
......
......@@ -208,8 +208,8 @@ public class ContactsController {
try {
accounts = am.getAccountsByType("org.telegram.account");
if (accounts != null && accounts.length > 0) {
for (Account c : accounts) {
am.removeAccount(c, null, null);
for (int a = 0; a < accounts.length; a++) {
am.removeAccount(accounts[a], null, null);
}
}
} catch (Exception e) {
......@@ -221,7 +221,7 @@ public class ContactsController {
if (UserConfig.isClientActivated()) {
if (accounts.length == 1) {
Account acc = accounts[0];
if (!acc.name.equals(UserConfig.getCurrentUser().phone)) {
if (!acc.name.equals("" + UserConfig.getClientUserId())) {
recreateAccount = true;
} else {
currentAccount = acc;
......@@ -236,12 +236,16 @@ public class ContactsController {
}
}
if (recreateAccount) {
for (Account c : accounts) {
am.removeAccount(c, null, null);
try {
for (int a = 0; a < accounts.length; a++) {
am.removeAccount(accounts[a], null, null);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (UserConfig.isClientActivated()) {
try {
currentAccount = new Account(UserConfig.getCurrentUser().phone, "org.telegram.messenger");
currentAccount = new Account("" + UserConfig.getClientUserId(), "org.telegram.messenger");
am.addAccountExplicitly(currentAccount, "", null);
} catch (Exception e) {
FileLog.e("tmessages", e);
......@@ -254,8 +258,8 @@ public class ContactsController {
try {
AccountManager am = AccountManager.get(ApplicationLoader.applicationContext);
Account[] accounts = am.getAccountsByType("org.telegram.messenger");
for (Account c : accounts) {
am.removeAccount(c, null, null);
for (int a = 0; a < accounts.length; a++) {
am.removeAccount(accounts[a], null, null);
}
} catch (Exception e) {
e.printStackTrace();
......@@ -277,7 +281,7 @@ public class ContactsController {
private boolean checkContactsInternal() {
boolean reload = false;
try {
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
if (!hasContactsPermission()) {
return false;
}
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
......@@ -334,7 +338,7 @@ public class ContactsController {
private HashMap<Integer, Contact> readContactsFromPhoneBook() {
HashMap<Integer, Contact> contactsMap = new HashMap<>();
try {
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
if (!hasContactsPermission()) {
return contactsMap;
}
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
......@@ -1044,7 +1048,7 @@ public class ContactsController {
sortedSectionsArray.add(key);
}
arr.add(value);
if ((user.flags & TLRPC.USER_FLAG_MUTUAL_CONTACT) != 0) {
if (user.mutual_contact) {
arr = sectionsDictMutual.get(key);
if (arr == null) {
arr = new ArrayList<>();
......@@ -1280,9 +1284,34 @@ public class ContactsController {
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) {
try {
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
if (!hasContactsPermission()) {
return;
}
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 {
}
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)) {
TLRPC.User user = MessagesController.getInstance().getUser(u.user_id);
addContactToPhoneBook(user, false);
......@@ -1486,7 +1516,7 @@ public class ContactsController {
if (currentAccount == null || user == null || user.phone == null || user.phone.length() == 0) {
return -1;
}
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
if (!hasContactsPermission()) {
return -1;
}
long res = -1;
......@@ -1536,7 +1566,9 @@ public class ContactsController {
query.add(builder.build());
try {
ContentProviderResult[] result = contentResolver.applyBatch(ContactsContract.AUTHORITY, query);
res = Long.parseLong(result[0].uri.getLastPathSegment());
if (result != null && result.length > 0 && result[0].uri != null) {
res = Long.parseLong(result[0].uri.getLastPathSegment());
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
......@@ -1547,7 +1579,7 @@ public class ContactsController {
}
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;
}
synchronized (observerLock) {
......
......@@ -12,9 +12,12 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import java.util.concurrent.CountDownLatch;
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) {
setName(threadName);
......@@ -22,40 +25,24 @@ public class DispatchQueue extends Thread {
}
private void sendMessage(Message msg, int delay) {
if (handler == null) {
try {
synchronized (handlerSyncObject) {
handlerSyncObject.wait();
}
} catch (Throwable t) {
t.printStackTrace();
}
}
if (handler != null) {
try {
syncLatch.await();
if (delay <= 0) {
handler.sendMessage(msg);
} else {
handler.sendMessageDelayed(msg, delay);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void cancelRunnable(Runnable runnable) {
if (handler == null) {
synchronized (handlerSyncObject) {
if (handler == null) {
try {
handlerSyncObject.wait();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
if (handler != null) {
try {
syncLatch.await();
handler.removeCallbacks(runnable);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
......@@ -64,39 +51,32 @@ public class DispatchQueue extends Thread {
}
public void postRunnable(Runnable runnable, long delay) {
if (handler == null) {
synchronized (handlerSyncObject) {
if (handler == null) {
try {
handlerSyncObject.wait();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
if (handler != null) {
try {
syncLatch.await();
if (delay <= 0) {
handler.post(runnable);
} else {
handler.postDelayed(runnable, delay);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void cleanupQueue() {
if (handler != null) {
try {
syncLatch.await();
handler.removeCallbacksAndMessages(null);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
@Override
public void run() {
Looper.prepare();
synchronized (handlerSyncObject) {
handler = new Handler();
handlerSyncObject.notify();
}
handler = new Handler();
syncLatch.countDown();
Looper.loop();
}
}
......@@ -266,10 +266,7 @@ public class Emoji {
}
if (!canvas.quickReject(b.left, b.top, b.right, b.bottom, Canvas.EdgeType.AA)) {
canvas.save();
canvas.clipRect(b);
canvas.drawBitmap(emojiBmp[info.page][info.page2], info.rect, b, fullSize ? null : paint);
canvas.restore();
canvas.drawBitmap(emojiBmp[info.page][info.page2], info.rect, b, paint);
}
}
......
......@@ -468,7 +468,7 @@ public class FileLoadOperation {
delegate.didFailedLoadingFile(FileLoadOperation.this, 2);
} else {
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();
delegate.didFailedLoadingFile(FileLoadOperation.this, 0);
......
......@@ -753,7 +753,8 @@ public class FileLoader {
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
for (File file : files) {
for (int a = 0; a < files.size(); a++) {
File file = files.get(a);
if (file.exists()) {
try {
if (!file.delete()) {
......@@ -763,6 +764,16 @@ public class FileLoader {
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 {
}
public static String getNetworkLogPath() {
if (!BuildVars.DEBUG_VERSION) {
return "";
}
try {
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
if (sdCard == null) {
......
......@@ -75,7 +75,7 @@ public class ImageLoader {
private HashMap<String, Runnable> retryHttpsTasks = new HashMap<>();
private int currentHttpFileLoadTasksCount = 0;
protected VMRuntimeHack runtimeHack = null;
public VMRuntimeHack runtimeHack = null;
private String ignoreRemoval = null;
private volatile long lastCacheOutTime = 0;
......@@ -1162,7 +1162,18 @@ public class ImageLoader {
FileLog.e("tmessages", "file system changed");
Runnable r = new Runnable() {
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())) {
......@@ -1186,7 +1197,35 @@ public class ImageLoader {
filter.addDataScheme("file");
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() {
......
......@@ -46,14 +46,14 @@ public class LocaleController {
public static boolean isRTL = false;
public static int nameDisplayOrder = 1;
private static boolean is24HourFormat = false;
public static FastDateFormat formatterDay;
public static FastDateFormat formatterWeek;
public static FastDateFormat formatterMonth;
public static FastDateFormat formatterYear;
public static FastDateFormat formatterMonthYear;
public static FastDateFormat formatterYearMax;
public static FastDateFormat chatDate;
public static FastDateFormat chatFullDate;
public FastDateFormat formatterDay;
public FastDateFormat formatterWeek;
public FastDateFormat formatterMonth;
public FastDateFormat formatterYear;
public FastDateFormat formatterMonthYear;
public FastDateFormat formatterYearMax;
public FastDateFormat chatDate;
public FastDateFormat chatFullDate;
private HashMap<String, PluralRules> allRules = new HashMap<>();
......@@ -671,9 +671,9 @@ public class LocaleController {
int dateYear = rightNow.get(Calendar.YEAR);
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) {
......@@ -686,13 +686,13 @@ public class LocaleController {
int dateYear = rightNow.get(Calendar.YEAR);
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) {
return getString("Yesterday", R.string.Yesterday);
} else if (year == dateYear) {
return formatterMonth.format(new Date(date * 1000));
return getInstance().formatterMonth.format(new Date(date * 1000));
} else {
return formatterYear.format(new Date(date * 1000));
return getInstance().formatterYear.format(new Date(date * 1000));
}
} catch (Exception e) {
FileLog.e("tmessages", e);
......@@ -710,7 +710,7 @@ public class LocaleController {
int dateYear = rightNow.get(Calendar.YEAR);
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;
if (diff < 1) {
return LocaleController.getString("LastSeenNow", R.string.LastSeenNow);
......@@ -720,12 +720,12 @@ public class LocaleController {
return LocaleController.formatPluralString("LastSeenHours", (int) Math.ceil(diff / 60.0f));
}*/
} 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) {
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);
} 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);
}
} catch (Exception e) {
......@@ -780,15 +780,15 @@ public class LocaleController {
int dateYear = rightNow.get(Calendar.YEAR);
if (year != dateYear) {
return formatterYear.format(new Date(date * 1000));
return getInstance().formatterYear.format(new Date(date * 1000));
} else {
int dayDiff = dateDay - day;
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) {
return formatterWeek.format(new Date(date * 1000));
return getInstance().formatterWeek.format(new Date(date * 1000));
} else {
return formatterMonth.format(new Date(date * 1000));
return getInstance().formatterMonth.format(new Date(date * 1000));
}
}
} catch (Exception e) {
......
......@@ -542,13 +542,18 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
shuffleMusic = preferences.getBoolean("shuffleMusic", false);
repeatMode = preferences.getInt("repeatMode", 0);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidLoaded);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileLoadProgressChanged);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileUploadProgressChanged);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesDeleted);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.removeAllMessagesFromDialog);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.musicDidLoaded);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileDidFailedLoad);
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileDidLoaded);
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileLoadProgressChanged);
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() {
@Override
......@@ -1117,7 +1122,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
try {
ArrayList<SendMessagesHelper.DelayedMessage> delayedMessages = SendMessagesHelper.getInstance().getDelayedMessages(fileName);
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) {
long dialog_id = delayedMessage.obj.getDialogId();
Long lastTime = typingTimes.get(dialog_id);
......@@ -2477,7 +2483,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
Cursor cursor = null;
try {
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) {
int imageIdColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID);
int bucketIdColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID);
......@@ -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) {
albums.clear();
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) {
int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._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;
import android.app.Activity;
import android.net.Uri;
import android.util.Log;
import net.hockeyapp.android.Constants;
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 net.hockeyapp.android.utils.SimpleMultipartEntity;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
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.UUID;
......@@ -24,7 +25,7 @@ public class NativeCrashManager {
for (String dumpFilename : filenames) {
String logFilename = createLogFile();
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 {
@Override
public void run() {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("https://rink.hockeyapp.net/api/2/apps/" + identifier + "/crashes/upload");
MultipartEntity entity = new MultipartEntity();
File dumpFile = new File(Constants.FILES_PATH, dumpFilename);
entity.addPart("attachment0", new FileBody(dumpFile));
File logFile = new File(Constants.FILES_PATH, logFilename);
entity.addPart("log", new FileBody(logFile));
httpPost.setEntity(entity);
httpClient.execute(httpPost);
} catch (Exception e) {
FileLog.e("tmessages", e);
SimpleMultipartEntity entity = new SimpleMultipartEntity();
entity.writeFirstBoundaryIfNeeds();
Uri attachmentUri = Uri.fromFile(new File(Constants.FILES_PATH, dumpFilename));
InputStream input = activity.getContentResolver().openInputStream(attachmentUri);
entity.addPart("attachment0", attachmentUri.getLastPathSegment(), input, false);
attachmentUri = Uri.fromFile(new File(Constants.FILES_PATH, logFilename));
input = activity.getContentResolver().openInputStream(attachmentUri);
entity.addPart("log", attachmentUri.getLastPathSegment(), input, false);
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 {
activity.deleteFile(logFilename);
activity.deleteFile(dumpFilename);
......
......@@ -23,7 +23,7 @@ import java.util.zip.ZipFile;
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_SO_NAME = "lib" + LIB_NAME + ".so";
private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so";
......
......@@ -80,7 +80,9 @@ public class SecretChatHelper {
newMsg.action.encryptedAction = decryptedMessage;
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
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.to_id = new TLRPC.TL_peerUser();
newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
......@@ -869,7 +871,8 @@ public class SecretChatHelper {
newMessage.to_id = new TLRPC.TL_peerUser();
newMessage.random_id = random_id;
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;
if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) {
newMessage.media = new TLRPC.TL_messageMediaEmpty();
......@@ -1043,7 +1046,8 @@ public class SecretChatHelper {
}
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
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.from_id = from_id;
newMessage.to_id = new TLRPC.TL_peerUser();
......
......@@ -61,7 +61,7 @@ public class TgChooserTargetService extends ChooserTargetService {
ArrayList<Integer> usersToLoad = new ArrayList<>();
usersToLoad.add(UserConfig.getClientUserId());
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()) {
long id = cursor.longValue(0);
......@@ -109,11 +109,13 @@ public class TgChooserTargetService extends ChooserTargetService {
for (int b = 0; b < users.size(); b++) {
TLRPC.User user = users.get(b);
if (user.id == id) {
extras.putLong("dialogId", (long) id);
if (user.photo != null && user.photo.photo_small != null) {
icon = createRoundBitmap(FileLoader.getPathToAttach(user.photo.photo_small, true));
if (!user.bot) {
extras.putLong("dialogId", (long) id);
if (user.photo != null && user.photo.photo_small != null) {
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;
}
}
......@@ -121,11 +123,13 @@ public class TgChooserTargetService extends ChooserTargetService {
for (int b = 0; b < chats.size(); b++) {
TLRPC.Chat chat = chats.get(b);
if (chat.id == -id) {
extras.putLong("dialogId", (long) id);
if (chat.photo != null && chat.photo.photo_small != null) {
icon = createRoundBitmap(FileLoader.getPathToAttach(chat.photo.photo_small, true));
if (!ChatObject.isNotInChat(chat) && (!ChatObject.isChannel(chat) || chat.megagroup)) {
extras.putLong("dialogId", (long) id);
if (chat.photo != null && chat.photo.photo_small != null) {
icon = createRoundBitmap(FileLoader.getPathToAttach(chat.photo.photo_small, true));
}
name = chat.title;
}
name = chat.title;
break;
}
}
......
......@@ -41,7 +41,13 @@ public class UserConfig {
public static boolean useFingerprint = true;
public static int lastUpdateVersion;
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() {
int id;
......@@ -79,9 +85,17 @@ public class UserConfig {
editor.putInt("lastPauseTime", lastPauseTime);
editor.putInt("lastUpdateVersion", lastUpdateVersion);
editor.putInt("lastContactsSyncTime", lastContactsSyncTime);
editor.putBoolean("channelsLoaded", channelsLoaded);
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 (withFile) {
SerializedData data = new SerializedData();
......@@ -212,7 +226,16 @@ public class UserConfig {
useFingerprint = preferences.getBoolean("useFingerprint", true);
lastUpdateVersion = preferences.getInt("lastUpdateVersion", 511);
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);
if (user != null) {
byte[] userBytes = Base64.decode(user, Base64.DEFAULT);
......@@ -277,7 +300,12 @@ public class UserConfig {
lastBroadcastId = -1;
saveIncomingPhotos = false;
blockedUsersLoaded = false;
channelsLoaded = false;
migrateOffsetId = -1;
migrateOffsetDate = -1;
migrateOffsetUserId = -1;
migrateOffsetChatId = -1;
migrateOffsetChannelId = -1;
migrateOffsetAccess = -1;
appLocked = false;
passcodeType = 0;
passcodeHash = "";
......
......@@ -14,15 +14,15 @@ import org.telegram.tgnet.TLRPC;
public class UserObject {
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) {
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) {
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) {
......
......@@ -32,6 +32,6 @@ public class WearReplyReceiver extends BroadcastReceiver {
return;
}
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;
import java.util.ArrayList;
@SuppressWarnings("unchecked")
public class MessagesSearchQuery {
private static int reqId;
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 String lastSearchQuery;
private static int lastReturnedNum;
private static int getMask() {
int mask = 0;
if (lastReturnedNum < searchResultMessages.size() - 1) {
if (lastReturnedNum < searchResultMessages.size() - 1 || !messagesSearchEndReached[0] || !messagesSearchEndReached[1]) {
mask |= 1;
}
if (lastReturnedNum > 0) {
......@@ -40,25 +41,37 @@ public class MessagesSearchQuery {
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) {
ConnectionsManager.getInstance().cancelRequest(reqId, true);
reqId = 0;
}
int max_id = 0;
long queryWithDialog = dialog_id;
if (query == null || query.length() == 0) {
if (direction == 1) {
lastReturnedNum++;
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;
} else {
if (messagesSearchEndReached) {
if (messagesSearchEndReached[0] && mergeDialogId == 0 || messagesSearchEndReached[1]) {
lastReturnedNum--;
return;
}
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) {
lastReturnedNum--;
......@@ -66,15 +79,22 @@ public class MessagesSearchQuery {
lastReturnedNum = 0;
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;
} else {
return;
}
}
if (messagesSearchEndReached[0] && !messagesSearchEndReached[1] && mergeDialogId != 0) {
queryWithDialog = mergeDialogId;
}
final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
req.limit = 21;
int lower_part = (int) dialog_id;
int lower_part = (int) queryWithDialog;
req.peer = MessagesController.getInputPeer(lower_part);
if (req.peer == null) {
return;
......@@ -84,19 +104,21 @@ public class MessagesSearchQuery {
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
final int currentReqId = ++lastReqId;
lastSearchQuery = query;
final long queryWithDialogFinal = queryWithDialog;
reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(final TLObject response, final TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
reqId = 0;
if (currentReqId == lastReqId) {
if (error == null) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true);
MessagesController.getInstance().putUsers(res.users, false);
MessagesController.getInstance().putChats(res.chats, false);
if (req.max_id == 0) {
if (req.max_id == 0 && queryWithDialogFinal == dialog_id) {
lastReturnedNum = 0;
searchResultMessages.clear();
}
......@@ -106,17 +128,27 @@ public class MessagesSearchQuery {
added = true;
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()) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask());
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), (long) 0);
} else {
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 {
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
message.dialog_id = dialog_id;
if (message.from_id > 0) {
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);
}
}
MessagesStorage.addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
result.add(message);
replyMessages.remove((Integer) message.id);
}
......@@ -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) {
final HashMap<Integer, TLRPC.User> usersHashMap = new HashMap<>();
for (TLRPC.User user : users) {
usersHashMap.put(user.id, user);
final HashMap<Integer, TLRPC.User> usersDict = new HashMap<>();
for (int a = 0; a < users.size(); a++) {
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() {
@Override
......@@ -216,11 +190,13 @@ public class ReplyMessageQuery {
MessagesController.getInstance().putUsers(users, isCache);
MessagesController.getInstance().putChats(chats, isCache);
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);
if (arrayList != null) {
MessageObject messageObject = new MessageObject(message, usersHashMap, false);
for (MessageObject m : arrayList) {
MessageObject messageObject = new MessageObject(message, usersDict, chatsDict, false);
for (int b = 0; b < arrayList.size(); b++) {
MessageObject m = arrayList.get(b);
m.replyMessageObject = messageObject;
}
changed = true;
......
......@@ -27,6 +27,7 @@ import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class ConnectionsManager {
......@@ -57,7 +58,7 @@ public class ConnectionsManager {
private int lastClassGuid = 1;
private boolean isUpdating = false;
private int connectionState = native_getConnectionState();
private volatile int lastRequestToken = 1;
private AtomicInteger lastRequestToken = new AtomicInteger(1);
private PowerManager.WakeLock wakeLock = null;
private static volatile ConnectionsManager Instance = null;
......@@ -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) {
final int requestToken = lastRequestToken++;
final int requestToken = lastRequestToken.getAndIncrement();
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
FileLog.d("tmessages", "send request " + object);
FileLog.d("tmessages", "send request " + object + " with token = " + requestToken);
NativeByteBuffer buffer = new NativeByteBuffer(object.getObjectSize());
object.serializeToStream(buffer);
object.freeResources();
......
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