Commit 419969f7 authored by DrKLO's avatar DrKLO

Merge branch 'dev'

parents 1eeb12f6 51aa4141
...@@ -82,7 +82,7 @@ android { ...@@ -82,7 +82,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 19 targetSdkVersion 19
versionCode 212 versionCode 219
versionName "1.4.9" versionName "1.4.9"
} }
} }
...@@ -154,6 +154,18 @@ LOCAL_SRC_FILES += \ ...@@ -154,6 +154,18 @@ LOCAL_SRC_FILES += \
./opus/opusfile/opusfile.c \ ./opus/opusfile/opusfile.c \
./opus/opusfile/stream.c ./opus/opusfile/stream.c
LOCAL_SRC_FILES += \
./giflib/dgif_lib.c \
./giflib/gifalloc.c
LOCAL_SRC_FILES += \
./aes/aes_core.c \
./aes/aes_ige.c \
./aes/aes_misc.c
LOCAL_SRC_FILES += \
./sqlite/sqlite3.c
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := \
./opus/include \ ./opus/include \
./opus/silk \ ./opus/silk \
...@@ -163,16 +175,12 @@ LOCAL_C_INCLUDES := \ ...@@ -163,16 +175,12 @@ LOCAL_C_INCLUDES := \
./opus/opusfile ./opus/opusfile
LOCAL_SRC_FILES += \ LOCAL_SRC_FILES += \
./aes_core.c \
./aes_ige.c \
./aes_misc.c \
./jni.c \ ./jni.c \
./sqlite3.c \ ./sqlite_cursor.c \
./org_telegram_SQLite_SQLiteCursor.c \ ./sqlite_database.c \
./org_telegram_SQLite_SQLiteDatabase.c \ ./sqlite_statement.c \
./org_telegram_SQLite_SQLitePreparedStatement.c \ ./sqlite.c \
./org_telegram_SQLite.c \ ./audio.c \
./audio.c ./gif.c
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
...@@ -5,14 +5,7 @@ ...@@ -5,14 +5,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <opusfile.h> #include <opusfile.h>
#include "log.h" #include "utils.h"
#ifndef max
#define max(x, y) ((x) > (y)) ? (x) : (y)
#endif
#ifndef min
#define min(x, y) ((x) < (y)) ? (x) : (y)
#endif
typedef struct { typedef struct {
int version; int version;
...@@ -540,9 +533,6 @@ int64_t _currentPcmOffset = 0; ...@@ -540,9 +533,6 @@ int64_t _currentPcmOffset = 0;
int _finished = 0; int _finished = 0;
static const int playerBuffersCount = 3; static const int playerBuffersCount = 3;
static const int playerSampleRate = 48000; static const int playerSampleRate = 48000;
int finished;
int pcmOffset;
int size;
void cleanupPlayer() { void cleanupPlayer() {
if (_opusFile) { if (_opusFile) {
...@@ -585,14 +575,14 @@ int initPlayer(const char *path) { ...@@ -585,14 +575,14 @@ int initPlayer(const char *path) {
return 1; return 1;
} }
void fillBuffer(uint8_t *buffer, int capacity) { void fillBuffer(uint8_t *buffer, int capacity, int *args) {
if (_opusFile) { if (_opusFile) {
pcmOffset = max(0, op_pcm_tell(_opusFile)); args[1] = max(0, op_pcm_tell(_opusFile));
if (_finished) { if (_finished) {
finished = 1; args[0] = 0;
size = 0; args[1] = 0;
pcmOffset = 0; args[2] = 1;
return; return;
} else { } else {
int writtenOutputBytes = 0; int writtenOutputBytes = 0;
...@@ -612,19 +602,19 @@ void fillBuffer(uint8_t *buffer, int capacity) { ...@@ -612,19 +602,19 @@ void fillBuffer(uint8_t *buffer, int capacity) {
} }
} }
size = writtenOutputBytes; args[0] = writtenOutputBytes;
if (endOfFileReached || pcmOffset + size == _totalPcmDuration) { if (endOfFileReached || args[1] + args[0] == _totalPcmDuration) {
_finished = 1; _finished = 1;
finished = 1; args[2] = 1;
} else { } else {
finished = 0; args[2] = 0;
} }
} }
} else { } else {
memset(buffer, 0, capacity); memset(buffer, 0, capacity);
size = capacity; args[0] = capacity;
pcmOffset = _totalPcmDuration; args[1] = _totalPcmDuration;
} }
} }
...@@ -632,21 +622,11 @@ JNIEXPORT jlong Java_org_telegram_messenger_MediaController_getTotalPcmDuration( ...@@ -632,21 +622,11 @@ JNIEXPORT jlong Java_org_telegram_messenger_MediaController_getTotalPcmDuration(
return _totalPcmDuration; return _totalPcmDuration;
} }
JNIEXPORT int Java_org_telegram_messenger_MediaController_getFinished(JNIEnv *env, jclass class) { JNIEXPORT void Java_org_telegram_messenger_MediaController_readOpusFile(JNIEnv *env, jclass class, jobject buffer, jint capacity, jintArray args) {
return finished; jint *argsArr = (*env)->GetIntArrayElements(env, args, 0);
}
JNIEXPORT int Java_org_telegram_messenger_MediaController_getSize(JNIEnv *env, jclass class) {
return size;
}
JNIEXPORT jlong Java_org_telegram_messenger_MediaController_getPcmOffset(JNIEnv *env, jclass class) {
return pcmOffset;
}
JNIEXPORT void Java_org_telegram_messenger_MediaController_readOpusFile(JNIEnv *env, jclass class, jobject buffer, jint capacity) {
jbyte *bufferBytes = (*env)->GetDirectBufferAddress(env, buffer); jbyte *bufferBytes = (*env)->GetDirectBufferAddress(env, buffer);
fillBuffer(bufferBytes, capacity); fillBuffer(bufferBytes, capacity, argsArr);
(*env)->ReleaseIntArrayElements(env, args, argsArr, 0);
} }
JNIEXPORT int Java_org_telegram_messenger_MediaController_seekOpusFile(JNIEnv *env, jclass class, jfloat position) { JNIEXPORT int Java_org_telegram_messenger_MediaController_seekOpusFile(JNIEnv *env, jclass class, jfloat position) {
......
#!/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
This diff is collapsed.
#ifndef gif_h
#define gif_h
jint gifOnJNILoad(JavaVM *vm, void *reserved, JNIEnv *env);
void gifOnJNIUnload(JavaVM *vm, void *reserved);
#endif
\ No newline at end of file
// giflib config.h
#ifndef GIF_CONFIG_H_DEFINED
#define GIF_CONFIG_H_DEFINED
#include <sys/types.h>
#define HAVE_STDINT_H
#define HAVE_FCNTL_H
typedef uint32_t UINT32;
#endif
This diff is collapsed.
/*****************************************************************************
gif_hash.c -- module to support the following operations:
1. InitHashTable - initialize hash table.
2. ClearHashTable - clear the hash table to an empty state.
2. InsertHashTable - insert one item into data structure.
3. ExistsHashTable - test if item exists in data structure.
This module is used to hash the GIF codes during encoding.
*****************************************************************************/
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include "gif_lib.h"
#include "gif_hash.h"
#include "gif_lib_private.h"
/* #define DEBUG_HIT_RATE Debug number of misses per hash Insert/Exists. */
#ifdef DEBUG_HIT_RATE
static long NumberOfTests = 0,
NumberOfMisses = 0;
#endif /* DEBUG_HIT_RATE */
static int KeyItem(uint32_t Item);
/******************************************************************************
Initialize HashTable - allocate the memory needed and clear it. *
******************************************************************************/
GifHashTableType *_InitHashTable(void)
{
GifHashTableType *HashTable;
if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType)))
== NULL)
return NULL;
_ClearHashTable(HashTable);
return HashTable;
}
/******************************************************************************
Routine to clear the HashTable to an empty state. *
This part is a little machine depended. Use the commented part otherwise. *
******************************************************************************/
void _ClearHashTable(GifHashTableType *HashTable)
{
memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(uint32_t));
}
/******************************************************************************
Routine to insert a new Item into the HashTable. The data is assumed to be *
new one. *
******************************************************************************/
void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code)
{
int HKey = KeyItem(Key);
uint32_t *HTable = HashTable -> HTable;
#ifdef DEBUG_HIT_RATE
NumberOfTests++;
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) {
#ifdef DEBUG_HIT_RATE
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
HKey = (HKey + 1) & HT_KEY_MASK;
}
HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code);
}
/******************************************************************************
Routine to test if given Key exists in HashTable and if so returns its code *
Returns the Code if key was found, -1 if not. *
******************************************************************************/
int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key)
{
int HKey = KeyItem(Key);
uint32_t *HTable = HashTable -> HTable, HTKey;
#ifdef DEBUG_HIT_RATE
NumberOfTests++;
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) {
#ifdef DEBUG_HIT_RATE
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
if (Key == HTKey) return HT_GET_CODE(HTable[HKey]);
HKey = (HKey + 1) & HT_KEY_MASK;
}
return -1;
}
/******************************************************************************
Routine to generate an HKey for the hashtable out of the given unique key. *
The given Key is assumed to be 20 bits as follows: lower 8 bits are the *
new postfix character, while the upper 12 bits are the prefix code. *
Because the average hit ratio is only 2 (2 hash references per entry), *
evaluating more complex keys (such as twin prime keys) does not worth it! *
******************************************************************************/
static int KeyItem(uint32_t Item)
{
return ((Item >> 12) ^ Item) & HT_KEY_MASK;
}
#ifdef DEBUG_HIT_RATE
/******************************************************************************
Debugging routine to print the hit ratio - number of times the hash table *
was tested per operation. This routine was used to test the KeyItem routine *
******************************************************************************/
void HashTablePrintHitRatio(void)
{
printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n",
NumberOfMisses, NumberOfTests,
NumberOfMisses * 100 / NumberOfTests);
}
#endif /* DEBUG_HIT_RATE */
/* end */
/******************************************************************************
gif_hash.h - magfic constants and declarations for GIF LZW
******************************************************************************/
#ifndef _GIF_HASH_H_
#define _GIF_HASH_H_
#include <unistd.h>
#include <stdint.h>
#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
#define HT_KEY_MASK 0x1FFF /* 13bits keys */
#define HT_KEY_NUM_BITS 13 /* 13bits keys */
#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
/* The 32 bits of the long are divided into two parts for the key & code: */
/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
/* The key is the upper 20 bits. The code is the lower 12. */
#define HT_GET_KEY(l) (l >> 12)
#define HT_GET_CODE(l) (l & 0x0FFF)
#define HT_PUT_KEY(l) (l << 12)
#define HT_PUT_CODE(l) (l & 0x0FFF)
typedef struct GifHashTableType {
uint32_t HTable[HT_SIZE];
} GifHashTableType;
GifHashTableType *_InitHashTable(void);
void _ClearHashTable(GifHashTableType *HashTable);
void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code);
int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key);
#endif /* _GIF_HASH_H_ */
/* end */
This diff is collapsed.
/****************************************************************************
gif_lib_private.h - internal giflib routines and structures
****************************************************************************/
#ifndef _GIF_LIB_PRIVATE_H
#define _GIF_LIB_PRIVATE_H
#include "gif_lib.h"
#include "gif_hash.h"
#define EXTENSION_INTRODUCER 0x21
#define DESCRIPTOR_INTRODUCER 0x2c
#define TERMINATOR_INTRODUCER 0x3b
#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define LZ_BITS 12
#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */
#define FIRST_CODE 4097 /* Impossible code, to signal first. */
#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
#define FILE_STATE_WRITE 0x01
#define FILE_STATE_SCREEN 0x02
#define FILE_STATE_IMAGE 0x04
#define FILE_STATE_READ 0x08
#define IS_READABLE(Private) (Private->FileState & FILE_STATE_READ)
#define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE)
typedef struct GifFilePrivateType {
GifWord FileState, FileHandle, /* Where all this data goes to! */
BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
ClearCode, /* The CLEAR LZ code. */
EOFCode, /* The EOF LZ code. */
RunningCode, /* The next code algorithm can generate. */
RunningBits, /* The number of bits required to represent RunningCode. */
MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
LastCode, /* The code before the current code. */
CrntCode, /* Current algorithm code. */
StackPtr, /* For character stack (see below). */
CrntShiftState; /* Number of bits in CrntShiftDWord. */
unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
unsigned long PixelCount; /* Number of pixels in image. */
FILE *File; /* File as stream. */
InputFunc Read; /* function to read gif input (TVT) */
OutputFunc Write; /* function to write gif output (MRB) */
GifByteType Buf[256]; /* Compressed input is buffered here. */
GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
GifPrefixType Prefix[LZ_MAX_CODE + 1];
GifHashTableType *HashTable;
bool gif89;
} GifFilePrivateType;
#endif /* _GIF_LIB_PRIVATE_H */
/* end */
This diff is collapsed.
...@@ -3,9 +3,32 @@ ...@@ -3,9 +3,32 @@
#include <jni.h> #include <jni.h>
#include <sys/types.h> #include <sys/types.h>
#include <inttypes.h> #include <inttypes.h>
#include <android/log.h> #include <stdlib.h>
#include "aes.h" #include "aes/aes.h"
#include "log.h" #include "utils.h"
#include "sqlite.h"
#include "gif.h"
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = 0;
srand(time(NULL));
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
if (sqliteOnJNILoad(vm, reserved, env) == -1) {
return -1;
}
gifOnJNILoad(vm, reserved, env);
return JNI_VERSION_1_4;
}
void JNI_OnUnload(JavaVM *vm, void *reserved) {
gifOnJNIUnload(vm, reserved);
}
JNIEXPORT jbyteArray Java_org_telegram_messenger_Utilities_aesIgeEncryption(JNIEnv *env, jclass class, jbyteArray _what, jbyteArray _key, jbyteArray _iv, jboolean encrypt, jboolean changeIv, jint l) { JNIEXPORT jbyteArray Java_org_telegram_messenger_Utilities_aesIgeEncryption(JNIEnv *env, jclass class, jbyteArray _what, jbyteArray _key, jbyteArray _iv, jboolean encrypt, jboolean changeIv, jint l) {
unsigned char *what = (unsigned char *)(*env)->GetByteArrayElements(env, _what, NULL); unsigned char *what = (unsigned char *)(*env)->GetByteArrayElements(env, _what, NULL);
......
#include "sqlite3.h" #include "sqlite/sqlite3.h"
#include "org_telegram_SQLite.h" #include "sqlite.h"
void throw_sqlite3_exception(JNIEnv *env, sqlite3 *handle, int errcode) { void throw_sqlite3_exception(JNIEnv *env, sqlite3 *handle, int errcode) {
if (SQLITE_OK == errcode) { if (SQLITE_OK == errcode) {
......
#ifndef __SQLITE_H__ #ifndef sqlite_h
#define __SQLITE_H__ #define sqlite_h
#include <jni.h> #include <jni.h>
#include "sqlite3.h" #include "sqlite/sqlite3.h"
void throw_sqlite3_exception(JNIEnv* env, sqlite3 *handle, int errcode); void throw_sqlite3_exception(JNIEnv* env, sqlite3 *handle, int errcode);
jint sqliteOnJNILoad(JavaVM *vm, void *reserved, JNIEnv *env);
#endif #endif
#include "org_telegram_SQLite.h" #include "sqlite.h"
int Java_org_telegram_SQLite_SQLiteCursor_columnType(JNIEnv *env, jobject object, int statementHandle, int columnIndex) { int Java_org_telegram_SQLite_SQLiteCursor_columnType(JNIEnv *env, jobject object, int statementHandle, int columnIndex) {
sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle; sqlite3_stmt *handle = (sqlite3_stmt *)statementHandle;
......
#include "org_telegram_SQLite.h" #include "sqlite.h"
void Java_org_telegram_SQLite_SQLiteDatabase_closedb(JNIEnv *env, jobject object, int sqliteHandle) { void Java_org_telegram_SQLite_SQLiteDatabase_closedb(JNIEnv *env, jobject object, int sqliteHandle) {
sqlite3 *handle = (sqlite3 *)sqliteHandle; sqlite3 *handle = (sqlite3 *)sqliteHandle;
......
#include <time.h> #include "sqlite.h"
#include <stdlib.h>
#include "org_telegram_SQLite.h"
jfieldID queryArgsCountField; jfieldID queryArgsCountField;
jint JNI_OnLoad(JavaVM *vm, void *reserved) { jint sqliteOnJNILoad(JavaVM *vm, void *reserved, JNIEnv *env) {
JNIEnv* env = 0;
srand(time(NULL));
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
jclass class = (*env)->FindClass(env, "org/telegram/SQLite/SQLitePreparedStatement"); jclass class = (*env)->FindClass(env, "org/telegram/SQLite/SQLitePreparedStatement");
queryArgsCountField = (*env)->GetFieldID(env, class, "queryArgsCount", "I"); queryArgsCountField = (*env)->GetFieldID(env, class, "queryArgsCount", "I");
return JNI_VERSION_1_4; return JNI_VERSION_1_4;
} }
......
...@@ -9,4 +9,11 @@ ...@@ -9,4 +9,11 @@
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, 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__) #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#ifndef max
#define max(x, y) ((x) > (y)) ? (x) : (y)
#endif
#ifndef min
#define min(x, y) ((x) < (y)) ? (x) : (y)
#endif
#endif #endif
#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);
}
}
#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
#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();
}
This diff is collapsed.
...@@ -27,11 +27,11 @@ package org.telegram.PhoneFormat; ...@@ -27,11 +27,11 @@ package org.telegram.PhoneFormat;
import java.util.ArrayList; import java.util.ArrayList;
public class CallingCodeInfo { public class CallingCodeInfo {
public ArrayList<String> countries; public ArrayList<String> countries = new ArrayList<String>();
public String callingCode; public String callingCode = "";
public ArrayList<String> trunkPrefixes; public ArrayList<String> trunkPrefixes = new ArrayList<String>();
public ArrayList<String> intlPrefixes; public ArrayList<String> intlPrefixes = new ArrayList<String>();
public ArrayList<RuleSet> ruleSets; public ArrayList<RuleSet> ruleSets = new ArrayList<RuleSet>();
//public ArrayList formatStrings; //public ArrayList formatStrings;
String matchingAccessCode(String str) { String matchingAccessCode(String str) {
......
...@@ -30,7 +30,7 @@ import java.util.regex.Pattern; ...@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
public class RuleSet { public class RuleSet {
public int matchLen; public int matchLen;
public ArrayList<PhoneRule> rules; public ArrayList<PhoneRule> rules = new ArrayList<PhoneRule>();
public boolean hasRuleWithIntlPrefix; public boolean hasRuleWithIntlPrefix;
public boolean hasRuleWithTrunkPrefix; public boolean hasRuleWithTrunkPrefix;
public static Pattern pattern = Pattern.compile("[0-9]+"); public static Pattern pattern = Pattern.compile("[0-9]+");
......
...@@ -37,7 +37,7 @@ public class AwakeService extends Service { ...@@ -37,7 +37,7 @@ public class AwakeService extends Service {
public static void startService() { public static void startService() {
try { try {
if (MessagesController.isScreenOn && ApplicationLoader.lastPauseTime == 0) { if (ApplicationLoader.isScreenOn && ApplicationLoader.lastPauseTime == 0) {
return; return;
} }
timeout = 10000; timeout = 10000;
......
...@@ -649,7 +649,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -649,7 +649,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (phone.startsWith("968")) { if (phone.startsWith("968")) {
for (HashMap.Entry<Integer, Datacenter> entry : datacenters.entrySet()) { for (HashMap.Entry<Integer, Datacenter> entry : datacenters.entrySet()) {
Datacenter datacenter = entry.getValue(); Datacenter datacenter = entry.getValue();
datacenter.overridePort = 14; datacenter.overridePort = 8888;
if (datacenter.connection != null) { if (datacenter.connection != null) {
datacenter.connection.suspendConnection(true); datacenter.connection.suspendConnection(true);
} }
...@@ -2041,13 +2041,14 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -2041,13 +2041,14 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (request.serverFailureCount < 1) { if (request.serverFailureCount < 1) {
discardResponse = true; discardResponse = true;
request.runningMinStartTime = request.runningStartTime + 1; request.runningMinStartTime = request.runningStartTime + 1;
request.serverFailureCount++;
} }
} else { } else {
discardResponse = true; discardResponse = true;
request.runningMinStartTime = request.runningStartTime + 1; int delay = Math.min(1, request.serverFailureCount * 2);
request.runningMinStartTime = request.runningStartTime + delay;
request.confirmed = false; request.confirmed = false;
} }
request.serverFailureCount++;
} else if (errorCode == 420) { } else if (errorCode == 420) {
if ((request.flags & RPCRequest.RPCRequestClassFailOnServerErrors) == 0) { if ((request.flags & RPCRequest.RPCRequestClassFailOnServerErrors) == 0) {
double waitTime = 2.0; double waitTime = 2.0;
......
...@@ -323,19 +323,9 @@ public class ContactsController { ...@@ -323,19 +323,9 @@ public class ContactsController {
name = PhoneFormat.getInstance().format(phone); name = PhoneFormat.getInstance().format(phone);
} }
String[] args = name.split(" ", 2);
Contact contact = new Contact(); Contact contact = new Contact();
if (args.length > 0) { contact.first_name = name;
contact.first_name = args[0]; contact.last_name = "";
} else {
contact.first_name = "";
}
if (args.length > 1) {
contact.last_name = args[1];
} else {
contact.last_name = "";
}
contact.id = pCur.getInt(2); contact.id = pCur.getInt(2);
contactsMap.put(contact.id, contact); contactsMap.put(contact.id, contact);
......
...@@ -25,7 +25,7 @@ public class Datacenter { ...@@ -25,7 +25,7 @@ public class Datacenter {
public ArrayList<String> addresses = new ArrayList<String>(); public ArrayList<String> addresses = new ArrayList<String>();
public HashMap<String, Integer> ports = new HashMap<String, Integer>(); public HashMap<String, Integer> ports = new HashMap<String, Integer>();
public int[] defaultPorts = new int[] {-1, 80, -1, 443, -1, 443, -1, 80, -1, 443, -1}; public int[] defaultPorts = new int[] {-1, 80, -1, 443, -1, 443, -1, 80, -1, 443, -1};
public int[] defaultPorts14 = new int[] {-1, 14, -1, 443, -1, 14, -1, 80, -1, 14, -1}; public int[] defaultPorts8888 = new int[] {-1, 8888, -1, 443, -1, 8888, -1, 80, -1, 8888, -1};
public boolean authorized; public boolean authorized;
public long authSessionId; public long authSessionId;
public long authDownloadSessionId; public long authDownloadSessionId;
...@@ -136,8 +136,8 @@ public class Datacenter { ...@@ -136,8 +136,8 @@ public class Datacenter {
int[] portsArray = defaultPorts; int[] portsArray = defaultPorts;
if (overridePort == 14) { if (overridePort == 8888) {
portsArray = defaultPorts14; portsArray = defaultPorts8888;
} }
if (currentPortNum >= defaultPorts.length) { if (currentPortNum >= defaultPorts.length) {
......
...@@ -198,7 +198,7 @@ public class FileLoadOperation { ...@@ -198,7 +198,7 @@ public class FileLoadOperation {
} }
final boolean dontDelete = isLocalFile; final boolean dontDelete = isLocalFile;
if ((exist = cacheFileFinal.exists()) && !ignoreCache) { if ((exist = cacheFileFinal.exists()) && !ignoreCache) {
Utilities.cacheOutQueue.postRunnable(new Runnable() { FileLoader.cacheOutQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
...@@ -403,7 +403,7 @@ public class FileLoadOperation { ...@@ -403,7 +403,7 @@ public class FileLoadOperation {
final boolean renamed = cacheFileTemp.renameTo(cacheFileFinal); final boolean renamed = cacheFileTemp.renameTo(cacheFileFinal);
if (needBitmapCreate) { if (needBitmapCreate) {
Utilities.cacheOutQueue.postRunnable(new Runnable() { FileLoader.cacheOutQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
int delay = 20; int delay = 20;
...@@ -520,7 +520,7 @@ public class FileLoadOperation { ...@@ -520,7 +520,7 @@ public class FileLoadOperation {
int readed = httpConnectionStream.read(data); int readed = httpConnectionStream.read(data);
if (readed > 0) { if (readed > 0) {
fileOutputStream.write(data, 0, readed); fileOutputStream.write(data, 0, readed);
Utilities.imageLoadQueue.postRunnable(new Runnable() { FileLoader.fileLoaderQueue.postRunnable(new Runnable() {
@Override @Override
public void run() { public void run() {
startDownloadHTTPRequest(); startDownloadHTTPRequest();
......
...@@ -49,13 +49,13 @@ public class GcmBroadcastReceiver extends BroadcastReceiver { ...@@ -49,13 +49,13 @@ public class GcmBroadcastReceiver extends BroadcastReceiver {
} }
} }
AwakeService.startService();
Utilities.RunOnUIThread(new Runnable() { Utilities.RunOnUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
ApplicationLoader.postInitApplication(); ApplicationLoader.postInitApplication();
AwakeService.startService();
try { try {
String key = intent.getStringExtra("loc_key"); String key = intent.getStringExtra("loc_key");
if ("DC_UPDATE".equals(key)) { if ("DC_UPDATE".equals(key)) {
......
...@@ -2825,4 +2825,109 @@ public class MessagesStorage { ...@@ -2825,4 +2825,109 @@ public class MessagesStorage {
} }
}); });
} }
public TLRPC.User getUser(final int user_id) {
TLRPC.User user = null;
try {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid = %d", user_id));
if (cursor.next()) {
byte[] userData = cursor.byteArrayValue(0);
if (userData != null) {
SerializedData data = new SerializedData(userData);
user = (TLRPC.User) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
if (user != null) {
if (user.status != null) {
user.status.expires = cursor.intValue(1);
}
}
}
}
cursor.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return user;
}
public ArrayList<TLRPC.User> getUsers(final ArrayList<Integer> uids, final boolean[] error) {
ArrayList<TLRPC.User> users = new ArrayList<TLRPC.User>();
try {
String uidsStr = "";
for (Integer uid : uids) {
if (uidsStr.length() != 0) {
uidsStr += ",";
}
uidsStr += uid;
}
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, status FROM users WHERE uid IN (%s)", uidsStr));
while (cursor.next()) {
byte[] userData = cursor.byteArrayValue(0);
if (userData != null) {
SerializedData data = new SerializedData(userData);
TLRPC.User user = (TLRPC.User) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
if (user != null) {
if (user.status != null) {
user.status.expires = cursor.intValue(1);
}
users.add(user);
} else {
error[0] = true;
break;
}
} else {
error[0] = true;
break;
}
}
cursor.dispose();
} catch (Exception e) {
error[0] = true;
FileLog.e("tmessages", e);
}
return users;
}
public TLRPC.Chat getChat(final int chat_id) {
TLRPC.Chat chat = null;
try {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM chats WHERE uid = %d", chat_id));
if (cursor.next()) {
byte[] chatData = cursor.byteArrayValue(0);
if (chatData != null) {
SerializedData data = new SerializedData(chatData);
chat = (TLRPC.Chat) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
}
}
cursor.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return chat;
}
public TLRPC.EncryptedChat getEncryptedChat(final int chat_id) {
TLRPC.EncryptedChat chat = null;
try {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl FROM enc_chats WHERE uid = %d", chat_id));
if (cursor.next()) {
byte[] chatData = cursor.byteArrayValue(0);
if (chatData != null) {
SerializedData data = new SerializedData(chatData);
chat = (TLRPC.EncryptedChat) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
if (chat != null) {
chat.user_id = cursor.intValue(1);
chat.a_or_b = cursor.byteArrayValue(2);
chat.auth_key = cursor.byteArrayValue(3);
chat.ttl = cursor.intValue(4);
}
}
}
cursor.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return chat;
}
} }
...@@ -12,15 +12,17 @@ import android.content.BroadcastReceiver; ...@@ -12,15 +12,17 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import org.telegram.ui.ApplicationLoader;
public class ScreenReceiver extends BroadcastReceiver { public class ScreenReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
FileLog.e("tmessages", "screen off"); FileLog.e("tmessages", "screen off");
MessagesController.isScreenOn = false; ApplicationLoader.isScreenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
FileLog.e("tmessages", "screen on"); FileLog.e("tmessages", "screen on");
MessagesController.isScreenOn = true; ApplicationLoader.isScreenOn = true;
} }
} }
} }
...@@ -76,9 +76,6 @@ public class Utilities { ...@@ -76,9 +76,6 @@ public class Utilities {
public static volatile DispatchQueue stageQueue = new DispatchQueue("stageQueue"); public static volatile DispatchQueue stageQueue = new DispatchQueue("stageQueue");
public static volatile DispatchQueue globalQueue = new DispatchQueue("globalQueue"); public static volatile DispatchQueue globalQueue = new DispatchQueue("globalQueue");
public static volatile DispatchQueue cacheOutQueue = new DispatchQueue("cacheOutQueue");
public static volatile DispatchQueue imageLoadQueue = new DispatchQueue("imageLoadQueue");
public static volatile DispatchQueue fileUploadQueue = new DispatchQueue("fileUploadQueue");
public static int[] arrColors = {0xffee4928, 0xff41a903, 0xffe09602, 0xff0f94ed, 0xff8f3bf7, 0xfffc4380, 0xff00a1c4, 0xffeb7002}; public static int[] arrColors = {0xffee4928, 0xff41a903, 0xffe09602, 0xff0f94ed, 0xff8f3bf7, 0xfffc4380, 0xff00a1c4, 0xffeb7002};
public static int[] arrUsersAvatars = { public static int[] arrUsersAvatars = {
......
...@@ -60,6 +60,9 @@ public class PhotoObject { ...@@ -60,6 +60,9 @@ public class PhotoObject {
int closestHeight = 9999; int closestHeight = 9999;
TLRPC.PhotoSize closestObject = null; TLRPC.PhotoSize closestObject = null;
for (TLRPC.PhotoSize obj : sizes) { for (TLRPC.PhotoSize obj : sizes) {
if (obj == null) {
continue;
}
int diffW = Math.abs(obj.w - width); int diffW = Math.abs(obj.w - width);
int diffH = Math.abs(obj.h - height); int diffH = Math.abs(obj.h - height);
if (closestObject == null || closestObject instanceof TLRPC.TL_photoCachedSize || closestWidth > diffW || closestHeight > diffH) { if (closestObject == null || closestObject instanceof TLRPC.TL_photoCachedSize || closestWidth > diffW || closestHeight > diffH) {
......
...@@ -28,8 +28,8 @@ public class ChatMessageCell extends ChatBaseCell { ...@@ -28,8 +28,8 @@ public class ChatMessageCell extends ChatBaseCell {
private int firstVisibleBlockNum = 0; private int firstVisibleBlockNum = 0;
private int totalVisibleBlocksCount = 0; private int totalVisibleBlocksCount = 0;
public ChatMessageCell(Context context, boolean isChat) { public ChatMessageCell(Context context) {
super(context, isChat); super(context, false);
drawForwardedName = true; drawForwardedName = true;
} }
...@@ -131,7 +131,7 @@ public class ChatMessageCell extends ChatBaseCell { ...@@ -131,7 +131,7 @@ public class ChatMessageCell extends ChatBaseCell {
} }
pressedLink = null; pressedLink = null;
int maxWidth; int maxWidth;
if (chat) { if (isChat && !messageObject.messageOwner.out) {
maxWidth = Utilities.displaySize.x - Utilities.dp(122); maxWidth = Utilities.displaySize.x - Utilities.dp(122);
drawName = true; drawName = true;
} else { } else {
...@@ -180,7 +180,7 @@ public class ChatMessageCell extends ChatBaseCell { ...@@ -180,7 +180,7 @@ public class ChatMessageCell extends ChatBaseCell {
textX = layoutWidth - backgroundWidth + Utilities.dp(10); textX = layoutWidth - backgroundWidth + Utilities.dp(10);
textY = Utilities.dp(10) + namesOffset; textY = Utilities.dp(10) + namesOffset;
} else { } else {
textX = Utilities.dp(19) + (chat ? Utilities.dp(52) : 0); textX = Utilities.dp(19) + (isChat ? Utilities.dp(52) : 0);
textY = Utilities.dp(10) + namesOffset; textY = Utilities.dp(10) + namesOffset;
} }
} }
...@@ -196,7 +196,7 @@ public class ChatMessageCell extends ChatBaseCell { ...@@ -196,7 +196,7 @@ public class ChatMessageCell extends ChatBaseCell {
textX = layoutWidth - backgroundWidth + Utilities.dp(10); textX = layoutWidth - backgroundWidth + Utilities.dp(10);
textY = Utilities.dp(10) + namesOffset; textY = Utilities.dp(10) + namesOffset;
} else { } else {
textX = Utilities.dp(19) + (chat ? Utilities.dp(52) : 0); textX = Utilities.dp(19) + (isChat ? Utilities.dp(52) : 0);
textY = Utilities.dp(10) + namesOffset; textY = Utilities.dp(10) + namesOffset;
} }
......
...@@ -114,6 +114,15 @@ public class ChatOrUserCell extends BaseCell { ...@@ -114,6 +114,15 @@ public class ChatOrUserCell extends BaseCell {
update(0); update(0);
} }
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (avatarImage != null) {
avatarImage.clearImage();
lastAvatar = null;
}
}
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), Utilities.dp(64)); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), Utilities.dp(64));
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment