mirror of
https://github.com/DrKLO/Telegram.git
synced 2024-12-22 06:25:14 +01:00
update to 9.5.8
This commit is contained in:
parent
7e6d40a77a
commit
683c4e6dcb
25 changed files with 399 additions and 336 deletions
|
@ -435,7 +435,7 @@ target_include_directories(breakpad PUBLIC
|
|||
#voip
|
||||
include(${CMAKE_HOME_DIRECTORY}/voip/CMakeLists.txt)
|
||||
|
||||
set(NATIVE_LIB "tmessages.43")
|
||||
set(NATIVE_LIB "tmessages.44")
|
||||
|
||||
#tmessages
|
||||
add_library(${NATIVE_LIB} SHARED
|
||||
|
|
|
@ -13,47 +13,48 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <android/log.h>
|
||||
#include <jni.h>
|
||||
#include <stdlib.h>
|
||||
#include <android/log.h>
|
||||
|
||||
extern "C" {
|
||||
#ifdef __cplusplus
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
#ifdef _STDINT_H
|
||||
#undef _STDINT_H
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavresample/avresample.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/error.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libswresample/swresample.h>
|
||||
}
|
||||
|
||||
#define LOG_TAG "ffmpeg_jni"
|
||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
|
||||
__VA_ARGS__))
|
||||
|
||||
#define DECODER_FUNC(RETURN_TYPE, NAME, ...) \
|
||||
extern "C" { \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegDecoder_ ## NAME \
|
||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__);\
|
||||
} \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegDecoder_ ## NAME \
|
||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
|
||||
#define LOGE(...) \
|
||||
((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
|
||||
#define LIBRARY_FUNC(RETURN_TYPE, NAME, ...) \
|
||||
extern "C" { \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegLibrary_ ## NAME \
|
||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__);\
|
||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegLibrary_##NAME( \
|
||||
JNIEnv *env, jobject thiz, ##__VA_ARGS__); \
|
||||
} \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegLibrary_ ## NAME \
|
||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
|
||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegLibrary_##NAME( \
|
||||
JNIEnv *env, jobject thiz, ##__VA_ARGS__)
|
||||
|
||||
#define AUDIO_DECODER_FUNC(RETURN_TYPE, NAME, ...) \
|
||||
extern "C" { \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegAudioDecoder_##NAME( \
|
||||
JNIEnv *env, jobject thiz, ##__VA_ARGS__); \
|
||||
} \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegAudioDecoder_##NAME( \
|
||||
JNIEnv *env, jobject thiz, ##__VA_ARGS__)
|
||||
|
||||
#define ERROR_STRING_BUFFER_LENGTH 256
|
||||
|
||||
|
@ -62,9 +63,8 @@ static const AVSampleFormat OUTPUT_FORMAT_PCM_16BIT = AV_SAMPLE_FMT_S16;
|
|||
// Output format corresponding to AudioFormat.ENCODING_PCM_FLOAT.
|
||||
static const AVSampleFormat OUTPUT_FORMAT_PCM_FLOAT = AV_SAMPLE_FMT_FLT;
|
||||
|
||||
// Error codes matching FfmpegDecoder.java.
|
||||
static const int DECODER_ERROR_INVALID_DATA = -1;
|
||||
static const int DECODER_ERROR_OTHER = -2;
|
||||
static const int AUDIO_DECODER_ERROR_INVALID_DATA = -1;
|
||||
static const int AUDIO_DECODER_ERROR_OTHER = -2;
|
||||
|
||||
/**
|
||||
* Returns the AVCodec with the specified name, or NULL if it is not available.
|
||||
|
@ -82,11 +82,17 @@ AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
|
|||
|
||||
/**
|
||||
* Decodes the packet into the output buffer, returning the number of bytes
|
||||
* written, or a negative DECODER_ERROR constant value in the case of an error.
|
||||
* written, or a negative AUDIO_DECODER_ERROR constant value in the case of an
|
||||
* error.
|
||||
*/
|
||||
int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||
uint8_t *outputBuffer, int outputSize);
|
||||
|
||||
/**
|
||||
* Transforms ffmpeg AVERROR into a negative AUDIO_DECODER_ERROR constant value.
|
||||
*/
|
||||
int transformError(int errorNumber);
|
||||
|
||||
/**
|
||||
* Outputs a log message describing the avcodec error number.
|
||||
*/
|
||||
|
@ -101,12 +107,17 @@ LIBRARY_FUNC(jstring, ffmpegGetVersion) {
|
|||
return env->NewStringUTF(LIBAVCODEC_IDENT);
|
||||
}
|
||||
|
||||
LIBRARY_FUNC(jint, ffmpegGetInputBufferPaddingSize) {
|
||||
return (jint)AV_INPUT_BUFFER_PADDING_SIZE;
|
||||
}
|
||||
|
||||
LIBRARY_FUNC(jboolean, ffmpegHasDecoder, jstring codecName) {
|
||||
return getCodecByName(env, codecName) != NULL;
|
||||
}
|
||||
|
||||
DECODER_FUNC(jlong, ffmpegInitialize, jstring codecName, jbyteArray extraData,
|
||||
jboolean outputFloat, jint rawSampleRate, jint rawChannelCount) {
|
||||
AUDIO_DECODER_FUNC(jlong, ffmpegInitialize, jstring codecName,
|
||||
jbyteArray extraData, jboolean outputFloat,
|
||||
jint rawSampleRate, jint rawChannelCount) {
|
||||
AVCodec *codec = getCodecByName(env, codecName);
|
||||
if (!codec) {
|
||||
LOGE("Codec not found.");
|
||||
|
@ -116,7 +127,7 @@ DECODER_FUNC(jlong, ffmpegInitialize, jstring codecName, jbyteArray extraData,
|
|||
rawChannelCount);
|
||||
}
|
||||
|
||||
DECODER_FUNC(jint, ffmpegDecode, jlong context, jobject inputData,
|
||||
AUDIO_DECODER_FUNC(jint, ffmpegDecode, jlong context, jobject inputData,
|
||||
jint inputSize, jobject outputData, jint outputSize) {
|
||||
if (!context) {
|
||||
LOGE("Context must be non-NULL.");
|
||||
|
@ -144,7 +155,7 @@ DECODER_FUNC(jint, ffmpegDecode, jlong context, jobject inputData,
|
|||
outputSize);
|
||||
}
|
||||
|
||||
DECODER_FUNC(jint, ffmpegGetChannelCount, jlong context) {
|
||||
AUDIO_DECODER_FUNC(jint, ffmpegGetChannelCount, jlong context) {
|
||||
if (!context) {
|
||||
LOGE("Context must be non-NULL.");
|
||||
return -1;
|
||||
|
@ -152,7 +163,7 @@ DECODER_FUNC(jint, ffmpegGetChannelCount, jlong context) {
|
|||
return ((AVCodecContext *)context)->channels;
|
||||
}
|
||||
|
||||
DECODER_FUNC(jint, ffmpegGetSampleRate, jlong context) {
|
||||
AUDIO_DECODER_FUNC(jint, ffmpegGetSampleRate, jlong context) {
|
||||
if (!context) {
|
||||
LOGE("Context must be non-NULL.");
|
||||
return -1;
|
||||
|
@ -160,7 +171,7 @@ DECODER_FUNC(jint, ffmpegGetSampleRate, jlong context) {
|
|||
return ((AVCodecContext *)context)->sample_rate;
|
||||
}
|
||||
|
||||
DECODER_FUNC(jlong, ffmpegReset, jlong jContext, jbyteArray extraData) {
|
||||
AUDIO_DECODER_FUNC(jlong, ffmpegReset, jlong jContext, jbyteArray extraData) {
|
||||
AVCodecContext *context = (AVCodecContext *)jContext;
|
||||
if (!context) {
|
||||
LOGE("Tried to reset without a context.");
|
||||
|
@ -188,7 +199,7 @@ DECODER_FUNC(jlong, ffmpegReset, jlong jContext, jbyteArray extraData) {
|
|||
return (jlong)context;
|
||||
}
|
||||
|
||||
DECODER_FUNC(void, ffmpegRelease, jlong context) {
|
||||
AUDIO_DECODER_FUNC(void, ffmpegRelease, jlong context) {
|
||||
if (context) {
|
||||
releaseContext((AVCodecContext *)context);
|
||||
}
|
||||
|
@ -249,8 +260,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
|||
result = avcodec_send_packet(context, packet);
|
||||
if (result) {
|
||||
logError("avcodec_send_packet", result);
|
||||
return result == AVERROR_INVALIDDATA ? DECODER_ERROR_INVALID_DATA
|
||||
: DECODER_ERROR_OTHER;
|
||||
return transformError(result);
|
||||
}
|
||||
|
||||
// Dequeue output data until it runs out.
|
||||
|
@ -259,7 +269,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
|||
AVFrame *frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
LOGE("Failed to allocate output frame.");
|
||||
return -1;
|
||||
return AUDIO_DECODER_ERROR_INVALID_DATA;
|
||||
}
|
||||
result = avcodec_receive_frame(context, frame);
|
||||
if (result) {
|
||||
|
@ -268,7 +278,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
|||
break;
|
||||
}
|
||||
logError("avcodec_receive_frame", result);
|
||||
return result;
|
||||
return transformError(result);
|
||||
}
|
||||
|
||||
// Resample output.
|
||||
|
@ -279,11 +289,11 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
|||
int sampleCount = frame->nb_samples;
|
||||
int dataSize = av_samples_get_buffer_size(NULL, channelCount, sampleCount,
|
||||
sampleFormat, 1);
|
||||
AVAudioResampleContext *resampleContext;
|
||||
SwrContext *resampleContext;
|
||||
if (context->opaque) {
|
||||
resampleContext = (AVAudioResampleContext *) context->opaque;
|
||||
resampleContext = (SwrContext *)context->opaque;
|
||||
} else {
|
||||
resampleContext = avresample_alloc_context();
|
||||
resampleContext = swr_alloc();
|
||||
av_opt_set_int(resampleContext, "in_channel_layout", channelLayout, 0);
|
||||
av_opt_set_int(resampleContext, "out_channel_layout", channelLayout, 0);
|
||||
av_opt_set_int(resampleContext, "in_sample_rate", sampleRate, 0);
|
||||
|
@ -292,37 +302,36 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
|||
// The output format is always the requested format.
|
||||
av_opt_set_int(resampleContext, "out_sample_fmt",
|
||||
context->request_sample_fmt, 0);
|
||||
result = avresample_open(resampleContext);
|
||||
result = swr_init(resampleContext);
|
||||
if (result < 0) {
|
||||
logError("avresample_open", result);
|
||||
logError("swr_init", result);
|
||||
av_frame_free(&frame);
|
||||
return -1;
|
||||
return transformError(result);
|
||||
}
|
||||
context->opaque = resampleContext;
|
||||
}
|
||||
int inSampleSize = av_get_bytes_per_sample(sampleFormat);
|
||||
int outSampleSize = av_get_bytes_per_sample(context->request_sample_fmt);
|
||||
int outSamples = avresample_get_out_samples(resampleContext, sampleCount);
|
||||
int outSamples = swr_get_out_samples(resampleContext, sampleCount);
|
||||
int bufferOutSize = outSampleSize * channelCount * outSamples;
|
||||
if (outSize + bufferOutSize > outputSize) {
|
||||
LOGE("Output buffer size (%d) too small for output data (%d).",
|
||||
outputSize, outSize + bufferOutSize);
|
||||
av_frame_free(&frame);
|
||||
return -1;
|
||||
return AUDIO_DECODER_ERROR_INVALID_DATA;
|
||||
}
|
||||
result = avresample_convert(resampleContext, &outputBuffer, bufferOutSize,
|
||||
outSamples, frame->data, frame->linesize[0],
|
||||
sampleCount);
|
||||
result = swr_convert(resampleContext, &outputBuffer, bufferOutSize,
|
||||
(const uint8_t **)frame->data, frame->nb_samples);
|
||||
av_frame_free(&frame);
|
||||
if (result < 0) {
|
||||
logError("avresample_convert", result);
|
||||
return result;
|
||||
logError("swr_convert", result);
|
||||
return AUDIO_DECODER_ERROR_INVALID_DATA;
|
||||
}
|
||||
int available = avresample_available(resampleContext);
|
||||
int available = swr_get_out_samples(resampleContext, 0);
|
||||
if (available != 0) {
|
||||
LOGE("Expected no samples remaining after resampling, but found %d.",
|
||||
available);
|
||||
return -1;
|
||||
return AUDIO_DECODER_ERROR_INVALID_DATA;
|
||||
}
|
||||
outputBuffer += bufferOutSize;
|
||||
outSize += bufferOutSize;
|
||||
|
@ -330,6 +339,11 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
|||
return outSize;
|
||||
}
|
||||
|
||||
int transformError(int errorNumber) {
|
||||
return errorNumber == AVERROR_INVALIDDATA ? AUDIO_DECODER_ERROR_INVALID_DATA
|
||||
: AUDIO_DECODER_ERROR_OTHER;
|
||||
}
|
||||
|
||||
void logError(const char *functionName, int errorNumber) {
|
||||
char *buffer = (char *)malloc(ERROR_STRING_BUFFER_LENGTH * sizeof(char));
|
||||
av_strerror(errorNumber, buffer, ERROR_STRING_BUFFER_LENGTH);
|
||||
|
@ -341,11 +355,10 @@ void releaseContext(AVCodecContext *context) {
|
|||
if (!context) {
|
||||
return;
|
||||
}
|
||||
AVAudioResampleContext *resampleContext;
|
||||
if ((resampleContext = (AVAudioResampleContext *) context->opaque)) {
|
||||
avresample_free(&resampleContext);
|
||||
SwrContext *swrContext;
|
||||
if ((swrContext = (SwrContext *)context->opaque)) {
|
||||
swr_free(&swrContext);
|
||||
context->opaque = NULL;
|
||||
}
|
||||
avcodec_free_context(&context);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
if (mid == NULL) {
|
||||
jclass cls = env->GetObjectClass(flacDecoderJni);
|
||||
mid = env->GetMethodID(cls, "read", "(Ljava/nio/ByteBuffer;)I");
|
||||
env->DeleteLocalRef(cls);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +58,7 @@ public:
|
|||
// Exception is thrown in Java when returning from the native call.
|
||||
result = -1;
|
||||
}
|
||||
env->DeleteLocalRef(byteBuffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -147,7 +149,7 @@ DECODER_FUNC(jobject, flacDecodeMetadata, jlong jContext) {
|
|||
context->parser->getStreamInfo();
|
||||
|
||||
jclass flacStreamMetadataClass = env->FindClass(
|
||||
"com/google/android/exoplayer2/util/"
|
||||
"com/google/android/exoplayer2/extractor/"
|
||||
"FlacStreamMetadata");
|
||||
jmethodID flacStreamMetadataConstructor =
|
||||
env->GetMethodID(flacStreamMetadataClass, "<init>",
|
||||
|
|
|
@ -16,9 +16,8 @@
|
|||
|
||||
#include "include/flac_parser.h"
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <android/log.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
|
|
|
@ -14,49 +14,60 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
#include <jni.h>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "opus.h" // NOLINT
|
||||
#include "opus_multistream.h" // NOLINT
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#define LOG_TAG "opus_jni"
|
||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, \
|
||||
__VA_ARGS__))
|
||||
#define LOGE(...) \
|
||||
((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
#else // __ANDROID__
|
||||
#define LOGE(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif // __ANDROID__
|
||||
|
||||
#define DECODER_FUNC(RETURN_TYPE, NAME, ...) \
|
||||
extern "C" { \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_opus_OpusDecoder_ ## NAME \
|
||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__);\
|
||||
Java_com_google_android_exoplayer2_ext_opus_OpusDecoder_##NAME( \
|
||||
JNIEnv* env, jobject thiz, ##__VA_ARGS__); \
|
||||
} \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_opus_OpusDecoder_ ## NAME \
|
||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
|
||||
Java_com_google_android_exoplayer2_ext_opus_OpusDecoder_##NAME( \
|
||||
JNIEnv* env, jobject thiz, ##__VA_ARGS__)
|
||||
|
||||
#define LIBRARY_FUNC(RETURN_TYPE, NAME, ...) \
|
||||
extern "C" { \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_opus_OpusLibrary_ ## NAME \
|
||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__);\
|
||||
Java_com_google_android_exoplayer2_ext_opus_OpusLibrary_##NAME( \
|
||||
JNIEnv* env, jobject thiz, ##__VA_ARGS__); \
|
||||
} \
|
||||
JNIEXPORT RETURN_TYPE \
|
||||
Java_com_google_android_exoplayer2_ext_opus_OpusLibrary_ ## NAME \
|
||||
(JNIEnv* env, jobject thiz, ##__VA_ARGS__)\
|
||||
Java_com_google_android_exoplayer2_ext_opus_OpusLibrary_##NAME( \
|
||||
JNIEnv* env, jobject thiz, ##__VA_ARGS__)
|
||||
|
||||
// JNI references for SimpleOutputBuffer class.
|
||||
static jmethodID outputBufferInit;
|
||||
|
||||
static const int kBytesPerSample = 2; // opus fixed point uses 16 bit samples.
|
||||
static const int kBytesPerIntPcmSample = 2;
|
||||
static const int kBytesPerFloatSample = 4;
|
||||
static const int kMaxOpusOutputPacketSizeSamples = 960 * 6;
|
||||
static int channelCount;
|
||||
static int errorCode;
|
||||
static bool outputFloat = false;
|
||||
|
||||
DECODER_FUNC(jlong, opusInit, jint sampleRate, jint channelCount,
|
||||
jint numStreams, jint numCoupled, jint gain, jbyteArray jStreamMap) {
|
||||
jint numStreams, jint numCoupled, jint gain,
|
||||
jbyteArray jStreamMap) {
|
||||
int status = OPUS_INVALID_STATE;
|
||||
::channelCount = channelCount;
|
||||
errorCode = 0;
|
||||
|
@ -77,9 +88,9 @@ DECODER_FUNC(jlong, opusInit, jint sampleRate, jint channelCount,
|
|||
|
||||
// Populate JNI References.
|
||||
const jclass outputBufferClass = env->FindClass(
|
||||
"com/google/android/exoplayer2/decoder/SimpleOutputBuffer");
|
||||
outputBufferInit = env->GetMethodID(outputBufferClass, "init",
|
||||
"(JI)Ljava/nio/ByteBuffer;");
|
||||
"com/google/android/exoplayer2/decoder/SimpleDecoderOutputBuffer");
|
||||
outputBufferInit =
|
||||
env->GetMethodID(outputBufferClass, "init", "(JI)Ljava/nio/ByteBuffer;");
|
||||
|
||||
return reinterpret_cast<intptr_t>(decoder);
|
||||
}
|
||||
|
@ -87,40 +98,52 @@ DECODER_FUNC(jlong, opusInit, jint sampleRate, jint channelCount,
|
|||
DECODER_FUNC(jint, opusDecode, jlong jDecoder, jlong jTimeUs,
|
||||
jobject jInputBuffer, jint inputSize, jobject jOutputBuffer) {
|
||||
OpusMSDecoder* decoder = reinterpret_cast<OpusMSDecoder*>(jDecoder);
|
||||
const uint8_t* inputBuffer =
|
||||
reinterpret_cast<const uint8_t*>(
|
||||
const uint8_t* inputBuffer = reinterpret_cast<const uint8_t*>(
|
||||
env->GetDirectBufferAddress(jInputBuffer));
|
||||
|
||||
const int byteSizePerSample =
|
||||
outputFloat ? kBytesPerFloatSample : kBytesPerIntPcmSample;
|
||||
const jint outputSize =
|
||||
kMaxOpusOutputPacketSizeSamples * kBytesPerSample * channelCount;
|
||||
kMaxOpusOutputPacketSizeSamples * byteSizePerSample * channelCount;
|
||||
|
||||
env->CallObjectMethod(jOutputBuffer, outputBufferInit, jTimeUs, outputSize);
|
||||
if (env->ExceptionCheck()) {
|
||||
// Exception is thrown in Java when returning from the native call.
|
||||
return -1;
|
||||
}
|
||||
const jobject jOutputBufferData = env->CallObjectMethod(jOutputBuffer,
|
||||
outputBufferInit, jTimeUs, outputSize);
|
||||
const jobject jOutputBufferData = env->CallObjectMethod(
|
||||
jOutputBuffer, outputBufferInit, jTimeUs, outputSize);
|
||||
if (env->ExceptionCheck()) {
|
||||
// Exception is thrown in Java when returning from the native call.
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sampleCount;
|
||||
if (outputFloat) {
|
||||
float* outputBufferData = reinterpret_cast<float*>(
|
||||
env->GetDirectBufferAddress(jOutputBufferData));
|
||||
sampleCount = opus_multistream_decode_float(
|
||||
decoder, inputBuffer, inputSize, outputBufferData,
|
||||
kMaxOpusOutputPacketSizeSamples, 0);
|
||||
} else {
|
||||
int16_t* outputBufferData = reinterpret_cast<int16_t*>(
|
||||
env->GetDirectBufferAddress(jOutputBufferData));
|
||||
int sampleCount = opus_multistream_decode(decoder, inputBuffer, inputSize,
|
||||
outputBufferData, kMaxOpusOutputPacketSizeSamples, 0);
|
||||
sampleCount = opus_multistream_decode(decoder, inputBuffer, inputSize,
|
||||
outputBufferData,
|
||||
kMaxOpusOutputPacketSizeSamples, 0);
|
||||
}
|
||||
|
||||
// record error code
|
||||
errorCode = (sampleCount < 0) ? sampleCount : 0;
|
||||
return (sampleCount < 0) ? sampleCount
|
||||
: sampleCount * kBytesPerSample * channelCount;
|
||||
: sampleCount * byteSizePerSample * channelCount;
|
||||
}
|
||||
|
||||
DECODER_FUNC(jint, opusSecureDecode, jlong jDecoder, jlong jTimeUs,
|
||||
jobject jInputBuffer, jint inputSize, jobject jOutputBuffer,
|
||||
jint sampleRate, jobject mediaCrypto, jint inputMode, jbyteArray key,
|
||||
jbyteArray javaIv, jint inputNumSubSamples, jintArray numBytesOfClearData,
|
||||
jintArray numBytesOfEncryptedData) {
|
||||
jint sampleRate, jobject mediaCrypto, jint inputMode,
|
||||
jbyteArray key, jbyteArray javaIv, jint inputNumSubSamples,
|
||||
jintArray numBytesOfClearData, jintArray numBytesOfEncryptedData) {
|
||||
// Doesn't support
|
||||
// Java client should have checked vpxSupportSecureDecode
|
||||
// and avoid calling this
|
||||
|
@ -142,9 +165,9 @@ DECODER_FUNC(jstring, opusGetErrorMessage, jlong jContext) {
|
|||
return env->NewStringUTF(opus_strerror(errorCode));
|
||||
}
|
||||
|
||||
DECODER_FUNC(jint, opusGetErrorCode, jlong jContext) {
|
||||
return errorCode;
|
||||
}
|
||||
DECODER_FUNC(jint, opusGetErrorCode, jlong jContext) { return errorCode; }
|
||||
|
||||
DECODER_FUNC(void, opusSetFloatOutput) { outputFloat = true; }
|
||||
|
||||
LIBRARY_FUNC(jstring, opusIsSecureDecodeSupported) {
|
||||
// Doesn't support
|
||||
|
|
6
TMessagesProj/proguard-rules.pro
vendored
6
TMessagesProj/proguard-rules.pro
vendored
|
@ -23,9 +23,9 @@
|
|||
-keep class org.telegram.tgnet.QuickAckDelegate { *; }
|
||||
-keep class org.telegram.tgnet.WriteToSocketDelegate { *; }
|
||||
-keep class com.google.android.exoplayer2.ext.** { *; }
|
||||
-keep class com.google.android.exoplayer2.util.FlacStreamMetadata { *; }
|
||||
-keep class com.google.android.exoplayer2.extractor.FlacStreamMetadata { *; }
|
||||
-keep class com.google.android.exoplayer2.metadata.flac.PictureFrame { *; }
|
||||
-keep class com.google.android.exoplayer2.decoder.SimpleOutputBuffer { *; }
|
||||
-keep class com.google.android.exoplayer2.decoder.SimpleDecoderOutputBuffer { *; }
|
||||
|
||||
# https://developers.google.com/ml-kit/known-issues#android_issues
|
||||
-keep class com.google.mlkit.nl.languageid.internal.LanguageIdentificationJni { *; }
|
||||
|
@ -42,7 +42,7 @@
|
|||
}
|
||||
|
||||
# Some members of this class are being accessed from native methods. Keep them unobfuscated.
|
||||
-keep class com.google.android.exoplayer2.video.VideoDecoderOutputBuffer {
|
||||
-keep class com.google.android.exoplayer2.decoder.VideoDecoderOutputBuffer {
|
||||
*;
|
||||
}
|
||||
|
||||
|
|
|
@ -2229,6 +2229,10 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
|
|||
}
|
||||
}
|
||||
|
||||
public boolean hasPendingScrollPosition() {
|
||||
return mPendingScrollPosition >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class that keeps temporary state while {LayoutManager} is filling out the empty
|
||||
* space.
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.google.android.exoplayer2.util.LibraryLoader;
|
|||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.telegram.messenger.NativeLoader;
|
||||
|
||||
/** Configures and queries the underlying native library. */
|
||||
public final class FfmpegLibrary {
|
||||
|
@ -32,14 +33,6 @@ public final class FfmpegLibrary {
|
|||
|
||||
private static final String TAG = "FfmpegLibrary";
|
||||
|
||||
private static final LibraryLoader LOADER =
|
||||
new LibraryLoader("ffmpegJNI") {
|
||||
@Override
|
||||
protected void loadLibrary(String name) {
|
||||
System.loadLibrary(name);
|
||||
}
|
||||
};
|
||||
|
||||
private static @MonotonicNonNull String version;
|
||||
private static int inputBufferPaddingSize = C.LENGTH_UNSET;
|
||||
|
||||
|
@ -53,12 +46,12 @@ public final class FfmpegLibrary {
|
|||
* @param libraries The names of the FFmpeg native libraries.
|
||||
*/
|
||||
public static void setLibraries(String... libraries) {
|
||||
LOADER.setLibraries(libraries);
|
||||
|
||||
}
|
||||
|
||||
/** Returns whether the underlying library is available, loading it if necessary. */
|
||||
public static boolean isAvailable() {
|
||||
return LOADER.isAvailable();
|
||||
return NativeLoader.loaded();
|
||||
}
|
||||
|
||||
/** Returns the version of the underlying library if available, or null otherwise. */
|
||||
|
|
|
@ -18,6 +18,8 @@ package com.google.android.exoplayer2.ext.flac;
|
|||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.util.LibraryLoader;
|
||||
|
||||
import org.telegram.messenger.NativeLoader;
|
||||
|
||||
/** Configures and queries the underlying native library. */
|
||||
public final class FlacLibrary {
|
||||
|
||||
|
@ -25,13 +27,6 @@ public final class FlacLibrary {
|
|||
ExoPlayerLibraryInfo.registerModule("goog.exo.flac");
|
||||
}
|
||||
|
||||
private static final LibraryLoader LOADER =
|
||||
new LibraryLoader("flacJNI") {
|
||||
@Override
|
||||
protected void loadLibrary(String name) {
|
||||
System.loadLibrary(name);
|
||||
}
|
||||
};
|
||||
|
||||
private FlacLibrary() {}
|
||||
|
||||
|
@ -43,11 +38,10 @@ public final class FlacLibrary {
|
|||
* @param libraries The names of the Flac native libraries.
|
||||
*/
|
||||
public static void setLibraries(String... libraries) {
|
||||
LOADER.setLibraries(libraries);
|
||||
}
|
||||
|
||||
/** Returns whether the underlying library is available, loading it if necessary. */
|
||||
public static boolean isAvailable() {
|
||||
return LOADER.isAvailable();
|
||||
return NativeLoader.loaded();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import com.google.android.exoplayer2.C;
|
|||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.util.LibraryLoader;
|
||||
|
||||
import org.telegram.messenger.NativeLoader;
|
||||
|
||||
/** Configures and queries the underlying native library. */
|
||||
public final class OpusLibrary {
|
||||
|
||||
|
@ -27,14 +29,6 @@ public final class OpusLibrary {
|
|||
ExoPlayerLibraryInfo.registerModule("goog.exo.opus");
|
||||
}
|
||||
|
||||
private static final LibraryLoader LOADER =
|
||||
new LibraryLoader("opusV2JNI") {
|
||||
@Override
|
||||
protected void loadLibrary(String name) {
|
||||
System.loadLibrary(name);
|
||||
}
|
||||
};
|
||||
|
||||
private static @C.CryptoType int cryptoType = C.CRYPTO_TYPE_UNSUPPORTED;
|
||||
|
||||
private OpusLibrary() {}
|
||||
|
@ -51,12 +45,11 @@ public final class OpusLibrary {
|
|||
*/
|
||||
public static void setLibraries(@C.CryptoType int cryptoType, String... libraries) {
|
||||
OpusLibrary.cryptoType = cryptoType;
|
||||
LOADER.setLibraries(libraries);
|
||||
}
|
||||
|
||||
/** Returns whether the underlying library is available, loading it if necessary. */
|
||||
public static boolean isAvailable() {
|
||||
return LOADER.isAvailable();
|
||||
return NativeLoader.loaded();
|
||||
}
|
||||
|
||||
/** Returns the version of the underlying library if available, or null otherwise. */
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.util;
|
||||
|
||||
import static java.lang.System.loadLibrary;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/** Configurable loader for native libraries. */
|
||||
|
@ -72,5 +74,5 @@ public abstract class LibraryLoader {
|
|||
*
|
||||
* @param name The name of the library to load.
|
||||
*/
|
||||
protected abstract void loadLibrary(String name);
|
||||
protected abstract void oadLibrary(String name);
|
||||
}
|
||||
|
|
|
@ -256,7 +256,11 @@ public class ApplicationLoader extends Application {
|
|||
}
|
||||
|
||||
NativeLoader.initNativeLibs(ApplicationLoader.applicationContext);
|
||||
try {
|
||||
ConnectionsManager.native_setJava(false);
|
||||
} catch (UnsatisfiedLinkError error) {
|
||||
throw new RuntimeException("can't load native libraries " + Build.CPU_ABI + " lookup folder " + NativeLoader.getAbiFolder());
|
||||
}
|
||||
new ForegroundDetector(this) {
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
|
|
|
@ -24,8 +24,8 @@ public class BuildVars {
|
|||
public static boolean USE_CLOUD_STRINGS = true;
|
||||
public static boolean CHECK_UPDATES = true;
|
||||
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
|
||||
public static int BUILD_VERSION = 3249;
|
||||
public static String BUILD_VERSION_STRING = "9.5.7";
|
||||
public static int BUILD_VERSION = 3252;
|
||||
public static String BUILD_VERSION_STRING = "9.5.8";
|
||||
public static int APP_ID = 4;
|
||||
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ public final class EmuInputDevicesDetector {
|
|||
}
|
||||
}
|
||||
}
|
||||
r.close();
|
||||
return lines;
|
||||
} catch (IOException e) {
|
||||
FileLog.e(e);
|
||||
|
|
|
@ -2277,7 +2277,8 @@ public class ImageLoader {
|
|||
newPath = ApplicationLoader.applicationContext.getExternalFilesDir(null);
|
||||
telegramPath = new File(newPath, "Telegram");
|
||||
} else {
|
||||
if (!(path.exists() ? path.isDirectory() : path.mkdirs()) || !path.canWrite()) {
|
||||
boolean isSdCard = !TextUtils.isEmpty(SharedConfig.storageCacheDir) && path.getAbsolutePath().startsWith(SharedConfig.storageCacheDir);
|
||||
if (!isSdCard && !(path.exists() ? path.isDirectory() : path.mkdirs()) || !path.canWrite()) {
|
||||
path = ApplicationLoader.applicationContext.getExternalFilesDir(null);
|
||||
}
|
||||
telegramPath = new File(path, "Telegram");
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.util.zip.ZipFile;
|
|||
|
||||
public class NativeLoader {
|
||||
|
||||
private final static int LIB_VERSION = 43;
|
||||
private final static int LIB_VERSION = 44;
|
||||
private final static String LIB_NAME = "tmessages." + LIB_VERSION;
|
||||
private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so";
|
||||
private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so";
|
||||
|
@ -127,36 +127,7 @@ public class NativeLoader {
|
|||
FileLog.e(e);
|
||||
}
|
||||
|
||||
String folder;
|
||||
try {
|
||||
String str = Build.CPU_ABI;
|
||||
if (Build.CPU_ABI.equalsIgnoreCase("x86_64")) {
|
||||
folder = "x86_64";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("arm64-v8a")) {
|
||||
folder = "arm64-v8a";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("armeabi-v7a")) {
|
||||
folder = "armeabi-v7a";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("armeabi")) {
|
||||
folder = "armeabi";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("x86")) {
|
||||
folder = "x86";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("mips")) {
|
||||
folder = "mips";
|
||||
} else {
|
||||
folder = "armeabi";
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.e("Unsupported arch: " + Build.CPU_ABI);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
folder = "armeabi";
|
||||
}
|
||||
|
||||
String javaArch = System.getProperty("os.arch");
|
||||
if (javaArch != null && javaArch.contains("686")) {
|
||||
folder = "x86";
|
||||
}
|
||||
String folder = getAbiFolder();
|
||||
|
||||
/*File destFile = getNativeLibraryDir(context);
|
||||
if (destFile != null) {
|
||||
|
@ -209,6 +180,40 @@ public class NativeLoader {
|
|||
}
|
||||
}
|
||||
|
||||
public static String getAbiFolder() {
|
||||
String folder;
|
||||
try {
|
||||
String str = Build.CPU_ABI;
|
||||
if (Build.CPU_ABI.equalsIgnoreCase("x86_64")) {
|
||||
folder = "x86_64";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("arm64-v8a")) {
|
||||
folder = "arm64-v8a";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("armeabi-v7a")) {
|
||||
folder = "armeabi-v7a";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("armeabi")) {
|
||||
folder = "armeabi";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("x86")) {
|
||||
folder = "x86";
|
||||
} else if (Build.CPU_ABI.equalsIgnoreCase("mips")) {
|
||||
folder = "mips";
|
||||
} else {
|
||||
folder = "armeabi";
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.e("Unsupported arch: " + Build.CPU_ABI);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
folder = "armeabi";
|
||||
}
|
||||
|
||||
String javaArch = System.getProperty("os.arch");
|
||||
if (javaArch != null && javaArch.contains("686")) {
|
||||
folder = "x86";
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
|
||||
private static native void init(String path, boolean enable);
|
||||
|
||||
public static boolean loaded() {
|
||||
|
|
|
@ -4837,7 +4837,7 @@ public class DialogCell extends BaseCell {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
int messageHash = message == null ? 0 : message.getId();
|
||||
int messageHash = message == null ? 0 : message.getId() + message.hashCode();
|
||||
Integer printingType = null;
|
||||
long readHash = dialog.read_inbox_max_id + ((long) dialog.read_outbox_max_id << 8) + ((long) (dialog.unread_count + (dialog.unread_mark ? -1 : 0)) << 16) +
|
||||
(dialog.unread_reactions_count > 0 ? (1 << 18) : 0) +
|
||||
|
|
|
@ -134,7 +134,7 @@ public class DialogsRequestedEmptyCell extends LinearLayout implements Notificat
|
|||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.diceStickersDidLoad);
|
||||
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.diceStickersDidLoad);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3507,6 +3507,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthSpec, int heightSpec) {
|
||||
saveScrollPosition();
|
||||
super.onMeasure(widthSpec, heightSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
|
@ -8748,28 +8754,24 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
if (chatListView != null && chatLayoutManager != null && chatAdapter != null) {
|
||||
if (chatListView.getPaddingTop() != p) {
|
||||
int firstVisPos = chatLayoutManager.findFirstVisibleItemPosition();
|
||||
int lastVisPos = chatLayoutManager.findLastVisibleItemPosition();
|
||||
int top = 0;
|
||||
MessageObject scrollToMessageObject = null;
|
||||
if (firstVisPos != RecyclerView.NO_POSITION) {
|
||||
for (int i = firstVisPos; i <= lastVisPos; i++) {
|
||||
View v = chatLayoutManager.findViewByPosition(i);
|
||||
for (int i = 0; i < chatListView.getChildCount(); i++) {
|
||||
View v = chatListView.getChildAt(i);
|
||||
if (v instanceof ChatMessageCell) {
|
||||
scrollToMessageObject = ((ChatMessageCell) v).getMessageObject();
|
||||
top = chatListView.getMeasuredHeight() - v.getBottom() - chatListView.getPaddingBottom();
|
||||
top = getScrollingOffsetForView(v);
|
||||
break;
|
||||
} else if (v instanceof ChatActionCell) {
|
||||
scrollToMessageObject = ((ChatActionCell) v).getMessageObject();
|
||||
top = chatListView.getMeasuredHeight() - v.getBottom() - chatListView.getPaddingBottom();
|
||||
top = getScrollingOffsetForView(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chatListView.setPadding(0, p, 0, AndroidUtilities.dp(3) + blurredViewBottomOffset);
|
||||
|
||||
if (firstVisPos != RecyclerView.NO_POSITION && scrollToMessageObject != null) {
|
||||
if (scrollToMessageObject != null) {
|
||||
chatAdapter.updateRowsSafe();
|
||||
int index = messages.indexOf(scrollToMessageObject);
|
||||
if (index >= 0) {
|
||||
|
@ -15843,24 +15845,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
startLoadFromMessageId = 0;
|
||||
}
|
||||
if (newRowsCount > 0) {
|
||||
int firstVisPos = chatLayoutManager.findFirstVisibleItemPosition();
|
||||
int lastVisPos = chatLayoutManager.findLastVisibleItemPosition();
|
||||
int top = 0;
|
||||
MessageObject scrollToMessageObject = null;
|
||||
if (firstVisPos != RecyclerView.NO_POSITION) {
|
||||
for (int i = firstVisPos; i <= lastVisPos; i++) {
|
||||
View v = chatLayoutManager.findViewByPosition(i);
|
||||
for (int i = 0; i < chatListView.getChildCount(); i++) {
|
||||
View v = chatListView.getChildAt(i);
|
||||
if (v instanceof ChatMessageCell) {
|
||||
scrollToMessageObject = ((ChatMessageCell) v).getMessageObject();
|
||||
top = chatListView.getMeasuredHeight() - v.getBottom() - chatListView.getPaddingBottom();
|
||||
top = getScrollingOffsetForView(v);
|
||||
break;
|
||||
} else if (v instanceof ChatActionCell) {
|
||||
scrollToMessageObject = ((ChatActionCell) v).getMessageObject();
|
||||
top = chatListView.getMeasuredHeight() - v.getBottom() - chatListView.getPaddingBottom();
|
||||
top = getScrollingOffsetForView(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!postponedScroll) {
|
||||
chatAdapter.notifyItemRangeInserted(1, newRowsCount);
|
||||
|
@ -15959,24 +15957,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
} else {
|
||||
if (newRowsCount != 0) {
|
||||
int firstVisPos = chatLayoutManager.findFirstVisibleItemPosition();
|
||||
int lastVisPos = chatLayoutManager.findLastVisibleItemPosition();
|
||||
int top = 0;
|
||||
MessageObject scrollToMessageObject = null;
|
||||
if (firstVisPos != RecyclerView.NO_POSITION) {
|
||||
for (int i = firstVisPos; i <= lastVisPos; i++) {
|
||||
View v = chatLayoutManager.findViewByPosition(i);
|
||||
for (int i = 0; i < chatListView.getChildCount(); i++) {
|
||||
View v = chatListView.getChildAt(i);
|
||||
if (v instanceof ChatMessageCell) {
|
||||
scrollToMessageObject = ((ChatMessageCell) v).getMessageObject();
|
||||
top = chatListView.getMeasuredHeight() - v.getBottom() - chatListView.getPaddingBottom();
|
||||
top = getScrollingOffsetForView(v);
|
||||
break;
|
||||
} else if (v instanceof ChatActionCell) {
|
||||
scrollToMessageObject = ((ChatActionCell) v).getMessageObject();
|
||||
top = chatListView.getMeasuredHeight() - v.getBottom() - chatListView.getPaddingBottom();
|
||||
top = getScrollingOffsetForView(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
int insertStart = chatAdapter.messagesEndRow;
|
||||
int loadingUpRow = chatAdapter.loadingUpRow;
|
||||
chatAdapter.updateRowsInternal();
|
||||
|
@ -18268,6 +18262,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
}
|
||||
|
||||
private int getScrollingOffsetForView(View v) {
|
||||
return chatListView.getMeasuredHeight() - v.getBottom() - chatListView.getPaddingBottom();
|
||||
}
|
||||
|
||||
private boolean updateMessageTranslation(MessageObject messageObject) {
|
||||
if (messageObject == null || messageObject.messageOwner == null) {
|
||||
return false;
|
||||
|
@ -19438,7 +19436,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
} else {
|
||||
if (child != null) {
|
||||
chatLayoutManager.scrollToPositionWithOffset(lastVisible + 1, chatListView.getMeasuredHeight() - child.getBottom() - chatListView.getPaddingBottom());
|
||||
chatLayoutManager.scrollToPositionWithOffset(lastVisible + 1, getScrollingOffsetForView(child));
|
||||
}
|
||||
}
|
||||
if (newMentionsCount != 0 && mentiondownButtonCounter != null) {
|
||||
|
@ -19488,6 +19486,32 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
}
|
||||
|
||||
private void saveScrollPosition() {
|
||||
if (chatListView == null || chatLayoutManager == null || chatLayoutManager.hasPendingScrollPosition()) {
|
||||
return;
|
||||
}
|
||||
int top = 0;
|
||||
MessageObject scrollToMessageObject = null;
|
||||
for (int i = 0; i < chatListView.getChildCount(); i++) {
|
||||
View v = chatListView.getChildAt(i);
|
||||
if (v instanceof ChatMessageCell) {
|
||||
scrollToMessageObject = ((ChatMessageCell) v).getMessageObject();
|
||||
top = getScrollingOffsetForView(v);
|
||||
break;
|
||||
} else if (v instanceof ChatActionCell) {
|
||||
scrollToMessageObject = ((ChatActionCell) v).getMessageObject();
|
||||
top = getScrollingOffsetForView(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scrollToMessageObject != null) {
|
||||
int scrollToIndex = messages.indexOf(scrollToMessageObject);
|
||||
if (scrollToIndex > 0) {
|
||||
chatLayoutManager.scrollToPositionWithOffset(chatAdapter.messagesStartRow + scrollToIndex, top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getSponsoredMessagesCount() {
|
||||
int sponsoredMessagesCount = 0;
|
||||
while (sponsoredMessagesCount < messages.size()) {
|
||||
|
@ -26123,7 +26147,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
int unreadMessageIndex = messages.indexOf(unreadMessageObject);
|
||||
if (unreadMessageIndex >= 0) {
|
||||
lastVisibleItem = chatAdapter.messagesStartRow + messages.indexOf(unreadMessageObject);
|
||||
top = chatListView.getMeasuredHeight() - child.getBottom() - chatListView.getPaddingBottom();
|
||||
top = getScrollingOffsetForView(child);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -26185,7 +26209,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
}
|
||||
if (lastVisibleItem != RecyclerView.NO_POSITION) {
|
||||
// chatLayoutManager.scrollToPositionWithOffset(lastVisibleItem, top);
|
||||
chatLayoutManager.scrollToPositionWithOffset(lastVisibleItem, top);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28288,7 +28312,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
int unreadMessageIndex = messages.indexOf(unreadMessageObject);
|
||||
if (unreadMessageIndex >= 0) {
|
||||
lastVisibleItem = messagesStartRow + messages.indexOf(unreadMessageObject);
|
||||
top = chatListView.getMeasuredHeight() - child.getBottom() - chatListView.getPaddingBottom();
|
||||
top = getScrollingOffsetForView(child);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.text.Layout;
|
|||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
|
@ -357,11 +358,11 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
|
|||
if (isOutboundGift) {
|
||||
titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumOutboundDialogTitleWithPlural, user != null ? user.first_name : "", LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
|
||||
subtitleView.setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumOutboundDialogSubtitle, user != null ? user.first_name : ""), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
|
||||
} else if (user != null && user.id == 777000) {
|
||||
} else if (user == null || TextUtils.isEmpty(user.first_name) || user.id == 777000) {
|
||||
titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumDialogTitleWithPluralSomeone, LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
|
||||
subtitleView.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.TelegramPremiumUserGiftedPremiumDialogSubtitle)));
|
||||
} else {
|
||||
titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumDialogTitleWithPlural, user != null ? user.first_name : "", LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
|
||||
titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumDialogTitleWithPlural, user.first_name, LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
|
||||
subtitleView.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.TelegramPremiumUserGiftedPremiumDialogSubtitle)));
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -294,7 +294,6 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
|
|||
if (onAnimationEndListener != null) {
|
||||
onAnimationEndListener = null;
|
||||
}
|
||||
invalidateInternal();
|
||||
}
|
||||
|
||||
public void setOnFinishCallback(Runnable callback, int frame) {
|
||||
|
|
|
@ -94,7 +94,7 @@ public class StickerCategoriesListView extends RecyclerListView {
|
|||
|
||||
public static void preload(int account, @CategoriesType int type) {
|
||||
fetcher.fetch(account, type, emojiGroups -> {
|
||||
if (emojiGroups.groups == null) {
|
||||
if (emojiGroups == null || emojiGroups.groups == null) {
|
||||
return;
|
||||
}
|
||||
for (TLRPC.TL_emojiGroup group : emojiGroups.groups) {
|
||||
|
|
|
@ -8683,6 +8683,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
} else if (id == NotificationCenter.dialogsUnreadReactionsCounterChanged) {
|
||||
updateVisibleRows(0);
|
||||
} else if (id == NotificationCenter.emojiLoaded) {
|
||||
if (viewPages != null) {
|
||||
for (int i = 0; i < viewPages.length; ++i) {
|
||||
final RecyclerListView listView = viewPages[i].listView;
|
||||
if (listView != null) {
|
||||
|
@ -8694,6 +8695,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filterTabsView != null) {
|
||||
filterTabsView.getTabsContainer().invalidateViews();
|
||||
}
|
||||
|
|
|
@ -1682,9 +1682,9 @@ public class LoginActivity extends BaseFragment {
|
|||
|
||||
if (obj.optBoolean("basicIntegrity") && obj.optBoolean("ctsProfileMatch")) {
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
|
||||
if (response instanceof TLRPC.TL_boolTrue) {
|
||||
needHideProgress(false);
|
||||
isRequestingFirebaseSms = false;
|
||||
if (response instanceof TLRPC.TL_boolTrue) {
|
||||
res.type.verifiedFirebase = true;
|
||||
AndroidUtilities.runOnUIThread(() -> fillNextCodeParams(params, res, animate));
|
||||
} else {
|
||||
|
@ -3654,19 +3654,6 @@ public class LoginActivity extends BaseFragment {
|
|||
wrongCode.setPadding(0, AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4));
|
||||
errorViewSwitcher.addView(wrongCode, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
|
||||
|
||||
if (currentType != AUTH_TYPE_FRAGMENT_SMS) {
|
||||
if (currentType == AUTH_TYPE_MESSAGE) {
|
||||
if (nextType == AUTH_TYPE_FLASH_CALL || nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_MISSED_CALL) {
|
||||
problemText.setText(LocaleController.getString("DidNotGetTheCodePhone", R.string.DidNotGetTheCodePhone));
|
||||
} else if (nextType == 0) {
|
||||
problemText.setText(LocaleController.getString("DidNotGetTheCode", R.string.DidNotGetTheCode));
|
||||
} else {
|
||||
problemText.setText(LocaleController.getString("DidNotGetTheCodeSms", R.string.DidNotGetTheCodeSms));
|
||||
}
|
||||
} else {
|
||||
problemText.setText(LocaleController.getString("DidNotGetTheCode", R.string.DidNotGetTheCode));
|
||||
}
|
||||
}
|
||||
if (centerContainer == null) {
|
||||
bottomContainer = new FrameLayout(context);
|
||||
bottomContainer.addView(errorViewSwitcher, LayoutHelper.createFrame(currentType == VIEW_CODE_FRAGMENT_SMS ? LayoutHelper.MATCH_PARENT : LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 32));
|
||||
|
@ -3998,6 +3985,20 @@ public class LoginActivity extends BaseFragment {
|
|||
}
|
||||
confirmTextView.setText(str);
|
||||
|
||||
if (currentType != AUTH_TYPE_FRAGMENT_SMS) {
|
||||
if (currentType == AUTH_TYPE_MESSAGE) {
|
||||
if (nextType == AUTH_TYPE_FLASH_CALL || nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_MISSED_CALL) {
|
||||
problemText.setText(LocaleController.getString("DidNotGetTheCodePhone", R.string.DidNotGetTheCodePhone));
|
||||
} else if (nextType == 0) {
|
||||
problemText.setText(LocaleController.getString("DidNotGetTheCode", R.string.DidNotGetTheCode));
|
||||
} else {
|
||||
problemText.setText(LocaleController.getString("DidNotGetTheCodeSms", R.string.DidNotGetTheCodeSms));
|
||||
}
|
||||
} else {
|
||||
problemText.setText(LocaleController.getString("DidNotGetTheCode", R.string.DidNotGetTheCode));
|
||||
}
|
||||
}
|
||||
|
||||
if (currentType != AUTH_TYPE_FLASH_CALL) {
|
||||
showKeyboard(codeFieldContainer.codeField[0]);
|
||||
codeFieldContainer.codeField[0].requestFocus();
|
||||
|
@ -4015,7 +4016,8 @@ public class LoginActivity extends BaseFragment {
|
|||
if (problemText != null) {
|
||||
problemText.setVisibility(VISIBLE);
|
||||
}
|
||||
} else if (currentType == AUTH_TYPE_FLASH_CALL && (nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_SMS)) {
|
||||
} else if (currentType == AUTH_TYPE_FLASH_CALL) {
|
||||
if (nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_SMS || nextType == AUTH_TYPE_MISSED_CALL) {
|
||||
setProblemTextVisible(false);
|
||||
timeText.setVisibility(VISIBLE);
|
||||
problemText.setVisibility(GONE);
|
||||
|
@ -4024,12 +4026,13 @@ public class LoginActivity extends BaseFragment {
|
|||
} else if (nextType == AUTH_TYPE_SMS) {
|
||||
timeText.setText(LocaleController.formatString("SmsAvailableIn", R.string.SmsAvailableIn, 1, 0));
|
||||
}
|
||||
}
|
||||
String callLogNumber = restore ? AndroidUtilities.obtainLoginPhoneCall(pattern) : null;
|
||||
if (callLogNumber != null) {
|
||||
onNextPressed(callLogNumber);
|
||||
} else if (catchedPhone != null) {
|
||||
onNextPressed(catchedPhone);
|
||||
} else {
|
||||
} else if (nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_SMS || nextType == AUTH_TYPE_MISSED_CALL) {
|
||||
createTimer();
|
||||
}
|
||||
} else if (currentType == AUTH_TYPE_SMS && (nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_FLASH_CALL)) {
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
#Sat Mar 12 05:53:50 MSK 2016
|
||||
APP_VERSION_CODE=3249
|
||||
APP_VERSION_NAME=9.5.7
|
||||
APP_VERSION_CODE=3252
|
||||
APP_VERSION_NAME=9.5.8
|
||||
APP_PACKAGE=org.telegram.messenger
|
||||
RELEASE_KEY_PASSWORD=android
|
||||
RELEASE_KEY_ALIAS=androidkey
|
||||
RELEASE_STORE_PASSWORD=android
|
||||
RELEASE_KEY_PASSWORD=TelegramAndroidPswd
|
||||
RELEASE_KEY_ALIAS=tmessages
|
||||
RELEASE_STORE_PASSWORD=TelegramAndroidPswd
|
||||
org.gradle.jvmargs=-Xmx4096M -XX:MaxPermSize=4096m
|
||||
org.gradle.daemon=true
|
||||
org.gradle.parallel=true
|
||||
|
|
Loading…
Reference in a new issue