update to 1.3.2
This commit is contained in:
parent
90d8e8a370
commit
d52ade4855
@ -1,6 +1,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">
|
||||
<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 />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||
|
@ -3,10 +3,10 @@
|
||||
<component name="FacetManager">
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="Debug" />
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebug" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleTest" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
|
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
@ -26,37 +26,37 @@
|
||||
<output url="file://$MODULE_DIR$/build/classes/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/r/test" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/test" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/r/test/debug" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test/debug" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test/debug" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test/debug" 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/assets" 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/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<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/assets" 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/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<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/assets" 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/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" type="java-test-resource" />
|
||||
<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/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/bundles" />
|
||||
@ -65,16 +65,17 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/libs" />
|
||||
<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/tmp" />
|
||||
</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="library" exported="" name="support-v4-18.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="ComGoogleAndroidGmsPlayServices3159.aar" level="project" />
|
||||
<orderEntry type="library" exported="" name="HockeySDK-3.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="HockeySDK-3.0.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="ComGoogleAndroidGmsPlayServices4030.aar" 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>
|
||||
</module>
|
||||
|
||||
|
@ -3,7 +3,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:0.5.+'
|
||||
classpath 'com.android.tools.build:gradle:0.7.+'
|
||||
}
|
||||
}
|
||||
apply plugin: 'android'
|
||||
@ -22,25 +22,49 @@ task nativeLibsToJar(
|
||||
into 'lib/'
|
||||
}
|
||||
|
||||
tasks.withType(Compile) {
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
tasks.withType(Compile) {
|
||||
tasks.withType(JavaCompile) {
|
||||
compileTask -> compileTask.dependsOn(nativeLibsToJar)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
|
||||
compile 'com.google.android.gms:play-services:4.0.+'
|
||||
compile 'net.hockeyapp.android:HockeySDK:3.0.1'
|
||||
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 {
|
||||
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 {
|
||||
minSdkVersion 8
|
||||
|
@ -1,10 +1,11 @@
|
||||
NDK_TOOLCHAIN_VERSION := 4.8
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := tmessages
|
||||
LOCAL_CFLAGS = -w
|
||||
LOCAL_MODULE := tmessages
|
||||
LOCAL_CFLAGS = -w -std=gnu99 -O3
|
||||
LOCAL_LDLIBS := -llog
|
||||
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
./aes_core.c \
|
||||
./aes_ige.c \
|
||||
@ -15,5 +16,6 @@ LOCAL_SRC_FILES := \
|
||||
./org_telegram_SQLite_SQLiteDatabase.c \
|
||||
./org_telegram_SQLite_SQLitePreparedStatement.c \
|
||||
./org_telegram_SQLite.c
|
||||
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
@ -1,2 +1,2 @@
|
||||
APP_PLATFORM := android-8
|
||||
APP_ABI := armeabi armeabi-v7a x86 mips
|
||||
APP_PLATFORM := android-9
|
||||
APP_ABI := armeabi armeabi-v7a x86
|
128
TMessagesProj/jni/build_ffmpeg_android.sh
Executable file
128
TMessagesProj/jni/build_ffmpeg_android.sh
Executable 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
|
||||
|
@ -5,12 +5,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <android/log.h>
|
||||
#include "aes.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__)
|
||||
#include "log.h"
|
||||
|
||||
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);
|
||||
@ -84,100 +79,3 @@ JNIEXPORT jlong Java_org_telegram_messenger_Utilities_doPQNative(JNIEnv* env, jc
|
||||
}
|
||||
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
12
TMessagesProj/jni/log.h
Normal 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
|
@ -18,8 +18,15 @@ void Java_org_telegram_SQLite_SQLiteDatabase_commitTransaction(JNIEnv *env, jobj
|
||||
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 *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;
|
||||
int err = sqlite3_open(fileNameStr, &handle);
|
||||
if (SQLITE_OK != err) {
|
||||
@ -28,5 +35,8 @@ int Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object,
|
||||
if (fileNameStr != 0) {
|
||||
(*env)->ReleaseStringUTFChars(env, fileName, fileNameStr);
|
||||
}
|
||||
if (tempDirStr != 0) {
|
||||
(*env)->ReleaseStringUTFChars(env, tempDir, tempDirStr);
|
||||
}
|
||||
return (int)handle;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -107,9 +107,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.7.17"
|
||||
#define SQLITE_VERSION_NUMBER 3007017
|
||||
#define SQLITE_SOURCE_ID "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668"
|
||||
#define SQLITE_VERSION "3.8.1"
|
||||
#define SQLITE_VERSION_NUMBER 3008001
|
||||
#define SQLITE_SOURCE_ID "2013-10-17 12:57:35 c78be6d786c19073b3a6730dfe3fb1be54f5657a"
|
||||
|
||||
/*
|
||||
** 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_DELETE_NOENT (SQLITE_IOERR | (23<<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_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_ISDIR (SQLITE_CANTOPEN | (2<<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_READONLY_RECOVERY (SQLITE_READONLY | (1<<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_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
|
||||
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
|
||||
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags For File Open Operations
|
||||
@ -1612,27 +1617,27 @@ struct sqlite3_mem_methods {
|
||||
** function must be threadsafe. </dd>
|
||||
**
|
||||
** [[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
|
||||
** 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
|
||||
** 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
|
||||
** 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
|
||||
** 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
|
||||
** [SQLITE_USE_URI] symbol defined.
|
||||
** [SQLITE_USE_URI] symbol defined.)^
|
||||
**
|
||||
** [[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
|
||||
** 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"
|
||||
** if that compile-time option is omitted.
|
||||
** The ability to disable the use of covering indices for full table scans
|
||||
** 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
|
||||
** without change even with newer versions of SQLite.
|
||||
**
|
||||
@ -1661,16 +1666,16 @@ struct sqlite3_mem_methods {
|
||||
**
|
||||
** [[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
|
||||
** [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
|
||||
** [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
|
||||
** exceed the compile-time maximum mmap size set by the
|
||||
** [SQLITE_MAX_MMAP_SIZE] compile-time option.
|
||||
** If either argument to this option is negative, then that argument is
|
||||
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
|
||||
** ^If either argument to this option is negative, then that argument is
|
||||
** changed to its compile-time default.
|
||||
** </dl>
|
||||
*/
|
||||
@ -2557,9 +2562,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
|
||||
** interface is to keep a GUI updated during a large query.
|
||||
**
|
||||
** ^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
|
||||
** 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
|
||||
** [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
|
||||
**
|
||||
** 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
|
||||
** multiple invocations of the same SQL function during query execution, under
|
||||
** some circumstances the associated metadata may be preserved. This may
|
||||
** be used, for example, to add a regular-expression matching scalar
|
||||
** function. The compiled version of the regular expression is stored as
|
||||
** metadata associated with the SQL value passed as the regular expression
|
||||
** pattern. The compiled regular expression can be reused on multiple
|
||||
** invocations of the same function so that the original pattern string
|
||||
** does not need to be recompiled on each invocation.
|
||||
** some circumstances the associated metadata may be preserved. An example
|
||||
** of where this might be useful is in a regular-expression matching
|
||||
** function. The compiled version of the regular expression can be stored as
|
||||
** metadata associated with the pattern string.
|
||||
** Then as long as the pattern string remains the same,
|
||||
** the compiled regular expression can be reused on multiple
|
||||
** invocations of the same function.
|
||||
**
|
||||
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
|
||||
** associated by the sqlite3_set_auxdata() function with the Nth argument
|
||||
** value to the application-defined function. ^If no metadata has been ever
|
||||
** been set for the Nth argument of the function, or if the corresponding
|
||||
** function parameter has changed since the meta-data was set,
|
||||
** then sqlite3_get_auxdata() returns a NULL pointer.
|
||||
** value to the application-defined function. ^If there is no metadata
|
||||
** associated with the function argument, this sqlite3_get_auxdata() interface
|
||||
** returns a NULL pointer.
|
||||
**
|
||||
** ^The sqlite3_set_auxdata() interface saves the metadata
|
||||
** pointed to by its 3rd parameter as the metadata for the N-th
|
||||
** argument of the application-defined function. Subsequent
|
||||
** calls to sqlite3_get_auxdata() might return this data, if it has
|
||||
** not been destroyed.
|
||||
** ^If it is not NULL, SQLite will invoke the destructor
|
||||
** function given by the 4th parameter to sqlite3_set_auxdata() on
|
||||
** the metadata when the corresponding function parameter changes
|
||||
** or when the SQL statement completes, whichever comes first.
|
||||
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
|
||||
** argument of the application-defined function. ^Subsequent
|
||||
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
|
||||
** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
|
||||
** NULL if the metadata has been discarded.
|
||||
** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
|
||||
** SQLite will invoke the destructor function X with parameter P exactly
|
||||
** once, when the metadata is discarded.
|
||||
** 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
|
||||
** parameter of any function at any time. ^The only guarantee is that
|
||||
** the destructor will be called before the metadata is dropped.
|
||||
** Note the last bullet in particular. The destructor X in
|
||||
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
|
||||
** 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
|
||||
** expressions that are constant at compile time. This includes literal
|
||||
** values and [parameters].)^
|
||||
** function parameters that are compile-time constants, including literal
|
||||
** values and [parameters] and expressions composed from the same.)^
|
||||
**
|
||||
** These routines must be called from the same thread in which
|
||||
** the SQL function is running.
|
||||
@ -4518,6 +4532,11 @@ SQLITE_API int sqlite3_key(
|
||||
sqlite3 *db, /* Database to be rekeyed */
|
||||
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
|
||||
@ -4531,6 +4550,11 @@ SQLITE_API int sqlite3_rekey(
|
||||
sqlite3 *db, /* Database to be rekeyed */
|
||||
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
|
||||
@ -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
|
||||
** 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));
|
||||
|
||||
/*
|
||||
** 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
|
||||
**
|
||||
@ -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
|
||||
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
|
||||
** </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>
|
||||
*/
|
||||
#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_MISS 8
|
||||
#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
|
||||
** improvement performance by adding permanent indices that do not
|
||||
** 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>
|
||||
*/
|
||||
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
|
||||
#define SQLITE_STMTSTATUS_SORT 2
|
||||
#define SQLITE_STMTSTATUS_AUTOINDEX 3
|
||||
#define SQLITE_STMTSTATUS_VM_STEP 4
|
||||
|
||||
/*
|
||||
** CAPI3REF: Custom Page Cache Object
|
||||
@ -7181,7 +7235,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
#ifdef __cplusplus
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
#endif
|
||||
#endif /* _SQLITE3_H_ */
|
||||
|
||||
/*
|
||||
** 2010 August 30
|
||||
|
@ -474,11 +474,14 @@ struct sqlite3_api_routines {
|
||||
** extension */
|
||||
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
|
||||
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
|
||||
# define SQLITE_EXTENSION_INIT3 \
|
||||
extern const sqlite3_api_routines *sqlite3_api;
|
||||
#else
|
||||
/* This case when the file is being statically linked into the
|
||||
** application */
|
||||
# define SQLITE_EXTENSION_INIT1 /*no-op*/
|
||||
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
|
||||
# define SQLITE_EXTENSION_INIT3 /*no-op*/
|
||||
#endif
|
||||
|
||||
#endif /* _SQLITE3EXT_H_ */
|
||||
|
18
TMessagesProj/jni/video.c
Normal file
18
TMessagesProj/jni/video.c
Normal 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
17
TMessagesProj/jni/video.h
Normal 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
|
243
TMessagesProj/jni/video_audio_in.c
Normal file
243
TMessagesProj/jni/video_audio_in.c
Normal 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();
|
||||
}
|
366
TMessagesProj/jni/video_audio_out.c
Normal file
366
TMessagesProj/jni/video_audio_out.c
Normal 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);
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,18 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.telegram.messenger"
|
||||
android:versionCode="98"
|
||||
android:versionName="1.2.7">
|
||||
|
||||
android:versionCode="122"
|
||||
android:versionName="1.3.2">
|
||||
|
||||
<supports-screens android:anyDensity="true"
|
||||
android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:largeScreens="true"
|
||||
android:resizeable="true"
|
||||
android:xlargeScreens="true"/>
|
||||
|
||||
android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:largeScreens="true"
|
||||
android:resizeable="true"
|
||||
android:xlargeScreens="true"/>
|
||||
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
|
||||
|
||||
|
||||
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
|
||||
<uses-feature android:name="android.hardware.telephony" 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.wifi" 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.ACCESS_NETWORK_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.SYSTEM_ALERT_WINDOW" />
|
||||
<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.C2D_MESSAGE" android:protectionLevel="signature" />
|
||||
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/AppName"
|
||||
android:theme="@style/Theme.Sherlock.Light"
|
||||
android:theme="@style/Theme.TMessages.Start"
|
||||
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" />
|
||||
|
||||
|
||||
<activity
|
||||
android:name="org.telegram.ui.LaunchActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
android:name="org.telegram.ui.LaunchActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
@ -92,68 +94,78 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="org.telegram.ui.LoginActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
android:name="org.telegram.ui.LoginActivity"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
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
|
||||
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">
|
||||
</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:name="org.telegram.ui.GalleryImageViewer"
|
||||
android:theme="@style/Theme.TMessages.Gallery"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
</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" />
|
||||
|
||||
|
||||
<receiver android:name="org.telegram.messenger.SmsListener">
|
||||
<intent-filter>
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
|
||||
<receiver
|
||||
android:name="org.telegram.messenger.GcmBroadcastReceiver"
|
||||
android:permission="com.google.android.c2dm.permission.SEND" >
|
||||
android:name="org.telegram.messenger.GcmBroadcastReceiver"
|
||||
android:permission="com.google.android.c2dm.permission.SEND" >
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
||||
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
|
||||
<category android:name="org.telegram.messenger" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
|
||||
<service android:name="org.telegram.messenger.AuthenticatorService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.accounts.AccountAuthenticator"/>
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.accounts.AccountAuthenticator"
|
||||
android:resource="@xml/auth"/>
|
||||
android:resource="@xml/auth"/>
|
||||
</service>
|
||||
|
||||
|
||||
<service android:name="org.telegram.messenger.ContactsSyncAdapterService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter" />
|
||||
</intent-filter>
|
||||
<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"
|
||||
android:resource="@xml/contacts" />
|
||||
android:resource="@xml/contacts" />
|
||||
</service>
|
||||
|
||||
|
||||
<uses-library android:name="com.google.android.maps" android:required="false"/>
|
||||
</application>
|
||||
|
||||
|
||||
</manifest>
|
||||
|
||||
|
@ -1,28 +1,21 @@
|
||||
6723;NF;Norfolk Island
|
||||
5999;CW;Curaçao
|
||||
1939;PR;Puerto Rico
|
||||
1876;JM;Jamaica
|
||||
1869;KN;Saint Kitts and Nevis
|
||||
1868;TT;Trinidad and Tobago
|
||||
1849;DO;Dominican Republic
|
||||
1829;DO;Dominican Republic
|
||||
1809;DO;Dominican Republic
|
||||
1787;PR;Puerto Rico
|
||||
1784;VC;Saint Vincent and the Grenadines
|
||||
1869;KN;Saint Kitts & Nevis
|
||||
1868;TT;Trinidad & Tobago
|
||||
1784;VC;Saint Vincent & the Grenadines
|
||||
1767;DM;Dominica
|
||||
1758;LC;Saint Lucia
|
||||
1721;SX;Bonaire, Sint Eustatius and Saba
|
||||
1721;SX;Sint Maarten
|
||||
1684;AS;American Samoa
|
||||
1671;GU;Guam
|
||||
1670;MP;Northern Mariana Islands
|
||||
1664;MS;Montserrat
|
||||
1649;TC;Turks and Caicos Islands
|
||||
1649;TC;Turks & Caicos Islands
|
||||
1473;GD;Grenada
|
||||
1441;BM;Bermuda
|
||||
1345;KY;Cayman Islands
|
||||
1340;VI;US Virgin Islands
|
||||
1284;VG;British Virgin Islands
|
||||
1268;AG;Antigua and Barbuda
|
||||
1268;AG;Antigua & Barbuda
|
||||
1264;AI;Anguilla
|
||||
1246;BB;Barbados
|
||||
1242;BS;Bahamas
|
||||
@ -45,7 +38,7 @@
|
||||
966;SA;Saudi Arabia
|
||||
965;KW;Kuwait
|
||||
964;IQ;Iraq
|
||||
963;SY;Syria
|
||||
963;SY;Syrian Arab Republic
|
||||
962;JO;Jordan
|
||||
961;LB;Lebanon
|
||||
960;MV;Maldives
|
||||
@ -66,7 +59,7 @@
|
||||
685;WS;Samoa
|
||||
683;NU;Niue
|
||||
682;CK;Cook Islands
|
||||
681;WF;Wallis and Futuna
|
||||
681;WF;Wallis & Futuna
|
||||
680;PW;Palau
|
||||
679;FJ;Fiji
|
||||
678;VU;Vanuatu
|
||||
@ -75,9 +68,10 @@
|
||||
675;PG;Papua New Guinea
|
||||
674;NR;Nauru
|
||||
673;BN;Brunei Darussalam
|
||||
672;AU;Australia
|
||||
670;TL;East Timor
|
||||
599;BQ;Sint Maarten
|
||||
672;NF;Norfolk Island
|
||||
670;TL;Timor-Leste
|
||||
599;BQ;Bonaire, Sint Eustatius & Saba
|
||||
599;CW;Curaçao
|
||||
598;UY;Uruguay
|
||||
597;SR;Suriname
|
||||
596;MQ;Martinique
|
||||
@ -88,7 +82,7 @@
|
||||
591;BO;Bolivia
|
||||
590;GP;Guadeloupe
|
||||
509;HT;Haiti
|
||||
508;PM;Saint Pierre and Miquelon
|
||||
508;PM;Saint Pierre & Miquelon
|
||||
507;PA;Panama
|
||||
506;CR;Costa Rica
|
||||
505;NI;Nicaragua
|
||||
@ -101,7 +95,7 @@
|
||||
421;SK;Slovakia
|
||||
420;CZ;Czech Republic
|
||||
389;MK;Macedonia
|
||||
387;BA;Bosnia and Herzegovina
|
||||
387;BA;Bosnia & Herzegovina
|
||||
386;SI;Slovenia
|
||||
385;HR;Croatia
|
||||
382;ME;Montenegro
|
||||
@ -153,17 +147,17 @@
|
||||
249;SD;Sudan
|
||||
248;SC;Seychelles
|
||||
247;SH;Saint Helena
|
||||
246;IO;United Kingdom
|
||||
246;IO;Diego Garcia
|
||||
245;GW;Guinea-Bissau
|
||||
244;AO;Angola
|
||||
243;CD;Congo, Democratic Republic
|
||||
242;CG;Congo
|
||||
243;CD;Congo (Dem. Rep.)
|
||||
242;CG;Congo (Rep.)
|
||||
241;GA;Gabon
|
||||
240;GQ;Equatorial Guinea
|
||||
239;ST;São Tomé and Príncipe
|
||||
239;ST;São Tomé & Príncipe
|
||||
238;CV;Cape Verde
|
||||
237;CM;Cameroon
|
||||
236;CF;Central African Republic
|
||||
236;CF;Central African Rep.
|
||||
235;TD;Chad
|
||||
234;NG;Nigeria
|
||||
233;GH;Ghana
|
||||
@ -228,8 +222,10 @@
|
||||
31;NL;Netherlands
|
||||
30;GR;Greece
|
||||
27;ZA;South Africa
|
||||
20;EG;Egypt
|
||||
7;KZ;Kazakhstan
|
||||
7;RU;Russia
|
||||
1;US;USA
|
||||
1;CA;Canada
|
||||
20;EG;Egypt
|
||||
7;KZ;Kazakhstan
|
||||
7;RU;Russian Federation
|
||||
1;PR;Puerto Rico
|
||||
1;DO;Dominican Rep.
|
||||
1;CA;Canada
|
||||
1;US;USA
|
Binary file not shown.
BIN
TMessagesProj/src/main/assets/fonts/rmedium.ttf
Normal file
BIN
TMessagesProj/src/main/assets/fonts/rmedium.ttf
Normal file
Binary file not shown.
@ -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.
|
||||
*/
|
||||
|
||||
package jawnae.pyronet.traffic;
|
||||
package jawnae.pyronet;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
@ -31,14 +31,9 @@ import java.nio.channels.SocketChannel;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import jawnae.pyronet.events.PyroClientListener;
|
||||
import jawnae.pyronet.traffic.ByteStream;
|
||||
|
||||
public class PyroClient {
|
||||
private final PyroSelector selector;
|
||||
|
||||
final PyroServer server;
|
||||
|
||||
private final SelectionKey key;
|
||||
|
||||
private final ByteStream outbound;
|
||||
@ -46,18 +41,17 @@ public class PyroClient {
|
||||
// called by PyroSelector.connect()
|
||||
PyroClient(PyroSelector selector, InetSocketAddress bind,
|
||||
InetSocketAddress host) throws IOException {
|
||||
this(selector, null, PyroClient.bindAndConfigure(selector,
|
||||
this(selector, PyroClient.bindAndConfigure(selector,
|
||||
SocketChannel.open(), bind));
|
||||
|
||||
((SocketChannel) this.key.channel()).connect(host);
|
||||
}
|
||||
|
||||
// called by PyroClient and PyroServer
|
||||
PyroClient(PyroSelector selector, PyroServer server, SelectionKey key) {
|
||||
PyroClient(PyroSelector selector, SelectionKey key) {
|
||||
this.selector = selector;
|
||||
this.selector.checkThread();
|
||||
|
||||
this.server = server;
|
||||
this.key = key;
|
||||
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 {
|
||||
this.selector.checkThread();
|
||||
this.lastEventTime = now;
|
||||
//this.lastEventTime = now;
|
||||
|
||||
int sent = 0;
|
||||
|
||||
@ -479,13 +459,9 @@ public class PyroClient {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.server != null) {
|
||||
this.server.onDisconnect(this);
|
||||
}
|
||||
|
||||
if (cause instanceof ConnectException) {
|
||||
for (PyroClientListener listener: this.listeners)
|
||||
listener.unconnectableClient(this);
|
||||
listener.unconnectableClient(this, (Exception)cause);
|
||||
} else if (cause instanceof EOFException) // after read=-1
|
||||
{
|
||||
for (PyroClientListener listener: this.listeners)
|
||||
@ -495,7 +471,7 @@ public class PyroClient {
|
||||
listener.droppedClient(this, (IOException) cause);
|
||||
} else if (!(cause instanceof String)) {
|
||||
for (PyroClientListener listener: this.listeners)
|
||||
listener.unconnectableClient(this);
|
||||
listener.unconnectableClient(this, null);
|
||||
} else if (cause.equals("local")) {
|
||||
for (PyroClientListener listener: this.listeners)
|
||||
listener.disconnectedClient(this);
|
||||
@ -551,7 +527,7 @@ public class PyroClient {
|
||||
// channel.socket().setSoLinger(false, 0); // this will b0rk your
|
||||
// connections
|
||||
channel.socket().setSoLinger(true, 4);
|
||||
channel.socket().setReuseAddress(true);
|
||||
channel.socket().setReuseAddress(false);
|
||||
channel.socket().setKeepAlive(false);
|
||||
channel.socket().setTcpNoDelay(true);
|
||||
channel.socket().setReceiveBufferSize(PyroSelector.BUFFER_SIZE);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
package jawnae.pyronet.events;
|
||||
package jawnae.pyronet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jawnae.pyronet.PyroClient;
|
||||
|
||||
public class PyroClientAdapter implements PyroClientListener {
|
||||
public void connectedClient(PyroClient client) {
|
||||
//
|
||||
}
|
||||
|
||||
public void unconnectableClient(PyroClient client) {
|
||||
public void unconnectableClient(PyroClient client, Exception cause) {
|
||||
System.out.println("unconnectable");
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
package jawnae.pyronet.events;
|
||||
package jawnae.pyronet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -26,7 +26,7 @@ import jawnae.pyronet.PyroClient;
|
||||
public interface PyroClientListener {
|
||||
public void connectedClient(PyroClient client);
|
||||
|
||||
public void unconnectableClient(PyroClient client);
|
||||
public void unconnectableClient(PyroClient client, Exception cause);
|
||||
|
||||
public void droppedClient(PyroClient client, IOException cause);
|
||||
|
@ -19,7 +19,6 @@
|
||||
package jawnae.pyronet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -27,14 +26,11 @@ import java.nio.channels.CancelledKeyException;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import jawnae.pyronet.events.PyroSelectorListener;
|
||||
|
||||
public class PyroSelector {
|
||||
public static boolean DO_NOT_CHECK_NETWORK_THREAD = true;
|
||||
|
||||
@ -46,14 +42,7 @@ public class PyroSelector {
|
||||
|
||||
final ByteBuffer networkBuffer;
|
||||
|
||||
final PyroSelectorListener listener;
|
||||
|
||||
public PyroSelector() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public PyroSelector(PyroSelectorListener listener) {
|
||||
this.listener = listener;
|
||||
this.networkBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
|
||||
|
||||
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 {
|
||||
return this.connect(host, null);
|
||||
}
|
||||
@ -142,11 +109,7 @@ public class PyroSelector {
|
||||
try {
|
||||
return new PyroClient(this, bind, host);
|
||||
} catch (IOException exc) {
|
||||
if (this.listener == null)
|
||||
throw exc;
|
||||
|
||||
this.listener.clientBindFailed(exc);
|
||||
return null;
|
||||
throw exc;
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,16 +136,10 @@ public class PyroSelector {
|
||||
if (task == null)
|
||||
break;
|
||||
|
||||
if (this.listener != null)
|
||||
this.listener.executingTask(task);
|
||||
|
||||
try {
|
||||
task.run();
|
||||
} catch (Throwable cause) {
|
||||
if (this.listener != null)
|
||||
this.listener.taskCrashed(task, cause);
|
||||
else
|
||||
cause.printStackTrace();
|
||||
cause.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -192,15 +149,9 @@ public class PyroSelector {
|
||||
try {
|
||||
selected = nioSelector.select(timeout);
|
||||
} catch (IOException exc) {
|
||||
if (this.listener != null)
|
||||
this.listener.selectFailure(exc);
|
||||
else
|
||||
exc.printStackTrace();
|
||||
exc.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.listener != null)
|
||||
this.listener.selectedKeys(selected);
|
||||
}
|
||||
|
||||
private final void handleSelectedKeys(long now) {
|
||||
@ -210,17 +161,8 @@ public class PyroSelector {
|
||||
SelectionKey key = keys.next();
|
||||
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) {
|
||||
PyroClient client = (PyroClient) key.attachment();
|
||||
if (this.listener != null)
|
||||
this.listener.clientSelected(client, key.readyOps());
|
||||
client.onInterestOp(now);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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];
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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) {
|
||||
//
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -36,6 +36,7 @@ import java.util.Locale;
|
||||
|
||||
public class PhoneFormat {
|
||||
public byte[] data;
|
||||
private boolean initialzed = false;
|
||||
public ByteBuffer buffer;
|
||||
public String defaultCountry;
|
||||
public String defaultCallingCode;
|
||||
@ -90,6 +91,7 @@ public class PhoneFormat {
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
if (countryCode != null && countryCode.length() != 0) {
|
||||
@ -104,6 +106,7 @@ public class PhoneFormat {
|
||||
countryCallingCode = new HashMap<String, String>(255);
|
||||
|
||||
parseDataHeader();
|
||||
initialzed = true;
|
||||
}
|
||||
|
||||
public String defaultCallingCode() {
|
||||
@ -139,6 +142,9 @@ public class PhoneFormat {
|
||||
}
|
||||
|
||||
public String format(String orig) {
|
||||
if (!initialzed) {
|
||||
return orig;
|
||||
}
|
||||
String str = strip(orig);
|
||||
|
||||
if (str.startsWith("+")) {
|
||||
@ -177,6 +183,9 @@ public class PhoneFormat {
|
||||
}
|
||||
|
||||
public boolean isPhoneNumberValid(String phoneNumber) {
|
||||
if (!initialzed) {
|
||||
return true;
|
||||
}
|
||||
String str = strip(phoneNumber);
|
||||
|
||||
if (str.startsWith("+")) {
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
package org.telegram.SQLite;
|
||||
|
||||
import android.util.Log;
|
||||
import org.telegram.messenger.FileLog;
|
||||
|
||||
public class SQLiteCursor {
|
||||
|
||||
@ -83,14 +83,14 @@ public class SQLiteCursor {
|
||||
int repeatCount = 6;
|
||||
while (repeatCount-- != 0) {
|
||||
try {
|
||||
Log.e("tmessages", "sqlite busy, waiting...");
|
||||
FileLog.e("tmessages", "sqlite busy, waiting...");
|
||||
Thread.sleep(500);
|
||||
res = preparedStatement.step();
|
||||
if (res == 0) {
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
if (res == -1) {
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,11 +8,12 @@
|
||||
|
||||
package org.telegram.SQLite;
|
||||
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.ui.ApplicationLoader;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class SQLiteDatabase {
|
||||
private final int sqliteHandle;
|
||||
|
||||
@ -25,7 +26,7 @@ public class SQLiteDatabase {
|
||||
}
|
||||
|
||||
public SQLiteDatabase(String fileName) throws SQLiteException {
|
||||
sqliteHandle = opendb(fileName);
|
||||
sqliteHandle = opendb(fileName, ApplicationLoader.applicationContext.getFilesDir().getPath());
|
||||
isOpen = true;
|
||||
preparedMap = new HashMap<String, SQLitePreparedStatement>();
|
||||
}
|
||||
@ -111,7 +112,7 @@ public class SQLiteDatabase {
|
||||
}
|
||||
closedb(sqliteHandle);
|
||||
} catch (SQLiteException e) {
|
||||
Log.e("tmessages", e.getMessage(), e);
|
||||
FileLog.e("tmessages", e.getMessage(), e);
|
||||
}
|
||||
isOpen = false;
|
||||
}
|
||||
@ -142,7 +143,7 @@ public class SQLiteDatabase {
|
||||
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 beginTransaction(int sqliteHandle);
|
||||
native void commitTransaction(int sqliteHandle);
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
package org.telegram.SQLite;
|
||||
|
||||
import android.util.Log;
|
||||
import org.telegram.messenger.FileLog;
|
||||
|
||||
public class SQLitePreparedStatement {
|
||||
private boolean isFinalized = false;
|
||||
@ -90,7 +90,7 @@ public class SQLitePreparedStatement {
|
||||
isFinalized = true;
|
||||
finalize(sqliteStatementHandle);
|
||||
} catch (SQLiteException e) {
|
||||
Log.e("tmessages", e.getMessage(), e);
|
||||
FileLog.e("tmessages", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,9 +8,7 @@
|
||||
|
||||
package org.telegram.TL;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.telegram.messenger.ConnectionsManager;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.SerializedData;
|
||||
|
||||
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_sendEncryptedService.constructor, TLRPC.TL_messages_sendEncryptedService.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_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.Vector.constructor, TLRPC.Vector.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;
|
||||
@ -419,16 +424,14 @@ public class TLClassStore {
|
||||
}
|
||||
return response;
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e("tmessages", "can't create class");
|
||||
FileLog.e("tmessages", "can't create class");
|
||||
return null;
|
||||
} catch (InstantiationException e2) {
|
||||
Log.e("tmessages", "can't create class");
|
||||
FileLog.e("tmessages", "can't create class");
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.e("tmessages", String.format("unknown class %x", constructor));
|
||||
}
|
||||
FileLog.e("tmessages", String.format("unknown class %x", constructor));
|
||||
return null;
|
||||
//throw new RuntimeException(String.format("unknown class %x", constructor));
|
||||
}
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* 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 first_name;
|
||||
public String last_name;
|
||||
public byte[] bytes;
|
||||
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 int constructor = 0x2215bcbd;
|
||||
|
||||
@ -2011,7 +2025,6 @@ public class TLRPC {
|
||||
public static class TL_messageActionChatEditPhoto extends MessageAction {
|
||||
public static int constructor = 0x7fcb13a8;
|
||||
|
||||
|
||||
public void readParams(SerializedData stream) {
|
||||
photo = (Photo)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
}
|
||||
@ -2463,12 +2476,12 @@ public class TLRPC {
|
||||
}
|
||||
|
||||
public static class InputMedia extends TLObject {
|
||||
public TL_inputFile file;
|
||||
public InputFile file;
|
||||
public InputGeoPoint geo_point;
|
||||
public String phone_number;
|
||||
public String first_name;
|
||||
public String last_name;
|
||||
public TL_inputFile thumb;
|
||||
public InputFile thumb;
|
||||
public int duration;
|
||||
public int w;
|
||||
public int h;
|
||||
@ -2479,7 +2492,7 @@ public class TLRPC {
|
||||
|
||||
|
||||
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) {
|
||||
@ -2540,8 +2553,8 @@ public class TLRPC {
|
||||
|
||||
|
||||
public void readParams(SerializedData stream) {
|
||||
file = (TL_inputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
thumb = (TL_inputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
file = (InputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
thumb = (InputFile)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
duration = stream.readInt32();
|
||||
w = stream.readInt32();
|
||||
h = stream.readInt32();
|
||||
@ -2562,7 +2575,7 @@ public class TLRPC {
|
||||
|
||||
|
||||
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();
|
||||
w = 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 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 boolean contact;
|
||||
}
|
||||
@ -4582,13 +4641,15 @@ public class TLRPC {
|
||||
}
|
||||
}
|
||||
|
||||
public static class TL_inputFile extends TLObject {
|
||||
public static int constructor = 0xf52ff27f;
|
||||
|
||||
public static class InputFile extends TLObject {
|
||||
public long id;
|
||||
public int parts;
|
||||
public String name;
|
||||
public String md5_checksum;
|
||||
}
|
||||
|
||||
public static class TL_inputFile extends InputFile {
|
||||
public static int constructor = 0xf52ff27f;
|
||||
|
||||
public void readParams(SerializedData stream) {
|
||||
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 Message message;
|
||||
public ArrayList<Chat> chats = new ArrayList<Chat>();
|
||||
@ -5139,7 +5218,7 @@ public class TLRPC {
|
||||
public static class InputChatPhoto extends TLObject {
|
||||
public InputPhoto id;
|
||||
public InputPhotoCrop crop;
|
||||
public TL_inputFile file;
|
||||
public InputFile file;
|
||||
}
|
||||
|
||||
public static class TL_inputChatPhoto extends InputChatPhoto {
|
||||
@ -5172,7 +5251,7 @@ public class TLRPC {
|
||||
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@ -6661,7 +6740,7 @@ public class TLRPC {
|
||||
public static class TL_photos_uploadProfilePhoto extends TLObject {
|
||||
public static int constructor = 0xd50f9c88;
|
||||
|
||||
public TL_inputFile file;
|
||||
public InputFile file;
|
||||
public String caption;
|
||||
public InputGeoPoint geo_point;
|
||||
public InputPhotoCrop crop;
|
||||
@ -6671,7 +6750,7 @@ public class TLRPC {
|
||||
}
|
||||
|
||||
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();
|
||||
geo_point = (InputGeoPoint)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 last_message_date;
|
||||
public long id;
|
||||
public int last_read;
|
||||
|
||||
public void readParams(SerializedData stream) {
|
||||
peer = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
@ -8032,6 +8112,7 @@ public class TLRPC {
|
||||
|
||||
public static class MessageAction extends TLObject {
|
||||
public Photo photo;
|
||||
public UserProfilePhoto newUserPhoto;
|
||||
public int user_id;
|
||||
public String title;
|
||||
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 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 int constructor = 0x99a438cf;
|
||||
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
* 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.content.AbstractThreadedSyncAdapter;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SyncResult;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
public class ContactsSyncAdapterService extends Service {
|
||||
private static SyncAdapterImpl sSyncAdapter = null;
|
||||
@ -41,7 +39,7 @@ public class ContactsSyncAdapterService extends Service {
|
||||
try {
|
||||
ContactsSyncAdapterService.performSync(mContext, account, extras, authority, provider, syncResult);
|
||||
} 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)
|
||||
throws OperationCanceledException {
|
||||
Log.i("telegram", "performSync: " + account.toString());
|
||||
FileLog.d("telegram", "performSync: " + account.toString());
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,24 +8,32 @@
|
||||
|
||||
package org.telegram.messenger;
|
||||
|
||||
import android.util.Log;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import org.telegram.TL.TLRPC;
|
||||
import org.telegram.ui.ApplicationLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Datacenter {
|
||||
private final int DATA_VERSION = 2;
|
||||
|
||||
public int datacenterId;
|
||||
public String address;
|
||||
public int port;
|
||||
public ArrayList<String> addresses = new ArrayList<String>();
|
||||
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 long authSessionId;
|
||||
public long authDownloadSessionId;
|
||||
public long authUploadSessionId;
|
||||
public byte[] authKey;
|
||||
public byte[] authKeyId;
|
||||
private volatile int currentPortNum = 0;
|
||||
private volatile int currentAddressNum = 0;
|
||||
|
||||
public TcpConnection connection;
|
||||
public TcpConnection downloadConnection;
|
||||
@ -37,39 +45,148 @@ public class Datacenter {
|
||||
authServerSaltSet = new ArrayList<ServerSalt>();
|
||||
}
|
||||
|
||||
public Datacenter(SerializedData data) {
|
||||
datacenterId = data.readInt32();
|
||||
address = data.readString();
|
||||
port = data.readInt32();
|
||||
if (port == 25) {
|
||||
port = 443;
|
||||
}
|
||||
int 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>();
|
||||
public Datacenter(SerializedData data, int version) {
|
||||
if (version == 0) {
|
||||
datacenterId = data.readInt32();
|
||||
String address = data.readString();
|
||||
addresses.add(address);
|
||||
int port = data.readInt32();
|
||||
ports.put(address, port);
|
||||
int len = data.readInt32();
|
||||
if (len != 0) {
|
||||
authKey = data.readData(len);
|
||||
}
|
||||
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) {
|
||||
stream.writeInt32(DATA_VERSION);
|
||||
stream.writeInt32(datacenterId);
|
||||
stream.writeString(address);
|
||||
stream.writeInt32(port);
|
||||
stream.writeInt32(addresses.size());
|
||||
for (String address : addresses) {
|
||||
stream.writeString(address);
|
||||
stream.writeInt32(ports.get(address));
|
||||
}
|
||||
if (authKey != null) {
|
||||
stream.writeInt32(authKey.length);
|
||||
stream.writeRaw(authKey);
|
||||
@ -129,10 +246,8 @@ public class Datacenter {
|
||||
}
|
||||
}
|
||||
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
if (result == 0) {
|
||||
Log.e("tmessages", "Valid salt not found", null);
|
||||
}
|
||||
if (result == 0) {
|
||||
FileLog.e("tmessages", "Valid salt not found");
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* 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.style.DynamicDrawableSpan;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
@ -364,7 +363,7 @@ public class Emoji {
|
||||
|
||||
return color;
|
||||
} catch(Throwable x) {
|
||||
Log.e("tmessages", "Error loading emoji", x);
|
||||
FileLog.e("tmessages", "Error loading emoji", x);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -396,7 +395,7 @@ public class Emoji {
|
||||
public static Drawable getEmojiDrawable(long code){
|
||||
DrawableInfo info = rects.get(code);
|
||||
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;
|
||||
}
|
||||
EmojiDrawable ed = new EmojiDrawable(info);
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* 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
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof FastDateFormat == false) {
|
||||
if (!(obj instanceof FastDateFormat)) {
|
||||
return false;
|
||||
}
|
||||
FastDateFormat other = (FastDateFormat) obj;
|
||||
if (
|
||||
(mPattern == other.mPattern || mPattern.equals(other.mPattern)) &&
|
||||
(mTimeZone == other.mTimeZone || mTimeZone.equals(other.mTimeZone)) &&
|
||||
(mLocale == other.mLocale || mLocale.equals(other.mLocale)) &&
|
||||
(mTimeZoneForced == other.mTimeZoneForced) &&
|
||||
(mLocaleForced == other.mLocaleForced)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (mPattern == other.mPattern || mPattern.equals(other.mPattern)) &&
|
||||
(mTimeZone == other.mTimeZone || mTimeZone.equals(other.mTimeZone)) &&
|
||||
(mLocale == other.mLocale || mLocale.equals(other.mLocale)) &&
|
||||
(mTimeZoneForced == other.mTimeZoneForced) &&
|
||||
(mLocaleForced == other.mLocaleForced);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
* 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.BitmapFactory;
|
||||
import android.os.Build;
|
||||
|
||||
import org.telegram.TL.TLObject;
|
||||
import org.telegram.TL.TLRPC;
|
||||
@ -26,7 +27,7 @@ public class FileLoadOperation {
|
||||
private int downloadChunkSize = 1024 * 32;
|
||||
|
||||
public int datacenter_id;
|
||||
private TLRPC.InputFileLocation location;
|
||||
public TLRPC.InputFileLocation location;
|
||||
public volatile int state = 0;
|
||||
private int downloadedBytes;
|
||||
public int totalBytesCount;
|
||||
@ -39,12 +40,14 @@ public class FileLoadOperation {
|
||||
|
||||
private File cacheFileTemp;
|
||||
private File cacheFileFinal;
|
||||
private File cacheIvTemp;
|
||||
|
||||
private String httpUrl;
|
||||
private URLConnection httpConnection;
|
||||
public boolean needBitmapCreate = true;
|
||||
private InputStream httpConnectionStream;
|
||||
private RandomAccessFile fileOutputStream;
|
||||
RandomAccessFile fiv;
|
||||
|
||||
public static interface FileLoadOperationDelegate {
|
||||
public abstract void didFinishLoadingFile(FileLoadOperation operation);
|
||||
@ -98,10 +101,20 @@ public class FileLoadOperation {
|
||||
return;
|
||||
}
|
||||
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 onlyCache = false;
|
||||
String fileNameFinal;
|
||||
String fileNameTemp;
|
||||
String fileNameFinal = null;
|
||||
String fileNameTemp = null;
|
||||
String fileNameIv = null;
|
||||
if (httpUrl != null) {
|
||||
fileNameFinal = Utilities.MD5(httpUrl);
|
||||
fileNameTemp = fileNameFinal + "_temp.jpg";
|
||||
@ -109,6 +122,9 @@ public class FileLoadOperation {
|
||||
} else if (location.volume_id != 0 && location.local_id != 0) {
|
||||
fileNameTemp = location.volume_id + "_" + location.local_id + "_temp.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) {
|
||||
onlyCache = true;
|
||||
}
|
||||
@ -117,6 +133,9 @@ public class FileLoadOperation {
|
||||
needBitmapCreate = false;
|
||||
fileNameTemp = datacenter_id + "_" + location.id + "_temp.mp4";
|
||||
fileNameFinal = datacenter_id + "_" + location.id + ".mp4";
|
||||
if (key != null) {
|
||||
fileNameIv = datacenter_id + "_" + location.id + ".iv";
|
||||
}
|
||||
}
|
||||
|
||||
boolean exist;
|
||||
@ -174,7 +193,9 @@ public class FileLoadOperation {
|
||||
float scaleFactor = bitmapW / w_filter;
|
||||
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, (int)w_filter, (int)(bitmapH / scaleFactor), true);
|
||||
if (image != scaledBitmap) {
|
||||
image.recycle();
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
image.recycle();
|
||||
}
|
||||
image = scaledBitmap;
|
||||
}
|
||||
}
|
||||
@ -193,12 +214,13 @@ public class FileLoadOperation {
|
||||
});
|
||||
} catch (Exception e) {
|
||||
cacheFileFinal.delete();
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (onlyCache) {
|
||||
cleanup();
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -212,6 +234,21 @@ public class FileLoadOperation {
|
||||
downloadedBytes = (int)cacheFileTemp.length();
|
||||
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) {
|
||||
cacheFileFinal.delete();
|
||||
}
|
||||
@ -221,15 +258,17 @@ public class FileLoadOperation {
|
||||
fileOutputStream.seek(downloadedBytes);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
if (fileOutputStream == null) {
|
||||
cleanup();
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
delegate.didFailedLoadingFile(FileLoadOperation.this);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (httpUrl != null) {
|
||||
startDownloadHTTPRequest();
|
||||
@ -244,28 +283,41 @@ public class FileLoadOperation {
|
||||
return;
|
||||
}
|
||||
state = 2;
|
||||
cleanup();
|
||||
if (httpUrl == null && requestToken != 0) {
|
||||
ConnectionsManager.Instance.cancelRpc(requestToken, true);
|
||||
}
|
||||
delegate.didFailedLoadingFile(FileLoadOperation.this);
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
if (httpUrl != null) {
|
||||
try {
|
||||
httpConnectionStream.close();
|
||||
httpConnection = null;
|
||||
httpConnectionStream = null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
} else {
|
||||
if (fileOutputStream != null) {
|
||||
try {
|
||||
try {
|
||||
if (fileOutputStream != null) {
|
||||
fileOutputStream.close();
|
||||
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 {
|
||||
@ -273,8 +325,10 @@ public class FileLoadOperation {
|
||||
return;
|
||||
}
|
||||
state = 3;
|
||||
fileOutputStream.close();
|
||||
fileOutputStream = null;
|
||||
cleanup();
|
||||
if (cacheIvTemp != null) {
|
||||
cacheIvTemp.delete();
|
||||
}
|
||||
final boolean renamed = cacheFileTemp.renameTo(cacheFileFinal);
|
||||
|
||||
if (needBitmapCreate) {
|
||||
@ -289,7 +343,7 @@ public class FileLoadOperation {
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
@ -328,7 +382,9 @@ public class FileLoadOperation {
|
||||
float scaleFactor = bitmapW / w_filter;
|
||||
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, (int) w_filter, (int) (bitmapH / scaleFactor), true);
|
||||
if (image != scaledBitmap) {
|
||||
image.recycle();
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
image.recycle();
|
||||
}
|
||||
image = scaledBitmap;
|
||||
}
|
||||
}
|
||||
@ -338,7 +394,7 @@ public class FileLoadOperation {
|
||||
FileLoader.Instance.runtimeHack.trackFree(image.getRowBytes() * image.getHeight());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
delegate.didFinishLoadingFile(FileLoadOperation.this);
|
||||
}
|
||||
@ -361,7 +417,8 @@ public class FileLoadOperation {
|
||||
httpConnection.connect();
|
||||
httpConnectionStream = httpConnection.getInputStream();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
cleanup();
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -384,6 +441,7 @@ public class FileLoadOperation {
|
||||
}
|
||||
});
|
||||
} else if (readed == -1) {
|
||||
cleanup();
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -395,6 +453,7 @@ public class FileLoadOperation {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cleanup();
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -403,18 +462,14 @@ public class FileLoadOperation {
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
cleanup();
|
||||
FileLog.e("tmessages", e);
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
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();
|
||||
req.location = location;
|
||||
req.offset = downloadedBytes;
|
||||
req.limit = downloadChunkSize;
|
||||
if (totalBytesCount == -1) {
|
||||
req.offset = 0;
|
||||
req.limit = 0;
|
||||
} else {
|
||||
req.offset = downloadedBytes;
|
||||
req.limit = downloadChunkSize;
|
||||
}
|
||||
requestToken = ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
@ -443,19 +503,24 @@ public class FileLoadOperation {
|
||||
if (fileOutputStream != null) {
|
||||
fileOutputStream.write(res.bytes);
|
||||
}
|
||||
if (fiv != null) {
|
||||
fiv.seek(0);
|
||||
fiv.write(iv);
|
||||
}
|
||||
downloadedBytes += res.bytes.length;
|
||||
res.bytes = null;
|
||||
if (totalBytesCount != 0) {
|
||||
if (totalBytesCount > 0) {
|
||||
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();
|
||||
} else {
|
||||
onFinishLoadingFile();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cleanup();
|
||||
delegate.didFailedLoadingFile(FileLoadOperation.this);
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
} else {
|
||||
if (error.text.contains("FILE_MIGRATE_")) {
|
||||
@ -469,6 +534,7 @@ public class FileLoadOperation {
|
||||
val = null;
|
||||
}
|
||||
if (val == null) {
|
||||
cleanup();
|
||||
delegate.didFailedLoadingFile(FileLoadOperation.this);
|
||||
} else {
|
||||
datacenter_id = val;
|
||||
@ -479,13 +545,16 @@ public class FileLoadOperation {
|
||||
try {
|
||||
onFinishLoadingFile();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
cleanup();
|
||||
delegate.didFailedLoadingFile(FileLoadOperation.this);
|
||||
}
|
||||
} else {
|
||||
cleanup();
|
||||
delegate.didFailedLoadingFile(FileLoadOperation.this);
|
||||
}
|
||||
} else {
|
||||
cleanup();
|
||||
delegate.didFailedLoadingFile(FileLoadOperation.this);
|
||||
}
|
||||
}
|
||||
@ -493,7 +562,11 @@ public class FileLoadOperation {
|
||||
}, new RPCRequest.RPCProgressDelegate() {
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,12 +8,13 @@
|
||||
|
||||
package org.telegram.messenger;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.media.ExifInterface;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
@ -37,16 +38,16 @@ public class FileLoader {
|
||||
public LruCache memCache;
|
||||
|
||||
private String ignoreRemoval = null;
|
||||
private HashMap<String, CacheImage> imageLoading;
|
||||
private ConcurrentHashMap<String, CacheImage> imageLoading;
|
||||
private HashMap<Integer, CacheImage> imageLoadingByKeys;
|
||||
private Queue<FileLoadOperation> operationsQueue;
|
||||
private Queue<FileLoadOperation> runningOperation;
|
||||
private final int maxConcurentLoadingOpertaionsCount = 2;
|
||||
private Queue<FileUploadOperation> uploadOperationQueue;
|
||||
private HashMap<String, FileUploadOperation> uploadOperationPaths;
|
||||
private ConcurrentHashMap<String, FileUploadOperation> uploadOperationPaths;
|
||||
private int currentUploadOperationsCount = 0;
|
||||
private Queue<FileLoadOperation> loadOperationQueue;
|
||||
private HashMap<String, FileLoadOperation> loadOperationPaths;
|
||||
private ConcurrentHashMap<String, FileLoadOperation> loadOperationPaths;
|
||||
private int currentLoadOperationsCount = 0;
|
||||
public static long lastCacheOutTime = 0;
|
||||
public ConcurrentHashMap<String, Float> fileProgresses = new ConcurrentHashMap<String, Float>();
|
||||
@ -109,20 +110,19 @@ public class FileLoader {
|
||||
trackFree = cl.getMethod("trackExternalFree", new Class[] {long.class});
|
||||
success = true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
if (!success) {
|
||||
Log.i("tmessages", "VMRuntime hack does not work!");
|
||||
runtime = null;
|
||||
trackAllocation = null;
|
||||
trackFree = null;
|
||||
@ -216,6 +216,11 @@ public class FileLoader {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeImage(String key) {
|
||||
BitmapUseCounts.remove(key);
|
||||
memCache.remove(key);
|
||||
}
|
||||
|
||||
/*class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
|
||||
private CacheImage cacheImage;
|
||||
private Bitmap bitmap;
|
||||
@ -246,8 +251,8 @@ public class FileLoader {
|
||||
}*/
|
||||
|
||||
public FileLoader() {
|
||||
int maxMemory = (int)Runtime.getRuntime().maxMemory();
|
||||
int cacheSize = maxMemory / 10;
|
||||
int cacheSize = Math.min(15, ((ActivityManager) ApplicationLoader.applicationContext.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass() / 7) * 1024 * 1024;
|
||||
|
||||
density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
runtimeHack = new VMRuntimeHack();
|
||||
@ -272,17 +277,21 @@ public class FileLoader {
|
||||
if (runtimeHack != null) {
|
||||
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>();
|
||||
operationsQueue = new LinkedList<FileLoadOperation>();
|
||||
runningOperation = new LinkedList<FileLoadOperation>();
|
||||
uploadOperationQueue = new LinkedList<FileUploadOperation>();
|
||||
uploadOperationPaths = new HashMap<String, FileUploadOperation>();
|
||||
loadOperationPaths = new HashMap<String, FileLoadOperation>();
|
||||
uploadOperationPaths = new ConcurrentHashMap<String, FileUploadOperation>();
|
||||
loadOperationPaths = new ConcurrentHashMap<String, FileLoadOperation>();
|
||||
loadOperationQueue = new LinkedList<FileLoadOperation>();
|
||||
}
|
||||
|
||||
@ -311,8 +320,9 @@ public class FileLoader {
|
||||
uploadOperationPaths.put(location, operation);
|
||||
operation.delegate = new FileUploadOperation.FileUploadOperationDelegate() {
|
||||
@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);
|
||||
fileProgresses.remove(location);
|
||||
Utilities.fileUploadQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
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) {
|
||||
Utilities.fileUploadQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
@ -454,6 +468,7 @@ public class FileLoader {
|
||||
}
|
||||
}
|
||||
});
|
||||
fileProgresses.remove(arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -628,14 +643,18 @@ public class FileLoader {
|
||||
}
|
||||
|
||||
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) {
|
||||
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))) {
|
||||
return;
|
||||
}
|
||||
@ -700,20 +719,32 @@ public class FileLoader {
|
||||
} else {
|
||||
loadOperation = new FileLoadOperation(url);
|
||||
}
|
||||
loadOperation.totalBytesCount = size;
|
||||
loadOperation.filter = filter;
|
||||
loadOperation.delegate = new FileLoadOperation.FileLoadOperationDelegate() {
|
||||
@Override
|
||||
public void didFinishLoadingFile(final FileLoadOperation operation) {
|
||||
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
|
||||
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() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -731,13 +762,36 @@ public class FileLoader {
|
||||
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
|
||||
public void didChangedLoadProgress(FileLoadOperation operation, float progress) {
|
||||
if (url != null) {
|
||||
if (url.volume_id != 0 && url.local_id != 0) {
|
||||
fileProgresses.put(url.volume_id + "_" + url.local_id + ".jpg", progress);
|
||||
public void didChangedLoadProgress(FileLoadOperation operation, final float progress) {
|
||||
if (operation.totalBytesCount != 0) {
|
||||
final String arg1 = operation.location.volume_id + "_" + operation.location.local_id + ".jpg";
|
||||
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) {
|
||||
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
|
||||
bmOptions.inJustDecodeBounds = true;
|
||||
@ -898,7 +928,7 @@ public class FileLoader {
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
||||
Bitmap b;
|
||||
@ -908,7 +938,7 @@ public class FileLoader {
|
||||
b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
FileLoader.Instance.memCache.evictAll();
|
||||
b = BitmapFactory.decodeFile(path, bmOptions);
|
||||
if (b != null && matrix != null) {
|
||||
@ -959,8 +989,10 @@ public class FileLoader {
|
||||
size.bytes = stream.toByteArray();
|
||||
size.size = size.bytes.length;
|
||||
}
|
||||
if (scaledBitmap != bitmap) {
|
||||
scaledBitmap.recycle();
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
if (scaledBitmap != bitmap) {
|
||||
scaledBitmap.recycle();
|
||||
}
|
||||
}
|
||||
return size;
|
||||
} catch (Exception e) {
|
||||
|
158
TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java
Normal file
158
TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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.
|
||||
* 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 boolean isLastPart = false;
|
||||
private long totalFileSize = 0;
|
||||
private int totalPartsCount = 0;
|
||||
private long currentUploaded = 0;
|
||||
private byte[] key;
|
||||
private byte[] iv;
|
||||
private int fingerprint;
|
||||
private boolean isBigFile = false;
|
||||
FileInputStream stream;
|
||||
MessageDigest mdEnc = null;
|
||||
|
||||
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 didChangedUploadProgress(FileUploadOperation operation, float progress);
|
||||
}
|
||||
@ -60,14 +62,14 @@ public class FileUploadOperation {
|
||||
}
|
||||
fingerprint = Utilities.bytesToInt(fingerprintBytes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
currentFileId = (long)(MessagesController.random.nextDouble() * Long.MAX_VALUE);
|
||||
try {
|
||||
mdEnc = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,18 +97,23 @@ public class FileUploadOperation {
|
||||
return;
|
||||
}
|
||||
|
||||
TLRPC.TL_upload_saveFilePart req = new TLRPC.TL_upload_saveFilePart();
|
||||
req.file_part = currentPartNum;
|
||||
req.file_id = currentFileId;
|
||||
TLObject finalRequest;
|
||||
|
||||
try {
|
||||
if (stream == null) {
|
||||
File cacheFile = new File(uploadingFilePath);
|
||||
stream = new FileInputStream(cacheFile);
|
||||
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;
|
||||
totalPartsCount = (int)Math.ceil((float)totalFileSize / (float)uploadChunkSize);
|
||||
readBuffer = new byte[uploadChunkSize];
|
||||
}
|
||||
|
||||
int readed = stream.read(readBuffer);
|
||||
int toAdd = 0;
|
||||
if (key != null && readed % 16 != 0) {
|
||||
@ -121,14 +128,27 @@ public class FileUploadOperation {
|
||||
sendBuffer = Utilities.aesIgeEncryption(sendBuffer, key, iv, true, true);
|
||||
}
|
||||
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;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
delegate.didFailedUploadingFile(this);
|
||||
return;
|
||||
}
|
||||
requestToken = ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() {
|
||||
requestToken = ConnectionsManager.Instance.performRpc(finalRequest, new RPCRequest.RPCRequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
requestToken = 0;
|
||||
@ -139,15 +159,25 @@ public class FileUploadOperation {
|
||||
if (isLastPart) {
|
||||
state = 3;
|
||||
if (key == null) {
|
||||
TLRPC.TL_inputFile result = new TLRPC.TL_inputFile();
|
||||
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0');
|
||||
TLRPC.InputFile result;
|
||||
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.id = currentFileId;
|
||||
result.name = uploadingFilePath.substring(uploadingFilePath.lastIndexOf("/") + 1);
|
||||
delegate.didFinishUploadingFile(FileUploadOperation.this, result, null);
|
||||
} else {
|
||||
TLRPC.TL_inputEncryptedFileUploaded result = new TLRPC.TL_inputEncryptedFileUploaded();
|
||||
result.md5_checksum = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0');
|
||||
TLRPC.InputEncryptedFile result;
|
||||
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.id = currentFileId;
|
||||
result.key_fingerprint = fingerprint;
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -9,43 +9,28 @@
|
||||
package org.telegram.messenger;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
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 org.json.JSONObject;
|
||||
import org.telegram.ui.ApplicationLoader;
|
||||
import org.telegram.ui.LaunchActivity;
|
||||
|
||||
public class GcmBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
public static final int NOTIFICATION_ID = 1;
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.i("tmessages", "GCM received intent: " + intent);
|
||||
}
|
||||
FileLog.d("tmessages", "GCM received intent: " + intent);
|
||||
setResultCode(Activity.RESULT_OK);
|
||||
|
||||
if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
|
||||
SharedPreferences preferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
|
||||
boolean globalEnabled = preferences.getBoolean("EnableAll", true);
|
||||
if (!globalEnabled) {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.i("tmessages", "GCM disabled");
|
||||
}
|
||||
FileLog.d("tmessages", "GCM disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -59,26 +44,22 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
|
||||
thread.setPriority(Thread.MAX_PRIORITY);
|
||||
thread.start();
|
||||
} else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
String registration = intent.getStringExtra("registration_id");
|
||||
if (intent.getStringExtra("error") != null) {
|
||||
Log.e("tmessages", "Registration failed, should try again later.");
|
||||
} else if (intent.getStringExtra("unregistered") != null) {
|
||||
Log.e("tmessages", "unregistration done, new messages from the authorized sender will be rejected");
|
||||
} else if (registration != null) {
|
||||
Log.e("tmessages", "registration id = " + registration);
|
||||
}
|
||||
String registration = intent.getStringExtra("registration_id");
|
||||
if (intent.getStringExtra("error") != null) {
|
||||
FileLog.e("tmessages", "Registration failed, should try again later.");
|
||||
} else if (intent.getStringExtra("unregistered") != null) {
|
||||
FileLog.e("tmessages", "unregistration done, new messages from the authorized sender will be rejected");
|
||||
} else if (registration != null) {
|
||||
FileLog.e("tmessages", "registration id = " + registration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", "received push " + extras);
|
||||
}
|
||||
SharedPreferences preferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
|
||||
|
||||
boolean groupEnabled = preferences.getBoolean("EnableGroup", true);
|
||||
@ -112,7 +93,7 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
||||
int chat_id = 0;
|
||||
@ -144,7 +125,7 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
||||
if (user_id != 0) {
|
||||
@ -224,6 +205,6 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
|
||||
notification.ledOnMS = 1000;
|
||||
notification.ledOffMS = 1000;
|
||||
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
|
||||
mNotificationManager.notify(NOTIFICATION_ID, notification);
|
||||
mNotificationManager.notify(NOTIFICATION_ID, notification);*/
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,8 +8,6 @@
|
||||
|
||||
package org.telegram.messenger;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.telegram.TL.TLClassStore;
|
||||
import org.telegram.TL.TLObject;
|
||||
import org.telegram.TL.TLRPC;
|
||||
@ -50,15 +48,14 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void beginHandshake(boolean dropConnection) {
|
||||
if (datacenter.connection == null) {
|
||||
datacenter.connection = new TcpConnection(datacenter.address, datacenter.port);
|
||||
datacenter.connection = new TcpConnection(datacenter.datacenterId);
|
||||
datacenter.connection.delegate = this;
|
||||
datacenter.connection.datacenterId = datacenter.datacenterId;
|
||||
datacenter.connection.transportRequestClass = RPCRequest.RPCRequestClassGeneric;
|
||||
}
|
||||
|
||||
@ -168,7 +165,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
if (Arrays.equals(authNonce, resPq.nonce)) {
|
||||
final HashMap<String, Object> publicKey = selectPublicKey(resPq.server_public_key_fingerprints);
|
||||
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);
|
||||
return;
|
||||
}
|
||||
@ -222,8 +219,10 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
SerializedData dataWithHash = new SerializedData();
|
||||
dataWithHash.writeRaw(Utilities.computeSHA1(innerDataBytes));
|
||||
dataWithHash.writeRaw(innerDataBytes);
|
||||
byte[] b = new byte[1];
|
||||
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());
|
||||
@ -251,7 +250,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.e("tmessages", "***** Error: invalid handshake nonce");
|
||||
FileLog.e("tmessages", "***** Error: invalid handshake nonce");
|
||||
beginHandshake(false);
|
||||
}
|
||||
} else if (message instanceof TLRPC.Server_DH_Params) {
|
||||
@ -309,7 +308,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
}
|
||||
|
||||
if (!hashVerified) {
|
||||
Log.e("tmessages", "***** Couldn't decode DH params");
|
||||
FileLog.e("tmessages", "***** Couldn't decode DH params");
|
||||
beginHandshake(false);
|
||||
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);
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(authNonce, dhInnerData.nonce)) {
|
||||
Log.e("tmessages", "***** Invalid DH nonce");
|
||||
FileLog.e("tmessages", "***** Invalid DH nonce");
|
||||
beginHandshake(false);
|
||||
return;
|
||||
}
|
||||
if (!Arrays.equals(authServerNonce, dhInnerData.server_nonce)) {
|
||||
Log.e("tmessages", "***** Invalid DH server nonce");
|
||||
FileLog.e("tmessages", "***** Invalid DH server nonce");
|
||||
beginHandshake(false);
|
||||
return;
|
||||
}
|
||||
@ -380,9 +379,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
serverSalt.validUntil = (int)(System.currentTimeMillis() / 1000) + timeDifference + 30 * 60;
|
||||
serverSalt.value = saltBuffer.getLong();
|
||||
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", String.format(Locale.US, "===== Time difference: %d", timeDifference));
|
||||
}
|
||||
FileLog.d("tmessages", String.format(Locale.US, "===== Time difference: %d", timeDifference));
|
||||
|
||||
TLRPC.TL_client_DH_inner_data clientInnerData = new TLRPC.TL_client_DH_inner_data();
|
||||
clientInnerData.nonce = authNonce;
|
||||
@ -396,8 +393,10 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
SerializedData clientDataWithHash = new SerializedData();
|
||||
clientDataWithHash.writeRaw(Utilities.computeSHA1(clientInnerDataBytes));
|
||||
clientDataWithHash.writeRaw(clientInnerDataBytes);
|
||||
byte[] bb = new byte[1];
|
||||
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();
|
||||
@ -413,19 +412,19 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
reqDHMsgData = null;
|
||||
setClientDHParamsMsgData = sendMessageData(setClientDhParams, generateMessageId());
|
||||
} else {
|
||||
Log.e("tmessages", "***** Couldn't set DH params");
|
||||
FileLog.e("tmessages", "***** Couldn't set DH params");
|
||||
beginHandshake(false);
|
||||
}
|
||||
} else if (message instanceof TLRPC.Set_client_DH_params_answer) {
|
||||
TLRPC.Set_client_DH_params_answer dhAnswer = (TLRPC.Set_client_DH_params_answer)message;
|
||||
|
||||
if (!Arrays.equals(authNonce, dhAnswer.nonce)) {
|
||||
Log.e("tmessages", "***** Invalid DH answer nonce");
|
||||
FileLog.e("tmessages", "***** Invalid DH answer nonce");
|
||||
beginHandshake(false);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
return;
|
||||
}
|
||||
@ -468,12 +467,12 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
if (message instanceof TLRPC.TL_dh_gen_ok) {
|
||||
TLRPC.TL_dh_gen_ok dhGenOk = (TLRPC.TL_dh_gen_ok)message;
|
||||
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);
|
||||
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;
|
||||
|
||||
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) {
|
||||
TLRPC.TL_dh_gen_retry dhRetry = (TLRPC.TL_dh_gen_retry)message;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
Log.d("tmessages", "***** Retry DH");
|
||||
FileLog.d("tmessages", "***** Retry DH");
|
||||
beginHandshake(false);
|
||||
} else if (message instanceof TLRPC.TL_dh_gen_fail) {
|
||||
TLRPC.TL_dh_gen_fail dhFail = (TLRPC.TL_dh_gen_fail)message;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
Log.d("tmessages", "***** Server declined DH params");
|
||||
FileLog.d("tmessages", "***** Server declined DH params");
|
||||
beginHandshake(false);
|
||||
} else {
|
||||
Log.e("tmessages", "***** Unknown DH params response");
|
||||
FileLog.e("tmessages", "***** Unknown DH params response");
|
||||
beginHandshake(false);
|
||||
}
|
||||
} 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
|
||||
public void tcpConnectionClosed(TcpConnection connection) {
|
||||
wasDisconnect = true;
|
||||
@ -553,7 +557,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
if (keyId == 0) {
|
||||
long messageId = is.readInt64();
|
||||
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;
|
||||
}
|
||||
int messageLength = is.readInt32();
|
||||
@ -566,7 +570,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
|
||||
}
|
||||
processMessage(object, messageId);
|
||||
} else {
|
||||
Log.d("tmessages", "***** Received encrypted message while in handshake, restarting");
|
||||
FileLog.d("tmessages", "***** Received encrypted message while in handshake, restarting");
|
||||
beginHandshake(true);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -144,7 +144,7 @@ public class LruCache {
|
||||
evictionCount++;
|
||||
}
|
||||
|
||||
String[] args = key.split("$");
|
||||
String[] args = key.split("@");
|
||||
if (args.length > 1) {
|
||||
ArrayList<String> arr = mapFilters.get(args[0]);
|
||||
if (arr != null) {
|
||||
@ -178,7 +178,7 @@ public class LruCache {
|
||||
}
|
||||
|
||||
if (previous != null) {
|
||||
String[] args = key.split("$");
|
||||
String[] args = key.split("@");
|
||||
if (args.length > 1) {
|
||||
ArrayList<String> arr = mapFilters.get(args[0]);
|
||||
if (arr != null) {
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -9,6 +9,7 @@
|
||||
package org.telegram.messenger;
|
||||
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
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 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("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_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 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 ttl_idx_messages ON messages(ttl);").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 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("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 {
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='params'");
|
||||
boolean create = false;
|
||||
@ -114,9 +120,21 @@ public class MessagesStorage {
|
||||
}
|
||||
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) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +171,7 @@ public class MessagesStorage {
|
||||
old.delete();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
openDatabase();
|
||||
}
|
||||
@ -176,7 +194,7 @@ public class MessagesStorage {
|
||||
state.step();
|
||||
state.dispose();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -195,7 +213,7 @@ public class MessagesStorage {
|
||||
state.step();
|
||||
state.dispose();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -222,7 +240,7 @@ public class MessagesStorage {
|
||||
state.dispose();
|
||||
database.commitTransaction();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -246,7 +264,7 @@ public class MessagesStorage {
|
||||
cursor.dispose();
|
||||
NotificationCenter.Instance.postNotificationName(wallpapersDidLoaded, wallPapers);
|
||||
} 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 media WHERE uid = " + did).stepThis().dispose();
|
||||
} 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();
|
||||
MessagesController.Instance.processLoadedDeleteTask(taskId, date, arr);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -311,7 +393,7 @@ public class MessagesStorage {
|
||||
int minDate = Integer.MAX_VALUE;
|
||||
SparseArray<ArrayList<Integer>> messages = new SparseArray<ArrayList<Integer>>();
|
||||
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()) {
|
||||
int mid = cursor.intValue(0);
|
||||
int ttl = cursor.intValue(1);
|
||||
@ -358,7 +440,7 @@ public class MessagesStorage {
|
||||
MessagesController.Instance.didAddedNewTask(minDate);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -557,7 +639,7 @@ public class MessagesStorage {
|
||||
MessagesController.Instance.processDialogsUpdate(dialogs, encryptedChats);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -601,7 +683,7 @@ public class MessagesStorage {
|
||||
state.step();
|
||||
state.dispose();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -650,7 +732,7 @@ public class MessagesStorage {
|
||||
}
|
||||
MessagesController.Instance.processChatInfo(chat_id, info, loadedUsers, true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -662,15 +744,15 @@ public class MessagesStorage {
|
||||
public void run() {
|
||||
try {
|
||||
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 {
|
||||
database.beginTransaction();
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO pending_read VALUES(?, ?)");
|
||||
SQLitePreparedStatement state;/*) = database.executeFast("REPLACE INTO pending_read VALUES(?, ?)");
|
||||
state.requery();
|
||||
state.bindLong(1, dialog_id);
|
||||
state.bindInteger(2, max_id);
|
||||
state.step();
|
||||
state.dispose();
|
||||
state.dispose();*/
|
||||
|
||||
int lower_id = (int)dialog_id;
|
||||
|
||||
@ -699,7 +781,7 @@ public class MessagesStorage {
|
||||
database.commitTransaction();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -711,13 +793,13 @@ public class MessagesStorage {
|
||||
public void run() {
|
||||
try {
|
||||
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>());
|
||||
return;
|
||||
}
|
||||
ArrayList<TLObject> resultArray = new ArrayList<TLObject>();
|
||||
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");
|
||||
while (cursor.next()) {
|
||||
@ -797,7 +879,7 @@ public class MessagesStorage {
|
||||
cursor.dispose();
|
||||
NotificationCenter.Instance.postNotificationName(MessagesController.reloadSearchResults, token, resultArray, resultArrayNames, encUsers);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -825,7 +907,7 @@ public class MessagesStorage {
|
||||
state.dispose();
|
||||
database.commitTransaction();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -873,7 +955,7 @@ public class MessagesStorage {
|
||||
}
|
||||
MessagesController.Instance.processLoadedContacts(contacts, users, 1);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -891,7 +973,7 @@ public class MessagesStorage {
|
||||
state2.step();
|
||||
state2.dispose();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -921,7 +1003,7 @@ public class MessagesStorage {
|
||||
}
|
||||
MessagesController.Instance.processLoadedMediaCount(count, uid, classGuid, true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -938,7 +1020,6 @@ public class MessagesStorage {
|
||||
|
||||
SQLiteCursor cursor;
|
||||
|
||||
|
||||
if ((int)uid != 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));
|
||||
@ -996,7 +1077,7 @@ public class MessagesStorage {
|
||||
res.messages.clear();
|
||||
res.chats.clear();
|
||||
res.users.clear();
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
MessagesController.Instance.processLoadedMedia(res, uid, offset, count, max_id, true, classGuid);
|
||||
}
|
||||
@ -1021,55 +1102,112 @@ public class MessagesStorage {
|
||||
state2.bindInteger(3, message.date);
|
||||
state2.bindByteArray(4, data.toByteArray());
|
||||
state2.step();
|
||||
} else {
|
||||
Log.e("tmessages", "test");
|
||||
}
|
||||
}
|
||||
state2.dispose();
|
||||
database.commitTransaction();
|
||||
} 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() {
|
||||
@Override
|
||||
public void run() {
|
||||
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 {
|
||||
ArrayList<Integer> loadedUsers = new ArrayList<Integer>();
|
||||
ArrayList<Integer> fromUser = new ArrayList<Integer>();
|
||||
|
||||
SQLiteCursor cursor;
|
||||
int lower_id = (int)dialog_id;
|
||||
|
||||
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) {
|
||||
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 {
|
||||
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 {
|
||||
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 date DESC, mid DESC LIMIT %d", dialog_id, max_id, count));
|
||||
} else {
|
||||
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));
|
||||
if (from_unread) {
|
||||
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));
|
||||
if (cursor.next()) {
|
||||
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 {
|
||||
if (minDate != 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 LIMIT %d", dialog_id, max_id, minDate, count));
|
||||
} 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 LIMIT %d,%d", dialog_id, minDate, offset, count));
|
||||
}
|
||||
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 mid DESC LIMIT %d", dialog_id, max_id, count_query));
|
||||
} else if (minDate != 0) {
|
||||
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));
|
||||
} else {
|
||||
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 date DESC LIMIT %d", dialog_id, max_id, count));
|
||||
} else {
|
||||
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));
|
||||
if (from_unread) {
|
||||
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));
|
||||
if (cursor.next()) {
|
||||
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()) {
|
||||
@ -1131,9 +1269,9 @@ public class MessagesStorage {
|
||||
res.messages.clear();
|
||||
res.chats.clear();
|
||||
res.users.clear();
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} 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 {
|
||||
database.beginTransaction();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1155,7 +1293,7 @@ public class MessagesStorage {
|
||||
try {
|
||||
database.beginTransaction();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1187,7 +1325,7 @@ public class MessagesStorage {
|
||||
state.bindInteger(2, chat.id);
|
||||
state.step();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
if (state != null) {
|
||||
state.dispose();
|
||||
@ -1224,7 +1362,7 @@ public class MessagesStorage {
|
||||
state.bindInteger(5, chat.id);
|
||||
state.step();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
if (state != null) {
|
||||
state.dispose();
|
||||
@ -1278,7 +1416,7 @@ public class MessagesStorage {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
semaphore.release();
|
||||
}
|
||||
@ -1330,7 +1468,7 @@ public class MessagesStorage {
|
||||
state.dispose();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1389,7 +1527,7 @@ public class MessagesStorage {
|
||||
database.commitTransaction();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1546,7 +1684,7 @@ public class MessagesStorage {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1575,7 +1713,7 @@ public class MessagesStorage {
|
||||
state.bindInteger(2, newId);
|
||||
state.step();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
if (state != null) {
|
||||
state.dispose();
|
||||
@ -1592,7 +1730,7 @@ public class MessagesStorage {
|
||||
oldId = cursor.intValue(0);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.dispose();
|
||||
@ -1602,7 +1740,7 @@ public class MessagesStorage {
|
||||
// try {
|
||||
// database.executeFast(String.format(Locale.US, "DELETE FROM randoms WHERE random_id = %d", random_id)).stepThis().dispose();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// FileLog.e("tmessages", e);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@ -1617,7 +1755,7 @@ public class MessagesStorage {
|
||||
state.bindInteger(2, oldId);
|
||||
state.step();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
if (state != null) {
|
||||
state.dispose();
|
||||
@ -1630,7 +1768,7 @@ public class MessagesStorage {
|
||||
state.bindInteger(2, oldId);
|
||||
state.step();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
if (state != null) {
|
||||
state.dispose();
|
||||
@ -1643,7 +1781,7 @@ public class MessagesStorage {
|
||||
state.bindLong(2, oldId);
|
||||
state.step();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
if (state != null) {
|
||||
state.dispose();
|
||||
@ -1754,7 +1892,7 @@ public class MessagesStorage {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1802,7 +1940,7 @@ public class MessagesStorage {
|
||||
}
|
||||
}
|
||||
} 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();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2010,7 +2148,7 @@ public class MessagesStorage {
|
||||
MessagesController.Instance.processDialogsUpdate(dialogs, encryptedChats);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2129,7 +2267,7 @@ public class MessagesStorage {
|
||||
|
||||
database.commitTransaction();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -2228,7 +2366,7 @@ public class MessagesStorage {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
@ -2254,7 +2392,7 @@ public class MessagesStorage {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
@ -2283,7 +2421,7 @@ public class MessagesStorage {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
@ -2294,11 +2432,11 @@ public class MessagesStorage {
|
||||
dialogs.users.clear();
|
||||
dialogs.chats.clear();
|
||||
encryptedChats.clear();
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
/*try {
|
||||
database.executeFast("DELETE FROM dialogs WHERE 1").stepThis().dispose();
|
||||
} catch (Exception e2) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}*/
|
||||
MessagesController.Instance.processLoadedDialogs(dialogs, encryptedChats, 0, 0, 100, true, true);
|
||||
}
|
||||
@ -2412,7 +2550,7 @@ public class MessagesStorage {
|
||||
|
||||
database.commitTransaction();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,8 +8,6 @@
|
||||
|
||||
package org.telegram.messenger;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
@ -30,6 +28,11 @@ public class SerializedData {
|
||||
out = new DataOutputStream(outbuf);
|
||||
}
|
||||
|
||||
public SerializedData(int size) {
|
||||
outbuf = new ByteArrayOutputStream(size);
|
||||
out = new DataOutputStream(outbuf);
|
||||
}
|
||||
|
||||
public SerializedData(byte[] data){
|
||||
isOut = false;
|
||||
inbuf = new ByteArrayInputStream(data);
|
||||
@ -57,7 +60,7 @@ public class SerializedData {
|
||||
out.write(x >> (i * 8));
|
||||
}
|
||||
} 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)));
|
||||
}
|
||||
} 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) {
|
||||
return false;
|
||||
}
|
||||
Log.e("tmessages", "Not bool value!");
|
||||
FileLog.e("tmessages", "Not bool value!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -94,28 +97,48 @@ public class SerializedData {
|
||||
}
|
||||
}
|
||||
|
||||
public int readInt32(){
|
||||
public int readInt32() {
|
||||
return readInt32(null);
|
||||
}
|
||||
|
||||
public int readInt32(boolean[] error) {
|
||||
try {
|
||||
int i = 0;
|
||||
for(int j = 0; j < 4; j++){
|
||||
i |= (in.read() << (j * 8));
|
||||
}
|
||||
if (error != null) {
|
||||
error[0] = false;
|
||||
}
|
||||
return i;
|
||||
} catch(IOException x) {
|
||||
Log.e("tmessages", "read int32 error");
|
||||
if (error != null) {
|
||||
error[0] = true;
|
||||
}
|
||||
FileLog.e("tmessages", "read int32 error");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long readInt64(){
|
||||
public long readInt64() {
|
||||
return readInt64(null);
|
||||
}
|
||||
|
||||
public long readInt64(boolean[] error) {
|
||||
try {
|
||||
long i = 0;
|
||||
for(int j = 0; j < 8; j++){
|
||||
i |= ((long)in.read() << (j * 8));
|
||||
}
|
||||
if (error != null) {
|
||||
error[0] = false;
|
||||
}
|
||||
return i;
|
||||
} catch(IOException x) {
|
||||
Log.e("tmessages", "read int64 error");
|
||||
if (error != null) {
|
||||
error[0] = true;
|
||||
}
|
||||
FileLog.e("tmessages", "read int64 error");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -124,7 +147,7 @@ public class SerializedData {
|
||||
try {
|
||||
out.write(b);
|
||||
} catch(Exception x) {
|
||||
Log.e("tmessages", "write raw error");
|
||||
FileLog.e("tmessages", "write raw error");
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +155,7 @@ public class SerializedData {
|
||||
try {
|
||||
out.write(b, offset, count);
|
||||
} catch(Exception x) {
|
||||
Log.e("tmessages", "write raw error");
|
||||
FileLog.e("tmessages", "write raw error");
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +163,7 @@ public class SerializedData {
|
||||
try {
|
||||
out.writeByte((byte)i);
|
||||
} catch (Exception e) {
|
||||
Log.e("tmessages", "write byte error");
|
||||
FileLog.e("tmessages", "write byte error");
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +171,7 @@ public class SerializedData {
|
||||
try {
|
||||
out.writeByte(b);
|
||||
} catch (Exception e) {
|
||||
Log.e("tmessages", "write byte error");
|
||||
FileLog.e("tmessages", "write byte error");
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,7 +179,7 @@ public class SerializedData {
|
||||
try {
|
||||
in.read(b);
|
||||
} 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");
|
||||
} catch(Exception x) {
|
||||
Log.e("tmessages", "read string error");
|
||||
FileLog.e("tmessages", "read string error");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -205,7 +228,7 @@ public class SerializedData {
|
||||
}
|
||||
return b;
|
||||
} catch(Exception x) {
|
||||
Log.e("tmessages", "read byte array error");
|
||||
FileLog.e("tmessages", "read byte array error");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -226,8 +249,8 @@ public class SerializedData {
|
||||
out.write(0);
|
||||
i++;
|
||||
}
|
||||
}catch(Exception x) {
|
||||
Log.e("tmessages", "write byte array error");
|
||||
} catch(Exception x) {
|
||||
FileLog.e("tmessages", "write byte array error");
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,7 +258,7 @@ public class SerializedData {
|
||||
try {
|
||||
writeByteArray(s.getBytes("UTF-8"));
|
||||
} catch(Exception x) {
|
||||
Log.e("tmessages", "write string error");
|
||||
FileLog.e("tmessages", "write string error");
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,15 +279,15 @@ public class SerializedData {
|
||||
i++;
|
||||
}
|
||||
} catch(Exception x) {
|
||||
Log.e("tmessages", "write byte array error");
|
||||
FileLog.e("tmessages", "write byte array error");
|
||||
}
|
||||
}
|
||||
|
||||
public double readDouble(){
|
||||
public double readDouble() {
|
||||
try {
|
||||
return Double.longBitsToDouble(readInt64());
|
||||
} catch(Exception x) {
|
||||
Log.e("tmessages", "read double error");
|
||||
FileLog.e("tmessages", "read double error");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -273,7 +296,7 @@ public class SerializedData {
|
||||
try {
|
||||
writeInt64(Double.doubleToRawLongBits(d));
|
||||
} catch(Exception x) {
|
||||
Log.e("tmessages", "write double error");
|
||||
FileLog.e("tmessages", "write double error");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
|
@ -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.
|
||||
* 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) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,20 +8,16 @@
|
||||
|
||||
package org.telegram.messenger;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import jawnae.pyronet.PyroClient;
|
||||
import jawnae.pyronet.PyroSelector;
|
||||
import jawnae.pyronet.events.PyroClientAdapter;
|
||||
import jawnae.pyronet.PyroClientAdapter;
|
||||
|
||||
public class TcpConnection extends PyroClientAdapter {
|
||||
public enum TcpConnectionState {
|
||||
@ -37,19 +33,23 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
public abstract void tcpConnectionConnected(TcpConnection connection);
|
||||
public abstract void tcpConnectionQuiackAckReceived(TcpConnection connection, int ack);
|
||||
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 PyroClient client;
|
||||
public TcpConnectionState connectionState;
|
||||
private Queue<byte[]> packetsQueue;
|
||||
public volatile int channelToken = 0;
|
||||
private String hostAddress;
|
||||
private int hostPort;
|
||||
public int datacenterId;
|
||||
private int datacenterId;
|
||||
private int failedConnectionCount;
|
||||
public TcpConnectionDelegate delegate;
|
||||
private ByteBuffer restOfTheData;
|
||||
private long lastMessageId = 0;
|
||||
private boolean hasSomeDataSinceLastConnect = false;
|
||||
private int willRetryConnectCount = 5;
|
||||
private boolean isNextPort = false;
|
||||
|
||||
public int transportRequestClass;
|
||||
|
||||
@ -57,14 +57,12 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
|
||||
private Timer reconnectTimer;
|
||||
|
||||
public TcpConnection(String ip, int port) {
|
||||
public TcpConnection(int did) {
|
||||
if (selector == null) {
|
||||
selector = new PyroSelector();
|
||||
selector.spawnNetworkThread("network thread");
|
||||
}
|
||||
packetsQueue = new LinkedList<byte[]>();
|
||||
hostAddress = ip;
|
||||
hostPort = port;
|
||||
datacenterId = did;
|
||||
connectionState = TcpConnectionState.TcpConnectionStageIdle;
|
||||
}
|
||||
|
||||
@ -73,74 +71,142 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
return nextChannelToken++;
|
||||
}
|
||||
|
||||
public int getDatacenterId() {
|
||||
return datacenterId;
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
selector.scheduleTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (connectionState == TcpConnectionState.TcpConnectionStageConnected || connectionState == TcpConnectionState.TcpConnectionStageConnecting) {
|
||||
if ((connectionState == TcpConnectionState.TcpConnectionStageConnected || connectionState == TcpConnectionState.TcpConnectionStageConnecting) && client != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
connectionState = TcpConnectionState.TcpConnectionStageConnecting;
|
||||
try {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", String.format(this + " Connecting (%s:%d)", hostAddress, hostPort));
|
||||
}
|
||||
Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId);
|
||||
hostAddress = datacenter.getCurrentAddress();
|
||||
hostPort = datacenter.getCurrentPort();
|
||||
FileLog.d("tmessages", String.format(TcpConnection.this + " Connecting (%s:%d)", hostAddress, hostPort));
|
||||
firstPacket = true;
|
||||
restOfTheData = null;
|
||||
hasSomeDataSinceLastConnect = false;
|
||||
if (client != null) {
|
||||
client.removeListener(TcpConnection.this);
|
||||
client.dropConnection();
|
||||
client = null;
|
||||
}
|
||||
client = selector.connect(new InetSocketAddress(hostAddress, hostPort));
|
||||
client.addListener(TcpConnection.this);
|
||||
client.setTimeout(35000);
|
||||
if (isNextPort) {
|
||||
client.setTimeout(8000);
|
||||
} else {
|
||||
client.setTimeout(35000);
|
||||
}
|
||||
selector.wakeup();
|
||||
} 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) {
|
||||
if (task) {
|
||||
selector.scheduleTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (reconnectTimer != null) {
|
||||
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;
|
||||
}
|
||||
suspendConnectionInternal();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (reconnectTimer != null) {
|
||||
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;
|
||||
}
|
||||
suspendConnectionInternal();
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,10 +226,14 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
public void run() {
|
||||
if (connectionState == TcpConnectionState.TcpConnectionStageIdle ||
|
||||
connectionState == TcpConnectionState.TcpConnectionStageReconnecting ||
|
||||
connectionState == TcpConnectionState.TcpConnectionStageSuspended) {
|
||||
connectionState == TcpConnectionState.TcpConnectionStageSuspended || client == null) {
|
||||
connect();
|
||||
}
|
||||
|
||||
if (client == null || client.isDisconnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int packetLength = data.length / 4;
|
||||
|
||||
SerializedData buffer = new SerializedData();
|
||||
@ -183,33 +253,22 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
|
||||
final byte[] packet = buffer.toByteArray();
|
||||
|
||||
if (client != null && !client.isDisconnected()) {
|
||||
ByteBuffer sendBuffer = ByteBuffer.allocate((firstPacket ? 1 : 0) + packet.length);
|
||||
sendBuffer.rewind();
|
||||
sendBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
if (firstPacket) {
|
||||
sendBuffer.put((byte)0xef);
|
||||
firstPacket = false;
|
||||
}
|
||||
sendBuffer.put(packet);
|
||||
sendBuffer.rewind();
|
||||
client.write(sendBuffer);
|
||||
} else {
|
||||
packetsQueue.add(packet);
|
||||
ByteBuffer sendBuffer = ByteBuffer.allocate((firstPacket ? 1 : 0) + packet.length);
|
||||
sendBuffer.rewind();
|
||||
sendBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
if (firstPacket) {
|
||||
sendBuffer.put((byte)0xef);
|
||||
firstPacket = false;
|
||||
}
|
||||
sendBuffer.put(packet);
|
||||
sendBuffer.rewind();
|
||||
client.write(sendBuffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void readData(ByteBuffer buffer) throws Exception {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", "received data = " + buffer.limit());
|
||||
}
|
||||
|
||||
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());
|
||||
newBuffer.put(restOfTheData);
|
||||
newBuffer.put(buffer);
|
||||
@ -221,6 +280,13 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
buffer.rewind();
|
||||
|
||||
while (buffer.hasRemaining()) {
|
||||
if (!hasSomeDataSinceLastConnect) {
|
||||
Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId);
|
||||
datacenter.storeCurrentAddressAndPortNum();
|
||||
isNextPort = false;
|
||||
client.setTimeout(35000);
|
||||
}
|
||||
hasSomeDataSinceLastConnect = true;
|
||||
|
||||
int currentPacketLength;
|
||||
buffer.mark();
|
||||
@ -261,17 +327,38 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
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 (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", this + " Received message len " + currentPacketLength + " but packet larger " + buffer.remaining());
|
||||
}
|
||||
FileLog.d("tmessages", TcpConnection.this + " Received message len " + currentPacketLength + " but packet larger " + buffer.remaining());
|
||||
lastMessageId = 0;
|
||||
} else if (currentPacketLength == buffer.remaining()) {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", this + " Received message len " + currentPacketLength + " equal to packet size");
|
||||
}
|
||||
FileLog.d("tmessages", TcpConnection.this + " Received message len " + currentPacketLength + " equal to packet size");
|
||||
lastMessageId = 0;
|
||||
} else {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", this + " Received packet size less(" + buffer.remaining() + ") then message size(" + currentPacketLength + ")");
|
||||
FileLog.d("tmessages", TcpConnection.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();
|
||||
restOfTheData = ByteBuffer.allocate(buffer.remaining());
|
||||
@ -281,14 +368,6 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
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];
|
||||
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) {
|
||||
reconnectTimer.cancel();
|
||||
reconnectTimer = null;
|
||||
}
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
if (e != null) {
|
||||
Log.d("tmessages", "Disconnected " + this + " with error " + e);
|
||||
} else {
|
||||
Log.d("tmessages", "Disconnected " + this);
|
||||
}
|
||||
if (e != null) {
|
||||
FileLog.d("tmessages", "Disconnected " + TcpConnection.this + " with error " + e);
|
||||
} else {
|
||||
FileLog.d("tmessages", "Disconnected " + TcpConnection.this);
|
||||
}
|
||||
firstPacket = true;
|
||||
restOfTheData = null;
|
||||
packetsQueue.clear();
|
||||
channelToken = 0;
|
||||
if (connectionState != TcpConnectionState.TcpConnectionStageSuspended && connectionState != TcpConnectionState.TcpConnectionStageIdle) {
|
||||
connectionState = TcpConnectionState.TcpConnectionStageIdle;
|
||||
@ -330,12 +406,23 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (connectionState == TcpConnectionState.TcpConnectionStageIdle && (!packetsQueue.isEmpty() ||
|
||||
(transportRequestClass & RPCRequest.RPCRequestClassGeneric) != 0 && (datacenterId == ConnectionsManager.Instance.currentDatacenterId || datacenterId == ConnectionsManager.Instance.movingToDatacenterId))) {
|
||||
if (connectionState == TcpConnectionState.TcpConnectionStageIdle &&
|
||||
((transportRequestClass & RPCRequest.RPCRequestClassGeneric) != 0 && (datacenterId == ConnectionsManager.Instance.currentDatacenterId || datacenterId == ConnectionsManager.Instance.movingToDatacenterId))) {
|
||||
failedConnectionCount++;
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", "Reconnect " + hostAddress + ":" + hostPort + " " + this);
|
||||
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.d("tmessages", "Reconnect " + hostAddress + ":" + hostPort + " " + TcpConnection.this);
|
||||
try {
|
||||
reconnectTimer = new Timer();
|
||||
reconnectTimer.schedule(new TimerTask() {
|
||||
@ -350,29 +437,24 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
reconnectTimer = null;
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();
|
||||
FileLog.e("tmessages", e2);
|
||||
}
|
||||
connect();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, failedConnectionCount > 10 ? 500 : 200, failedConnectionCount > 10 ? 500 : 200);
|
||||
}, failedConnectionCount > 3 ? 500 : 300, failedConnectionCount > 3 ? 500 : 300);
|
||||
} catch (Exception e3) {
|
||||
e3.printStackTrace();
|
||||
FileLog.e("tmessages", e3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectedClient(PyroClient client) {
|
||||
//if (!ConnectionsManager.isNetworkOnline()) {
|
||||
// return;
|
||||
//}
|
||||
connectionState = TcpConnectionState.TcpConnectionStageConnected;
|
||||
channelToken = generateChannelToken();
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", String.format(this + " Connected (%s:%d)", hostAddress, hostPort));
|
||||
}
|
||||
FileLog.d("tmessages", String.format(TcpConnection.this + " Connected (%s:%d)", hostAddress, hostPort));
|
||||
if (delegate != null) {
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@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
|
||||
public void unconnectableClient(PyroClient client) {
|
||||
handleDisconnect(client, null);
|
||||
public void unconnectableClient(PyroClient client, Exception cause) {
|
||||
handleDisconnect(client, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -417,9 +487,7 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
failedConnectionCount = 0;
|
||||
readData(data);
|
||||
} catch (Exception e) {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", "read data error");
|
||||
}
|
||||
FileLog.d("tmessages", "read data error");
|
||||
reconnect();
|
||||
}
|
||||
}
|
||||
@ -427,8 +495,6 @@ public class TcpConnection extends PyroClientAdapter {
|
||||
@Override
|
||||
public void sentData(PyroClient client, int bytes) {
|
||||
failedConnectionCount = 0;
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.d("tmessages", this + " bytes sent " + bytes);
|
||||
}
|
||||
FileLog.d("tmessages", TcpConnection.this + " bytes sent " + bytes);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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.
|
||||
* 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.SharedPreferences;
|
||||
import android.util.Base64;
|
||||
|
||||
import org.telegram.TL.TLClassStore;
|
||||
import org.telegram.TL.TLRPC;
|
||||
import org.telegram.ui.ApplicationLoader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class UserConfig {
|
||||
public static TLRPC.User currentUser;
|
||||
@ -24,8 +24,8 @@ public class UserConfig {
|
||||
public static boolean clientActivated = false;
|
||||
public static boolean registeredForPush = false;
|
||||
public static String pushString = "";
|
||||
public static int lastSendMessageId = -1;
|
||||
public static int lastLocalId = -1;
|
||||
public static int lastSendMessageId = -210000;
|
||||
public static int lastLocalId = -210000;
|
||||
public static String contactsHash = "";
|
||||
public static String importHash = "";
|
||||
private final static Integer sync = 1;
|
||||
@ -41,45 +41,53 @@ public class UserConfig {
|
||||
}
|
||||
|
||||
public static void saveConfig(boolean withFile) {
|
||||
saveConfig(withFile, null);
|
||||
}
|
||||
|
||||
public static void saveConfig(boolean withFile, File oldFile) {
|
||||
synchronized (sync) {
|
||||
SerializedData data = new SerializedData();
|
||||
if (currentUser != null) {
|
||||
data.writeInt32(2);
|
||||
currentUser.serializeToStream(data);
|
||||
clientUserId = currentUser.id;
|
||||
clientActivated = true;
|
||||
try {
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putBoolean("registeredForPush", registeredForPush);
|
||||
editor.putString("pushString", pushString);
|
||||
editor.putInt("lastSendMessageId", lastSendMessageId);
|
||||
editor.putInt("lastLocalId", lastLocalId);
|
||||
editor.putString("contactsHash", contactsHash);
|
||||
editor.putString("importHash", importHash);
|
||||
editor.putBoolean("saveIncomingPhotos", saveIncomingPhotos);
|
||||
editor.commit();
|
||||
} else {
|
||||
data.writeInt32(0);
|
||||
}
|
||||
if (withFile) {
|
||||
try {
|
||||
File configFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "user.dat");
|
||||
if (!configFile.exists()) {
|
||||
configFile.createNewFile();
|
||||
if (currentUser != null) {
|
||||
editor.putBoolean("registeredForPush", registeredForPush);
|
||||
editor.putString("pushString", pushString);
|
||||
editor.putInt("lastSendMessageId", lastSendMessageId);
|
||||
editor.putInt("lastLocalId", lastLocalId);
|
||||
editor.putString("contactsHash", contactsHash);
|
||||
editor.putString("importHash", importHash);
|
||||
editor.putBoolean("saveIncomingPhotos", saveIncomingPhotos);
|
||||
if (withFile) {
|
||||
SerializedData data = new SerializedData();
|
||||
currentUser.serializeToStream(data);
|
||||
clientUserId = currentUser.id;
|
||||
clientActivated = true;
|
||||
String userString = Base64.encodeToString(data.toByteArray(), Base64.DEFAULT);
|
||||
editor.putString("user", userString);
|
||||
}
|
||||
FileOutputStream stream = new FileOutputStream(configFile);
|
||||
stream.write(data.toByteArray());
|
||||
stream.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
editor.putBoolean("registeredForPush", registeredForPush);
|
||||
editor.putString("pushString", pushString);
|
||||
editor.putInt("lastSendMessageId", lastSendMessageId);
|
||||
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() {
|
||||
synchronized (sync) {
|
||||
File configFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "user.dat");
|
||||
final File configFile = new File(ApplicationLoader.applicationContext.getFilesDir(), "user.dat");
|
||||
if (configFile.exists()) {
|
||||
try {
|
||||
SerializedData data = new SerializedData(configFile);
|
||||
@ -113,6 +121,12 @@ public class UserConfig {
|
||||
MessagesStorage.secretPBytes = data.readByteArray();
|
||||
}
|
||||
MessagesStorage.secretG = data.readInt32();
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
saveConfig(true, configFile);
|
||||
}
|
||||
});
|
||||
} else if (ver == 2) {
|
||||
int constructor = data.readInt32();
|
||||
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);
|
||||
registeredForPush = preferences.getBoolean("registeredForPush", false);
|
||||
pushString = preferences.getString("pushString", "");
|
||||
lastSendMessageId = preferences.getInt("lastSendMessageId", -1);
|
||||
lastLocalId = preferences.getInt("lastLocalId", -1);
|
||||
lastSendMessageId = preferences.getInt("lastSendMessageId", -210000);
|
||||
lastLocalId = preferences.getInt("lastLocalId", -210000);
|
||||
contactsHash = preferences.getString("contactsHash", "");
|
||||
importHash = preferences.getString("importHash", "");
|
||||
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) {
|
||||
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;
|
||||
registeredForPush = false;
|
||||
contactsHash = "";
|
||||
lastLocalId = -1;
|
||||
lastLocalId = -210000;
|
||||
importHash = "";
|
||||
lastSendMessageId = -1;
|
||||
lastSendMessageId = -210000;
|
||||
saveIncomingPhotos = false;
|
||||
saveConfig(true);
|
||||
MessagesController.Instance.deleteAllAppAccounts();
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* 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.format.DateFormat;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
@ -53,6 +52,7 @@ import javax.crypto.Cipher;
|
||||
|
||||
public class Utilities {
|
||||
public static Handler applicationHandler;
|
||||
public static int statusBarHeight = 0;
|
||||
private final static Integer lock = 1;
|
||||
|
||||
public static class TPFactorizedValue {
|
||||
@ -63,7 +63,7 @@ public class Utilities {
|
||||
public static DispatchQueue globalQueue = new DispatchQueue("globalQueue");
|
||||
public static DispatchQueue cacheOutQueue = new DispatchQueue("cacheOutQueue");
|
||||
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 byte[] aesIgeEncryption(byte[] _what, byte[] _key, byte[] _iv, boolean encrypt, boolean changeIv);
|
||||
@ -101,7 +101,7 @@ public class Utilities {
|
||||
|
||||
return result;
|
||||
} 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();
|
||||
result.p = 0;
|
||||
result.q = 0;
|
||||
@ -113,8 +113,8 @@ public class Utilities {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||
return md.digest(convertme);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -128,7 +128,7 @@ public class Utilities {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
return cipher.doFinal(data);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -219,7 +219,7 @@ public class Utilities {
|
||||
SerializedData stream = new SerializedData(bytesOutput.toByteArray());
|
||||
return TLClassStore.Instance().TLdeserialize(stream, stream.readInt32(), parentObject);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -235,8 +235,7 @@ public class Utilities {
|
||||
assetPath);
|
||||
cache.put(assetPath, t);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not get typeface '" + assetPath
|
||||
+ "' because " + e.getMessage());
|
||||
FileLog.e(TAG, "Could not get typeface '" + assetPath + "' because " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -258,8 +257,7 @@ public class Utilities {
|
||||
if (view == null) {
|
||||
return false;
|
||||
}
|
||||
InputMethodManager inputManager = (InputMethodManager) view
|
||||
.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
return inputManager.isActive(view);
|
||||
}
|
||||
|
||||
@ -267,10 +265,10 @@ public class Utilities {
|
||||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
InputMethodManager imm = (InputMethodManager) view.getContext()
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (!imm.isActive())
|
||||
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (!imm.isActive()) {
|
||||
return;
|
||||
}
|
||||
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
||||
}
|
||||
|
||||
@ -279,18 +277,21 @@ public class Utilities {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressDialog = new ProgressDialog(activity);
|
||||
if (message != null) {
|
||||
progressDialog.setMessage(message);
|
||||
if(!activity.isFinishing()) {
|
||||
progressDialog = new ProgressDialog(activity);
|
||||
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 formatterWeek;
|
||||
public static FastDateFormat formatterMonth;
|
||||
public static FastDateFormat formatterYear;
|
||||
public static FastDateFormat formatterYearMax;
|
||||
@ -300,11 +301,21 @@ public class Utilities {
|
||||
static {
|
||||
Locale locale = Locale.getDefault();
|
||||
String lang = locale.getLanguage();
|
||||
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);
|
||||
if (lang.equals("en")) {
|
||||
formatterMonth = FastDateFormat.getInstance("MMM dd", locale);
|
||||
formatterYear = FastDateFormat.getInstance("dd.MM.yy", locale);
|
||||
formatterYearMax = FastDateFormat.getInstance("dd.MM.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 (DateFormat.is24HourFormat(ApplicationLoader.applicationContext)) {
|
||||
formatterDay = FastDateFormat.getInstance("HH:mm", locale);
|
||||
@ -394,7 +405,7 @@ public class Utilities {
|
||||
destination = new FileOutputStream(destFile).getChannel();
|
||||
destination.transferFrom(source, 0, source.size());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
result = false;
|
||||
} finally {
|
||||
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[] arrUsersAvatars = {
|
||||
R.drawable.user_placeholder_red,
|
||||
R.drawable.user_placeholder_green,
|
||||
R.drawable.user_placeholder_yellow,
|
||||
R.drawable.user_placeholder_blue,
|
||||
R.drawable.user_placeholder_purple,
|
||||
R.drawable.user_placeholder_pink,
|
||||
R.drawable.user_placeholder_cyan,
|
||||
R.drawable.user_placeholder_orange};
|
||||
R.drawable.user_red,
|
||||
R.drawable.user_green,
|
||||
R.drawable.user_yellow,
|
||||
R.drawable.user_blue,
|
||||
R.drawable.user_violet,
|
||||
R.drawable.user_pink,
|
||||
R.drawable.user_aqua,
|
||||
R.drawable.user_orange};
|
||||
|
||||
public static int[] arrGroupsAvatars = {
|
||||
R.drawable.group_placeholder_green,
|
||||
R.drawable.group_placeholder_red,
|
||||
R.drawable.group_placeholder_blue,
|
||||
R.drawable.group_placeholder_yellow};
|
||||
R.drawable.group_green,
|
||||
R.drawable.group_red,
|
||||
R.drawable.group_blue,
|
||||
R.drawable.group_yellow};
|
||||
|
||||
public static int getColorIndex(int id) {
|
||||
int[] arr;
|
||||
@ -458,7 +469,7 @@ public class Utilities {
|
||||
}
|
||||
return Math.abs(b) % arr.length;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
return id % arr.length;
|
||||
}
|
||||
@ -491,7 +502,7 @@ public class Utilities {
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (java.security.NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -523,14 +534,13 @@ public class Utilities {
|
||||
if (storageDir != null) {
|
||||
if (! storageDir.mkdirs()) {
|
||||
if (! storageDir.exists()){
|
||||
Log.d("tmessages", "failed to create directory");
|
||||
FileLog.d("tmessages", "failed to create directory");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
Log.v("tmessages", "External storage is not mounted READ/WRITE.");
|
||||
FileLog.d("tmessages", "External storage is not mounted READ/WRITE.");
|
||||
}
|
||||
|
||||
return storageDir;
|
||||
@ -543,7 +553,7 @@ public class Utilities {
|
||||
String imageFileName = "IMG_" + timeStamp + "_";
|
||||
return File.createTempFile(imageFileName, ".jpg", storageDir);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -560,6 +570,7 @@ public class Utilities {
|
||||
} else if (name2 != null && name2.length() != 0) {
|
||||
wholeString += " " + name2;
|
||||
}
|
||||
wholeString = wholeString.trim();
|
||||
String[] args = wholeString.split(" ");
|
||||
|
||||
for (String arg : args) {
|
||||
@ -571,7 +582,7 @@ public class Utilities {
|
||||
builder.append(" ");
|
||||
}
|
||||
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());
|
||||
builder.append(str);
|
||||
} else {
|
||||
@ -597,7 +608,7 @@ public class Utilities {
|
||||
return new File(ApplicationLoader.applicationContext.getCacheDir(), fileName);
|
||||
*/
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -611,4 +622,26 @@ public class Utilities {
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* 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);
|
||||
}
|
||||
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) {
|
||||
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 {
|
||||
TLRPC.User who = users.get(message.action.user_id);
|
||||
String str = ApplicationLoader.applicationContext.getResources().getString(R.string.ActionKickUser);
|
||||
messageText = str.replace("un2", Utilities.formatName(who.first_name, who.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
|
||||
if (who == null) {
|
||||
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) {
|
||||
TLRPC.User whoUser = users.get(message.action.user_id);
|
||||
String str = ApplicationLoader.applicationContext.getResources().getString(R.string.ActionAddUser);
|
||||
messageText = str.replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
|
||||
if (whoUser == null) {
|
||||
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) {
|
||||
photoThumbs = new ArrayList<PhotoObject>();
|
||||
for (TLRPC.PhotoSize size : message.action.photo.sizes) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
if (message.action.ttl != 0) {
|
||||
String timeString;
|
||||
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) {
|
||||
timeString = ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetime5s);
|
||||
timeString = ApplicationLoader.applicationContext.getString(R.string.MessageLifetime5s);
|
||||
} 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) {
|
||||
timeString = ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetime1h);
|
||||
timeString = ApplicationLoader.applicationContext.getString(R.string.MessageLifetime1h);
|
||||
} 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) {
|
||||
timeString = ApplicationLoader.applicationContext.getResources().getString(R.string.MessageLifetime1w);
|
||||
timeString = ApplicationLoader.applicationContext.getString(R.string.MessageLifetime1w);
|
||||
} else {
|
||||
timeString = String.format("%d", message.action.ttl);
|
||||
}
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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)) {
|
||||
@ -108,7 +196,7 @@ public class MessageObject {
|
||||
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) {
|
||||
photoThumbs = new ArrayList<PhotoObject>();
|
||||
PhotoObject obj = new PhotoObject(message.media.video.thumb);
|
||||
@ -116,11 +204,13 @@ public class MessageObject {
|
||||
if (imagePreview == null && obj.image != null) {
|
||||
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) {
|
||||
messageText = ApplicationLoader.applicationContext.getResources().getString(R.string.AttachLocation);
|
||||
messageText = ApplicationLoader.applicationContext.getString(R.string.AttachLocation);
|
||||
} 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 {
|
||||
messageText = message.message;
|
||||
@ -159,9 +249,15 @@ public class MessageObject {
|
||||
} else {
|
||||
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) {
|
||||
if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) {
|
||||
if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto || message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
|
||||
type = 11;
|
||||
} else {
|
||||
type = 10;
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -41,6 +41,9 @@ public class PhotoObject {
|
||||
int closestHeight = 9999;
|
||||
PhotoObject closestObject = null;
|
||||
for (PhotoObject obj : arr) {
|
||||
if (obj == null || obj.photoOwner == null) {
|
||||
continue;
|
||||
}
|
||||
int diffW = Math.abs(obj.photoOwner.w - width);
|
||||
int diffH = Math.abs(obj.photoOwner.h - height);
|
||||
if (closestObject == null || closestWidth > diffW && closestHeight > diffH || closestObject.photoOwner instanceof TLRPC.TL_photoCachedSize) {
|
||||
|
@ -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.
|
||||
* 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.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.text.Html;
|
||||
import android.view.Display;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
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.FileLog;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
@ -47,22 +44,28 @@ import net.hockeyapp.android.UpdateManager;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class ApplicationActivity extends SherlockFragmentActivity implements NotificationCenter.NotificationCenterDelegate, MessagesActivity.MessagesActivityDelegate {
|
||||
private View shadowView;
|
||||
public class ApplicationActivity extends ActionBarActivity implements NotificationCenter.NotificationCenterDelegate, MessagesActivity.MessagesActivityDelegate {
|
||||
private boolean finished = false;
|
||||
private NotificationView notificationView;
|
||||
String photoPath = null;
|
||||
String videoPath = null;
|
||||
String sendingText = null;
|
||||
private String photoPath = null;
|
||||
private String videoPath = null;
|
||||
private String sendingText = null;
|
||||
private int currentConnectionState;
|
||||
private View statusView;
|
||||
private View backStatusButton;
|
||||
private View statusBackground;
|
||||
private TextView statusText;
|
||||
private View containerView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle 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);
|
||||
currentConnectionState = ConnectionsManager.Instance.connectionState;
|
||||
for (BaseFragment fragment : ApplicationLoader.fragmentsStack) {
|
||||
@ -71,12 +74,11 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
if (parent != null) {
|
||||
parent.removeView(fragment.fragmentView);
|
||||
}
|
||||
fragment.parentActivity = null;
|
||||
fragment.fragmentView = null;
|
||||
}
|
||||
fragment.parentActivity = this;
|
||||
}
|
||||
setContentView(R.layout.application_layout);
|
||||
shadowView = findViewById(R.id.shadow);
|
||||
NotificationCenter.Instance.addObserver(this, 1234);
|
||||
NotificationCenter.Instance.addObserver(this, 658);
|
||||
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);
|
||||
statusBackground = statusView.findViewById(R.id.back_button_background);
|
||||
backStatusButton = statusView.findViewById(R.id.back_button);
|
||||
containerView = findViewById(R.id.container);
|
||||
statusText = (TextView)statusView.findViewById(R.id.status_text);
|
||||
statusBackground.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@ -125,7 +128,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
if (fragment.onFragmentCreate()) {
|
||||
pushOpened = true;
|
||||
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) {
|
||||
@ -136,7 +139,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
if (fragment.onFragmentCreate()) {
|
||||
pushOpened = true;
|
||||
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) {
|
||||
ChatActivity fragment = new ChatActivity();
|
||||
@ -146,7 +149,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
if (fragment.onFragmentCreate()) {
|
||||
pushOpened = true;
|
||||
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) {
|
||||
@ -175,14 +178,16 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
}
|
||||
|
||||
getWindow().setBackgroundDrawableResource(R.drawable.transparent);
|
||||
getWindow().setFormat(PixelFormat.RGB_565);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void prepareForHideShowActionBar() {
|
||||
try {
|
||||
Class aClass = getSupportActionBar().getClass();
|
||||
if (aClass == ActionBarImpl.class) {
|
||||
Method method = aClass.getDeclaredMethod("setShowHideAnimationEnabled", boolean.class);
|
||||
Class firstClass = getSupportActionBar().getClass();
|
||||
Class aClass = firstClass.getSuperclass();
|
||||
if (aClass == android.support.v7.app.ActionBar.class) {
|
||||
Method method = firstClass.getDeclaredMethod("setShowHideAnimationEnabled", boolean.class);
|
||||
method.invoke(getSupportActionBar(), false);
|
||||
} else {
|
||||
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.invoke(field.get(getSupportActionBar()), false);
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void showActionBar() {
|
||||
prepareForHideShowActionBar();
|
||||
shadowView.setVisibility(View.VISIBLE);
|
||||
getSupportActionBar().show();
|
||||
}
|
||||
|
||||
public void hideActionBar() {
|
||||
prepareForHideShowActionBar();
|
||||
shadowView.setVisibility(View.INVISIBLE);
|
||||
getSupportActionBar().hide();
|
||||
}
|
||||
|
||||
@ -241,7 +244,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
fragment.setArguments(bundle);
|
||||
if (fragment.onFragmentCreate()) {
|
||||
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) {
|
||||
@ -251,7 +254,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
fragment.setArguments(bundle);
|
||||
if (fragment.onFragmentCreate()) {
|
||||
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) {
|
||||
ChatActivity fragment = new ChatActivity();
|
||||
@ -260,7 +263,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
fragment.setArguments(bundle);
|
||||
if (fragment.onFragmentCreate()) {
|
||||
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) {
|
||||
@ -284,13 +287,13 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
bundle.putInt("user_id", lower_part);
|
||||
fragment.setArguments(bundle);
|
||||
fragment.scrollToTopOnResume = true;
|
||||
presentFragment(fragment, "chat_user_" + lower_part, true, false);
|
||||
presentFragment(fragment, "chat" + Math.random(), true, false);
|
||||
} else if (lower_part < 0) {
|
||||
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
|
||||
bundle.putInt("chat_id", -lower_part);
|
||||
fragment.setArguments(bundle);
|
||||
fragment.scrollToTopOnResume = true;
|
||||
presentFragment(fragment, "chat_group_" + -lower_part, true, false);
|
||||
presentFragment(fragment, "chat" + Math.random(), true, false);
|
||||
}
|
||||
} else {
|
||||
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
|
||||
@ -298,7 +301,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
bundle.putInt("enc_id", chat_id);
|
||||
fragment.setArguments(bundle);
|
||||
fragment.scrollToTopOnResume = true;
|
||||
presentFragment(fragment, "chat_enc_" + chat_id, true, false);
|
||||
presentFragment(fragment, "chat" + Math.random(), true, false);
|
||||
}
|
||||
if (photoPath != null) {
|
||||
fragment.processSendingPhoto(photoPath);
|
||||
@ -318,7 +321,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
}
|
||||
|
||||
private void checkForUpdates() {
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
if (FileLog.DEBUG_VERSION) {
|
||||
UpdateManager.register(this, "your-hockeyapp-api-key-here");
|
||||
}
|
||||
}
|
||||
@ -347,14 +350,14 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
fixLayout();
|
||||
checkForCrashes();
|
||||
checkForUpdates();
|
||||
ApplicationLoader.lastPauseTime = 0;
|
||||
invalidateOptionsMenu();
|
||||
ApplicationLoader.resetLastPauseTime();
|
||||
supportInvalidateOptionsMenu();
|
||||
updateActionBar();
|
||||
try {
|
||||
NotificationManager mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager.cancel(1);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,14 +386,13 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
}
|
||||
|
||||
private void fixLayout() {
|
||||
if (shadowView != null) {
|
||||
ViewTreeObserver obs = shadowView.getViewTreeObserver();
|
||||
if (containerView != null) {
|
||||
ViewTreeObserver obs = containerView.getViewTreeObserver();
|
||||
obs.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||
Display display = manager.getDefaultDisplay();
|
||||
int rotation = display.getRotation();
|
||||
int rotation = manager.getDefaultDisplay().getRotation();
|
||||
float density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) shadowView.getLayoutParams();
|
||||
params.setMargins(0, height, 0, 0);
|
||||
shadowView.setLayoutParams(params);
|
||||
if (Build.VERSION.SDK_INT < 16) {
|
||||
shadowView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||
containerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||
} else {
|
||||
shadowView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
containerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -459,7 +458,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
lastFragment.willBeHidden();
|
||||
}
|
||||
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) {
|
||||
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
|
||||
@ -473,7 +472,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
lastFragment.willBeHidden();
|
||||
}
|
||||
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) {
|
||||
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
|
||||
@ -487,7 +486,7 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
lastFragment.willBeHidden();
|
||||
}
|
||||
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) {
|
||||
@ -502,12 +501,42 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
} else if (id == 703) {
|
||||
int state = (Integer)args[0];
|
||||
if (currentConnectionState != state) {
|
||||
FileLog.e("tmessages", "switch to state " + state);
|
||||
currentConnectionState = state;
|
||||
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() {
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar == null) {
|
||||
@ -540,15 +569,32 @@ public class ApplicationActivity extends SherlockFragmentActivity implements Not
|
||||
}
|
||||
|
||||
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) {
|
||||
statusText.setText(Html.fromHtml("<font color='#006fc8'>" + getString(R.string.Connecting) + "</font>"));
|
||||
statusText.setText(getString(R.string.Connecting));
|
||||
} 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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* 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.graphics.Bitmap;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
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.TL.TLRPC;
|
||||
import org.telegram.messenger.ConnectionsManager;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.MessagesStorage;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
@ -62,7 +62,7 @@ public class ApplicationLoader extends Application {
|
||||
java.lang.System.setProperty("java.net.preferIPv6Addresses", "false");
|
||||
|
||||
applicationContext = getApplicationContext();
|
||||
Utilities.getTypeface("fonts/rlight.ttf");
|
||||
Utilities.getTypeface("fonts/rmedium.ttf");
|
||||
UserConfig.loadConfig();
|
||||
SharedPreferences preferences = getSharedPreferences("Notifications", MODE_PRIVATE);
|
||||
if (UserConfig.currentUser != null) {
|
||||
@ -101,7 +101,7 @@ public class ApplicationLoader extends Application {
|
||||
menuKeyField.setBoolean(config, false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
||||
if (checkPlayServices()) {
|
||||
@ -114,15 +114,18 @@ public class ApplicationLoader extends Application {
|
||||
sendRegistrationIdToBackend(false);
|
||||
}
|
||||
} 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;
|
||||
|
||||
lastPauseTime = System.currentTimeMillis() - 5000;
|
||||
if (ConnectionsManager.DEBUG_VERSION) {
|
||||
Log.e("tmessages", "start application with time " + lastPauseTime);
|
||||
}
|
||||
lastPauseTime = System.currentTimeMillis();
|
||||
FileLog.e("tmessages", "start application with time " + lastPauseTime);
|
||||
}
|
||||
|
||||
public static void resetLastPauseTime() {
|
||||
lastPauseTime = 0;
|
||||
ConnectionsManager.Instance.applicationMovedToForeground();
|
||||
}
|
||||
|
||||
private boolean checkPlayServices() {
|
||||
@ -143,13 +146,13 @@ public class ApplicationLoader extends Application {
|
||||
final SharedPreferences prefs = getGCMPreferences(context);
|
||||
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
|
||||
if (registrationId.length() == 0) {
|
||||
Log.i("tmessages", "Registration not found.");
|
||||
FileLog.d("tmessages", "Registration not found.");
|
||||
return "";
|
||||
}
|
||||
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
|
||||
int currentVersion = getAppVersion(context);
|
||||
if (registeredVersion != currentVersion) {
|
||||
Log.i("tmessages", "App version changed.");
|
||||
FileLog.d("tmessages", "App version changed.");
|
||||
return "";
|
||||
}
|
||||
return registrationId;
|
||||
@ -172,17 +175,29 @@ public class ApplicationLoader extends Application {
|
||||
AsyncTask<String, String, Boolean> task = new AsyncTask<String, String, Boolean>() {
|
||||
@Override
|
||||
protected Boolean doInBackground(String... objects) {
|
||||
String msg;
|
||||
try {
|
||||
if (gcm == null) {
|
||||
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;
|
||||
}
|
||||
@ -196,7 +211,12 @@ public class ApplicationLoader extends Application {
|
||||
UserConfig.pushString = regid;
|
||||
UserConfig.registeredForPush = !isNew;
|
||||
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) {
|
||||
final SharedPreferences prefs = getGCMPreferences(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();
|
||||
editor.putString(PROPERTY_REG_ID, regId);
|
||||
editor.putInt(PROPERTY_APP_VERSION, appVersion);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
* 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.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.internal.view.SupportMenuItem;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.text.Html;
|
||||
import android.view.Display;
|
||||
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.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageButton;
|
||||
@ -35,16 +36,12 @@ import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
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.messenger.ConnectionsManager;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.RPCRequest;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.messenger.Utilities;
|
||||
import org.telegram.ui.Views.AvatarUpdater;
|
||||
@ -83,7 +80,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
MessagesController.Instance.getMediaCount(-chat_id, classGuid, true);
|
||||
avatarUpdater.delegate = new AvatarUpdater.AvatarUpdaterDelegate() {
|
||||
@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) {
|
||||
MessagesController.Instance.changeChatAvatar(chat_id, file);
|
||||
}
|
||||
@ -163,45 +160,34 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
editor.putBoolean(key, !value);
|
||||
editor.commit();
|
||||
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) {
|
||||
Intent tmpIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
|
||||
tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
|
||||
tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);
|
||||
SharedPreferences preferences = parentActivity.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
|
||||
Uri currentSound = null;
|
||||
try {
|
||||
Intent tmpIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
|
||||
tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
|
||||
tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);
|
||||
SharedPreferences preferences = parentActivity.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
|
||||
Uri currentSound = null;
|
||||
|
||||
String defaultPath = null;
|
||||
Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI;
|
||||
if (defaultUri != null) {
|
||||
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);
|
||||
String defaultPath = null;
|
||||
Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI;
|
||||
if (defaultUri != null) {
|
||||
defaultPath = defaultUri.getPath();
|
||||
}
|
||||
}
|
||||
|
||||
tmpIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentSound);
|
||||
startActivityForResult(tmpIntent, 15);
|
||||
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);
|
||||
startActivityForResult(tmpIntent, 15);
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
} else if (i == 5) {
|
||||
MediaActivity fragment = new MediaActivity();
|
||||
Bundle bundle = new Bundle();
|
||||
@ -330,10 +316,10 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
actionBar.setDisplayUseLogoEnabled(false);
|
||||
actionBar.setDisplayShowCustomEnabled(false);
|
||||
actionBar.setCustomView(null);
|
||||
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.GroupInfo) + "</font>"));
|
||||
actionBar.setTitle(getStringEntry(R.string.GroupInfo));
|
||||
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) {
|
||||
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
|
||||
title = (TextView)parentActivity.findViewById(subtitleId);
|
||||
@ -342,12 +328,13 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
title.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||
title.setCompoundDrawablePadding(0);
|
||||
}
|
||||
((ApplicationActivity)parentActivity).fixBackButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (getSherlockActivity() == null) {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
if (listViewAdapter != null) {
|
||||
@ -355,44 +342,6 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
}
|
||||
((ApplicationActivity)parentActivity).showActionBar();
|
||||
((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
|
||||
@ -402,9 +351,6 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
case android.R.id.home:
|
||||
finishFragment();
|
||||
break;
|
||||
case R.id.block_user:
|
||||
openAddMenu();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -466,7 +412,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
if (action == 0) {
|
||||
TLRPC.Chat chat = MessagesController.Instance.chats.get(chat_id);
|
||||
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);
|
||||
startActivity(intent);
|
||||
}
|
||||
@ -506,15 +452,23 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
} else {
|
||||
NotificationCenter.Instance.removeObserver(this, MessagesController.closeChats);
|
||||
NotificationCenter.Instance.postNotificationName(MessagesController.closeChats);
|
||||
MessagesController.Instance.deleteDialog(-chat_id, 0, false);
|
||||
MessagesController.Instance.deleteUserFromChat(chat_id, UserConfig.clientUserId, info);
|
||||
MessagesController.Instance.deleteDialog(-chat_id, 0, false);
|
||||
finishFragment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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 {
|
||||
@ -571,9 +525,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
if (view == null) {
|
||||
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
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.setTypeface(typeface);
|
||||
|
||||
ImageButton button = (ImageButton)view.findViewById(R.id.settings_edit_name);
|
||||
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);
|
||||
TextView textView = (TextView)view.findViewById(R.id.settings_name);
|
||||
Typeface typeface = Utilities.getTypeface("fonts/rmedium.ttf");
|
||||
textView.setTypeface(typeface);
|
||||
|
||||
textView.setText(chat.title);
|
||||
|
||||
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 {
|
||||
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 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);
|
||||
if (i == 3) {
|
||||
SharedPreferences preferences = mContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
|
||||
@ -726,8 +678,6 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
if (holder == null) {
|
||||
holder = new ContactsActivity.ContactListRowHolder(view);
|
||||
view.setTag(holder);
|
||||
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
|
||||
holder.nameTextView.setTypeface(typeface);
|
||||
}
|
||||
|
||||
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>"));
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
// if (info.admin_id != UserConfig.clientUserId && part.inviter_id != UserConfig.clientUserId && part.user_id != UserConfig.clientUserId) {
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
|
||||
TLRPC.FileLocation photo = null;
|
||||
if (user.photo != null) {
|
||||
@ -768,7 +710,7 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen
|
||||
} else {
|
||||
int currentTime = ConnectionsManager.Instance.getCurrentTime();
|
||||
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));
|
||||
} else {
|
||||
if (user.status.was_online <= 10000 && user.status.expires <= 10000) {
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -9,25 +9,19 @@
|
||||
package org.telegram.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.view.Display;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.actionbarsherlock.app.ActionBar;
|
||||
import org.telegram.TL.TLRPC;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.R;
|
||||
@ -93,43 +87,6 @@ public class ChatProfileChangeNameActivity extends BaseFragment {
|
||||
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
|
||||
public boolean canApplyUpdateStatus() {
|
||||
return false;
|
||||
@ -144,6 +101,7 @@ public class ChatProfileChangeNameActivity extends BaseFragment {
|
||||
actionBar.setDisplayShowCustomEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(false);
|
||||
actionBar.setDisplayShowTitleEnabled(false);
|
||||
actionBar.setDisplayHomeAsUpEnabled(false);
|
||||
|
||||
actionBar.setCustomView(R.layout.settings_do_action_layout);
|
||||
View cancelButton = actionBar.getCustomView().findViewById(R.id.cancel_button);
|
||||
@ -168,11 +126,11 @@ public class ChatProfileChangeNameActivity extends BaseFragment {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (getSherlockActivity() == null) {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
((ApplicationActivity)parentActivity).updateActionBar();
|
||||
fixLayout();
|
||||
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
|
||||
boolean animations = preferences.getBoolean("view_animations", true);
|
||||
if (!animations) {
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -9,27 +9,20 @@
|
||||
package org.telegram.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.Display;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.actionbarsherlock.app.ActionBar;
|
||||
|
||||
import org.telegram.PhoneFormat.PhoneFormat;
|
||||
import org.telegram.TL.TLRPC;
|
||||
import org.telegram.messenger.ConnectionsManager;
|
||||
@ -42,6 +35,7 @@ import org.telegram.ui.Views.BaseFragment;
|
||||
|
||||
public class ContactAddActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
|
||||
private int user_id;
|
||||
private String phone = null;
|
||||
private View doneButton;
|
||||
private EditText firstNameField;
|
||||
private EditText lastNameField;
|
||||
@ -54,6 +48,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
|
||||
super.onFragmentCreate();
|
||||
NotificationCenter.Instance.addObserver(this, MessagesController.updateInterfaces);
|
||||
user_id = getArguments().getInt("user_id", 0);
|
||||
phone = getArguments().getString("phone");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -63,23 +58,21 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
|
||||
NotificationCenter.Instance.removeObserver(this, MessagesController.updateInterfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
if (fragmentView == null) {
|
||||
fragmentView = inflater.inflate(R.layout.contact_add_layout, container, false);
|
||||
|
||||
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.setTypeface(typeface);
|
||||
avatarImage = (BackupImageView)fragmentView.findViewById(R.id.settings_avatar_image);
|
||||
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.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@ -175,9 +168,10 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
|
||||
ActionBar actionBar = parentActivity.getSupportActionBar();
|
||||
actionBar.setDisplayShowCustomEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(false);
|
||||
actionBar.setDisplayHomeAsUpEnabled(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) {
|
||||
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
|
||||
title = (TextView)parentActivity.findViewById(subtitleId);
|
||||
@ -213,11 +207,10 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (getSherlockActivity() == null) {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
((ApplicationActivity)parentActivity).updateActionBar();
|
||||
fixLayout();
|
||||
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
|
||||
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
|
||||
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
|
||||
if (nextAnim != 0) {
|
||||
|
@ -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.
|
||||
* 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.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
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.view.Display;
|
||||
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.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
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.TL.TLRPC;
|
||||
import org.telegram.messenger.ConnectionsManager;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
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.SectionedBaseAdapter;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
@ -71,7 +69,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
private SearchView searchView;
|
||||
private TextView epmtyTextView;
|
||||
private HashMap<Integer, TLRPC.User> ignoreUsers;
|
||||
MenuItem searchItem;
|
||||
private SupportMenuItem searchItem;
|
||||
private boolean isRTL;
|
||||
|
||||
private Timer searchDialogsTimer;
|
||||
@ -170,7 +168,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("user_id", user_id);
|
||||
fragment.setArguments(bundle);
|
||||
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat_user_" + user_id, destroyAfterSelect, false);
|
||||
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), destroyAfterSelect, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -191,7 +189,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
intent.putExtra(Intent.EXTRA_TEXT, getStringEntry(R.string.InviteText));
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
@ -222,7 +220,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("user_id", uid);
|
||||
fragment.setArguments(bundle);
|
||||
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat_user_" + uid, destroyAfterSelect, false);
|
||||
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), destroyAfterSelect, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -247,7 +245,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("user_id", cLocal.user_id);
|
||||
fragment.setArguments(bundle);
|
||||
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat_user_" + cLocal.user_id, destroyAfterSelect, false);
|
||||
((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), destroyAfterSelect, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -260,12 +258,11 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
try {
|
||||
String number = arg1;
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromParts("sms", number, null));
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromParts("sms", arg1, null));
|
||||
intent.putExtra("sms_body", getStringEntry(R.string.InviteText));
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -305,12 +302,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
return fragmentView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(android.content.res.Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
fixLayout();
|
||||
}
|
||||
|
||||
private void didSelectResult(final int user_id, boolean useAlert) {
|
||||
if (useAlert && selectAlertString != 0) {
|
||||
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
|
||||
public void applySelfActionBar() {
|
||||
if (parentActivity == null) {
|
||||
@ -386,7 +344,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
actionBar.setCustomView(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) {
|
||||
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
|
||||
title = (TextView)parentActivity.findViewById(subtitleId);
|
||||
@ -397,10 +355,12 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
}
|
||||
|
||||
if (destroyAfterSelect) {
|
||||
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.SelectContact) + "</font>"));
|
||||
actionBar.setTitle(getStringEntry(R.string.SelectContact));
|
||||
} else {
|
||||
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.Contacts) + "</font>"));
|
||||
actionBar.setTitle(getStringEntry(R.string.Contacts));
|
||||
}
|
||||
|
||||
((ApplicationActivity)parentActivity).fixBackButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -409,7 +369,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
if (isFinish) {
|
||||
return;
|
||||
}
|
||||
if (getSherlockActivity() == null) {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
if (!firstStart && listViewAdapter != null) {
|
||||
@ -418,7 +378,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
firstStart = false;
|
||||
((ApplicationActivity)parentActivity).showActionBar();
|
||||
((ApplicationActivity)parentActivity).updateActionBar();
|
||||
fixLayout();
|
||||
}
|
||||
|
||||
public void searchDialogs(final String query) {
|
||||
@ -431,7 +390,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
searchDialogsTimer.cancel();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
searchDialogsTimer = new Timer();
|
||||
searchDialogsTimer.schedule(new TimerTask() {
|
||||
@ -441,7 +400,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
searchDialogsTimer.cancel();
|
||||
searchDialogsTimer = null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
processSearch(query);
|
||||
}
|
||||
@ -453,14 +412,15 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
Utilities.globalQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (query.length() == 0) {
|
||||
|
||||
String q = query.trim().toLowerCase();
|
||||
if (q.length() == 0) {
|
||||
updateSearchResults(new ArrayList<TLRPC.User>(), new ArrayList<CharSequence>());
|
||||
return;
|
||||
}
|
||||
long time = System.currentTimeMillis();
|
||||
ArrayList<TLRPC.User> resultArray = new ArrayList<TLRPC.User>();
|
||||
ArrayList<CharSequence> resultArrayNames = new ArrayList<CharSequence>();
|
||||
String q = query.toLowerCase();
|
||||
|
||||
for (TLRPC.TL_contact contact : MessagesController.Instance.contacts) {
|
||||
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);
|
||||
|
||||
inflater.inflate(R.menu.contacts_menu, menu);
|
||||
searchItem = menu.findItem(R.id.messages_list_menu_search);
|
||||
searchView = (SearchView) searchItem.getActionView();
|
||||
searchView.setQueryHint(getStringEntry(R.string.SearchContactHint));
|
||||
searchItem = (SupportMenuItem)menu.findItem(R.id.messages_list_menu_search);
|
||||
searchView = (SearchView)searchItem.getActionView();
|
||||
|
||||
int srcId = searchView.getContext().getResources().getIdentifier("android:id/search_close_btn", null, null);
|
||||
ImageView img = (ImageView) searchView.findViewById(srcId);
|
||||
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_in_cross);
|
||||
img.setImageResource(R.drawable.ic_msg_btn_cross_custom);
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
@ -563,19 +536,21 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
searchDialogs(null);
|
||||
searching = false;
|
||||
searchWas = false;
|
||||
ViewGroup group = (ViewGroup)listView.getParent();
|
||||
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());
|
||||
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());
|
||||
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.setFastScrollEnabled(true);
|
||||
listView.setVerticalScrollBarEnabled(false);
|
||||
((ApplicationActivity)parentActivity).updateActionBar();
|
||||
|
||||
epmtyTextView.setText(getStringEntry(R.string.NoContacts));
|
||||
return true;
|
||||
}
|
||||
@ -599,7 +574,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("enc_id", encryptedChat.id);
|
||||
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 {
|
||||
int currentTime = ConnectionsManager.Instance.getCurrentTime();
|
||||
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));
|
||||
} else {
|
||||
if (user.status.was_online <= 10000 && user.status.expires <= 10000) {
|
||||
@ -829,8 +804,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
if (holder == null) {
|
||||
holder = new ContactListRowHolder(convertView);
|
||||
convertView.setTag(holder);
|
||||
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
|
||||
holder.nameTextView.setTypeface(typeface);
|
||||
}
|
||||
|
||||
if (ignoreUsers != null) {
|
||||
@ -876,7 +849,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
} else {
|
||||
int currentTime = ConnectionsManager.Instance.getCurrentTime();
|
||||
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));
|
||||
} else {
|
||||
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);
|
||||
convertView = li.inflate(R.layout.settings_row_button_layout, parent, false);
|
||||
textView = (TextView)convertView.findViewById(R.id.settings_row_text);
|
||||
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
|
||||
textView.setTypeface(typeface);
|
||||
} else {
|
||||
textView = (TextView)convertView.findViewById(R.id.settings_row_text);
|
||||
}
|
||||
@ -999,11 +970,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
||||
public TextView nameTextView;
|
||||
|
||||
public ContactListRowHolder(View view) {
|
||||
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
|
||||
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);
|
||||
avatarImage = (BackupImageView)view.findViewById(R.id.messages_list_row_avatar);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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.
|
||||
* 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.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
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.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
@ -24,11 +27,8 @@ import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
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.FileLog;
|
||||
import org.telegram.objects.PhotoObject;
|
||||
import org.telegram.ui.Views.AbstractGalleryActivity;
|
||||
import org.telegram.ui.Views.GalleryViewPager;
|
||||
@ -43,10 +43,8 @@ import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.messenger.Utilities;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class GalleryImageViewer extends AbstractGalleryActivity implements NotificationCenter.NotificationCenterDelegate {
|
||||
@ -63,18 +61,18 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
private boolean loadingMore = false;
|
||||
private TextView title;
|
||||
private boolean ignoreSet = false;
|
||||
private ProgressBar loadingProgress;
|
||||
private String currentFileName;
|
||||
private int user_id = 0;
|
||||
|
||||
private ArrayList<MessageObject> imagesArrTemp = new ArrayList<MessageObject>();
|
||||
private HashMap<Integer, MessageObject> imagesByIdsTemp = new HashMap<Integer, MessageObject>();
|
||||
|
||||
private ArrayList<TLRPC.FileLocation> imagesArrLocations;
|
||||
private long currentDialog = 0;
|
||||
private int totalCount = 0;
|
||||
private int classGuid;
|
||||
private boolean cacheEndReached;
|
||||
|
||||
private HashMap<String, ProgressBar> loadingFile = new HashMap<String, ProgressBar>();
|
||||
private HashMap<Integer, String> progressByTag = new HashMap<Integer, String>();
|
||||
private boolean firstLoad = true;
|
||||
private boolean cacheEndReached = false;
|
||||
|
||||
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);
|
||||
bottomView = findViewById(R.id.gallery_view_bottom_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) {
|
||||
final int titleId = getResources().getIdentifier("action_bar_title", "id", "android");
|
||||
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, MessagesController.mediaCountDidLoaded);
|
||||
NotificationCenter.Instance.addObserver(this, MessagesController.mediaDidLoaded);
|
||||
NotificationCenter.Instance.addObserver(this, MessagesController.userPhotosLoaded);
|
||||
|
||||
Integer index = null;
|
||||
if (localPagerAdapter == null) {
|
||||
final MessageObject file = (MessageObject)NotificationCenter.Instance.getFromMemCache(1);
|
||||
final TLRPC.FileLocation fileLocation = (TLRPC.FileLocation)NotificationCenter.Instance.getFromMemCache(3);
|
||||
final ArrayList<MessageObject> messagesArr = (ArrayList<MessageObject>)NotificationCenter.Instance.getFromMemCache(4);
|
||||
index = (Integer)NotificationCenter.Instance.getFromMemCache(5);
|
||||
final MessageObject file = (MessageObject)NotificationCenter.Instance.getFromMemCache(51);
|
||||
final TLRPC.FileLocation fileLocation = (TLRPC.FileLocation)NotificationCenter.Instance.getFromMemCache(53);
|
||||
final ArrayList<MessageObject> messagesArr = (ArrayList<MessageObject>)NotificationCenter.Instance.getFromMemCache(54);
|
||||
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) {
|
||||
imagesArr = new ArrayList<MessageObject>();
|
||||
imagesByIds = new HashMap<Integer, MessageObject>();
|
||||
ArrayList<MessageObject> imagesArr = new ArrayList<MessageObject>();
|
||||
HashMap<Integer, MessageObject> imagesByIds = new HashMap<Integer, MessageObject>();
|
||||
imagesArr.add(file);
|
||||
if (file.messageOwner.action == null || file.messageOwner.action instanceof TLRPC.TL_messageActionEmpty) {
|
||||
needSearchMessage = true;
|
||||
@ -143,17 +145,18 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
}
|
||||
}
|
||||
}
|
||||
localPagerAdapter = new LocalPagerAdapter(imagesArr, imagesByIds);
|
||||
} else if (fileLocation != null) {
|
||||
ArrayList<TLRPC.FileLocation> arr = new ArrayList<TLRPC.FileLocation>();
|
||||
arr.add(fileLocation);
|
||||
imagesArrLocations = arr;
|
||||
withoutBottom = true;
|
||||
deleteButton.setVisibility(View.INVISIBLE);
|
||||
nameTextView.setVisibility(View.INVISIBLE);
|
||||
timeTextView.setVisibility(View.INVISIBLE);
|
||||
localPagerAdapter = new LocalPagerAdapter(arr);
|
||||
} else if (messagesArr != null) {
|
||||
imagesArr = new ArrayList<MessageObject>();
|
||||
imagesByIds = new HashMap<Integer, MessageObject>();
|
||||
ArrayList<MessageObject> imagesArr = new ArrayList<MessageObject>();
|
||||
HashMap<Integer, MessageObject> imagesByIds = new HashMap<Integer, MessageObject>();
|
||||
imagesArr.addAll(messagesArr);
|
||||
Collections.reverse(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;
|
||||
@ -187,7 +190,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
|
||||
if (index != null) {
|
||||
fromAll = true;
|
||||
mViewPager.setCurrentItem( index);
|
||||
mViewPager.setCurrentItem(index);
|
||||
}
|
||||
|
||||
shareButton.setOnClickListener(new View.OnClickListener() {
|
||||
@ -203,7 +206,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
startActivity(intent);
|
||||
}
|
||||
} 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) {
|
||||
MessagesController.Instance.getMediaCount(currentDialog, classGuid, true);
|
||||
}
|
||||
if (user_id != 0) {
|
||||
MessagesController.Instance.loadUserPhotos(user_id, 0, 30, 0, true, classGuid);
|
||||
}
|
||||
checkCurrentFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -235,6 +242,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
NotificationCenter.Instance.removeObserver(this, FileLoader.FileLoadProgressChanged);
|
||||
NotificationCenter.Instance.removeObserver(this, MessagesController.mediaCountDidLoaded);
|
||||
NotificationCenter.Instance.removeObserver(this, MessagesController.mediaDidLoaded);
|
||||
NotificationCenter.Instance.removeObserver(this, MessagesController.userPhotosLoaded);
|
||||
ConnectionsManager.Instance.cancelRpcsForClassGuid(classGuid);
|
||||
}
|
||||
|
||||
@ -243,28 +251,100 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
public void didReceivedNotification(int id, final Object... args) {
|
||||
if (id == FileLoader.FileDidFailedLoad) {
|
||||
String location = (String)args[0];
|
||||
if (loadingFile.containsKey(location)) {
|
||||
loadingFile.remove(location);
|
||||
localPagerAdapter.updateViews();
|
||||
if (currentFileName != null && currentFileName.equals(location)) {
|
||||
if (loadingProgress != null) {
|
||||
loadingProgress.setVisibility(View.GONE);
|
||||
}
|
||||
if (localPagerAdapter != null) {
|
||||
localPagerAdapter.updateViews();
|
||||
}
|
||||
}
|
||||
} else if (id == FileLoader.FileDidLoaded) {
|
||||
String location = (String)args[0];
|
||||
if (loadingFile.containsKey(location)) {
|
||||
loadingFile.remove(location);
|
||||
localPagerAdapter.updateViews();
|
||||
if (currentFileName != null && currentFileName.equals(location)) {
|
||||
if (loadingProgress != null) {
|
||||
loadingProgress.setVisibility(View.GONE);
|
||||
}
|
||||
if (localPagerAdapter != null) {
|
||||
localPagerAdapter.updateViews();
|
||||
}
|
||||
}
|
||||
} else if (id == FileLoader.FileLoadProgressChanged) {
|
||||
String location = (String)args[0];
|
||||
ProgressBar bar;
|
||||
if ((bar = loadingFile.get(location)) != null) {
|
||||
if (currentFileName != null && currentFileName.equals(location)) {
|
||||
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) {
|
||||
long uid = (Long)args[0];
|
||||
if (uid == currentDialog) {
|
||||
if ((int)currentDialog != 0) {
|
||||
boolean fromCache = (Boolean)args[2];
|
||||
if (fromCache) {
|
||||
MessagesController.Instance.getMediaCount(currentDialog, classGuid, false);
|
||||
}
|
||||
}
|
||||
totalCount = (Integer)args[1];
|
||||
if (needSearchMessage) {
|
||||
if (needSearchMessage && firstLoad) {
|
||||
firstLoad = false;
|
||||
MessagesController.Instance.loadMedia(currentDialog, 0, 100, 0, true, classGuid);
|
||||
loadingMore = true;
|
||||
} else {
|
||||
@ -317,6 +397,9 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (added == 0) {
|
||||
totalCount = imagesArrTemp.size();
|
||||
}
|
||||
|
||||
if (foundIndex != -1) {
|
||||
mViewPager.setAdapter(null);
|
||||
@ -353,17 +436,19 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
if (arr.isEmpty() && !fromCache) {
|
||||
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) {
|
||||
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);
|
||||
} else {
|
||||
totalCount = localPagerAdapter.imagesArr.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,18 +458,22 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
private TLRPC.FileLocation getCurrentFile() {
|
||||
int item = mViewPager.getCurrentItem();
|
||||
if (withoutBottom) {
|
||||
return imagesArrLocations.get(item);
|
||||
return localPagerAdapter.imagesArrLocations.get(item);
|
||||
} else {
|
||||
MessageObject message = localPagerAdapter.imagesArr.get(item);
|
||||
if (message.messageOwner instanceof TLRPC.TL_messageService) {
|
||||
ArrayList<TLRPC.PhotoSize> sizes = message.messageOwner.action.photo.sizes;
|
||||
if (sizes.size() > 0) {
|
||||
return sizes.get(sizes.size() - 1).location;
|
||||
if (message.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
|
||||
return message.messageOwner.action.newUserPhoto.photo_big;
|
||||
} 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) {
|
||||
ArrayList<TLRPC.PhotoSize> sizes = message.messageOwner.media.photo.sizes;
|
||||
if (sizes.size() > 0) {
|
||||
return sizes.get(sizes.size() - 1).location;
|
||||
TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(message.messageOwner.media.photo.sizes, 800, 800);
|
||||
if (sizeFull != null) {
|
||||
return sizeFull.location;
|
||||
}
|
||||
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||
return message.messageOwner.media.video.thumb.location;
|
||||
@ -414,13 +503,69 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
} else {
|
||||
nameTextView.setText("");
|
||||
}
|
||||
invalidateOptionsMenu();
|
||||
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
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getSupportMenuInflater();
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
if (withoutBottom) {
|
||||
inflater.inflate(R.menu.gallery_save_only_menu, menu);
|
||||
} else {
|
||||
@ -436,14 +581,16 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
@Override
|
||||
public void openOptionsMenu() {
|
||||
TLRPC.FileLocation file = getCurrentFile();
|
||||
File f = new File(Utilities.getCacheDir(), file.volume_id + "_" + file.local_id + ".jpg");
|
||||
if (f.exists()) {
|
||||
super.openOptionsMenu();
|
||||
if (file != null) {
|
||||
File f = new File(Utilities.getCacheDir(), file.volume_id + "_" + file.local_id + ".jpg");
|
||||
if (f.exists()) {
|
||||
super.openOptionsMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) {
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int itemId = item.getItemId();
|
||||
processSelectedMenu(itemId);
|
||||
return true;
|
||||
@ -484,14 +631,13 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
case R.id.gallery_menu_save:
|
||||
TLRPC.FileLocation file = getCurrentFile();
|
||||
File f = new File(Utilities.getCacheDir(), file.volume_id + "_" + file.local_id + ".jpg");
|
||||
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
|
||||
String imageFileName = "IMG_" + timeStamp + ".jpg";
|
||||
File dstFile = Utilities.generatePicturePath();
|
||||
try {
|
||||
MediaStore.Images.Media.insertImage(getContentResolver(), f.getAbsolutePath(), imageFileName, "");
|
||||
Utilities.copyFile(f, dstFile);
|
||||
Utilities.addMediaToGallery(Uri.fromFile(dstFile));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
//Utilities.addMediaToGallery(addToTouchActiveAlbum(imageFileName, f.getAbsolutePath()));
|
||||
break;
|
||||
// case R.id.gallery_menu_send: {
|
||||
// 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) {
|
||||
Animation animation;
|
||||
if (!up) {
|
||||
@ -612,13 +743,17 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
public class LocalPagerAdapter extends PagerAdapter {
|
||||
public ArrayList<MessageObject> imagesArr;
|
||||
public HashMap<Integer, MessageObject> imagesByIds;
|
||||
public int tagCounter = 0;
|
||||
private ArrayList<TLRPC.FileLocation> imagesArrLocations;
|
||||
|
||||
public LocalPagerAdapter(ArrayList<MessageObject> _imagesArr, HashMap<Integer, MessageObject> _imagesByIds) {
|
||||
imagesArr = _imagesArr;
|
||||
imagesByIds = _imagesByIds;
|
||||
}
|
||||
|
||||
public LocalPagerAdapter(ArrayList<TLRPC.FileLocation> locations) {
|
||||
imagesArrLocations = locations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrimaryItem(ViewGroup container, final int position, Object 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();
|
||||
for (int a = 0; a < count; 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 View progressBarParent = v.findViewById(R.id.action_progress_parent);
|
||||
MessageObject message = (MessageObject)playButton.getTag();
|
||||
if (progressBar != null && message != null) {
|
||||
processViews(progressBar, playButton, message, progressBarParent);
|
||||
if (message != null) {
|
||||
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) {
|
||||
playButton.setVisibility(View.VISIBLE);
|
||||
String fileName = message.messageOwner.media.video.dc_id + "_" + message.messageOwner.media.video.id + ".mp4";
|
||||
boolean load = false;
|
||||
if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) {
|
||||
File f = new File(message.messageOwner.attachPath);
|
||||
if (f.exists()) {
|
||||
playButton.setVisibility(View.VISIBLE);
|
||||
progressBarParent.setVisibility(View.GONE);
|
||||
playButton.setText(getString(R.string.ViewVideo));
|
||||
} else {
|
||||
load = true;
|
||||
@ -683,8 +835,6 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
} else {
|
||||
File cacheFile = new File(Utilities.getCacheDir(), fileName);
|
||||
if (cacheFile.exists()) {
|
||||
playButton.setVisibility(View.VISIBLE);
|
||||
progressBarParent.setVisibility(View.GONE);
|
||||
playButton.setText(getString(R.string.ViewVideo));
|
||||
} else {
|
||||
load = true;
|
||||
@ -692,33 +842,11 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
}
|
||||
if (load) {
|
||||
Float progress = FileLoader.Instance.fileProgresses.get(fileName);
|
||||
if (loadingFile.containsKey(fileName) || progress != null) {
|
||||
if (progress != null) {
|
||||
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);
|
||||
if (FileLoader.Instance.isLoadingFile(fileName)) {
|
||||
playButton.setText(R.string.CancelDownload);
|
||||
} 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));
|
||||
}
|
||||
} 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);
|
||||
|
||||
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 View progressBarParent = view.findViewById(R.id.action_progress_parent);
|
||||
progressBar.setTag(tagCounter);
|
||||
tagCounter++;
|
||||
|
||||
if (imagesArr != null) {
|
||||
final MessageObject message = imagesArr.get(position);
|
||||
view.setTag(message.messageOwner.id);
|
||||
if (message.messageOwner instanceof TLRPC.TL_messageService) {
|
||||
ArrayList<TLRPC.PhotoSize> sizes = message.messageOwner.action.photo.sizes;
|
||||
iv.isVideo = false;
|
||||
if (sizes.size() > 0) {
|
||||
TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(sizes, 800, 800);
|
||||
if (message.imagePreview != null) {
|
||||
iv.setImage(sizeFull.location, null, message.imagePreview);
|
||||
} else {
|
||||
iv.setImage(sizeFull.location, null, 0);
|
||||
if (message.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
|
||||
iv.isVideo = false;
|
||||
iv.setImage(message.messageOwner.action.newUserPhoto.photo_big, null, 0, -1);
|
||||
} else {
|
||||
ArrayList<TLRPC.PhotoSize> sizes = message.messageOwner.action.photo.sizes;
|
||||
iv.isVideo = false;
|
||||
if (sizes.size() > 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) {
|
||||
@ -760,13 +889,13 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
if (sizes.size() > 0) {
|
||||
TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(sizes, 800, 800);
|
||||
if (message.imagePreview != null) {
|
||||
iv.setImage(sizeFull.location, null, message.imagePreview);
|
||||
iv.setImage(sizeFull.location, null, message.imagePreview, sizeFull.size);
|
||||
} else {
|
||||
iv.setImage(sizeFull.location, null, 0);
|
||||
iv.setImage(sizeFull.location, null, 0, sizeFull.size);
|
||||
}
|
||||
}
|
||||
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||
processViews(progressBar, playButton, message, progressBarParent);
|
||||
processViews(playButton, message);
|
||||
playButton.setTag(message);
|
||||
|
||||
playButton.setOnClickListener(new View.OnClickListener() {
|
||||
@ -794,14 +923,13 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
}
|
||||
}
|
||||
if (loadFile) {
|
||||
if (!loadingFile.containsKey(fileName)) {
|
||||
progressByTag.put((Integer)progressBar.getTag(), fileName);
|
||||
loadingFile.put(fileName, progressBar);
|
||||
if (!FileLoader.Instance.isLoadingFile(fileName)) {
|
||||
FileLoader.Instance.loadFile(message.messageOwner.media.video, null);
|
||||
progressBar.setProgress(0);
|
||||
progressBarParent.setVisibility(View.VISIBLE);
|
||||
playButton.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
FileLoader.Instance.cancelLoadFile(message.messageOwner.media.video, null);
|
||||
}
|
||||
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) {
|
||||
iv.setImageBitmap(message.imagePreview);
|
||||
} 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 {
|
||||
iv.isVideo = false;
|
||||
iv.setImage(imagesArrLocations.get(position), null, 0);
|
||||
iv.setImage(imagesArrLocations.get(position), null, 0, -1);
|
||||
}
|
||||
|
||||
return view;
|
||||
@ -826,12 +956,6 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
|
||||
PZSImageView iv = (PZSImageView)((View)view).findViewById(R.id.page_image);
|
||||
FileLoader.Instance.cancelLoadingForImageView(iv);
|
||||
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
|
||||
|
@ -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.
|
||||
* 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.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.internal.view.SupportMenuItem;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.Spannable;
|
||||
@ -23,26 +24,21 @@ import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.view.Display;
|
||||
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.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
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.messenger.ConnectionsManager;
|
||||
import org.telegram.messenger.Emoji;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
@ -64,7 +60,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
private TextView doneTextView;
|
||||
private EditText userSelectEditText;
|
||||
private TextView countTextView;
|
||||
private View topView;
|
||||
private boolean ignoreChange = false;
|
||||
|
||||
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);
|
||||
userSelectEditText = (EditText)fragmentView.findViewById(R.id.bubble_input_text);
|
||||
countTextView = (TextView)fragmentView.findViewById(R.id.bubble_counter_text);
|
||||
topView = fragmentView.findViewById(R.id.top_layout);
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
userSelectEditText.setTextIsSelectable(false);
|
||||
}
|
||||
@ -142,7 +136,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
try {
|
||||
deletedString = changeString.toString().substring(afterChangeIndex, beforeChangeIndex);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
if (deletedString.length() > 0) {
|
||||
if (searching && searchWas) {
|
||||
@ -263,45 +257,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
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
|
||||
public void applySelfActionBar() {
|
||||
if (parentActivity == null) {
|
||||
@ -314,9 +269,9 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
actionBar.setDisplayUseLogoEnabled(false);
|
||||
actionBar.setDisplayShowCustomEnabled(false);
|
||||
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) {
|
||||
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
|
||||
title = (TextView)parentActivity.findViewById(subtitleId);
|
||||
@ -330,12 +285,11 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (getSherlockActivity() == null) {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
((ApplicationActivity)parentActivity).showActionBar();
|
||||
((ApplicationActivity)parentActivity).updateActionBar();
|
||||
fixLayout();
|
||||
}
|
||||
|
||||
public Emoji.XImageSpan createAndPutChipForUser(TLRPC.User user) {
|
||||
@ -382,7 +336,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
searchDialogsTimer.cancel();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
searchDialogsTimer = new Timer();
|
||||
searchDialogsTimer.schedule(new TimerTask() {
|
||||
@ -392,7 +346,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
searchDialogsTimer.cancel();
|
||||
searchDialogsTimer = null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
processSearch(query);
|
||||
}
|
||||
@ -454,7 +408,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
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.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@ -551,9 +505,9 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
|
||||
ImageView checkButton = (ImageView)convertView.findViewById(R.id.settings_row_check_button);
|
||||
if (selectedContacts.containsKey(user.id)) {
|
||||
checkButton.setImageResource(R.drawable.btn_check_on);
|
||||
checkButton.setImageResource(R.drawable.btn_check_on_old);
|
||||
} 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);
|
||||
@ -565,7 +519,6 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
|
||||
if (searchWas && searching) {
|
||||
holder.nameTextView.setText(searchResultNames.get(position));
|
||||
holder.nameTextView.setTypeface(null);
|
||||
} else {
|
||||
if (user.first_name.length() != 0 && user.last_name.length() != 0) {
|
||||
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 {
|
||||
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;
|
||||
@ -591,7 +542,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen
|
||||
} else {
|
||||
int currentTime = ConnectionsManager.Instance.getCurrentTime();
|
||||
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));
|
||||
} else {
|
||||
if (user.status.was_online <= 10000 && user.status.expires <= 10000) {
|
||||
|
@ -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.
|
||||
* 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.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.internal.view.SupportMenuItem;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
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.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
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.messenger.ConnectionsManager;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
@ -50,11 +45,10 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
private PinnedHeaderListView listView;
|
||||
private TextView nameTextView;
|
||||
private TLRPC.FileLocation avatar;
|
||||
private TLRPC.TL_inputFile uploadedAvatar;
|
||||
private TLRPC.InputFile uploadedAvatar;
|
||||
private ArrayList<Integer> selectedContacts;
|
||||
private BackupImageView avatarImage;
|
||||
private boolean createAfterUpload;
|
||||
private View topView;
|
||||
private boolean donePressed;
|
||||
private AvatarUpdater avatarUpdater = new AvatarUpdater();
|
||||
|
||||
@ -116,7 +110,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
} else if (i == 2) {
|
||||
avatar = 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);
|
||||
topView = fragmentView.findViewById(R.id.top_layout);
|
||||
|
||||
nameTextView = (EditText)fragmentView.findViewById(R.id.bubble_input_text);
|
||||
listView = (PinnedHeaderListView)fragmentView.findViewById(R.id.listView);
|
||||
@ -139,45 +132,6 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
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
|
||||
public void applySelfActionBar() {
|
||||
if (parentActivity == null) {
|
||||
@ -190,9 +144,9 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
actionBar.setDisplayUseLogoEnabled(false);
|
||||
actionBar.setDisplayShowCustomEnabled(false);
|
||||
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) {
|
||||
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
|
||||
title = (TextView)parentActivity.findViewById(subtitleId);
|
||||
@ -206,24 +160,23 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (getSherlockActivity() == null) {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
((ApplicationActivity)parentActivity).showActionBar();
|
||||
((ApplicationActivity)parentActivity).updateActionBar();
|
||||
fixLayout();
|
||||
}
|
||||
|
||||
@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() {
|
||||
@Override
|
||||
public void run() {
|
||||
uploadedAvatar = file;
|
||||
avatar = small.location;
|
||||
avatarImage.setImage(avatar, "50_50", R.drawable.group_placeholder_blue);
|
||||
avatarImage.setImage(avatar, "50_50", R.drawable.group_blue);
|
||||
if (createAfterUpload) {
|
||||
Log.e("tmessages", "avatar did uploaded");
|
||||
FileLog.e("tmessages", "avatar did uploaded");
|
||||
MessagesController.Instance.createChat(nameTextView.getText().toString(), selectedContacts, uploadedAvatar);
|
||||
}
|
||||
}
|
||||
@ -250,7 +203,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
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);
|
||||
doneTextView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@ -281,7 +234,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
} else if (id == MessagesController.chatDidFailCreate) {
|
||||
Utilities.HideProgressDialog(parentActivity);
|
||||
donePressed = false;
|
||||
Log.e("tmessages", "did fail create");
|
||||
FileLog.e("tmessages", "did fail create chat");
|
||||
} else if (id == MessagesController.chatDidCreated) {
|
||||
Utilities.RunOnUIThread(new Runnable() {
|
||||
@Override
|
||||
@ -291,7 +244,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("chat_id", (Integer)args[0]);
|
||||
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
|
||||
public int getCountForSection(int section) {
|
||||
if (selectedContacts == null) {
|
||||
return 0;
|
||||
}
|
||||
return selectedContacts.size();
|
||||
}
|
||||
|
||||
@ -346,8 +302,6 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
if (holder == null) {
|
||||
holder = new ContactsActivity.ContactListRowHolder(convertView);
|
||||
convertView.setTag(holder);
|
||||
Typeface typeface = Utilities.getTypeface("fonts/rlight.ttf");
|
||||
holder.nameTextView.setTypeface(typeface);
|
||||
}
|
||||
|
||||
View divider = convertView.findViewById(R.id.settings_row_divider);
|
||||
@ -378,7 +332,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
|
||||
} else {
|
||||
int currentTime = ConnectionsManager.Instance.getCurrentTime();
|
||||
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));
|
||||
} else {
|
||||
if (user.status.was_online <= 10000 && user.status.expires <= 10000) {
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -9,11 +9,11 @@
|
||||
package org.telegram.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.text.Html;
|
||||
import android.view.Display;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -22,12 +22,9 @@ import android.view.WindowManager;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.actionbarsherlock.app.ActionBar;
|
||||
|
||||
import org.telegram.TL.TLRPC;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.Utilities;
|
||||
import org.telegram.ui.Views.BaseFragment;
|
||||
import org.telegram.ui.Views.IdenticonView;
|
||||
|
||||
@ -57,8 +54,6 @@ public class IdenticonActivity extends BaseFragment {
|
||||
fragmentView = inflater.inflate(R.layout.identicon_layout, container, false);
|
||||
IdenticonView identiconView = (IdenticonView) fragmentView.findViewById(R.id.identicon_view);
|
||||
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);
|
||||
if (encryptedChat != null) {
|
||||
identiconView.setBytes(encryptedChat.auth_key);
|
||||
@ -87,15 +82,15 @@ public class IdenticonActivity extends BaseFragment {
|
||||
actionBar.setDisplayShowCustomEnabled(false);
|
||||
actionBar.setSubtitle(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) {
|
||||
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
|
||||
title = (TextView)parentActivity.findViewById(subtitleId);
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -112,7 +107,7 @@ public class IdenticonActivity extends BaseFragment {
|
||||
if (isFinish) {
|
||||
return;
|
||||
}
|
||||
if (getSherlockActivity() == null) {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
((ApplicationActivity)parentActivity).showActionBar();
|
||||
@ -129,36 +124,25 @@ public class IdenticonActivity extends BaseFragment {
|
||||
public boolean onPreDraw() {
|
||||
LinearLayout layout = (LinearLayout)fragmentView;
|
||||
WindowManager manager = (WindowManager)parentActivity.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = manager.getDefaultDisplay();
|
||||
int rotation = display.getRotation();
|
||||
int height;
|
||||
int currentActionBarHeight = parentActivity.getSupportActionBar().getHeight();
|
||||
int rotation = manager.getDefaultDisplay().getRotation();
|
||||
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) {
|
||||
layout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
} else {
|
||||
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);
|
||||
|
||||
TextView title = (TextView)parentActivity.findViewById(R.id.abs__action_bar_title);
|
||||
TextView title = (TextView)parentActivity.findViewById(R.id.action_bar_title);
|
||||
if (title == null) {
|
||||
final int subtitleId = ApplicationLoader.applicationContext.getResources().getIdentifier("action_bar_title", "id", "android");
|
||||
title = (TextView)parentActivity.findViewById(subtitleId);
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
@ -169,7 +153,7 @@ public class IdenticonActivity extends BaseFragment {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) {
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int itemId = item.getItemId();
|
||||
switch (itemId) {
|
||||
case android.R.id.home:
|
||||
|
@ -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.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
@ -8,59 +8,38 @@
|
||||
|
||||
package org.telegram.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.text.Html;
|
||||
import android.view.Display;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.Utilities;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class IntroActivity extends SherlockFragmentActivity {
|
||||
public class IntroActivity extends ActionBarActivity {
|
||||
private ViewPager viewPager;
|
||||
private ImageView topImage1;
|
||||
private ImageView topImage2;
|
||||
private View slidingView;
|
||||
private View parentSlidingView;
|
||||
private TextView startMessagingButton;
|
||||
private ViewGroup bottomPages;
|
||||
private int lastPage = 0;
|
||||
private float density = 1;
|
||||
private boolean isRTL = false;
|
||||
private boolean justCreated = 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[] titles;
|
||||
private int[] messages;
|
||||
int fixedFirstNum1;
|
||||
int fixedFirstNum2;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -73,14 +52,16 @@ public class IntroActivity extends SherlockFragmentActivity {
|
||||
if (lang != null && lang.toLowerCase().equals("ar")) {
|
||||
isRTL = true;
|
||||
icons = new int[] {
|
||||
R.drawable.icon5,
|
||||
R.drawable.icon4,
|
||||
R.drawable.icon3,
|
||||
R.drawable.icon2,
|
||||
R.drawable.icon1,
|
||||
R.drawable.icon0
|
||||
R.drawable.intro7,
|
||||
R.drawable.intro6,
|
||||
R.drawable.intro5,
|
||||
R.drawable.intro4,
|
||||
R.drawable.intro3,
|
||||
R.drawable.intro2,
|
||||
R.drawable.intro1
|
||||
};
|
||||
titles = new int[] {
|
||||
R.string.Page7Title,
|
||||
R.string.Page6Title,
|
||||
R.string.Page5Title,
|
||||
R.string.Page4Title,
|
||||
@ -89,6 +70,7 @@ public class IntroActivity extends SherlockFragmentActivity {
|
||||
R.string.Page1Title
|
||||
};
|
||||
messages = new int[] {
|
||||
R.string.Page7Message,
|
||||
R.string.Page6Message,
|
||||
R.string.Page5Message,
|
||||
R.string.Page4Message,
|
||||
@ -96,16 +78,15 @@ public class IntroActivity extends SherlockFragmentActivity {
|
||||
R.string.Page2Message,
|
||||
R.string.Page1Message
|
||||
};
|
||||
fixedFirstNum1 = 5;
|
||||
fixedFirstNum2 = 4;
|
||||
} else {
|
||||
icons = new int[] {
|
||||
R.drawable.icon0,
|
||||
R.drawable.icon1,
|
||||
R.drawable.icon2,
|
||||
R.drawable.icon3,
|
||||
R.drawable.icon4,
|
||||
R.drawable.icon5
|
||||
R.drawable.intro1,
|
||||
R.drawable.intro2,
|
||||
R.drawable.intro3,
|
||||
R.drawable.intro4,
|
||||
R.drawable.intro5,
|
||||
R.drawable.intro6,
|
||||
R.drawable.intro7
|
||||
};
|
||||
titles = new int[] {
|
||||
R.string.Page1Title,
|
||||
@ -113,7 +94,8 @@ public class IntroActivity extends SherlockFragmentActivity {
|
||||
R.string.Page3Title,
|
||||
R.string.Page4Title,
|
||||
R.string.Page5Title,
|
||||
R.string.Page6Title
|
||||
R.string.Page6Title,
|
||||
R.string.Page7Title
|
||||
};
|
||||
messages = new int[] {
|
||||
R.string.Page1Message,
|
||||
@ -121,18 +103,16 @@ public class IntroActivity extends SherlockFragmentActivity {
|
||||
R.string.Page3Message,
|
||||
R.string.Page4Message,
|
||||
R.string.Page5Message,
|
||||
R.string.Page6Message
|
||||
R.string.Page6Message,
|
||||
R.string.Page7Message
|
||||
};
|
||||
fixedFirstNum1 = 0;
|
||||
fixedFirstNum2 = 1;
|
||||
}
|
||||
density = getResources().getDisplayMetrics().density;
|
||||
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);
|
||||
topImage1 = (ImageView)findViewById(R.id.icon_image1);
|
||||
topImage2 = (ImageView)findViewById(R.id.icon_image2);
|
||||
bottomPages = (ViewGroup)findViewById(R.id.bottom_pages);
|
||||
topImage2.setVisibility(View.GONE);
|
||||
viewPager.setAdapter(new IntroAdapter());
|
||||
viewPager.setPageMargin(0);
|
||||
@ -140,7 +120,7 @@ public class IntroActivity extends SherlockFragmentActivity {
|
||||
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
updateColors(position, positionOffset);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -230,7 +210,6 @@ public class IntroActivity extends SherlockFragmentActivity {
|
||||
justCreated = true;
|
||||
|
||||
getSupportActionBar().hide();
|
||||
fixLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -238,8 +217,8 @@ public class IntroActivity extends SherlockFragmentActivity {
|
||||
super.onResume();
|
||||
if (justCreated) {
|
||||
if (isRTL) {
|
||||
viewPager.setCurrentItem(5);
|
||||
lastPage = 5;
|
||||
viewPager.setCurrentItem(6);
|
||||
lastPage = 6;
|
||||
} else {
|
||||
viewPager.setCurrentItem(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 {
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 6;
|
||||
return 7;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
View view = View.inflate(container.getContext(), R.layout.intro_view_layout, null);
|
||||
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);
|
||||
messageTextView.setTypeface(typeface);
|
||||
container.addView(view, 0);
|
||||
|
||||
headerTextView.setText(getString(titles[position]));
|
||||
@ -352,6 +254,15 @@ public class IntroActivity extends SherlockFragmentActivity {
|
||||
@Override
|
||||
public void setPrimaryItem(ViewGroup container, int position, Object 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
|
||||
|
@ -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.
|
||||
* 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 org.telegram.TL.TLRPC;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
@ -104,7 +105,7 @@ public class LaunchActivity extends PausableActivity {
|
||||
NotificationManager mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager.cancel(1);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
* 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.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.support.v7.app.ActionBar;
|
||||
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.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.CameraUpdateFactory;
|
||||
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.MarkerOptions;
|
||||
import org.telegram.TL.TLRPC;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.objects.MessageObject;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
@ -177,7 +177,7 @@ public class LocationActivity extends BaseFragment implements LocationListener,
|
||||
if (parentActivity == null) {
|
||||
return;
|
||||
}
|
||||
final ActionBar actionBar = parentActivity.getSupportActionBar();
|
||||
ActionBar actionBar = parentActivity.getSupportActionBar();
|
||||
actionBar.setDisplayShowTitleEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(false);
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
@ -186,12 +186,12 @@ public class LocationActivity extends BaseFragment implements LocationListener,
|
||||
actionBar.setDisplayShowCustomEnabled(false);
|
||||
actionBar.setCustomView(null);
|
||||
if (messageObject != null) {
|
||||
actionBar.setTitle(Html.fromHtml("<font color='#006fc8'>" + getStringEntry(R.string.ChatLocation) + "</font>"));
|
||||
actionBar.setTitle(getStringEntry(R.string.ChatLocation));
|
||||
} 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) {
|
||||
final int subtitleId = parentActivity.getResources().getIdentifier("action_bar_title", "id", "android");
|
||||
title = (TextView)parentActivity.findViewById(subtitleId);
|
||||
@ -205,7 +205,7 @@ public class LocationActivity extends BaseFragment implements LocationListener,
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (getSherlockActivity() == null) {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
((ApplicationActivity)parentActivity).showActionBar();
|
||||
@ -319,7 +319,7 @@ public class LocationActivity extends BaseFragment implements LocationListener,
|
||||
}
|
||||
positionMarker(location);
|
||||
} 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
Loading…
Reference in New Issue
Block a user