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];
} else {
contact.first_name = "";
}
if (args.length > 1) {
contact.last_name = args[1];
} else {
contact.last_name = ""; 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)) {
......
...@@ -20,9 +20,12 @@ import android.media.audiofx.AutomaticGainControl; ...@@ -20,9 +20,12 @@ import android.media.audiofx.AutomaticGainControl;
import android.net.Uri; import android.net.Uri;
import android.os.Environment; import android.os.Environment;
import android.os.Vibrator; import android.os.Vibrator;
import android.view.View;
import org.telegram.objects.MessageObject; import org.telegram.objects.MessageObject;
import org.telegram.ui.ApplicationLoader; import org.telegram.ui.ApplicationLoader;
import org.telegram.ui.Cells.ChatMediaCell;
import org.telegram.ui.Views.GifDrawable;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
...@@ -45,17 +48,16 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -45,17 +48,16 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
private native int seekOpusFile(float position); private native int seekOpusFile(float position);
private native int isOpusFile(String path); private native int isOpusFile(String path);
private native void closeOpusFile(); private native void closeOpusFile();
private native void readOpusFile(ByteBuffer buffer, int capacity); private native void readOpusFile(ByteBuffer buffer, int capacity, int[] args);
private native int getFinished();
private native int getSize();
private native long getPcmOffset();
private native long getTotalPcmDuration(); private native long getTotalPcmDuration();
public static int[] readArgs = new int[3];
public static interface FileDownloadProgressListener { public static interface FileDownloadProgressListener {
public void onFailedDownload(String fileName); public void onFailedDownload(String fileName);
public void onSuccessDownload(String fileName); public void onSuccessDownload(String fileName);
public void onProgressDownload(String fileName, float progress); public void onProgressDownload(String fileName, float progress);
public void onProgressUpload(String fileName, float progress, boolean isEncrypted);
public int getObserverTag(); public int getObserverTag();
} }
...@@ -86,6 +88,10 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -86,6 +88,10 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
private ArrayList<FileDownloadProgressListener> deleteLaterArray = new ArrayList<FileDownloadProgressListener>(); private ArrayList<FileDownloadProgressListener> deleteLaterArray = new ArrayList<FileDownloadProgressListener>();
private int lastTag = 0; private int lastTag = 0;
private GifDrawable currentGifDrawable;
private MessageObject currentGifMessageObject;
private ChatMediaCell currentMediaCell;
private boolean isPaused = false; private boolean isPaused = false;
private MediaPlayer audioPlayer = null; private MediaPlayer audioPlayer = null;
private AudioTrack audioTrackPlayer = null; private AudioTrack audioTrackPlayer = null;
...@@ -228,6 +234,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -228,6 +234,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
NotificationCenter.getInstance().addObserver(this, FileLoader.FileDidFailedLoad); NotificationCenter.getInstance().addObserver(this, FileLoader.FileDidFailedLoad);
NotificationCenter.getInstance().addObserver(this, FileLoader.FileDidLoaded); NotificationCenter.getInstance().addObserver(this, FileLoader.FileDidLoaded);
NotificationCenter.getInstance().addObserver(this, FileLoader.FileLoadProgressChanged); NotificationCenter.getInstance().addObserver(this, FileLoader.FileLoadProgressChanged);
NotificationCenter.getInstance().addObserver(this, FileLoader.FileUploadProgressChanged);
Timer progressTimer = new Timer(); Timer progressTimer = new Timer();
progressTimer.schedule(new TimerTask() { progressTimer.schedule(new TimerTask() {
...@@ -275,6 +282,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -275,6 +282,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
public void cleanup() { public void cleanup() {
clenupPlayer(false); clenupPlayer(false);
if (currentGifDrawable != null) {
currentGifDrawable.recycle();
currentGifDrawable = null;
}
currentMediaCell = null;
currentGifMessageObject = null;
} }
public int generateObserverTag() { public int generateObserverTag() {
...@@ -379,6 +392,22 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -379,6 +392,22 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
} }
listenerInProgress = false; listenerInProgress = false;
processLaterArrays(); processLaterArrays();
} else if (id == FileLoader.FileUploadProgressChanged) {
String location = (String)args[0];
listenerInProgress = true;
String fileName = (String)args[0];
ArrayList<WeakReference<FileDownloadProgressListener>> arrayList = loadingFileObservers.get(fileName);
if (arrayList != null) {
Float progress = (Float)args[1];
Boolean enc = (Boolean)args[2];
for (WeakReference<FileDownloadProgressListener> reference : arrayList) {
if (reference.get() != null) {
reference.get().onProgressUpload(fileName, progress, enc);
}
}
}
listenerInProgress = false;
processLaterArrays();
} }
} }
...@@ -403,10 +432,10 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -403,10 +432,10 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
} }
} }
if (buffer != null) { if (buffer != null) {
readOpusFile(buffer.buffer, playerBufferSize); readOpusFile(buffer.buffer, playerBufferSize, readArgs);
buffer.size = getSize(); buffer.size = readArgs[0];
buffer.pcmOffset = getPcmOffset(); buffer.pcmOffset = readArgs[1];
buffer.finished = getFinished(); buffer.finished = readArgs[2];
if (buffer.finished == 1) { if (buffer.finished == 1) {
decodingFinished = true; decodingFinished = true;
} }
...@@ -832,6 +861,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -832,6 +861,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
fileBuffer.rewind(); fileBuffer.rewind();
if (android.os.Build.VERSION.SDK_INT >= 16) { if (android.os.Build.VERSION.SDK_INT >= 16) {
File f = new File("/vendor/lib/libaudioeffect_jni.so");
File f2 = new File("/system/lib/libaudioeffect_jni.so");
if (f.exists() || f2.exists()) {
AutomaticGainControl agc = null; AutomaticGainControl agc = null;
try { try {
if (AutomaticGainControl.isAvailable()) { if (AutomaticGainControl.isAvailable()) {
...@@ -851,6 +883,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -851,6 +883,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
FileLog.e("tmessages", e); FileLog.e("tmessages", e);
} }
} }
}
audioRecorder.startRecording(); audioRecorder.startRecording();
} catch (Exception e) { } catch (Exception e) {
...@@ -1077,4 +1110,73 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -1077,4 +1110,73 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}); });
} }
} }
public GifDrawable getGifDrawable(ChatMediaCell cell, boolean create) {
if (cell == null) {
return null;
}
MessageObject messageObject = cell.getMessageObject();
if (messageObject == null) {
return null;
}
if (currentGifMessageObject != null && messageObject.messageOwner.id == currentGifMessageObject.messageOwner.id) {
currentMediaCell = cell;
currentGifDrawable.parentView = new WeakReference<View>(cell);
return currentGifDrawable;
}
if (create) {
if (currentMediaCell != null) {
if (currentGifDrawable != null) {
currentGifDrawable.stop();
currentGifDrawable.recycle();
}
currentMediaCell.clearGifImage();
}
currentGifMessageObject = cell.getMessageObject();
currentMediaCell = cell;
File cacheFile = null;
if (currentGifMessageObject.messageOwner.attachPath != null && currentGifMessageObject.messageOwner.attachPath.length() != 0) {
File f = new File(currentGifMessageObject.messageOwner.attachPath);
if (f.length() > 0) {
cacheFile = f;
}
} else {
cacheFile = new File(Utilities.getCacheDir(), messageObject.getFileName());
}
try {
currentGifDrawable = new GifDrawable(cacheFile);
currentGifDrawable.parentView = new WeakReference<View>(cell);
return currentGifDrawable;
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
return null;
}
public void clearGifDrawable(ChatMediaCell cell) {
if (cell == null) {
return;
}
MessageObject messageObject = cell.getMessageObject();
if (messageObject == null) {
return;
}
if (currentGifMessageObject != null && messageObject.messageOwner.id == currentGifMessageObject.messageOwner.id) {
if (currentGifDrawable != null) {
currentGifDrawable.stop();
currentGifDrawable.recycle();
currentGifDrawable = null;
}
currentMediaCell = null;
currentGifMessageObject = null;
}
}
} }
...@@ -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;
} }
} }
} }
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