Commit fe599cd5 authored by DrKLO's avatar DrKLO

Update to 4.9.1

parent d073b800

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

......@@ -11,26 +11,29 @@ configurations {
}
dependencies {
compile 'com.google.firebase:firebase-messaging:17.1.0'
compile 'com.google.firebase:firebase-config:16.0.0'
compile 'com.google.android.gms:play-services-maps:15.0.1'
compile 'com.google.android.gms:play-services-vision:15.0.2'
compile 'com.google.android.gms:play-services-wallet:15.0.1'
compile 'com.google.android.gms:play-services-wearable:15.0.1'
implementation 'com.android.support:support-core-ui:27.1.1'
implementation 'com.android.support:support-compat:27.1.1'
implementation 'com.android.support:support-core-utils:27.1.1'
implementation 'com.android.support:support-v13:27.1.1'
implementation 'com.android.support:palette-v7:27.1.1'
implementation 'com.android.support:exifinterface:27.1.1'
compile 'net.hockeyapp.android:HockeySDK:5.1.0'
compile 'com.googlecode.mp4parser:isoparser:1.0.6'
compile 'com.stripe:stripe-android:2.0.2'
compileOnly 'org.checkerframework:checker-qual:2.5.0'
compileOnly 'org.checkerframework:checker-compat-qual:2.5.0'
implementation 'com.google.firebase:firebase-core:16.0.3'
implementation 'com.google.firebase:firebase-messaging:17.3.0'
implementation 'com.google.firebase:firebase-config:16.0.0'
implementation 'com.google.android.gms:play-services-maps:15.0.1'
implementation 'com.google.android.gms:play-services-vision:15.0.2'
implementation 'com.google.android.gms:play-services-wallet:16.0.0'
implementation 'com.google.android.gms:play-services-wearable:15.0.1'
implementation 'com.android.support:support-core-ui:28.0.0-rc01'
implementation 'com.android.support:support-compat:28.0.0-rc01'
implementation 'com.android.support:support-core-utils:28.0.0-rc01'
implementation 'com.android.support:support-v13:28.0.0-rc01'
implementation 'com.android.support:palette-v7:28.0.0-rc01'
implementation 'com.android.support:exifinterface:28.0.0-rc01'
implementation 'net.hockeyapp.android:HockeySDK:5.1.0'
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
implementation 'com.stripe:stripe-android:2.0.2'
}
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
compileSdkVersion 28
buildToolsVersion '28.0.2'
defaultConfig.applicationId = "org.telegram.messenger"
......@@ -52,8 +55,8 @@ android {
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
signingConfigs {
......@@ -98,7 +101,7 @@ android {
}
}
defaultConfig.versionCode = 1340
defaultConfig.versionCode = 1358
sourceSets.debug {
manifest.srcFile 'config/debug/AndroidManifest.xml'
......@@ -235,7 +238,7 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 27
versionName "4.9.0"
versionName "4.9.1"
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']
......
......@@ -387,7 +387,7 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := tmessages.28
LOCAL_MODULE := tmessages.29
LOCAL_CFLAGS := -w -std=c11 -Os -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno
LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math -D__STDC_CONSTANT_MACROS
......
......@@ -142,10 +142,12 @@ jlong Java_org_telegram_SQLite_SQLiteDatabase_opendb(JNIEnv *env, jobject object
char const *fileNameStr = env->GetStringUTFChars(fileName, 0);
char const *tempDirStr = env->GetStringUTFChars(tempDir, 0);
if (sqlite3_temp_directory != 0) {
if (sqlite3_temp_directory != 0 && strcmp(sqlite3_temp_directory, tempDirStr)) {
sqlite3_free(sqlite3_temp_directory);
}
sqlite3_temp_directory = sqlite3_mprintf("%s", tempDirStr);
if (sqlite3_temp_directory == 0) {
sqlite3_temp_directory = sqlite3_mprintf("%s", tempDirStr);
}
sqlite3 *handle = 0;
int err = sqlite3_open(fileNameStr, &handle);
......
......@@ -39,6 +39,8 @@ jmethodID jclass_ConnectionsManager_onProxyError;
jmethodID jclass_ConnectionsManager_getHostByName;
jmethodID jclass_ConnectionsManager_getInitFlags;
bool check_utf8(const char *data, size_t len);
/*jint createLoadOpetation(JNIEnv *env, jclass c, jint dc_id, jlong id, jlong volume_id, jlong access_hash, jint local_id, jbyteArray encKey, jbyteArray encIv, jstring extension, jint version, jint size, jstring dest, jstring temp, jobject delegate) {
if (encKey != nullptr && encIv == nullptr || encKey == nullptr && encIv != nullptr || extension == nullptr || dest == nullptr || temp == nullptr) {
return 0;
......@@ -196,7 +198,13 @@ void sendRequest(JNIEnv *env, jclass c, jint instanceNum, jlong object, jobject
ptr = (jlong) resp->response.get();
} else if (error != nullptr) {
errorCode = error->code;
errorText = jniEnv[instanceNum]->NewStringUTF(error->text.c_str());
const char *text = error->text.c_str();
size_t size = error->text.size();
if (check_utf8(text, size)) {
errorText = jniEnv[instanceNum]->NewStringUTF(text);
} else {
errorText = jniEnv[instanceNum]->NewStringUTF("UTF-8 ERROR");
}
}
if (onComplete != nullptr) {
jniEnv[instanceNum]->CallVoidMethod(onComplete, jclass_RequestDelegateInternal_run, ptr, errorCode, errorText, networkType);
......@@ -632,3 +640,56 @@ extern "C" int registerNativeTgNetFunctions(JavaVM *vm, JNIEnv *env) {
return JNI_TRUE;
}
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
bool check_utf8(const char *data, size_t len) {
const char *data_end = data + len;
do {
unsigned int a = (unsigned char) (*data++);
if ((a & 0x80) == 0) {
if (data == data_end + 1) {
return true;
}
continue;
}
#define ENSURE(condition) \
if (!(condition)) { \
return false; \
}
ENSURE((a & 0x40) != 0);
unsigned int b = (unsigned char) (*data++);
ENSURE((b & 0xc0) == 0x80);
if ((a & 0x20) == 0) {
ENSURE((a & 0x1e) > 0);
continue;
}
unsigned int c = (unsigned char) (*data++);
ENSURE((c & 0xc0) == 0x80);
if ((a & 0x10) == 0) {
int x = (((a & 0x0f) << 6) | (b & 0x20));
ENSURE(x != 0 && x != 0x360);
continue;
}
unsigned int d = (unsigned char) (*data++);
ENSURE((d & 0xc0) == 0x80);
if ((a & 0x08) == 0) {
int t = (((a & 0x07) << 6) | (b & 0x30));
ENSURE(0 < t && t < 0x110);
continue;
}
return false;
#undef ENSURE
} while (1);
}
......@@ -36,10 +36,10 @@ extern "C" {
__VA_ARGS__))
#define DECODER_FUNC(RETURN_TYPE, NAME, ...) \
JNIEXPORT RETURN_TYPE Java_org_telegram_messenger_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 LIBRARY_FUNC(RETURN_TYPE, NAME, ...) \
JNIEXPORT RETURN_TYPE Java_org_telegram_messenger_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__)
#define ERROR_STRING_BUFFER_LENGTH 256
......@@ -60,8 +60,9 @@ AVCodec *getCodecByName(JNIEnv* env, jstring codecName);
* provided extraData as initialization data for the decoder if it is non-NULL.
* Returns the created context.
*/
AVCodecContext *createContext(JNIEnv *env, AVCodec *codec,
jbyteArray extraData, jboolean outputFloat);
AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
jboolean outputFloat, jint rawSampleRate,
jint rawChannelCount);
/**
* Decodes the packet into the output buffer, returning the number of bytes
......@@ -89,13 +90,14 @@ LIBRARY_FUNC(jboolean, ffmpegHasDecoder, jstring codecName) {
}
DECODER_FUNC(jlong, ffmpegInitialize, jstring codecName, jbyteArray extraData,
jboolean outputFloat) {
jboolean outputFloat, jint rawSampleRate, jint rawChannelCount) {
AVCodec *codec = getCodecByName(env, codecName);
if (!codec) {
LOGE("Codec not found.");
return 0L;
}
return (jlong) createContext(env, codec, extraData, outputFloat);
return (jlong)createContext(env, codec, extraData, outputFloat, rawSampleRate,
rawChannelCount);
}
DECODER_FUNC(jint, ffmpegDecode, jlong context, jobject inputData,
......@@ -159,8 +161,11 @@ DECODER_FUNC(jlong, ffmpegReset, jlong jContext, jbyteArray extraData) {
LOGE("Unexpected error finding codec %d.", codecId);
return 0L;
}
return (jlong) createContext(env, codec, extraData,
context->request_sample_fmt == OUTPUT_FORMAT_PCM_FLOAT);
jboolean outputFloat =
(jboolean)(context->request_sample_fmt == OUTPUT_FORMAT_PCM_FLOAT);
return (jlong)createContext(env, codec, extraData, outputFloat,
/* rawSampleRate= */ -1,
/* rawChannelCount= */ -1);
}
avcodec_flush_buffers(context);
......@@ -173,7 +178,7 @@ DECODER_FUNC(void, ffmpegRelease, jlong context) {
}
}
AVCodec *getCodecByName(JNIEnv *env, jstring codecName) {
AVCodec *getCodecByName(JNIEnv* env, jstring codecName) {
if (!codecName) {
return NULL;
}
......@@ -183,8 +188,9 @@ AVCodec *getCodecByName(JNIEnv *env, jstring codecName) {
return codec;
}
AVCodecContext *createContext(JNIEnv *env, AVCodec *codec,
jbyteArray extraData, jboolean outputFloat) {
AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
jboolean outputFloat, jint rawSampleRate,
jint rawChannelCount) {
AVCodecContext *context = avcodec_alloc_context3(codec);
if (!context) {
LOGE("Failed to allocate context.");
......@@ -204,6 +210,12 @@ AVCodecContext *createContext(JNIEnv *env, AVCodec *codec,
}
env->GetByteArrayRegion(extraData, 0, size, (jbyte *) context->extradata);
}
if (context->codec_id == AV_CODEC_ID_PCM_MULAW ||
context->codec_id == AV_CODEC_ID_PCM_ALAW) {
context->sample_rate = rawSampleRate;
context->channels = rawChannelCount;
context->channel_layout = av_get_default_channel_layout(rawChannelCount);
}
int result = avcodec_open2(context, codec, NULL);
if (result < 0) {
logError("avcodec_open2", result);
......@@ -244,7 +256,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
// Resample output.
AVSampleFormat sampleFormat = context->sample_fmt;
int channelCount = context->channels;
uint64_t channelLayout = context->channel_layout;
int channelLayout = context->channel_layout;
int sampleRate = context->sample_rate;
int sampleCount = frame->nb_samples;
int dataSize = av_samples_get_buffer_size(NULL, channelCount, sampleCount,
......@@ -254,7 +266,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
resampleContext = (AVAudioResampleContext *) context->opaque;
} else {
resampleContext = avresample_alloc_context();
av_opt_set_int(resampleContext, "in_channel_layout", channelLayout, 0);
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);
av_opt_set_int(resampleContext, "out_sample_rate", sampleRate, 0);
......
......@@ -19,150 +19,152 @@
#include "include/flac_parser.h"
#define DECODER_FUNC(RETURN_TYPE, NAME, ...) \
RETURN_TYPE Java_org_telegram_messenger_exoplayer2_ext_flac_FlacDecoderJni_##NAME(JNIEnv *env, jobject thiz, ##__VA_ARGS__)
RETURN_TYPE Java_com_google_android_exoplayer2_ext_flac_FlacDecoderJni_##NAME(JNIEnv *env, jobject thiz, ##__VA_ARGS__)
class JavaDataSource : public DataSource {
public:
void setFlacDecoderJni(JNIEnv *env, jobject flacDecoderJni) {
this->env = env;
this->flacDecoderJni = flacDecoderJni;
if (mid == NULL) {
jclass cls = env->GetObjectClass(flacDecoderJni);
mid = env->GetMethodID(cls, "read", "(Ljava/nio/ByteBuffer;)I");
env->DeleteLocalRef(cls);
public:
void setFlacDecoderJni(JNIEnv *env, jobject flacDecoderJni) {
this->env = env;
this->flacDecoderJni = flacDecoderJni;
if (mid == NULL) {
jclass cls = env->GetObjectClass(this->flacDecoderJni);
mid = env->GetMethodID(cls, "read", "(Ljava/nio/ByteBuffer;)I");
env->DeleteLocalRef(cls);
}
}
}
ssize_t readAt(off64_t offset, void *const data, size_t size) {
jobject byteBuffer = env->NewDirectByteBuffer(data, size);
int result = env->CallIntMethod(flacDecoderJni, mid, byteBuffer);
if (env->ExceptionCheck()) {
// Exception is thrown in Java when returning from the native call.
result = -1;
ssize_t readAt(off64_t offset, void *const data, size_t size) {
jobject byteBuffer = env->NewDirectByteBuffer(data, size);
int result = env->CallIntMethod(flacDecoderJni, mid, byteBuffer);
if (env->ExceptionCheck()) {
// Exception is thrown in Java when returning from the native call.
result = -1;
}
env->DeleteLocalRef(byteBuffer);
return result;
}
env->DeleteLocalRef(byteBuffer);
return result;
}
private:
JNIEnv *env;
jobject flacDecoderJni;
jmethodID mid;
private:
JNIEnv *env;
jobject flacDecoderJni;
jmethodID mid;
};
struct Context {
JavaDataSource *source;
FLACParser *parser;
Context() {
source = new JavaDataSource();
parser = new FLACParser(source);
}
~Context() {
delete parser;
delete source;
}
JavaDataSource *source;
FLACParser *parser;
Context() {
source = new JavaDataSource();
parser = new FLACParser(source);
}
~Context() {
delete parser;
delete source;
}
};
extern "C" {
DECODER_FUNC(jlong, flacInit) {
Context *context = new Context;
if (!context->parser->init()) {
delete context;
return 0;
}
return reinterpret_cast<intptr_t>(context);
Context *context = new Context;
if (!context->parser->init()) {
delete context;
return 0;
}
return reinterpret_cast<intptr_t>(context);
}
DECODER_FUNC(jobject, flacDecodeMetadata, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext);
context->source->setFlacDecoderJni(env, thiz);
if (!context->parser->decodeMetadata()) {
return NULL;
}
const FLAC__StreamMetadata_StreamInfo &streamInfo =
context->parser->getStreamInfo();
jclass cls = env->FindClass("org/telegram/messenger/exoplayer2/util/FlacStreamInfo");
jmethodID constructor = env->GetMethodID(cls, "<init>", "(IIIIIIIJ)V");
return env->NewObject(cls, constructor, streamInfo.min_blocksize,
streamInfo.max_blocksize, streamInfo.min_framesize,
streamInfo.max_framesize, streamInfo.sample_rate,
streamInfo.channels, streamInfo.bits_per_sample,
streamInfo.total_samples);
Context *context = reinterpret_cast<Context *>(jContext);
context->source->setFlacDecoderJni(env, thiz);
if (!context->parser->decodeMetadata()) {
return NULL;
}
const FLAC__StreamMetadata_StreamInfo &streamInfo =
context->parser->getStreamInfo();
jclass cls = env->FindClass(
"com/google/android/exoplayer2/util/"
"FlacStreamInfo");
jmethodID constructor = env->GetMethodID(cls, "<init>", "(IIIIIIIJ)V");
return env->NewObject(cls, constructor, streamInfo.min_blocksize,
streamInfo.max_blocksize, streamInfo.min_framesize,
streamInfo.max_framesize, streamInfo.sample_rate,
streamInfo.channels, streamInfo.bits_per_sample,
streamInfo.total_samples);
}
DECODER_FUNC(jint, flacDecodeToBuffer, jlong jContext, jobject jOutputBuffer) {
Context *context = reinterpret_cast<Context *>(jContext);
context->source->setFlacDecoderJni(env, thiz);
void *outputBuffer = env->GetDirectBufferAddress(jOutputBuffer);
jint outputSize = env->GetDirectBufferCapacity(jOutputBuffer);
return context->parser->readBuffer(outputBuffer, outputSize);
Context *context = reinterpret_cast<Context *>(jContext);
context->source->setFlacDecoderJni(env, thiz);
void *outputBuffer = env->GetDirectBufferAddress(jOutputBuffer);
jint outputSize = env->GetDirectBufferCapacity(jOutputBuffer);
return context->parser->readBuffer(outputBuffer, outputSize);
}
DECODER_FUNC(jint, flacDecodeToArray, jlong jContext, jbyteArray jOutputArray) {
Context *context = reinterpret_cast<Context *>(jContext);
context->source->setFlacDecoderJni(env, thiz);
jbyte *outputBuffer = env->GetByteArrayElements(jOutputArray, NULL);
jint outputSize = env->GetArrayLength(jOutputArray);
int count = context->parser->readBuffer(outputBuffer, outputSize);
env->ReleaseByteArrayElements(jOutputArray, outputBuffer, 0);
return count;
Context *context = reinterpret_cast<Context *>(jContext);
context->source->setFlacDecoderJni(env, thiz);
jbyte *outputBuffer = env->GetByteArrayElements(jOutputArray, NULL);
jint outputSize = env->GetArrayLength(jOutputArray);
int count = context->parser->readBuffer(outputBuffer, outputSize);
env->ReleaseByteArrayElements(jOutputArray, outputBuffer, 0);
return count;
}
DECODER_FUNC(jlong, flacGetDecodePosition, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getDecodePosition();
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getDecodePosition();
}
DECODER_FUNC(jlong, flacGetLastFrameTimestamp, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getLastFrameTimestamp();
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getLastFrameTimestamp();
}
DECODER_FUNC(jlong, flacGetLastFrameFirstSampleIndex, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getLastFrameFirstSampleIndex();
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getLastFrameFirstSampleIndex();
}
DECODER_FUNC(jlong, flacGetNextFrameFirstSampleIndex, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getNextFrameFirstSampleIndex();
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getNextFrameFirstSampleIndex();
}
DECODER_FUNC(jlong, flacGetSeekPosition, jlong jContext, jlong timeUs) {
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getSeekPosition(timeUs);
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->getSeekPosition(timeUs);
}
DECODER_FUNC(jstring, flacGetStateString, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext);
const char *str = context->parser->getDecoderStateString();
return env->NewStringUTF(str);
Context *context = reinterpret_cast<Context *>(jContext);
const char *str = context->parser->getDecoderStateString();
return env->NewStringUTF(str);
}
DECODER_FUNC(jboolean, flacIsDecoderAtEndOfStream, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->isDecoderAtEndOfStream();
Context *context = reinterpret_cast<Context *>(jContext);
return context->parser->isDecoderAtEndOfStream();
}
DECODER_FUNC(void, flacFlush, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext);
context->parser->flush();
Context *context = reinterpret_cast<Context *>(jContext);
context->parser->flush();
}
DECODER_FUNC(void, flacReset, jlong jContext, jlong newPosition) {
Context *context = reinterpret_cast<Context *>(jContext);
context->parser->reset(newPosition);
Context *context = reinterpret_cast<Context *>(jContext);
context->parser->reset(newPosition);
}
DECODER_FUNC(void, flacRelease, jlong jContext) {
Context *context = reinterpret_cast<Context *>(jContext);
delete context;
Context *context = reinterpret_cast<Context *>(jContext);
delete context;
}
}
......@@ -52,31 +52,31 @@ const int endian = 1;
// with the same parameter list, but discard redundant information.
FLAC__StreamDecoderReadStatus FLACParser::read_callback(
const FLAC__StreamDecoder * /* decoder */, FLAC__byte buffer[],
size_t *bytes, void *client_data) {
const FLAC__StreamDecoder * /* decoder */, FLAC__byte buffer[],
size_t *bytes, void *client_data) {
return reinterpret_cast<FLACParser *>(client_data)
->readCallback(buffer, bytes);
->readCallback(buffer, bytes);
}
FLAC__StreamDecoderSeekStatus FLACParser::seek_callback(
const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 absolute_byte_offset, void *client_data) {
const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 absolute_byte_offset, void *client_data) {
return reinterpret_cast<FLACParser *>(client_data)
->seekCallback(absolute_byte_offset);
->seekCallback(absolute_byte_offset);
}
FLAC__StreamDecoderTellStatus FLACParser::tell_callback(
const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 *absolute_byte_offset, void *client_data) {
const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 *absolute_byte_offset, void *client_data) {
return reinterpret_cast<FLACParser *>(client_data)
->tellCallback(absolute_byte_offset);
->tellCallback(absolute_byte_offset);
}
FLAC__StreamDecoderLengthStatus FLACParser::length_callback(
const FLAC__StreamDecoder * /* decoder */, FLAC__uint64 *stream_length,
void *client_data) {
const FLAC__StreamDecoder * /* decoder */, FLAC__uint64 *stream_length,
void *client_data) {
return reinterpret_cast<FLACParser *>(client_data)
->lengthCallback(stream_length);
->lengthCallback(stream_length);
}
FLAC__bool FLACParser::eof_callback(const FLAC__StreamDecoder * /* decoder */,
......@@ -85,10 +85,10 @@ FLAC__bool FLACParser::eof_callback(const FLAC__StreamDecoder * /* decoder */,
}
FLAC__StreamDecoderWriteStatus FLACParser::write_callback(
const FLAC__StreamDecoder * /* decoder */, const FLAC__Frame *frame,
const FLAC__int32 *const buffer[], void *client_data) {
const FLAC__StreamDecoder * /* decoder */, const FLAC__Frame *frame,
const FLAC__int32 *const buffer[], void *client_data) {
return reinterpret_cast<FLACParser *>(client_data)
->writeCallback(frame, buffer);
->writeCallback(frame, buffer);
}
void FLACParser::metadata_callback(const FLAC__StreamDecoder * /* decoder */,
......@@ -125,27 +125,27 @@ FLAC__StreamDecoderReadStatus FLACParser::readCallback(FLAC__byte buffer[],
}
FLAC__StreamDecoderSeekStatus FLACParser::seekCallback(
FLAC__uint64 absolute_byte_offset) {
FLAC__uint64 absolute_byte_offset) {
mCurrentPos = absolute_byte_offset;
mEOF = false;
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
}
FLAC__StreamDecoderTellStatus FLACParser::tellCallback(
FLAC__uint64 *absolute_byte_offset) {
FLAC__uint64 *absolute_byte_offset) {
*absolute_byte_offset = mCurrentPos;
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}
FLAC__StreamDecoderLengthStatus FLACParser::lengthCallback(
FLAC__uint64 *stream_length) {
FLAC__uint64 *stream_length) {
return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
}
FLAC__bool FLACParser::eofCallback() { return mEOF; }
FLAC__StreamDecoderWriteStatus FLACParser::writeCallback(
const FLAC__Frame *frame, const FLAC__int32 *const buffer[]) {
const FLAC__Frame *frame, const FLAC__int32 *const buffer[]) {
if (mWriteRequested) {
mWriteRequested = false;
// FLAC parser doesn't free or realloc buffer until next frame or finish
......@@ -168,13 +168,13 @@ void FLACParser::metadataCallback(const FLAC__StreamMetadata *metadata) {
} else {
ALOGE("FLACParser::metadataCallback unexpected STREAMINFO");
}
break;
break;
case FLAC__METADATA_TYPE_SEEKTABLE:
mSeekTable = &metadata->data.seek_table;
break;
break;
default:
ALOGE("FLACParser::metadataCallback unexpected type %u", metadata->type);
break;
break;
}
}
......@@ -195,7 +195,7 @@ static void copyToByteArrayBigEndian(int8_t *dst, const int *const *src,
// and then skip the first few bytes (most significant bytes)
// depending on the bit depth
const int8_t *byteSrc =
reinterpret_cast<const int8_t *>(&src[c][i]) + 4 - bytesPerSample;
reinterpret_cast<const int8_t *>(&src[c][i]) + 4 - bytesPerSample;
memcpy(dst, byteSrc, bytesPerSample);
dst = dst + bytesPerSample;
}
......@@ -225,18 +225,18 @@ static void copyTrespass(int8_t * /* dst */, const int *const * /* src */,
// FLACParser
FLACParser::FLACParser(DataSource *source)
: mDataSource(source),
mCopy(copyTrespass),
mDecoder(NULL),
mSeekTable(NULL),
firstFrameOffset(0LL),
mCurrentPos(0LL),
mEOF(false),
mStreamInfoValid(false),
mWriteRequested(false),
mWriteCompleted(false),
mWriteBuffer(NULL),
mErrorStatus((FLAC__StreamDecoderErrorStatus)-1) {
: mDataSource(source),
mCopy(copyTrespass),
mDecoder(NULL),
mSeekTable(NULL),
firstFrameOffset(0LL),
mCurrentPos(0LL),
mEOF(false),
mStreamInfoValid(false),
mWriteRequested(false),
mWriteCompleted(false),
mWriteBuffer(NULL),
mErrorStatus((FLAC__StreamDecoderErrorStatus)-1) {
ALOGV("FLACParser::FLACParser");
memset(&mStreamInfo, 0, sizeof(mStreamInfo));
memset(&mWriteHeader, 0, sizeof(mWriteHeader));
......@@ -268,9 +268,9 @@ bool FLACParser::init() {
FLAC__METADATA_TYPE_SEEKTABLE);
FLAC__StreamDecoderInitStatus initStatus;
initStatus = FLAC__stream_decoder_init_stream(
mDecoder, read_callback, seek_callback, tell_callback, length_callback,
eof_callback, write_callback, metadata_callback, error_callback,
reinterpret_cast<void *>(this));
mDecoder, read_callback, seek_callback, tell_callback, length_callback,
eof_callback, write_callback, metadata_callback, error_callback,
reinterpret_cast<void *>(this));
if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
// A failure here probably indicates a programming error and so is
// unlikely to happen. But we check and log here similarly to above.
......@@ -304,7 +304,7 @@ bool FLACParser::decodeMetadata() {
break;
default:
ALOGE("unsupported bits per sample %u", getBitsPerSample());
return false;
return false;
}
// check sample rate
switch (getSampleRate()) {
......@@ -324,7 +324,7 @@ bool FLACParser::decodeMetadata() {
break;
default:
ALOGE("unsupported sample rate %u", getSampleRate());
return false;
return false;
}
// configure the appropriate copy function based on device endianness.
if (isBigEndian()) {
......@@ -367,11 +367,11 @@ size_t FLACParser::readBuffer(void *output, size_t output_size) {
mWriteHeader.channels != getChannels() ||
mWriteHeader.bits_per_sample != getBitsPerSample()) {
ALOGE(
"FLACParser::readBuffer write changed parameters mid-stream: %d/%d/%d "
"-> %d/%d/%d",
getSampleRate(), getChannels(), getBitsPerSample(),
mWriteHeader.sample_rate, mWriteHeader.channels,
mWriteHeader.bits_per_sample);
"FLACParser::readBuffer write changed parameters mid-stream: %d/%d/%d "
"-> %d/%d/%d",
getSampleRate(), getChannels(), getBitsPerSample(),
mWriteHeader.sample_rate, mWriteHeader.channels,
mWriteHeader.bits_per_sample);
return -1;
}
......@@ -379,9 +379,9 @@ size_t FLACParser::readBuffer(void *output, size_t output_size) {
size_t bufferSize = blocksize * getChannels() * bytesPerSample;
if (bufferSize > output_size) {
ALOGE(
"FLACParser::readBuffer not enough space in output buffer "
"%zu < %zu",
output_size, bufferSize);
"FLACParser::readBuffer not enough space in output buffer "
"%zu < %zu",
output_size, bufferSize);
return -1;
}
......@@ -402,7 +402,7 @@ int64_t FLACParser::getSeekPosition(int64_t timeUs) {
int64_t sample = (timeUs * getSampleRate()) / 1000000LL;
if (sample >= getTotalSamples()) {
sample = getTotalSamples();
sample = getTotalSamples();
}
FLAC__StreamMetadata_SeekPoint* points = mSeekTable->points;
......
......@@ -28,10 +28,10 @@
__VA_ARGS__))
#define DECODER_FUNC(RETURN_TYPE, NAME, ...) \
JNIEXPORT RETURN_TYPE Java_org_telegram_messenger_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__)
#define LIBRARY_FUNC(RETURN_TYPE, NAME, ...) \
JNIEXPORT RETURN_TYPE Java_org_telegram_messenger_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__)
// JNI references for SimpleOutputBuffer class.
static jmethodID outputBufferInit;
......@@ -65,7 +65,7 @@ DECODER_FUNC(jlong, opusInit, jint sampleRate, jint channelCount,
// Populate JNI References.
const jclass outputBufferClass = env->FindClass(
"org/telegram/messenger/exoplayer2/decoder/SimpleOutputBuffer");
"com/google/android/exoplayer2/decoder/SimpleOutputBuffer");
outputBufferInit = env->GetMethodID(outputBufferClass, "init",
"(JI)Ljava/nio/ByteBuffer;");
......
......@@ -5,6 +5,7 @@
#include <inttypes.h>
#include <stdlib.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
......@@ -52,6 +53,23 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_aesIgeEncryption(JNIEnv *en
(*env)->ReleaseByteArrayElements(env, iv, ivBuff, 0);
}
JNIEXPORT jint Java_org_telegram_messenger_Utilities_pbkdf2(JNIEnv *env, jclass class, jbyteArray password, jbyteArray salt, jbyteArray dst, jint iterations) {
jbyte *passwordBuff = (*env)->GetByteArrayElements(env, password, NULL);
size_t passwordLength = (size_t) (*env)->GetArrayLength(env, password);
jbyte *saltBuff = (*env)->GetByteArrayElements(env, salt, NULL);
size_t saltLength = (size_t) (*env)->GetArrayLength(env, salt);
jbyte *dstBuff = (*env)->GetByteArrayElements(env, dst, NULL);
size_t dstLength = (size_t) (*env)->GetArrayLength(env, dst);
int result = PKCS5_PBKDF2_HMAC((char *) passwordBuff, passwordLength, (uint8_t *) saltBuff, saltLength, (unsigned int) iterations, EVP_sha512(), dstLength, (uint8_t *) dstBuff);
(*env)->ReleaseByteArrayElements(env, password, passwordBuff, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, salt, saltBuff, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, dst, dstBuff, 0);
return result;
}
JNIEXPORT void Java_org_telegram_messenger_Utilities_aesCtrDecryption(JNIEnv *env, jclass class, jobject buffer, jbyteArray key, jbyteArray iv, jint offset, jint length) {
jbyte *what = (*env)->GetDirectBufferAddress(env, buffer) + offset;
unsigned char *keyBuff = (unsigned char *)(*env)->GetByteArrayElements(env, key, NULL);
......
Subproject commit 8faf6f670037a8049ede4b85a004c40bdd359c6a
Subproject commit 23ae67306d7fa1c4d5a8a9c8653f63ab93100f88
......@@ -4,9 +4,12 @@
@com.google.android.gms.common.annotation.KeepName *;
}
-keep class org.telegram.** { *; }
-keep class com.google.android.exoplayer2.** { *; }
-keep class com.coremedia.** { *; }
-keep class com.googlecode.mp4parser.** { *; }
-dontwarn com.coremedia.**
-dontwarn org.telegram.**
-dontwarn com.google.android.exoplayer2.**
-dontwarn com.google.android.gms.**
-dontwarn com.google.common.cache.**
-dontwarn com.google.common.primitives.**
......
......@@ -20,6 +20,7 @@
<uses-feature android:name="android.hardware.camera2" android:required="false" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
......@@ -231,9 +232,9 @@
</intent-filter>
</receiver>
<receiver android:name=".CallReceiver" >
<receiver android:name=".CallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
......
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import com.google.android.exoplayer2.Player.RepeatMode;
/**
* Dispatches operations to the {@link Player}.
* <p>
* Implementations may choose to suppress (e.g. prevent playback from resuming if audio focus is
* denied) or modify (e.g. change the seek position to prevent a user from seeking past a
* non-skippable advert) operations.
*/
public interface ControlDispatcher {
/**
* Dispatches a {@link Player#setPlayWhenReady(boolean)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param playWhenReady Whether playback should proceed when ready.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSetPlayWhenReady(Player player, boolean playWhenReady);
/**
* Dispatches a {@link Player#seekTo(int, long)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param windowIndex The index of the window.
* @param positionMs The seek position in the specified window, or {@link C#TIME_UNSET} to seek to
* the window's default position.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSeekTo(Player player, int windowIndex, long positionMs);
/**
* Dispatches a {@link Player#setRepeatMode(int)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param repeatMode The repeat mode.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSetRepeatMode(Player player, @RepeatMode int repeatMode);
/**
* Dispatches a {@link Player#setShuffleModeEnabled(boolean)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param shuffleModeEnabled Whether shuffling is enabled.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSetShuffleModeEnabled(Player player, boolean shuffleModeEnabled);
/**
* Dispatches a {@link Player#stop()} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param reset Whether the player should be reset.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchStop(Player player, boolean reset);
}
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import com.google.android.exoplayer2.Player.RepeatMode;
/**
* Default {@link ControlDispatcher} that dispatches all operations to the player without
* modification.
*/
public class DefaultControlDispatcher implements ControlDispatcher {
@Override
public boolean dispatchSetPlayWhenReady(Player player, boolean playWhenReady) {
player.setPlayWhenReady(playWhenReady);
return true;
}
@Override
public boolean dispatchSeekTo(Player player, int windowIndex, long positionMs) {
player.seekTo(windowIndex, positionMs);
return true;
}
@Override
public boolean dispatchSetRepeatMode(Player player, @RepeatMode int repeatMode) {
player.setRepeatMode(repeatMode);
return true;
}
@Override
public boolean dispatchSetShuffleModeEnabled(Player player, boolean shuffleModeEnabled) {
player.setShuffleModeEnabled(shuffleModeEnabled);
return true;
}
@Override
public boolean dispatchStop(Player player, boolean reset) {
player.stop(reset);
return true;
}
}
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.MediaClock;
import com.google.android.exoplayer2.util.StandaloneMediaClock;
/**
* Default {@link MediaClock} which uses a renderer media clock and falls back to a
* {@link StandaloneMediaClock} if necessary.
*/
/* package */ final class DefaultMediaClock implements MediaClock {
/**
* Listener interface to be notified of changes to the active playback parameters.
*/
public interface PlaybackParameterListener {
/**
* Called when the active playback parameters changed.
*
* @param newPlaybackParameters The newly active {@link PlaybackParameters}.
*/
void onPlaybackParametersChanged(PlaybackParameters newPlaybackParameters);
}
private final StandaloneMediaClock standaloneMediaClock;
private final PlaybackParameterListener listener;
private @Nullable Renderer rendererClockSource;
private @Nullable MediaClock rendererClock;
/**
* Creates a new instance with listener for playback parameter changes and a {@link Clock} to use
* for the standalone clock implementation.
*
* @param listener A {@link PlaybackParameterListener} to listen for playback parameter
* changes.
* @param clock A {@link Clock}.
*/
public DefaultMediaClock(PlaybackParameterListener listener, Clock clock) {
this.listener = listener;
this.standaloneMediaClock = new StandaloneMediaClock(clock);
}
/**
* Starts the standalone fallback clock.
*/
public void start() {
standaloneMediaClock.start();
}
/**
* Stops the standalone fallback clock.
*/
public void stop() {
standaloneMediaClock.stop();
}
/**
* Resets the position of the standalone fallback clock.
*
* @param positionUs The position to set in microseconds.
*/
public void resetPosition(long positionUs) {
standaloneMediaClock.resetPosition(positionUs);
}
/**
* Notifies the media clock that a renderer has been enabled. Starts using the media clock of the
* provided renderer if available.
*
* @param renderer The renderer which has been enabled.
* @throws ExoPlaybackException If the renderer provides a media clock and another renderer media
* clock is already provided.
*/
public void onRendererEnabled(Renderer renderer) throws ExoPlaybackException {
MediaClock rendererMediaClock = renderer.getMediaClock();
if (rendererMediaClock != null && rendererMediaClock != rendererClock) {
if (rendererClock != null) {
throw ExoPlaybackException.createForUnexpected(
new IllegalStateException("Multiple renderer media clocks enabled."));
}
this.rendererClock = rendererMediaClock;
this.rendererClockSource = renderer;
rendererClock.setPlaybackParameters(standaloneMediaClock.getPlaybackParameters());
ensureSynced();
}
}
/**
* Notifies the media clock that a renderer has been disabled. Stops using the media clock of this
* renderer if used.
*
* @param renderer The renderer which has been disabled.
*/
public void onRendererDisabled(Renderer renderer) {
if (renderer == rendererClockSource) {
this.rendererClock = null;
this.rendererClockSource = null;
}
}
/**
* Syncs internal clock if needed and returns current clock position in microseconds.
*/
public long syncAndGetPositionUs() {
if (isUsingRendererClock()) {
ensureSynced();
return rendererClock.getPositionUs();
} else {
return standaloneMediaClock.getPositionUs();
}
}
// MediaClock implementation.
@Override
public long getPositionUs() {
if (isUsingRendererClock()) {
return rendererClock.getPositionUs();
} else {
return standaloneMediaClock.getPositionUs();
}
}
@Override
public PlaybackParameters setPlaybackParameters(PlaybackParameters playbackParameters) {
if (rendererClock != null) {
playbackParameters = rendererClock.setPlaybackParameters(playbackParameters);
}
standaloneMediaClock.setPlaybackParameters(playbackParameters);
listener.onPlaybackParametersChanged(playbackParameters);
return playbackParameters;
}
@Override
public PlaybackParameters getPlaybackParameters() {
return rendererClock != null ? rendererClock.getPlaybackParameters()
: standaloneMediaClock.getPlaybackParameters();
}
private void ensureSynced() {
long rendererClockPositionUs = rendererClock.getPositionUs();
standaloneMediaClock.resetPosition(rendererClockPositionUs);
PlaybackParameters playbackParameters = rendererClock.getPlaybackParameters();
if (!playbackParameters.equals(standaloneMediaClock.getPlaybackParameters())) {
standaloneMediaClock.setPlaybackParameters(playbackParameters);
listener.onPlaybackParametersChanged(playbackParameters);
}
}
private boolean isUsingRendererClock() {
// Use the renderer clock if the providing renderer has not ended or needs the next sample
// stream to reenter the ready state. The latter case uses the standalone clock to avoid getting
// stuck if tracks in the current period have uneven durations.
// See: https://github.com/google/ExoPlayer/issues/1874.
return rendererClockSource != null && !rendererClockSource.isEnded()
&& (rendererClockSource.isReady() || !rendererClockSource.hasReadStreamToEnd());
}
}
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Thrown when a non-recoverable playback failure occurs.
*/
public final class ExoPlaybackException extends Exception {
/**
* The type of source that produced the error.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_SOURCE, TYPE_RENDERER, TYPE_UNEXPECTED})
public @interface Type {}
/**
* The error occurred loading data from a {@link MediaSource}.
* <p>
* Call {@link #getSourceException()} to retrieve the underlying cause.
*/
public static final int TYPE_SOURCE = 0;
/**
* The error occurred in a {@link Renderer}.
* <p>
* Call {@link #getRendererException()} to retrieve the underlying cause.
*/
public static final int TYPE_RENDERER = 1;
/**
* The error was an unexpected {@link RuntimeException}.
* <p>
* Call {@link #getUnexpectedException()} to retrieve the underlying cause.
*/
public static final int TYPE_UNEXPECTED = 2;
/**
* The type of the playback failure. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER} and
* {@link #TYPE_UNEXPECTED}.
*/
@Type public final int type;
/**
* If {@link #type} is {@link #TYPE_RENDERER}, this is the index of the renderer.
*/
public final int rendererIndex;
/**
* Creates an instance of type {@link #TYPE_RENDERER}.
*
* @param cause The cause of the failure.
* @param rendererIndex The index of the renderer in which the failure occurred.
* @return The created instance.
*/
public static ExoPlaybackException createForRenderer(Exception cause, int rendererIndex) {
return new ExoPlaybackException(TYPE_RENDERER, null, cause, rendererIndex);
}
/**
* Creates an instance of type {@link #TYPE_SOURCE}.
*
* @param cause The cause of the failure.
* @return The created instance.
*/
public static ExoPlaybackException createForSource(IOException cause) {
return new ExoPlaybackException(TYPE_SOURCE, null, cause, C.INDEX_UNSET);
}
/**
* Creates an instance of type {@link #TYPE_UNEXPECTED}.
*
* @param cause The cause of the failure.
* @return The created instance.
*/
/* package */ static ExoPlaybackException createForUnexpected(RuntimeException cause) {
return new ExoPlaybackException(TYPE_UNEXPECTED, null, cause, C.INDEX_UNSET);
}
private ExoPlaybackException(@Type int type, String message, Throwable cause,
int rendererIndex) {
super(message, cause);
this.type = type;
this.rendererIndex = rendererIndex;
}
/**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_SOURCE}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_SOURCE}.
*/
public IOException getSourceException() {
Assertions.checkState(type == TYPE_SOURCE);
return (IOException) getCause();
}
/**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_RENDERER}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_RENDERER}.
*/
public Exception getRendererException() {
Assertions.checkState(type == TYPE_RENDERER);
return (Exception) getCause();
}
/**
* Retrieves the underlying error when {@link #type} is {@link #TYPE_UNEXPECTED}.
*
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_UNEXPECTED}.
*/
public RuntimeException getUnexpectedException() {
Assertions.checkState(type == TYPE_UNEXPECTED);
return (RuntimeException) getCause();
}
}
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import java.util.HashSet;
/**
* Information about the ExoPlayer library.
*/
public final class ExoPlayerLibraryInfo {
/**
* A tag to use when logging library information.
*/
public static final String TAG = "ExoPlayer";
/** The version of the library expressed as a string, for example "1.2.3". */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
public static final String VERSION = "2.8.3";
/** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final String VERSION_SLASHY = "ExoPlayerLib/2.8.3";
/**
* The version of the library expressed as an integer, for example 1002003.
*
* <p>Three digits are used for each component of {@link #VERSION}. For example "1.2.3" has the
* corresponding integer version 1002003 (001-002-003), and "123.45.6" has the corresponding
* integer version 123045006 (123-045-006).
*/
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final int VERSION_INT = 2008003;
/**
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions}
* checks enabled.
*/
public static final boolean ASSERTIONS_ENABLED = true;
/** Whether an exception should be thrown in case of an OpenGl error. */
public static final boolean GL_ASSERTIONS_ENABLED = false;
/**
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.TraceUtil}
* trace enabled.
*/
public static final boolean TRACE_ENABLED = true;
private static final HashSet<String> registeredModules = new HashSet<>();
private static String registeredModulesString = "goog.exo.core";
private ExoPlayerLibraryInfo() {} // Prevents instantiation.
/**
* Returns a string consisting of registered module names separated by ", ".
*/
public static synchronized String registeredModules() {
return registeredModulesString;
}
/**
* Registers a module to be returned in the {@link #registeredModules()} string.
*
* @param name The name of the module being registered.
*/
public static synchronized void registerModule(String name) {
if (registeredModules.add(name)) {
registeredModulesString = registeredModulesString + ", " + name;
}
}
}
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import android.support.annotation.Nullable;
/**
* Holds a {@link Format}.
*/
public final class FormatHolder {
/** The held {@link Format}. */
public @Nullable Format format;
}
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
/**
* Thrown when an attempt is made to seek to a position that does not exist in the player's
* {@link Timeline}.
*/
public final class IllegalSeekPositionException extends IllegalStateException {
/**
* The {@link Timeline} in which the seek was attempted.
*/
public final Timeline timeline;
/**
* The index of the window being seeked to.
*/
public final int windowIndex;
/**
* The seek position in the specified window.
*/
public final long positionMs;
/**
* @param timeline The {@link Timeline} in which the seek was attempted.
* @param windowIndex The index of the window being seeked to.
* @param positionMs The seek position in the specified window.
*/
public IllegalSeekPositionException(Timeline timeline, int windowIndex, long positionMs) {
this.timeline = timeline;
this.windowIndex = windowIndex;
this.positionMs = positionMs;
}
}
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
/** Stores the information required to load and play a {@link MediaPeriod}. */
/* package */ final class MediaPeriodInfo {
/** The media period's identifier. */
public final MediaPeriodId id;
/** The start position of the media to play within the media period, in microseconds. */
public final long startPositionUs;
/**
* If this is an ad, the position to play in the next content media period. {@link C#TIME_UNSET}
* otherwise.
*/
public final long contentPositionUs;
/**
* The duration of the media period, like {@link MediaPeriodId#endPositionUs} but with {@link
* C#TIME_END_OF_SOURCE} resolved to the timeline period duration. May be {@link C#TIME_UNSET} if
* the end position is not known.
*/
public final long durationUs;
/**
* Whether this is the last media period in its timeline period (e.g., a postroll ad, or a media
* period corresponding to a timeline period without ads).
*/
public final boolean isLastInTimelinePeriod;
/**
* Whether this is the last media period in the entire timeline. If true, {@link
* #isLastInTimelinePeriod} will also be true.
*/
public final boolean isFinal;
MediaPeriodInfo(
MediaPeriodId id,
long startPositionUs,
long contentPositionUs,
long durationUs,
boolean isLastInTimelinePeriod,
boolean isFinal) {
this.id = id;
this.startPositionUs = startPositionUs;
this.contentPositionUs = contentPositionUs;
this.durationUs = durationUs;
this.isLastInTimelinePeriod = isLastInTimelinePeriod;
this.isFinal = isFinal;
}
/**
* Returns a copy of this instance with the period identifier's period index set to the specified
* value.
*/
public MediaPeriodInfo copyWithPeriodIndex(int periodIndex) {
return new MediaPeriodInfo(
id.copyWithPeriodIndex(periodIndex),
startPositionUs,
contentPositionUs,
durationUs,
isLastInTimelinePeriod,
isFinal);
}
/** Returns a copy of this instance with the start position set to the specified value. */
public MediaPeriodInfo copyWithStartPositionUs(long startPositionUs) {
return new MediaPeriodInfo(
id,
startPositionUs,
contentPositionUs,
durationUs,
isLastInTimelinePeriod,
isFinal);
}
}
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.drm;
/**
* Thrown when the drm keys loaded into an open session expire.
*/
public final class KeysExpiredException extends Exception {
}
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