1
0
mirror of https://github.com/MGislv/NekoX.git synced 2024-07-02 10:33:36 +00:00

update to 1.3.2

This commit is contained in:
DrKLO 2013-12-20 23:25:49 +04:00
parent 90d8e8a370
commit d52ade4855
969 changed files with 20183 additions and 14775 deletions

View File

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4"> <module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/classes/main" />
<output-test url="file://$MODULE_DIR$/build/classes/test" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" /> <excludeFolder url="file://$MODULE_DIR$/.gradle" />

View File

@ -3,10 +3,10 @@
<component name="FacetManager"> <component name="FacetManager">
<facet type="android" name="Android"> <facet type="android" name="Android">
<configuration> <configuration>
<option name="SELECTED_BUILD_VARIANT" value="Debug" /> <option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebug" /> <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleTest" /> <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" /> <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ALLOW_USER_CONFIGURATION" value="false" /> <option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
@ -26,37 +26,37 @@
<output url="file://$MODULE_DIR$/build/classes/debug" /> <output url="file://$MODULE_DIR$/build/classes/debug" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/source/r/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/source/r/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/source/rs/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/build/res/rs/test/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/assets" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/assets" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/jni" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/build/apk" /> <excludeFolder url="file://$MODULE_DIR$/build/apk" />
<excludeFolder url="file://$MODULE_DIR$/build/assets" /> <excludeFolder url="file://$MODULE_DIR$/build/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/bundles" /> <excludeFolder url="file://$MODULE_DIR$/build/bundles" />
@ -65,16 +65,17 @@
<excludeFolder url="file://$MODULE_DIR$/build/incremental" /> <excludeFolder url="file://$MODULE_DIR$/build/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/libs" /> <excludeFolder url="file://$MODULE_DIR$/build/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/manifests" /> <excludeFolder url="file://$MODULE_DIR$/build/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/res" />
<excludeFolder url="file://$MODULE_DIR$/build/symbols" /> <excludeFolder url="file://$MODULE_DIR$/build/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" /> <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content> </content>
<orderEntry type="jdk" jdkName="Android 4.3 Platform" jdkType="Android SDK" /> <orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-v4-18.0.0" level="project" /> <orderEntry type="library" exported="" name="HockeySDK-3.0.1" level="project" />
<orderEntry type="library" exported="" name="ComGoogleAndroidGmsPlayServices3159.aar" level="project" /> <orderEntry type="library" exported="" name="ComGoogleAndroidGmsPlayServices4030.aar" level="project" />
<orderEntry type="library" exported="" name="HockeySDK-3.0.0" level="project" />
<orderEntry type="library" exported="" name="native-libs" level="project" /> <orderEntry type="library" exported="" name="native-libs" level="project" />
<orderEntry type="library" exported="" name="ComActionbarsherlockActionbarsherlock440.aar" level="project" /> <orderEntry type="library" exported="" name="support-v4-19.0.0" level="project" />
<orderEntry type="library" exported="" name="ComAndroidSupportAppcompatV71900.aar" level="project" />
</component> </component>
</module> </module>

View File

@ -3,7 +3,7 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:0.5.+' classpath 'com.android.tools.build:gradle:0.7.+'
} }
} }
apply plugin: 'android' apply plugin: 'android'
@ -22,25 +22,49 @@ task nativeLibsToJar(
into 'lib/' into 'lib/'
} }
tasks.withType(Compile) { tasks.withType(JavaCompile) {
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
tasks.withType(Compile) { tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(nativeLibsToJar) compileTask -> compileTask.dependsOn(nativeLibsToJar)
} }
dependencies { dependencies {
compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
compile 'com.google.android.gms:play-services:4.0.+' compile 'com.google.android.gms:play-services:4.0.+'
compile 'net.hockeyapp.android:HockeySDK:3.0.1' compile 'net.hockeyapp.android:HockeySDK:3.0.1'
compile 'com.android.support:support-v4:19.0.+' compile 'com.android.support:support-v4:19.0.+'
compile fileTree(dir: "$buildDir/native-libs", include: '*.jar') compile 'com.android.support:appcompat-v7:19.0.+'
compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
} }
android { android {
compileSdkVersion 19 compileSdkVersion 19
buildToolsVersion "19.0.0" buildToolsVersion '19.0.0'
signingConfigs {
debug {
storeFile file("debug.keystore")
}
release {
storeFile file("release.keystore")
}
}
buildTypes {
debug {
debuggable true
jniDebugBuild true
signingConfig signingConfigs.debug
}
release {
debuggable false
jniDebugBuild false
signingConfig signingConfigs.release
}
}
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8

View File

@ -1,10 +1,11 @@
NDK_TOOLCHAIN_VERSION := 4.8
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := tmessages LOCAL_MODULE := tmessages
LOCAL_CFLAGS = -w LOCAL_CFLAGS = -w -std=gnu99 -O3
LOCAL_LDLIBS := -llog LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
./aes_core.c \ ./aes_core.c \
./aes_ige.c \ ./aes_ige.c \
@ -15,5 +16,6 @@ LOCAL_SRC_FILES := \
./org_telegram_SQLite_SQLiteDatabase.c \ ./org_telegram_SQLite_SQLiteDatabase.c \
./org_telegram_SQLite_SQLitePreparedStatement.c \ ./org_telegram_SQLite_SQLitePreparedStatement.c \
./org_telegram_SQLite.c ./org_telegram_SQLite.c
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)

View File

@ -1,2 +1,2 @@
APP_PLATFORM := android-8 APP_PLATFORM := android-9
APP_ABI := armeabi armeabi-v7a x86 mips APP_ABI := armeabi armeabi-v7a x86

View File

@ -0,0 +1,128 @@
#!/bin/bash
function build_one {
echo "Cleaning..."
make clean
echo "Configuring..."
./configure --target-os=linux \
--prefix=$PREFIX \
--enable-cross-compile \
--extra-libs="-lgcc" \
--arch=$ARCH \
--cc=$CC \
--cross-prefix=$CROSS_PREFIX \
--nm=$NM \
--sysroot=$PLATFORM \
--extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -fasm -Wno-psabi -fno-short-enums -Dipv6mr_interface=ipv6mr_ifindex -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS " \
--disable-shared \
--enable-static \
--extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl" \
\
--disable-everything \
--disable-network \
--enable-small \
--enable-zlib \
--disable-avfilter \
--disable-avdevice \
--disable-programs \
--disable-doc \
--disable-lsp \
--disable-dwt \
--disable-dct \
--enable-stripping \
--disable-postproc \
--disable-fft \
--disable-lzo \
--disable-rdft \
--disable-mdct \
--disable-debug \
\
--enable-muxer='mp4' \
--enable-protocol='file' \
--enable-encoder='aac,mpeg4' \
--enable-decoder='aac,amrnb,amrwb,flv,h263,h264' \
--enable-demuxer='flv,mpegvideo,mov' \
--enable-hwaccel='mpeg4_vaapi,mpeg4_vdpau' \
--enable-swresample \
--enable-swscale \
--enable-asm \
$ADDITIONAL_CONFIGURE_FLAG
echo "continue?"
read
make -j8 install
#$AR d libavcodec/libavcodec.a inverse.o
#$LD -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -soname libffmpeg.a -static -nostdlib -z noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a -lc -lm -lz -ldl --dynamic-linker=/system/bin/linker $GCCLIB
}
NDK=/Users/DrKLO/ndk9
#arm platform
PLATFORM=$NDK/platforms/android-8/arch-arm
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64
LD=$PREBUILT/bin/arm-linux-androideabi-ld
AR=$PREBUILT/bin/arm-linux-androideabi-ar
NM=$PREBUILT/bin/arm-linux-androideabi-nm
GCCLIB=$PREBUILT/lib/gcc/arm-linux-androideabi/4.8/libgcc.a
ARCH=arm
CC=$PREBUILT/bin/arm-linux-androideabi-gcc
CROSS_PREFIX=$PREBUILT/bin/arm-linux-androideabi-
#arm v6
CPU=armv6
OPTIMIZE_CFLAGS="-marm -march=$CPU"
PREFIX=/Users/DrKLO/ndk9/platforms/android-9/arch-$ARCH/usr
ADDITIONAL_CONFIGURE_FLAG=
build_one
#arm v7vfpv3
#CPU=armv7-a
#OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU "
#PREFIX=./android/$CPU
#ADDITIONAL_CONFIGURE_FLAG=
#build_one
#arm v7vfp
#CPU=armv7-a
#OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
#PREFIX=./android/$CPU-vfp
#ADDITIONAL_CONFIGURE_FLAG=
#build_one
#arm v7n
#CPU=armv7-a
#OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=neon -marm -march=$CPU -mtune=cortex-a8"
#PREFIX=./android/$CPU
#ADDITIONAL_CONFIGURE_FLAG=--enable-neon
#build_one
#arm v6+vfp
#CPU=armv6
#OPTIMIZE_CFLAGS="-DCMP_HAVE_VFP -mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU"
#PREFIX=./android/${CPU}_vfp
#ADDITIONAL_CONFIGURE_FLAG=
#build_one
#x86 platform
PLATFORM=$NDK/platforms/android-9/arch-x86
PREBUILT=$NDK/toolchains/x86-4.8/prebuilt/darwin-x86_64
LD=$PREBUILT/bin/i686-linux-android-ld
AR=$PREBUILT/bin/i686-linux-android-ar
NM=$PREBUILT/bin/i686-linux-android-nm
GCCLIB=$PREBUILT/lib/gcc/i686-linux-android/4.8/libgcc.a
ARCH=x86
CC=$PREBUILT/bin/i686-linux-android-gcc
CROSS_PREFIX=$PREBUILT/bin/i686-linux-android-
CPU=i686
OPTIMIZE_CFLAGS="-march=$CPU"
PREFIX=/Users/DrKLO/ndk9/platforms/android-9/arch-$ARCH/usr
ADDITIONAL_CONFIGURE_FLAG="--disable-mmx --disable-yasm"
build_one

View File

@ -5,12 +5,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <android/log.h> #include <android/log.h>
#include "aes.h" #include "aes.h"
#include "log.h"
#define LOG_TAG "tmessages_native"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
JNIEXPORT jbyteArray Java_org_telegram_messenger_Utilities_aesIgeEncryption(JNIEnv *env, jclass class, jbyteArray _what, jbyteArray _key, jbyteArray _iv, jboolean encrypt, jboolean changeIv) { JNIEXPORT jbyteArray Java_org_telegram_messenger_Utilities_aesIgeEncryption(JNIEnv *env, jclass class, jbyteArray _what, jbyteArray _key, jbyteArray _iv, jboolean encrypt, jboolean changeIv) {
unsigned char *what = (unsigned char *)(*env)->GetByteArrayElements(env, _what, NULL); unsigned char *what = (unsigned char *)(*env)->GetByteArrayElements(env, _what, NULL);
@ -84,100 +79,3 @@ JNIEXPORT jlong Java_org_telegram_messenger_Utilities_doPQNative(JNIEnv* env, jc
} }
return g; return g;
} }
//sqlite
/*JNIEXPORT void Java_org_telegram_messenger_Utilities_beginTransaction(JNIEnv* env, jobject object, int dbHandle) {
sqlite3 *db = (sqlite3 *)dbHandle;
if (db == NULL) {
return;
}
sqlite3_exec(db, "BEGIN", 0, 0, 0);
}
JNIEXPORT void Java_org_telegram_messenger_Utilities_commitTransaction(JNIEnv* env, jobject object, int dbHandle) {
sqlite3 *db = (sqlite3 *)dbHandle;
if (db == NULL) {
return;
}
sqlite3_exec(db, "COMMIT", 0, 0, 0);
}
int Java_org_telegram_messenger_Utilities_step(JNIEnv* env, jobject object, int statementHandle) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int errcode = 0 ;
errcode = sqlite3_step(handle);
if (errcode == SQLITE_ROW) {
return 0;
} else if(errcode == SQLITE_DONE) {
return 1;
} else if(errcode == SQLITE_BUSY) {
return -1;
}
throw_sqlite3_exception(env, sqlite3_db_handle(handle), errcode);
}
int Java_org_telegram_messenger_Utilities_columnType(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
return sqlite3_column_type(handle, columnIndex);
}
int Java_org_telegram_messenger_Utilities_columnIsNull(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
return SQLITE_NULL == valType;
}
int Java_org_telegram_messenger_Utilities_columnIntValue(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_int(handle, columnIndex);
}
jdouble Java_org_telegram_messenger_Utilities_columnDoubleValue(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
int valType = sqlite3_column_type(handle, columnIndex);
if (SQLITE_NULL == valType) {
return 0;
}
return sqlite3_column_double(handle, columnIndex);
}
jstring Java_org_telegram_messenger_Utilities_columnStringValue(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
const char* str = sqlite3_column_text(handle, columnIndex);
if (str != 0) {
return (*env)->NewStringUTF(env, str);
}
return 0;
}
jbyteArray Java_org_telegram_messenger_Utilities_columnByteArrayValue(JNIEnv* env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
void *buf = sqlite3_column_blob(handle, columnIndex);
int length = sqlite3_column_bytes(handle, columnIndex);
if (buf != 0 && length > 0) {
jbyteArray result = (*env)->NewByteArray(env, length);
(*env)->SetByteArrayRegion(env, result, 0, length, buf);
return result;
}
return 0;
}*/

12
TMessagesProj/jni/log.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef log_h
#define log_h
#include <android/log.h>
#define LOG_TAG "tmessages_native"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#endif

View File

@ -18,8 +18,15 @@ void Java_org_telegram_SQLite_SQLiteDatabase_commitTransaction(JNIEnv *env, jobj
sqlite3_exec(handle, "COMMIT", 0, 0, 0); sqlite3_exec(handle, "COMMIT", 0, 0, 0);
} }
int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object, jstring fileName) { int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object, jstring fileName, jstring tempDir) {
char const *fileNameStr = (*env)->GetStringUTFChars(env, fileName, 0); char const *fileNameStr = (*env)->GetStringUTFChars(env, fileName, 0);
char const *tempDirStr = (*env)->GetStringUTFChars(env, tempDir, 0);
if (sqlite3_temp_directory != 0) {
sqlite3_free(sqlite3_temp_directory);
}
sqlite3_temp_directory = sqlite3_mprintf("%s", tempDirStr);
sqlite3 *handle = 0; sqlite3 *handle = 0;
int err = sqlite3_open(fileNameStr, &handle); int err = sqlite3_open(fileNameStr, &handle);
if (SQLITE_OK != err) { if (SQLITE_OK != err) {
@ -28,5 +35,8 @@ int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object,
if (fileNameStr != 0) { if (fileNameStr != 0) {
(*env)->ReleaseStringUTFChars(env, fileName, fileNameStr); (*env)->ReleaseStringUTFChars(env, fileName, fileNameStr);
} }
if (tempDirStr != 0) {
(*env)->ReleaseStringUTFChars(env, tempDir, tempDirStr);
}
return (int)handle; return (int)handle;
} }

File diff suppressed because it is too large Load Diff

View File

@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.7.17" #define SQLITE_VERSION "3.8.1"
#define SQLITE_VERSION_NUMBER 3007017 #define SQLITE_VERSION_NUMBER 3008001
#define SQLITE_SOURCE_ID "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668" #define SQLITE_SOURCE_ID "2013-10-17 12:57:35 c78be6d786c19073b3a6730dfe3fb1be54f5657a"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@ -478,11 +478,15 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@ -499,6 +503,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
/* /*
** CAPI3REF: Flags For File Open Operations ** CAPI3REF: Flags For File Open Operations
@ -1612,27 +1617,27 @@ struct sqlite3_mem_methods {
** function must be threadsafe. </dd> ** function must be threadsafe. </dd>
** **
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
** <dd> This option takes a single argument of type int. If non-zero, then ** <dd>^(This option takes a single argument of type int. If non-zero, then
** URI handling is globally enabled. If the parameter is zero, then URI handling ** URI handling is globally enabled. If the parameter is zero, then URI handling
** is globally disabled. If URI handling is globally enabled, all filenames ** is globally disabled.)^ ^If URI handling is globally enabled, all filenames
** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or ** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless ** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
** connection is opened. If it is globally disabled, filenames are ** connection is opened. ^If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** database connection is opened. By default, URI handling is globally ** database connection is opened. ^(By default, URI handling is globally
** disabled. The default value may be changed by compiling with the ** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined. ** [SQLITE_USE_URI] symbol defined.)^
** **
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd> This option takes a single integer argument which is interpreted as ** <dd>^This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for ** a boolean in order to enable or disable the use of covering indices for
** full table scans in the query optimizer. The default setting is determined ** full table scans in the query optimizer. ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on" ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted. ** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans ** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction ** is because some incorrectly coded legacy applications might malfunction
** malfunction when the optimization is enabled. Providing the ability to ** when the optimization is enabled. Providing the ability to
** disable the optimization allows the older, buggy application code to work ** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite. ** without change even with newer versions of SQLite.
** **
@ -1661,16 +1666,16 @@ struct sqlite3_mem_methods {
** **
** [[SQLITE_CONFIG_MMAP_SIZE]] ** [[SQLITE_CONFIG_MMAP_SIZE]]
** <dt>SQLITE_CONFIG_MMAP_SIZE ** <dt>SQLITE_CONFIG_MMAP_SIZE
** <dd>SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values ** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** that are the default mmap size limit (the default setting for ** that are the default mmap size limit (the default setting for
** [PRAGMA mmap_size]) and the maximum allowed mmap size limit. ** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
** The default setting can be overridden by each database connection using ** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the ** either the [PRAGMA mmap_size] command, or by using the
** [SQLITE_FCNTL_MMAP_SIZE] file control. The maximum allowed mmap size ** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size
** cannot be changed at run-time. Nor may the maximum allowed mmap size ** cannot be changed at run-time. Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the ** exceed the compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option. ** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** If either argument to this option is negative, then that argument is ** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default. ** changed to its compile-time default.
** </dl> ** </dl>
*/ */
@ -2557,9 +2562,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
** interface is to keep a GUI updated during a large query. ** interface is to keep a GUI updated during a large query.
** **
** ^The parameter P is passed through as the only parameter to the ** ^The parameter P is passed through as the only parameter to the
** callback function X. ^The parameter N is the number of ** callback function X. ^The parameter N is the approximate number of
** [virtual machine instructions] that are evaluated between successive ** [virtual machine instructions] that are evaluated between successive
** invocations of the callback X. ** invocations of the callback X. ^If N is less than one then the progress
** handler is disabled.
** **
** ^Only a single progress handler may be defined at one time per ** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the ** [database connection]; setting a new progress handler cancels the
@ -4179,41 +4185,49 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/* /*
** CAPI3REF: Function Auxiliary Data ** CAPI3REF: Function Auxiliary Data
** **
** The following two functions may be used by scalar SQL functions to ** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to ** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under ** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved. This may ** some circumstances the associated metadata may be preserved. An example
** be used, for example, to add a regular-expression matching scalar ** of where this might be useful is in a regular-expression matching
** function. The compiled version of the regular expression is stored as ** function. The compiled version of the regular expression can be stored as
** metadata associated with the SQL value passed as the regular expression ** metadata associated with the pattern string.
** pattern. The compiled regular expression can be reused on multiple ** Then as long as the pattern string remains the same,
** invocations of the same function so that the original pattern string ** the compiled regular expression can be reused on multiple
** does not need to be recompiled on each invocation. ** invocations of the same function.
** **
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument ** associated by the sqlite3_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If no metadata has been ever ** value to the application-defined function. ^If there is no metadata
** been set for the Nth argument of the function, or if the corresponding ** associated with the function argument, this sqlite3_get_auxdata() interface
** function parameter has changed since the meta-data was set, ** returns a NULL pointer.
** then sqlite3_get_auxdata() returns a NULL pointer.
** **
** ^The sqlite3_set_auxdata() interface saves the metadata ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** pointed to by its 3rd parameter as the metadata for the N-th ** argument of the application-defined function. ^Subsequent
** argument of the application-defined function. Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent
** calls to sqlite3_get_auxdata() might return this data, if it has ** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
** not been destroyed. ** NULL if the metadata has been discarded.
** ^If it is not NULL, SQLite will invoke the destructor ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
** function given by the 4th parameter to sqlite3_set_auxdata() on ** SQLite will invoke the destructor function X with parameter P exactly
** the metadata when the corresponding function parameter changes ** once, when the metadata is discarded.
** or when the SQL statement completes, whichever comes first. ** SQLite is free to discard the metadata at any time, including: <ul>
** <li> when the corresponding function parameter changes, or
** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
** SQL statement, or
** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
** <li> during the original sqlite3_set_auxdata() call when a memory
** allocation error occurs. </ul>)^
** **
** SQLite is free to call the destructor and drop metadata on any ** Note the last bullet in particular. The destructor X in
** parameter of any function at any time. ^The only guarantee is that ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
** the destructor will be called before the metadata is dropped. ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
** should be called near the end of the function implementation and the
** function implementation should not make any use of P after
** sqlite3_set_auxdata() has been called.
** **
** ^(In practice, metadata is preserved between function calls for ** ^(In practice, metadata is preserved between function calls for
** expressions that are constant at compile time. This includes literal ** function parameters that are compile-time constants, including literal
** values and [parameters].)^ ** values and [parameters] and expressions composed from the same.)^
** **
** These routines must be called from the same thread in which ** These routines must be called from the same thread in which
** the SQL function is running. ** the SQL function is running.
@ -4518,6 +4532,11 @@ SQLITE_API int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */ sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */ const void *pKey, int nKey /* The key */
); );
SQLITE_API int sqlite3_key_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The key */
);
/* /*
** Change the key on an open database. If the current database is not ** Change the key on an open database. If the current database is not
@ -4531,6 +4550,11 @@ SQLITE_API int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */ sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */ const void *pKey, int nKey /* The new key */
); );
SQLITE_API int sqlite3_rekey_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The new key */
);
/* /*
** Specify the activation key for a SEE database. Unless ** Specify the activation key for a SEE database. Unless
@ -5116,10 +5140,23 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** on the list of automatic extensions is a harmless no-op. ^No entry point ** on the list of automatic extensions is a harmless no-op. ^No entry point
** will be called more than once for each database connection that is opened. ** will be called more than once for each database connection that is opened.
** **
** See also: [sqlite3_reset_auto_extension()]. ** See also: [sqlite3_reset_auto_extension()]
** and [sqlite3_cancel_auto_extension()]
*/ */
SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
/*
** CAPI3REF: Cancel Automatic Extension Loading
**
** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
** initialization routine X that was registered using a prior call to
** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
** routine returns 1 if initialization routine X was successfully
** unregistered and it returns 0 if X was not on the list of initialization
** routines.
*/
SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
/* /*
** CAPI3REF: Reset Automatic Extension Loading ** CAPI3REF: Reset Automatic Extension Loading
** **
@ -6232,6 +6269,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd> ** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns zero for the current value if and only if
** all foreign key constraints (deferred or immediate) have been
** resolved.)^ ^The highwater mark is always 0.
** </dd>
** </dl> ** </dl>
*/ */
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_LOOKASIDE_USED 0
@ -6244,7 +6287,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_HIT 7
#define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_MISS 8
#define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_CACHE_WRITE 9
#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */ #define SQLITE_DBSTATUS_DEFERRED_FKS 10
#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
/* /*
@ -6298,11 +6342,21 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
** A non-zero value in this counter may indicate an opportunity to ** A non-zero value in this counter may indicate an opportunity to
** improvement performance by adding permanent indices that do not ** improvement performance by adding permanent indices that do not
** need to be reinitialized each time the statement is run.</dd> ** need to be reinitialized each time the statement is run.</dd>
**
** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
** <dd>^This is the number of virtual machine operations executed
** by the prepared statement if that number is less than or equal
** to 2147483647. The number of virtual machine operations can be
** used as a proxy for the total work done by the prepared statement.
** If the number of virtual machine operations exceeds 2147483647
** then the value returned by this statement status code is undefined.
** </dd>
** </dl> ** </dl>
*/ */
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2 #define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3 #define SQLITE_STMTSTATUS_AUTOINDEX 3
#define SQLITE_STMTSTATUS_VM_STEP 4
/* /*
** CAPI3REF: Custom Page Cache Object ** CAPI3REF: Custom Page Cache Object
@ -7181,7 +7235,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
#ifdef __cplusplus #ifdef __cplusplus
} /* End of the 'extern "C"' block */ } /* End of the 'extern "C"' block */
#endif #endif
#endif #endif /* _SQLITE3_H_ */
/* /*
** 2010 August 30 ** 2010 August 30

View File

@ -474,11 +474,14 @@ struct sqlite3_api_routines {
** extension */ ** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3 \
extern const sqlite3_api_routines *sqlite3_api;
#else #else
/* This case when the file is being statically linked into the /* This case when the file is being statically linked into the
** application */ ** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/ # define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif #endif
#endif /* _SQLITE3EXT_H_ */ #endif /* _SQLITE3EXT_H_ */

18
TMessagesProj/jni/video.c Normal file
View File

@ -0,0 +1,18 @@
#include <jni.h>
#include "video.h"
JNIEXPORT void Java_org_telegram_messenger_VideoTools_initialize(JNIEnv* env, jclass class) {
av_register_all();
}
JNIEXPORT void Java_org_telegram_messenger_VideoTools_convert(JNIEnv* env, jclass class, jstring in, jstring out, int bitr) {
char const *in_str = (*env)->GetStringUTFChars(env, in, 0);
char const *out_str = (*env)->GetStringUTFChars(env, out, 0);
convertFile(in_str, out_str, bitr);
if (in_str != 0) {
(*env)->ReleaseStringUTFChars(env, in, in_str);
}
if (out_str != 0) {
(*env)->ReleaseStringUTFChars(env, out, out_str);
}
}

17
TMessagesProj/jni/video.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef video_h
#define video_h
#include <libavformat/avformat.h>
int prepare_for_video_conversion(const char *dst_filename, AVCodecContext *video_dec_ctx, AVCodecContext *audio_dec_ctx, AVFormatContext *fmt_ctx, AVStream *src_video_stream, AVStream *src_audio_stream, int bitr);
int write_video_frame(AVFrame *src_frame);
int write_audio_frame(AVFrame *src_frame, AVCodecContext *src_codec);
void post_video_conversion();
void cleanup_out();
void onError();
void onProgress();
void onDone();
void convertFile(const char *src_filename, const char *dst_filename, int bitr);
#endif

View File

@ -0,0 +1,243 @@
#include "video.h"
#include <stdio.h>
#include <libavutil/timestamp.h>
#include <libavutil/imgutils.h>
#include "log.h"
AVPacket pkt;
int video_stream_idx = -1, audio_stream_idx = -1;
AVCodecContext *video_dec_ctx = NULL, *audio_dec_ctx = NULL;
AVFrame *frame = NULL;
AVStream *video_stream = NULL, *audio_stream = NULL;
AVFormatContext *fmt_ctx = NULL;
int64_t total_duration;
int64_t current_duration;
char *src = NULL;
char *dest = NULL;
int lastLog = 10;
void cleanup_in() {
if (video_dec_ctx) {
avcodec_close(video_dec_ctx);
video_dec_ctx = NULL;
}
if (audio_dec_ctx) {
avcodec_close(audio_dec_ctx);
audio_dec_ctx = NULL;
}
if (fmt_ctx) {
avformat_close_input(&fmt_ctx);
fmt_ctx = NULL;
}
if (frame) {
av_frame_free(&frame);
frame = NULL;
}
if (src) {
free(src);
src = NULL;
}
if (dest) {
free(dest);
dest = NULL;
}
total_duration = 0;
current_duration = 0;
video_stream_idx = -1;
audio_stream_idx = -1;
video_stream = NULL;
audio_stream = NULL;
lastLog = 10;
}
void onError() {
cleanup_in();
cleanup_out();
}
void onDone() {
LOGD("OK\n");
cleanup_in();
cleanup_out();
}
void onProgress() {
float progress = (float)current_duration / (float)total_duration * 100;
if (progress > lastLog) {
lastLog += 10;
LOGD("progress %.2f\n", progress);
}
}
int open_codec_context(int *stream_idx, AVFormatContext *fmt_ctx, enum AVMediaType type) {
int ret;
AVStream *st;
AVCodecContext *dec_ctx = NULL;
AVCodec *dec = NULL;
AVDictionary *opts = NULL;
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
if (ret < 0) {
LOGD("Could not find %s stream in input file\n", av_get_media_type_string(type));
return ret;
} else {
*stream_idx = ret;
st = fmt_ctx->streams[*stream_idx];
dec_ctx = st->codec;
dec = avcodec_find_decoder(dec_ctx->codec_id);
if (!dec) {
LOGD("Failed to find %s codec\n", av_get_media_type_string(type));
return ret;
}
av_dict_set(&opts, "refcounted_frames", "1", 0);
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
LOGD("Failed to open %s codec\n", av_get_media_type_string(type));
return ret;
}
}
return 0;
}
int decode_packet(int *got_frame, int cached) {
int ret = 0;
int decoded = pkt.size;
*got_frame = 0;
if (pkt.stream_index == video_stream_idx) {
ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
LOGD("Error decoding video frame\n");
return ret;
}
if (*got_frame) {
ret = write_video_frame(frame);
if (ret < 0) {
return ret;
}
}
} else if (pkt.stream_index == audio_stream_idx) {
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
if (ret < 0) {
LOGD("Error decoding audio frame\n");
return ret;
}
decoded = FFMIN(ret, pkt.size);
if (*got_frame) {
ret = write_audio_frame(frame, audio_dec_ctx);
if (ret < 0) {
return -1;
}
}
frame->pts = AV_NOPTS_VALUE;
}
if (*got_frame) {
av_frame_unref(frame);
}
return decoded;
}
void convertFile(const char *src_filename, const char *dst_filename, int bitr) {
int ret = 0;
int got_frame;
src = malloc(strlen(src_filename) + 1);
memcpy(src, src_filename, strlen(src_filename));
src[strlen(src_filename)] = '\0';
dest = malloc(strlen(dst_filename) + 1);
memcpy(dest, dst_filename, strlen(dst_filename));
dest[strlen(dst_filename)] = '\0';
if ((ret = avformat_open_input(&fmt_ctx, src, NULL, NULL)) < 0) {
LOGD("Could not open source file %s, %s\n", src, av_err2str(ret));
onError();
return;
}
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
LOGD("Could not find stream information\n");
onError();
return;
}
if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
video_stream = fmt_ctx->streams[video_stream_idx];
video_dec_ctx = video_stream->codec;
}
if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
audio_stream = fmt_ctx->streams[audio_stream_idx];
audio_dec_ctx = audio_stream->codec;
}
av_dump_format(fmt_ctx, 0, src, 0);
if (!audio_stream && !video_stream) {
LOGD("Could not find audio or video stream in the input, aborting\n");
onError();
return;
}
frame = av_frame_alloc();
if (!frame) {
LOGD("Could not allocate frame\n");
onError();
return;
}
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
if (video_stream) {
LOGD("Demuxing video from file '%s'\n", src);
}
if (audio_stream) {
LOGD("Demuxing audio from file '%s'\n", src);
}
ret = prepare_for_video_conversion(dest, video_dec_ctx, audio_dec_ctx, fmt_ctx, video_stream, audio_stream, bitr);
if (ret < 0) {
return;
}
if (video_stream) {
total_duration = video_stream->duration;
}
if (audio_stream) {
total_duration += audio_stream->duration;
}
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
AVPacket orig_pkt = pkt;
do {
ret = decode_packet(&got_frame, 0);
if (ret < 0) {
onError();
return;
}
pkt.data += ret;
pkt.size -= ret;
current_duration += pkt.duration;
onProgress();
} while (pkt.size > 0);
av_free_packet(&orig_pkt);
}
pkt.data = NULL;
pkt.size = 0;
do {
decode_packet(&got_frame, 1);
} while (got_frame);
post_video_conversion();
onDone();
}

View File

@ -0,0 +1,366 @@
#include "video.h"
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include "log.h"
AVFrame *out_frame = NULL;
struct SwsContext *sws_ctx = NULL;
AVStream *video_st = NULL, *audio_st = NULL;
AVFormatContext *oc = NULL;
AVOutputFormat *fmt = NULL;
AVPicture dst_picture;
uint8_t **dst_samples_data = NULL;
SwrContext *swr_ctx = NULL;
int current_n_out = 0;
int current_in_buff = 0;
uint8_t buff[4096 * 2];
int min(int val1, int val2) {
return val1 < val2 ? val1 : val2;
}
int prepare_for_video_conversion(const char *dst_filename, AVCodecContext *video_dec_ctx, AVCodecContext *audio_dec_ctx, AVFormatContext *fmt_ctx, AVStream *src_video_stream, AVStream *src_audio_stream, int bitr) {
if (!video_dec_ctx && !audio_dec_ctx) {
onError();
return -1;
}
avformat_alloc_output_context2(&oc, NULL, "mp4", dst_filename);
if (!oc) {
onError();
return -1;
}
fmt = oc->oformat;
av_dict_copy(&oc->metadata, fmt_ctx->metadata, 0);
int ret = 0;
if (!(fmt->flags & AVFMT_NOFILE)) {
ret = avio_open(&oc->pb, dst_filename, AVIO_FLAG_WRITE);
if (ret < 0) {
LOGD("Could not open '%s': %s\n", dst_filename, av_err2str(ret));
onError();
return -1;
}
}
AVCodecContext *c;
if (video_dec_ctx && src_video_stream && fmt_ctx) {
//calculate video resolution
int dst_width = video_dec_ctx->width, dst_height = video_dec_ctx->height;
if (video_dec_ctx->width > video_dec_ctx->height) {
if (video_dec_ctx->width > 480) {
float scale = video_dec_ctx->width / 480.0f;
dst_width = 480;
dst_height = ceilf(video_dec_ctx->height / scale);
}
} else {
if (video_dec_ctx->width > 480) {
float scale = video_dec_ctx->height / 480.0f;
dst_height = 480;
dst_width = ceilf(video_dec_ctx->width / scale);
}
}
if (video_dec_ctx->height != dst_height || video_dec_ctx->width != dst_width || video_dec_ctx->pix_fmt != AV_PIX_FMT_YUV420P) {
sws_ctx = sws_getContext(video_dec_ctx->width, video_dec_ctx->height, video_dec_ctx->pix_fmt, dst_width, dst_height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);
if (!sws_ctx) {
LOGD("Could not initialize the conversion context\n");
onError();
return -1;
}
}
//create video stream
AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
if (!codec) {
LOGD("Could not find encoder for '%s'\n", avcodec_get_name(AV_CODEC_ID_MPEG4));
onError();
return -1;
}
video_st = avformat_new_stream(oc, codec);
if (!video_st) {
LOGD("Could not allocate stream\n");
onError();
return -1;
}
video_st->id = oc->nb_streams - 1;
av_dict_copy(&video_st->metadata, src_video_stream->metadata, 0);
c = video_st->codec;
c->codec_id = AV_CODEC_ID_MPEG4;
c->bit_rate = bitr;
c->width = dst_width;
c->height = dst_height;
double fps = (double)src_video_stream->avg_frame_rate.num / (double)src_video_stream->avg_frame_rate.den;
c->time_base.den = 65535;
c->time_base.num = floor(65635 / fps);
c->gop_size = 12;
c->pix_fmt = AV_PIX_FMT_YUV420P;
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
ret = avcodec_open2(c, codec, NULL);
if (ret < 0) {
LOGD("Could not open video codec: %s\n", av_err2str(ret));
onError();
return -1;
}
out_frame = avcodec_alloc_frame();
if (!out_frame) {
LOGD("Could not allocate video frame\n");
onError();
return -1;
}
ret = avpicture_alloc(&dst_picture, c->pix_fmt, c->width, c->height);
if (ret < 0) {
LOGD("Could not allocate picture: %s\n", av_err2str(ret));
onError();
return -1;
}
*((AVPicture *)out_frame) = dst_picture;
}
//create audio stream
if (audio_dec_ctx && src_audio_stream) {
AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
if (!codec) {
LOGD("Could not find encoder for '%s'\n", avcodec_get_name(AV_CODEC_ID_AAC));
onError();
return -1;
}
audio_st = avformat_new_stream(oc, codec);
if (!audio_st) {
LOGD("Could not allocate stream\n");
onError();
return -1;
}
audio_st->id = oc->nb_streams - 1;
av_dict_copy(&audio_st->metadata, src_audio_stream->metadata, 0);
c = audio_st->codec;
c->sample_fmt = AV_SAMPLE_FMT_FLTP;
c->bit_rate = 40000;
c->sample_rate = min(audio_dec_ctx->sample_rate, 44100);
c->channels = 1;
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
c = audio_st->codec;
c->strict_std_compliance = -2;
swr_ctx = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_MONO, c->sample_fmt, c->sample_rate, audio_dec_ctx->channel_layout, audio_dec_ctx->sample_fmt, audio_dec_ctx->sample_rate, 0, NULL);
if (!swr_ctx) {
LOGD("Could not allocate resampler context\n");
onError();
return -1;
}
if ((ret = swr_init(swr_ctx)) < 0) {
LOGD("Failed to initialize the resampling context\n");
onError();
return -1;
}
ret = avcodec_open2(c, codec, NULL);
if (ret < 0) {
LOGD("Could not open audio codec: %s\n", av_err2str(ret));
onError();
return -1;
}
av_dump_format(oc, 0, dst_filename, 1);
ret = avformat_write_header(oc, NULL);
if (ret < 0) {
LOGD("Error occurred when opening output file: %s\n", av_err2str(ret));
onError();
return -1;
}
if (out_frame) {
out_frame->pts = 0;
}
}
return 0;
}
void cleanup_out() {
if (video_st) {
avcodec_close(video_st->codec);
if (dst_picture.data) {
av_free(dst_picture.data[0]);
}
if (out_frame) {
av_free(out_frame);
out_frame = NULL;
}
video_st = NULL;
}
if (audio_st) {
avcodec_close(audio_st->codec);
if (dst_samples_data) {
av_free(dst_samples_data[0]);
dst_samples_data = NULL;
}
audio_st = NULL;
}
if (fmt && !(fmt->flags & AVFMT_NOFILE)) {
avio_close(oc->pb);
fmt = NULL;
}
if (oc) {
avformat_free_context(oc);
oc = NULL;
}
if (sws_ctx) {
sws_freeContext(sws_ctx);
sws_ctx = NULL;
}
if (swr_ctx) {
swr_free(&swr_ctx);
swr_ctx = NULL;
}
current_n_out = 0;
current_in_buff = 0;
}
int write_video_frame(AVFrame *src_frame) {
int ret;
if (sws_ctx) {
ret = sws_scale(sws_ctx, (const uint8_t * const *)src_frame->data, src_frame->linesize, 0, src_frame->height, out_frame->data, out_frame->linesize);
if (ret < 0) {
LOGD("scale error: %s\n", av_err2str(ret));
onError();
return -1;
}
} else {
for (int i = 0; i < 4; i++){
out_frame->data[i] = src_frame->data[i];
out_frame->linesize[i] = src_frame->linesize[i];
}
}
AVPacket pkt = { 0 };
int got_packet;
av_init_packet(&pkt);
ret = avcodec_encode_video2(video_st->codec, &pkt, out_frame, &got_packet);
if (ret < 0) {
LOGD("Error encoding video frame: %s\n", av_err2str(ret));
onError();
return -1;
}
if (!ret && got_packet && pkt.size) {
pkt.stream_index = video_st->index;
ret = av_interleaved_write_frame(oc, &pkt);
} else {
ret = 0;
}
if (ret != 0) {
LOGD("Error while writing video frame: %s\n", av_err2str(ret));
onError();
return -1;
}
int64_t val = av_rescale_q(1, video_st->codec->time_base, video_st->time_base);
out_frame->pts += val;
return 0;
}
int check_write_packet(int flush) {
int got_packet, ret;
int writed = 0;
int dst_samples_size = av_samples_get_buffer_size(NULL, audio_st->codec->channels, audio_st->codec->frame_size, audio_st->codec->sample_fmt, 1);
while (current_n_out > audio_st->codec->frame_size || (flush && current_n_out)) {
AVFrame *frame = avcodec_alloc_frame();
AVPacket pkt2 = { 0 };
av_init_packet(&pkt2);
frame->nb_samples = min(audio_st->codec->frame_size, current_n_out);
int nb_samples_size = min(dst_samples_size, current_in_buff);
ret = avcodec_fill_audio_frame(frame, audio_st->codec->channels, audio_st->codec->sample_fmt, buff + writed, nb_samples_size, 1);
if (ret < 0) {
LOGD("Error fill frame: %s\n", av_err2str(ret));
onError();
return -1;
}
ret = avcodec_encode_audio2(audio_st->codec, &pkt2, frame, &got_packet);
if (ret < 0) {
LOGD("Error encoding audio frame: %s\n", av_err2str(ret));
onError();
return -1;
}
if (got_packet) {
pkt2.stream_index = audio_st->index;
ret = av_interleaved_write_frame(oc, &pkt2);
if (ret != 0) {
LOGD("Error while writing audio frame: %s\n", av_err2str(ret));
onError();
return -1;
}
}
writed += dst_samples_size;
current_n_out -= frame->nb_samples;
current_in_buff -= nb_samples_size;
avcodec_free_frame(&frame);
}
if (current_in_buff != 0 && writed != 0) {
memcpy(buff, buff + writed, current_in_buff);
}
return 0;
}
int write_audio_frame(AVFrame *src_frame, AVCodecContext *src_codec) {
const int n_in = src_frame->nb_samples;
double ratio = (double)audio_st->codec->sample_rate / src_frame->sample_rate;
int n_out = n_in * ratio + 32;
int64_t delay = swr_get_delay(swr_ctx, audio_st->codec->sample_rate);
if (delay > 0) {
n_out += delay;
}
if (!dst_samples_data) {
int ret = av_samples_alloc_array_and_samples(&dst_samples_data, NULL, audio_st->codec->channels, n_out, audio_st->codec->sample_fmt, 0);
if (ret < 0) {
LOGD("Could not allocate destination samples\n");
onError();
return -1;
}
}
n_out = swr_convert(swr_ctx, dst_samples_data, n_out, (const uint8_t **)src_frame->extended_data, src_frame->nb_samples);
if (n_out <= 0) {
LOGD("Error while converting\n");
onError();
return -1;
}
int total_size = av_samples_get_buffer_size(NULL, audio_st->codec->channels, n_out, audio_st->codec->sample_fmt, 1);
memcpy(buff + current_in_buff, dst_samples_data[0], total_size);
current_n_out += n_out;
current_in_buff += total_size;
return check_write_packet(0);
}
void post_video_conversion() {
check_write_packet(1);
av_write_trailer(oc);
}

View File

@ -1,18 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.telegram.messenger" package="org.telegram.messenger"
android:versionCode="98" android:versionCode="122"
android:versionName="1.2.7"> android:versionName="1.3.2">
<supports-screens android:anyDensity="true" <supports-screens android:anyDensity="true"
android:smallScreens="true" android:smallScreens="true"
android:normalScreens="true" android:normalScreens="true"
android:largeScreens="true" android:largeScreens="true"
android:resizeable="true" android:resizeable="true"
android:xlargeScreens="true"/> android:xlargeScreens="true"/>
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
<uses-feature android:glEsVersion="0x00020000" android:required="true"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<uses-feature android:name="android.hardware.telephony" android:required="false" /> <uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" /> <uses-feature android:name="android.hardware.location.gps" android:required="false" />
@ -22,7 +22,8 @@
<uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.wifi" android:required="false" /> <uses-feature android:name="android.hardware.wifi" android:required="false" />
<uses-feature android:name="android.hardware.LOCATION" android:required="false" /> <uses-feature android:name="android.hardware.LOCATION" android:required="false" />
<uses-feature android:name="android.hardware.screen.PORTRAIT" android:required="false" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
@ -48,24 +49,25 @@
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<permission android:name="org.telegram.messenger.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <permission android:name="org.telegram.messenger.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<permission android:name="org.telegram.messenger.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <permission android:name="org.telegram.messenger.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/AppName" android:label="@string/AppName"
android:theme="@style/Theme.Sherlock.Light" android:theme="@style/Theme.TMessages.Start"
android:name="org.telegram.ui.ApplicationLoader" android:name="org.telegram.ui.ApplicationLoader"
android:hardwareAccelerated="true"> android:hardwareAccelerated="true"
android:largeHeap="true">
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="your-google-maps-api-key-here" /> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="your-google-maps-api-key-here" />
<activity <activity
android:name="org.telegram.ui.LaunchActivity" android:name="org.telegram.ui.LaunchActivity"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
@ -92,68 +94,78 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name="org.telegram.ui.LoginActivity" android:name="org.telegram.ui.LoginActivity"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait">
</activity>
<activity
android:name="org.telegram.ui.CountrySelectActivity"
android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.TMessages"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait">
</activity> </activity>
<activity <activity
android:name="org.telegram.ui.IntroActivity" android:name="org.telegram.ui.IntroActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait">
</activity>
<activity
android:name="org.telegram.ui.ApplicationActivity"
android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.TMessages"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
</activity> </activity>
<activity <activity
android:name="org.telegram.ui.ApplicationActivity" android:name="org.telegram.ui.GalleryImageViewer"
android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.TMessages.Gallery"
android:theme="@style/Theme.TMessages" android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
</activity> </activity>
<activity
android:name="org.telegram.ui.GalleryImageViewer"
android:theme="@style/Theme.TMessages.Gallery"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
</activity>
<activity android:name="net.hockeyapp.android.UpdateActivity" /> <activity android:name="net.hockeyapp.android.UpdateActivity" />
<receiver android:name="org.telegram.messenger.SmsListener"> <receiver android:name="org.telegram.messenger.SmsListener">
<intent-filter> <intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" /> <action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver <receiver
android:name="org.telegram.messenger.GcmBroadcastReceiver" android:name="org.telegram.messenger.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" > android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter> <intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="org.telegram.messenger" /> <category android:name="org.telegram.messenger" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<service android:name="org.telegram.messenger.AuthenticatorService" <service android:name="org.telegram.messenger.AuthenticatorService"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/> <action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter> </intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator" <meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/auth"/> android:resource="@xml/auth"/>
</service> </service>
<service android:name="org.telegram.messenger.ContactsSyncAdapterService" <service android:name="org.telegram.messenger.ContactsSyncAdapterService"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.content.SyncAdapter" /> <action android:name="android.content.SyncAdapter" />
</intent-filter> </intent-filter>
<meta-data android:name="android.content.SyncAdapter" <meta-data android:name="android.content.SyncAdapter"
android:resource="@xml/sync_contacts" /> android:resource="@xml/sync_contacts" />
<meta-data android:name="android.provider.CONTACTS_STRUCTURE" <meta-data android:name="android.provider.CONTACTS_STRUCTURE"
android:resource="@xml/contacts" /> android:resource="@xml/contacts" />
</service> </service>
<uses-library android:name="com.google.android.maps" android:required="false"/> <uses-library android:name="com.google.android.maps" android:required="false"/>
</application> </application>
</manifest> </manifest>

View File

@ -1,28 +1,21 @@
6723;NF;Norfolk Island
5999;CW;Curaçao
1939;PR;Puerto Rico
1876;JM;Jamaica 1876;JM;Jamaica
1869;KN;Saint Kitts and Nevis 1869;KN;Saint Kitts & Nevis
1868;TT;Trinidad and Tobago 1868;TT;Trinidad & Tobago
1849;DO;Dominican Republic 1784;VC;Saint Vincent & the Grenadines
1829;DO;Dominican Republic
1809;DO;Dominican Republic
1787;PR;Puerto Rico
1784;VC;Saint Vincent and the Grenadines
1767;DM;Dominica 1767;DM;Dominica
1758;LC;Saint Lucia 1758;LC;Saint Lucia
1721;SX;Bonaire, Sint Eustatius and Saba 1721;SX;Sint Maarten
1684;AS;American Samoa 1684;AS;American Samoa
1671;GU;Guam 1671;GU;Guam
1670;MP;Northern Mariana Islands 1670;MP;Northern Mariana Islands
1664;MS;Montserrat 1664;MS;Montserrat
1649;TC;Turks and Caicos Islands 1649;TC;Turks & Caicos Islands
1473;GD;Grenada 1473;GD;Grenada
1441;BM;Bermuda 1441;BM;Bermuda
1345;KY;Cayman Islands 1345;KY;Cayman Islands
1340;VI;US Virgin Islands 1340;VI;US Virgin Islands
1284;VG;British Virgin Islands 1284;VG;British Virgin Islands
1268;AG;Antigua and Barbuda 1268;AG;Antigua & Barbuda
1264;AI;Anguilla 1264;AI;Anguilla
1246;BB;Barbados 1246;BB;Barbados
1242;BS;Bahamas 1242;BS;Bahamas
@ -45,7 +38,7 @@
966;SA;Saudi Arabia 966;SA;Saudi Arabia
965;KW;Kuwait 965;KW;Kuwait
964;IQ;Iraq 964;IQ;Iraq
963;SY;Syria 963;SY;Syrian Arab Republic
962;JO;Jordan 962;JO;Jordan
961;LB;Lebanon 961;LB;Lebanon
960;MV;Maldives 960;MV;Maldives
@ -66,7 +59,7 @@
685;WS;Samoa 685;WS;Samoa
683;NU;Niue 683;NU;Niue
682;CK;Cook Islands 682;CK;Cook Islands
681;WF;Wallis and Futuna 681;WF;Wallis & Futuna
680;PW;Palau 680;PW;Palau
679;FJ;Fiji 679;FJ;Fiji
678;VU;Vanuatu 678;VU;Vanuatu
@ -75,9 +68,10 @@
675;PG;Papua New Guinea 675;PG;Papua New Guinea
674;NR;Nauru 674;NR;Nauru
673;BN;Brunei Darussalam 673;BN;Brunei Darussalam
672;AU;Australia 672;NF;Norfolk Island
670;TL;East Timor 670;TL;Timor-Leste
599;BQ;Sint Maarten 599;BQ;Bonaire, Sint Eustatius & Saba
599;CW;Curaçao
598;UY;Uruguay 598;UY;Uruguay
597;SR;Suriname 597;SR;Suriname
596;MQ;Martinique 596;MQ;Martinique
@ -88,7 +82,7 @@
591;BO;Bolivia 591;BO;Bolivia
590;GP;Guadeloupe 590;GP;Guadeloupe
509;HT;Haiti 509;HT;Haiti
508;PM;Saint Pierre and Miquelon 508;PM;Saint Pierre & Miquelon
507;PA;Panama 507;PA;Panama
506;CR;Costa Rica 506;CR;Costa Rica
505;NI;Nicaragua 505;NI;Nicaragua
@ -101,7 +95,7 @@
421;SK;Slovakia 421;SK;Slovakia
420;CZ;Czech Republic 420;CZ;Czech Republic
389;MK;Macedonia 389;MK;Macedonia
387;BA;Bosnia and Herzegovina 387;BA;Bosnia & Herzegovina
386;SI;Slovenia 386;SI;Slovenia
385;HR;Croatia 385;HR;Croatia
382;ME;Montenegro 382;ME;Montenegro
@ -153,17 +147,17 @@
249;SD;Sudan 249;SD;Sudan
248;SC;Seychelles 248;SC;Seychelles
247;SH;Saint Helena 247;SH;Saint Helena
246;IO;United Kingdom 246;IO;Diego Garcia
245;GW;Guinea-Bissau 245;GW;Guinea-Bissau
244;AO;Angola 244;AO;Angola
243;CD;Congo, Democratic Republic 243;CD;Congo (Dem. Rep.)
242;CG;Congo 242;CG;Congo (Rep.)
241;GA;Gabon 241;GA;Gabon
240;GQ;Equatorial Guinea 240;GQ;Equatorial Guinea
239;ST;São Tomé and Príncipe 239;ST;São Tomé & Príncipe
238;CV;Cape Verde 238;CV;Cape Verde
237;CM;Cameroon 237;CM;Cameroon
236;CF;Central African Republic 236;CF;Central African Rep.
235;TD;Chad 235;TD;Chad
234;NG;Nigeria 234;NG;Nigeria
233;GH;Ghana 233;GH;Ghana
@ -228,8 +222,10 @@
31;NL;Netherlands 31;NL;Netherlands
30;GR;Greece 30;GR;Greece
27;ZA;South Africa 27;ZA;South Africa
20;EG;Egypt 20;EG;Egypt
7;KZ;Kazakhstan 7;KZ;Kazakhstan
7;RU;Russia 7;RU;Russian Federation
1;US;USA 1;PR;Puerto Rico
1;CA;Canada 1;DO;Dominican Rep.
1;CA;Canada
1;US;USA

Binary file not shown.

View File

@ -16,7 +16,7 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package jawnae.pyronet.traffic; package jawnae.pyronet;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -31,14 +31,9 @@ import java.nio.channels.SocketChannel;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import jawnae.pyronet.events.PyroClientListener;
import jawnae.pyronet.traffic.ByteStream;
public class PyroClient { public class PyroClient {
private final PyroSelector selector; private final PyroSelector selector;
final PyroServer server;
private final SelectionKey key; private final SelectionKey key;
private final ByteStream outbound; private final ByteStream outbound;
@ -46,18 +41,17 @@ public class PyroClient {
// called by PyroSelector.connect() // called by PyroSelector.connect()
PyroClient(PyroSelector selector, InetSocketAddress bind, PyroClient(PyroSelector selector, InetSocketAddress bind,
InetSocketAddress host) throws IOException { InetSocketAddress host) throws IOException {
this(selector, null, PyroClient.bindAndConfigure(selector, this(selector, PyroClient.bindAndConfigure(selector,
SocketChannel.open(), bind)); SocketChannel.open(), bind));
((SocketChannel) this.key.channel()).connect(host); ((SocketChannel) this.key.channel()).connect(host);
} }
// called by PyroClient and PyroServer // called by PyroClient and PyroServer
PyroClient(PyroSelector selector, PyroServer server, SelectionKey key) { PyroClient(PyroSelector selector, SelectionKey key) {
this.selector = selector; this.selector = selector;
this.selector.checkThread(); this.selector.checkThread();
this.server = server;
this.key = key; this.key = key;
this.key.attach(this); this.key.attach(this);
@ -163,20 +157,6 @@ public class PyroClient {
// //
/**
* Returns the server that accepted this client.
*
* @throws PyroException
* if this client was not accepted by a server (it connected to
* a server)
*/
public final PyroServer getServer() throws PyroException {
if (this.server == null)
throw new PyroException("this client was not accepted by a server");
return this.server;
}
// //
// //
@ -425,7 +405,7 @@ public class PyroClient {
private int onReadyToWrite(long now) throws IOException { private int onReadyToWrite(long now) throws IOException {
this.selector.checkThread(); this.selector.checkThread();
this.lastEventTime = now; //this.lastEventTime = now;
int sent = 0; int sent = 0;
@ -479,13 +459,9 @@ public class PyroClient {
return; return;
} }
if (this.server != null) {
this.server.onDisconnect(this);
}
if (cause instanceof ConnectException) { if (cause instanceof ConnectException) {
for (PyroClientListener listener: this.listeners) for (PyroClientListener listener: this.listeners)
listener.unconnectableClient(this); listener.unconnectableClient(this, (Exception)cause);
} else if (cause instanceof EOFException) // after read=-1 } else if (cause instanceof EOFException) // after read=-1
{ {
for (PyroClientListener listener: this.listeners) for (PyroClientListener listener: this.listeners)
@ -495,7 +471,7 @@ public class PyroClient {
listener.droppedClient(this, (IOException) cause); listener.droppedClient(this, (IOException) cause);
} else if (!(cause instanceof String)) { } else if (!(cause instanceof String)) {
for (PyroClientListener listener: this.listeners) for (PyroClientListener listener: this.listeners)
listener.unconnectableClient(this); listener.unconnectableClient(this, null);
} else if (cause.equals("local")) { } else if (cause.equals("local")) {
for (PyroClientListener listener: this.listeners) for (PyroClientListener listener: this.listeners)
listener.disconnectedClient(this); listener.disconnectedClient(this);
@ -551,7 +527,7 @@ public class PyroClient {
// channel.socket().setSoLinger(false, 0); // this will b0rk your // channel.socket().setSoLinger(false, 0); // this will b0rk your
// connections // connections
channel.socket().setSoLinger(true, 4); channel.socket().setSoLinger(true, 4);
channel.socket().setReuseAddress(true); channel.socket().setReuseAddress(false);
channel.socket().setKeepAlive(false); channel.socket().setKeepAlive(false);
channel.socket().setTcpNoDelay(true); channel.socket().setTcpNoDelay(true);
channel.socket().setReceiveBufferSize(PyroSelector.BUFFER_SIZE); channel.socket().setReceiveBufferSize(PyroSelector.BUFFER_SIZE);

View File

@ -16,19 +16,17 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package jawnae.pyronet.events; package jawnae.pyronet;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
public class PyroClientAdapter implements PyroClientListener { public class PyroClientAdapter implements PyroClientListener {
public void connectedClient(PyroClient client) { public void connectedClient(PyroClient client) {
// //
} }
public void unconnectableClient(PyroClient client) { public void unconnectableClient(PyroClient client, Exception cause) {
System.out.println("unconnectable"); System.out.println("unconnectable");
} }

View File

@ -16,7 +16,7 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package jawnae.pyronet.events; package jawnae.pyronet;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -26,7 +26,7 @@ import jawnae.pyronet.PyroClient;
public interface PyroClientListener { public interface PyroClientListener {
public void connectedClient(PyroClient client); public void connectedClient(PyroClient client);
public void unconnectableClient(PyroClient client); public void unconnectableClient(PyroClient client, Exception cause);
public void droppedClient(PyroClient client, IOException cause); public void droppedClient(PyroClient client, IOException cause);

View File

@ -19,7 +19,6 @@
package jawnae.pyronet; package jawnae.pyronet;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -27,14 +26,11 @@ import java.nio.channels.CancelledKeyException;
import java.nio.channels.SelectableChannel; import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey; import java.nio.channels.SelectionKey;
import java.nio.channels.Selector; import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import jawnae.pyronet.events.PyroSelectorListener;
public class PyroSelector { public class PyroSelector {
public static boolean DO_NOT_CHECK_NETWORK_THREAD = true; public static boolean DO_NOT_CHECK_NETWORK_THREAD = true;
@ -46,14 +42,7 @@ public class PyroSelector {
final ByteBuffer networkBuffer; final ByteBuffer networkBuffer;
final PyroSelectorListener listener;
public PyroSelector() { public PyroSelector() {
this(null);
}
public PyroSelector(PyroSelectorListener listener) {
this.listener = listener;
this.networkBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE); this.networkBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
try { try {
@ -111,28 +100,6 @@ public class PyroSelector {
} }
} }
public PyroServer listen(InetSocketAddress end, int backlog)
throws IOException {
try {
return new PyroServer(this, nioSelector, end, backlog);
} catch (IOException exc) {
if (this.listener == null)
throw exc;
this.listener.serverBindFailed(exc);
return null;
}
}
public PyroServer listen(InetSocketAddress end) throws IOException {
return this.listen(end, 50);
}
public PyroServer listen(int port) throws IOException {
return this.listen(new InetSocketAddress(InetAddress.getLocalHost(),
port));
}
public PyroClient connect(InetSocketAddress host) throws IOException { public PyroClient connect(InetSocketAddress host) throws IOException {
return this.connect(host, null); return this.connect(host, null);
} }
@ -142,11 +109,7 @@ public class PyroSelector {
try { try {
return new PyroClient(this, bind, host); return new PyroClient(this, bind, host);
} catch (IOException exc) { } catch (IOException exc) {
if (this.listener == null) throw exc;
throw exc;
this.listener.clientBindFailed(exc);
return null;
} }
} }
@ -173,16 +136,10 @@ public class PyroSelector {
if (task == null) if (task == null)
break; break;
if (this.listener != null)
this.listener.executingTask(task);
try { try {
task.run(); task.run();
} catch (Throwable cause) { } catch (Throwable cause) {
if (this.listener != null) cause.printStackTrace();
this.listener.taskCrashed(task, cause);
else
cause.printStackTrace();
} }
} }
} }
@ -192,15 +149,9 @@ public class PyroSelector {
try { try {
selected = nioSelector.select(timeout); selected = nioSelector.select(timeout);
} catch (IOException exc) { } catch (IOException exc) {
if (this.listener != null) exc.printStackTrace();
this.listener.selectFailure(exc);
else
exc.printStackTrace();
return; return;
} }
if (this.listener != null)
this.listener.selectedKeys(selected);
} }
private final void handleSelectedKeys(long now) { private final void handleSelectedKeys(long now) {
@ -210,17 +161,8 @@ public class PyroSelector {
SelectionKey key = keys.next(); SelectionKey key = keys.next();
keys.remove(); keys.remove();
if (key.channel() instanceof ServerSocketChannel) {
PyroServer server = (PyroServer) key.attachment();
if (this.listener != null)
this.listener.serverSelected(server);
server.onInterestOp();
}
if (key.channel() instanceof SocketChannel) { if (key.channel() instanceof SocketChannel) {
PyroClient client = (PyroClient) key.attachment(); PyroClient client = (PyroClient) key.attachment();
if (this.listener != null)
this.listener.clientSelected(client, key.readyOps());
client.onInterestOp(now); client.onInterestOp(now);
} }
} }

View File

@ -1,224 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import jawnae.pyronet.addon.PyroSelectorProvider;
import jawnae.pyronet.events.PyroServerListener;
public class PyroServer implements Iterable<PyroClient> {
private final PyroSelector selector;
public final SelectionKey serverKey;
final List<PyroClient> clients;
PyroServer(PyroSelector selector, Selector nioSelector,
InetSocketAddress endpoint, int backlog) throws IOException {
this.selector = selector;
this.selector.checkThread();
ServerSocketChannel ssc;
ssc = ServerSocketChannel.open();
ssc.socket().bind(endpoint, backlog);
ssc.configureBlocking(false);
this.serverKey = ssc.register(nioSelector, SelectionKey.OP_ACCEPT);
this.serverKey.attach(this);
this.clients = new ArrayList<PyroClient>();
this.listeners = new CopyOnWriteArrayList<PyroServerListener>();
}
//
private final List<PyroServerListener> listeners;
public void addListener(PyroServerListener listener) {
this.selector.checkThread();
this.listeners.add(listener);
}
public void removeListener(PyroServerListener listener) {
this.selector.checkThread();
this.listeners.remove(listener);
}
public void removeListeners() {
this.selector.checkThread();
this.listeners.clear();
}
/**
* Returns the network that created this server
*/
public PyroSelector selector() {
return this.selector;
}
private PyroSelectorProvider selectorProvider;
/**
* By installing a PyroSelectorProvider you alter the PyroSelector used to
* do the I/O of a PyroClient. This can be used for multi-threading your
* network code
*/
public void installSelectorProvider(PyroSelectorProvider selectorProvider) {
this.selector().checkThread();
this.selectorProvider = selectorProvider;
}
void onInterestOp() {
if (!serverKey.isValid())
throw new PyroException("invalid selection key");
try {
if (serverKey.isAcceptable()) {
this.onReadyToAccept();
}
} catch (IOException exc) {
throw new IllegalStateException(exc);
}
}
/**
* Returns an iterator to access all connected clients of this server
*/
@Override
public Iterator<PyroClient> iterator() {
this.selector.checkThread();
List<PyroClient> copy = new ArrayList<PyroClient>();
copy.addAll(this.clients);
return copy.iterator();
}
/**
* Closes the server socket. Any current connections will continue.
*/
public void close() throws IOException {
this.selector.checkThread();
this.serverKey.channel().close();
}
/**
* Closes the server socket. Any current connections will be closed.
*/
public void terminate() throws IOException {
this.close();
for (PyroClient client: this) {
client.dropConnection();
}
}
private void onReadyToAccept() throws IOException {
this.selector.checkThread();
final SocketChannel channel = ((ServerSocketChannel) serverKey
.channel()).accept();
final PyroSelector acceptedClientSelector;
{
if (this.selectorProvider == null)
acceptedClientSelector = this.selector;
else
acceptedClientSelector = this.selectorProvider
.provideFor(channel);
}
if (acceptedClientSelector == this.selector) {
SelectionKey clientKey = PyroClient.configure(
acceptedClientSelector, channel, false);
PyroClient client = new PyroClient(acceptedClientSelector, this,
clientKey);
this.fireAcceptedClient(client);
this.clients.add(client);
} else {
// create client in PyroClient-selector thread
acceptedClientSelector.scheduleTask(new Runnable() {
@Override
public void run() {
SelectionKey clientKey;
try {
clientKey = PyroClient.configure(
acceptedClientSelector, channel, false);
} catch (IOException exc) {
throw new IllegalStateException(exc);
}
final PyroClient client = new PyroClient(
acceptedClientSelector, PyroServer.this, clientKey);
PyroServer.this.fireAcceptedClient(client);
// add client to list in PyroServer-selector thread
PyroServer.this.selector().scheduleTask(new Runnable() {
@Override
public void run() {
PyroServer.this.clients.add(client);
}
});
PyroServer.this.selector().wakeup();
}
});
acceptedClientSelector.wakeup();
}
}
void fireAcceptedClient(PyroClient client) {
for (PyroServerListener listener: this.listeners) {
listener.acceptedClient(client);
}
}
void onDisconnect(final PyroClient client) {
if (this.selector().isNetworkThread()) {
this.clients.remove(client);
} else {
// we are in the PyroClient-selector thread
this.selector().scheduleTask(new Runnable() {
@Override
public void run() {
// call again from the PyroServer-selector thread
PyroServer.this.onDisconnect(client);
}
});
this.selector().wakeup();
}
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.addon;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import jawnae.pyronet.PyroSelector;
public class PyroRoundrobinSelectorProvider implements PyroSelectorProvider {
private final PyroSelector[] selectors;
private int index;
public PyroRoundrobinSelectorProvider(PyroSelector[] selectors) {
this.selectors = Arrays.copyOf(selectors, selectors.length);
}
@Override
public PyroSelector provideFor(SocketChannel channel) {
// this is called from the PyroServer-selector thread
return this.selectors[this.index++ % this.selectors.length];
}
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.addon;
import java.nio.channels.SocketChannel;
import jawnae.pyronet.PyroSelector;
public interface PyroSelectorProvider {
public PyroSelector provideFor(SocketChannel channel);
}

View File

@ -1,36 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.addon;
import java.nio.channels.SocketChannel;
import jawnae.pyronet.PyroSelector;
public class PyroSingletonSelectorProvider implements PyroSelectorProvider {
private final PyroSelector selector;
public PyroSingletonSelectorProvider(PyroSelector selector) {
this.selector = selector;
}
@Override
public PyroSelector provideFor(SocketChannel channel) {
return this.selector;
}
}

View File

@ -1,111 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroServer;
public class PyroLazyBastardAdapter implements PyroSelectorListener,
PyroServerListener, PyroClientListener {
// --------------- PyroSelectorListener
public void executingTask(Runnable task) {
//
}
public void taskCrashed(Runnable task, Throwable cause) {
System.out.println(this.getClass().getSimpleName()
+ ".taskCrashed() caught exception:");
cause.printStackTrace();
}
public void selectedKeys(int count) {
//
}
public void selectFailure(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".selectFailure() caught exception:");
cause.printStackTrace();
}
public void serverSelected(PyroServer server) {
//
}
public void clientSelected(PyroClient client, int readyOps) {
//
}
// ------------- PyroServerListener
public void acceptedClient(PyroClient client) {
//
}
// ------------- PyroClientListener
public void connectedClient(PyroClient client) {
//
}
public void unconnectableClient(PyroClient client) {
System.out.println(this.getClass().getSimpleName()
+ ".unconnectableClient()");
}
public void droppedClient(PyroClient client, IOException cause) {
if (cause != null && !(cause instanceof EOFException)) {
System.out.println(this.getClass().getSimpleName()
+ ".droppedClient() caught exception: " + cause);
}
}
public void disconnectedClient(PyroClient client) {
//
}
//
public void receivedData(PyroClient client, ByteBuffer data) {
//
}
public void sentData(PyroClient client, int bytes) {
//
}
@Override
public void serverBindFailed(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".serverBindFailed() caught exception:");
cause.printStackTrace();
}
@Override
public void clientBindFailed(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".serverBindFailed() caught exception:");
cause.printStackTrace();
}
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import java.io.IOException;
import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroServer;
public class PyroSelectorAdapter implements PyroSelectorListener {
public void executingTask(Runnable task) {
//
}
public void taskCrashed(Runnable task, Throwable cause) {
System.out.println(this.getClass().getSimpleName()
+ " caught exception: " + cause);
}
//
public void selectedKeys(int count) {
//
}
public void selectFailure(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ " caught exception: " + cause);
}
//
public void serverSelected(PyroServer server) {
//
}
public void clientSelected(PyroClient client, int readyOps) {
//
}
//
@Override
public void serverBindFailed(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".serverBindFailed() caught exception: " + cause);
}
@Override
public void clientBindFailed(IOException cause) {
System.out.println(this.getClass().getSimpleName()
+ ".serverBindFailed() caught exception: " + cause);
}
}

View File

@ -1,48 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import java.io.IOException;
import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroServer;
public interface PyroSelectorListener {
public void executingTask(Runnable task);
public void taskCrashed(Runnable task, Throwable cause);
//
public void selectedKeys(int count);
public void selectFailure(IOException cause);
//
public void serverSelected(PyroServer server);
public void clientSelected(PyroClient client, int readyOps);
//
public void serverBindFailed(IOException cause);
public void clientBindFailed(IOException cause);
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import jawnae.pyronet.PyroClient;
public class PyroServerAdapter implements PyroServerListener {
@Override
public void acceptedClient(PyroClient client) {
//
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.events;
import jawnae.pyronet.PyroClient;
public interface PyroServerListener {
/**
* Note: invoked from the PyroSelector-thread that created this PyroClient
*/
public void acceptedClient(PyroClient client);
}

View File

@ -1,48 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
public interface ByteSink {
public static int FEED_ACCEPTED = 1;
public static int FEED_ACCEPTED_LAST = 2;
public static int FEED_REJECTED = 3;
/**
* determines what to do with the specified byte: accept, accept as final
* byte, reject
*/
public int feed(byte b);
/**
* Resets the state of this ByteSink, allowing it to be enqueued again
*/
public void reset();
/**
* Called by the client when this ByteSink is complete
*/
public void onReady(ByteBuffer buffer);
}

View File

@ -1,74 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
public abstract class ByteSinkEndsWith implements ByteSink {
private final ByteBuffer result;
private final byte[] endsWith;
private final boolean includeEndsWith;
private int matchCount;
private int filled;
public ByteSinkEndsWith(byte[] endsWith, int capacity,
boolean includeEndsWith) {
if (endsWith == null || endsWith.length == 0)
throw new IllegalStateException();
this.result = ByteBuffer.allocate(capacity);
this.endsWith = endsWith;
this.includeEndsWith = includeEndsWith;
this.reset();
}
@Override
public void reset() {
this.result.clear();
this.matchCount = 0;
this.filled = 0;
}
@Override
public int feed(byte b) {
if (this.endsWith[this.matchCount] == b) {
this.matchCount++;
} else {
this.matchCount = 0;
}
this.result.put(this.filled, b);
this.filled += 1;
if (this.matchCount == this.endsWith.length) {
int len = this.filled
- (this.includeEndsWith ? 0 : this.endsWith.length);
this.result.limit(len);
this.onReady(this.result);
return FEED_ACCEPTED_LAST;
}
return ByteSink.FEED_ACCEPTED;
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
public abstract class ByteSinkLength implements ByteSink {
private final ByteBuffer result;
private int filled;
public ByteSinkLength(int size) {
if (size == 0)
throw new IllegalArgumentException();
this.result = ByteBuffer.allocate(size);
this.reset();
}
@Override
public void reset() {
this.result.clear();
this.filled = 0;
}
@Override
public int feed(byte b) {
this.result.put(this.filled, b);
this.filled += 1;
if (this.filled == this.result.capacity()) {
this.onReady(this.result);
return FEED_ACCEPTED_LAST;
}
return ByteSink.FEED_ACCEPTED;
}
}

View File

@ -1,95 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
public abstract class ByteSinkPacket16 implements ByteSink {
public static void sendTo(PyroClient client, byte[] payload) {
if (payload.length > 0x0000FFFF) {
throw new IllegalStateException("packet bigger than 64K-1 bytes");
}
byte[] wrapped = new byte[2 + payload.length];
wrapped[0] = (byte) (payload.length >> 8);
wrapped[1] = (byte) (payload.length >> 0);
System.arraycopy(payload, 0, wrapped, 2, payload.length);
client.write(client.selector().malloc(wrapped));
}
//
ByteSinkLength current;
public ByteSinkPacket16() {
this.reset();
}
@Override
public void reset() {
this.current = new ByteSinkLength(2) {
@Override
public void onReady(ByteBuffer buffer) {
// header is received
int len = buffer.getShort(0) & 0xFFFF;
current = new ByteSinkLength(len) {
@Override
public void onReady(ByteBuffer buffer) {
// sometime we want do reset in
// ByteSinkPacket16.this.onReady, then add the sink back
// to feeder, in such process, onReady should be execute
// at last.
current = null;
// content is received
ByteSinkPacket16.this.onReady(buffer);
}
};
}
};
}
@Override
public int feed(byte b) {
if (this.current == null) {
throw new IllegalStateException();
}
int result = this.current.feed(b);
if (result == FEED_ACCEPTED) {
return result;
}
// 'current' will be replaced by now
if (this.current == null) {
return result;
}
else {
return FEED_ACCEPTED;
}
// return this.current.feed(b);
}
}

View File

@ -1,94 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
public abstract class ByteSinkPacket24 implements ByteSink {
public static void sendTo(PyroClient client, byte[] payload) {
if (payload.length > 0x00FFFFFF) {
throw new IllegalStateException("packet bigger than 16M-1 bytes");
}
byte[] wrapped = new byte[3 + payload.length];
wrapped[0] = (byte) (payload.length >> 16);
wrapped[1] = (byte) (payload.length >> 8);
wrapped[2] = (byte) (payload.length >> 0);
System.arraycopy(payload, 0, wrapped, 3, payload.length);
client.write(client.selector().malloc(wrapped));
}
//
ByteSinkLength current;
public ByteSinkPacket24() {
this.reset();
}
@Override
public void reset() {
this.current = new ByteSinkLength(3) {
@Override
public void onReady(ByteBuffer buffer) {
// header is received
int len = ((buffer.getShort(0) & 0xFFFF) << 8)
| (buffer.get(3) & 0xFF);
current = new ByteSinkLength(len) {
@Override
public void onReady(ByteBuffer buffer) {
// sometime we want do reset in
// ByteSinkPacket24.this.onReady, then add the sink back
// to feeder, in such process, onReady should be execute
// at last.
current = null;
// content is received
ByteSinkPacket24.this.onReady(buffer);
}
};
}
};
}
@Override
public int feed(byte b) {
if (this.current == null) {
throw new IllegalStateException();
}
int result = this.current.feed(b);
if (result == FEED_ACCEPTED) {
return result;
}
// 'current' will be replaced by now
if (this.current == null) {
return result;
} else {
return FEED_ACCEPTED;
}
// return this.current.feed(b);
}
}

View File

@ -1,102 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
import jawnae.pyronet.PyroClient;
public abstract class ByteSinkPacket32 implements ByteSink {
public static void sendTo(PyroClient client, byte[] payload) {
boolean isExtreme = (payload.length > 0xFFFFFFFF - 4);
byte[] wrapped = new byte[4 + (isExtreme ? 0 : payload.length)];
wrapped[0] = (byte) (payload.length >> 24);
wrapped[1] = (byte) (payload.length >> 16);
wrapped[2] = (byte) (payload.length >> 8);
wrapped[3] = (byte) (payload.length >> 0);
if (!isExtreme) {
System.arraycopy(payload, 0, wrapped, 4, payload.length);
}
client.write(client.selector().malloc(wrapped));
if (isExtreme) {
client.write(client.selector().malloc(payload));
}
}
//
ByteSinkLength current;
public ByteSinkPacket32() {
this.reset();
}
@Override
public void reset() {
this.current = new ByteSinkLength(4) {
@Override
public void onReady(ByteBuffer buffer) {
// header is received
int len = buffer.getInt(0);
current = new ByteSinkLength(len) {
@Override
public void onReady(ByteBuffer buffer) {
// sometime we want do reset in
// ByteSinkPacket24.this.onReady, then add the sink back
// to feeder, in such process, onReady should be execute
// at last.
current = null;
// content is received
ByteSinkPacket32.this.onReady(buffer);
}
};
}
};
}
@Override
public int feed(byte b) {
if (this.current == null) {
throw new IllegalStateException();
}
int result = this.current.feed(b);
if (result == FEED_ACCEPTED) {
return result;
}
// 'current' will be replaced by now
if (this.current == null) {
return result;
}
else {
return FEED_ACCEPTED;
}
// return this.current.feed(b);
}
}

View File

@ -1,119 +0,0 @@
/*
* Copyright (c) 2008, https://code.google.com/p/pyronet/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroSelector;
import jawnae.pyronet.events.PyroClientAdapter;
public class PyroByteSinkFeeder extends PyroClientAdapter {
private final PyroSelector selector;
private final ByteStream inbound;
private final LinkedList<ByteSink> sinks;
public PyroByteSinkFeeder(PyroClient client) {
this(client.selector());
}
public PyroByteSinkFeeder(PyroSelector selector) {
this(selector, 8 * 1024);
}
public PyroByteSinkFeeder(PyroSelector selector, int bufferSize) {
this.selector = selector;
this.inbound = new ByteStream();
this.sinks = new LinkedList<ByteSink>();
}
//
@Override
public void receivedData(PyroClient client, ByteBuffer data) {
this.feed(data);
}
//
public ByteBuffer shutdown() {
int bytes = this.inbound.getByteCount();
ByteBuffer tmp = this.selector.malloc(bytes);
this.inbound.get(tmp);
this.inbound.discard(bytes);
tmp.flip();
return tmp;
}
public void addByteSink(ByteSink sink) {
this.selector.checkThread();
this.register(sink);
}
public void feed(ByteBuffer data) {
ByteBuffer copy = this.selector.copy(data);
this.inbound.append(copy);
this.fill();
}
final void register(ByteSink sink) {
this.sinks.addLast(sink);
this.fill();
}
private final void fill() {
if (this.sinks.isEmpty()) {
return;
}
ByteSink currentSink = this.sinks.removeFirst();
while (currentSink != null && inbound.hasData()) {
switch (currentSink.feed(inbound.read())) {
case ByteSink.FEED_ACCEPTED:
continue; // continue to next feed
case ByteSink.FEED_ACCEPTED_LAST:
break; // break out switch, not while
case ByteSink.FEED_REJECTED:
break; // break out switch, not while
}
if (this.sinks.isEmpty()) {
currentSink = null;
break;
}
currentSink = this.sinks.removeFirst();
}
if (currentSink != null) {
this.sinks.addFirst(currentSink);
}
}
}

View File

@ -36,6 +36,7 @@ import java.util.Locale;
public class PhoneFormat { public class PhoneFormat {
public byte[] data; public byte[] data;
private boolean initialzed = false;
public ByteBuffer buffer; public ByteBuffer buffer;
public String defaultCountry; public String defaultCountry;
public String defaultCallingCode; public String defaultCallingCode;
@ -90,6 +91,7 @@ public class PhoneFormat {
buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.order(ByteOrder.LITTLE_ENDIAN);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return;
} }
if (countryCode != null && countryCode.length() != 0) { if (countryCode != null && countryCode.length() != 0) {
@ -104,6 +106,7 @@ public class PhoneFormat {
countryCallingCode = new HashMap<String, String>(255); countryCallingCode = new HashMap<String, String>(255);
parseDataHeader(); parseDataHeader();
initialzed = true;
} }
public String defaultCallingCode() { public String defaultCallingCode() {
@ -139,6 +142,9 @@ public class PhoneFormat {
} }
public String format(String orig) { public String format(String orig) {
if (!initialzed) {
return orig;
}
String str = strip(orig); String str = strip(orig);
if (str.startsWith("+")) { if (str.startsWith("+")) {
@ -177,6 +183,9 @@ public class PhoneFormat {
} }
public boolean isPhoneNumberValid(String phoneNumber) { public boolean isPhoneNumberValid(String phoneNumber) {
if (!initialzed) {
return true;
}
String str = strip(phoneNumber); String str = strip(phoneNumber);
if (str.startsWith("+")) { if (str.startsWith("+")) {

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,7 +8,7 @@
package org.telegram.SQLite; package org.telegram.SQLite;
import android.util.Log; import org.telegram.messenger.FileLog;
public class SQLiteCursor { public class SQLiteCursor {
@ -83,14 +83,14 @@ public class SQLiteCursor {
int repeatCount = 6; int repeatCount = 6;
while (repeatCount-- != 0) { while (repeatCount-- != 0) {
try { try {
Log.e("tmessages", "sqlite busy, waiting..."); FileLog.e("tmessages", "sqlite busy, waiting...");
Thread.sleep(500); Thread.sleep(500);
res = preparedStatement.step(); res = preparedStatement.step();
if (res == 0) { if (res == 0) {
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
if (res == -1) { if (res == -1) {

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,11 +8,12 @@
package org.telegram.SQLite; package org.telegram.SQLite;
import org.telegram.messenger.FileLog;
import org.telegram.ui.ApplicationLoader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import android.util.Log;
public class SQLiteDatabase { public class SQLiteDatabase {
private final int sqliteHandle; private final int sqliteHandle;
@ -25,7 +26,7 @@ public class SQLiteDatabase {
} }
public SQLiteDatabase(String fileName) throws SQLiteException { public SQLiteDatabase(String fileName) throws SQLiteException {
sqliteHandle = opendb(fileName); sqliteHandle = opendb(fileName, ApplicationLoader.applicationContext.getFilesDir().getPath());
isOpen = true; isOpen = true;
preparedMap = new HashMap<String, SQLitePreparedStatement>(); preparedMap = new HashMap<String, SQLitePreparedStatement>();
} }
@ -111,7 +112,7 @@ public class SQLiteDatabase {
} }
closedb(sqliteHandle); closedb(sqliteHandle);
} catch (SQLiteException e) { } catch (SQLiteException e) {
Log.e("tmessages", e.getMessage(), e); FileLog.e("tmessages", e.getMessage(), e);
} }
isOpen = false; isOpen = false;
} }
@ -142,7 +143,7 @@ public class SQLiteDatabase {
commitTransaction(sqliteHandle); commitTransaction(sqliteHandle);
} }
native int opendb(String fileName) throws SQLiteException; native int opendb(String fileName, String tempDir) throws SQLiteException;
native void closedb(int sqliteHandle) throws SQLiteException; native void closedb(int sqliteHandle) throws SQLiteException;
native void beginTransaction(int sqliteHandle); native void beginTransaction(int sqliteHandle);
native void commitTransaction(int sqliteHandle); native void commitTransaction(int sqliteHandle);

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,7 +8,7 @@
package org.telegram.SQLite; package org.telegram.SQLite;
import android.util.Log; import org.telegram.messenger.FileLog;
public class SQLitePreparedStatement { public class SQLitePreparedStatement {
private boolean isFinalized = false; private boolean isFinalized = false;
@ -90,7 +90,7 @@ public class SQLitePreparedStatement {
isFinalized = true; isFinalized = true;
finalize(sqliteStatementHandle); finalize(sqliteStatementHandle);
} catch (SQLiteException e) { } catch (SQLiteException e) {
Log.e("tmessages", e.getMessage(), e); FileLog.e("tmessages", e.getMessage(), e);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,9 +8,7 @@
package org.telegram.TL; package org.telegram.TL;
import android.util.Log; import org.telegram.messenger.FileLog;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.SerializedData; import org.telegram.messenger.SerializedData;
import java.util.HashMap; import java.util.HashMap;
@ -373,6 +371,10 @@ public class TLClassStore {
classStore.put(TLRPC.TL_messages_sendEncryptedFile.constructor, TLRPC.TL_messages_sendEncryptedFile.class); classStore.put(TLRPC.TL_messages_sendEncryptedFile.constructor, TLRPC.TL_messages_sendEncryptedFile.class);
classStore.put(TLRPC.TL_messages_sendEncryptedService.constructor, TLRPC.TL_messages_sendEncryptedService.class); classStore.put(TLRPC.TL_messages_sendEncryptedService.constructor, TLRPC.TL_messages_sendEncryptedService.class);
classStore.put(TLRPC.TL_messages_receivedQueue.constructor, TLRPC.TL_messages_receivedQueue.class); classStore.put(TLRPC.TL_messages_receivedQueue.constructor, TLRPC.TL_messages_receivedQueue.class);
classStore.put(TLRPC.TL_upload_saveBigFilePart.constructor, TLRPC.TL_upload_saveBigFilePart.class);
classStore.put(TLRPC.TL_inputEncryptedFileBigUploaded.constructor, TLRPC.TL_inputEncryptedFileBigUploaded.class);
classStore.put(TLRPC.TL_inputFileBig.constructor, TLRPC.TL_inputFileBig.class);
classStore.put(TLRPC.TL_messageMediaUnsupported.constructor, TLRPC.TL_messageMediaUnsupported.class);
classStore.put(TLRPC.TL_msg_container.constructor, TLRPC.TL_msg_container.class); classStore.put(TLRPC.TL_msg_container.constructor, TLRPC.TL_msg_container.class);
classStore.put(TLRPC.TL_fileEncryptedLocation.constructor, TLRPC.TL_fileEncryptedLocation.class); classStore.put(TLRPC.TL_fileEncryptedLocation.constructor, TLRPC.TL_fileEncryptedLocation.class);
@ -381,6 +383,9 @@ public class TLClassStore {
classStore.put(TLRPC.TL_gzip_packed.constructor, TLRPC.TL_gzip_packed.class); classStore.put(TLRPC.TL_gzip_packed.constructor, TLRPC.TL_gzip_packed.class);
classStore.put(TLRPC.Vector.constructor, TLRPC.Vector.class); classStore.put(TLRPC.Vector.constructor, TLRPC.Vector.class);
classStore.put(TLRPC.TL_userProfilePhotoOld.constructor, TLRPC.TL_userProfilePhotoOld.class); classStore.put(TLRPC.TL_userProfilePhotoOld.constructor, TLRPC.TL_userProfilePhotoOld.class);
classStore.put(TLRPC.TL_messageActionUserUpdatedPhoto.constructor, TLRPC.TL_messageActionUserUpdatedPhoto.class);
classStore.put(TLRPC.TL_messageActionUserJoined.constructor, TLRPC.TL_messageActionUserJoined.class);
classStore.put(TLRPC.TL_messageActionLoginUnknownLocation.constructor, TLRPC.TL_messageActionLoginUnknownLocation.class);
} }
static TLClassStore store = null; static TLClassStore store = null;
@ -419,16 +424,14 @@ public class TLClassStore {
} }
return response; return response;
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
Log.e("tmessages", "can't create class"); FileLog.e("tmessages", "can't create class");
return null; return null;
} catch (InstantiationException e2) { } catch (InstantiationException e2) {
Log.e("tmessages", "can't create class"); FileLog.e("tmessages", "can't create class");
return null; return null;
} }
} else { } else {
if (ConnectionsManager.DEBUG_VERSION) { FileLog.e("tmessages", String.format("unknown class %x", constructor));
Log.e("tmessages", String.format("unknown class %x", constructor));
}
return null; return null;
//throw new RuntimeException(String.format("unknown class %x", constructor)); //throw new RuntimeException(String.format("unknown class %x", constructor));
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -813,6 +813,7 @@ public class TLRPC {
public String phone_number; public String phone_number;
public String first_name; public String first_name;
public String last_name; public String last_name;
public byte[] bytes;
public int user_id; public int user_id;
} }
@ -887,6 +888,19 @@ public class TLRPC {
} }
} }
public static class TL_messageMediaUnsupported extends MessageMedia {
public static int constructor = 0x29632a36;
public void readParams(SerializedData stream) {
bytes = stream.readByteArray();
}
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
stream.writeByteArray(bytes);
}
}
public static class TL_auth_sentCode extends TLObject { public static class TL_auth_sentCode extends TLObject {
public static int constructor = 0x2215bcbd; public static int constructor = 0x2215bcbd;
@ -2011,7 +2025,6 @@ public class TLRPC {
public static class TL_messageActionChatEditPhoto extends MessageAction { public static class TL_messageActionChatEditPhoto extends MessageAction {
public static int constructor = 0x7fcb13a8; public static int constructor = 0x7fcb13a8;
public void readParams(SerializedData stream) { public void readParams(SerializedData stream) {
photo = (Photo)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); photo = (Photo)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
} }
@ -2463,12 +2476,12 @@ public class TLRPC {
} }
public static class InputMedia extends TLObject { public static class InputMedia extends TLObject {
public TL_inputFile file; public InputFile file;
public InputGeoPoint geo_point; public InputGeoPoint geo_point;
public String phone_number; public String phone_number;
public String first_name; public String first_name;
public String last_name; public String last_name;
public TL_inputFile thumb; public InputFile thumb;
public int duration; public int duration;
public int w; public int w;
public int h; public int h;
@ -2479,7 +2492,7 @@ public class TLRPC {
public void readParams(SerializedData stream) { public void readParams(SerializedData stream) {
file = (TL_inputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); file = (InputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
} }
public void serializeToStream(SerializedData stream) { public void serializeToStream(SerializedData stream) {
@ -2540,8 +2553,8 @@ public class TLRPC {
public void readParams(SerializedData stream) { public void readParams(SerializedData stream) {
file = (TL_inputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); file = (InputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
thumb = (TL_inputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); thumb = (InputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
duration = stream.readInt32(); duration = stream.readInt32();
w = stream.readInt32(); w = stream.readInt32();
h = stream.readInt32(); h = stream.readInt32();
@ -2562,7 +2575,7 @@ public class TLRPC {
public void readParams(SerializedData stream) { public void readParams(SerializedData stream) {
file = (TL_inputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); file = (InputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
duration = stream.readInt32(); duration = stream.readInt32();
w = stream.readInt32(); w = stream.readInt32();
h = stream.readInt32(); h = stream.readInt32();
@ -3408,6 +3421,24 @@ public class TLRPC {
} }
} }
public static class TL_inputEncryptedFileBigUploaded extends InputEncryptedFile {
public static int constructor = 0x2dc173c8;
public void readParams(SerializedData stream) {
id = stream.readInt64();
parts = stream.readInt32();
key_fingerprint = stream.readInt32();
}
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(id);
stream.writeInt32(parts);
stream.writeInt32(key_fingerprint);
}
}
public static class TL_inputEncryptedFileEmpty extends InputEncryptedFile { public static class TL_inputEncryptedFileEmpty extends InputEncryptedFile {
public static int constructor = 0x1837c364; public static int constructor = 0x1837c364;
@ -3437,6 +3468,34 @@ public class TLRPC {
} }
} }
public static class TL_upload_saveBigFilePart extends TLObject {
public static int constructor = 0xde7b673d;
public long file_id;
public int file_part;
public int file_total_parts;
public byte[] bytes;
public Class responseClass () {
return Bool.class;
}
public void readParams(SerializedData stream) {
file_id = stream.readInt64();
file_part = stream.readInt32();
file_total_parts = stream.readInt32();
bytes = stream.readByteArray();
}
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(file_id);
stream.writeInt32(file_part);
stream.writeInt32(file_total_parts);
stream.writeByteArray(bytes);
}
}
public static class contacts_MyLink extends TLObject { public static class contacts_MyLink extends TLObject {
public boolean contact; public boolean contact;
} }
@ -4582,13 +4641,15 @@ public class TLRPC {
} }
} }
public static class TL_inputFile extends TLObject { public static class InputFile extends TLObject {
public static int constructor = 0xf52ff27f;
public long id; public long id;
public int parts; public int parts;
public String name; public String name;
public String md5_checksum; public String md5_checksum;
}
public static class TL_inputFile extends InputFile {
public static int constructor = 0xf52ff27f;
public void readParams(SerializedData stream) { public void readParams(SerializedData stream) {
id = stream.readInt64(); id = stream.readInt64();
@ -4606,6 +4667,24 @@ public class TLRPC {
} }
} }
public static class TL_inputFileBig extends InputFile {
public static int constructor = 0xfa4f0bb5;
public void readParams(SerializedData stream) {
id = stream.readInt64();
parts = stream.readInt32();
name = stream.readString();
}
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(id);
stream.writeInt32(parts);
stream.writeString(name);
}
}
public static class messages_StatedMessage extends TLObject { public static class messages_StatedMessage extends TLObject {
public Message message; public Message message;
public ArrayList<Chat> chats = new ArrayList<Chat>(); public ArrayList<Chat> chats = new ArrayList<Chat>();
@ -5139,7 +5218,7 @@ public class TLRPC {
public static class InputChatPhoto extends TLObject { public static class InputChatPhoto extends TLObject {
public InputPhoto id; public InputPhoto id;
public InputPhotoCrop crop; public InputPhotoCrop crop;
public TL_inputFile file; public InputFile file;
} }
public static class TL_inputChatPhoto extends InputChatPhoto { public static class TL_inputChatPhoto extends InputChatPhoto {
@ -5172,7 +5251,7 @@ public class TLRPC {
public void readParams(SerializedData stream) { public void readParams(SerializedData stream) {
file = (TL_inputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); file = (InputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
crop = (InputPhotoCrop)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); crop = (InputPhotoCrop)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
} }
@ -6661,7 +6740,7 @@ public class TLRPC {
public static class TL_photos_uploadProfilePhoto extends TLObject { public static class TL_photos_uploadProfilePhoto extends TLObject {
public static int constructor = 0xd50f9c88; public static int constructor = 0xd50f9c88;
public TL_inputFile file; public InputFile file;
public String caption; public String caption;
public InputGeoPoint geo_point; public InputGeoPoint geo_point;
public InputPhotoCrop crop; public InputPhotoCrop crop;
@ -6671,7 +6750,7 @@ public class TLRPC {
} }
public void readParams(SerializedData stream) { public void readParams(SerializedData stream) {
file = (TL_inputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); file = (InputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
caption = stream.readString(); caption = stream.readString();
geo_point = (InputGeoPoint)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); geo_point = (InputGeoPoint)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
crop = (InputPhotoCrop)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); crop = (InputPhotoCrop)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
@ -7949,6 +8028,7 @@ public class TLRPC {
public int unread_count; public int unread_count;
public int last_message_date; public int last_message_date;
public long id; public long id;
public int last_read;
public void readParams(SerializedData stream) { public void readParams(SerializedData stream) {
peer = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32()); peer = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
@ -8032,6 +8112,7 @@ public class TLRPC {
public static class MessageAction extends TLObject { public static class MessageAction extends TLObject {
public Photo photo; public Photo photo;
public UserProfilePhoto newUserPhoto;
public int user_id; public int user_id;
public String title; public String title;
public ArrayList<Integer> users = new ArrayList<Integer>(); public ArrayList<Integer> users = new ArrayList<Integer>();
@ -8090,6 +8171,46 @@ public class TLRPC {
} }
} }
public static class TL_messageActionUserUpdatedPhoto extends MessageAction {
public static int constructor = 0x55555551;
public void readParams(SerializedData stream) {
newUserPhoto = (UserProfilePhoto)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
}
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
newUserPhoto.serializeToStream(stream);
}
}
public static class TL_messageActionUserJoined extends MessageAction {
public static int constructor = 0x55555550;
public void readParams(SerializedData stream) {
}
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_messageActionLoginUnknownLocation extends MessageAction {
public static int constructor = 0x555555F5;
public void readParams(SerializedData stream) {
title = stream.readString();
address = stream.readString();
}
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
stream.writeString(title);
stream.writeString(address);
}
}
public static class invokeWithLayer8 extends TLObject { public static class invokeWithLayer8 extends TLObject {
public static int constructor = 0xe9abd9fd; public static int constructor = 0xe9abd9fd;
@ -8101,6 +8222,38 @@ public class TLRPC {
} }
} }
public static class invokeWithLayer9 extends TLObject {
public static int constructor = 0x76715a63;
public TLObject query;
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
query.serializeToStream(stream);
}
}
public static class initConnection extends TLObject {
public static int constructor = 0x69796de9;
public int api_id;
public String device_model;
public String system_version;
public String app_version;
public String lang_code;
public TLObject query;
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(api_id);
stream.writeString(device_model);
stream.writeString(system_version);
stream.writeString(app_version);
stream.writeString(lang_code);
query.serializeToStream(stream);
}
}
public static class decryptedMessageLayer extends TLObject { public static class decryptedMessageLayer extends TLObject {
public static int constructor = 0x99a438cf; public static int constructor = 0x99a438cf;

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -13,13 +13,11 @@ import android.accounts.OperationCanceledException;
import android.app.Service; import android.app.Service;
import android.content.AbstractThreadedSyncAdapter; import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient; import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SyncResult; import android.content.SyncResult;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.util.Log;
public class ContactsSyncAdapterService extends Service { public class ContactsSyncAdapterService extends Service {
private static SyncAdapterImpl sSyncAdapter = null; private static SyncAdapterImpl sSyncAdapter = null;
@ -41,7 +39,7 @@ public class ContactsSyncAdapterService extends Service {
try { try {
ContactsSyncAdapterService.performSync(mContext, account, extras, authority, provider, syncResult); ContactsSyncAdapterService.performSync(mContext, account, extras, authority, provider, syncResult);
} catch (OperationCanceledException e) { } catch (OperationCanceledException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
} }
@ -60,6 +58,6 @@ public class ContactsSyncAdapterService extends Service {
private static void performSync(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) private static void performSync(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
throws OperationCanceledException { throws OperationCanceledException {
Log.i("telegram", "performSync: " + account.toString()); FileLog.d("telegram", "performSync: " + account.toString());
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,24 +8,32 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.util.Log; import android.content.Context;
import android.content.SharedPreferences;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.ui.ApplicationLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
public class Datacenter { public class Datacenter {
private final int DATA_VERSION = 2;
public int datacenterId; public int datacenterId;
public String address; public ArrayList<String> addresses = new ArrayList<String>();
public int port; public HashMap<String, Integer> ports = new HashMap<String, Integer>();
public int[] defaultPorts = new int[] {-1, 80, -1, 88, -1, 443, -1, 80, -1, 443, -1};
public boolean authorized; public boolean authorized;
public long authSessionId; public long authSessionId;
public long authDownloadSessionId; public long authDownloadSessionId;
public long authUploadSessionId; public long authUploadSessionId;
public byte[] authKey; public byte[] authKey;
public byte[] authKeyId; public byte[] authKeyId;
private volatile int currentPortNum = 0;
private volatile int currentAddressNum = 0;
public TcpConnection connection; public TcpConnection connection;
public TcpConnection downloadConnection; public TcpConnection downloadConnection;
@ -37,39 +45,148 @@ public class Datacenter {
authServerSaltSet = new ArrayList<ServerSalt>(); authServerSaltSet = new ArrayList<ServerSalt>();
} }
public Datacenter(SerializedData data) { public Datacenter(SerializedData data, int version) {
datacenterId = data.readInt32(); if (version == 0) {
address = data.readString(); datacenterId = data.readInt32();
port = data.readInt32(); String address = data.readString();
if (port == 25) { addresses.add(address);
port = 443; int port = data.readInt32();
} ports.put(address, port);
int len = data.readInt32(); int len = data.readInt32();
if (len != 0) { if (len != 0) {
authKey = data.readData(len); authKey = data.readData(len);
}
len = data.readInt32();
if (len != 0) {
authKeyId = data.readData(len);
}
authorized = data.readInt32() != 0;
len = data.readInt32();
for (int a = 0; a < len; a++) {
ServerSalt salt = new ServerSalt();
salt.validSince = data.readInt32();
salt.validUntil = data.readInt32();
salt.value = data.readInt64();
if (authServerSaltSet == null) {
authServerSaltSet = new ArrayList<ServerSalt>();
} }
authServerSaltSet.add(salt); len = data.readInt32();
if (len != 0) {
authKeyId = data.readData(len);
}
authorized = data.readInt32() != 0;
len = data.readInt32();
for (int a = 0; a < len; a++) {
ServerSalt salt = new ServerSalt();
salt.validSince = data.readInt32();
salt.validUntil = data.readInt32();
salt.value = data.readInt64();
if (authServerSaltSet == null) {
authServerSaltSet = new ArrayList<ServerSalt>();
}
authServerSaltSet.add(salt);
}
} else if (version == 1) {
int currentVersion = data.readInt32();
if (currentVersion == 2) {
datacenterId = data.readInt32();
int len = data.readInt32();
for (int a = 0; a < len; a++) {
String address = data.readString();
addresses.add(address);
ports.put(address, data.readInt32());
}
len = data.readInt32();
if (len != 0) {
authKey = data.readData(len);
}
len = data.readInt32();
if (len != 0) {
authKeyId = data.readData(len);
}
authorized = data.readInt32() != 0;
len = data.readInt32();
for (int a = 0; a < len; a++) {
ServerSalt salt = new ServerSalt();
salt.validSince = data.readInt32();
salt.validUntil = data.readInt32();
salt.value = data.readInt64();
if (authServerSaltSet == null) {
authServerSaltSet = new ArrayList<ServerSalt>();
}
authServerSaltSet.add(salt);
}
}
}
readCurrentAddressAndPortNum();
}
public String getCurrentAddress() {
if (addresses.isEmpty()) {
return null;
}
if (currentAddressNum >= addresses.size()) {
currentAddressNum = 0;
}
return addresses.get(currentAddressNum);
}
public int getCurrentPort() {
if (ports.isEmpty()) {
return 443;
}
if (currentPortNum >= defaultPorts.length) {
currentPortNum = 0;
}
int port = defaultPorts[currentPortNum];
if (port == -1) {
String address = getCurrentAddress();
return ports.get(address);
}
return port;
}
public void addAddressAndPort(String address, int port) {
if (addresses.contains(address)) {
return;
}
addresses.add(address);
ports.put(address, port);
}
public void nextAddressOrPort() {
if (currentPortNum + 1 < defaultPorts.length) {
currentPortNum++;
} else {
if (currentAddressNum + 1 < addresses.size()) {
currentAddressNum++;
} else {
currentAddressNum = 0;
}
currentPortNum = 0;
} }
} }
public void storeCurrentAddressAndPortNum() {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("dataconfig", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("dc" + datacenterId + "port", currentPortNum);
editor.putInt("dc" + datacenterId + "address", currentAddressNum);
editor.commit();
}
});
}
private void readCurrentAddressAndPortNum() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("dataconfig", Context.MODE_PRIVATE);
currentPortNum = preferences.getInt("dc" + datacenterId + "port", 0);
currentAddressNum = preferences.getInt("dc" + datacenterId + "address", 0);
}
public void replaceAddressesAndPorts(ArrayList<String> newAddresses, HashMap<String, Integer> newPorts) {
addresses = newAddresses;
ports = newPorts;
}
public void SerializeToStream(SerializedData stream) { public void SerializeToStream(SerializedData stream) {
stream.writeInt32(DATA_VERSION);
stream.writeInt32(datacenterId); stream.writeInt32(datacenterId);
stream.writeString(address); stream.writeInt32(addresses.size());
stream.writeInt32(port); for (String address : addresses) {
stream.writeString(address);
stream.writeInt32(ports.get(address));
}
if (authKey != null) { if (authKey != null) {
stream.writeInt32(authKey.length); stream.writeInt32(authKey.length);
stream.writeRaw(authKey); stream.writeRaw(authKey);
@ -129,10 +246,8 @@ public class Datacenter {
} }
} }
if (ConnectionsManager.DEBUG_VERSION) { if (result == 0) {
if (result == 0) { FileLog.e("tmessages", "Valid salt not found");
Log.e("tmessages", "Valid salt not found", null);
}
} }
return result; return result;

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -22,7 +22,6 @@ import android.text.Spannable;
import android.text.Spanned; import android.text.Spanned;
import android.text.style.DynamicDrawableSpan; import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan; import android.text.style.ImageSpan;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
@ -364,7 +363,7 @@ public class Emoji {
return color; return color;
} catch(Throwable x) { } catch(Throwable x) {
Log.e("tmessages", "Error loading emoji", x); FileLog.e("tmessages", "Error loading emoji", x);
} }
return null; return null;
} }
@ -396,7 +395,7 @@ public class Emoji {
public static Drawable getEmojiDrawable(long code){ public static Drawable getEmojiDrawable(long code){
DrawableInfo info = rects.get(code); DrawableInfo info = rects.get(code);
if(info == null){ if(info == null){
Log.e("tmessages", "No emoji drawable for code " + String.format("%016X", code)); FileLog.e("tmessages", "No emoji drawable for code " + String.format("%016X", code));
return null; return null;
} }
EmojiDrawable ed = new EmojiDrawable(info); EmojiDrawable ed = new EmojiDrawable(info);

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -961,20 +961,15 @@ public class FastDateFormat extends Format {
* @return <code>true</code> if equal * @return <code>true</code> if equal
*/ */
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof FastDateFormat == false) { if (!(obj instanceof FastDateFormat)) {
return false; return false;
} }
FastDateFormat other = (FastDateFormat) obj; FastDateFormat other = (FastDateFormat) obj;
if ( return (mPattern == other.mPattern || mPattern.equals(other.mPattern)) &&
(mPattern == other.mPattern || mPattern.equals(other.mPattern)) && (mTimeZone == other.mTimeZone || mTimeZone.equals(other.mTimeZone)) &&
(mTimeZone == other.mTimeZone || mTimeZone.equals(other.mTimeZone)) && (mLocale == other.mLocale || mLocale.equals(other.mLocale)) &&
(mLocale == other.mLocale || mLocale.equals(other.mLocale)) && (mTimeZoneForced == other.mTimeZoneForced) &&
(mTimeZoneForced == other.mTimeZoneForced) && (mLocaleForced == other.mLocaleForced);
(mLocaleForced == other.mLocaleForced)
) {
return true;
}
return false;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -10,6 +10,7 @@ package org.telegram.messenger;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.Build;
import org.telegram.TL.TLObject; import org.telegram.TL.TLObject;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
@ -26,7 +27,7 @@ public class FileLoadOperation {
private int downloadChunkSize = 1024 * 32; private int downloadChunkSize = 1024 * 32;
public int datacenter_id; public int datacenter_id;
private TLRPC.InputFileLocation location; public TLRPC.InputFileLocation location;
public volatile int state = 0; public volatile int state = 0;
private int downloadedBytes; private int downloadedBytes;
public int totalBytesCount; public int totalBytesCount;
@ -39,12 +40,14 @@ public class FileLoadOperation {
private File cacheFileTemp; private File cacheFileTemp;
private File cacheFileFinal; private File cacheFileFinal;
private File cacheIvTemp;
private String httpUrl; private String httpUrl;
private URLConnection httpConnection; private URLConnection httpConnection;
public boolean needBitmapCreate = true; public boolean needBitmapCreate = true;
private InputStream httpConnectionStream; private InputStream httpConnectionStream;
private RandomAccessFile fileOutputStream; private RandomAccessFile fileOutputStream;
RandomAccessFile fiv;
public static interface FileLoadOperationDelegate { public static interface FileLoadOperationDelegate {
public abstract void didFinishLoadingFile(FileLoadOperation operation); public abstract void didFinishLoadingFile(FileLoadOperation operation);
@ -98,10 +101,20 @@ public class FileLoadOperation {
return; return;
} }
state = 1; state = 1;
if (location == null && httpUrl == null) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
delegate.didFailedLoadingFile(FileLoadOperation.this);
}
});
return;
}
boolean ignoreCache = false; boolean ignoreCache = false;
boolean onlyCache = false; boolean onlyCache = false;
String fileNameFinal; String fileNameFinal = null;
String fileNameTemp; String fileNameTemp = null;
String fileNameIv = null;
if (httpUrl != null) { if (httpUrl != null) {
fileNameFinal = Utilities.MD5(httpUrl); fileNameFinal = Utilities.MD5(httpUrl);
fileNameTemp = fileNameFinal + "_temp.jpg"; fileNameTemp = fileNameFinal + "_temp.jpg";
@ -109,6 +122,9 @@ public class FileLoadOperation {
} else if (location.volume_id != 0 && location.local_id != 0) { } else if (location.volume_id != 0 && location.local_id != 0) {
fileNameTemp = location.volume_id + "_" + location.local_id + "_temp.jpg"; fileNameTemp = location.volume_id + "_" + location.local_id + "_temp.jpg";
fileNameFinal = location.volume_id + "_" + location.local_id + ".jpg"; fileNameFinal = location.volume_id + "_" + location.local_id + ".jpg";
if (key != null) {
fileNameIv = location.volume_id + "_" + location.local_id + ".iv";
}
if (datacenter_id == Integer.MIN_VALUE || location.volume_id == Integer.MIN_VALUE) { if (datacenter_id == Integer.MIN_VALUE || location.volume_id == Integer.MIN_VALUE) {
onlyCache = true; onlyCache = true;
} }
@ -117,6 +133,9 @@ public class FileLoadOperation {
needBitmapCreate = false; needBitmapCreate = false;
fileNameTemp = datacenter_id + "_" + location.id + "_temp.mp4"; fileNameTemp = datacenter_id + "_" + location.id + "_temp.mp4";
fileNameFinal = datacenter_id + "_" + location.id + ".mp4"; fileNameFinal = datacenter_id + "_" + location.id + ".mp4";
if (key != null) {
fileNameIv = datacenter_id + "_" + location.id + ".iv";
}
} }
boolean exist; boolean exist;
@ -174,7 +193,9 @@ public class FileLoadOperation {
float scaleFactor = bitmapW / w_filter; float scaleFactor = bitmapW / w_filter;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, (int)w_filter, (int)(bitmapH / scaleFactor), true); Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, (int)w_filter, (int)(bitmapH / scaleFactor), true);
if (image != scaledBitmap) { if (image != scaledBitmap) {
image.recycle(); if (Build.VERSION.SDK_INT < 11) {
image.recycle();
}
image = scaledBitmap; image = scaledBitmap;
} }
} }
@ -193,12 +214,13 @@ public class FileLoadOperation {
}); });
} catch (Exception e) { } catch (Exception e) {
cacheFileFinal.delete(); cacheFileFinal.delete();
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
} else { } else {
if (onlyCache) { if (onlyCache) {
cleanup();
Utilities.stageQueue.postRunnable(new Runnable() { Utilities.stageQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -212,6 +234,21 @@ public class FileLoadOperation {
downloadedBytes = (int)cacheFileTemp.length(); downloadedBytes = (int)cacheFileTemp.length();
downloadedBytes = downloadedBytes / 1024 * 1024; downloadedBytes = downloadedBytes / 1024 * 1024;
} }
if (fileNameIv != null) {
cacheIvTemp = new File(Utilities.getCacheDir(), fileNameIv);
try {
fiv = new RandomAccessFile(cacheIvTemp, "rws");
long len = cacheIvTemp.length();
if (len > 0 && len % 32 == 0) {
fiv.read(iv, 0, 32);
} else {
downloadedBytes = 0;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
downloadedBytes = 0;
}
}
if (exist) { if (exist) {
cacheFileFinal.delete(); cacheFileFinal.delete();
} }
@ -221,15 +258,17 @@ public class FileLoadOperation {
fileOutputStream.seek(downloadedBytes); fileOutputStream.seek(downloadedBytes);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
if (fileOutputStream == null) { if (fileOutputStream == null) {
cleanup();
Utilities.stageQueue.postRunnable(new Runnable() { Utilities.stageQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
delegate.didFailedLoadingFile(FileLoadOperation.this); delegate.didFailedLoadingFile(FileLoadOperation.this);
} }
}); });
return;
} }
if (httpUrl != null) { if (httpUrl != null) {
startDownloadHTTPRequest(); startDownloadHTTPRequest();
@ -244,28 +283,41 @@ public class FileLoadOperation {
return; return;
} }
state = 2; state = 2;
cleanup();
if (httpUrl == null && requestToken != 0) {
ConnectionsManager.Instance.cancelRpc(requestToken, true);
}
delegate.didFailedLoadingFile(FileLoadOperation.this);
}
private void cleanup() {
if (httpUrl != null) { if (httpUrl != null) {
try { try {
httpConnectionStream.close(); httpConnectionStream.close();
httpConnection = null; httpConnection = null;
httpConnectionStream = null; httpConnectionStream = null;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} else { } else {
if (fileOutputStream != null) { try {
try { if (fileOutputStream != null) {
fileOutputStream.close(); fileOutputStream.close();
fileOutputStream = null; fileOutputStream = null;
} catch (Exception e) {
e.printStackTrace();
} }
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
if (requestToken != 0) {
ConnectionsManager.Instance.cancelRpc(requestToken, true); try {
if (fiv != null) {
fiv.close();
fiv = null;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
} }
delegate.didFailedLoadingFile(FileLoadOperation.this);
} }
private void onFinishLoadingFile() throws Exception { private void onFinishLoadingFile() throws Exception {
@ -273,8 +325,10 @@ public class FileLoadOperation {
return; return;
} }
state = 3; state = 3;
fileOutputStream.close(); cleanup();
fileOutputStream = null; if (cacheIvTemp != null) {
cacheIvTemp.delete();
}
final boolean renamed = cacheFileTemp.renameTo(cacheFileFinal); final boolean renamed = cacheFileTemp.renameTo(cacheFileFinal);
if (needBitmapCreate) { if (needBitmapCreate) {
@ -289,7 +343,7 @@ public class FileLoadOperation {
try { try {
Thread.sleep(delay); Thread.sleep(delay);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
BitmapFactory.Options opts = new BitmapFactory.Options(); BitmapFactory.Options opts = new BitmapFactory.Options();
@ -328,7 +382,9 @@ public class FileLoadOperation {
float scaleFactor = bitmapW / w_filter; float scaleFactor = bitmapW / w_filter;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, (int) w_filter, (int) (bitmapH / scaleFactor), true); Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, (int) w_filter, (int) (bitmapH / scaleFactor), true);
if (image != scaledBitmap) { if (image != scaledBitmap) {
image.recycle(); if (Build.VERSION.SDK_INT < 11) {
image.recycle();
}
image = scaledBitmap; image = scaledBitmap;
} }
} }
@ -338,7 +394,7 @@ public class FileLoadOperation {
FileLoader.Instance.runtimeHack.trackFree(image.getRowBytes() * image.getHeight()); FileLoader.Instance.runtimeHack.trackFree(image.getRowBytes() * image.getHeight());
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
delegate.didFinishLoadingFile(FileLoadOperation.this); delegate.didFinishLoadingFile(FileLoadOperation.this);
} }
@ -361,7 +417,8 @@ public class FileLoadOperation {
httpConnection.connect(); httpConnection.connect();
httpConnectionStream = httpConnection.getInputStream(); httpConnectionStream = httpConnection.getInputStream();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
cleanup();
Utilities.stageQueue.postRunnable(new Runnable() { Utilities.stageQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -384,6 +441,7 @@ public class FileLoadOperation {
} }
}); });
} else if (readed == -1) { } else if (readed == -1) {
cleanup();
Utilities.stageQueue.postRunnable(new Runnable() { Utilities.stageQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -395,6 +453,7 @@ public class FileLoadOperation {
} }
}); });
} else { } else {
cleanup();
Utilities.stageQueue.postRunnable(new Runnable() { Utilities.stageQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -403,18 +462,14 @@ public class FileLoadOperation {
}); });
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); cleanup();
FileLog.e("tmessages", e);
Utilities.stageQueue.postRunnable(new Runnable() { Utilities.stageQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
delegate.didFailedLoadingFile(FileLoadOperation.this); delegate.didFailedLoadingFile(FileLoadOperation.this);
} }
}); });
try {
httpConnectionStream.close();
} catch (Exception e2) {
e2.printStackTrace();
}
} }
} }
@ -424,8 +479,13 @@ public class FileLoadOperation {
} }
TLRPC.TL_upload_getFile req = new TLRPC.TL_upload_getFile(); TLRPC.TL_upload_getFile req = new TLRPC.TL_upload_getFile();
req.location = location; req.location = location;
req.offset = downloadedBytes; if (totalBytesCount == -1) {
req.limit = downloadChunkSize; req.offset = 0;
req.limit = 0;
} else {
req.offset = downloadedBytes;
req.limit = downloadChunkSize;
}
requestToken = ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { requestToken = ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override @Override
public void run(TLObject response, TLRPC.TL_error error) { public void run(TLObject response, TLRPC.TL_error error) {
@ -443,19 +503,24 @@ public class FileLoadOperation {
if (fileOutputStream != null) { if (fileOutputStream != null) {
fileOutputStream.write(res.bytes); fileOutputStream.write(res.bytes);
} }
if (fiv != null) {
fiv.seek(0);
fiv.write(iv);
}
downloadedBytes += res.bytes.length; downloadedBytes += res.bytes.length;
res.bytes = null; res.bytes = null;
if (totalBytesCount != 0) { if (totalBytesCount > 0) {
delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float)downloadedBytes / (float)totalBytesCount)); delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float)downloadedBytes / (float)totalBytesCount));
} }
if (downloadedBytes % downloadChunkSize == 0 || totalBytesCount != 0 && totalBytesCount != downloadedBytes) { if (downloadedBytes % downloadChunkSize == 0 || totalBytesCount > 0 && totalBytesCount != downloadedBytes) {
startDownloadRequest(); startDownloadRequest();
} else { } else {
onFinishLoadingFile(); onFinishLoadingFile();
} }
} catch (Exception e) { } catch (Exception e) {
cleanup();
delegate.didFailedLoadingFile(FileLoadOperation.this); delegate.didFailedLoadingFile(FileLoadOperation.this);
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} else { } else {
if (error.text.contains("FILE_MIGRATE_")) { if (error.text.contains("FILE_MIGRATE_")) {
@ -469,6 +534,7 @@ public class FileLoadOperation {
val = null; val = null;
} }
if (val == null) { if (val == null) {
cleanup();
delegate.didFailedLoadingFile(FileLoadOperation.this); delegate.didFailedLoadingFile(FileLoadOperation.this);
} else { } else {
datacenter_id = val; datacenter_id = val;
@ -479,13 +545,16 @@ public class FileLoadOperation {
try { try {
onFinishLoadingFile(); onFinishLoadingFile();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
cleanup();
delegate.didFailedLoadingFile(FileLoadOperation.this); delegate.didFailedLoadingFile(FileLoadOperation.this);
} }
} else { } else {
cleanup();
delegate.didFailedLoadingFile(FileLoadOperation.this); delegate.didFailedLoadingFile(FileLoadOperation.this);
} }
} else { } else {
cleanup();
delegate.didFailedLoadingFile(FileLoadOperation.this); delegate.didFailedLoadingFile(FileLoadOperation.this);
} }
} }
@ -493,7 +562,11 @@ public class FileLoadOperation {
}, new RPCRequest.RPCProgressDelegate() { }, new RPCRequest.RPCProgressDelegate() {
@Override @Override
public void progress(int length, int progress) { public void progress(int length, int progress) {
if (totalBytesCount > 0) {
delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float)(downloadedBytes + progress) / (float)totalBytesCount));
} else if (totalBytesCount == -1) {
delegate.didChangedLoadProgress(FileLoadOperation.this, Math.min(1.0f, (float)(progress) / (float)length));
}
} }
}, null, true, RPCRequest.RPCRequestClassDownloadMedia, datacenter_id); }, null, true, RPCRequest.RPCRequestClassDownloadMedia, datacenter_id);
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,12 +8,13 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.media.ExifInterface; import android.media.ExifInterface;
import android.os.Build; import android.os.Build;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
@ -37,16 +38,16 @@ public class FileLoader {
public LruCache memCache; public LruCache memCache;
private String ignoreRemoval = null; private String ignoreRemoval = null;
private HashMap<String, CacheImage> imageLoading; private ConcurrentHashMap<String, CacheImage> imageLoading;
private HashMap<Integer, CacheImage> imageLoadingByKeys; private HashMap<Integer, CacheImage> imageLoadingByKeys;
private Queue<FileLoadOperation> operationsQueue; private Queue<FileLoadOperation> operationsQueue;
private Queue<FileLoadOperation> runningOperation; private Queue<FileLoadOperation> runningOperation;
private final int maxConcurentLoadingOpertaionsCount = 2; private final int maxConcurentLoadingOpertaionsCount = 2;
private Queue<FileUploadOperation> uploadOperationQueue; private Queue<FileUploadOperation> uploadOperationQueue;
private HashMap<String, FileUploadOperation> uploadOperationPaths; private ConcurrentHashMap<String, FileUploadOperation> uploadOperationPaths;
private int currentUploadOperationsCount = 0; private int currentUploadOperationsCount = 0;
private Queue<FileLoadOperation> loadOperationQueue; private Queue<FileLoadOperation> loadOperationQueue;
private HashMap<String, FileLoadOperation> loadOperationPaths; private ConcurrentHashMap<String, FileLoadOperation> loadOperationPaths;
private int currentLoadOperationsCount = 0; private int currentLoadOperationsCount = 0;
public static long lastCacheOutTime = 0; public static long lastCacheOutTime = 0;
public ConcurrentHashMap<String, Float> fileProgresses = new ConcurrentHashMap<String, Float>(); public ConcurrentHashMap<String, Float> fileProgresses = new ConcurrentHashMap<String, Float>();
@ -109,20 +110,19 @@ public class FileLoader {
trackFree = cl.getMethod("trackExternalFree", new Class[] {long.class}); trackFree = cl.getMethod("trackExternalFree", new Class[] {long.class});
success = true; success = true;
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} catch (SecurityException e) { } catch (SecurityException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
if (!success) { if (!success) {
Log.i("tmessages", "VMRuntime hack does not work!");
runtime = null; runtime = null;
trackAllocation = null; trackAllocation = null;
trackFree = null; trackFree = null;
@ -216,6 +216,11 @@ public class FileLoader {
return false; return false;
} }
public void removeImage(String key) {
BitmapUseCounts.remove(key);
memCache.remove(key);
}
/*class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { /*class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private CacheImage cacheImage; private CacheImage cacheImage;
private Bitmap bitmap; private Bitmap bitmap;
@ -246,8 +251,8 @@ public class FileLoader {
}*/ }*/
public FileLoader() { public FileLoader() {
int maxMemory = (int)Runtime.getRuntime().maxMemory(); int cacheSize = Math.min(15, ((ActivityManager) ApplicationLoader.applicationContext.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass() / 7) * 1024 * 1024;
int cacheSize = maxMemory / 10;
density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (Build.VERSION.SDK_INT < 11) { if (Build.VERSION.SDK_INT < 11) {
runtimeHack = new VMRuntimeHack(); runtimeHack = new VMRuntimeHack();
@ -272,17 +277,21 @@ public class FileLoader {
if (runtimeHack != null) { if (runtimeHack != null) {
runtimeHack.trackAlloc(oldBitmap.getRowBytes() * oldBitmap.getHeight()); runtimeHack.trackAlloc(oldBitmap.getRowBytes() * oldBitmap.getHeight());
} }
oldBitmap.recycle(); if (Build.VERSION.SDK_INT < 11) {
if (!oldBitmap.isRecycled()) {
oldBitmap.recycle();
}
}
} }
} }
}; };
imageLoading = new HashMap<String, CacheImage>(); imageLoading = new ConcurrentHashMap<String, CacheImage>();
imageLoadingByKeys = new HashMap<Integer, CacheImage>(); imageLoadingByKeys = new HashMap<Integer, CacheImage>();
operationsQueue = new LinkedList<FileLoadOperation>(); operationsQueue = new LinkedList<FileLoadOperation>();
runningOperation = new LinkedList<FileLoadOperation>(); runningOperation = new LinkedList<FileLoadOperation>();
uploadOperationQueue = new LinkedList<FileUploadOperation>(); uploadOperationQueue = new LinkedList<FileUploadOperation>();
uploadOperationPaths = new HashMap<String, FileUploadOperation>(); uploadOperationPaths = new ConcurrentHashMap<String, FileUploadOperation>();
loadOperationPaths = new HashMap<String, FileLoadOperation>(); loadOperationPaths = new ConcurrentHashMap<String, FileLoadOperation>();
loadOperationQueue = new LinkedList<FileLoadOperation>(); loadOperationQueue = new LinkedList<FileLoadOperation>();
} }
@ -311,8 +320,9 @@ public class FileLoader {
uploadOperationPaths.put(location, operation); uploadOperationPaths.put(location, operation);
operation.delegate = new FileUploadOperation.FileUploadOperationDelegate() { operation.delegate = new FileUploadOperation.FileUploadOperationDelegate() {
@Override @Override
public void didFinishUploadingFile(FileUploadOperation operation, final TLRPC.TL_inputFile inputFile, final TLRPC.TL_inputEncryptedFileUploaded inputEncryptedFile) { public void didFinishUploadingFile(FileUploadOperation operation, final TLRPC.InputFile inputFile, final TLRPC.InputEncryptedFile inputEncryptedFile) {
NotificationCenter.Instance.postNotificationName(FileDidUpload, location, inputFile, inputEncryptedFile); NotificationCenter.Instance.postNotificationName(FileDidUpload, location, inputFile, inputEncryptedFile);
fileProgresses.remove(location);
Utilities.fileUploadQueue.postRunnable(new Runnable() { Utilities.fileUploadQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -400,6 +410,10 @@ public class FileLoader {
}); });
} }
public boolean isLoadingFile(String fileName) {
return loadOperationPaths.containsKey(fileName);
}
public void loadFile(final TLRPC.Video video, final TLRPC.PhotoSize photo) { public void loadFile(final TLRPC.Video video, final TLRPC.PhotoSize photo) {
Utilities.fileUploadQueue.postRunnable(new Runnable() { Utilities.fileUploadQueue.postRunnable(new Runnable() {
@Override @Override
@ -454,6 +468,7 @@ public class FileLoader {
} }
} }
}); });
fileProgresses.remove(arg1);
} }
@Override @Override
@ -628,14 +643,18 @@ public class FileLoader {
} }
public void loadImage(final String url, final View imageView, final String filter, final boolean cancel) { public void loadImage(final String url, final View imageView, final String filter, final boolean cancel) {
loadImage(null, url, imageView, filter, cancel); loadImage(null, url, imageView, filter, cancel, 0);
} }
public void loadImage(final TLRPC.FileLocation url, final View imageView, final String filter, final boolean cancel) { public void loadImage(final TLRPC.FileLocation url, final View imageView, final String filter, final boolean cancel) {
loadImage(url, null, imageView, filter, cancel); loadImage(url, null, imageView, filter, cancel, 0);
} }
public void loadImage(final TLRPC.FileLocation url, final String httpUrl, final View imageView, final String filter, final boolean cancel) { public void loadImage(final TLRPC.FileLocation url, final View imageView, final String filter, final boolean cancel, final int size) {
loadImage(url, null, imageView, filter, cancel, size);
}
public void loadImage(final TLRPC.FileLocation url, final String httpUrl, final View imageView, final String filter, final boolean cancel, final int size) {
if ((url == null && httpUrl == null) || imageView == null || (url != null && !(url instanceof TLRPC.TL_fileLocation) && !(url instanceof TLRPC.TL_fileEncryptedLocation))) { if ((url == null && httpUrl == null) || imageView == null || (url != null && !(url instanceof TLRPC.TL_fileLocation) && !(url instanceof TLRPC.TL_fileEncryptedLocation))) {
return; return;
} }
@ -700,20 +719,32 @@ public class FileLoader {
} else { } else {
loadOperation = new FileLoadOperation(url); loadOperation = new FileLoadOperation(url);
} }
loadOperation.totalBytesCount = size;
loadOperation.filter = filter; loadOperation.filter = filter;
loadOperation.delegate = new FileLoadOperation.FileLoadOperationDelegate() { loadOperation.delegate = new FileLoadOperation.FileLoadOperationDelegate() {
@Override @Override
public void didFinishLoadingFile(final FileLoadOperation operation) { public void didFinishLoadingFile(final FileLoadOperation operation) {
enqueueImageProcessingOperationWithImage(operation.image, filter, arg2, img); enqueueImageProcessingOperationWithImage(operation.image, filter, arg2, img);
if (operation.totalBytesCount != 0) {
final String arg1 = operation.location.volume_id + "_" + operation.location.local_id + ".jpg";
fileProgresses.remove(arg1);
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.Instance.postNotificationName(FileLoadProgressChanged, arg1, 1.0f);
}
});
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.Instance.postNotificationName(FileDidLoaded, arg1);
}
});
}
} }
@Override @Override
public void didFailedLoadingFile(final FileLoadOperation operation) { public void didFailedLoadingFile(final FileLoadOperation operation) {
if (url != null) {
if (url.volume_id != 0 && url.local_id != 0) {
fileProgresses.remove(url.volume_id + "_" + url.local_id + ".jpg");
}
}
Utilities.imageLoadQueue.postRunnable(new Runnable() { Utilities.imageLoadQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -731,13 +762,36 @@ public class FileLoader {
img.callAndClear(null); img.callAndClear(null);
} }
}); });
if (operation.totalBytesCount != 0) {
final String arg1 = operation.location.volume_id + "_" + operation.location.local_id + ".jpg";
fileProgresses.remove(arg1);
if (operation.state != 2) {
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.Instance.postNotificationName(FileDidFailedLoad, arg1);
}
});
}
}
} }
@Override @Override
public void didChangedLoadProgress(FileLoadOperation operation, float progress) { public void didChangedLoadProgress(FileLoadOperation operation, final float progress) {
if (url != null) { if (operation.totalBytesCount != 0) {
if (url.volume_id != 0 && url.local_id != 0) { final String arg1 = operation.location.volume_id + "_" + operation.location.local_id + ".jpg";
fileProgresses.put(url.volume_id + "_" + url.local_id + ".jpg", progress); if (operation.state != 2) {
fileProgresses.put(arg1, progress);
}
long currentTime = System.currentTimeMillis();
if (lastProgressUpdateTime == 0 || lastProgressUpdateTime < currentTime - 50) {
lastProgressUpdateTime = currentTime;
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.Instance.postNotificationName(FileLoadProgressChanged, arg1, progress);
}
});
} }
} }
} }
@ -842,31 +896,7 @@ public class FileLoader {
} }
}); });
} }
/*AsyncTask
NSBlockOperation *processingOperation = [NSBlockOperation blockOperationWithBlock:^(void) {
if (countCores() == 1)
[NSThread sleepForTimeInterval:0.1];
UIImage *filterImage = [UIImage decodedImageWithImage:image andFilter:filter];
if (!filterImage)
filterImage = image;
dispatch_async(dispatch_get_main_queue(), ^{
if (filterImage) {
if (![memCache objectForKey:key]) {
[memCache setObject:filterImage forKey:key];
[memArray addObject:key];
}
}
for (UIView *view in img.imageViewArray) {
NSNumber *num = objc_getAssociatedObject(view, &VIEW_CACHE_KEY);
[imageLoadingByKeys removeObjectForKey:num];
}
[img callAndClear:filterImage];
[imageLoading removeObjectForKey:key];
});
}];
[imageProcessingQueue addOperation:processingOperation];
*/
public static Bitmap loadBitmap(String path, float maxWidth, float maxHeight) { public static Bitmap loadBitmap(String path, float maxWidth, float maxHeight) {
BitmapFactory.Options bmOptions = new BitmapFactory.Options(); BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true; bmOptions.inJustDecodeBounds = true;
@ -898,7 +928,7 @@ public class FileLoader {
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
Bitmap b; Bitmap b;
@ -908,7 +938,7 @@ public class FileLoader {
b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true); b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
FileLoader.Instance.memCache.evictAll(); FileLoader.Instance.memCache.evictAll();
b = BitmapFactory.decodeFile(path, bmOptions); b = BitmapFactory.decodeFile(path, bmOptions);
if (b != null && matrix != null) { if (b != null && matrix != null) {
@ -959,8 +989,10 @@ public class FileLoader {
size.bytes = stream.toByteArray(); size.bytes = stream.toByteArray();
size.size = size.bytes.length; size.size = size.bytes.length;
} }
if (scaledBitmap != bitmap) { if (Build.VERSION.SDK_INT < 11) {
scaledBitmap.recycle(); if (scaledBitmap != bitmap) {
scaledBitmap.recycle();
}
} }
return size; return size;
} catch (Exception e) { } catch (Exception e) {

View File

@ -0,0 +1,158 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013.
*/
package org.telegram.messenger;
import android.net.Uri;
import android.util.Log;
import org.telegram.ui.ApplicationLoader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Locale;
public class FileLog {
public static boolean DEBUG_VERSION = true;
public static FileLog Instance = new FileLog();
private OutputStreamWriter streamWriter = null;
private FastDateFormat dateFormat = null;
private DispatchQueue logQueue = null;
private File currentFile = null;
public FileLog() {
if (!DEBUG_VERSION) {
return;
}
dateFormat = FastDateFormat.getInstance("dd_MM_yyyy_HH_mm_ss", Locale.US);
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
if (sdCard == null) {
return;
}
File dir = new File(sdCard.getAbsolutePath() + "/logs");
if (dir == null) {
return;
}
dir.mkdirs();
currentFile = new File(dir, dateFormat.format(System.currentTimeMillis()) + ".txt");
if (currentFile == null) {
return;
}
try {
currentFile.createNewFile();
FileOutputStream stream = new FileOutputStream(currentFile);
streamWriter = new OutputStreamWriter(stream);
streamWriter.write("-----start log " + dateFormat.format(System.currentTimeMillis()) + "-----\n");
streamWriter.flush();
logQueue = new DispatchQueue("logQueue");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void e(final String tag, final String message, final Throwable exception) {
if (!DEBUG_VERSION) {
return;
}
Log.e(tag, message, exception);
if (Instance.streamWriter != null) {
Instance.logQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "" + message + "\n");
Instance.streamWriter.write(exception.toString());
Instance.streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public static void e(final String tag, final String message) {
if (!DEBUG_VERSION) {
return;
}
Log.e(tag, message);
if (Instance.streamWriter != null) {
Instance.logQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "" + message + "\n");
Instance.streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public static void e(final String tag, final Exception e) {
if (!DEBUG_VERSION) {
return;
}
e.printStackTrace();
if (Instance.streamWriter != null) {
Instance.logQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "" + e + "\n");
StackTraceElement[] stack = e.getStackTrace();
for (StackTraceElement el : stack) {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "" + el + "\n");
}
Instance.streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public static void d(final String tag, final String message) {
if (!DEBUG_VERSION) {
return;
}
Log.d(tag, message);
if (Instance.streamWriter != null) {
Instance.logQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
Instance.streamWriter.write(Instance.dateFormat.format(System.currentTimeMillis()) + " D/" + tag + "" + message + "\n");
Instance.streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
public static void cleanupLogs() {
ArrayList<Uri> uris = new ArrayList<Uri>();
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
File dir = new File (sdCard.getAbsolutePath() + "/logs");
File[] files = dir.listFiles();
for (File file : files) {
if (Instance.currentFile != null && file.getAbsolutePath().equals(Instance.currentFile.getAbsolutePath())) {
continue;
}
file.delete();
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -29,15 +29,17 @@ public class FileUploadOperation {
private long currentFileId; private long currentFileId;
private boolean isLastPart = false; private boolean isLastPart = false;
private long totalFileSize = 0; private long totalFileSize = 0;
private int totalPartsCount = 0;
private long currentUploaded = 0; private long currentUploaded = 0;
private byte[] key; private byte[] key;
private byte[] iv; private byte[] iv;
private int fingerprint; private int fingerprint;
private boolean isBigFile = false;
FileInputStream stream; FileInputStream stream;
MessageDigest mdEnc = null; MessageDigest mdEnc = null;
public static interface FileUploadOperationDelegate { public static interface FileUploadOperationDelegate {
public abstract void didFinishUploadingFile(FileUploadOperation operation, TLRPC.TL_inputFile inputFile, TLRPC.TL_inputEncryptedFileUploaded inputEncryptedFile); public abstract void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile);
public abstract void didFailedUploadingFile(FileUploadOperation operation); public abstract void didFailedUploadingFile(FileUploadOperation operation);
public abstract void didChangedUploadProgress(FileUploadOperation operation, float progress); public abstract void didChangedUploadProgress(FileUploadOperation operation, float progress);
} }
@ -60,14 +62,14 @@ public class FileUploadOperation {
} }
fingerprint = Utilities.bytesToInt(fingerprintBytes); fingerprint = Utilities.bytesToInt(fingerprintBytes);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
currentFileId = (long)(MessagesController.random.nextDouble() * Long.MAX_VALUE); currentFileId = (long)(MessagesController.random.nextDouble() * Long.MAX_VALUE);
try { try {
mdEnc = MessageDigest.getInstance("MD5"); mdEnc = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -95,18 +97,23 @@ public class FileUploadOperation {
return; return;
} }
TLRPC.TL_upload_saveFilePart req = new TLRPC.TL_upload_saveFilePart(); TLObject finalRequest;
req.file_part = currentPartNum;
req.file_id = currentFileId;
try { try {
if (stream == null) { if (stream == null) {
File cacheFile = new File(uploadingFilePath); File cacheFile = new File(uploadingFilePath);
stream = new FileInputStream(cacheFile); stream = new FileInputStream(cacheFile);
totalFileSize = cacheFile.length(); totalFileSize = cacheFile.length();
if (totalFileSize > 10 * 1024 * 1024) {
FileLog.e("tmessages", "file is big!");
isBigFile = true;
}
uploadChunkSize = (int)Math.max(32, Math.ceil(totalFileSize / (1024.0f * 3000))) * 1024; uploadChunkSize = (int)Math.max(32, Math.ceil(totalFileSize / (1024.0f * 3000))) * 1024;
totalPartsCount = (int)Math.ceil((float)totalFileSize / (float)uploadChunkSize);
readBuffer = new byte[uploadChunkSize]; readBuffer = new byte[uploadChunkSize];
} }
int readed = stream.read(readBuffer); int readed = stream.read(readBuffer);
int toAdd = 0; int toAdd = 0;
if (key != null && readed % 16 != 0) { if (key != null && readed % 16 != 0) {
@ -121,14 +128,27 @@ public class FileUploadOperation {
sendBuffer = Utilities.aesIgeEncryption(sendBuffer, key, iv, true, true); sendBuffer = Utilities.aesIgeEncryption(sendBuffer, key, iv, true, true);
} }
mdEnc.update(sendBuffer, 0, readed + toAdd); mdEnc.update(sendBuffer, 0, readed + toAdd);
req.bytes = sendBuffer; if (isBigFile) {
TLRPC.TL_upload_saveBigFilePart req = new TLRPC.TL_upload_saveBigFilePart();
req.file_part = currentPartNum;
req.file_id = currentFileId;
req.file_total_parts = totalPartsCount;
req.bytes = sendBuffer;
finalRequest = req;
} else {
TLRPC.TL_upload_saveFilePart req = new TLRPC.TL_upload_saveFilePart();
req.file_part = currentPartNum;
req.file_id = currentFileId;
req.bytes = sendBuffer;
finalRequest = req;
}
currentUploaded += readed; currentUploaded += readed;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
delegate.didFailedUploadingFile(this); delegate.didFailedUploadingFile(this);
return; return;
} }
requestToken = ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { requestToken = ConnectionsManager.Instance.performRpc(finalRequest, new RPCRequest.RPCRequestDelegate() {
@Override @Override
public void run(TLObject response, TLRPC.TL_error error) { public void run(TLObject response, TLRPC.TL_error error) {
requestToken = 0; requestToken = 0;
@ -139,15 +159,25 @@ public class FileUploadOperation {
if (isLastPart) { if (isLastPart) {
state = 3; state = 3;
if (key == null) { if (key == null) {
TLRPC.TL_inputFile result = new TLRPC.TL_inputFile(); TLRPC.InputFile result;
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0'); if (isBigFile) {
result = new TLRPC.TL_inputFileBig();
} else {
result = new TLRPC.TL_inputFile();
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0');
}
result.parts = currentPartNum; result.parts = currentPartNum;
result.id = currentFileId; result.id = currentFileId;
result.name = uploadingFilePath.substring(uploadingFilePath.lastIndexOf("/") + 1); result.name = uploadingFilePath.substring(uploadingFilePath.lastIndexOf("/") + 1);
delegate.didFinishUploadingFile(FileUploadOperation.this, result, null); delegate.didFinishUploadingFile(FileUploadOperation.this, result, null);
} else { } else {
TLRPC.TL_inputEncryptedFileUploaded result = new TLRPC.TL_inputEncryptedFileUploaded(); TLRPC.InputEncryptedFile result;
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0'); if (isBigFile) {
result = new TLRPC.TL_inputEncryptedFileBigUploaded();
} else {
result = new TLRPC.TL_inputEncryptedFileUploaded();
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0');
}
result.parts = currentPartNum; result.parts = currentPartNum;
result.id = currentFileId; result.id = currentFileId;
result.key_fingerprint = fingerprint; result.key_fingerprint = fingerprint;

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -9,43 +9,28 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.app.Activity; import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.gcm.GoogleCloudMessaging; import com.google.android.gms.gcm.GoogleCloudMessaging;
import org.json.JSONObject;
import org.telegram.ui.ApplicationLoader;
import org.telegram.ui.LaunchActivity;
public class GcmBroadcastReceiver extends BroadcastReceiver { public class GcmBroadcastReceiver extends BroadcastReceiver {
public static final int NOTIFICATION_ID = 1; public static final int NOTIFICATION_ID = 1;
@Override @Override
public void onReceive(final Context context, final Intent intent) { public void onReceive(final Context context, final Intent intent) {
if (ConnectionsManager.DEBUG_VERSION) { FileLog.d("tmessages", "GCM received intent: " + intent);
Log.i("tmessages", "GCM received intent: " + intent);
}
setResultCode(Activity.RESULT_OK); setResultCode(Activity.RESULT_OK);
if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) { if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
SharedPreferences preferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE); SharedPreferences preferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
boolean globalEnabled = preferences.getBoolean("EnableAll", true); boolean globalEnabled = preferences.getBoolean("EnableAll", true);
if (!globalEnabled) { if (!globalEnabled) {
if (ConnectionsManager.DEBUG_VERSION) { FileLog.d("tmessages", "GCM disabled");
Log.i("tmessages", "GCM disabled");
}
return; return;
} }
@ -59,26 +44,22 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
thread.setPriority(Thread.MAX_PRIORITY); thread.setPriority(Thread.MAX_PRIORITY);
thread.start(); thread.start();
} else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) { } else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
if (ConnectionsManager.DEBUG_VERSION) { String registration = intent.getStringExtra("registration_id");
String registration = intent.getStringExtra("registration_id"); if (intent.getStringExtra("error") != null) {
if (intent.getStringExtra("error") != null) { FileLog.e("tmessages", "Registration failed, should try again later.");
Log.e("tmessages", "Registration failed, should try again later."); } else if (intent.getStringExtra("unregistered") != null) {
} else if (intent.getStringExtra("unregistered") != null) { FileLog.e("tmessages", "unregistration done, new messages from the authorized sender will be rejected");
Log.e("tmessages", "unregistration done, new messages from the authorized sender will be rejected"); } else if (registration != null) {
} else if (registration != null) { FileLog.e("tmessages", "registration id = " + registration);
Log.e("tmessages", "registration id = " + registration);
}
} }
} }
} }
private void sendNotification(Context context, Bundle extras) { private void sendNotification(Context context, Bundle extras) {
if (!UserConfig.clientActivated || context == null || extras == null) { ConnectionsManager.Instance.resumeNetworkMaybe();
/*if (!UserConfig.clientActivated || context == null || extras == null) {
return; return;
} }
if (ConnectionsManager.DEBUG_VERSION) {
Log.d("tmessages", "received push " + extras);
}
SharedPreferences preferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE); SharedPreferences preferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
boolean groupEnabled = preferences.getBoolean("EnableGroup", true); boolean groupEnabled = preferences.getBoolean("EnableGroup", true);
@ -112,7 +93,7 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
return; return;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
int chat_id = 0; int chat_id = 0;
@ -144,7 +125,7 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
if (user_id != 0) { if (user_id != 0) {
@ -224,6 +205,6 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
notification.ledOnMS = 1000; notification.ledOnMS = 1000;
notification.ledOffMS = 1000; notification.ledOffMS = 1000;
notification.flags |= Notification.FLAG_SHOW_LIGHTS; notification.flags |= Notification.FLAG_SHOW_LIGHTS;
mNotificationManager.notify(NOTIFICATION_ID, notification); mNotificationManager.notify(NOTIFICATION_ID, notification);*/
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,8 +8,6 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.util.Log;
import org.telegram.TL.TLClassStore; import org.telegram.TL.TLClassStore;
import org.telegram.TL.TLObject; import org.telegram.TL.TLObject;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
@ -50,15 +48,14 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
} }
public void execute(HashMap params) { public void execute(HashMap params) {
Log.d("tmessages", String.format("Begin handshake with DC%d", datacenter.datacenterId)); FileLog.d("tmessages", String.format(Locale.US, "Begin handshake with DC%d", datacenter.datacenterId));
beginHandshake(true); beginHandshake(true);
} }
void beginHandshake(boolean dropConnection) { void beginHandshake(boolean dropConnection) {
if (datacenter.connection == null) { if (datacenter.connection == null) {
datacenter.connection = new TcpConnection(datacenter.address, datacenter.port); datacenter.connection = new TcpConnection(datacenter.datacenterId);
datacenter.connection.delegate = this; datacenter.connection.delegate = this;
datacenter.connection.datacenterId = datacenter.datacenterId;
datacenter.connection.transportRequestClass = RPCRequest.RPCRequestClassGeneric; datacenter.connection.transportRequestClass = RPCRequest.RPCRequestClassGeneric;
} }
@ -168,7 +165,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
if (Arrays.equals(authNonce, resPq.nonce)) { if (Arrays.equals(authNonce, resPq.nonce)) {
final HashMap<String, Object> publicKey = selectPublicKey(resPq.server_public_key_fingerprints); final HashMap<String, Object> publicKey = selectPublicKey(resPq.server_public_key_fingerprints);
if (publicKey == null) { if (publicKey == null) {
Log.e("tmessages", "***** Couldn't find valid server public key"); FileLog.e("tmessages", "***** Couldn't find valid server public key");
beginHandshake(false); beginHandshake(false);
return; return;
} }
@ -222,8 +219,10 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
SerializedData dataWithHash = new SerializedData(); SerializedData dataWithHash = new SerializedData();
dataWithHash.writeRaw(Utilities.computeSHA1(innerDataBytes)); dataWithHash.writeRaw(Utilities.computeSHA1(innerDataBytes));
dataWithHash.writeRaw(innerDataBytes); dataWithHash.writeRaw(innerDataBytes);
byte[] b = new byte[1];
while (dataWithHash.length() < 255) { while (dataWithHash.length() < 255) {
dataWithHash.writeByte(0); MessagesController.random.nextBytes(b);
dataWithHash.writeByte(b[0]);
} }
byte[] encryptedBytes = Utilities.encryptWithRSA((BigInteger[])publicKey.get("key"), dataWithHash.toByteArray()); byte[] encryptedBytes = Utilities.encryptWithRSA((BigInteger[])publicKey.get("key"), dataWithHash.toByteArray());
@ -251,7 +250,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
} }
}); });
} else { } else {
Log.e("tmessages", "***** Error: invalid handshake nonce"); FileLog.e("tmessages", "***** Error: invalid handshake nonce");
beginHandshake(false); beginHandshake(false);
} }
} else if (message instanceof TLRPC.Server_DH_Params) { } else if (message instanceof TLRPC.Server_DH_Params) {
@ -309,7 +308,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
} }
if (!hashVerified) { if (!hashVerified) {
Log.e("tmessages", "***** Couldn't decode DH params"); FileLog.e("tmessages", "***** Couldn't decode DH params");
beginHandshake(false); beginHandshake(false);
return; return;
} }
@ -319,18 +318,18 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
TLRPC.TL_server_DH_inner_data dhInnerData = (TLRPC.TL_server_DH_inner_data)TLClassStore.Instance().TLdeserialize(answerIs, constructor); TLRPC.TL_server_DH_inner_data dhInnerData = (TLRPC.TL_server_DH_inner_data)TLClassStore.Instance().TLdeserialize(answerIs, constructor);
if (!(dhInnerData instanceof TLRPC.TL_server_DH_inner_data)) { if (!(dhInnerData instanceof TLRPC.TL_server_DH_inner_data)) {
Log.e("tmessages", "***** Couldn't parse decoded DH params"); FileLog.e("tmessages", "***** Couldn't parse decoded DH params");
beginHandshake(false); beginHandshake(false);
return; return;
} }
if (!Arrays.equals(authNonce, dhInnerData.nonce)) { if (!Arrays.equals(authNonce, dhInnerData.nonce)) {
Log.e("tmessages", "***** Invalid DH nonce"); FileLog.e("tmessages", "***** Invalid DH nonce");
beginHandshake(false); beginHandshake(false);
return; return;
} }
if (!Arrays.equals(authServerNonce, dhInnerData.server_nonce)) { if (!Arrays.equals(authServerNonce, dhInnerData.server_nonce)) {
Log.e("tmessages", "***** Invalid DH server nonce"); FileLog.e("tmessages", "***** Invalid DH server nonce");
beginHandshake(false); beginHandshake(false);
return; return;
} }
@ -380,9 +379,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
serverSalt.validUntil = (int)(System.currentTimeMillis() / 1000) + timeDifference + 30 * 60; serverSalt.validUntil = (int)(System.currentTimeMillis() / 1000) + timeDifference + 30 * 60;
serverSalt.value = saltBuffer.getLong(); serverSalt.value = saltBuffer.getLong();
if (ConnectionsManager.DEBUG_VERSION) { FileLog.d("tmessages", String.format(Locale.US, "===== Time difference: %d", timeDifference));
Log.d("tmessages", String.format(Locale.US, "===== Time difference: %d", timeDifference));
}
TLRPC.TL_client_DH_inner_data clientInnerData = new TLRPC.TL_client_DH_inner_data(); TLRPC.TL_client_DH_inner_data clientInnerData = new TLRPC.TL_client_DH_inner_data();
clientInnerData.nonce = authNonce; clientInnerData.nonce = authNonce;
@ -396,8 +393,10 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
SerializedData clientDataWithHash = new SerializedData(); SerializedData clientDataWithHash = new SerializedData();
clientDataWithHash.writeRaw(Utilities.computeSHA1(clientInnerDataBytes)); clientDataWithHash.writeRaw(Utilities.computeSHA1(clientInnerDataBytes));
clientDataWithHash.writeRaw(clientInnerDataBytes); clientDataWithHash.writeRaw(clientInnerDataBytes);
byte[] bb = new byte[1];
while (clientDataWithHash.length() % 16 != 0) { while (clientDataWithHash.length() % 16 != 0) {
clientDataWithHash.writeByte(0); MessagesController.random.nextBytes(bb);
clientDataWithHash.writeByte(bb[0]);
} }
TLRPC.TL_set_client_DH_params setClientDhParams = new TLRPC.TL_set_client_DH_params(); TLRPC.TL_set_client_DH_params setClientDhParams = new TLRPC.TL_set_client_DH_params();
@ -413,19 +412,19 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
reqDHMsgData = null; reqDHMsgData = null;
setClientDHParamsMsgData = sendMessageData(setClientDhParams, generateMessageId()); setClientDHParamsMsgData = sendMessageData(setClientDhParams, generateMessageId());
} else { } else {
Log.e("tmessages", "***** Couldn't set DH params"); FileLog.e("tmessages", "***** Couldn't set DH params");
beginHandshake(false); beginHandshake(false);
} }
} else if (message instanceof TLRPC.Set_client_DH_params_answer) { } else if (message instanceof TLRPC.Set_client_DH_params_answer) {
TLRPC.Set_client_DH_params_answer dhAnswer = (TLRPC.Set_client_DH_params_answer)message; TLRPC.Set_client_DH_params_answer dhAnswer = (TLRPC.Set_client_DH_params_answer)message;
if (!Arrays.equals(authNonce, dhAnswer.nonce)) { if (!Arrays.equals(authNonce, dhAnswer.nonce)) {
Log.e("tmessages", "***** Invalid DH answer nonce"); FileLog.e("tmessages", "***** Invalid DH answer nonce");
beginHandshake(false); beginHandshake(false);
return; return;
} }
if (!Arrays.equals(authServerNonce, dhAnswer.server_nonce)) { if (!Arrays.equals(authServerNonce, dhAnswer.server_nonce)) {
Log.e("tmessages", "***** Invalid DH answer server nonce"); FileLog.e("tmessages", "***** Invalid DH answer server nonce");
beginHandshake(false); beginHandshake(false);
return; return;
} }
@ -468,12 +467,12 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
if (message instanceof TLRPC.TL_dh_gen_ok) { if (message instanceof TLRPC.TL_dh_gen_ok) {
TLRPC.TL_dh_gen_ok dhGenOk = (TLRPC.TL_dh_gen_ok)message; TLRPC.TL_dh_gen_ok dhGenOk = (TLRPC.TL_dh_gen_ok)message;
if (!Arrays.equals(newNonceHash1, dhGenOk.new_nonce_hash1)) { if (!Arrays.equals(newNonceHash1, dhGenOk.new_nonce_hash1)) {
Log.e("tmessages", "***** Invalid DH answer nonce hash 1"); FileLog.e("tmessages", "***** Invalid DH answer nonce hash 1");
beginHandshake(false); beginHandshake(false);
return; return;
} }
Log.d("tmessages", String.format("Handshake with DC%d completed", datacenter.datacenterId)); FileLog.d("tmessages", String.format("Handshake with DC%d completed", datacenter.datacenterId));
datacenter.connection.delegate = null; datacenter.connection.delegate = null;
final Action parent = this; final Action parent = this;
@ -493,23 +492,23 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
} else if (message instanceof TLRPC.TL_dh_gen_retry) { } else if (message instanceof TLRPC.TL_dh_gen_retry) {
TLRPC.TL_dh_gen_retry dhRetry = (TLRPC.TL_dh_gen_retry)message; TLRPC.TL_dh_gen_retry dhRetry = (TLRPC.TL_dh_gen_retry)message;
if (!Arrays.equals(newNonceHash2, dhRetry.new_nonce_hash2)) { if (!Arrays.equals(newNonceHash2, dhRetry.new_nonce_hash2)) {
Log.e("tmessages", "***** Invalid DH answer nonce hash 2"); FileLog.e("tmessages", "***** Invalid DH answer nonce hash 2");
beginHandshake(false); beginHandshake(false);
return; return;
} }
Log.d("tmessages", "***** Retry DH"); FileLog.d("tmessages", "***** Retry DH");
beginHandshake(false); beginHandshake(false);
} else if (message instanceof TLRPC.TL_dh_gen_fail) { } else if (message instanceof TLRPC.TL_dh_gen_fail) {
TLRPC.TL_dh_gen_fail dhFail = (TLRPC.TL_dh_gen_fail)message; TLRPC.TL_dh_gen_fail dhFail = (TLRPC.TL_dh_gen_fail)message;
if (!Arrays.equals(newNonceHash3, dhFail.new_nonce_hash3)) { if (!Arrays.equals(newNonceHash3, dhFail.new_nonce_hash3)) {
Log.e("tmessages", "***** Invalid DH answer nonce hash 3"); FileLog.e("tmessages", "***** Invalid DH answer nonce hash 3");
beginHandshake(false); beginHandshake(false);
return; return;
} }
Log.d("tmessages", "***** Server declined DH params"); FileLog.d("tmessages", "***** Server declined DH params");
beginHandshake(false); beginHandshake(false);
} else { } else {
Log.e("tmessages", "***** Unknown DH params response"); FileLog.e("tmessages", "***** Unknown DH params response");
beginHandshake(false); beginHandshake(false);
} }
} else { } else {
@ -520,6 +519,11 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
} }
} }
@Override
public void tcpConnectionProgressChanged(TcpConnection connection, long messageId, int currentSize, int length) {
}
@Override @Override
public void tcpConnectionClosed(TcpConnection connection) { public void tcpConnectionClosed(TcpConnection connection) {
wasDisconnect = true; wasDisconnect = true;
@ -553,7 +557,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
if (keyId == 0) { if (keyId == 0) {
long messageId = is.readInt64(); long messageId = is.readInt64();
if (processedMessageIds.contains(messageId)) { if (processedMessageIds.contains(messageId)) {
Log.d("tmessages", String.format("===== Duplicate message id %d received, ignoring", messageId)); FileLog.d("tmessages", String.format("===== Duplicate message id %d received, ignoring", messageId));
return; return;
} }
int messageLength = is.readInt32(); int messageLength = is.readInt32();
@ -566,7 +570,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
} }
processMessage(object, messageId); processMessage(object, messageId);
} else { } else {
Log.d("tmessages", "***** Received encrypted message while in handshake, restarting"); FileLog.d("tmessages", "***** Received encrypted message while in handshake, restarting");
beginHandshake(true); beginHandshake(true);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -144,7 +144,7 @@ public class LruCache {
evictionCount++; evictionCount++;
} }
String[] args = key.split("$"); String[] args = key.split("@");
if (args.length > 1) { if (args.length > 1) {
ArrayList<String> arr = mapFilters.get(args[0]); ArrayList<String> arr = mapFilters.get(args[0]);
if (arr != null) { if (arr != null) {
@ -178,7 +178,7 @@ public class LruCache {
} }
if (previous != null) { if (previous != null) {
String[] args = key.split("$"); String[] args = key.split("@");
if (args.length > 1) { if (args.length > 1) {
ArrayList<String> arr = mapFilters.get(args[0]); ArrayList<String> arr = mapFilters.get(args[0]);
if (arr != null) { if (arr != null) {

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -9,6 +9,7 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.text.Html; import android.text.Html;
import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import org.telegram.SQLite.SQLiteCursor; import org.telegram.SQLite.SQLiteCursor;
@ -70,15 +71,20 @@ public class MessagesStorage {
database.executeFast("CREATE TABLE enc_tasks(date INTEGER, data BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE enc_tasks(date INTEGER, data BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE params(id INTEGER PRIMARY KEY, seq INTEGER, pts INTEGER, date INTEGER, qts INTEGER, lsv INTEGER, sg INTEGER, pbytes BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE params(id INTEGER PRIMARY KEY, seq INTEGER, pts INTEGER, date INTEGER, qts INTEGER, lsv INTEGER, sg INTEGER, pbytes BLOB)").stepThis().dispose();
database.executeFast("INSERT INTO params VALUES(1, 0, 0, 0, 0, 0, 0, NULL)").stepThis().dispose(); database.executeFast("INSERT INTO params VALUES(1, 0, 0, 0, 0, 0, 0, NULL)").stepThis().dispose();
database.executeFast("CREATE TABLE user_photos(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_dialogs ON dialogs(date);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_dialogs ON dialogs(date);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks ON enc_tasks(date);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks ON enc_tasks(date);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS last_mid_idx_dialogs ON dialogs(last_mid);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS last_mid_idx_dialogs ON dialogs(last_mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_idx_messages ON messages(uid, mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_messages ON messages(date);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_idx_media ON media(uid, mid);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_idx_media ON media(uid, mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS ttl_idx_messages ON messages(ttl);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_media ON media(mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS read_state_out_idx_messages ON messages(read_state, out);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_media ON media(uid, date, mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_idx_messages ON messages(uid, mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_messages ON messages(uid, date, mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages ON messages(mid, out);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages ON messages(uid, out, read_state, ttl, date, send_state);").stepThis().dispose();
} else { } else {
SQLiteCursor cursor = database.queryFinalized("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='params'"); SQLiteCursor cursor = database.queryFinalized("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='params'");
boolean create = false; boolean create = false;
@ -114,9 +120,21 @@ public class MessagesStorage {
} }
cursor.dispose(); cursor.dispose();
} }
database.executeFast("CREATE TABLE IF NOT EXISTS user_photos(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_media ON media(mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_media ON media(uid, date, mid);").stepThis().dispose();
database.executeFast("DROP INDEX IF EXISTS read_state_out_idx_messages;").stepThis().dispose();
database.executeFast("DROP INDEX IF EXISTS ttl_idx_messages;").stepThis().dispose();
database.executeFast("DROP INDEX IF EXISTS date_idx_messages;").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages ON messages(mid, out);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages ON messages(uid, out, read_state, ttl, date, send_state);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_messages ON messages(uid, date, mid);").stepThis().dispose();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -153,7 +171,7 @@ public class MessagesStorage {
old.delete(); old.delete();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
openDatabase(); openDatabase();
} }
@ -176,7 +194,7 @@ public class MessagesStorage {
state.step(); state.step();
state.dispose(); state.dispose();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -195,7 +213,7 @@ public class MessagesStorage {
state.step(); state.step();
state.dispose(); state.dispose();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -222,7 +240,7 @@ public class MessagesStorage {
state.dispose(); state.dispose();
database.commitTransaction(); database.commitTransaction();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -246,7 +264,7 @@ public class MessagesStorage {
cursor.dispose(); cursor.dispose();
NotificationCenter.Instance.postNotificationName(wallpapersDidLoaded, wallPapers); NotificationCenter.Instance.postNotificationName(wallpapersDidLoaded, wallPapers);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -265,7 +283,71 @@ public class MessagesStorage {
database.executeFast("DELETE FROM messages WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM messages WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM media WHERE uid = " + did).stepThis().dispose();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
}
}
});
}
public void getUserPhotos(final int uid, final int offset, final int count, final long max_id, final int classGuid) {
try {
SQLiteCursor cursor;
if (max_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM user_photos WHERE uid = %d AND id < %d ORDER BY id DESC LIMIT %d", uid, max_id, count));
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM user_photos WHERE uid = %d ORDER BY id DESC LIMIT %d,%d", uid, offset, count));
}
final TLRPC.photos_Photos res = new TLRPC.photos_Photos();
while (cursor.next()) {
byte[] messageData = cursor.byteArrayValue(0);
if (messageData != null) {
SerializedData data = new SerializedData(messageData);
TLRPC.Photo photo = (TLRPC.Photo)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
res.photos.add(photo);
}
}
cursor.dispose();
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
MessagesController.Instance.processLoadedUserPhotos(res, uid, offset, count, max_id, true, classGuid);
}
});
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void putUserPhotos(final int uid, final TLRPC.photos_Photos photos) {
if (photos == null || photos.photos.isEmpty()) {
return;
}
storageQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO user_photos VALUES(?, ?, ?)");
for (TLRPC.Photo photo : photos.photos) {
if (photo instanceof TLRPC.TL_photoEmpty) {
continue;
}
state.requery();
SerializedData data = new SerializedData();
photo.serializeToStream(data);
state.bindInteger(1, uid);
state.bindLong(2, photo.id);
byte[] bytes = data.toByteArray();
state.bindByteArray(3, bytes);
state.step();
}
state.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
} }
}); });
@ -297,7 +379,7 @@ public class MessagesStorage {
cursor.dispose(); cursor.dispose();
MessagesController.Instance.processLoadedDeleteTask(taskId, date, arr); MessagesController.Instance.processLoadedDeleteTask(taskId, date, arr);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -311,7 +393,7 @@ public class MessagesStorage {
int minDate = Integer.MAX_VALUE; int minDate = Integer.MAX_VALUE;
SparseArray<ArrayList<Integer>> messages = new SparseArray<ArrayList<Integer>>(); SparseArray<ArrayList<Integer>> messages = new SparseArray<ArrayList<Integer>>();
String mids = ""; String mids = "";
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl FROM messages WHERE uid = %d AND out = %d AND read_state = 1 AND ttl > 0 AND date <= %d", ((long)chat_id) << 32, isOut, time)); SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl FROM messages WHERE uid = %d AND out = %d AND read_state = 1 AND ttl > 0 AND date <= %d AND send_state = 0", ((long)chat_id) << 32, isOut, time));
while (cursor.next()) { while (cursor.next()) {
int mid = cursor.intValue(0); int mid = cursor.intValue(0);
int ttl = cursor.intValue(1); int ttl = cursor.intValue(1);
@ -358,7 +440,7 @@ public class MessagesStorage {
MessagesController.Instance.didAddedNewTask(minDate); MessagesController.Instance.didAddedNewTask(minDate);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -557,7 +639,7 @@ public class MessagesStorage {
MessagesController.Instance.processDialogsUpdate(dialogs, encryptedChats); MessagesController.Instance.processDialogsUpdate(dialogs, encryptedChats);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -601,7 +683,7 @@ public class MessagesStorage {
state.step(); state.step();
state.dispose(); state.dispose();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -650,7 +732,7 @@ public class MessagesStorage {
} }
MessagesController.Instance.processChatInfo(chat_id, info, loadedUsers, true); MessagesController.Instance.processChatInfo(chat_id, info, loadedUsers, true);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -662,15 +744,15 @@ public class MessagesStorage {
public void run() { public void run() {
try { try {
if (delete) { if (delete) {
database.executeFast("DELETE FROM pending_read WHERE uid = " + dialog_id).stepThis().dispose(); //database.executeFast("DELETE FROM pending_read WHERE uid = " + dialog_id).stepThis().dispose();
} else { } else {
database.beginTransaction(); database.beginTransaction();
SQLitePreparedStatement state = database.executeFast("REPLACE INTO pending_read VALUES(?, ?)"); SQLitePreparedStatement state;/*) = database.executeFast("REPLACE INTO pending_read VALUES(?, ?)");
state.requery(); state.requery();
state.bindLong(1, dialog_id); state.bindLong(1, dialog_id);
state.bindInteger(2, max_id); state.bindInteger(2, max_id);
state.step(); state.step();
state.dispose(); state.dispose();*/
int lower_id = (int)dialog_id; int lower_id = (int)dialog_id;
@ -699,7 +781,7 @@ public class MessagesStorage {
database.commitTransaction(); database.commitTransaction();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -711,13 +793,13 @@ public class MessagesStorage {
public void run() { public void run() {
try { try {
ArrayList<TLRPC.User> encUsers = new ArrayList<TLRPC.User>(); ArrayList<TLRPC.User> encUsers = new ArrayList<TLRPC.User>();
if (query.length() == 0) { String q = query.trim().toLowerCase();
if (q.length() == 0) {
NotificationCenter.Instance.postNotificationName(MessagesController.reloadSearchResults, token, new ArrayList<TLObject>(), new ArrayList<CharSequence>(), new ArrayList<CharSequence>()); NotificationCenter.Instance.postNotificationName(MessagesController.reloadSearchResults, token, new ArrayList<TLObject>(), new ArrayList<CharSequence>(), new ArrayList<CharSequence>());
return; return;
} }
ArrayList<TLObject> resultArray = new ArrayList<TLObject>(); ArrayList<TLObject> resultArray = new ArrayList<TLObject>();
ArrayList<CharSequence> resultArrayNames = new ArrayList<CharSequence>(); ArrayList<CharSequence> resultArrayNames = new ArrayList<CharSequence>();
String q = query.toLowerCase();
SQLiteCursor cursor = database.queryFinalized("SELECT u.data, u.status, u.name FROM users as u INNER JOIN contacts as c ON u.uid = c.uid"); SQLiteCursor cursor = database.queryFinalized("SELECT u.data, u.status, u.name FROM users as u INNER JOIN contacts as c ON u.uid = c.uid");
while (cursor.next()) { while (cursor.next()) {
@ -797,7 +879,7 @@ public class MessagesStorage {
cursor.dispose(); cursor.dispose();
NotificationCenter.Instance.postNotificationName(MessagesController.reloadSearchResults, token, resultArray, resultArrayNames, encUsers); NotificationCenter.Instance.postNotificationName(MessagesController.reloadSearchResults, token, resultArray, resultArrayNames, encUsers);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -825,7 +907,7 @@ public class MessagesStorage {
state.dispose(); state.dispose();
database.commitTransaction(); database.commitTransaction();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -873,7 +955,7 @@ public class MessagesStorage {
} }
MessagesController.Instance.processLoadedContacts(contacts, users, 1); MessagesController.Instance.processLoadedContacts(contacts, users, 1);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -891,7 +973,7 @@ public class MessagesStorage {
state2.step(); state2.step();
state2.dispose(); state2.dispose();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -921,7 +1003,7 @@ public class MessagesStorage {
} }
MessagesController.Instance.processLoadedMediaCount(count, uid, classGuid, true); MessagesController.Instance.processLoadedMediaCount(count, uid, classGuid, true);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -938,7 +1020,6 @@ public class MessagesStorage {
SQLiteCursor cursor; SQLiteCursor cursor;
if ((int)uid != 0) { if ((int)uid != 0) {
if (max_id != 0) { if (max_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media WHERE uid = %d AND mid < %d ORDER BY date DESC, mid DESC LIMIT %d", uid, max_id, count)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media WHERE uid = %d AND mid < %d ORDER BY date DESC, mid DESC LIMIT %d", uid, max_id, count));
@ -996,7 +1077,7 @@ public class MessagesStorage {
res.messages.clear(); res.messages.clear();
res.chats.clear(); res.chats.clear();
res.users.clear(); res.users.clear();
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
MessagesController.Instance.processLoadedMedia(res, uid, offset, count, max_id, true, classGuid); MessagesController.Instance.processLoadedMedia(res, uid, offset, count, max_id, true, classGuid);
} }
@ -1021,55 +1102,112 @@ public class MessagesStorage {
state2.bindInteger(3, message.date); state2.bindInteger(3, message.date);
state2.bindByteArray(4, data.toByteArray()); state2.bindByteArray(4, data.toByteArray());
state2.step(); state2.step();
} else {
Log.e("tmessages", "test");
} }
} }
state2.dispose(); state2.dispose();
database.commitTransaction(); database.commitTransaction();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
} }
public void getMessages(final long dialog_id, final int offset, final int count, final int max_id, final int minDate, final int classGuid) { public void getMessages(final long dialog_id, final int offset, final int count, final int max_id, final int minDate, final int classGuid, final boolean from_unread, final boolean forward) {
storageQueue.postRunnable(new Runnable() { storageQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages(); TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages();
int count_unread = 0;
int count_query = count;
int offset_query = offset;
int min_unread_id = 0;
int max_unread_id = 0;
int max_unread_date = 0;
try { try {
ArrayList<Integer> loadedUsers = new ArrayList<Integer>(); ArrayList<Integer> loadedUsers = new ArrayList<Integer>();
ArrayList<Integer> fromUser = new ArrayList<Integer>(); ArrayList<Integer> fromUser = new ArrayList<Integer>();
SQLiteCursor cursor; SQLiteCursor cursor;
int lower_id = (int)dialog_id; int lower_id = (int)dialog_id;
if (lower_id != 0) { if (lower_id != 0) {
if (minDate != 0) { if (forward) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND mid > %d ORDER BY date ASC, mid ASC LIMIT %d", dialog_id, max_id, count_query));
} else if (minDate != 0) {
if (max_id != 0) { if (max_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND mid < %d AND date < %d ORDER BY date DESC, mid DESC LIMIT %d", dialog_id, max_id, minDate, count)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND date < %d AND mid < %d ORDER BY date DESC, mid DESC LIMIT %d", dialog_id, minDate, max_id, count_query));
} else { } else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND date < %d ORDER BY date DESC, mid DESC LIMIT %d,%d", dialog_id, minDate, offset, count)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND date < %d ORDER BY date DESC, mid DESC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query));
} }
} else { } else {
if (max_id != 0) { if (from_unread) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND mid < %d ORDER BY date DESC, mid DESC LIMIT %d", dialog_id, max_id, count)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid), max(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state = 0 AND mid > 0", dialog_id));
} else { if (cursor.next()) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d ORDER BY date DESC, mid DESC LIMIT %d,%d", dialog_id, offset, count)); min_unread_id = cursor.intValue(0);
max_unread_id = cursor.intValue(1);
max_unread_date = cursor.intValue(2);
}
cursor.dispose();
if (min_unread_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages WHERE uid = %d AND mid >= %d AND out = 0 AND read_state = 0", dialog_id, min_unread_id));
if (cursor.next()) {
count_unread = cursor.intValue(0);
}
cursor.dispose();
}
} }
if (count_query > count_unread || count_unread < 4) {
count_query = Math.max(count_query, count_unread + 10);
if (count_unread < 4) {
count_unread = 0;
min_unread_id = 0;
max_unread_id = 0;
}
} else {
offset_query = count_unread - count_query;
count_query += 10;
}
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d ORDER BY date DESC, mid DESC LIMIT %d,%d", dialog_id, offset_query, count_query));
} }
} else { } else {
if (minDate != 0) { if (forward) {
if (max_id != 0) { cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND mid < %d ORDER BY mid DESC LIMIT %d", dialog_id, max_id, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND mid < %d AND date < %d ORDER BY date DESC LIMIT %d", dialog_id, max_id, minDate, count)); } else if (minDate != 0) {
} else { cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND date < %d ORDER BY mid ASC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND date < %d ORDER BY date DESC LIMIT %d,%d", dialog_id, minDate, offset, count));
}
} else { } else {
if (max_id != 0) { if (from_unread) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND mid < %d ORDER BY date DESC LIMIT %d", dialog_id, max_id, count)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid), min(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state = 0 AND mid < 0", dialog_id));
} else { if (cursor.next()) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d ORDER BY date DESC LIMIT %d,%d", dialog_id, offset, count)); min_unread_id = cursor.intValue(0);
max_unread_id = cursor.intValue(1);
max_unread_date = cursor.intValue(2);
}
cursor.dispose();
if (min_unread_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages WHERE uid = %d AND mid <= %d AND out = 0 AND read_state = 0", dialog_id, min_unread_id));
if (cursor.next()) {
count_unread = cursor.intValue(0);
}
cursor.dispose();
}
} }
if (count_query > count_unread || count_unread < 4) {
count_query = Math.max(count_query, count_unread + 10);
if (count_unread < 4) {
count_unread = 0;
min_unread_id = 0;
max_unread_id = 0;
}
} else {
offset_query = count_unread - count_query;
count_query += 10;
}
cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d ORDER BY mid ASC LIMIT %d,%d", dialog_id, offset_query, count_query));
} }
} }
while (cursor.next()) { while (cursor.next()) {
@ -1131,9 +1269,9 @@ public class MessagesStorage {
res.messages.clear(); res.messages.clear();
res.chats.clear(); res.chats.clear();
res.users.clear(); res.users.clear();
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
MessagesController.Instance.processLoadedMessages(res, dialog_id, offset, count, max_id, true, classGuid); MessagesController.Instance.processLoadedMessages(res, dialog_id, offset, count_query, max_id, true, classGuid, min_unread_id, max_unread_id, count_unread, max_unread_date, forward);
} }
} }
}); });
@ -1147,7 +1285,7 @@ public class MessagesStorage {
try { try {
database.beginTransaction(); database.beginTransaction();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -1155,7 +1293,7 @@ public class MessagesStorage {
try { try {
database.beginTransaction(); database.beginTransaction();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
} }
@ -1187,7 +1325,7 @@ public class MessagesStorage {
state.bindInteger(2, chat.id); state.bindInteger(2, chat.id);
state.step(); state.step();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
if (state != null) { if (state != null) {
state.dispose(); state.dispose();
@ -1224,7 +1362,7 @@ public class MessagesStorage {
state.bindInteger(5, chat.id); state.bindInteger(5, chat.id);
state.step(); state.step();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
if (state != null) { if (state != null) {
state.dispose(); state.dispose();
@ -1278,7 +1416,7 @@ public class MessagesStorage {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
semaphore.release(); semaphore.release();
} }
@ -1330,7 +1468,7 @@ public class MessagesStorage {
state.dispose(); state.dispose();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -1389,7 +1527,7 @@ public class MessagesStorage {
database.commitTransaction(); database.commitTransaction();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -1546,7 +1684,7 @@ public class MessagesStorage {
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -1575,7 +1713,7 @@ public class MessagesStorage {
state.bindInteger(2, newId); state.bindInteger(2, newId);
state.step(); state.step();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
if (state != null) { if (state != null) {
state.dispose(); state.dispose();
@ -1592,7 +1730,7 @@ public class MessagesStorage {
oldId = cursor.intValue(0); oldId = cursor.intValue(0);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
if (cursor != null) { if (cursor != null) {
cursor.dispose(); cursor.dispose();
@ -1602,7 +1740,7 @@ public class MessagesStorage {
// try { // try {
// database.executeFast(String.format(Locale.US, "DELETE FROM randoms WHERE random_id = %d", random_id)).stepThis().dispose(); // database.executeFast(String.format(Locale.US, "DELETE FROM randoms WHERE random_id = %d", random_id)).stepThis().dispose();
// } catch (Exception e) { // } catch (Exception e) {
// e.printStackTrace(); // FileLog.e("tmessages", e);
// } // }
// } // }
} }
@ -1617,7 +1755,7 @@ public class MessagesStorage {
state.bindInteger(2, oldId); state.bindInteger(2, oldId);
state.step(); state.step();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
if (state != null) { if (state != null) {
state.dispose(); state.dispose();
@ -1630,7 +1768,7 @@ public class MessagesStorage {
state.bindInteger(2, oldId); state.bindInteger(2, oldId);
state.step(); state.step();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
if (state != null) { if (state != null) {
state.dispose(); state.dispose();
@ -1643,7 +1781,7 @@ public class MessagesStorage {
state.bindLong(2, oldId); state.bindLong(2, oldId);
state.step(); state.step();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} finally { } finally {
if (state != null) { if (state != null) {
state.dispose(); state.dispose();
@ -1754,7 +1892,7 @@ public class MessagesStorage {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -1802,7 +1940,7 @@ public class MessagesStorage {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -1836,7 +1974,7 @@ public class MessagesStorage {
database.executeFast("DELETE FROM media_counts WHERE 1").stepThis().dispose(); database.executeFast("DELETE FROM media_counts WHERE 1").stepThis().dispose();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -2010,7 +2148,7 @@ public class MessagesStorage {
MessagesController.Instance.processDialogsUpdate(dialogs, encryptedChats); MessagesController.Instance.processDialogsUpdate(dialogs, encryptedChats);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -2129,7 +2267,7 @@ public class MessagesStorage {
database.commitTransaction(); database.commitTransaction();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -2228,7 +2366,7 @@ public class MessagesStorage {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
cursor.dispose(); cursor.dispose();
@ -2254,7 +2392,7 @@ public class MessagesStorage {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
cursor.dispose(); cursor.dispose();
@ -2283,7 +2421,7 @@ public class MessagesStorage {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
cursor.dispose(); cursor.dispose();
@ -2294,11 +2432,11 @@ public class MessagesStorage {
dialogs.users.clear(); dialogs.users.clear();
dialogs.chats.clear(); dialogs.chats.clear();
encryptedChats.clear(); encryptedChats.clear();
e.printStackTrace(); FileLog.e("tmessages", e);
/*try { /*try {
database.executeFast("DELETE FROM dialogs WHERE 1").stepThis().dispose(); database.executeFast("DELETE FROM dialogs WHERE 1").stepThis().dispose();
} catch (Exception e2) { } catch (Exception e2) {
e.printStackTrace(); FileLog.e("tmessages", e);
}*/ }*/
MessagesController.Instance.processLoadedDialogs(dialogs, encryptedChats, 0, 0, 100, true, true); MessagesController.Instance.processLoadedDialogs(dialogs, encryptedChats, 0, 0, 100, true, true);
} }
@ -2412,7 +2550,7 @@ public class MessagesStorage {
database.commitTransaction(); database.commitTransaction();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,8 +8,6 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.util.Log;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
@ -30,6 +28,11 @@ public class SerializedData {
out = new DataOutputStream(outbuf); out = new DataOutputStream(outbuf);
} }
public SerializedData(int size) {
outbuf = new ByteArrayOutputStream(size);
out = new DataOutputStream(outbuf);
}
public SerializedData(byte[] data){ public SerializedData(byte[] data){
isOut = false; isOut = false;
inbuf = new ByteArrayInputStream(data); inbuf = new ByteArrayInputStream(data);
@ -57,7 +60,7 @@ public class SerializedData {
out.write(x >> (i * 8)); out.write(x >> (i * 8));
} }
} catch(IOException gfdsgd) { } catch(IOException gfdsgd) {
Log.e("tmessages", "write int32 error"); FileLog.e("tmessages", "write int32 error");
} }
} }
@ -71,7 +74,7 @@ public class SerializedData {
out.write((int)(x >> (i * 8))); out.write((int)(x >> (i * 8)));
} }
} catch(IOException gfdsgd) { } catch(IOException gfdsgd) {
Log.e("tmessages", "write int64 error"); FileLog.e("tmessages", "write int64 error");
} }
} }
@ -82,7 +85,7 @@ public class SerializedData {
} else if (consructor == 0xbc799737) { } else if (consructor == 0xbc799737) {
return false; return false;
} }
Log.e("tmessages", "Not bool value!"); FileLog.e("tmessages", "Not bool value!");
return false; return false;
} }
@ -94,28 +97,48 @@ public class SerializedData {
} }
} }
public int readInt32(){ public int readInt32() {
return readInt32(null);
}
public int readInt32(boolean[] error) {
try { try {
int i = 0; int i = 0;
for(int j = 0; j < 4; j++){ for(int j = 0; j < 4; j++){
i |= (in.read() << (j * 8)); i |= (in.read() << (j * 8));
} }
if (error != null) {
error[0] = false;
}
return i; return i;
} catch(IOException x) { } catch(IOException x) {
Log.e("tmessages", "read int32 error"); if (error != null) {
error[0] = true;
}
FileLog.e("tmessages", "read int32 error");
} }
return 0; return 0;
} }
public long readInt64(){ public long readInt64() {
return readInt64(null);
}
public long readInt64(boolean[] error) {
try { try {
long i = 0; long i = 0;
for(int j = 0; j < 8; j++){ for(int j = 0; j < 8; j++){
i |= ((long)in.read() << (j * 8)); i |= ((long)in.read() << (j * 8));
} }
if (error != null) {
error[0] = false;
}
return i; return i;
} catch(IOException x) { } catch(IOException x) {
Log.e("tmessages", "read int64 error"); if (error != null) {
error[0] = true;
}
FileLog.e("tmessages", "read int64 error");
} }
return 0; return 0;
} }
@ -124,7 +147,7 @@ public class SerializedData {
try { try {
out.write(b); out.write(b);
} catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "write raw error"); FileLog.e("tmessages", "write raw error");
} }
} }
@ -132,7 +155,7 @@ public class SerializedData {
try { try {
out.write(b, offset, count); out.write(b, offset, count);
} catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "write raw error"); FileLog.e("tmessages", "write raw error");
} }
} }
@ -140,7 +163,7 @@ public class SerializedData {
try { try {
out.writeByte((byte)i); out.writeByte((byte)i);
} catch (Exception e) { } catch (Exception e) {
Log.e("tmessages", "write byte error"); FileLog.e("tmessages", "write byte error");
} }
} }
@ -148,7 +171,7 @@ public class SerializedData {
try { try {
out.writeByte(b); out.writeByte(b);
} catch (Exception e) { } catch (Exception e) {
Log.e("tmessages", "write byte error"); FileLog.e("tmessages", "write byte error");
} }
} }
@ -156,7 +179,7 @@ public class SerializedData {
try { try {
in.read(b); in.read(b);
} catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "read raw error"); FileLog.e("tmessages", "read raw error");
} }
} }
@ -183,7 +206,7 @@ public class SerializedData {
} }
return new String(b, "UTF-8"); return new String(b, "UTF-8");
} catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "read string error"); FileLog.e("tmessages", "read string error");
} }
return null; return null;
} }
@ -205,7 +228,7 @@ public class SerializedData {
} }
return b; return b;
} catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "read byte array error"); FileLog.e("tmessages", "read byte array error");
} }
return null; return null;
} }
@ -226,8 +249,8 @@ public class SerializedData {
out.write(0); out.write(0);
i++; i++;
} }
}catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "write byte array error"); FileLog.e("tmessages", "write byte array error");
} }
} }
@ -235,7 +258,7 @@ public class SerializedData {
try { try {
writeByteArray(s.getBytes("UTF-8")); writeByteArray(s.getBytes("UTF-8"));
} catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "write string error"); FileLog.e("tmessages", "write string error");
} }
} }
@ -256,15 +279,15 @@ public class SerializedData {
i++; i++;
} }
} catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "write byte array error"); FileLog.e("tmessages", "write byte array error");
} }
} }
public double readDouble(){ public double readDouble() {
try { try {
return Double.longBitsToDouble(readInt64()); return Double.longBitsToDouble(readInt64());
} catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "read double error"); FileLog.e("tmessages", "read double error");
} }
return 0; return 0;
} }
@ -273,7 +296,7 @@ public class SerializedData {
try { try {
writeInt64(Double.doubleToRawLongBits(d)); writeInt64(Double.doubleToRawLongBits(d));
} catch(Exception x) { } catch(Exception x) {
Log.e("tmessages", "write double error"); FileLog.e("tmessages", "write double error");
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -49,11 +49,11 @@ public class SmsListener extends BroadcastReceiver {
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,20 +8,16 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.util.Log;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import jawnae.pyronet.PyroClient; import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroSelector; import jawnae.pyronet.PyroSelector;
import jawnae.pyronet.events.PyroClientAdapter; import jawnae.pyronet.PyroClientAdapter;
public class TcpConnection extends PyroClientAdapter { public class TcpConnection extends PyroClientAdapter {
public enum TcpConnectionState { public enum TcpConnectionState {
@ -37,19 +33,23 @@ public class TcpConnection extends PyroClientAdapter {
public abstract void tcpConnectionConnected(TcpConnection connection); public abstract void tcpConnectionConnected(TcpConnection connection);
public abstract void tcpConnectionQuiackAckReceived(TcpConnection connection, int ack); public abstract void tcpConnectionQuiackAckReceived(TcpConnection connection, int ack);
public abstract void tcpConnectionReceivedData(TcpConnection connection, byte[] data); public abstract void tcpConnectionReceivedData(TcpConnection connection, byte[] data);
public abstract void tcpConnectionProgressChanged(TcpConnection connection, long messageId, int currentSize, int length);
} }
private static PyroSelector selector; private static PyroSelector selector;
private PyroClient client; private PyroClient client;
public TcpConnectionState connectionState; public TcpConnectionState connectionState;
private Queue<byte[]> packetsQueue;
public volatile int channelToken = 0; public volatile int channelToken = 0;
private String hostAddress; private String hostAddress;
private int hostPort; private int hostPort;
public int datacenterId; private int datacenterId;
private int failedConnectionCount; private int failedConnectionCount;
public TcpConnectionDelegate delegate; public TcpConnectionDelegate delegate;
private ByteBuffer restOfTheData; private ByteBuffer restOfTheData;
private long lastMessageId = 0;
private boolean hasSomeDataSinceLastConnect = false;
private int willRetryConnectCount = 5;
private boolean isNextPort = false;
public int transportRequestClass; public int transportRequestClass;
@ -57,14 +57,12 @@ public class TcpConnection extends PyroClientAdapter {
private Timer reconnectTimer; private Timer reconnectTimer;
public TcpConnection(String ip, int port) { public TcpConnection(int did) {
if (selector == null) { if (selector == null) {
selector = new PyroSelector(); selector = new PyroSelector();
selector.spawnNetworkThread("network thread"); selector.spawnNetworkThread("network thread");
} }
packetsQueue = new LinkedList<byte[]>(); datacenterId = did;
hostAddress = ip;
hostPort = port;
connectionState = TcpConnectionState.TcpConnectionStageIdle; connectionState = TcpConnectionState.TcpConnectionStageIdle;
} }
@ -73,74 +71,142 @@ public class TcpConnection extends PyroClientAdapter {
return nextChannelToken++; return nextChannelToken++;
} }
public int getDatacenterId() {
return datacenterId;
}
public void connect() { public void connect() {
selector.scheduleTask(new Runnable() { selector.scheduleTask(new Runnable() {
@Override @Override
public void run() { public void run() {
if (connectionState == TcpConnectionState.TcpConnectionStageConnected || connectionState == TcpConnectionState.TcpConnectionStageConnecting) { if ((connectionState == TcpConnectionState.TcpConnectionStageConnected || connectionState == TcpConnectionState.TcpConnectionStageConnecting) && client != null) {
return; return;
} }
connectionState = TcpConnectionState.TcpConnectionStageConnecting; connectionState = TcpConnectionState.TcpConnectionStageConnecting;
try { try {
if (ConnectionsManager.DEBUG_VERSION) { Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId);
Log.d("tmessages", String.format(this + " Connecting (%s:%d)", hostAddress, hostPort)); hostAddress = datacenter.getCurrentAddress();
} hostPort = datacenter.getCurrentPort();
FileLog.d("tmessages", String.format(TcpConnection.this + " Connecting (%s:%d)", hostAddress, hostPort));
firstPacket = true; firstPacket = true;
restOfTheData = null; restOfTheData = null;
hasSomeDataSinceLastConnect = false;
if (client != null) { if (client != null) {
client.removeListener(TcpConnection.this); client.removeListener(TcpConnection.this);
client.dropConnection(); client.dropConnection();
client = null;
} }
client = selector.connect(new InetSocketAddress(hostAddress, hostPort)); client = selector.connect(new InetSocketAddress(hostAddress, hostPort));
client.addListener(TcpConnection.this); client.addListener(TcpConnection.this);
client.setTimeout(35000); if (isNextPort) {
client.setTimeout(8000);
} else {
client.setTimeout(35000);
}
selector.wakeup(); selector.wakeup();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); try {
if (reconnectTimer != null) {
reconnectTimer.cancel();
reconnectTimer = null;
}
} catch (Exception e2) {
FileLog.e("tmessages", e2);
}
connectionState = TcpConnectionState.TcpConnectionStageReconnecting;
if (delegate != null) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
delegate.tcpConnectionClosed(TcpConnection.this);
}
});
}
failedConnectionCount++;
if (failedConnectionCount == 1) {
if (hasSomeDataSinceLastConnect) {
willRetryConnectCount = 5;
} else {
willRetryConnectCount = 1;
}
}
isNextPort = true;
if (failedConnectionCount > willRetryConnectCount) {
Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId);
datacenter.nextAddressOrPort();
failedConnectionCount = 0;
}
FileLog.e("tmessages", e);
FileLog.d("tmessages", "Reconnect " + hostAddress + ":" + hostPort + " " + TcpConnection.this);
try {
reconnectTimer = new Timer();
reconnectTimer.schedule(new TimerTask() {
@Override
public void run() {
selector.scheduleTask(new Runnable() {
@Override
public void run() {
try {
if (reconnectTimer != null) {
reconnectTimer.cancel();
reconnectTimer = null;
}
} catch (Exception e2) {
FileLog.e("tmessages", e2);
}
connect();
}
});
}
}, failedConnectionCount >= 3 ? 500 : 300, failedConnectionCount >= 3 ? 500 : 300);
} catch (Exception e3) {
FileLog.e("tmessages", e3);
}
} }
} }
}); });
} }
private void suspendConnectionInternal() {
if (reconnectTimer != null) {
reconnectTimer.cancel();
reconnectTimer = null;
}
if (connectionState == TcpConnectionState.TcpConnectionStageIdle || connectionState == TcpConnectionState.TcpConnectionStageSuspended) {
return;
}
FileLog.d("tmessages", "suspend connnection " + TcpConnection.this);
connectionState = TcpConnectionState.TcpConnectionStageSuspended;
if (client != null) {
client.removeListener(TcpConnection.this);
client.dropConnection();
client = null;
}
if (delegate != null) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
delegate.tcpConnectionClosed(TcpConnection.this);
}
});
}
firstPacket = true;
restOfTheData = null;
channelToken = 0;
}
public void suspendConnection(boolean task) { public void suspendConnection(boolean task) {
if (task) { if (task) {
selector.scheduleTask(new Runnable() { selector.scheduleTask(new Runnable() {
@Override @Override
public void run() { public void run() {
if (reconnectTimer != null) { suspendConnectionInternal();
reconnectTimer.cancel();
reconnectTimer = null;
}
if (connectionState == TcpConnectionState.TcpConnectionStageIdle || connectionState == TcpConnectionState.TcpConnectionStageSuspended) {
return;
}
if (ConnectionsManager.DEBUG_VERSION) {
Log.d("tmessages", "suspend connnection " + this);
}
connectionState = TcpConnectionState.TcpConnectionStageSuspended;
if (client != null) {
client.dropConnection();
client = null;
}
} }
}); });
} else { } else {
if (reconnectTimer != null) { suspendConnectionInternal();
reconnectTimer.cancel();
reconnectTimer = null;
}
if (connectionState == TcpConnectionState.TcpConnectionStageIdle || connectionState == TcpConnectionState.TcpConnectionStageSuspended) {
return;
}
if (ConnectionsManager.DEBUG_VERSION) {
Log.d("tmessages", "suspend connnection " + this);
}
connectionState = TcpConnectionState.TcpConnectionStageSuspended;
if (client != null) {
client.dropConnection();
client = null;
}
} }
} }
@ -160,10 +226,14 @@ public class TcpConnection extends PyroClientAdapter {
public void run() { public void run() {
if (connectionState == TcpConnectionState.TcpConnectionStageIdle || if (connectionState == TcpConnectionState.TcpConnectionStageIdle ||
connectionState == TcpConnectionState.TcpConnectionStageReconnecting || connectionState == TcpConnectionState.TcpConnectionStageReconnecting ||
connectionState == TcpConnectionState.TcpConnectionStageSuspended) { connectionState == TcpConnectionState.TcpConnectionStageSuspended || client == null) {
connect(); connect();
} }
if (client == null || client.isDisconnected()) {
return;
}
int packetLength = data.length / 4; int packetLength = data.length / 4;
SerializedData buffer = new SerializedData(); SerializedData buffer = new SerializedData();
@ -183,33 +253,22 @@ public class TcpConnection extends PyroClientAdapter {
final byte[] packet = buffer.toByteArray(); final byte[] packet = buffer.toByteArray();
if (client != null && !client.isDisconnected()) { ByteBuffer sendBuffer = ByteBuffer.allocate((firstPacket ? 1 : 0) + packet.length);
ByteBuffer sendBuffer = ByteBuffer.allocate((firstPacket ? 1 : 0) + packet.length); sendBuffer.rewind();
sendBuffer.rewind(); sendBuffer.order(ByteOrder.LITTLE_ENDIAN);
sendBuffer.order(ByteOrder.LITTLE_ENDIAN); if (firstPacket) {
if (firstPacket) { sendBuffer.put((byte)0xef);
sendBuffer.put((byte)0xef); firstPacket = false;
firstPacket = false;
}
sendBuffer.put(packet);
sendBuffer.rewind();
client.write(sendBuffer);
} else {
packetsQueue.add(packet);
} }
sendBuffer.put(packet);
sendBuffer.rewind();
client.write(sendBuffer);
} }
}); });
} }
private void readData(ByteBuffer buffer) throws Exception { private void readData(ByteBuffer buffer) throws Exception {
if (ConnectionsManager.DEBUG_VERSION) {
Log.d("tmessages", "received data = " + buffer.limit());
}
if (restOfTheData != null) { if (restOfTheData != null) {
if (ConnectionsManager.DEBUG_VERSION) {
Log.d("tmessages", "there is rest of data " + restOfTheData.limit());
}
ByteBuffer newBuffer = ByteBuffer.allocate(restOfTheData.limit() + buffer.limit()); ByteBuffer newBuffer = ByteBuffer.allocate(restOfTheData.limit() + buffer.limit());
newBuffer.put(restOfTheData); newBuffer.put(restOfTheData);
newBuffer.put(buffer); newBuffer.put(buffer);
@ -221,6 +280,13 @@ public class TcpConnection extends PyroClientAdapter {
buffer.rewind(); buffer.rewind();
while (buffer.hasRemaining()) { while (buffer.hasRemaining()) {
if (!hasSomeDataSinceLastConnect) {
Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId);
datacenter.storeCurrentAddressAndPortNum();
isNextPort = false;
client.setTimeout(35000);
}
hasSomeDataSinceLastConnect = true;
int currentPacketLength; int currentPacketLength;
buffer.mark(); buffer.mark();
@ -261,17 +327,38 @@ public class TcpConnection extends PyroClientAdapter {
currentPacketLength = (buffer.getInt() >> 8) * 4; currentPacketLength = (buffer.getInt() >> 8) * 4;
} }
if (currentPacketLength % 4 != 0 || currentPacketLength > 2 * 1024 * 1024) {
FileLog.e("tmessages", "Invalid packet length");
reconnect();
return;
}
if (currentPacketLength < buffer.remaining()) { if (currentPacketLength < buffer.remaining()) {
if (ConnectionsManager.DEBUG_VERSION) { FileLog.d("tmessages", TcpConnection.this + " Received message len " + currentPacketLength + " but packet larger " + buffer.remaining());
Log.d("tmessages", this + " Received message len " + currentPacketLength + " but packet larger " + buffer.remaining()); lastMessageId = 0;
}
} else if (currentPacketLength == buffer.remaining()) { } else if (currentPacketLength == buffer.remaining()) {
if (ConnectionsManager.DEBUG_VERSION) { FileLog.d("tmessages", TcpConnection.this + " Received message len " + currentPacketLength + " equal to packet size");
Log.d("tmessages", this + " Received message len " + currentPacketLength + " equal to packet size"); lastMessageId = 0;
}
} else { } else {
if (ConnectionsManager.DEBUG_VERSION) { FileLog.d("tmessages", TcpConnection.this + " Received packet size less(" + buffer.remaining() + ") then message size(" + currentPacketLength + ")");
Log.d("tmessages", this + " Received packet size less(" + buffer.remaining() + ") then message size(" + currentPacketLength + ")"); if (buffer.remaining() >= 152 && (transportRequestClass & RPCRequest.RPCRequestClassDownloadMedia) != 0) {
if (lastMessageId == 0) {
byte[] temp = new byte[152];
buffer.get(temp);
lastMessageId = ConnectionsManager.Instance.needsToDecodeMessageIdFromPartialData(TcpConnection.this, temp);
}
if (lastMessageId != -1 && lastMessageId != 0) {
if (delegate != null) {
final int arg2 = buffer.remaining();
final int arg3 = currentPacketLength;
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
delegate.tcpConnectionProgressChanged(TcpConnection.this, lastMessageId, arg2, arg3);
}
});
}
}
} }
buffer.reset(); buffer.reset();
restOfTheData = ByteBuffer.allocate(buffer.remaining()); restOfTheData = ByteBuffer.allocate(buffer.remaining());
@ -281,14 +368,6 @@ public class TcpConnection extends PyroClientAdapter {
return; return;
} }
if (currentPacketLength % 4 != 0 || currentPacketLength > 2 * 1024 * 1024) {
if (ConnectionsManager.DEBUG_VERSION) {
Log.e("tmessages", "Invalid packet length");
}
reconnect();
return;
}
final byte[] packetData = new byte[currentPacketLength]; final byte[] packetData = new byte[currentPacketLength];
buffer.get(packetData); buffer.get(packetData);
@ -303,21 +382,18 @@ public class TcpConnection extends PyroClientAdapter {
} }
} }
public void handleDisconnect(PyroClient client, IOException e) { public void handleDisconnect(PyroClient client, Exception e) {
if (reconnectTimer != null) { if (reconnectTimer != null) {
reconnectTimer.cancel(); reconnectTimer.cancel();
reconnectTimer = null; reconnectTimer = null;
} }
if (ConnectionsManager.DEBUG_VERSION) { if (e != null) {
if (e != null) { FileLog.d("tmessages", "Disconnected " + TcpConnection.this + " with error " + e);
Log.d("tmessages", "Disconnected " + this + " with error " + e); } else {
} else { FileLog.d("tmessages", "Disconnected " + TcpConnection.this);
Log.d("tmessages", "Disconnected " + this);
}
} }
firstPacket = true; firstPacket = true;
restOfTheData = null; restOfTheData = null;
packetsQueue.clear();
channelToken = 0; channelToken = 0;
if (connectionState != TcpConnectionState.TcpConnectionStageSuspended && connectionState != TcpConnectionState.TcpConnectionStageIdle) { if (connectionState != TcpConnectionState.TcpConnectionStageSuspended && connectionState != TcpConnectionState.TcpConnectionStageIdle) {
connectionState = TcpConnectionState.TcpConnectionStageIdle; connectionState = TcpConnectionState.TcpConnectionStageIdle;
@ -330,12 +406,23 @@ public class TcpConnection extends PyroClientAdapter {
} }
}); });
} }
if (connectionState == TcpConnectionState.TcpConnectionStageIdle && (!packetsQueue.isEmpty() || if (connectionState == TcpConnectionState.TcpConnectionStageIdle &&
(transportRequestClass & RPCRequest.RPCRequestClassGeneric) != 0 && (datacenterId == ConnectionsManager.Instance.currentDatacenterId || datacenterId == ConnectionsManager.Instance.movingToDatacenterId))) { ((transportRequestClass & RPCRequest.RPCRequestClassGeneric) != 0 && (datacenterId == ConnectionsManager.Instance.currentDatacenterId || datacenterId == ConnectionsManager.Instance.movingToDatacenterId))) {
failedConnectionCount++; failedConnectionCount++;
if (ConnectionsManager.DEBUG_VERSION) { if (failedConnectionCount == 1) {
Log.d("tmessages", "Reconnect " + hostAddress + ":" + hostPort + " " + this); if (hasSomeDataSinceLastConnect) {
willRetryConnectCount = 5;
} else {
willRetryConnectCount = 1;
}
} }
isNextPort = true;
if (failedConnectionCount > willRetryConnectCount) {
Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId);
datacenter.nextAddressOrPort();
failedConnectionCount = 0;
}
FileLog.d("tmessages", "Reconnect " + hostAddress + ":" + hostPort + " " + TcpConnection.this);
try { try {
reconnectTimer = new Timer(); reconnectTimer = new Timer();
reconnectTimer.schedule(new TimerTask() { reconnectTimer.schedule(new TimerTask() {
@ -350,29 +437,24 @@ public class TcpConnection extends PyroClientAdapter {
reconnectTimer = null; reconnectTimer = null;
} }
} catch (Exception e2) { } catch (Exception e2) {
e2.printStackTrace(); FileLog.e("tmessages", e2);
} }
connect(); connect();
} }
}); });
} }
}, failedConnectionCount > 10 ? 500 : 200, failedConnectionCount > 10 ? 500 : 200); }, failedConnectionCount > 3 ? 500 : 300, failedConnectionCount > 3 ? 500 : 300);
} catch (Exception e3) { } catch (Exception e3) {
e3.printStackTrace(); FileLog.e("tmessages", e3);
} }
} }
} }
@Override @Override
public void connectedClient(PyroClient client) { public void connectedClient(PyroClient client) {
//if (!ConnectionsManager.isNetworkOnline()) {
// return;
//}
connectionState = TcpConnectionState.TcpConnectionStageConnected; connectionState = TcpConnectionState.TcpConnectionStageConnected;
channelToken = generateChannelToken(); channelToken = generateChannelToken();
if (ConnectionsManager.DEBUG_VERSION) { FileLog.d("tmessages", String.format(TcpConnection.this + " Connected (%s:%d)", hostAddress, hostPort));
Log.d("tmessages", String.format(this + " Connected (%s:%d)", hostAddress, hostPort));
}
if (delegate != null) { if (delegate != null) {
Utilities.stageQueue.postRunnable(new Runnable() { Utilities.stageQueue.postRunnable(new Runnable() {
@Override @Override
@ -381,23 +463,11 @@ public class TcpConnection extends PyroClientAdapter {
} }
}); });
} }
while (packetsQueue.size() != 0) {
byte[] packet = packetsQueue.poll();
ByteBuffer sendBuffer = ByteBuffer.allocate((firstPacket ? 1 : 0) + packet.length);
sendBuffer.order(ByteOrder.LITTLE_ENDIAN);
if (firstPacket) {
sendBuffer.put((byte)0xef);
firstPacket = false;
}
sendBuffer.put(packet);
sendBuffer.rewind();
client.write(sendBuffer);
}
} }
@Override @Override
public void unconnectableClient(PyroClient client) { public void unconnectableClient(PyroClient client, Exception cause) {
handleDisconnect(client, null); handleDisconnect(client, cause);
} }
@Override @Override
@ -417,9 +487,7 @@ public class TcpConnection extends PyroClientAdapter {
failedConnectionCount = 0; failedConnectionCount = 0;
readData(data); readData(data);
} catch (Exception e) { } catch (Exception e) {
if (ConnectionsManager.DEBUG_VERSION) { FileLog.d("tmessages", "read data error");
Log.d("tmessages", "read data error");
}
reconnect(); reconnect();
} }
} }
@ -427,8 +495,6 @@ public class TcpConnection extends PyroClientAdapter {
@Override @Override
public void sentData(PyroClient client, int bytes) { public void sentData(PyroClient client, int bytes) {
failedConnectionCount = 0; failedConnectionCount = 0;
if (ConnectionsManager.DEBUG_VERSION) { FileLog.d("tmessages", TcpConnection.this + " bytes sent " + bytes);
Log.d("tmessages", this + " bytes sent " + bytes);
}
} }
} }

View File

@ -1,55 +0,0 @@
/*
* This is the source code of Telegram for Android v. 1.2.3.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013.
*/
package org.telegram.messenger;
import org.telegram.TL.TLObject;
import org.telegram.TL.TLRPC;
import java.util.ArrayList;
import java.util.HashMap;
public class UpdateDatacenterListAction extends Action {
public int datacenterId;
public UpdateDatacenterListAction(int id) {
datacenterId = id;
}
public void execute(HashMap params) {
TLRPC.TL_help_getConfig getConfig = new TLRPC.TL_help_getConfig();
ConnectionsManager.Instance.performRpc(getConfig, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (delegate == null) {
return;
}
if (error == null) {
TLRPC.TL_config config = (TLRPC.TL_config)response;
ArrayList<Datacenter> datacenters = new ArrayList<Datacenter>();
for (TLRPC.TL_dcOption datacenterDesc : config.dc_options) {
Datacenter datacenter = new Datacenter();
datacenter.datacenterId = datacenterDesc.id;
datacenter.authSessionId = (long)(MessagesController.random.nextDouble() * Long.MAX_VALUE);
datacenter.address = datacenterDesc.ip_address;
datacenter.port = datacenterDesc.port;
datacenters.add(datacenter);
}
HashMap<String, Object> result = new HashMap<String, Object>();
result.put("datacenters", datacenters);
delegate.ActionDidFinishExecution(UpdateDatacenterListAction.this, result);
} else {
delegate.ActionDidFailExecution(UpdateDatacenterListAction.this);
}
}
}, null, true, RPCRequest.RPCRequestClassEnableUnauthorized | RPCRequest.RPCRequestClassGeneric);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -10,13 +10,13 @@ package org.telegram.messenger;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.util.Base64;
import org.telegram.TL.TLClassStore; import org.telegram.TL.TLClassStore;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.ui.ApplicationLoader; import org.telegram.ui.ApplicationLoader;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
public class UserConfig { public class UserConfig {
public static TLRPC.User currentUser; public static TLRPC.User currentUser;
@ -24,8 +24,8 @@ public class UserConfig {
public static boolean clientActivated = false; public static boolean clientActivated = false;
public static boolean registeredForPush = false; public static boolean registeredForPush = false;
public static String pushString = ""; public static String pushString = "";
public static int lastSendMessageId = -1; public static int lastSendMessageId = -210000;
public static int lastLocalId = -1; public static int lastLocalId = -210000;
public static String contactsHash = ""; public static String contactsHash = "";
public static String importHash = ""; public static String importHash = "";
private final static Integer sync = 1; private final static Integer sync = 1;
@ -41,45 +41,53 @@ public class UserConfig {
} }
public static void saveConfig(boolean withFile) { public static void saveConfig(boolean withFile) {
saveConfig(withFile, null);
}
public static void saveConfig(boolean withFile, File oldFile) {
synchronized (sync) { synchronized (sync) {
SerializedData data = new SerializedData(); try {
if (currentUser != null) {
data.writeInt32(2);
currentUser.serializeToStream(data);
clientUserId = currentUser.id;
clientActivated = true;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit(); SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("registeredForPush", registeredForPush); if (currentUser != null) {
editor.putString("pushString", pushString); editor.putBoolean("registeredForPush", registeredForPush);
editor.putInt("lastSendMessageId", lastSendMessageId); editor.putString("pushString", pushString);
editor.putInt("lastLocalId", lastLocalId); editor.putInt("lastSendMessageId", lastSendMessageId);
editor.putString("contactsHash", contactsHash); editor.putInt("lastLocalId", lastLocalId);
editor.putString("importHash", importHash); editor.putString("contactsHash", contactsHash);
editor.putBoolean("saveIncomingPhotos", saveIncomingPhotos); editor.putString("importHash", importHash);
editor.commit(); editor.putBoolean("saveIncomingPhotos", saveIncomingPhotos);
} else { if (withFile) {
data.writeInt32(0); SerializedData data = new SerializedData();
} currentUser.serializeToStream(data);
if (withFile) { clientUserId = currentUser.id;
try { clientActivated = true;
File configFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "user.dat"); String userString = Base64.encodeToString(data.toByteArray(), Base64.DEFAULT);
if (!configFile.exists()) { editor.putString("user", userString);
configFile.createNewFile();
} }
FileOutputStream stream = new FileOutputStream(configFile); } else {
stream.write(data.toByteArray()); editor.putBoolean("registeredForPush", registeredForPush);
stream.close(); editor.putString("pushString", pushString);
} catch (Exception e) { editor.putInt("lastSendMessageId", lastSendMessageId);
e.printStackTrace(); editor.putInt("lastLocalId", lastLocalId);
editor.putString("contactsHash", contactsHash);
editor.putString("importHash", importHash);
editor.putBoolean("saveIncomingPhotos", saveIncomingPhotos);
editor.remove("user");
} }
editor.commit();
if (oldFile != null) {
oldFile.delete();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
} }
} }
} }
public static void loadConfig() { public static void loadConfig() {
synchronized (sync) { synchronized (sync) {
File configFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "user.dat"); final File configFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "user.dat");
if (configFile.exists()) { if (configFile.exists()) {
try { try {
SerializedData data = new SerializedData(configFile); SerializedData data = new SerializedData(configFile);
@ -113,6 +121,12 @@ public class UserConfig {
MessagesStorage.secretPBytes = data.readByteArray(); MessagesStorage.secretPBytes = data.readByteArray();
} }
MessagesStorage.secretG = data.readInt32(); MessagesStorage.secretG = data.readInt32();
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
saveConfig(true, configFile);
}
});
} else if (ver == 2) { } else if (ver == 2) {
int constructor = data.readInt32(); int constructor = data.readInt32();
currentUser = (TLRPC.TL_userSelf)TLClassStore.Instance().TLdeserialize(data, constructor); currentUser = (TLRPC.TL_userSelf)TLClassStore.Instance().TLdeserialize(data, constructor);
@ -122,14 +136,49 @@ public class UserConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE);
registeredForPush = preferences.getBoolean("registeredForPush", false); registeredForPush = preferences.getBoolean("registeredForPush", false);
pushString = preferences.getString("pushString", ""); pushString = preferences.getString("pushString", "");
lastSendMessageId = preferences.getInt("lastSendMessageId", -1); lastSendMessageId = preferences.getInt("lastSendMessageId", -210000);
lastLocalId = preferences.getInt("lastLocalId", -1); lastLocalId = preferences.getInt("lastLocalId", -210000);
contactsHash = preferences.getString("contactsHash", ""); contactsHash = preferences.getString("contactsHash", "");
importHash = preferences.getString("importHash", ""); importHash = preferences.getString("importHash", "");
saveIncomingPhotos = preferences.getBoolean("saveIncomingPhotos", false); saveIncomingPhotos = preferences.getBoolean("saveIncomingPhotos", false);
} }
if (lastLocalId > -210000) {
lastLocalId = -210000;
}
if (lastSendMessageId > -210000) {
lastSendMessageId = -210000;
}
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
saveConfig(true, configFile);
}
});
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
}
} else {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE);
registeredForPush = preferences.getBoolean("registeredForPush", false);
pushString = preferences.getString("pushString", "");
lastSendMessageId = preferences.getInt("lastSendMessageId", -210000);
lastLocalId = preferences.getInt("lastLocalId", -210000);
contactsHash = preferences.getString("contactsHash", "");
importHash = preferences.getString("importHash", "");
saveIncomingPhotos = preferences.getBoolean("saveIncomingPhotos", false);
String user = preferences.getString("user", null);
if (user != null) {
byte[] userBytes = Base64.decode(user, Base64.DEFAULT);
if (userBytes != null) {
SerializedData data = new SerializedData(userBytes);
currentUser = (TLRPC.TL_userSelf)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
clientUserId = currentUser.id;
clientActivated = true;
}
}
if (currentUser == null) {
clientActivated = false;
clientUserId = 0;
} }
} }
} }
@ -141,10 +190,11 @@ public class UserConfig {
currentUser = null; currentUser = null;
registeredForPush = false; registeredForPush = false;
contactsHash = ""; contactsHash = "";
lastLocalId = -1; lastLocalId = -210000;
importHash = ""; importHash = "";
lastSendMessageId = -1; lastSendMessageId = -210000;
saveIncomingPhotos = false; saveIncomingPhotos = false;
saveConfig(true); saveConfig(true);
MessagesController.Instance.deleteAllAppAccounts();
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -20,7 +20,6 @@ import android.text.Html;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.format.DateFormat; import android.text.format.DateFormat;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
@ -53,6 +52,7 @@ import javax.crypto.Cipher;
public class Utilities { public class Utilities {
public static Handler applicationHandler; public static Handler applicationHandler;
public static int statusBarHeight = 0;
private final static Integer lock = 1; private final static Integer lock = 1;
public static class TPFactorizedValue { public static class TPFactorizedValue {
@ -63,7 +63,7 @@ public class Utilities {
public static DispatchQueue globalQueue = new DispatchQueue("globalQueue"); public static DispatchQueue globalQueue = new DispatchQueue("globalQueue");
public static DispatchQueue cacheOutQueue = new DispatchQueue("cacheOutQueue"); public static DispatchQueue cacheOutQueue = new DispatchQueue("cacheOutQueue");
public static DispatchQueue imageLoadQueue = new DispatchQueue("imageLoadQueue"); public static DispatchQueue imageLoadQueue = new DispatchQueue("imageLoadQueue");
public static DispatchQueue fileUploadQueue = new DispatchQueue("imageLoadQueue"); public static DispatchQueue fileUploadQueue = new DispatchQueue("fileUploadQueue");
public native static long doPQNative(long _what); public native static long doPQNative(long _what);
public native static byte[] aesIgeEncryption(byte[] _what, byte[] _key, byte[] _iv, boolean encrypt, boolean changeIv); public native static byte[] aesIgeEncryption(byte[] _what, byte[] _key, byte[] _iv, boolean encrypt, boolean changeIv);
@ -101,7 +101,7 @@ public class Utilities {
return result; return result;
} else { } else {
Log.e("tmessages", String.format("**** Factorization failed for %d", what)); FileLog.e("tmessages", String.format("**** Factorization failed for %d", what));
TPFactorizedValue result = new TPFactorizedValue(); TPFactorizedValue result = new TPFactorizedValue();
result.p = 0; result.p = 0;
result.q = 0; result.q = 0;
@ -113,8 +113,8 @@ public class Utilities {
try { try {
MessageDigest md = MessageDigest.getInstance("SHA-1"); MessageDigest md = MessageDigest.getInstance("SHA-1");
return md.digest(convertme); return md.digest(convertme);
} catch (Throwable e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
return null; return null;
} }
@ -128,7 +128,7 @@ public class Utilities {
cipher.init(Cipher.ENCRYPT_MODE, publicKey); cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data); return cipher.doFinal(data);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
return null; return null;
} }
@ -219,7 +219,7 @@ public class Utilities {
SerializedData stream = new SerializedData(bytesOutput.toByteArray()); SerializedData stream = new SerializedData(bytesOutput.toByteArray());
return TLClassStore.Instance().TLdeserialize(stream, stream.readInt32(), parentObject); return TLClassStore.Instance().TLdeserialize(stream, stream.readInt32(), parentObject);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
return null; return null;
} }
@ -235,8 +235,7 @@ public class Utilities {
assetPath); assetPath);
cache.put(assetPath, t); cache.put(assetPath, t);
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "Could not get typeface '" + assetPath FileLog.e(TAG, "Could not get typeface '" + assetPath + "' because " + e.getMessage());
+ "' because " + e.getMessage());
return null; return null;
} }
} }
@ -258,8 +257,7 @@ public class Utilities {
if (view == null) { if (view == null) {
return false; return false;
} }
InputMethodManager inputManager = (InputMethodManager) view InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return inputManager.isActive(view); return inputManager.isActive(view);
} }
@ -267,10 +265,10 @@ public class Utilities {
if (view == null) { if (view == null) {
return; return;
} }
InputMethodManager imm = (InputMethodManager) view.getContext() InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
.getSystemService(Context.INPUT_METHOD_SERVICE); if (!imm.isActive()) {
if (!imm.isActive())
return; return;
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0); imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
} }
@ -279,18 +277,21 @@ public class Utilities {
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
progressDialog = new ProgressDialog(activity); if(!activity.isFinishing()) {
if (message != null) { progressDialog = new ProgressDialog(activity);
progressDialog.setMessage(message); if (message != null) {
progressDialog.setMessage(message);
}
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.show();
} }
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.show();
} }
}); });
} }
public static FastDateFormat formatterDay; public static FastDateFormat formatterDay;
public static FastDateFormat formatterWeek;
public static FastDateFormat formatterMonth; public static FastDateFormat formatterMonth;
public static FastDateFormat formatterYear; public static FastDateFormat formatterYear;
public static FastDateFormat formatterYearMax; public static FastDateFormat formatterYearMax;
@ -300,11 +301,21 @@ public class Utilities {
static { static {
Locale locale = Locale.getDefault(); Locale locale = Locale.getDefault();
String lang = locale.getLanguage(); String lang = locale.getLanguage();
formatterMonth = FastDateFormat.getInstance("dd MMM", locale); if (lang.equals("en")) {
formatterYear = FastDateFormat.getInstance("dd.MM.yy", locale); formatterMonth = FastDateFormat.getInstance("MMM dd", locale);
formatterYearMax = FastDateFormat.getInstance("dd.MM.yyyy", locale); formatterYear = FastDateFormat.getInstance("dd.MM.yy", locale);
chatDate = FastDateFormat.getInstance("d MMMM", locale); formatterYearMax = FastDateFormat.getInstance("dd.MM.yyyy", locale);
chatFullDate = FastDateFormat.getInstance("d MMMM yyyy", locale); chatDate = FastDateFormat.getInstance("MMMM d", locale);
chatFullDate = FastDateFormat.getInstance("MMMM d, yyyy", locale);
} else {
formatterMonth = FastDateFormat.getInstance("dd MMM", locale);
formatterYear = FastDateFormat.getInstance("dd.MM.yy", locale);
formatterYearMax = FastDateFormat.getInstance("dd.MM.yyyy", locale);
chatDate = FastDateFormat.getInstance("d MMMM", locale);
chatFullDate = FastDateFormat.getInstance("d MMMM yyyy", locale);
}
formatterWeek = FastDateFormat.getInstance("EEE", locale);
if (lang != null) { if (lang != null) {
if (DateFormat.is24HourFormat(ApplicationLoader.applicationContext)) { if (DateFormat.is24HourFormat(ApplicationLoader.applicationContext)) {
formatterDay = FastDateFormat.getInstance("HH:mm", locale); formatterDay = FastDateFormat.getInstance("HH:mm", locale);
@ -394,7 +405,7 @@ public class Utilities {
destination = new FileOutputStream(destFile).getChannel(); destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size()); destination.transferFrom(source, 0, source.size());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
result = false; result = false;
} finally { } finally {
if(source != null) { if(source != null) {
@ -418,20 +429,20 @@ public class Utilities {
public static int[] arrColors = {0xffee4928, 0xff41a903, 0xffe09602, 0xff0f94ed, 0xff8f3bf7, 0xfffc4380, 0xff00a1c4, 0xffeb7002}; public static int[] arrColors = {0xffee4928, 0xff41a903, 0xffe09602, 0xff0f94ed, 0xff8f3bf7, 0xfffc4380, 0xff00a1c4, 0xffeb7002};
public static int[] arrUsersAvatars = { public static int[] arrUsersAvatars = {
R.drawable.user_placeholder_red, R.drawable.user_red,
R.drawable.user_placeholder_green, R.drawable.user_green,
R.drawable.user_placeholder_yellow, R.drawable.user_yellow,
R.drawable.user_placeholder_blue, R.drawable.user_blue,
R.drawable.user_placeholder_purple, R.drawable.user_violet,
R.drawable.user_placeholder_pink, R.drawable.user_pink,
R.drawable.user_placeholder_cyan, R.drawable.user_aqua,
R.drawable.user_placeholder_orange}; R.drawable.user_orange};
public static int[] arrGroupsAvatars = { public static int[] arrGroupsAvatars = {
R.drawable.group_placeholder_green, R.drawable.group_green,
R.drawable.group_placeholder_red, R.drawable.group_red,
R.drawable.group_placeholder_blue, R.drawable.group_blue,
R.drawable.group_placeholder_yellow}; R.drawable.group_yellow};
public static int getColorIndex(int id) { public static int getColorIndex(int id) {
int[] arr; int[] arr;
@ -458,7 +469,7 @@ public class Utilities {
} }
return Math.abs(b) % arr.length; return Math.abs(b) % arr.length;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
return id % arr.length; return id % arr.length;
} }
@ -491,7 +502,7 @@ public class Utilities {
} }
return sb.toString(); return sb.toString();
} catch (java.security.NoSuchAlgorithmException e) { } catch (java.security.NoSuchAlgorithmException e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
return null; return null;
} }
@ -523,14 +534,13 @@ public class Utilities {
if (storageDir != null) { if (storageDir != null) {
if (! storageDir.mkdirs()) { if (! storageDir.mkdirs()) {
if (! storageDir.exists()){ if (! storageDir.exists()){
Log.d("tmessages", "failed to create directory"); FileLog.d("tmessages", "failed to create directory");
return null; return null;
} }
} }
} }
} else { } else {
Log.v("tmessages", "External storage is not mounted READ/WRITE."); FileLog.d("tmessages", "External storage is not mounted READ/WRITE.");
} }
return storageDir; return storageDir;
@ -543,7 +553,7 @@ public class Utilities {
String imageFileName = "IMG_" + timeStamp + "_"; String imageFileName = "IMG_" + timeStamp + "_";
return File.createTempFile(imageFileName, ".jpg", storageDir); return File.createTempFile(imageFileName, ".jpg", storageDir);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
return null; return null;
} }
@ -560,6 +570,7 @@ public class Utilities {
} else if (name2 != null && name2.length() != 0) { } else if (name2 != null && name2.length() != 0) {
wholeString += " " + name2; wholeString += " " + name2;
} }
wholeString = wholeString.trim();
String[] args = wholeString.split(" "); String[] args = wholeString.split(" ");
for (String arg : args) { for (String arg : args) {
@ -571,7 +582,7 @@ public class Utilities {
builder.append(" "); builder.append(" ");
} }
String query = str.substring(0, q.length()); String query = str.substring(0, q.length());
builder.append(Html.fromHtml("<font color=\"#1274c9\">" + query + "</font>")); builder.append(Html.fromHtml("<font color=\"#357aa8\">" + query + "</font>"));
str = str.substring(q.length()); str = str.substring(q.length());
builder.append(str); builder.append(str);
} else { } else {
@ -597,7 +608,7 @@ public class Utilities {
return new File(ApplicationLoader.applicationContext.getCacheDir(), fileName); return new File(ApplicationLoader.applicationContext.getCacheDir(), fileName);
*/ */
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
return null; return null;
} }
@ -611,4 +622,26 @@ public class Utilities {
} }
return result; return result;
} }
public static String stringForMessageListDate(long date) {
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date * 1000);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (year != dateYear) {
return 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));
} else if(dayDiff > -7 && dayDiff <= -1) {
return formatterWeek.format(new Date(date * 1000));
} else {
return formatterMonth.format(new Date(date * 1000));
}
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -43,59 +43,147 @@ public class MessageObject {
fromUser = MessagesController.Instance.users.get(message.from_id); fromUser = MessagesController.Instance.users.get(message.from_id);
} }
if (message.action instanceof TLRPC.TL_messageActionChatCreate) { if (message.action instanceof TLRPC.TL_messageActionChatCreate) {
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.ActionCreateGroup).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); if (message.from_id == UserConfig.clientUserId) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionCreateGroup).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou));
} else {
if (fromUser != null) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionCreateGroup).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
} else {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionCreateGroup).replace("un1", "");
}
}
} else if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) { } else if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) {
if (message.action.user_id == message.from_id) { if (message.action.user_id == message.from_id) {
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.ActionLeftUser).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); if (message.from_id == UserConfig.clientUserId) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionLeftUser).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou));
} else {
if (fromUser != null) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionLeftUser).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
} else {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionLeftUser).replace("un1", "");
}
}
} else { } else {
TLRPC.User who = users.get(message.action.user_id); TLRPC.User who = users.get(message.action.user_id);
String str = ApplicationLoader.applicationContext.getResources().getString(R.string.ActionKickUser); if (who == null) {
messageText = str.replace("un2", Utilities.formatName(who.first_name, who.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); MessagesController.Instance.users.get(message.action.user_id);
}
String str = ApplicationLoader.applicationContext.getString(R.string.ActionKickUser);
if (who != null && fromUser != null) {
if (message.from_id == UserConfig.clientUserId) {
messageText = str.replace("un2", Utilities.formatName(who.first_name, who.last_name)).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou));
} else if (message.action.user_id == UserConfig.clientUserId) {
messageText = str.replace("un2", ApplicationLoader.applicationContext.getString(R.string.FromYou)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
} else {
messageText = str.replace("un2", Utilities.formatName(who.first_name, who.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
}
} else {
messageText = str.replace("un2", "").replace("un1", "");
}
} }
} else if (message.action instanceof TLRPC.TL_messageActionChatAddUser) { } else if (message.action instanceof TLRPC.TL_messageActionChatAddUser) {
TLRPC.User whoUser = users.get(message.action.user_id); TLRPC.User whoUser = users.get(message.action.user_id);
String str = ApplicationLoader.applicationContext.getResources().getString(R.string.ActionAddUser); if (whoUser == null) {
messageText = str.replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); MessagesController.Instance.users.get(message.action.user_id);
}
String str = ApplicationLoader.applicationContext.getString(R.string.ActionAddUser);
if (whoUser != null && fromUser != null) {
if (message.from_id == UserConfig.clientUserId) {
messageText = str.replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou));
} else if (message.action.user_id == UserConfig.clientUserId) {
messageText = str.replace("un2", ApplicationLoader.applicationContext.getString(R.string.FromYou)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
} else {
messageText = str.replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
}
} else {
messageText = str.replace("un2", "").replace("un1", "");
}
} else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) { } else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) {
photoThumbs = new ArrayList<PhotoObject>(); photoThumbs = new ArrayList<PhotoObject>();
for (TLRPC.PhotoSize size : message.action.photo.sizes) { for (TLRPC.PhotoSize size : message.action.photo.sizes) {
photoThumbs.add(new PhotoObject(size)); photoThumbs.add(new PhotoObject(size));
} }
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.ActionChangedPhoto).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); if (message.from_id == UserConfig.clientUserId) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedPhoto).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou));
} else {
if (fromUser != null) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedPhoto).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
} else {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedPhoto).replace("un1", "");
}
}
} else if (message.action instanceof TLRPC.TL_messageActionChatEditTitle) { } else if (message.action instanceof TLRPC.TL_messageActionChatEditTitle) {
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.ActionChangedTitle).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)).replace("un2", message.action.title); if (message.from_id == UserConfig.clientUserId) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedTitle).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou)).replace("un2", message.action.title);
} else {
if (fromUser != null) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedTitle).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)).replace("un2", message.action.title);
} else {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedTitle).replace("un1", "").replace("un2", message.action.title);
}
}
} else if (message.action instanceof TLRPC.TL_messageActionChatDeletePhoto) { } else if (message.action instanceof TLRPC.TL_messageActionChatDeletePhoto) {
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.ActionRemovedPhoto).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); if (message.from_id == UserConfig.clientUserId) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionRemovedPhoto).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou));
} else {
if (fromUser != null) {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionRemovedPhoto).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
} else {
messageText = ApplicationLoader.applicationContext.getString(R.string.ActionRemovedPhoto).replace("un1", "");
}
}
} else if (message.action instanceof TLRPC.TL_messageActionTTLChange) { } else if (message.action instanceof TLRPC.TL_messageActionTTLChange) {
if (message.action.ttl != 0) { if (message.action.ttl != 0) {
String timeString; String timeString;
if (message.action.ttl == 2) { if (message.action.ttl == 2) {
timeString = ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetime2s); timeString = ApplicationLoader.applicationContext.getString(R.string.MessageLifetime2s);
} else if (message.action.ttl == 5) { } else if (message.action.ttl == 5) {
timeString = ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetime5s); timeString = ApplicationLoader.applicationContext.getString(R.string.MessageLifetime5s);
} else if (message.action.ttl == 60) { } else if (message.action.ttl == 60) {
timeString = ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetime1m); timeString = ApplicationLoader.applicationContext.getString(R.string.MessageLifetime1m);
} else if (message.action.ttl == 60 * 60) { } else if (message.action.ttl == 60 * 60) {
timeString = ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetime1h); timeString = ApplicationLoader.applicationContext.getString(R.string.MessageLifetime1h);
} else if (message.action.ttl == 60 * 60 * 24) { } else if (message.action.ttl == 60 * 60 * 24) {
timeString = ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetime1d); timeString = ApplicationLoader.applicationContext.getString(R.string.MessageLifetime1d);
} else if (message.action.ttl == 60 * 60 * 24 * 7) { } else if (message.action.ttl == 60 * 60 * 24 * 7) {
timeString = ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetime1w); timeString = ApplicationLoader.applicationContext.getString(R.string.MessageLifetime1w);
} else { } else {
timeString = String.format("%d", message.action.ttl); timeString = String.format("%d", message.action.ttl);
} }
if (message.from_id == UserConfig.clientUserId) { if (message.from_id == UserConfig.clientUserId) {
messageText = String.format(ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetimeChangedOutgoing), timeString); messageText = String.format(ApplicationLoader.applicationContext.getString(R.string.MessageLifetimeChangedOutgoing), timeString);
} else { } else {
messageText = String.format(ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetimeChanged), fromUser.first_name, timeString); if (fromUser != null) {
messageText = String.format(ApplicationLoader.applicationContext.getString(R.string.MessageLifetimeChanged), fromUser.first_name, timeString);
} else {
messageText = String.format(ApplicationLoader.applicationContext.getString(R.string.MessageLifetimeChanged), "", timeString);
}
} }
} else { } else {
if (message.from_id == UserConfig.clientUserId) { if (message.from_id == UserConfig.clientUserId) {
messageText = String.format(ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetimeRemoved), ApplicationLoader.applicationContext.getResources().getString(R.string.FromYou)); messageText = String.format(ApplicationLoader.applicationContext.getString(R.string.MessageLifetimeRemoved), ApplicationLoader.applicationContext.getString(R.string.FromYou));
} else { } else {
messageText = String.format(ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetimeRemoved), fromUser.first_name); if (fromUser != null) {
messageText = String.format(ApplicationLoader.applicationContext.getString(R.string.MessageLifetimeRemoved), fromUser.first_name);
} else {
messageText = String.format(ApplicationLoader.applicationContext.getString(R.string.MessageLifetimeRemoved), "");
}
} }
} }
} else if (message.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
messageText = ApplicationLoader.applicationContext.getString(R.string.NotificationUnrecognizedDevice, message.action.title, message.action.address);
} else if (message.action instanceof TLRPC.TL_messageActionUserJoined) {
if (fromUser != null) {
messageText = ApplicationLoader.applicationContext.getString(R.string.NotificationContactJoined, Utilities.formatName(fromUser.first_name, fromUser.last_name));
} else {
messageText = ApplicationLoader.applicationContext.getString(R.string.NotificationContactJoined, "");
}
} else if (message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
if (fromUser != null) {
messageText = ApplicationLoader.applicationContext.getString(R.string.NotificationContactNewPhoto, Utilities.formatName(fromUser.first_name, fromUser.last_name));
} else {
messageText = ApplicationLoader.applicationContext.getString(R.string.NotificationContactNewPhoto, "");
}
} }
} }
} else if (message.media != null && !(message.media instanceof TLRPC.TL_messageMediaEmpty)) { } else if (message.media != null && !(message.media instanceof TLRPC.TL_messageMediaEmpty)) {
@ -108,7 +196,7 @@ public class MessageObject {
imagePreview = obj.image; imagePreview = obj.image;
} }
} }
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.AttachPhoto); messageText = ApplicationLoader.applicationContext.getString(R.string.AttachPhoto);
} else if (message.media instanceof TLRPC.TL_messageMediaVideo) { } else if (message.media instanceof TLRPC.TL_messageMediaVideo) {
photoThumbs = new ArrayList<PhotoObject>(); photoThumbs = new ArrayList<PhotoObject>();
PhotoObject obj = new PhotoObject(message.media.video.thumb); PhotoObject obj = new PhotoObject(message.media.video.thumb);
@ -116,11 +204,13 @@ public class MessageObject {
if (imagePreview == null && obj.image != null) { if (imagePreview == null && obj.image != null) {
imagePreview = obj.image; imagePreview = obj.image;
} }
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.AttachVideo); messageText = ApplicationLoader.applicationContext.getString(R.string.AttachVideo);
} else if (message.media instanceof TLRPC.TL_messageMediaGeo) { } else if (message.media instanceof TLRPC.TL_messageMediaGeo) {
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.AttachLocation); messageText = ApplicationLoader.applicationContext.getString(R.string.AttachLocation);
} else if (message.media instanceof TLRPC.TL_messageMediaContact) { } else if (message.media instanceof TLRPC.TL_messageMediaContact) {
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.AttachContact); messageText = ApplicationLoader.applicationContext.getString(R.string.AttachContact);
} else if (message.media instanceof TLRPC.TL_messageMediaUnsupported) {
messageText = ApplicationLoader.applicationContext.getString(R.string.UnsuppotedMedia);
} }
} else { } else {
messageText = message.message; messageText = message.message;
@ -159,9 +249,15 @@ public class MessageObject {
} else { } else {
type = 13; type = 13;
} }
} else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaUnsupported) {
if (message.from_id == UserConfig.clientUserId) {
type = 0;
} else {
type = 1;
}
} }
} else if (message instanceof TLRPC.TL_messageService) { } else if (message instanceof TLRPC.TL_messageService) {
if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) { if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto || message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
type = 11; type = 11;
} else { } else {
type = 10; type = 10;

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -41,6 +41,9 @@ public class PhotoObject {
int closestHeight = 9999; int closestHeight = 9999;
PhotoObject closestObject = null; PhotoObject closestObject = null;
for (PhotoObject obj : arr) { for (PhotoObject obj : arr) {
if (obj == null || obj.photoOwner == null) {
continue;
}
int diffW = Math.abs(obj.photoOwner.w - width); int diffW = Math.abs(obj.photoOwner.w - width);
int diffH = Math.abs(obj.photoOwner.h - height); int diffH = Math.abs(obj.photoOwner.h - height);
if (closestObject == null || closestWidth > diffW && closestHeight > diffH || closestObject.photoOwner instanceof TLRPC.TL_photoCachedSize) { if (closestObject == null || closestWidth > diffW && closestHeight > diffH || closestObject.photoOwner instanceof TLRPC.TL_photoCachedSize) {

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -13,25 +13,22 @@ import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.PixelFormat;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.text.Html; import android.support.v7.app.ActionBar;
import android.view.Display; import android.support.v7.app.ActionBarActivity;
import android.view.Surface; import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.internal.app.ActionBarImpl;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
@ -47,22 +44,28 @@ import net.hockeyapp.android.UpdateManager;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
public class ApplicationActivity extends SherlockFragmentActivity implements NotificationCenter.NotificationCenterDelegate, MessagesActivity.MessagesActivityDelegate { public class ApplicationActivity extends ActionBarActivity implements NotificationCenter.NotificationCenterDelegate, MessagesActivity.MessagesActivityDelegate {
private View shadowView;
private boolean finished = false; private boolean finished = false;
private NotificationView notificationView; private NotificationView notificationView;
String photoPath = null; private String photoPath = null;
String videoPath = null; private String videoPath = null;
String sendingText = null; private String sendingText = null;
private int currentConnectionState; private int currentConnectionState;
private View statusView; private View statusView;
private View backStatusButton; private View backStatusButton;
private View statusBackground; private View statusBackground;
private TextView statusText; private TextView statusText;
private View containerView;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
Utilities.statusBarHeight = getResources().getDimensionPixelSize(resourceId);
}
NotificationCenter.Instance.postNotificationName(702, this); NotificationCenter.Instance.postNotificationName(702, this);
currentConnectionState = ConnectionsManager.Instance.connectionState; currentConnectionState = ConnectionsManager.Instance.connectionState;
for (BaseFragment fragment : ApplicationLoader.fragmentsStack) { for (BaseFragment fragment : ApplicationLoader.fragmentsStack) {
@ -71,12 +74,11 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
if (parent != null) { if (parent != null) {
parent.removeView(fragment.fragmentView); parent.removeView(fragment.fragmentView);
} }
fragment.parentActivity = null;
fragment.fragmentView = null; fragment.fragmentView = null;
} }
fragment.parentActivity = this;
} }
setContentView(R.layout.application_layout); setContentView(R.layout.application_layout);
shadowView = findViewById(R.id.shadow);
NotificationCenter.Instance.addObserver(this, 1234); NotificationCenter.Instance.addObserver(this, 1234);
NotificationCenter.Instance.addObserver(this, 658); NotificationCenter.Instance.addObserver(this, 658);
NotificationCenter.Instance.addObserver(this, 701); NotificationCenter.Instance.addObserver(this, 701);
@ -88,6 +90,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
statusView = getLayoutInflater().inflate(R.layout.updating_state_layout, null); statusView = getLayoutInflater().inflate(R.layout.updating_state_layout, null);
statusBackground = statusView.findViewById(R.id.back_button_background); statusBackground = statusView.findViewById(R.id.back_button_background);
backStatusButton = statusView.findViewById(R.id.back_button); backStatusButton = statusView.findViewById(R.id.back_button);
containerView = findViewById(R.id.container);
statusText = (TextView)statusView.findViewById(R.id.status_text); statusText = (TextView)statusView.findViewById(R.id.status_text);
statusBackground.setOnClickListener(new View.OnClickListener() { statusBackground.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -125,7 +128,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
if (fragment.onFragmentCreate()) { if (fragment.onFragmentCreate()) {
pushOpened = true; pushOpened = true;
ApplicationLoader.fragmentsStack.add(fragment); ApplicationLoader.fragmentsStack.add(fragment);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat_user_" + push_user_id).commitAllowingStateLoss(); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat" + Math.random()).commitAllowingStateLoss();
} }
} }
} else if (push_chat_id != 0) { } else if (push_chat_id != 0) {
@ -136,7 +139,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
if (fragment.onFragmentCreate()) { if (fragment.onFragmentCreate()) {
pushOpened = true; pushOpened = true;
ApplicationLoader.fragmentsStack.add(fragment); ApplicationLoader.fragmentsStack.add(fragment);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat_group_" + push_chat_id).commitAllowingStateLoss(); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat" + Math.random()).commitAllowingStateLoss();
} }
} else if (push_enc_id != 0) { } else if (push_enc_id != 0) {
ChatActivity fragment = new ChatActivity(); ChatActivity fragment = new ChatActivity();
@ -146,7 +149,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
if (fragment.onFragmentCreate()) { if (fragment.onFragmentCreate()) {
pushOpened = true; pushOpened = true;
ApplicationLoader.fragmentsStack.add(fragment); ApplicationLoader.fragmentsStack.add(fragment);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat_enc_" + push_enc_id).commitAllowingStateLoss(); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat" + Math.random()).commitAllowingStateLoss();
} }
} }
if (videoPath != null || photoPath != null || sendingText != null) { if (videoPath != null || photoPath != null || sendingText != null) {
@ -175,14 +178,16 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
} }
getWindow().setBackgroundDrawableResource(R.drawable.transparent); getWindow().setBackgroundDrawableResource(R.drawable.transparent);
getWindow().setFormat(PixelFormat.RGB_565);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void prepareForHideShowActionBar() { private void prepareForHideShowActionBar() {
try { try {
Class aClass = getSupportActionBar().getClass(); Class firstClass = getSupportActionBar().getClass();
if (aClass == ActionBarImpl.class) { Class aClass = firstClass.getSuperclass();
Method method = aClass.getDeclaredMethod("setShowHideAnimationEnabled", boolean.class); if (aClass == android.support.v7.app.ActionBar.class) {
Method method = firstClass.getDeclaredMethod("setShowHideAnimationEnabled", boolean.class);
method.invoke(getSupportActionBar(), false); method.invoke(getSupportActionBar(), false);
} else { } else {
Field field = aClass.getDeclaredField("mActionBar"); Field field = aClass.getDeclaredField("mActionBar");
@ -190,20 +195,18 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
Method method = field.get(getSupportActionBar()).getClass().getDeclaredMethod("setShowHideAnimationEnabled", boolean.class); Method method = field.get(getSupportActionBar()).getClass().getDeclaredMethod("setShowHideAnimationEnabled", boolean.class);
method.invoke(field.get(getSupportActionBar()), false); method.invoke(field.get(getSupportActionBar()), false);
} }
} catch (Exception exception) { } catch (Exception e) {
exception.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
public void showActionBar() { public void showActionBar() {
prepareForHideShowActionBar(); prepareForHideShowActionBar();
shadowView.setVisibility(View.VISIBLE);
getSupportActionBar().show(); getSupportActionBar().show();
} }
public void hideActionBar() { public void hideActionBar() {
prepareForHideShowActionBar(); prepareForHideShowActionBar();
shadowView.setVisibility(View.INVISIBLE);
getSupportActionBar().hide(); getSupportActionBar().hide();
} }
@ -241,7 +244,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
fragment.setArguments(bundle); fragment.setArguments(bundle);
if (fragment.onFragmentCreate()) { if (fragment.onFragmentCreate()) {
ApplicationLoader.fragmentsStack.add(fragment); ApplicationLoader.fragmentsStack.add(fragment);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat_user_" + push_user_id).commitAllowingStateLoss(); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat" + Math.random()).commitAllowingStateLoss();
} }
} }
} else if (push_chat_id != 0) { } else if (push_chat_id != 0) {
@ -251,7 +254,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
fragment.setArguments(bundle); fragment.setArguments(bundle);
if (fragment.onFragmentCreate()) { if (fragment.onFragmentCreate()) {
ApplicationLoader.fragmentsStack.add(fragment); ApplicationLoader.fragmentsStack.add(fragment);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat_group_" + push_chat_id).commitAllowingStateLoss(); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat" + Math.random()).commitAllowingStateLoss();
} }
} else if (push_enc_id != 0) { } else if (push_enc_id != 0) {
ChatActivity fragment = new ChatActivity(); ChatActivity fragment = new ChatActivity();
@ -260,7 +263,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
fragment.setArguments(bundle); fragment.setArguments(bundle);
if (fragment.onFragmentCreate()) { if (fragment.onFragmentCreate()) {
ApplicationLoader.fragmentsStack.add(fragment); ApplicationLoader.fragmentsStack.add(fragment);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat_enc_" + push_enc_id).commitAllowingStateLoss(); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat" + Math.random()).commitAllowingStateLoss();
} }
} }
if (open_settings != 0) { if (open_settings != 0) {
@ -284,13 +287,13 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
bundle.putInt("user_id", lower_part); bundle.putInt("user_id", lower_part);
fragment.setArguments(bundle); fragment.setArguments(bundle);
fragment.scrollToTopOnResume = true; fragment.scrollToTopOnResume = true;
presentFragment(fragment, "chat_user_" + lower_part, true, false); presentFragment(fragment, "chat" + Math.random(), true, false);
} else if (lower_part < 0) { } else if (lower_part < 0) {
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
bundle.putInt("chat_id", -lower_part); bundle.putInt("chat_id", -lower_part);
fragment.setArguments(bundle); fragment.setArguments(bundle);
fragment.scrollToTopOnResume = true; fragment.scrollToTopOnResume = true;
presentFragment(fragment, "chat_group_" + -lower_part, true, false); presentFragment(fragment, "chat" + Math.random(), true, false);
} }
} else { } else {
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
@ -298,7 +301,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
bundle.putInt("enc_id", chat_id); bundle.putInt("enc_id", chat_id);
fragment.setArguments(bundle); fragment.setArguments(bundle);
fragment.scrollToTopOnResume = true; fragment.scrollToTopOnResume = true;
presentFragment(fragment, "chat_enc_" + chat_id, true, false); presentFragment(fragment, "chat" + Math.random(), true, false);
} }
if (photoPath != null) { if (photoPath != null) {
fragment.processSendingPhoto(photoPath); fragment.processSendingPhoto(photoPath);
@ -318,7 +321,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
} }
private void checkForUpdates() { private void checkForUpdates() {
if (ConnectionsManager.DEBUG_VERSION) { if (FileLog.DEBUG_VERSION) {
UpdateManager.register(this, "your-hockeyapp-api-key-here"); UpdateManager.register(this, "your-hockeyapp-api-key-here");
} }
} }
@ -347,14 +350,14 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
fixLayout(); fixLayout();
checkForCrashes(); checkForCrashes();
checkForUpdates(); checkForUpdates();
ApplicationLoader.lastPauseTime = 0; ApplicationLoader.resetLastPauseTime();
invalidateOptionsMenu(); supportInvalidateOptionsMenu();
updateActionBar(); updateActionBar();
try { try {
NotificationManager mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(1); mNotificationManager.cancel(1);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
@ -383,14 +386,13 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
} }
private void fixLayout() { private void fixLayout() {
if (shadowView != null) { if (containerView != null) {
ViewTreeObserver obs = shadowView.getViewTreeObserver(); ViewTreeObserver obs = containerView.getViewTreeObserver();
obs.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { obs.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override @Override
public void onGlobalLayout() { public void onGlobalLayout() {
WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE); WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = manager.getDefaultDisplay(); int rotation = manager.getDefaultDisplay().getRotation();
int rotation = display.getRotation();
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
int height; int height;
@ -408,13 +410,10 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
notificationView.applyOrientationPaddings(rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90, density, height); notificationView.applyOrientationPaddings(rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90, density, height);
} }
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) shadowView.getLayoutParams();
params.setMargins(0, height, 0, 0);
shadowView.setLayoutParams(params);
if (Build.VERSION.SDK_INT < 16) { if (Build.VERSION.SDK_INT < 16) {
shadowView.getViewTreeObserver().removeGlobalOnLayoutListener(this); containerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else { } else {
shadowView.getViewTreeObserver().removeOnGlobalLayoutListener(this); containerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} }
} }
}); });
@ -459,7 +458,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
lastFragment.willBeHidden(); lastFragment.willBeHidden();
} }
ApplicationLoader.fragmentsStack.add(fragment); ApplicationLoader.fragmentsStack.add(fragment);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat_user_" + push_user_id).commitAllowingStateLoss(); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat" + Math.random()).commitAllowingStateLoss();
} }
} else if (push_chat_id != 0) { } else if (push_chat_id != 0) {
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
@ -473,7 +472,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
lastFragment.willBeHidden(); lastFragment.willBeHidden();
} }
ApplicationLoader.fragmentsStack.add(fragment); ApplicationLoader.fragmentsStack.add(fragment);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat_group_" + push_chat_id).commitAllowingStateLoss(); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat" + Math.random()).commitAllowingStateLoss();
} }
} else if (push_enc_id != 0) { } else if (push_enc_id != 0) {
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
@ -487,7 +486,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
lastFragment.willBeHidden(); lastFragment.willBeHidden();
} }
ApplicationLoader.fragmentsStack.add(fragment); ApplicationLoader.fragmentsStack.add(fragment);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat_enc_" + push_enc_id).commitAllowingStateLoss(); getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "chat" + Math.random()).commitAllowingStateLoss();
} }
} }
} else if (id == 701) { } else if (id == 701) {
@ -502,12 +501,42 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
} else if (id == 703) { } else if (id == 703) {
int state = (Integer)args[0]; int state = (Integer)args[0];
if (currentConnectionState != state) { if (currentConnectionState != state) {
FileLog.e("tmessages", "switch to state " + state);
currentConnectionState = state; currentConnectionState = state;
updateActionBar(); updateActionBar();
} }
} }
} }
public void fixBackButton() {
if(android.os.Build.VERSION.SDK_INT == 19) {
//workaround for back button dissapear
try {
Class firstClass = getSupportActionBar().getClass();
Class aClass = firstClass.getSuperclass();
if (aClass == android.support.v7.app.ActionBar.class) {
} else {
Field field = aClass.getDeclaredField("mActionBar");
field.setAccessible(true);
android.app.ActionBar bar = (android.app.ActionBar)field.get(getSupportActionBar());
field = bar.getClass().getDeclaredField("mActionView");
field.setAccessible(true);
View v = (View)field.get(bar);
aClass = v.getClass();
field = aClass.getDeclaredField("mHomeLayout");
field.setAccessible(true);
v = (View)field.get(v);
v.setVisibility(View.VISIBLE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void updateActionBar() { public void updateActionBar() {
ActionBar actionBar = getSupportActionBar(); ActionBar actionBar = getSupportActionBar();
if (actionBar == null) { if (actionBar == null) {
@ -540,15 +569,32 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
} }
if (currentConnectionState == 1) { if (currentConnectionState == 1) {
statusText.setText(Html.fromHtml("<font color='#006fc8'>" + getString(R.string.WaitingForNetwork) + "</font>")); statusText.setText(getString(R.string.WaitingForNetwork));
} else if (currentConnectionState == 2) { } else if (currentConnectionState == 2) {
statusText.setText(Html.fromHtml("<font color='#006fc8'>" + getString(R.string.Connecting) + "</font>")); statusText.setText(getString(R.string.Connecting));
} else if (currentConnectionState == 3) { } else if (currentConnectionState == 3) {
statusText.setText(Html.fromHtml("<font color='#006fc8'>" + getString(R.string.Updating) + "</font>")); statusText.setText(getString(R.string.Updating));
} }
if (actionBar.getCustomView() != statusView) { if (actionBar.getCustomView() != statusView) {
actionBar.setCustomView(statusView); actionBar.setCustomView(statusView);
} }
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
try {
if (statusView.getLayoutParams() instanceof android.support.v7.app.ActionBar.LayoutParams) {
android.support.v7.app.ActionBar.LayoutParams statusParams = (android.support.v7.app.ActionBar.LayoutParams)statusView.getLayoutParams();
statusText.measure(View.MeasureSpec.makeMeasureSpec(800, View.MeasureSpec.AT_MOST), 100);
statusParams.width = (int)(statusText.getMeasuredWidth() + 54 * density);
statusView.setLayoutParams(statusParams);
} else if (statusView.getLayoutParams() instanceof android.app.ActionBar.LayoutParams) {
android.app.ActionBar.LayoutParams statusParams = (android.app.ActionBar.LayoutParams)statusView.getLayoutParams();
statusText.measure(View.MeasureSpec.makeMeasureSpec(800, View.MeasureSpec.AT_MOST), 100);
statusParams.width = (int)(statusText.getMeasuredWidth() + 54 * density);
statusView.setLayoutParams(statusParams);
}
} catch (Exception e) {
e.printStackTrace();
}
} }
} }
} }
@ -646,4 +692,13 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
} }
} }
} }
@Override
protected void onSaveInstanceState(Bundle outState) {
try {
super.onSaveInstanceState(outState);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -15,7 +15,6 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.util.Log;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.ConnectionResult;
@ -25,6 +24,7 @@ import com.google.android.gms.gcm.GoogleCloudMessaging;
import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
@ -62,7 +62,7 @@ public class ApplicationLoader extends Application {
java.lang.System.setProperty("java.net.preferIPv6Addresses", "false"); java.lang.System.setProperty("java.net.preferIPv6Addresses", "false");
applicationContext = getApplicationContext(); applicationContext = getApplicationContext();
Utilities.getTypeface("fonts/rlight.ttf"); Utilities.getTypeface("fonts/rmedium.ttf");
UserConfig.loadConfig(); UserConfig.loadConfig();
SharedPreferences preferences = getSharedPreferences("Notifications", MODE_PRIVATE); SharedPreferences preferences = getSharedPreferences("Notifications", MODE_PRIVATE);
if (UserConfig.currentUser != null) { if (UserConfig.currentUser != null) {
@ -101,7 +101,7 @@ public class ApplicationLoader extends Application {
menuKeyField.setBoolean(config, false); menuKeyField.setBoolean(config, false);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
if (checkPlayServices()) { if (checkPlayServices()) {
@ -114,15 +114,18 @@ public class ApplicationLoader extends Application {
sendRegistrationIdToBackend(false); sendRegistrationIdToBackend(false);
} }
} else { } else {
Log.i("tmessages", "No valid Google Play Services APK found."); FileLog.d("tmessages", "No valid Google Play Services APK found.");
} }
PhoneFormat format = PhoneFormat.Instance; PhoneFormat format = PhoneFormat.Instance;
lastPauseTime = System.currentTimeMillis() - 5000; lastPauseTime = System.currentTimeMillis();
if (ConnectionsManager.DEBUG_VERSION) { FileLog.e("tmessages", "start application with time " + lastPauseTime);
Log.e("tmessages", "start application with time " + lastPauseTime); }
}
public static void resetLastPauseTime() {
lastPauseTime = 0;
ConnectionsManager.Instance.applicationMovedToForeground();
} }
private boolean checkPlayServices() { private boolean checkPlayServices() {
@ -143,13 +146,13 @@ public class ApplicationLoader extends Application {
final SharedPreferences prefs = getGCMPreferences(context); final SharedPreferences prefs = getGCMPreferences(context);
String registrationId = prefs.getString(PROPERTY_REG_ID, ""); String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.length() == 0) { if (registrationId.length() == 0) {
Log.i("tmessages", "Registration not found."); FileLog.d("tmessages", "Registration not found.");
return ""; return "";
} }
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE); int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context); int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) { if (registeredVersion != currentVersion) {
Log.i("tmessages", "App version changed."); FileLog.d("tmessages", "App version changed.");
return ""; return "";
} }
return registrationId; return registrationId;
@ -172,17 +175,29 @@ public class ApplicationLoader extends Application {
AsyncTask<String, String, Boolean> task = new AsyncTask<String, String, Boolean>() { AsyncTask<String, String, Boolean> task = new AsyncTask<String, String, Boolean>() {
@Override @Override
protected Boolean doInBackground(String... objects) { protected Boolean doInBackground(String... objects) {
String msg; if (gcm == null) {
try { gcm = GoogleCloudMessaging.getInstance(applicationContext);
if (gcm == null) { }
gcm = GoogleCloudMessaging.getInstance(applicationContext); int count = 0;
while (count < 1000) {
try {
count++;
regid = gcm.register(SENDER_ID);
sendRegistrationIdToBackend(true);
storeRegistrationId(applicationContext, regid);
return true;
} catch (IOException e) {
FileLog.e("tmessages", e);
}
try {
if (count % 20 == 0) {
Thread.sleep(60000 * 30);
} else {
Thread.sleep(5000);
}
} catch (InterruptedException e) {
FileLog.e("tmessages", e);
} }
regid = gcm.register(SENDER_ID);
sendRegistrationIdToBackend(true);
storeRegistrationId(applicationContext, regid);
return true;
} catch (IOException ex) {
ex.printStackTrace();
} }
return false; return false;
} }
@ -196,7 +211,12 @@ public class ApplicationLoader extends Application {
UserConfig.pushString = regid; UserConfig.pushString = regid;
UserConfig.registeredForPush = !isNew; UserConfig.registeredForPush = !isNew;
UserConfig.saveConfig(false); UserConfig.saveConfig(false);
MessagesController.Instance.registerForPush(regid); Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
MessagesController.Instance.registerForPush(regid);
}
});
} }
}); });
} }
@ -204,7 +224,7 @@ public class ApplicationLoader extends Application {
private void storeRegistrationId(Context context, String regId) { private void storeRegistrationId(Context context, String regId) {
final SharedPreferences prefs = getGCMPreferences(context); final SharedPreferences prefs = getGCMPreferences(context);
int appVersion = getAppVersion(context); int appVersion = getAppVersion(context);
Log.i("tmessages", "Saving regId on app version " + appVersion); FileLog.e("tmessages", "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit(); SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regId); editor.putString(PROPERTY_REG_ID, regId);
editor.putInt(PROPERTY_APP_VERSION, appVersion); editor.putInt(PROPERTY_APP_VERSION, appVersion);

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -20,14 +20,15 @@ import android.media.RingtoneManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.support.v4.internal.view.SupportMenuItem;
import android.support.v7.app.ActionBar;
import android.text.Html; import android.text.Html;
import android.view.Display;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Surface; import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.ImageButton; import android.widget.ImageButton;
@ -35,16 +36,12 @@ import android.widget.ImageView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.ui.Views.AvatarUpdater; import org.telegram.ui.Views.AvatarUpdater;
@ -83,7 +80,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
MessagesController.Instance.getMediaCount(-chat_id, classGuid, true); MessagesController.Instance.getMediaCount(-chat_id, classGuid, true);
avatarUpdater.delegate = new AvatarUpdater.AvatarUpdaterDelegate() { avatarUpdater.delegate = new AvatarUpdater.AvatarUpdaterDelegate() {
@Override @Override
public void didUploadedPhoto(TLRPC.TL_inputFile file, TLRPC.PhotoSize small, TLRPC.PhotoSize big) { public void didUploadedPhoto(TLRPC.InputFile file, TLRPC.PhotoSize small, TLRPC.PhotoSize big) {
if (chat_id != 0) { if (chat_id != 0) {
MessagesController.Instance.changeChatAvatar(chat_id, file); MessagesController.Instance.changeChatAvatar(chat_id, file);
} }
@ -163,45 +160,34 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
editor.putBoolean(key, !value); editor.putBoolean(key, !value);
editor.commit(); editor.commit();
listView.invalidateViews(); listView.invalidateViews();
TLRPC.TL_account_updateNotifySettings req = new TLRPC.TL_account_updateNotifySettings();
req.settings = new TLRPC.TL_inputPeerNotifySettings();
req.settings.sound = "";
req.peer = new TLRPC.TL_inputNotifyPeer();
((TLRPC.TL_inputNotifyPeer)req.peer).peer = new TLRPC.TL_inputPeerChat();
((TLRPC.TL_inputNotifyPeer)req.peer).peer.chat_id = chat_id;
req.settings.show_previews = true;
req.settings.events_mask = 1;
if (value) {
req.settings.mute_until = (int)(System.currentTimeMillis() / 1000) + 10 * 365 * 24 * 60 * 60;
} else {
req.settings.mute_until = 0;
}
ConnectionsManager.Instance.performRpc(req, null, null, true, RPCRequest.RPCRequestClassGeneric);
} else if (i == 3) { } else if (i == 3) {
Intent tmpIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); try {
tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); Intent tmpIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false); tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
SharedPreferences preferences = parentActivity.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);
Uri currentSound = null; SharedPreferences preferences = parentActivity.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
Uri currentSound = null;
String defaultPath = null; String defaultPath = null;
Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI; Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI;
if (defaultUri != null) { if (defaultUri != null) {
defaultPath = defaultUri.getPath(); defaultPath = defaultUri.getPath();
}
String path = preferences.getString("sound_chat_path_" + chat_id, defaultPath);
if (path != null && !path.equals("NoSound")) {
if (path.equals(defaultPath)) {
currentSound = defaultUri;
} else {
currentSound = Uri.parse(path);
} }
}
tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentSound); String path = preferences.getString("sound_chat_path_" + chat_id, defaultPath);
startActivityForResult(tmpIntent, 15); if (path != null && !path.equals("NoSound")) {
if (path.equals(defaultPath)) {
currentSound = defaultUri;
} else {
currentSound = Uri.parse(path);
}
}
tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentSound);
startActivityForResult(tmpIntent, 15);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
} else if (i == 5) { } else if (i == 5) {
MediaActivity fragment = new MediaActivity(); MediaActivity fragment = new MediaActivity();
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
@ -330,10 +316,10 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
actionBar.setDisplayUseLogoEnabled(false); actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayShowCustomEnabled(false); actionBar.setDisplayShowCustomEnabled(false);
actionBar.setCustomView(null); actionBar.setCustomView(null);
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.GroupInfo) + "</font>")); actionBar.setTitle(getStringEntry(R.string.GroupInfo));
actionBar.setSubtitle(null); actionBar.setSubtitle(null);
TextView title = (TextView)parentActivity.findViewById(R.id.abs__action_bar_title); TextView title = (TextView)parentActivity.findViewById(R.id.action_bar_title);
if (title == null) { if (title == null) {
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android"); final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
title = (TextView)parentActivity.findViewById(subtitleId); title = (TextView)parentActivity.findViewById(subtitleId);
@ -342,12 +328,13 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
title.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); title.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
title.setCompoundDrawablePadding(0); title.setCompoundDrawablePadding(0);
} }
((ApplicationActivity)parentActivity).fixBackButton();
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (getSherlockActivity() == null) { if (getActivity() == null) {
return; return;
} }
if (listViewAdapter != null) { if (listViewAdapter != null) {
@ -355,44 +342,6 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
} }
((ApplicationActivity)parentActivity).showActionBar(); ((ApplicationActivity)parentActivity).showActionBar();
((ApplicationActivity)parentActivity).updateActionBar(); ((ApplicationActivity)parentActivity).updateActionBar();
fixLayout();
}
@Override
public void onConfigurationChanged(android.content.res.Configuration newConfig) {
super.onConfigurationChanged(newConfig);
fixLayout();
}
private void fixLayout() {
if (listView != null) {
ViewTreeObserver obs = listView.getViewTreeObserver();
obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
WindowManager manager = (WindowManager)parentActivity.getSystemService(Activity.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int rotation = display.getRotation();
int height;
int currentActionBarHeight = parentActivity.getSupportActionBar().getHeight();
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (currentActionBarHeight != 48 * density && currentActionBarHeight != 40 * density) {
height = currentActionBarHeight;
} else {
height = (int)(48.0f * density);
if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) {
height = (int)(40.0f * density);
}
}
listView.setPadding(listView.getPaddingLeft(), height, listView.getPaddingRight(), listView.getPaddingBottom());
listView.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
} }
@Override @Override
@ -402,9 +351,6 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
case android.R.id.home: case android.R.id.home:
finishFragment(); finishFragment();
break; break;
case R.id.block_user:
openAddMenu();
break;
} }
return true; return true;
} }
@ -466,7 +412,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
if (action == 0) { if (action == 0) {
TLRPC.Chat chat = MessagesController.Instance.chats.get(chat_id); TLRPC.Chat chat = MessagesController.Instance.chats.get(chat_id);
if (chat.photo != null && chat.photo.photo_big != null) { if (chat.photo != null && chat.photo.photo_big != null) {
NotificationCenter.Instance.addToMemCache(3, chat.photo.photo_big); NotificationCenter.Instance.addToMemCache(53, chat.photo.photo_big);
Intent intent = new Intent(parentActivity, GalleryImageViewer.class); Intent intent = new Intent(parentActivity, GalleryImageViewer.class);
startActivity(intent); startActivity(intent);
} }
@ -506,15 +452,23 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
} else { } else {
NotificationCenter.Instance.removeObserver(this, MessagesController.closeChats); NotificationCenter.Instance.removeObserver(this, MessagesController.closeChats);
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
MessagesController.Instance.deleteDialog(-chat_id, 0, false);
MessagesController.Instance.deleteUserFromChat(chat_id, UserConfig.clientUserId, info); MessagesController.Instance.deleteUserFromChat(chat_id, UserConfig.clientUserId, info);
MessagesController.Instance.deleteDialog(-chat_id, 0, false);
finishFragment(); finishFragment();
} }
} }
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.settings_block_users_bar_menu, menu); inflater.inflate(R.menu.group_profile_menu, menu);
SupportMenuItem doneItem = (SupportMenuItem)menu.findItem(R.id.block_user);
TextView doneTextView = (TextView)doneItem.getActionView().findViewById(R.id.done_button);
doneTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openAddMenu();
}
});
} }
private class ListAdapter extends BaseAdapter { private class ListAdapter extends BaseAdapter {
@ -571,9 +525,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
if (view == null) { if (view == null) {
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.chat_profile_avatar_layout, viewGroup, false); view = li.inflate(R.layout.chat_profile_avatar_layout, viewGroup, false);
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
onlineText = (TextView)view.findViewById(R.id.settings_online); onlineText = (TextView)view.findViewById(R.id.settings_online);
onlineText.setTypeface(typeface);
ImageButton button = (ImageButton)view.findViewById(R.id.settings_edit_name); ImageButton button = (ImageButton)view.findViewById(R.id.settings_edit_name);
button.setOnClickListener(new View.OnClickListener() { button.setOnClickListener(new View.OnClickListener() {
@ -636,11 +588,13 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
} }
avatarImage = (BackupImageView)view.findViewById(R.id.settings_avatar_image); avatarImage = (BackupImageView)view.findViewById(R.id.settings_avatar_image);
TextView textView = (TextView)view.findViewById(R.id.settings_name); TextView textView = (TextView)view.findViewById(R.id.settings_name);
Typeface typeface = Utilities.getTypeface("fonts/rmedium.ttf");
textView.setTypeface(typeface);
textView.setText(chat.title); textView.setText(chat.title);
if (chat.participants_count != 0 && onlineCount > 0) { if (chat.participants_count != 0 && onlineCount > 0) {
onlineText.setText(Html.fromHtml(String.format("%d %s, <font color='#006fc8'>%d %s</font>", chat.participants_count, getStringEntry(R.string.Members), onlineCount, getStringEntry(R.string.Online)))); onlineText.setText(Html.fromHtml(String.format("%d %s, <font color='#357aa8'>%d %s</font>", chat.participants_count, getStringEntry(R.string.Members), onlineCount, getStringEntry(R.string.Online))));
} else { } else {
onlineText.setText(String.format("%d %s", chat.participants_count, getStringEntry(R.string.Members))); onlineText.setText(String.format("%d %s", chat.participants_count, getStringEntry(R.string.Members)));
} }
@ -692,8 +646,6 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
} }
TextView textView = (TextView)view.findViewById(R.id.settings_row_text); TextView textView = (TextView)view.findViewById(R.id.settings_row_text);
TextView detailTextView = (TextView)view.findViewById(R.id.settings_row_text_detail); TextView detailTextView = (TextView)view.findViewById(R.id.settings_row_text_detail);
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
detailTextView.setTypeface(typeface);
View divider = view.findViewById(R.id.settings_row_divider); View divider = view.findViewById(R.id.settings_row_divider);
if (i == 3) { if (i == 3) {
SharedPreferences preferences = mContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); SharedPreferences preferences = mContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
@ -726,8 +678,6 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
if (holder == null) { if (holder == null) {
holder = new ContactsActivity.ContactListRowHolder(view); holder = new ContactsActivity.ContactListRowHolder(view);
view.setTag(holder); view.setTag(holder);
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
holder.nameTextView.setTypeface(typeface);
} }
View divider = view.findViewById(R.id.settings_row_divider); View divider = view.findViewById(R.id.settings_row_divider);
@ -741,19 +691,11 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
holder.nameTextView.setText(Html.fromHtml("<b>" + user.last_name + "</b>")); holder.nameTextView.setText(Html.fromHtml("<b>" + user.last_name + "</b>"));
} }
if (info.admin_id != UserConfig.clientUserId && part.inviter_id != UserConfig.clientUserId && part.user_id != UserConfig.clientUserId) { // if (info.admin_id != UserConfig.clientUserId && part.inviter_id != UserConfig.clientUserId && part.user_id != UserConfig.clientUserId) {
if(android.os.Build.VERSION.SDK_INT >= 11) { //
holder.avatarImage.setAlpha(0.7f); // } else {
holder.nameTextView.setAlpha(0.7f); //
holder.messageTextView.setAlpha(0.7f); // }
}
} else {
if(android.os.Build.VERSION.SDK_INT >= 11) {
holder.avatarImage.setAlpha(1.0f);
holder.nameTextView.setAlpha(1.0f);
holder.messageTextView.setAlpha(1.0f);
}
}
TLRPC.FileLocation photo = null; TLRPC.FileLocation photo = null;
if (user.photo != null) { if (user.photo != null) {
@ -768,7 +710,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
} else { } else {
int currentTime = ConnectionsManager.Instance.getCurrentTime(); int currentTime = ConnectionsManager.Instance.getCurrentTime();
if ((user.status.expires > currentTime || user.status.was_online > currentTime || user.id == UserConfig.clientUserId) && user.status.expires != 0) { if ((user.status.expires > currentTime || user.status.was_online > currentTime || user.id == UserConfig.clientUserId) && user.status.expires != 0) {
holder.messageTextView.setTextColor(0xff006fc8); holder.messageTextView.setTextColor(0xff357aa8);
holder.messageTextView.setText(getStringEntry(R.string.Online)); holder.messageTextView.setText(getStringEntry(R.string.Online));
} else { } else {
if (user.status.was_online <= 10000 && user.status.expires <= 10000) { if (user.status.was_online <= 10000 && user.status.expires <= 10000) {

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -9,25 +9,19 @@
package org.telegram.ui; package org.telegram.ui;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.view.Display; import android.support.v7.app.ActionBar;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
@ -93,43 +87,6 @@ public class ChatProfileChangeNameActivity extends BaseFragment {
return fragmentView; return fragmentView;
} }
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
fixLayout();
}
private void fixLayout() {
final View view = getView();
if (view != null) {
ViewTreeObserver obs = view.getViewTreeObserver();
obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
WindowManager manager = (WindowManager)parentActivity.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int rotation = display.getRotation();
int height;
int currentActionBarHeight = parentActivity.getSupportActionBar().getHeight();
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (currentActionBarHeight != 48 * density && currentActionBarHeight != 40 * density) {
height = currentActionBarHeight;
} else {
height = (int)(48.0f * density);
if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) {
height = (int)(40.0f * density);
}
}
view.setPadding(view.getPaddingLeft(), height, view.getPaddingRight(), view.getPaddingBottom());
view.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
}
@Override @Override
public boolean canApplyUpdateStatus() { public boolean canApplyUpdateStatus() {
return false; return false;
@ -144,6 +101,7 @@ public class ChatProfileChangeNameActivity extends BaseFragment {
actionBar.setDisplayShowCustomEnabled(true); actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowHomeEnabled(false); actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false); actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setCustomView(R.layout.settings_do_action_layout); actionBar.setCustomView(R.layout.settings_do_action_layout);
View cancelButton = actionBar.getCustomView().findViewById(R.id.cancel_button); View cancelButton = actionBar.getCustomView().findViewById(R.id.cancel_button);
@ -168,11 +126,11 @@ public class ChatProfileChangeNameActivity extends BaseFragment {
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (getSherlockActivity() == null) { if (getActivity() == null) {
return; return;
} }
((ApplicationActivity)parentActivity).updateActionBar(); ((ApplicationActivity)parentActivity).updateActionBar();
fixLayout();
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
boolean animations = preferences.getBoolean("view_animations", true); boolean animations = preferences.getBoolean("view_animations", true);
if (!animations) { if (!animations) {

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -9,27 +9,20 @@
package org.telegram.ui; package org.telegram.ui;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import android.view.Display; import android.support.v7.app.ActionBar;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
@ -42,6 +35,7 @@ import org.telegram.ui.Views.BaseFragment;
public class ContactAddActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate { public class ContactAddActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
private int user_id; private int user_id;
private String phone = null;
private View doneButton; private View doneButton;
private EditText firstNameField; private EditText firstNameField;
private EditText lastNameField; private EditText lastNameField;
@ -54,6 +48,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
super.onFragmentCreate(); super.onFragmentCreate();
NotificationCenter.Instance.addObserver(this, MessagesController.updateInterfaces); NotificationCenter.Instance.addObserver(this, MessagesController.updateInterfaces);
user_id = getArguments().getInt("user_id", 0); user_id = getArguments().getInt("user_id", 0);
phone = getArguments().getString("phone");
return true; return true;
} }
@ -63,23 +58,21 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
NotificationCenter.Instance.removeObserver(this, MessagesController.updateInterfaces); NotificationCenter.Instance.removeObserver(this, MessagesController.updateInterfaces);
} }
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (fragmentView == null) { if (fragmentView == null) {
fragmentView = inflater.inflate(R.layout.contact_add_layout, container, false); fragmentView = inflater.inflate(R.layout.contact_add_layout, container, false);
TLRPC.User user = MessagesController.Instance.users.get(user_id); TLRPC.User user = MessagesController.Instance.users.get(user_id);
if (phone != null) {
user.phone = PhoneFormat.stripExceptNumbers(phone);
}
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
onlineText = (TextView)fragmentView.findViewById(R.id.settings_online); onlineText = (TextView)fragmentView.findViewById(R.id.settings_online);
onlineText.setTypeface(typeface);
avatarImage = (BackupImageView)fragmentView.findViewById(R.id.settings_avatar_image); avatarImage = (BackupImageView)fragmentView.findViewById(R.id.settings_avatar_image);
phoneText = (TextView)fragmentView.findViewById(R.id.settings_name); phoneText = (TextView)fragmentView.findViewById(R.id.settings_name);
Typeface typeface = Utilities.getTypeface("fonts/rmedium.ttf");
phoneText.setTypeface(typeface);
firstNameField = (EditText)fragmentView.findViewById(R.id.first_name_field); firstNameField = (EditText)fragmentView.findViewById(R.id.first_name_field);
firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() { firstNameField.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@ -175,9 +168,10 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
ActionBar actionBar = parentActivity.getSupportActionBar(); ActionBar actionBar = parentActivity.getSupportActionBar();
actionBar.setDisplayShowCustomEnabled(true); actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowHomeEnabled(false); actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setDisplayShowTitleEnabled(false); actionBar.setDisplayShowTitleEnabled(false);
TextView title = (TextView)parentActivity.findViewById(R.id.abs__action_bar_title); TextView title = (TextView)parentActivity.findViewById(R.id.action_bar_title);
if (title == null) { if (title == null) {
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android"); final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
title = (TextView)parentActivity.findViewById(subtitleId); title = (TextView)parentActivity.findViewById(subtitleId);
@ -213,11 +207,10 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (getSherlockActivity() == null) { if (getActivity() == null) {
return; return;
} }
((ApplicationActivity)parentActivity).updateActionBar(); ((ApplicationActivity)parentActivity).updateActionBar();
fixLayout();
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
boolean animations = preferences.getBoolean("view_animations", true); boolean animations = preferences.getBoolean("view_animations", true);
@ -227,43 +220,6 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
} }
} }
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
fixLayout();
}
private void fixLayout() {
final View view = getView();
if (view != null) {
ViewTreeObserver obs = view.getViewTreeObserver();
obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
WindowManager manager = (WindowManager)parentActivity.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int rotation = display.getRotation();
int height;
int currentActionBarHeight = parentActivity.getSupportActionBar().getHeight();
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (currentActionBarHeight != 48 * density && currentActionBarHeight != 40 * density) {
height = currentActionBarHeight;
} else {
height = (int)(48.0f * density);
if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) {
height = (int)(40.0f * density);
}
}
view.setPadding(view.getPaddingLeft(), height, view.getPaddingRight(), view.getPaddingBottom());
view.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
}
@Override @Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
if (nextAnim != 0) { if (nextAnim != 0) {

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -12,32 +12,28 @@ import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.internal.view.SupportMenuItem;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.SearchView;
import android.text.Html; import android.text.Html;
import android.view.Display;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Surface; import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.widget.SearchView;
import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
@ -49,6 +45,8 @@ import org.telegram.ui.Views.OnSwipeTouchListener;
import org.telegram.ui.Views.PinnedHeaderListView; import org.telegram.ui.Views.PinnedHeaderListView;
import org.telegram.ui.Views.SectionedBaseAdapter; import org.telegram.ui.Views.SectionedBaseAdapter;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
@ -71,7 +69,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
private SearchView searchView; private SearchView searchView;
private TextView epmtyTextView; private TextView epmtyTextView;
private HashMap<Integer, TLRPC.User> ignoreUsers; private HashMap<Integer, TLRPC.User> ignoreUsers;
MenuItem searchItem; private SupportMenuItem searchItem;
private boolean isRTL; private boolean isRTL;
private Timer searchDialogsTimer; private Timer searchDialogsTimer;
@ -170,7 +168,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt("user_id", user_id); bundle.putInt("user_id", user_id);
fragment.setArguments(bundle); fragment.setArguments(bundle);
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat_user_" + user_id, destroyAfterSelect, false); ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), destroyAfterSelect, false);
} }
} }
} else { } else {
@ -191,7 +189,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
intent.putExtra(Intent.EXTRA_TEXT, getStringEntry(R.string.InviteText)); intent.putExtra(Intent.EXTRA_TEXT, getStringEntry(R.string.InviteText));
startActivity(intent); startActivity(intent);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
return; return;
} else { } else {
@ -222,7 +220,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt("user_id", uid); bundle.putInt("user_id", uid);
fragment.setArguments(bundle); fragment.setArguments(bundle);
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat_user_" + uid, destroyAfterSelect, false); ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), destroyAfterSelect, false);
} }
} }
} else { } else {
@ -247,7 +245,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt("user_id", cLocal.user_id); bundle.putInt("user_id", cLocal.user_id);
fragment.setArguments(bundle); fragment.setArguments(bundle);
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat_user_" + cLocal.user_id, destroyAfterSelect, false); ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), destroyAfterSelect, false);
} }
return; return;
} }
@ -260,12 +258,11 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
try { try {
String number = arg1; Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromParts("sms", arg1, null));
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromParts("sms", number, null));
intent.putExtra("sms_body", getStringEntry(R.string.InviteText)); intent.putExtra("sms_body", getStringEntry(R.string.InviteText));
startActivity(intent); startActivity(intent);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -305,12 +302,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
return fragmentView; return fragmentView;
} }
@Override
public void onConfigurationChanged(android.content.res.Configuration newConfig) {
super.onConfigurationChanged(newConfig);
fixLayout();
}
private void didSelectResult(final int user_id, boolean useAlert) { private void didSelectResult(final int user_id, boolean useAlert) {
if (useAlert && selectAlertString != 0) { if (useAlert && selectAlertString != 0) {
AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity);
@ -339,39 +330,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
} }
} }
private void fixLayout() {
if (listView != null) {
ViewTreeObserver obs = listView.getViewTreeObserver();
obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
WindowManager manager = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int rotation = display.getRotation();
int height;
int currentActionBarHeight = parentActivity.getSupportActionBar().getHeight();
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (currentActionBarHeight != 48 * density && currentActionBarHeight != 40 * density) {
height = currentActionBarHeight;
} else {
height = (int)(48.0f * density);
if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) {
height = (int)(40.0f * density);
}
}
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)listView.getLayoutParams();
params.setMargins(0, height, 0, 0);
listView.setLayoutParams(params);
listView.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
}
@Override @Override
public void applySelfActionBar() { public void applySelfActionBar() {
if (parentActivity == null) { if (parentActivity == null) {
@ -386,7 +344,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
actionBar.setCustomView(null); actionBar.setCustomView(null);
actionBar.setSubtitle(null); actionBar.setSubtitle(null);
TextView title = (TextView)parentActivity.findViewById(R.id.abs__action_bar_title); TextView title = (TextView)parentActivity.findViewById(R.id.action_bar_title);
if (title == null) { if (title == null) {
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android"); final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
title = (TextView)parentActivity.findViewById(subtitleId); title = (TextView)parentActivity.findViewById(subtitleId);
@ -397,10 +355,12 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
} }
if (destroyAfterSelect) { if (destroyAfterSelect) {
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.SelectContact) + "</font>")); actionBar.setTitle(getStringEntry(R.string.SelectContact));
} else { } else {
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.Contacts) + "</font>")); actionBar.setTitle(getStringEntry(R.string.Contacts));
} }
((ApplicationActivity)parentActivity).fixBackButton();
} }
@Override @Override
@ -409,7 +369,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
if (isFinish) { if (isFinish) {
return; return;
} }
if (getSherlockActivity() == null) { if (getActivity() == null) {
return; return;
} }
if (!firstStart && listViewAdapter != null) { if (!firstStart && listViewAdapter != null) {
@ -418,7 +378,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
firstStart = false; firstStart = false;
((ApplicationActivity)parentActivity).showActionBar(); ((ApplicationActivity)parentActivity).showActionBar();
((ApplicationActivity)parentActivity).updateActionBar(); ((ApplicationActivity)parentActivity).updateActionBar();
fixLayout();
} }
public void searchDialogs(final String query) { public void searchDialogs(final String query) {
@ -431,7 +390,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
searchDialogsTimer.cancel(); searchDialogsTimer.cancel();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
searchDialogsTimer = new Timer(); searchDialogsTimer = new Timer();
searchDialogsTimer.schedule(new TimerTask() { searchDialogsTimer.schedule(new TimerTask() {
@ -441,7 +400,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
searchDialogsTimer.cancel(); searchDialogsTimer.cancel();
searchDialogsTimer = null; searchDialogsTimer = null;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
processSearch(query); processSearch(query);
} }
@ -453,14 +412,15 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
Utilities.globalQueue.postRunnable(new Runnable() { Utilities.globalQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
if (query.length() == 0) {
String q = query.trim().toLowerCase();
if (q.length() == 0) {
updateSearchResults(new ArrayList<TLRPC.User>(), new ArrayList<CharSequence>()); updateSearchResults(new ArrayList<TLRPC.User>(), new ArrayList<CharSequence>());
return; return;
} }
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
ArrayList<TLRPC.User> resultArray = new ArrayList<TLRPC.User>(); ArrayList<TLRPC.User> resultArray = new ArrayList<TLRPC.User>();
ArrayList<CharSequence> resultArrayNames = new ArrayList<CharSequence>(); ArrayList<CharSequence> resultArrayNames = new ArrayList<CharSequence>();
String q = query.toLowerCase();
for (TLRPC.TL_contact contact : MessagesController.Instance.contacts) { for (TLRPC.TL_contact contact : MessagesController.Instance.contacts) {
TLRPC.User user = MessagesController.Instance.users.get(contact.user_id); TLRPC.User user = MessagesController.Instance.users.get(contact.user_id);
@ -510,14 +470,24 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.contacts_menu, menu); inflater.inflate(R.menu.contacts_menu, menu);
searchItem = menu.findItem(R.id.messages_list_menu_search); searchItem = (SupportMenuItem)menu.findItem(R.id.messages_list_menu_search);
searchView = (SearchView) searchItem.getActionView(); searchView = (SearchView)searchItem.getActionView();
searchView.setQueryHint(getStringEntry(R.string.SearchContactHint));
int srcId = searchView.getContext().getResources().getIdentifier("android:id/search_close_btn", null, null); TextView textView = (TextView) searchView.findViewById(R.id.search_src_text);
ImageView img = (ImageView) searchView.findViewById(srcId); if (textView != null) {
textView.setTextColor(0xffffffff);
try {
Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
mCursorDrawableRes.setAccessible(true);
mCursorDrawableRes.set(textView, R.drawable.search_carret);
} catch (Exception e) {
e.printStackTrace();
}
}
ImageView img = (ImageView) searchView.findViewById(R.id.search_close_btn);
if (img != null) { if (img != null) {
img.setImageResource(R.drawable.ic_msg_in_cross); img.setImageResource(R.drawable.ic_msg_btn_cross_custom);
} }
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@ -549,10 +519,13 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
} }
}); });
searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { searchItem.setSupportOnActionExpandListener(new MenuItemCompat.OnActionExpandListener() {
@Override @Override
public boolean onMenuItemActionExpand(MenuItem menuItem) { public boolean onMenuItemActionExpand(MenuItem menuItem) {
parentActivity.getSupportActionBar().setIcon(R.drawable.ic_ab_search); if (parentActivity != null) {
ActionBar actionBar = parentActivity.getSupportActionBar();
actionBar.setIcon(R.drawable.ic_ab_search);
}
searching = true; searching = true;
return true; return true;
} }
@ -563,19 +536,21 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
searchDialogs(null); searchDialogs(null);
searching = false; searching = false;
searchWas = false; searchWas = false;
ViewGroup group = (ViewGroup)listView.getParent(); ViewGroup group = (ViewGroup) listView.getParent();
listView.setAdapter(listViewAdapter); listView.setAdapter(listViewAdapter);
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (!isRTL) { if (!isRTL) {
listView.setPadding((int)(density * 16), listView.getPaddingTop(), (int)(density * 30), listView.getPaddingBottom()); listView.setPadding((int) (density * 16), listView.getPaddingTop(), (int) (density * 30), listView.getPaddingBottom());
} else { } else {
listView.setPadding((int)(density * 30), listView.getPaddingTop(), (int)(density * 16), listView.getPaddingBottom()); listView.setPadding((int) (density * 30), listView.getPaddingTop(), (int) (density * 16), listView.getPaddingBottom());
} }
if(android.os.Build.VERSION.SDK_INT >= 11) { if (android.os.Build.VERSION.SDK_INT >= 11) {
listView.setFastScrollAlwaysVisible(true); listView.setFastScrollAlwaysVisible(true);
} }
listView.setFastScrollEnabled(true); listView.setFastScrollEnabled(true);
listView.setVerticalScrollBarEnabled(false); listView.setVerticalScrollBarEnabled(false);
((ApplicationActivity)parentActivity).updateActionBar();
epmtyTextView.setText(getStringEntry(R.string.NoContacts)); epmtyTextView.setText(getStringEntry(R.string.NoContacts));
return true; return true;
} }
@ -599,7 +574,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt("enc_id", encryptedChat.id); bundle.putInt("enc_id", encryptedChat.id);
fragment.setArguments(bundle); fragment.setArguments(bundle);
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat_enc_" + id, true, false); ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), true, false);
} }
} }
} }
@ -703,7 +678,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
} else { } else {
int currentTime = ConnectionsManager.Instance.getCurrentTime(); int currentTime = ConnectionsManager.Instance.getCurrentTime();
if (user.status.expires > currentTime || user.status.was_online > currentTime) { if (user.status.expires > currentTime || user.status.was_online > currentTime) {
holder.messageTextView.setTextColor(0xff006fc8); holder.messageTextView.setTextColor(0xff357aa8);
holder.messageTextView.setText(getStringEntry(R.string.Online)); holder.messageTextView.setText(getStringEntry(R.string.Online));
} else { } else {
if (user.status.was_online <= 10000 && user.status.expires <= 10000) { if (user.status.was_online <= 10000 && user.status.expires <= 10000) {
@ -829,8 +804,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
if (holder == null) { if (holder == null) {
holder = new ContactListRowHolder(convertView); holder = new ContactListRowHolder(convertView);
convertView.setTag(holder); convertView.setTag(holder);
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
holder.nameTextView.setTypeface(typeface);
} }
if (ignoreUsers != null) { if (ignoreUsers != null) {
@ -876,7 +849,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
} else { } else {
int currentTime = ConnectionsManager.Instance.getCurrentTime(); int currentTime = ConnectionsManager.Instance.getCurrentTime();
if (user.status.expires > currentTime || user.status.was_online > currentTime) { if (user.status.expires > currentTime || user.status.was_online > currentTime) {
holder.messageTextView.setTextColor(0xff006fc8); holder.messageTextView.setTextColor(0xff357aa8);
holder.messageTextView.setText(getStringEntry(R.string.Online)); holder.messageTextView.setText(getStringEntry(R.string.Online));
} else { } else {
if (user.status.was_online <= 10000 && user.status.expires <= 10000) { if (user.status.was_online <= 10000 && user.status.expires <= 10000) {
@ -899,8 +872,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.settings_row_button_layout, parent, false); convertView = li.inflate(R.layout.settings_row_button_layout, parent, false);
textView = (TextView)convertView.findViewById(R.id.settings_row_text); textView = (TextView)convertView.findViewById(R.id.settings_row_text);
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
textView.setTypeface(typeface);
} else { } else {
textView = (TextView)convertView.findViewById(R.id.settings_row_text); textView = (TextView)convertView.findViewById(R.id.settings_row_text);
} }
@ -999,11 +970,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
public TextView nameTextView; public TextView nameTextView;
public ContactListRowHolder(View view) { public ContactListRowHolder(View view) {
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
messageTextView = (TextView)view.findViewById(R.id.messages_list_row_message); messageTextView = (TextView)view.findViewById(R.id.messages_list_row_message);
if (messageTextView != null) {
messageTextView.setTypeface(typeface);
}
nameTextView = (TextView)view.findViewById(R.id.messages_list_row_name); nameTextView = (TextView)view.findViewById(R.id.messages_list_row_name);
avatarImage = (BackupImageView)view.findViewById(R.id.messages_list_row_avatar); avatarImage = (BackupImageView)view.findViewById(R.id.messages_list_row_avatar);
} }

View File

@ -0,0 +1,541 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Nikolai Kudashov, 2013.
*/
package org.telegram.ui;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.support.v4.internal.view.SupportMenuItem;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Views.PinnedHeaderListView;
import org.telegram.ui.Views.SectionedBaseAdapter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
public class CountrySelectActivity extends ActionBarActivity {
private SupportMenuItem searchItem;
private SearchView searchView;
private SectionedBaseAdapter listViewAdapter;
private PinnedHeaderListView listView;
private boolean searchWas;
private boolean searching;
private BaseAdapter searchListViewAdapter;
private TextView epmtyTextView;
private boolean isRTL;
private HashMap<String, ArrayList<Country>> countries = new HashMap<String, ArrayList<Country>>();
private ArrayList<String> sortedCountries = new ArrayList<String>();
private Timer searchDialogsTimer;
public ArrayList<Country> searchResult;
public static class Country {
public String name;
public String code;
public String shortname;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Locale locale = Locale.getDefault();
String lang = locale.getLanguage();
isRTL = lang != null && lang.toLowerCase().equals("ar");
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().getAssets().open("countries.txt")));
String line;
while ((line = reader.readLine()) != null) {
String[] args = line.split(";");
Country c = new Country();
c.name = args[2];
c.code = args[0];
c.shortname = args[1];
String n = c.name.substring(0, 1).toUpperCase();
ArrayList<Country> arr = countries.get(n);
if (arr == null) {
arr = new ArrayList<Country>();
countries.put(n, arr);
sortedCountries.add(n);
}
arr.add(c);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
Collections.sort(sortedCountries, new Comparator<String>() {
@Override
public int compare(String lhs, String rhs) {
return lhs.compareTo(rhs);
}
});
for (ArrayList<Country> arr : countries.values()) {
Collections.sort(arr, new Comparator<Country>() {
@Override
public int compare(Country country, Country country2) {
return country.name.compareTo(country2.name);
}
});
}
setContentView(R.layout.country_select_layout);
epmtyTextView = (TextView)findViewById(R.id.searchEmptyView);
searchListViewAdapter = new SearchAdapter(this);
listView = (PinnedHeaderListView)findViewById(R.id.listView);
listView.setEmptyView(epmtyTextView);
listView.setVerticalScrollBarEnabled(false);
listView.setAdapter(listViewAdapter = new ListAdapter(this));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if (searching && searchWas) {
if (i < searchResult.size()) {
Country c = searchResult.get(i);
Intent intent = new Intent();
intent.putExtra("country", c.name);
setResult(RESULT_OK, intent);
finish();
}
} else {
int section = listViewAdapter.getSectionForPosition(i);
int row = listViewAdapter.getPositionInSectionForPosition(i);
if (section < sortedCountries.size()) {
String n = sortedCountries.get(section);
ArrayList<Country> arr = countries.get(n);
if (row < arr.size()) {
Country c = arr.get(row);
Intent intent = new Intent();
intent.putExtra("country", c.name);
setResult(RESULT_OK, intent);
finish();
}
}
}
}
});
getWindow().setBackgroundDrawableResource(R.drawable.transparent);
getWindow().setFormat(PixelFormat.RGB_565);
}
public void applySelfActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayShowCustomEnabled(false);
actionBar.setCustomView(null);
actionBar.setSubtitle(null);
actionBar.setTitle(getString(R.string.ChooseCountry));
fixBackButton();
}
@Override
protected void onResume() {
super.onResume();
applySelfActionBar();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case android.R.id.home:
if (searchItem != null) {
if (searchItem.isActionViewExpanded()) {
searchItem.collapseActionView();
}
}
finish();
break;
}
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.contacts_menu, menu);
searchItem = (SupportMenuItem)menu.findItem(R.id.messages_list_menu_search);
searchView = (SearchView)searchItem.getActionView();
TextView textView = (TextView) searchView.findViewById(R.id.search_src_text);
if (textView != null) {
textView.setTextColor(0xffffffff);
try {
Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
mCursorDrawableRes.setAccessible(true);
mCursorDrawableRes.set(textView, R.drawable.search_carret);
} catch (Exception e) {
e.printStackTrace();
}
}
ImageView img = (ImageView) searchView.findViewById(R.id.search_close_btn);
if (img != null) {
img.setImageResource(R.drawable.ic_msg_btn_cross_custom);
}
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return true;
}
@Override
public boolean onQueryTextChange(String s) {
searchDialogs(s);
if (s.length() != 0) {
searchWas = true;
if (listView != null) {
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
listView.setPadding((int)(density * 16), listView.getPaddingTop(), (int)(density * 16), listView.getPaddingBottom());
listView.setAdapter(searchListViewAdapter);
if(android.os.Build.VERSION.SDK_INT >= 11) {
listView.setFastScrollAlwaysVisible(false);
}
listView.setFastScrollEnabled(false);
listView.setVerticalScrollBarEnabled(true);
}
if (epmtyTextView != null) {
epmtyTextView.setText(getString(R.string.NoResult));
}
}
return true;
}
});
searchItem.setSupportOnActionExpandListener(new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem menuItem) {
getSupportActionBar().setIcon(R.drawable.ic_ab_search);
searching = true;
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem menuItem) {
searchView.setQuery("", false);
searchDialogs(null);
searching = false;
searchWas = false;
ViewGroup group = (ViewGroup) listView.getParent();
listView.setAdapter(listViewAdapter);
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (!isRTL) {
listView.setPadding((int) (density * 16), listView.getPaddingTop(), (int) (density * 30), listView.getPaddingBottom());
} else {
listView.setPadding((int) (density * 30), listView.getPaddingTop(), (int) (density * 16), listView.getPaddingBottom());
}
if (android.os.Build.VERSION.SDK_INT >= 11) {
listView.setFastScrollAlwaysVisible(true);
}
listView.setFastScrollEnabled(true);
listView.setVerticalScrollBarEnabled(false);
applySelfActionBar();
epmtyTextView.setText(getString(R.string.ChooseCountry));
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
public void fixBackButton() {
if(android.os.Build.VERSION.SDK_INT == 19) {
//workaround for back button dissapear
try {
Class firstClass = getSupportActionBar().getClass();
Class aClass = firstClass.getSuperclass();
if (aClass == android.support.v7.app.ActionBar.class) {
} else {
Field field = aClass.getDeclaredField("mActionBar");
field.setAccessible(true);
android.app.ActionBar bar = (android.app.ActionBar)field.get(getSupportActionBar());
field = bar.getClass().getDeclaredField("mActionView");
field.setAccessible(true);
View v = (View)field.get(bar);
aClass = v.getClass();
field = aClass.getDeclaredField("mHomeLayout");
field.setAccessible(true);
v = (View)field.get(v);
v.setVisibility(View.VISIBLE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void searchDialogs(final String query) {
if (query == null) {
searchResult = null;
} else {
try {
if (searchDialogsTimer != null) {
searchDialogsTimer.cancel();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
searchDialogsTimer = new Timer();
searchDialogsTimer.schedule(new TimerTask() {
@Override
public void run() {
try {
searchDialogsTimer.cancel();
searchDialogsTimer = null;
} catch (Exception e) {
FileLog.e("tmessages", e);
}
processSearch(query);
}
}, 100, 300);
}
}
private void processSearch(final String query) {
Utilities.globalQueue.postRunnable(new Runnable() {
@Override
public void run() {
String q = query.trim().toLowerCase();
if (q.length() == 0) {
updateSearchResults(new ArrayList<Country>());
return;
}
long time = System.currentTimeMillis();
ArrayList<Country> resultArray = new ArrayList<Country>();
String n = query.substring(0, 1);
ArrayList<Country> arr = countries.get(n.toUpperCase());
if (arr != null) {
for (Country c : arr) {
if (c.name.toLowerCase().startsWith(query)) {
resultArray.add(c);
}
}
}
updateSearchResults(resultArray);
}
});
}
private void updateSearchResults(final ArrayList<Country> arrCounties) {
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
searchResult = arrCounties;
searchListViewAdapter.notifyDataSetChanged();
}
});
}
private class SearchAdapter extends BaseAdapter {
private Context mContext;
public SearchAdapter(Context context) {
mContext = context;
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
@Override
public boolean isEnabled(int i) {
return true;
}
@Override
public int getCount() {
if (searchResult == null) {
return 0;
}
return searchResult.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.country_row_layout, viewGroup, false);
}
TextView textView = (TextView)view.findViewById(R.id.settings_row_text);
TextView detailTextView = (TextView)view.findViewById(R.id.settings_row_text_detail);
View divider = view.findViewById(R.id.settings_row_divider);
Country c = searchResult.get(i);
textView.setText(c.name);
detailTextView.setText("+" + c.code);
if (i == searchResult.size() - 1) {
divider.setVisibility(View.GONE);
} else {
divider.setVisibility(View.VISIBLE);
}
return view;
}
@Override
public int getItemViewType(int i) {
return 0;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public boolean isEmpty() {
return searchResult == null || searchResult.size() == 0;
}
}
private class ListAdapter extends SectionedBaseAdapter {
private Context mContext;
public ListAdapter(Context context) {
mContext = context;
}
@Override
public Object getItem(int section, int position) {
return null;
}
@Override
public long getItemId(int section, int position) {
return 0;
}
@Override
public int getSectionCount() {
return sortedCountries.size();
}
@Override
public int getCountForSection(int section) {
String n = sortedCountries.get(section);
ArrayList<Country> arr = countries.get(n);
return arr.size();
}
@Override
public View getItemView(int section, int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.country_row_layout, parent, false);
}
TextView textView = (TextView)convertView.findViewById(R.id.settings_row_text);
TextView detailTextView = (TextView)convertView.findViewById(R.id.settings_row_text_detail);
View divider = convertView.findViewById(R.id.settings_row_divider);
String n = sortedCountries.get(section);
ArrayList<Country> arr = countries.get(n);
Country c = arr.get(position);
textView.setText(c.name);
detailTextView.setText("+" + c.code);
if (position == arr.size() - 1) {
divider.setVisibility(View.GONE);
} else {
divider.setVisibility(View.VISIBLE);
}
return convertView;
}
@Override
public int getItemViewType(int section, int position) {
return 0;
}
@Override
public int getItemViewTypeCount() {
return 1;
}
@Override
public int getSectionHeaderViewType(int section) {
return 0;
}
@Override
public int getSectionHeaderViewTypeCount() {
return 1;
}
@Override
public View getSectionHeaderView(int section, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.settings_section_layout, parent, false);
convertView.setBackgroundColor(0xfffafafa);
}
TextView textView = (TextView)convertView.findViewById(R.id.settings_section_text);
textView.setText(sortedCountries.get(section).toUpperCase());
return convertView;
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -12,9 +12,12 @@ import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.v4.view.PagerAdapter; import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
@ -24,11 +27,8 @@ import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.objects.PhotoObject; import org.telegram.objects.PhotoObject;
import org.telegram.ui.Views.AbstractGalleryActivity; import org.telegram.ui.Views.AbstractGalleryActivity;
import org.telegram.ui.Views.GalleryViewPager; import org.telegram.ui.Views.GalleryViewPager;
@ -43,10 +43,8 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import java.io.File; import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
public class GalleryImageViewer extends AbstractGalleryActivity implements NotificationCenter.NotificationCenterDelegate { public class GalleryImageViewer extends AbstractGalleryActivity implements NotificationCenter.NotificationCenterDelegate {
@ -63,18 +61,18 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
private boolean loadingMore = false; private boolean loadingMore = false;
private TextView title; private TextView title;
private boolean ignoreSet = false; private boolean ignoreSet = false;
private ProgressBar loadingProgress;
private String currentFileName;
private int user_id = 0;
private ArrayList<MessageObject> imagesArrTemp = new ArrayList<MessageObject>(); private ArrayList<MessageObject> imagesArrTemp = new ArrayList<MessageObject>();
private HashMap<Integer, MessageObject> imagesByIdsTemp = new HashMap<Integer, MessageObject>(); private HashMap<Integer, MessageObject> imagesByIdsTemp = new HashMap<Integer, MessageObject>();
private ArrayList<TLRPC.FileLocation> imagesArrLocations;
private long currentDialog = 0; private long currentDialog = 0;
private int totalCount = 0; private int totalCount = 0;
private int classGuid; private int classGuid;
private boolean cacheEndReached; private boolean firstLoad = true;
private boolean cacheEndReached = false;
private HashMap<String, ProgressBar> loadingFile = new HashMap<String, ProgressBar>();
private HashMap<Integer, String> progressByTag = new HashMap<Integer, String>();
public static int needShowAllMedia = 2000; public static int needShowAllMedia = 2000;
@ -100,8 +98,9 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
timeTextView = (TextView)findViewById(R.id.gallery_view_time_text); timeTextView = (TextView)findViewById(R.id.gallery_view_time_text);
bottomView = findViewById(R.id.gallery_view_bottom_view); bottomView = findViewById(R.id.gallery_view_bottom_view);
fakeTitleView = (TextView)findViewById(R.id.fake_title_view); fakeTitleView = (TextView)findViewById(R.id.fake_title_view);
loadingProgress = (ProgressBar)findViewById(R.id.action_progress);
title = (TextView)findViewById(R.id.abs__action_bar_title); title = (TextView)findViewById(R.id.action_bar_title);
if (title == null) { if (title == null) {
final int titleId = getResources().getIdentifier("action_bar_title", "id", "android"); final int titleId = getResources().getIdentifier("action_bar_title", "id", "android");
title = (TextView)findViewById(titleId); title = (TextView)findViewById(titleId);
@ -112,19 +111,22 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
NotificationCenter.Instance.addObserver(this, FileLoader.FileLoadProgressChanged); NotificationCenter.Instance.addObserver(this, FileLoader.FileLoadProgressChanged);
NotificationCenter.Instance.addObserver(this, MessagesController.mediaCountDidLoaded); NotificationCenter.Instance.addObserver(this, MessagesController.mediaCountDidLoaded);
NotificationCenter.Instance.addObserver(this, MessagesController.mediaDidLoaded); NotificationCenter.Instance.addObserver(this, MessagesController.mediaDidLoaded);
NotificationCenter.Instance.addObserver(this, MessagesController.userPhotosLoaded);
Integer index = null; Integer index = null;
if (localPagerAdapter == null) { if (localPagerAdapter == null) {
final MessageObject file = (MessageObject)NotificationCenter.Instance.getFromMemCache(1); final MessageObject file = (MessageObject)NotificationCenter.Instance.getFromMemCache(51);
final TLRPC.FileLocation fileLocation = (TLRPC.FileLocation)NotificationCenter.Instance.getFromMemCache(3); final TLRPC.FileLocation fileLocation = (TLRPC.FileLocation)NotificationCenter.Instance.getFromMemCache(53);
final ArrayList<MessageObject> messagesArr = (ArrayList<MessageObject>)NotificationCenter.Instance.getFromMemCache(4); final ArrayList<MessageObject> messagesArr = (ArrayList<MessageObject>)NotificationCenter.Instance.getFromMemCache(54);
index = (Integer)NotificationCenter.Instance.getFromMemCache(5); index = (Integer)NotificationCenter.Instance.getFromMemCache(55);
Integer uid = (Integer)NotificationCenter.Instance.getFromMemCache(56);
if (uid != null) {
user_id = uid;
}
ArrayList<MessageObject> imagesArr = null;
HashMap<Integer, MessageObject> imagesByIds = null;
if (file != null) { if (file != null) {
imagesArr = new ArrayList<MessageObject>(); ArrayList<MessageObject> imagesArr = new ArrayList<MessageObject>();
imagesByIds = new HashMap<Integer, MessageObject>(); HashMap<Integer, MessageObject> imagesByIds = new HashMap<Integer, MessageObject>();
imagesArr.add(file); imagesArr.add(file);
if (file.messageOwner.action == null || file.messageOwner.action instanceof TLRPC.TL_messageActionEmpty) { if (file.messageOwner.action == null || file.messageOwner.action instanceof TLRPC.TL_messageActionEmpty) {
needSearchMessage = true; needSearchMessage = true;
@ -143,17 +145,18 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
} }
} }
} }
localPagerAdapter = new LocalPagerAdapter(imagesArr, imagesByIds);
} else if (fileLocation != null) { } else if (fileLocation != null) {
ArrayList<TLRPC.FileLocation> arr = new ArrayList<TLRPC.FileLocation>(); ArrayList<TLRPC.FileLocation> arr = new ArrayList<TLRPC.FileLocation>();
arr.add(fileLocation); arr.add(fileLocation);
imagesArrLocations = arr;
withoutBottom = true; withoutBottom = true;
deleteButton.setVisibility(View.INVISIBLE); deleteButton.setVisibility(View.INVISIBLE);
nameTextView.setVisibility(View.INVISIBLE); nameTextView.setVisibility(View.INVISIBLE);
timeTextView.setVisibility(View.INVISIBLE); timeTextView.setVisibility(View.INVISIBLE);
localPagerAdapter = new LocalPagerAdapter(arr);
} else if (messagesArr != null) { } else if (messagesArr != null) {
imagesArr = new ArrayList<MessageObject>(); ArrayList<MessageObject> imagesArr = new ArrayList<MessageObject>();
imagesByIds = new HashMap<Integer, MessageObject>(); HashMap<Integer, MessageObject> imagesByIds = new HashMap<Integer, MessageObject>();
imagesArr.addAll(messagesArr); imagesArr.addAll(messagesArr);
Collections.reverse(imagesArr); Collections.reverse(imagesArr);
for (MessageObject message : imagesArr) { for (MessageObject message : imagesArr) {
@ -175,8 +178,8 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
} }
} }
} }
localPagerAdapter = new LocalPagerAdapter(imagesArr, imagesByIds);
} }
localPagerAdapter = new LocalPagerAdapter(imagesArr, imagesByIds);
} }
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
@ -187,7 +190,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
if (index != null) { if (index != null) {
fromAll = true; fromAll = true;
mViewPager.setCurrentItem( index); mViewPager.setCurrentItem(index);
} }
shareButton.setOnClickListener(new View.OnClickListener() { shareButton.setOnClickListener(new View.OnClickListener() {
@ -203,7 +206,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
startActivity(intent); startActivity(intent);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }
}); });
@ -225,6 +228,10 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
if (currentDialog != 0 && totalCount == 0) { if (currentDialog != 0 && totalCount == 0) {
MessagesController.Instance.getMediaCount(currentDialog, classGuid, true); MessagesController.Instance.getMediaCount(currentDialog, classGuid, true);
} }
if (user_id != 0) {
MessagesController.Instance.loadUserPhotos(user_id, 0, 30, 0, true, classGuid);
}
checkCurrentFile();
} }
@Override @Override
@ -235,6 +242,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
NotificationCenter.Instance.removeObserver(this, FileLoader.FileLoadProgressChanged); NotificationCenter.Instance.removeObserver(this, FileLoader.FileLoadProgressChanged);
NotificationCenter.Instance.removeObserver(this, MessagesController.mediaCountDidLoaded); NotificationCenter.Instance.removeObserver(this, MessagesController.mediaCountDidLoaded);
NotificationCenter.Instance.removeObserver(this, MessagesController.mediaDidLoaded); NotificationCenter.Instance.removeObserver(this, MessagesController.mediaDidLoaded);
NotificationCenter.Instance.removeObserver(this, MessagesController.userPhotosLoaded);
ConnectionsManager.Instance.cancelRpcsForClassGuid(classGuid); ConnectionsManager.Instance.cancelRpcsForClassGuid(classGuid);
} }
@ -243,28 +251,100 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
public void didReceivedNotification(int id, final Object... args) { public void didReceivedNotification(int id, final Object... args) {
if (id == FileLoader.FileDidFailedLoad) { if (id == FileLoader.FileDidFailedLoad) {
String location = (String)args[0]; String location = (String)args[0];
if (loadingFile.containsKey(location)) { if (currentFileName != null && currentFileName.equals(location)) {
loadingFile.remove(location); if (loadingProgress != null) {
localPagerAdapter.updateViews(); loadingProgress.setVisibility(View.GONE);
}
if (localPagerAdapter != null) {
localPagerAdapter.updateViews();
}
} }
} else if (id == FileLoader.FileDidLoaded) { } else if (id == FileLoader.FileDidLoaded) {
String location = (String)args[0]; String location = (String)args[0];
if (loadingFile.containsKey(location)) { if (currentFileName != null && currentFileName.equals(location)) {
loadingFile.remove(location); if (loadingProgress != null) {
localPagerAdapter.updateViews(); loadingProgress.setVisibility(View.GONE);
}
if (localPagerAdapter != null) {
localPagerAdapter.updateViews();
}
} }
} else if (id == FileLoader.FileLoadProgressChanged) { } else if (id == FileLoader.FileLoadProgressChanged) {
String location = (String)args[0]; String location = (String)args[0];
ProgressBar bar; if (currentFileName != null && currentFileName.equals(location)) {
if ((bar = loadingFile.get(location)) != null) {
Float progress = (Float)args[1]; Float progress = (Float)args[1];
bar.setProgress((int)(progress * 100)); if (loadingProgress != null) {
loadingProgress.setVisibility(View.VISIBLE);
loadingProgress.setProgress((int)(progress * 100));
}
if (localPagerAdapter != null) {
localPagerAdapter.updateViews();
}
}
} else if (id == MessagesController.userPhotosLoaded) {
int guid = (Integer)args[4];
int uid = (Integer)args[0];
if (user_id == uid && classGuid == guid) {
boolean fromCache = (Boolean)args[3];
TLRPC.FileLocation currentLocation = null;
int setToImage = -1;
if (localPagerAdapter != null && mViewPager != null) {
int idx = mViewPager.getCurrentItem();
if (localPagerAdapter.imagesArrLocations.size() > idx) {
currentLocation = localPagerAdapter.imagesArrLocations.get(idx);
}
}
ArrayList<TLRPC.Photo> photos = (ArrayList<TLRPC.Photo>)args[5];
if (photos.isEmpty()) {
return;
}
ArrayList<TLRPC.FileLocation> arr = new ArrayList<TLRPC.FileLocation>();
for (TLRPC.Photo photo : photos) {
if (photo instanceof TLRPC.TL_photoEmpty) {
continue;
}
TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(photo.sizes, 800, 800);
if (sizeFull != null) {
if (currentLocation != null && sizeFull.location.local_id == currentLocation.local_id && sizeFull.location.volume_id == currentLocation.volume_id) {
setToImage = arr.size();
}
arr.add(sizeFull.location);
}
}
mViewPager.setAdapter(null);
int count = mViewPager.getChildCount();
for (int a = 0; a < count; a++) {
View child = mViewPager.getChildAt(0);
mViewPager.removeView(child);
}
mViewPager.mCurrentView = null;
needSearchMessage = false;
ignoreSet = true;
mViewPager.setAdapter(localPagerAdapter = new LocalPagerAdapter(arr));
mViewPager.invalidate();
ignoreSet = false;
if (setToImage != -1) {
mViewPager.setCurrentItem(setToImage);
} else {
mViewPager.setCurrentItem(0);
}
if (fromCache) {
MessagesController.Instance.loadUserPhotos(user_id, 0, 30, 0, false, classGuid);
}
} }
} else if (id == MessagesController.mediaCountDidLoaded) { } else if (id == MessagesController.mediaCountDidLoaded) {
long uid = (Long)args[0]; long uid = (Long)args[0];
if (uid == currentDialog) { if (uid == currentDialog) {
if ((int)currentDialog != 0) {
boolean fromCache = (Boolean)args[2];
if (fromCache) {
MessagesController.Instance.getMediaCount(currentDialog, classGuid, false);
}
}
totalCount = (Integer)args[1]; totalCount = (Integer)args[1];
if (needSearchMessage) { if (needSearchMessage && firstLoad) {
firstLoad = false;
MessagesController.Instance.loadMedia(currentDialog, 0, 100, 0, true, classGuid); MessagesController.Instance.loadMedia(currentDialog, 0, 100, 0, true, classGuid);
loadingMore = true; loadingMore = true;
} else { } else {
@ -317,6 +397,9 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
} }
} }
} }
if (added == 0) {
totalCount = imagesArrTemp.size();
}
if (foundIndex != -1) { if (foundIndex != -1) {
mViewPager.setAdapter(null); mViewPager.setAdapter(null);
@ -353,17 +436,19 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
if (arr.isEmpty() && !fromCache) { if (arr.isEmpty() && !fromCache) {
totalCount = arr.size(); totalCount = arr.size();
} }
int current = mViewPager.getCurrentItem();
ignoreSet = true;
imagesArrTemp = new ArrayList<MessageObject>(localPagerAdapter.imagesArr);
imagesByIdsTemp = new HashMap<Integer, MessageObject>(localPagerAdapter.imagesByIds);
mViewPager.setAdapter(localPagerAdapter = new LocalPagerAdapter(imagesArrTemp, imagesByIdsTemp));
mViewPager.invalidate();
ignoreSet = false;
imagesArrTemp = null;
imagesByIdsTemp = null;
if (added != 0) { if (added != 0) {
int current = mViewPager.getCurrentItem();
ignoreSet = true;
imagesArrTemp = new ArrayList<MessageObject>(localPagerAdapter.imagesArr);
imagesByIdsTemp = new HashMap<Integer, MessageObject>(localPagerAdapter.imagesByIds);
mViewPager.setAdapter(localPagerAdapter = new LocalPagerAdapter(imagesArrTemp, imagesByIdsTemp));
mViewPager.invalidate();
ignoreSet = false;
imagesArrTemp = null;
imagesByIdsTemp = null;
mViewPager.setCurrentItem(current + added); mViewPager.setCurrentItem(current + added);
} else {
totalCount = localPagerAdapter.imagesArr.size();
} }
} }
} }
@ -373,18 +458,22 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
private TLRPC.FileLocation getCurrentFile() { private TLRPC.FileLocation getCurrentFile() {
int item = mViewPager.getCurrentItem(); int item = mViewPager.getCurrentItem();
if (withoutBottom) { if (withoutBottom) {
return imagesArrLocations.get(item); return localPagerAdapter.imagesArrLocations.get(item);
} else { } else {
MessageObject message = localPagerAdapter.imagesArr.get(item); MessageObject message = localPagerAdapter.imagesArr.get(item);
if (message.messageOwner instanceof TLRPC.TL_messageService) { if (message.messageOwner instanceof TLRPC.TL_messageService) {
ArrayList<TLRPC.PhotoSize> sizes = message.messageOwner.action.photo.sizes; if (message.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
if (sizes.size() > 0) { return message.messageOwner.action.newUserPhoto.photo_big;
return sizes.get(sizes.size() - 1).location; } else {
TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(message.messageOwner.action.photo.sizes, 800, 800);
if (sizeFull != null) {
return sizeFull.location;
}
} }
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { } else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
ArrayList<TLRPC.PhotoSize> sizes = message.messageOwner.media.photo.sizes; TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(message.messageOwner.media.photo.sizes, 800, 800);
if (sizes.size() > 0) { if (sizeFull != null) {
return sizes.get(sizes.size() - 1).location; return sizeFull.location;
} }
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { } else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
return message.messageOwner.media.video.thumb.location; return message.messageOwner.media.video.thumb.location;
@ -414,13 +503,69 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
} else { } else {
nameTextView.setText(""); nameTextView.setText("");
} }
invalidateOptionsMenu();
isVideo = obj.messageOwner.media != null && obj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo; isVideo = obj.messageOwner.media != null && obj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo;
if (obj.messageOwner instanceof TLRPC.TL_messageService) {
if (obj.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
TLRPC.FileLocation file = obj.messageOwner.action.newUserPhoto.photo_big;
currentFileName = file.volume_id + "_" + file.local_id + ".jpg";
} else {
ArrayList<TLRPC.PhotoSize> sizes = obj.messageOwner.action.photo.sizes;
if (sizes.size() > 0) {
TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(sizes, 800, 800);
if (sizeFull != null) {
currentFileName = sizeFull.location.volume_id + "_" + sizeFull.location.local_id + ".jpg";
}
}
}
} else if (obj.messageOwner.media != null) {
if (obj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
currentFileName = obj.messageOwner.media.video.dc_id + "_" + obj.messageOwner.media.video.id + ".mp4";
} else if (obj.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
TLRPC.FileLocation file = getCurrentFile();
if (file != null) {
currentFileName = file.volume_id + "_" + file.local_id + ".jpg";
} else {
currentFileName = null;
}
}
} else {
currentFileName = null;
}
checkCurrentFile();
supportInvalidateOptionsMenu();
}
private void checkCurrentFile() {
if (currentFileName != null) {
File f = new File(Utilities.getCacheDir(), currentFileName);
if (f.exists()) {
loadingProgress.setVisibility(View.GONE);
} else {
loadingProgress.setVisibility(View.VISIBLE);
Float progress = FileLoader.Instance.fileProgresses.get(currentFileName);
if (progress != null) {
loadingProgress.setProgress((int)(progress * 100));
} else {
loadingProgress.setProgress(0);
}
}
} else {
loadingProgress.setVisibility(View.GONE);
}
if (isVideo) {
if (!FileLoader.Instance.isLoadingFile(currentFileName)) {
loadingProgress.setVisibility(View.GONE);
} else {
loadingProgress.setVisibility(View.VISIBLE);
}
}
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater(); MenuInflater inflater = getMenuInflater();
if (withoutBottom) { if (withoutBottom) {
inflater.inflate(R.menu.gallery_save_only_menu, menu); inflater.inflate(R.menu.gallery_save_only_menu, menu);
} else { } else {
@ -436,14 +581,16 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
@Override @Override
public void openOptionsMenu() { public void openOptionsMenu() {
TLRPC.FileLocation file = getCurrentFile(); TLRPC.FileLocation file = getCurrentFile();
File f = new File(Utilities.getCacheDir(), file.volume_id + "_" + file.local_id + ".jpg"); if (file != null) {
if (f.exists()) { File f = new File(Utilities.getCacheDir(), file.volume_id + "_" + file.local_id + ".jpg");
super.openOptionsMenu(); if (f.exists()) {
super.openOptionsMenu();
}
} }
} }
@Override @Override
public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId(); int itemId = item.getItemId();
processSelectedMenu(itemId); processSelectedMenu(itemId);
return true; return true;
@ -484,14 +631,13 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
case R.id.gallery_menu_save: case R.id.gallery_menu_save:
TLRPC.FileLocation file = getCurrentFile(); TLRPC.FileLocation file = getCurrentFile();
File f = new File(Utilities.getCacheDir(), file.volume_id + "_" + file.local_id + ".jpg"); File f = new File(Utilities.getCacheDir(), file.volume_id + "_" + file.local_id + ".jpg");
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File dstFile = Utilities.generatePicturePath();
String imageFileName = "IMG_" + timeStamp + ".jpg";
try { try {
MediaStore.Images.Media.insertImage(getContentResolver(), f.getAbsolutePath(), imageFileName, ""); Utilities.copyFile(f, dstFile);
Utilities.addMediaToGallery(Uri.fromFile(dstFile));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
//Utilities.addMediaToGallery(addToTouchActiveAlbum(imageFileName, f.getAbsolutePath()));
break; break;
// case R.id.gallery_menu_send: { // case R.id.gallery_menu_send: {
// Intent intent = new Intent(this, MessagesActivity.class); // Intent intent = new Intent(this, MessagesActivity.class);
@ -548,21 +694,6 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
} }
} }
/*public Uri addToTouchActiveAlbum(String title, String filePath) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, title);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.BUCKET_ID, filePath.hashCode());
values.put(MediaStore.Images.Media.BUCKET_DISPLAY_NAME, "TMessages");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
//values.put(MediaStore.MediaColumns.DATA, filePath);
values.put(MediaStore.Images.Media.DATA, filePath);
return getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}*/
private void startViewAnimation(final View panel, boolean up) { private void startViewAnimation(final View panel, boolean up) {
Animation animation; Animation animation;
if (!up) { if (!up) {
@ -612,13 +743,17 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
public class LocalPagerAdapter extends PagerAdapter { public class LocalPagerAdapter extends PagerAdapter {
public ArrayList<MessageObject> imagesArr; public ArrayList<MessageObject> imagesArr;
public HashMap<Integer, MessageObject> imagesByIds; public HashMap<Integer, MessageObject> imagesByIds;
public int tagCounter = 0; private ArrayList<TLRPC.FileLocation> imagesArrLocations;
public LocalPagerAdapter(ArrayList<MessageObject> _imagesArr, HashMap<Integer, MessageObject> _imagesByIds) { public LocalPagerAdapter(ArrayList<MessageObject> _imagesArr, HashMap<Integer, MessageObject> _imagesByIds) {
imagesArr = _imagesArr; imagesArr = _imagesArr;
imagesByIds = _imagesByIds; imagesByIds = _imagesByIds;
} }
public LocalPagerAdapter(ArrayList<TLRPC.FileLocation> locations) {
imagesArrLocations = locations;
}
@Override @Override
public void setPrimaryItem(ViewGroup container, final int position, Object object) { public void setPrimaryItem(ViewGroup container, final int position, Object object) {
super.setPrimaryItem(container, position, object); super.setPrimaryItem(container, position, object);
@ -650,6 +785,26 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
}); });
} }
} else if (imagesArrLocations != null) {
TLRPC.FileLocation file = imagesArrLocations.get(position);
currentFileName = file.volume_id + "_" + file.local_id + ".jpg";
checkCurrentFile();
if (imagesArrLocations.size() > 1) {
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
getSupportActionBar().setTitle(String.format("%d %s %d", position + 1, getString(R.string.Of), imagesArrLocations.size()));
if (title != null) {
fakeTitleView.setText(String.format("%d %s %d", position + 1, getString(R.string.Of), imagesArrLocations.size()));
fakeTitleView.measure(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.AT_MOST), 40);
title.setWidth(fakeTitleView.getMeasuredWidth() + (int)(8 * getResources().getDisplayMetrics().density));
title.setMaxWidth(fakeTitleView.getMeasuredWidth() + (int)(8 * getResources().getDisplayMetrics().density));
}
}
});
} else {
getSupportActionBar().setTitle(getString(R.string.Gallery));
}
} }
} }
@ -657,25 +812,22 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
int count = mViewPager.getChildCount(); int count = mViewPager.getChildCount();
for (int a = 0; a < count; a++) { for (int a = 0; a < count; a++) {
View v = mViewPager.getChildAt(a); View v = mViewPager.getChildAt(a);
final ProgressBar progressBar = (ProgressBar)v.findViewById(R.id.action_progress);
final TextView playButton = (TextView)v.findViewById(R.id.action_button); final TextView playButton = (TextView)v.findViewById(R.id.action_button);
final View progressBarParent = v.findViewById(R.id.action_progress_parent);
MessageObject message = (MessageObject)playButton.getTag(); MessageObject message = (MessageObject)playButton.getTag();
if (progressBar != null && message != null) { if (message != null) {
processViews(progressBar, playButton, message, progressBarParent); processViews(playButton, message);
} }
} }
} }
public void processViews(ProgressBar progressBar, TextView playButton, MessageObject message, View progressBarParent) { public void processViews(TextView playButton, MessageObject message) {
if (message.messageOwner.send_state != MessagesController.MESSAGE_SEND_STATE_SENDING && message.messageOwner.send_state != MessagesController.MESSAGE_SEND_STATE_SEND_ERROR) { if (message.messageOwner.send_state != MessagesController.MESSAGE_SEND_STATE_SENDING && message.messageOwner.send_state != MessagesController.MESSAGE_SEND_STATE_SEND_ERROR) {
playButton.setVisibility(View.VISIBLE);
String fileName = message.messageOwner.media.video.dc_id + "_" + message.messageOwner.media.video.id + ".mp4"; String fileName = message.messageOwner.media.video.dc_id + "_" + message.messageOwner.media.video.id + ".mp4";
boolean load = false; boolean load = false;
if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) { if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) {
File f = new File(message.messageOwner.attachPath); File f = new File(message.messageOwner.attachPath);
if (f.exists()) { if (f.exists()) {
playButton.setVisibility(View.VISIBLE);
progressBarParent.setVisibility(View.GONE);
playButton.setText(getString(R.string.ViewVideo)); playButton.setText(getString(R.string.ViewVideo));
} else { } else {
load = true; load = true;
@ -683,8 +835,6 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
} else { } else {
File cacheFile = new File(Utilities.getCacheDir(), fileName); File cacheFile = new File(Utilities.getCacheDir(), fileName);
if (cacheFile.exists()) { if (cacheFile.exists()) {
playButton.setVisibility(View.VISIBLE);
progressBarParent.setVisibility(View.GONE);
playButton.setText(getString(R.string.ViewVideo)); playButton.setText(getString(R.string.ViewVideo));
} else { } else {
load = true; load = true;
@ -692,33 +842,11 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
} }
if (load) { if (load) {
Float progress = FileLoader.Instance.fileProgresses.get(fileName); Float progress = FileLoader.Instance.fileProgresses.get(fileName);
if (loadingFile.containsKey(fileName) || progress != null) { if (FileLoader.Instance.isLoadingFile(fileName)) {
if (progress != null) { playButton.setText(R.string.CancelDownload);
progressBar.setProgress((int) (progress * 100));
} else {
progressBar.setProgress(0);
}
progressByTag.put((Integer)progressBar.getTag(), fileName);
loadingFile.put(fileName, progressBar);
progressBarParent.setVisibility(View.VISIBLE);
playButton.setVisibility(View.GONE);
} else { } else {
progressBarParent.setVisibility(View.GONE);
playButton.setVisibility(View.VISIBLE);
playButton.setText(String.format("%s %.1f MB", getString(R.string.DOWNLOAD), message.messageOwner.media.video.size / 1024.0f / 1024.0f)); playButton.setText(String.format("%s %.1f MB", getString(R.string.DOWNLOAD), message.messageOwner.media.video.size / 1024.0f / 1024.0f));
} }
} else {
Integer tag = (Integer)progressBar.getTag();
String file = progressByTag.get(tag);
if (file != null) {
loadingFile.remove(file);
}
}
} else {
Integer tag = (Integer)progressBar.getTag();
String file = progressByTag.get(tag);
if (file != null) {
loadingFile.remove(file);
} }
} }
} }
@ -734,24 +862,25 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
((ViewPager) collection).addView(view, 0); ((ViewPager) collection).addView(view, 0);
PZSImageView iv = (PZSImageView)view.findViewById(R.id.page_image); PZSImageView iv = (PZSImageView)view.findViewById(R.id.page_image);
final ProgressBar progressBar = (ProgressBar)view.findViewById(R.id.action_progress);
final TextView playButton = (TextView)view.findViewById(R.id.action_button); final TextView playButton = (TextView)view.findViewById(R.id.action_button);
final View progressBarParent = view.findViewById(R.id.action_progress_parent);
progressBar.setTag(tagCounter);
tagCounter++;
if (imagesArr != null) { if (imagesArr != null) {
final MessageObject message = imagesArr.get(position); final MessageObject message = imagesArr.get(position);
view.setTag(message.messageOwner.id); view.setTag(message.messageOwner.id);
if (message.messageOwner instanceof TLRPC.TL_messageService) { if (message.messageOwner instanceof TLRPC.TL_messageService) {
ArrayList<TLRPC.PhotoSize> sizes = message.messageOwner.action.photo.sizes; if (message.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
iv.isVideo = false; iv.isVideo = false;
if (sizes.size() > 0) { iv.setImage(message.messageOwner.action.newUserPhoto.photo_big, null, 0, -1);
TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(sizes, 800, 800); } else {
if (message.imagePreview != null) { ArrayList<TLRPC.PhotoSize> sizes = message.messageOwner.action.photo.sizes;
iv.setImage(sizeFull.location, null, message.imagePreview); iv.isVideo = false;
} else { if (sizes.size() > 0) {
iv.setImage(sizeFull.location, null, 0); TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(sizes, 800, 800);
if (message.imagePreview != null) {
iv.setImage(sizeFull.location, null, message.imagePreview, sizeFull.size);
} else {
iv.setImage(sizeFull.location, null, 0, sizeFull.size);
}
} }
} }
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { } else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
@ -760,13 +889,13 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
if (sizes.size() > 0) { if (sizes.size() > 0) {
TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(sizes, 800, 800); TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(sizes, 800, 800);
if (message.imagePreview != null) { if (message.imagePreview != null) {
iv.setImage(sizeFull.location, null, message.imagePreview); iv.setImage(sizeFull.location, null, message.imagePreview, sizeFull.size);
} else { } else {
iv.setImage(sizeFull.location, null, 0); iv.setImage(sizeFull.location, null, 0, sizeFull.size);
} }
} }
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { } else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
processViews(progressBar, playButton, message, progressBarParent); processViews(playButton, message);
playButton.setTag(message); playButton.setTag(message);
playButton.setOnClickListener(new View.OnClickListener() { playButton.setOnClickListener(new View.OnClickListener() {
@ -794,14 +923,13 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
} }
} }
if (loadFile) { if (loadFile) {
if (!loadingFile.containsKey(fileName)) { if (!FileLoader.Instance.isLoadingFile(fileName)) {
progressByTag.put((Integer)progressBar.getTag(), fileName);
loadingFile.put(fileName, progressBar);
FileLoader.Instance.loadFile(message.messageOwner.media.video, null); FileLoader.Instance.loadFile(message.messageOwner.media.video, null);
progressBar.setProgress(0); } else {
progressBarParent.setVisibility(View.VISIBLE); FileLoader.Instance.cancelLoadFile(message.messageOwner.media.video, null);
playButton.setVisibility(View.INVISIBLE);
} }
checkCurrentFile();
processViews(playButton, message);
} }
} }
}); });
@ -809,12 +937,14 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
if (message.messageOwner.media.video.thumb instanceof TLRPC.TL_photoCachedSize) { if (message.messageOwner.media.video.thumb instanceof TLRPC.TL_photoCachedSize) {
iv.setImageBitmap(message.imagePreview); iv.setImageBitmap(message.imagePreview);
} else { } else {
iv.setImage(message.messageOwner.media.video.thumb.location, null, 0); if (message.messageOwner.media.video.thumb != null) {
iv.setImage(message.messageOwner.media.video.thumb.location, null, 0, message.messageOwner.media.video.thumb.size);
}
} }
} }
} else { } else {
iv.isVideo = false; iv.isVideo = false;
iv.setImage(imagesArrLocations.get(position), null, 0); iv.setImage(imagesArrLocations.get(position), null, 0, -1);
} }
return view; return view;
@ -826,12 +956,6 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
PZSImageView iv = (PZSImageView)((View)view).findViewById(R.id.page_image); PZSImageView iv = (PZSImageView)((View)view).findViewById(R.id.page_image);
FileLoader.Instance.cancelLoadingForImageView(iv); FileLoader.Instance.cancelLoadingForImageView(iv);
iv.clearImage(); iv.clearImage();
final ProgressBar progressBar = (ProgressBar)((View)view).findViewById(R.id.action_progress);
Integer tag = (Integer)progressBar.getTag();
String file = progressByTag.get(tag);
if (file != null) {
loadingFile.remove(file);
}
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -12,10 +12,11 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.internal.view.SupportMenuItem;
import android.support.v7.app.ActionBar;
import android.text.Editable; import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.Spannable; import android.text.Spannable;
@ -23,26 +24,21 @@ import android.text.SpannableString;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.text.style.ImageSpan; import android.text.style.ImageSpan;
import android.view.Display;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Surface; import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.Emoji; import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
@ -64,7 +60,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
private TextView doneTextView; private TextView doneTextView;
private EditText userSelectEditText; private EditText userSelectEditText;
private TextView countTextView; private TextView countTextView;
private View topView;
private boolean ignoreChange = false; private boolean ignoreChange = false;
private HashMap<Integer, Emoji.XImageSpan> selectedContacts = new HashMap<Integer, Emoji.XImageSpan>(); private HashMap<Integer, Emoji.XImageSpan> selectedContacts = new HashMap<Integer, Emoji.XImageSpan>();
@ -114,7 +109,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
epmtyTextView = (TextView)fragmentView.findViewById(R.id.searchEmptyView); epmtyTextView = (TextView)fragmentView.findViewById(R.id.searchEmptyView);
userSelectEditText = (EditText)fragmentView.findViewById(R.id.bubble_input_text); userSelectEditText = (EditText)fragmentView.findViewById(R.id.bubble_input_text);
countTextView = (TextView)fragmentView.findViewById(R.id.bubble_counter_text); countTextView = (TextView)fragmentView.findViewById(R.id.bubble_counter_text);
topView = fragmentView.findViewById(R.id.top_layout);
if (Build.VERSION.SDK_INT >= 11) { if (Build.VERSION.SDK_INT >= 11) {
userSelectEditText.setTextIsSelectable(false); userSelectEditText.setTextIsSelectable(false);
} }
@ -142,7 +136,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
try { try {
deletedString = changeString.toString().substring(afterChangeIndex, beforeChangeIndex); deletedString = changeString.toString().substring(afterChangeIndex, beforeChangeIndex);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
if (deletedString.length() > 0) { if (deletedString.length() > 0) {
if (searching && searchWas) { if (searching && searchWas) {
@ -263,45 +257,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
return fragmentView; return fragmentView;
} }
@Override
public void onConfigurationChanged(android.content.res.Configuration newConfig) {
super.onConfigurationChanged(newConfig);
fixLayout();
}
private void fixLayout() {
if (listView != null) {
ViewTreeObserver obs = listView.getViewTreeObserver();
obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
WindowManager manager = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int rotation = display.getRotation();
int height;
int currentActionBarHeight = parentActivity.getSupportActionBar().getHeight();
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (currentActionBarHeight != 48 * density && currentActionBarHeight != 40 * density) {
height = currentActionBarHeight;
} else {
height = (int)(48.0f * density);
if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) {
height = (int)(40.0f * density);
}
}
LinearLayout.LayoutParams params2 = (LinearLayout.LayoutParams)topView.getLayoutParams();
params2.setMargins(0, height, 0, 0);
topView.setLayoutParams(params2);
listView.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
}
@Override @Override
public void applySelfActionBar() { public void applySelfActionBar() {
if (parentActivity == null) { if (parentActivity == null) {
@ -314,9 +269,9 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
actionBar.setDisplayUseLogoEnabled(false); actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayShowCustomEnabled(false); actionBar.setDisplayShowCustomEnabled(false);
actionBar.setCustomView(null); actionBar.setCustomView(null);
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.NewGroup) + "</font>")); actionBar.setTitle(getStringEntry(R.string.NewGroup));
TextView title = (TextView)parentActivity.findViewById(R.id.abs__action_bar_title); TextView title = (TextView)parentActivity.findViewById(R.id.action_bar_title);
if (title == null) { if (title == null) {
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android"); final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
title = (TextView)parentActivity.findViewById(subtitleId); title = (TextView)parentActivity.findViewById(subtitleId);
@ -330,12 +285,11 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (getSherlockActivity() == null) { if (getActivity() == null) {
return; return;
} }
((ApplicationActivity)parentActivity).showActionBar(); ((ApplicationActivity)parentActivity).showActionBar();
((ApplicationActivity)parentActivity).updateActionBar(); ((ApplicationActivity)parentActivity).updateActionBar();
fixLayout();
} }
public Emoji.XImageSpan createAndPutChipForUser(TLRPC.User user) { public Emoji.XImageSpan createAndPutChipForUser(TLRPC.User user) {
@ -382,7 +336,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
searchDialogsTimer.cancel(); searchDialogsTimer.cancel();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
searchDialogsTimer = new Timer(); searchDialogsTimer = new Timer();
searchDialogsTimer.schedule(new TimerTask() { searchDialogsTimer.schedule(new TimerTask() {
@ -392,7 +346,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
searchDialogsTimer.cancel(); searchDialogsTimer.cancel();
searchDialogsTimer = null; searchDialogsTimer = null;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
processSearch(query); processSearch(query);
} }
@ -454,7 +408,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.group_create_menu, menu); inflater.inflate(R.menu.group_create_menu, menu);
MenuItem doneItem = menu.findItem(R.id.done_menu_item); SupportMenuItem doneItem = (SupportMenuItem)menu.findItem(R.id.done_menu_item);
doneTextView = (TextView)doneItem.getActionView().findViewById(R.id.done_button); doneTextView = (TextView)doneItem.getActionView().findViewById(R.id.done_button);
doneTextView.setOnClickListener(new View.OnClickListener() { doneTextView.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -551,9 +505,9 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
ImageView checkButton = (ImageView)convertView.findViewById(R.id.settings_row_check_button); ImageView checkButton = (ImageView)convertView.findViewById(R.id.settings_row_check_button);
if (selectedContacts.containsKey(user.id)) { if (selectedContacts.containsKey(user.id)) {
checkButton.setImageResource(R.drawable.btn_check_on); checkButton.setImageResource(R.drawable.btn_check_on_old);
} else { } else {
checkButton.setImageResource(R.drawable.btn_check_off); checkButton.setImageResource(R.drawable.btn_check_off_old);
} }
View divider = convertView.findViewById(R.id.settings_row_divider); View divider = convertView.findViewById(R.id.settings_row_divider);
@ -565,7 +519,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
if (searchWas && searching) { if (searchWas && searching) {
holder.nameTextView.setText(searchResultNames.get(position)); holder.nameTextView.setText(searchResultNames.get(position));
holder.nameTextView.setTypeface(null);
} else { } else {
if (user.first_name.length() != 0 && user.last_name.length() != 0) { if (user.first_name.length() != 0 && user.last_name.length() != 0) {
holder.nameTextView.setText(Html.fromHtml(user.first_name + " <b>" + user.last_name + "</b>")); holder.nameTextView.setText(Html.fromHtml(user.first_name + " <b>" + user.last_name + "</b>"));
@ -574,8 +527,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
} else { } else {
holder.nameTextView.setText(Html.fromHtml("<b>" + user.last_name + "</b>")); holder.nameTextView.setText(Html.fromHtml("<b>" + user.last_name + "</b>"));
} }
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
holder.nameTextView.setTypeface(typeface);
} }
TLRPC.FileLocation photo = null; TLRPC.FileLocation photo = null;
@ -591,7 +542,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
} else { } else {
int currentTime = ConnectionsManager.Instance.getCurrentTime(); int currentTime = ConnectionsManager.Instance.getCurrentTime();
if (user.status.expires > currentTime || user.status.was_online > currentTime) { if (user.status.expires > currentTime || user.status.was_online > currentTime) {
holder.messageTextView.setTextColor(0xff006fc8); holder.messageTextView.setTextColor(0xff357aa8);
holder.messageTextView.setText(getStringEntry(R.string.Online)); holder.messageTextView.setText(getStringEntry(R.string.Online));
} else { } else {
if (user.status.was_online <= 10000 && user.status.expires <= 10000) { if (user.status.was_online <= 10000 && user.status.expires <= 10000) {

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -12,28 +12,23 @@ import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.internal.view.SupportMenuItem;
import android.support.v7.app.ActionBar;
import android.text.Html; import android.text.Html;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Surface; import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
@ -50,11 +45,10 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
private PinnedHeaderListView listView; private PinnedHeaderListView listView;
private TextView nameTextView; private TextView nameTextView;
private TLRPC.FileLocation avatar; private TLRPC.FileLocation avatar;
private TLRPC.TL_inputFile uploadedAvatar; private TLRPC.InputFile uploadedAvatar;
private ArrayList<Integer> selectedContacts; private ArrayList<Integer> selectedContacts;
private BackupImageView avatarImage; private BackupImageView avatarImage;
private boolean createAfterUpload; private boolean createAfterUpload;
private View topView;
private boolean donePressed; private boolean donePressed;
private AvatarUpdater avatarUpdater = new AvatarUpdater(); private AvatarUpdater avatarUpdater = new AvatarUpdater();
@ -116,7 +110,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
} else if (i == 2) { } else if (i == 2) {
avatar = null; avatar = null;
uploadedAvatar = null; uploadedAvatar = null;
avatarImage.setImage(avatar, "50_50", R.drawable.group_placeholder_blue); avatarImage.setImage(avatar, "50_50", R.drawable.group_blue);
} }
} }
}); });
@ -125,7 +119,6 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
}); });
avatarImage = (BackupImageView)fragmentView.findViewById(R.id.settings_avatar_image); avatarImage = (BackupImageView)fragmentView.findViewById(R.id.settings_avatar_image);
topView = fragmentView.findViewById(R.id.top_layout);
nameTextView = (EditText)fragmentView.findViewById(R.id.bubble_input_text); nameTextView = (EditText)fragmentView.findViewById(R.id.bubble_input_text);
listView = (PinnedHeaderListView)fragmentView.findViewById(R.id.listView); listView = (PinnedHeaderListView)fragmentView.findViewById(R.id.listView);
@ -139,45 +132,6 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
return fragmentView; return fragmentView;
} }
@Override
public void onConfigurationChanged(android.content.res.Configuration newConfig) {
super.onConfigurationChanged(newConfig);
fixLayout();
}
private void fixLayout() {
if (listView != null) {
ViewTreeObserver obs = listView.getViewTreeObserver();
obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
WindowManager manager = (WindowManager)parentActivity.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int rotation = display.getRotation();
int height;
int currentActionBarHeight = parentActivity.getSupportActionBar().getHeight();
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (currentActionBarHeight != 48 * density && currentActionBarHeight != 40 * density) {
height = currentActionBarHeight;
} else {
height = (int)(48.0f * density);
if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) {
height = (int)(40.0f * density);
}
}
LinearLayout.LayoutParams params2 = (LinearLayout.LayoutParams)topView.getLayoutParams();
params2.setMargins(0, height, 0, 0);
topView.setLayoutParams(params2);
listView.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
}
@Override @Override
public void applySelfActionBar() { public void applySelfActionBar() {
if (parentActivity == null) { if (parentActivity == null) {
@ -190,9 +144,9 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
actionBar.setDisplayUseLogoEnabled(false); actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayShowCustomEnabled(false); actionBar.setDisplayShowCustomEnabled(false);
actionBar.setCustomView(null); actionBar.setCustomView(null);
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.NewGroup) + "</font>")); actionBar.setTitle(getStringEntry(R.string.NewGroup));
TextView title = (TextView)parentActivity.findViewById(R.id.abs__action_bar_title); TextView title = (TextView)parentActivity.findViewById(R.id.action_bar_title);
if (title == null) { if (title == null) {
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android"); final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
title = (TextView)parentActivity.findViewById(subtitleId); title = (TextView)parentActivity.findViewById(subtitleId);
@ -206,24 +160,23 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (getSherlockActivity() == null) { if (getActivity() == null) {
return; return;
} }
((ApplicationActivity)parentActivity).showActionBar(); ((ApplicationActivity)parentActivity).showActionBar();
((ApplicationActivity)parentActivity).updateActionBar(); ((ApplicationActivity)parentActivity).updateActionBar();
fixLayout();
} }
@Override @Override
public void didUploadedPhoto(final TLRPC.TL_inputFile file, final TLRPC.PhotoSize small, final TLRPC.PhotoSize big) { public void didUploadedPhoto(final TLRPC.InputFile file, final TLRPC.PhotoSize small, final TLRPC.PhotoSize big) {
Utilities.RunOnUIThread(new Runnable() { Utilities.RunOnUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
uploadedAvatar = file; uploadedAvatar = file;
avatar = small.location; avatar = small.location;
avatarImage.setImage(avatar, "50_50", R.drawable.group_placeholder_blue); avatarImage.setImage(avatar, "50_50", R.drawable.group_blue);
if (createAfterUpload) { if (createAfterUpload) {
Log.e("tmessages", "avatar did uploaded"); FileLog.e("tmessages", "avatar did uploaded");
MessagesController.Instance.createChat(nameTextView.getText().toString(), selectedContacts, uploadedAvatar); MessagesController.Instance.createChat(nameTextView.getText().toString(), selectedContacts, uploadedAvatar);
} }
} }
@ -250,7 +203,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.group_create_menu, menu); inflater.inflate(R.menu.group_create_menu, menu);
MenuItem doneItem = menu.findItem(R.id.done_menu_item); SupportMenuItem doneItem = (SupportMenuItem)menu.findItem(R.id.done_menu_item);
TextView doneTextView = (TextView)doneItem.getActionView().findViewById(R.id.done_button); TextView doneTextView = (TextView)doneItem.getActionView().findViewById(R.id.done_button);
doneTextView.setOnClickListener(new View.OnClickListener() { doneTextView.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -281,7 +234,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
} else if (id == MessagesController.chatDidFailCreate) { } else if (id == MessagesController.chatDidFailCreate) {
Utilities.HideProgressDialog(parentActivity); Utilities.HideProgressDialog(parentActivity);
donePressed = false; donePressed = false;
Log.e("tmessages", "did fail create"); FileLog.e("tmessages", "did fail create chat");
} else if (id == MessagesController.chatDidCreated) { } else if (id == MessagesController.chatDidCreated) {
Utilities.RunOnUIThread(new Runnable() { Utilities.RunOnUIThread(new Runnable() {
@Override @Override
@ -291,7 +244,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt("chat_id", (Integer)args[0]); bundle.putInt("chat_id", (Integer)args[0]);
fragment.setArguments(bundle); fragment.setArguments(bundle);
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat_group_" + args[0], true, false); ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), true, false);
} }
}); });
} }
@ -331,6 +284,9 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
@Override @Override
public int getCountForSection(int section) { public int getCountForSection(int section) {
if (selectedContacts == null) {
return 0;
}
return selectedContacts.size(); return selectedContacts.size();
} }
@ -346,8 +302,6 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
if (holder == null) { if (holder == null) {
holder = new ContactsActivity.ContactListRowHolder(convertView); holder = new ContactsActivity.ContactListRowHolder(convertView);
convertView.setTag(holder); convertView.setTag(holder);
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
holder.nameTextView.setTypeface(typeface);
} }
View divider = convertView.findViewById(R.id.settings_row_divider); View divider = convertView.findViewById(R.id.settings_row_divider);
@ -378,7 +332,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
} else { } else {
int currentTime = ConnectionsManager.Instance.getCurrentTime(); int currentTime = ConnectionsManager.Instance.getCurrentTime();
if (user.status.expires > currentTime || user.status.was_online > currentTime) { if (user.status.expires > currentTime || user.status.was_online > currentTime) {
holder.messageTextView.setTextColor(0xff006fc8); holder.messageTextView.setTextColor(0xff357aa8);
holder.messageTextView.setText(getStringEntry(R.string.Online)); holder.messageTextView.setText(getStringEntry(R.string.Online));
} else { } else {
if (user.status.was_online <= 10000 && user.status.expires <= 10000) { if (user.status.was_online <= 10000 && user.status.expires <= 10000) {

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -9,11 +9,11 @@
package org.telegram.ui; package org.telegram.ui;
import android.content.Context; import android.content.Context;
import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.text.Html; import android.text.Html;
import android.view.Display;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.Surface; import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -22,12 +22,9 @@ import android.view.WindowManager;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Views.BaseFragment; import org.telegram.ui.Views.BaseFragment;
import org.telegram.ui.Views.IdenticonView; import org.telegram.ui.Views.IdenticonView;
@ -57,8 +54,6 @@ public class IdenticonActivity extends BaseFragment {
fragmentView = inflater.inflate(R.layout.identicon_layout, container, false); fragmentView = inflater.inflate(R.layout.identicon_layout, container, false);
IdenticonView identiconView = (IdenticonView) fragmentView.findViewById(R.id.identicon_view); IdenticonView identiconView = (IdenticonView) fragmentView.findViewById(R.id.identicon_view);
TextView textView = (TextView)fragmentView.findViewById(R.id.identicon_text); TextView textView = (TextView)fragmentView.findViewById(R.id.identicon_text);
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
textView.setTypeface(typeface);
TLRPC.EncryptedChat encryptedChat = MessagesController.Instance.encryptedChats.get(chat_id); TLRPC.EncryptedChat encryptedChat = MessagesController.Instance.encryptedChats.get(chat_id);
if (encryptedChat != null) { if (encryptedChat != null) {
identiconView.setBytes(encryptedChat.auth_key); identiconView.setBytes(encryptedChat.auth_key);
@ -87,15 +82,15 @@ public class IdenticonActivity extends BaseFragment {
actionBar.setDisplayShowCustomEnabled(false); actionBar.setDisplayShowCustomEnabled(false);
actionBar.setSubtitle(null); actionBar.setSubtitle(null);
actionBar.setCustomView(null); actionBar.setCustomView(null);
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.EncryptionKey) + "</font>")); actionBar.setTitle(getStringEntry(R.string.EncryptionKey));
TextView title = (TextView)parentActivity.findViewById(R.id.abs__action_bar_title); TextView title = (TextView)parentActivity.findViewById(R.id.action_bar_title);
if (title == null) { if (title == null) {
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android"); final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
title = (TextView)parentActivity.findViewById(subtitleId); title = (TextView)parentActivity.findViewById(subtitleId);
} }
if (title != null) { if (title != null) {
title.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_blue, 0, 0, 0); title.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_white, 0, 0, 0);
title.setCompoundDrawablePadding((int)(4 * getResources().getDisplayMetrics().density)); title.setCompoundDrawablePadding((int)(4 * getResources().getDisplayMetrics().density));
} }
} }
@ -112,7 +107,7 @@ public class IdenticonActivity extends BaseFragment {
if (isFinish) { if (isFinish) {
return; return;
} }
if (getSherlockActivity() == null) { if (getActivity() == null) {
return; return;
} }
((ApplicationActivity)parentActivity).showActionBar(); ((ApplicationActivity)parentActivity).showActionBar();
@ -129,36 +124,25 @@ public class IdenticonActivity extends BaseFragment {
public boolean onPreDraw() { public boolean onPreDraw() {
LinearLayout layout = (LinearLayout)fragmentView; LinearLayout layout = (LinearLayout)fragmentView;
WindowManager manager = (WindowManager)parentActivity.getSystemService(Context.WINDOW_SERVICE); WindowManager manager = (WindowManager)parentActivity.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay(); int rotation = manager.getDefaultDisplay().getRotation();
int rotation = display.getRotation();
int height;
int currentActionBarHeight = parentActivity.getSupportActionBar().getHeight();
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
if (currentActionBarHeight != 48 * density && currentActionBarHeight != 40 * density) {
height = currentActionBarHeight;
} else {
height = (int)(48.0f * density);
if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) {
height = (int)(40.0f * density);
layout.setOrientation(LinearLayout.HORIZONTAL);
}
}
if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) {
layout.setOrientation(LinearLayout.HORIZONTAL); layout.setOrientation(LinearLayout.HORIZONTAL);
} else { } else {
layout.setOrientation(LinearLayout.VERTICAL); layout.setOrientation(LinearLayout.VERTICAL);
} }
v.setPadding(v.getPaddingLeft(), height, v.getPaddingRight(), v.getPaddingBottom()); v.setPadding(v.getPaddingLeft(), 0, v.getPaddingRight(), v.getPaddingBottom());
v.getViewTreeObserver().removeOnPreDrawListener(this); v.getViewTreeObserver().removeOnPreDrawListener(this);
TextView title = (TextView)parentActivity.findViewById(R.id.abs__action_bar_title); TextView title = (TextView)parentActivity.findViewById(R.id.action_bar_title);
if (title == null) { if (title == null) {
final int subtitleId = ApplicationLoader.applicationContext.getResources().getIdentifier("action_bar_title", "id", "android"); final int subtitleId = ApplicationLoader.applicationContext.getResources().getIdentifier("action_bar_title", "id", "android");
title = (TextView)parentActivity.findViewById(subtitleId); title = (TextView)parentActivity.findViewById(subtitleId);
} }
if (title != null) { if (title != null) {
title.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_blue, 0, 0, 0); title.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_white, 0, 0, 0);
title.setCompoundDrawablePadding((int)(4 * density)); title.setCompoundDrawablePadding((int)(4 * density));
} }
@ -169,7 +153,7 @@ public class IdenticonActivity extends BaseFragment {
} }
@Override @Override
public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId(); int itemId = item.getItemId();
switch (itemId) { switch (itemId) {
case android.R.id.home: case android.R.id.home:

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -8,59 +8,38 @@
package org.telegram.ui; package org.telegram.ui;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.v4.view.PagerAdapter; import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.text.Html; import android.text.Html;
import android.view.Display;
import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import java.util.Locale; import java.util.Locale;
public class IntroActivity extends SherlockFragmentActivity { public class IntroActivity extends ActionBarActivity {
private ViewPager viewPager; private ViewPager viewPager;
private ImageView topImage1; private ImageView topImage1;
private ImageView topImage2; private ImageView topImage2;
private View slidingView;
private View parentSlidingView;
private TextView startMessagingButton; private TextView startMessagingButton;
private ViewGroup bottomPages;
private int lastPage = 0; private int lastPage = 0;
private float density = 1; private float density = 1;
private boolean isRTL = false; private boolean isRTL = false;
private boolean justCreated = false; private boolean justCreated = false;
private boolean startPressed = false; private boolean startPressed = false;
private int[][] colors2 = new int[][] {
new int[] {179, 179, 179},
new int[] {247, 91, 47},
new int[] {249, 145, 23},
new int[] {250, 200, 0},
new int[] {93, 195, 38},
new int[] {47, 146, 232}
};
private int[] icons; private int[] icons;
private int[] titles; private int[] titles;
private int[] messages; private int[] messages;
int fixedFirstNum1;
int fixedFirstNum2;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -73,14 +52,16 @@ public class IntroActivity extends SherlockFragmentActivity {
if (lang != null && lang.toLowerCase().equals("ar")) { if (lang != null && lang.toLowerCase().equals("ar")) {
isRTL = true; isRTL = true;
icons = new int[] { icons = new int[] {
R.drawable.icon5, R.drawable.intro7,
R.drawable.icon4, R.drawable.intro6,
R.drawable.icon3, R.drawable.intro5,
R.drawable.icon2, R.drawable.intro4,
R.drawable.icon1, R.drawable.intro3,
R.drawable.icon0 R.drawable.intro2,
R.drawable.intro1
}; };
titles = new int[] { titles = new int[] {
R.string.Page7Title,
R.string.Page6Title, R.string.Page6Title,
R.string.Page5Title, R.string.Page5Title,
R.string.Page4Title, R.string.Page4Title,
@ -89,6 +70,7 @@ public class IntroActivity extends SherlockFragmentActivity {
R.string.Page1Title R.string.Page1Title
}; };
messages = new int[] { messages = new int[] {
R.string.Page7Message,
R.string.Page6Message, R.string.Page6Message,
R.string.Page5Message, R.string.Page5Message,
R.string.Page4Message, R.string.Page4Message,
@ -96,16 +78,15 @@ public class IntroActivity extends SherlockFragmentActivity {
R.string.Page2Message, R.string.Page2Message,
R.string.Page1Message R.string.Page1Message
}; };
fixedFirstNum1 = 5;
fixedFirstNum2 = 4;
} else { } else {
icons = new int[] { icons = new int[] {
R.drawable.icon0, R.drawable.intro1,
R.drawable.icon1, R.drawable.intro2,
R.drawable.icon2, R.drawable.intro3,
R.drawable.icon3, R.drawable.intro4,
R.drawable.icon4, R.drawable.intro5,
R.drawable.icon5 R.drawable.intro6,
R.drawable.intro7
}; };
titles = new int[] { titles = new int[] {
R.string.Page1Title, R.string.Page1Title,
@ -113,7 +94,8 @@ public class IntroActivity extends SherlockFragmentActivity {
R.string.Page3Title, R.string.Page3Title,
R.string.Page4Title, R.string.Page4Title,
R.string.Page5Title, R.string.Page5Title,
R.string.Page6Title R.string.Page6Title,
R.string.Page7Title
}; };
messages = new int[] { messages = new int[] {
R.string.Page1Message, R.string.Page1Message,
@ -121,18 +103,16 @@ public class IntroActivity extends SherlockFragmentActivity {
R.string.Page3Message, R.string.Page3Message,
R.string.Page4Message, R.string.Page4Message,
R.string.Page5Message, R.string.Page5Message,
R.string.Page6Message R.string.Page6Message,
R.string.Page7Message
}; };
fixedFirstNum1 = 0;
fixedFirstNum2 = 1;
} }
density = getResources().getDisplayMetrics().density; density = getResources().getDisplayMetrics().density;
viewPager = (ViewPager)findViewById(R.id.intro_view_pager); viewPager = (ViewPager)findViewById(R.id.intro_view_pager);
slidingView = findViewById(R.id.sliding_view);
parentSlidingView = findViewById(R.id.parent_slinding_view);
startMessagingButton = (TextView)findViewById(R.id.start_messaging_button); startMessagingButton = (TextView)findViewById(R.id.start_messaging_button);
topImage1 = (ImageView)findViewById(R.id.icon_image1); topImage1 = (ImageView)findViewById(R.id.icon_image1);
topImage2 = (ImageView)findViewById(R.id.icon_image2); topImage2 = (ImageView)findViewById(R.id.icon_image2);
bottomPages = (ViewGroup)findViewById(R.id.bottom_pages);
topImage2.setVisibility(View.GONE); topImage2.setVisibility(View.GONE);
viewPager.setAdapter(new IntroAdapter()); viewPager.setAdapter(new IntroAdapter());
viewPager.setPageMargin(0); viewPager.setPageMargin(0);
@ -140,7 +120,7 @@ public class IntroActivity extends SherlockFragmentActivity {
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
updateColors(position, positionOffset);
} }
@Override @Override
@ -230,7 +210,6 @@ public class IntroActivity extends SherlockFragmentActivity {
justCreated = true; justCreated = true;
getSupportActionBar().hide(); getSupportActionBar().hide();
fixLayout();
} }
@Override @Override
@ -238,8 +217,8 @@ public class IntroActivity extends SherlockFragmentActivity {
super.onResume(); super.onResume();
if (justCreated) { if (justCreated) {
if (isRTL) { if (isRTL) {
viewPager.setCurrentItem(5); viewPager.setCurrentItem(6);
lastPage = 5; lastPage = 6;
} else { } else {
viewPager.setCurrentItem(0); viewPager.setCurrentItem(0);
lastPage = 0; lastPage = 0;
@ -248,94 +227,17 @@ public class IntroActivity extends SherlockFragmentActivity {
} }
} }
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
fixLayout();
}
private void fixLayout() {
viewPager.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
WindowManager manager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int rotation = display.getRotation();
density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)parentSlidingView.getLayoutParams();
FrameLayout.LayoutParams buttonParams = (FrameLayout.LayoutParams)startMessagingButton.getLayoutParams();
if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) {
params.setMargins(params.leftMargin, params.topMargin, params.rightMargin, (int)(50 * density));
buttonParams.height = (int)(density * 52);
} else {
params.setMargins(params.leftMargin, params.topMargin, params.rightMargin, (int)(82 * density));
buttonParams.height = (int)(density * 84);
}
parentSlidingView.setLayoutParams(params);
startMessagingButton.setLayoutParams(buttonParams);
updateColors(viewPager.getCurrentItem(), 0);
viewPager.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
private void updateColors(int position, float positionOffset) {
int colorPosition = position;
int nextColorPosition = colorPosition + 1;
float offset = positionOffset;
if (isRTL) {
colorPosition = 5 - position;
if (positionOffset != 0) {
colorPosition--;
offset = 1 - offset;
}
nextColorPosition = colorPosition + 1;
}
if (colorPosition >= 0) {
int r = colors2[colorPosition][0];
int g = colors2[colorPosition][1];
int b = colors2[colorPosition][2];
if (nextColorPosition < colors2.length && nextColorPosition > 0 && offset != 0) {
r += (colors2[nextColorPosition][0] - colors2[colorPosition][0]) * offset;
g += (colors2[nextColorPosition][1] - colors2[colorPosition][1]) * offset;
b += (colors2[nextColorPosition][2] - colors2[colorPosition][2]) * offset;
}
slidingView.setBackgroundColor(colorFromRGB(r, g, b));
}
int width = parentSlidingView.getWidth() / 6;
FrameLayout.LayoutParams parentParams = (FrameLayout.LayoutParams)parentSlidingView.getLayoutParams();
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)slidingView.getLayoutParams();
int posX = (int)(24 * density + position * width + positionOffset * width);
if (position >= colors2.length - 2) {
int missed = parentSlidingView.getWidth() - width * 6;
posX += missed * (position == colors2.length - 2 ? positionOffset : 1);
}
params.width = width;
params.setMargins(posX, params.topMargin, params.rightMargin, parentParams.bottomMargin);
slidingView.setLayoutParams(params);
}
private int colorFromRGB(int red, int green, int blue) {
return 0xff000000 | red << 16 | green << 8 | blue;
}
private class IntroAdapter extends PagerAdapter { private class IntroAdapter extends PagerAdapter {
@Override @Override
public int getCount() { public int getCount() {
return 6; return 7;
} }
@Override @Override
public Object instantiateItem(ViewGroup container, int position) { public Object instantiateItem(ViewGroup container, int position) {
View view = View.inflate(container.getContext(), R.layout.intro_view_layout, null); View view = View.inflate(container.getContext(), R.layout.intro_view_layout, null);
TextView headerTextView = (TextView)view.findViewById(R.id.header_text); TextView headerTextView = (TextView)view.findViewById(R.id.header_text);
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
headerTextView.setTypeface(typeface);
TextView messageTextView = (TextView)view.findViewById(R.id.message_text); TextView messageTextView = (TextView)view.findViewById(R.id.message_text);
messageTextView.setTypeface(typeface);
container.addView(view, 0); container.addView(view, 0);
headerTextView.setText(getString(titles[position])); headerTextView.setText(getString(titles[position]));
@ -352,6 +254,15 @@ public class IntroActivity extends SherlockFragmentActivity {
@Override @Override
public void setPrimaryItem(ViewGroup container, int position, Object object) { public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object); super.setPrimaryItem(container, position, object);
int count = bottomPages.getChildCount();
for (int a = 0; a < count; a++) {
View child = bottomPages.getChildAt(a);
if (a == position) {
child.setBackgroundColor(0xff2ca5e0);
} else {
child.setBackgroundColor(0xffbbbbbb);
}
}
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -16,6 +16,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
@ -104,7 +105,7 @@ public class LaunchActivity extends PausableActivity {
NotificationManager mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(1); mNotificationManager.cancel(1);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* This is the source code of Telegram for Android v. 1.2.3. * This is the source code of Telegram for Android v. 1.3.2.
* It is licensed under GNU GPL v. 2 or later. * It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE). * You should have received a copy of the license in this archive (see LICENSE).
* *
@ -13,16 +13,15 @@ import android.location.Location;
import android.location.LocationListener; import android.location.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.text.Html; import android.support.v7.app.ActionBar;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap;
@ -33,6 +32,7 @@ import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.MarkerOptions;
import org.telegram.TL.TLRPC; import org.telegram.TL.TLRPC;
import org.telegram.messenger.FileLog;
import org.telegram.objects.MessageObject; import org.telegram.objects.MessageObject;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
@ -177,7 +177,7 @@ public class LocationActivity extends BaseFragment implements LocationListener,
if (parentActivity == null) { if (parentActivity == null) {
return; return;
} }
final ActionBar actionBar = parentActivity.getSupportActionBar(); ActionBar actionBar = parentActivity.getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(true); actionBar.setDisplayShowTitleEnabled(true);
actionBar.setDisplayShowHomeEnabled(false); actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true);
@ -186,12 +186,12 @@ public class LocationActivity extends BaseFragment implements LocationListener,
actionBar.setDisplayShowCustomEnabled(false); actionBar.setDisplayShowCustomEnabled(false);
actionBar.setCustomView(null); actionBar.setCustomView(null);
if (messageObject != null) { if (messageObject != null) {
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.ChatLocation) + "</font>")); actionBar.setTitle(getStringEntry(R.string.ChatLocation));
} else { } else {
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.ShareLocation) + "</font>")); actionBar.setTitle(getStringEntry(R.string.ShareLocation));
} }
TextView title = (TextView)parentActivity.findViewById(R.id.abs__action_bar_title); TextView title = (TextView)parentActivity.findViewById(R.id.action_bar_title);
if (title == null) { if (title == null) {
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android"); final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
title = (TextView)parentActivity.findViewById(subtitleId); title = (TextView)parentActivity.findViewById(subtitleId);
@ -205,7 +205,7 @@ public class LocationActivity extends BaseFragment implements LocationListener,
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (getSherlockActivity() == null) { if (getActivity() == null) {
return; return;
} }
((ApplicationActivity)parentActivity).showActionBar(); ((ApplicationActivity)parentActivity).showActionBar();
@ -319,7 +319,7 @@ public class LocationActivity extends BaseFragment implements LocationListener,
} }
positionMarker(location); positionMarker(location);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); FileLog.e("tmessages", e);
} }
} }

Some files were not shown because too many files have changed in this diff Show More