mirror of
https://github.com/DrKLO/Telegram.git
synced 2024-12-22 14:35:03 +01:00
Update to 7.0.1 (2065)
This commit is contained in:
parent
4c5f32babf
commit
e33a2fbedc
48 changed files with 557 additions and 251 deletions
|
@ -2,7 +2,7 @@ FROM gradle:6.1.1-jdk8
|
||||||
|
|
||||||
ENV ANDROID_SDK_URL https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
|
ENV ANDROID_SDK_URL https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
|
||||||
ENV ANDROID_API_LEVEL android-30
|
ENV ANDROID_API_LEVEL android-30
|
||||||
ENV ANDROID_BUILD_TOOLS_VERSION 30.0.1
|
ENV ANDROID_BUILD_TOOLS_VERSION 30.0.2
|
||||||
ENV ANDROID_HOME /usr/local/android-sdk-linux
|
ENV ANDROID_HOME /usr/local/android-sdk-linux
|
||||||
ENV ANDROID_NDK_VERSION 21.1.6352462
|
ENV ANDROID_NDK_VERSION 21.1.6352462
|
||||||
ENV ANDROID_VERSION 30
|
ENV ANDROID_VERSION 30
|
||||||
|
@ -24,4 +24,4 @@ RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSIO
|
||||||
ENV PATH ${ANDROID_NDK_HOME}:$PATH
|
ENV PATH ${ANDROID_NDK_HOME}:$PATH
|
||||||
ENV PATH ${ANDROID_NDK_HOME}/prebuilt/linux-x86_64/bin/:$PATH
|
ENV PATH ${ANDROID_NDK_HOME}/prebuilt/linux-x86_64/bin/:$PATH
|
||||||
|
|
||||||
CMD mkdir -p /home/source/TMessagesProj/build/outputs/apk && cp -R /home/source/. /home/gradle && cd /home/gradle && gradle assembleRelease && cp -R /home/gradle/TMessagesProj/build/outputs/apk/. /home/source/TMessagesProj/build/outputs/apk
|
CMD mkdir -p /home/source/TMessagesProj/build/outputs/apk && mkdir -p /home/source/TMessagesProj/build/intermediates/ndkBuild && cp -R /home/source/. /home/gradle && cd /home/gradle && gradle assembleRelease && cp -R /home/gradle/TMessagesProj/build/outputs/apk/. /home/source/TMessagesProj/build/outputs/apk && cp -R /home/gradle/TMessagesProj/build/intermediates/ndkBuild/. /home/source/TMessagesProj/build/intermediates/ndkBuild
|
||||||
|
|
|
@ -43,7 +43,7 @@ dependencies {
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 30
|
compileSdkVersion 30
|
||||||
buildToolsVersion '30.0.1'
|
buildToolsVersion '30.0.2'
|
||||||
ndkVersion "21.1.6352462"
|
ndkVersion "21.1.6352462"
|
||||||
|
|
||||||
defaultConfig.applicationId = "org.telegram.messenger"
|
defaultConfig.applicationId = "org.telegram.messenger"
|
||||||
|
@ -280,7 +280,7 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig.versionCode = 2064
|
defaultConfig.versionCode = 2065
|
||||||
|
|
||||||
applicationVariants.all { variant ->
|
applicationVariants.all { variant ->
|
||||||
variant.outputs.all { output ->
|
variant.outputs.all { output ->
|
||||||
|
@ -315,7 +315,7 @@ android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionName "7.0.0"
|
versionName "7.0.1"
|
||||||
|
|
||||||
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']
|
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']
|
||||||
|
|
||||||
|
|
|
@ -753,6 +753,7 @@ LOCAL_SRC_FILES := \
|
||||||
./tgcalls/ThreadLocalObject.cpp \
|
./tgcalls/ThreadLocalObject.cpp \
|
||||||
./tgcalls/VideoCaptureInterface.cpp \
|
./tgcalls/VideoCaptureInterface.cpp \
|
||||||
./tgcalls/VideoCaptureInterfaceImpl.cpp \
|
./tgcalls/VideoCaptureInterfaceImpl.cpp \
|
||||||
|
./tgcalls/JsonConfig.cpp \
|
||||||
./tgcalls/reference/InstanceImplReference.cpp \
|
./tgcalls/reference/InstanceImplReference.cpp \
|
||||||
./tgcalls/legacy/InstanceImplLegacy.cpp \
|
./tgcalls/legacy/InstanceImplLegacy.cpp \
|
||||||
./tgcalls/platform/android/AndroidInterface.cpp \
|
./tgcalls/platform/android/AndroidInterface.cpp \
|
||||||
|
|
|
@ -69,14 +69,16 @@ struct InstanceHolder {
|
||||||
std::unique_ptr<Instance> nativeInstance;
|
std::unique_ptr<Instance> nativeInstance;
|
||||||
jobject javaInstance;
|
jobject javaInstance;
|
||||||
std::shared_ptr<tgcalls::VideoCaptureInterface> _videoCapture;
|
std::shared_ptr<tgcalls::VideoCaptureInterface> _videoCapture;
|
||||||
|
std::shared_ptr<PlatformContext> _platformContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
jclass TrafficStatsClass;
|
jclass TrafficStatsClass;
|
||||||
jclass FinalStateClass;
|
jclass FinalStateClass;
|
||||||
|
jclass NativeInstanceClass;
|
||||||
jmethodID FinalStateInitMethod;
|
jmethodID FinalStateInitMethod;
|
||||||
|
|
||||||
jlong getInstanceHolderId(JNIEnv *env, jobject obj) {
|
jlong getInstanceHolderId(JNIEnv *env, jobject obj) {
|
||||||
return env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "nativePtr", "J"));
|
return env->GetLongField(obj, env->GetFieldID(NativeInstanceClass, "nativePtr", "J"));
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceHolder *getInstanceHolder(JNIEnv *env, jobject obj) {
|
InstanceHolder *getInstanceHolder(JNIEnv *env, jobject obj) {
|
||||||
|
@ -231,6 +233,7 @@ void initWebRTC(JNIEnv *env) {
|
||||||
rtc::InitializeSSL();
|
rtc::InitializeSSL();
|
||||||
webrtcLoaded = true;
|
webrtcLoaded = true;
|
||||||
|
|
||||||
|
NativeInstanceClass = static_cast<jclass>(env->NewGlobalRef(env->FindClass("org/telegram/messenger/voip/NativeInstance")));
|
||||||
TrafficStatsClass = static_cast<jclass>(env->NewGlobalRef(env->FindClass("org/telegram/messenger/voip/Instance$TrafficStats")));
|
TrafficStatsClass = static_cast<jclass>(env->NewGlobalRef(env->FindClass("org/telegram/messenger/voip/Instance$TrafficStats")));
|
||||||
FinalStateClass = static_cast<jclass>(env->NewGlobalRef(env->FindClass("org/telegram/messenger/voip/Instance$FinalState")));
|
FinalStateClass = static_cast<jclass>(env->NewGlobalRef(env->FindClass("org/telegram/messenger/voip/Instance$FinalState")));
|
||||||
FinalStateInitMethod = env->GetMethodID(FinalStateClass, "<init>", "([BLjava/lang/String;Lorg/telegram/messenger/voip/Instance$TrafficStats;Z)V");
|
FinalStateInitMethod = env->GetMethodID(FinalStateClass, "<init>", "([BLjava/lang/String;Lorg/telegram/messenger/voip/Instance$TrafficStats;Z)V");
|
||||||
|
@ -252,6 +255,8 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNati
|
||||||
jobject globalRef = env->NewGlobalRef(instanceObj);
|
jobject globalRef = env->NewGlobalRef(instanceObj);
|
||||||
std::shared_ptr<VideoCaptureInterface> videoCapture = videoCapturer ? std::shared_ptr<VideoCaptureInterface>(reinterpret_cast<VideoCaptureInterface *>(videoCapturer)) : nullptr;
|
std::shared_ptr<VideoCaptureInterface> videoCapture = videoCapturer ? std::shared_ptr<VideoCaptureInterface>(reinterpret_cast<VideoCaptureInterface *>(videoCapturer)) : nullptr;
|
||||||
|
|
||||||
|
std::shared_ptr<PlatformContext> platformContext = videoCapture ? videoCapture->getPlatformContext() : std::make_shared<AndroidContext>(env);
|
||||||
|
|
||||||
Descriptor descriptor = {
|
Descriptor descriptor = {
|
||||||
.config = Config{
|
.config = Config{
|
||||||
.initializationTimeout = configObject.getDoubleField("initializationTimeout"),
|
.initializationTimeout = configObject.getDoubleField("initializationTimeout"),
|
||||||
|
@ -273,23 +278,25 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNati
|
||||||
.stateUpdated = [globalRef](State state) {
|
.stateUpdated = [globalRef](State state) {
|
||||||
jint javaState = asJavaState(state);
|
jint javaState = asJavaState(state);
|
||||||
tgvoip::jni::DoWithJNI([globalRef, javaState](JNIEnv *env) {
|
tgvoip::jni::DoWithJNI([globalRef, javaState](JNIEnv *env) {
|
||||||
env->CallVoidMethod(globalRef, env->GetMethodID(env->GetObjectClass(globalRef), "onStateUpdated", "(I)V"), javaState);
|
env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onStateUpdated", "(I)V"), javaState);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
.platformContext = platformContext,
|
||||||
.signalBarsUpdated = [globalRef](int count) {
|
.signalBarsUpdated = [globalRef](int count) {
|
||||||
tgvoip::jni::DoWithJNI([globalRef, count](JNIEnv *env) {
|
tgvoip::jni::DoWithJNI([globalRef, count](JNIEnv *env) {
|
||||||
env->CallVoidMethod(globalRef, env->GetMethodID(env->GetObjectClass(globalRef), "onSignalBarsUpdated", "(I)V"), count);
|
env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onSignalBarsUpdated", "(I)V"), count);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
.remoteMediaStateUpdated = [globalRef](AudioState audioState, VideoState videoState) {
|
.remoteMediaStateUpdated = [globalRef](AudioState audioState, VideoState videoState) {
|
||||||
tgvoip::jni::DoWithJNI([globalRef, audioState, videoState](JNIEnv *env) {
|
tgvoip::jni::DoWithJNI([globalRef, audioState, videoState](JNIEnv *env) {
|
||||||
env->CallVoidMethod(globalRef, env->GetMethodID(env->GetObjectClass(globalRef), "onRemoteMediaStateUpdated", "(II)V"), audioState, videoState);
|
env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onRemoteMediaStateUpdated", "(II)V"), (jint) audioState, (jint )videoState);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
.signalingDataEmitted = [globalRef](const std::vector<uint8_t> &data) {
|
.signalingDataEmitted = [globalRef](const std::vector<uint8_t> &data) {
|
||||||
tgvoip::jni::DoWithJNI([globalRef, data](JNIEnv *env) {
|
tgvoip::jni::DoWithJNI([globalRef, data](JNIEnv *env) {
|
||||||
jbyteArray arr = copyVectorToJavaByteArray(env, data);
|
jbyteArray arr = copyVectorToJavaByteArray(env, data);
|
||||||
env->CallVoidMethod(globalRef, env->GetMethodID(env->GetObjectClass(globalRef), "onSignalingData", "([B)V"), arr);
|
env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onSignalingData", "([B)V"), arr);
|
||||||
|
env->DeleteLocalRef(arr);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -336,6 +343,7 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNati
|
||||||
holder->nativeInstance = tgcalls::Meta::Create(v, std::move(descriptor));
|
holder->nativeInstance = tgcalls::Meta::Create(v, std::move(descriptor));
|
||||||
holder->javaInstance = globalRef;
|
holder->javaInstance = globalRef;
|
||||||
holder->_videoCapture = videoCapture;
|
holder->_videoCapture = videoCapture;
|
||||||
|
holder->_platformContext = platformContext;
|
||||||
holder->nativeInstance->setIncomingVideoOutput(webrtc::JavaToNativeVideoSink(env, remoteSink));
|
holder->nativeInstance->setIncomingVideoOutput(webrtc::JavaToNativeVideoSink(env, remoteSink));
|
||||||
holder->nativeInstance->setNetworkType(parseNetworkType(networkType));
|
holder->nativeInstance->setNetworkType(parseNetworkType(networkType));
|
||||||
return reinterpret_cast<jlong>(holder);
|
return reinterpret_cast<jlong>(holder);
|
||||||
|
@ -396,7 +404,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_stopNativ
|
||||||
JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded();
|
JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded();
|
||||||
const std::string &path = tgvoip::jni::JavaStringToStdString(env, JavaObject(env, instance->javaInstance).getStringField("persistentStateFilePath"));
|
const std::string &path = tgvoip::jni::JavaStringToStdString(env, JavaObject(env, instance->javaInstance).getStringField("persistentStateFilePath"));
|
||||||
savePersistentState(path.c_str(), finalState.persistentState);
|
savePersistentState(path.c_str(), finalState.persistentState);
|
||||||
env->CallVoidMethod(instance->javaInstance, env->GetMethodID(env->GetObjectClass(instance->javaInstance), "onStop", "(Lorg/telegram/messenger/voip/Instance$FinalState;)V"), asJavaFinalState(env, finalState));
|
env->CallVoidMethod(instance->javaInstance, env->GetMethodID(NativeInstanceClass, "onStop", "(Lorg/telegram/messenger/voip/Instance$FinalState;)V"), asJavaFinalState(env, finalState));
|
||||||
env->DeleteGlobalRef(instance->javaInstance);
|
env->DeleteGlobalRef(instance->javaInstance);
|
||||||
delete instance;
|
delete instance;
|
||||||
});
|
});
|
||||||
|
@ -446,7 +454,7 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setupOutg
|
||||||
if (instance->_videoCapture) {
|
if (instance->_videoCapture) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instance->_videoCapture = tgcalls::VideoCaptureInterface::Create(std::make_shared<AndroidContext>(env));
|
instance->_videoCapture = tgcalls::VideoCaptureInterface::Create(instance->_platformContext);
|
||||||
instance->_videoCapture->setOutput(webrtc::JavaToNativeVideoSink(env, localSink));
|
instance->_videoCapture->setOutput(webrtc::JavaToNativeVideoSink(env, localSink));
|
||||||
instance->_videoCapture->setState(VideoState::Active);
|
instance->_videoCapture->setState(VideoState::Active);
|
||||||
instance->nativeInstance->setVideoCapture(instance->_videoCapture);
|
instance->nativeInstance->setVideoCapture(instance->_videoCapture);
|
||||||
|
|
|
@ -773,9 +773,11 @@ std::shared_ptr<LOTAsset> LottieParserImpl::parseAsset() {
|
||||||
return sharedAsset;
|
return sharedAsset;
|
||||||
}
|
}
|
||||||
std::shared_ptr<LOTData> layer = parseLayer();
|
std::shared_ptr<LOTData> layer = parseLayer();
|
||||||
|
if (layer) {
|
||||||
staticFlag = staticFlag && layer->isStatic();
|
staticFlag = staticFlag && layer->isStatic();
|
||||||
asset->mLayers.push_back(layer);
|
asset->mLayers.push_back(layer);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!IsValid()) {
|
if (!IsValid()) {
|
||||||
parsingError = true;
|
parsingError = true;
|
||||||
return sharedAsset;
|
return sharedAsset;
|
||||||
|
|
|
@ -23,7 +23,7 @@ bool CompareFormats(const VideoFormat &a, const VideoFormat &b) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FormatPriority(const VideoFormat &format, const std::vector<std::string> &preferredCodecs) {
|
int FormatPriority(const VideoFormat &format, const std::vector<std::string> &preferredCodecs, std::shared_ptr<PlatformContext> platformContext) {
|
||||||
static const auto kCodecs = {
|
static const auto kCodecs = {
|
||||||
std::string(cricket::kAv1CodecName),
|
std::string(cricket::kAv1CodecName),
|
||||||
std::string(cricket::kVp9CodecName),
|
std::string(cricket::kVp9CodecName),
|
||||||
|
@ -31,13 +31,13 @@ int FormatPriority(const VideoFormat &format, const std::vector<std::string> &pr
|
||||||
std::string(cricket::kH264CodecName),
|
std::string(cricket::kH264CodecName),
|
||||||
std::string(cricket::kVp8CodecName),
|
std::string(cricket::kVp8CodecName),
|
||||||
};
|
};
|
||||||
static const auto kSupported = [] {
|
static const auto kSupported = [platformContext] {
|
||||||
const auto platform = PlatformInterface::SharedInstance();
|
const auto platform = PlatformInterface::SharedInstance();
|
||||||
|
|
||||||
auto result = std::vector<std::string>();
|
auto result = std::vector<std::string>();
|
||||||
result.reserve(kCodecs.size());
|
result.reserve(kCodecs.size());
|
||||||
for (const auto &codec : kCodecs) {
|
for (const auto &codec : kCodecs) {
|
||||||
if (platform->supportsEncoding(codec)) {
|
if (platform->supportsEncoding(codec, platformContext)) {
|
||||||
result.push_back(codec);
|
result.push_back(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,19 +62,19 @@ int FormatPriority(const VideoFormat &format, const std::vector<std::string> &pr
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComparePriorities(const VideoFormat &a, const VideoFormat &b, const std::vector<std::string> &preferredCodecs) {
|
bool ComparePriorities(const VideoFormat &a, const VideoFormat &b, const std::vector<std::string> &preferredCodecs, std::shared_ptr<PlatformContext> platformContext) {
|
||||||
return FormatPriority(a, preferredCodecs) < FormatPriority(b, preferredCodecs);
|
return FormatPriority(a, preferredCodecs, platformContext) < FormatPriority(b, preferredCodecs, platformContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VideoFormat> FilterAndSortEncoders(std::vector<VideoFormat> list, const std::vector<std::string> &preferredCodecs) {
|
std::vector<VideoFormat> FilterAndSortEncoders(std::vector<VideoFormat> list, const std::vector<std::string> &preferredCodecs, std::shared_ptr<PlatformContext> platformContext) {
|
||||||
const auto listBegin = begin(list);
|
const auto listBegin = begin(list);
|
||||||
const auto listEnd = end(list);
|
const auto listEnd = end(list);
|
||||||
std::sort(listBegin, listEnd, [&preferredCodecs](const VideoFormat &lhs, const VideoFormat &rhs) {
|
std::sort(listBegin, listEnd, [&preferredCodecs, platformContext](const VideoFormat &lhs, const VideoFormat &rhs) {
|
||||||
return ComparePriorities(lhs, rhs, preferredCodecs);
|
return ComparePriorities(lhs, rhs, preferredCodecs, platformContext);
|
||||||
});
|
});
|
||||||
auto eraseFrom = listBegin;
|
auto eraseFrom = listBegin;
|
||||||
auto eraseTill = eraseFrom;
|
auto eraseTill = eraseFrom;
|
||||||
while (eraseTill != listEnd && FormatPriority(*eraseTill, preferredCodecs) == -1) {
|
while (eraseTill != listEnd && FormatPriority(*eraseTill, preferredCodecs, platformContext) == -1) {
|
||||||
++eraseTill;
|
++eraseTill;
|
||||||
}
|
}
|
||||||
if (eraseTill != eraseFrom) {
|
if (eraseTill != eraseFrom) {
|
||||||
|
@ -142,8 +142,9 @@ void AddDefaultFeedbackParams(cricket::VideoCodec *codec) {
|
||||||
VideoFormatsMessage ComposeSupportedFormats(
|
VideoFormatsMessage ComposeSupportedFormats(
|
||||||
std::vector<VideoFormat> encoders,
|
std::vector<VideoFormat> encoders,
|
||||||
std::vector<VideoFormat> decoders,
|
std::vector<VideoFormat> decoders,
|
||||||
const std::vector<std::string> &preferredCodecs) {
|
const std::vector<std::string> &preferredCodecs,
|
||||||
encoders = FilterAndSortEncoders(std::move(encoders), preferredCodecs);
|
std::shared_ptr<PlatformContext> platformContext) {
|
||||||
|
encoders = FilterAndSortEncoders(std::move(encoders), preferredCodecs, platformContext);
|
||||||
|
|
||||||
auto result = VideoFormatsMessage();
|
auto result = VideoFormatsMessage();
|
||||||
result.encodersCount = (int)encoders.size();
|
result.encodersCount = (int)encoders.size();
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
namespace tgcalls {
|
namespace tgcalls {
|
||||||
|
|
||||||
|
class PlatformContext;
|
||||||
|
|
||||||
struct CommonFormats {
|
struct CommonFormats {
|
||||||
std::vector<webrtc::SdpVideoFormat> list;
|
std::vector<webrtc::SdpVideoFormat> list;
|
||||||
int myEncoderIndex = -1;
|
int myEncoderIndex = -1;
|
||||||
|
@ -19,7 +21,8 @@ struct CommonCodecs {
|
||||||
VideoFormatsMessage ComposeSupportedFormats(
|
VideoFormatsMessage ComposeSupportedFormats(
|
||||||
std::vector<webrtc::SdpVideoFormat> encoders,
|
std::vector<webrtc::SdpVideoFormat> encoders,
|
||||||
std::vector<webrtc::SdpVideoFormat> decoders,
|
std::vector<webrtc::SdpVideoFormat> decoders,
|
||||||
const std::vector<std::string> &preferredCodecs);
|
const std::vector<std::string> &preferredCodecs,
|
||||||
|
std::shared_ptr<PlatformContext> platformContext);
|
||||||
|
|
||||||
CommonFormats ComputeCommonFormats(
|
CommonFormats ComputeCommonFormats(
|
||||||
const VideoFormatsMessage &my,
|
const VideoFormatsMessage &my,
|
||||||
|
|
|
@ -19,6 +19,7 @@ class VideoFrame;
|
||||||
namespace tgcalls {
|
namespace tgcalls {
|
||||||
|
|
||||||
class VideoCaptureInterface;
|
class VideoCaptureInterface;
|
||||||
|
class PlatformContext;
|
||||||
|
|
||||||
struct Proxy {
|
struct Proxy {
|
||||||
std::string host;
|
std::string host;
|
||||||
|
@ -203,6 +204,7 @@ struct Descriptor {
|
||||||
std::function<void(AudioState, VideoState)> remoteMediaStateUpdated;
|
std::function<void(AudioState, VideoState)> remoteMediaStateUpdated;
|
||||||
std::function<void(float)> remotePrefferedAspectRatioUpdated;
|
std::function<void(float)> remotePrefferedAspectRatioUpdated;
|
||||||
std::function<void(const std::vector<uint8_t> &)> signalingDataEmitted;
|
std::function<void(const std::vector<uint8_t> &)> signalingDataEmitted;
|
||||||
|
std::shared_ptr<PlatformContext> platformContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Meta {
|
class Meta {
|
||||||
|
|
13
TMessagesProj/jni/tgcalls/JsonConfig.cpp
Normal file
13
TMessagesProj/jni/tgcalls/JsonConfig.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "JsonConfig.h"
|
||||||
|
|
||||||
|
namespace tgcalls {
|
||||||
|
|
||||||
|
JsonConfig::JsonConfig(Values values) : _values(values) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Value JsonConfig::getValue(std::string key) {
|
||||||
|
return _values[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tgcalls
|
25
TMessagesProj/jni/tgcalls/JsonConfig.h
Normal file
25
TMessagesProj/jni/tgcalls/JsonConfig.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef TGCALLS_JSON_CONFIG_H
|
||||||
|
#define TGCALLS_JSON_CONFIG_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include "absl/types/variant.h"
|
||||||
|
|
||||||
|
namespace tgcalls {
|
||||||
|
|
||||||
|
typedef absl::variant<int, double, bool, std::string> Value;
|
||||||
|
typedef std::map<std::string, Value> Values;
|
||||||
|
|
||||||
|
class JsonConfig {
|
||||||
|
|
||||||
|
public:
|
||||||
|
JsonConfig(Values values);
|
||||||
|
Value getValue(std::string key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Values _values;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace tgcalls
|
||||||
|
|
||||||
|
#endif
|
|
@ -49,7 +49,8 @@ _remotePrefferedAspectRatioUpdated(std::move(descriptor.remotePrefferedAspectRat
|
||||||
_signalingDataEmitted(std::move(descriptor.signalingDataEmitted)),
|
_signalingDataEmitted(std::move(descriptor.signalingDataEmitted)),
|
||||||
_signalBarsUpdated(std::move(descriptor.signalBarsUpdated)),
|
_signalBarsUpdated(std::move(descriptor.signalBarsUpdated)),
|
||||||
_localPreferredVideoAspectRatio(descriptor.config.preferredAspectRatio),
|
_localPreferredVideoAspectRatio(descriptor.config.preferredAspectRatio),
|
||||||
_enableHighBitrateVideo(descriptor.config.enableHighBitrateVideo) {
|
_enableHighBitrateVideo(descriptor.config.enableHighBitrateVideo),
|
||||||
|
_platformContext(descriptor.platformContext) {
|
||||||
assert(_thread->IsCurrent());
|
assert(_thread->IsCurrent());
|
||||||
assert(_stateUpdated != nullptr);
|
assert(_stateUpdated != nullptr);
|
||||||
assert(_signalingDataEmitted != nullptr);
|
assert(_signalingDataEmitted != nullptr);
|
||||||
|
@ -166,7 +167,7 @@ void Manager::start() {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
bool isOutgoing = _encryptionKey.isOutgoing;
|
bool isOutgoing = _encryptionKey.isOutgoing;
|
||||||
_mediaManager.reset(new ThreadLocalObject<MediaManager>(getMediaThread(), [weak, isOutgoing, thread, sendSignalingMessage, videoCapture = _videoCapture, localPreferredVideoAspectRatio = _localPreferredVideoAspectRatio, enableHighBitrateVideo = _enableHighBitrateVideo, signalBarsUpdated = _signalBarsUpdated, preferredCodecs = _preferredCodecs]() {
|
_mediaManager.reset(new ThreadLocalObject<MediaManager>(getMediaThread(), [weak, isOutgoing, thread, sendSignalingMessage, videoCapture = _videoCapture, localPreferredVideoAspectRatio = _localPreferredVideoAspectRatio, enableHighBitrateVideo = _enableHighBitrateVideo, signalBarsUpdated = _signalBarsUpdated, preferredCodecs = _preferredCodecs, platformContext = _platformContext]() {
|
||||||
return new MediaManager(
|
return new MediaManager(
|
||||||
getMediaThread(),
|
getMediaThread(),
|
||||||
isOutgoing,
|
isOutgoing,
|
||||||
|
@ -184,7 +185,8 @@ void Manager::start() {
|
||||||
signalBarsUpdated,
|
signalBarsUpdated,
|
||||||
localPreferredVideoAspectRatio,
|
localPreferredVideoAspectRatio,
|
||||||
enableHighBitrateVideo,
|
enableHighBitrateVideo,
|
||||||
preferredCodecs);
|
preferredCodecs,
|
||||||
|
platformContext);
|
||||||
}));
|
}));
|
||||||
_networkManager->perform(RTC_FROM_HERE, [](NetworkManager *networkManager) {
|
_networkManager->perform(RTC_FROM_HERE, [](NetworkManager *networkManager) {
|
||||||
networkManager->start();
|
networkManager->start();
|
||||||
|
|
|
@ -57,6 +57,8 @@ private:
|
||||||
bool _localNetworkIsLowCost = false;
|
bool _localNetworkIsLowCost = false;
|
||||||
bool _remoteNetworkIsLowCost = false;
|
bool _remoteNetworkIsLowCost = false;
|
||||||
|
|
||||||
|
std::shared_ptr<PlatformContext> _platformContext;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tgcalls
|
} // namespace tgcalls
|
||||||
|
|
|
@ -59,7 +59,8 @@ MediaManager::MediaManager(
|
||||||
std::function<void(int)> signalBarsUpdated,
|
std::function<void(int)> signalBarsUpdated,
|
||||||
float localPreferredVideoAspectRatio,
|
float localPreferredVideoAspectRatio,
|
||||||
bool enableHighBitrateVideo,
|
bool enableHighBitrateVideo,
|
||||||
std::vector<std::string> preferredCodecs) :
|
std::vector<std::string> preferredCodecs,
|
||||||
|
std::shared_ptr<PlatformContext> platformContext) :
|
||||||
_thread(thread),
|
_thread(thread),
|
||||||
_eventLog(std::make_unique<webrtc::RtcEventLogNull>()),
|
_eventLog(std::make_unique<webrtc::RtcEventLogNull>()),
|
||||||
_taskQueueFactory(webrtc::CreateDefaultTaskQueueFactory()),
|
_taskQueueFactory(webrtc::CreateDefaultTaskQueueFactory()),
|
||||||
|
@ -69,7 +70,8 @@ _signalBarsUpdated(std::move(signalBarsUpdated)),
|
||||||
_outgoingVideoState(videoCapture ? VideoState::Active : VideoState::Inactive),
|
_outgoingVideoState(videoCapture ? VideoState::Active : VideoState::Inactive),
|
||||||
_videoCapture(std::move(videoCapture)),
|
_videoCapture(std::move(videoCapture)),
|
||||||
_localPreferredVideoAspectRatio(localPreferredVideoAspectRatio),
|
_localPreferredVideoAspectRatio(localPreferredVideoAspectRatio),
|
||||||
_enableHighBitrateVideo(enableHighBitrateVideo) {
|
_enableHighBitrateVideo(enableHighBitrateVideo),
|
||||||
|
_platformContext(platformContext) {
|
||||||
_ssrcAudio.incoming = isOutgoing ? ssrcAudioIncoming : ssrcAudioOutgoing;
|
_ssrcAudio.incoming = isOutgoing ? ssrcAudioIncoming : ssrcAudioOutgoing;
|
||||||
_ssrcAudio.outgoing = (!isOutgoing) ? ssrcAudioIncoming : ssrcAudioOutgoing;
|
_ssrcAudio.outgoing = (!isOutgoing) ? ssrcAudioIncoming : ssrcAudioOutgoing;
|
||||||
_ssrcAudio.fecIncoming = isOutgoing ? ssrcAudioFecIncoming : ssrcAudioFecOutgoing;
|
_ssrcAudio.fecIncoming = isOutgoing ? ssrcAudioFecIncoming : ssrcAudioFecOutgoing;
|
||||||
|
@ -99,13 +101,14 @@ _enableHighBitrateVideo(enableHighBitrateVideo) {
|
||||||
mediaDeps.audio_encoder_factory = webrtc::CreateAudioEncoderFactory<webrtc::AudioEncoderOpus>();
|
mediaDeps.audio_encoder_factory = webrtc::CreateAudioEncoderFactory<webrtc::AudioEncoderOpus>();
|
||||||
mediaDeps.audio_decoder_factory = webrtc::CreateAudioDecoderFactory<webrtc::AudioDecoderOpus>();
|
mediaDeps.audio_decoder_factory = webrtc::CreateAudioDecoderFactory<webrtc::AudioDecoderOpus>();
|
||||||
|
|
||||||
mediaDeps.video_encoder_factory = PlatformInterface::SharedInstance()->makeVideoEncoderFactory();
|
mediaDeps.video_encoder_factory = PlatformInterface::SharedInstance()->makeVideoEncoderFactory(_platformContext);
|
||||||
mediaDeps.video_decoder_factory = PlatformInterface::SharedInstance()->makeVideoDecoderFactory();
|
mediaDeps.video_decoder_factory = PlatformInterface::SharedInstance()->makeVideoDecoderFactory(_platformContext);
|
||||||
|
|
||||||
_myVideoFormats = ComposeSupportedFormats(
|
_myVideoFormats = ComposeSupportedFormats(
|
||||||
mediaDeps.video_encoder_factory->GetSupportedFormats(),
|
mediaDeps.video_encoder_factory->GetSupportedFormats(),
|
||||||
mediaDeps.video_decoder_factory->GetSupportedFormats(),
|
mediaDeps.video_decoder_factory->GetSupportedFormats(),
|
||||||
preferredCodecs);
|
preferredCodecs,
|
||||||
|
_platformContext);
|
||||||
|
|
||||||
mediaDeps.audio_processing = webrtc::AudioProcessingBuilder().Create();
|
mediaDeps.audio_processing = webrtc::AudioProcessingBuilder().Create();
|
||||||
_mediaEngine = cricket::CreateMediaEngine(std::move(mediaDeps));
|
_mediaEngine = cricket::CreateMediaEngine(std::move(mediaDeps));
|
||||||
|
@ -121,6 +124,9 @@ _enableHighBitrateVideo(enableHighBitrateVideo) {
|
||||||
audioOptions.noise_suppression = true;
|
audioOptions.noise_suppression = true;
|
||||||
audioOptions.audio_jitter_buffer_fast_accelerate = true;
|
audioOptions.audio_jitter_buffer_fast_accelerate = true;
|
||||||
|
|
||||||
|
std::vector<std::string> streamIds;
|
||||||
|
streamIds.push_back("1");
|
||||||
|
|
||||||
_audioChannel.reset(_mediaEngine->voice().CreateMediaChannel(_call.get(), cricket::MediaConfig(), audioOptions, webrtc::CryptoOptions::NoGcm()));
|
_audioChannel.reset(_mediaEngine->voice().CreateMediaChannel(_call.get(), cricket::MediaConfig(), audioOptions, webrtc::CryptoOptions::NoGcm()));
|
||||||
_videoChannel.reset(_mediaEngine->video().CreateMediaChannel(_call.get(), cricket::MediaConfig(), cricket::VideoOptions(), webrtc::CryptoOptions::NoGcm(), _videoBitrateAllocatorFactory.get()));
|
_videoChannel.reset(_mediaEngine->video().CreateMediaChannel(_call.get(), cricket::MediaConfig(), cricket::VideoOptions(), webrtc::CryptoOptions::NoGcm(), _videoBitrateAllocatorFactory.get()));
|
||||||
|
|
||||||
|
@ -166,7 +172,9 @@ _enableHighBitrateVideo(enableHighBitrateVideo) {
|
||||||
audioRecvParameters.rtcp.remote_estimate = true;
|
audioRecvParameters.rtcp.remote_estimate = true;
|
||||||
|
|
||||||
_audioChannel->SetRecvParameters(audioRecvParameters);
|
_audioChannel->SetRecvParameters(audioRecvParameters);
|
||||||
_audioChannel->AddRecvStream(cricket::StreamParams::CreateLegacy(_ssrcAudio.incoming));
|
cricket::StreamParams audioRecvStreamParams = cricket::StreamParams::CreateLegacy(_ssrcAudio.incoming);
|
||||||
|
audioRecvStreamParams.set_stream_ids(streamIds);
|
||||||
|
_audioChannel->AddRecvStream(audioRecvStreamParams);
|
||||||
_audioChannel->SetPlayout(true);
|
_audioChannel->SetPlayout(true);
|
||||||
|
|
||||||
_videoChannel->SetInterface(_videoNetworkInterface.get());
|
_videoChannel->SetInterface(_videoNetworkInterface.get());
|
||||||
|
@ -506,6 +514,9 @@ void MediaManager::checkIsReceivingVideoChanged(bool wasReceiving) {
|
||||||
videoRecvStreamParams.ssrcs = {_ssrcVideo.incoming};
|
videoRecvStreamParams.ssrcs = {_ssrcVideo.incoming};
|
||||||
videoRecvStreamParams.ssrc_groups.push_back(videoRecvSsrcGroup);
|
videoRecvStreamParams.ssrc_groups.push_back(videoRecvSsrcGroup);
|
||||||
videoRecvStreamParams.cname = "cname";
|
videoRecvStreamParams.cname = "cname";
|
||||||
|
std::vector<std::string> streamIds;
|
||||||
|
streamIds.push_back("1");
|
||||||
|
videoRecvStreamParams.set_stream_ids(streamIds);
|
||||||
|
|
||||||
_videoChannel->SetRecvParameters(videoRecvParameters);
|
_videoChannel->SetRecvParameters(videoRecvParameters);
|
||||||
_videoChannel->AddRecvStream(videoRecvStreamParams);
|
_videoChannel->AddRecvStream(videoRecvStreamParams);
|
||||||
|
|
|
@ -43,7 +43,8 @@ public:
|
||||||
std::function<void(int)> signalBarsUpdated,
|
std::function<void(int)> signalBarsUpdated,
|
||||||
float localPreferredVideoAspectRatio,
|
float localPreferredVideoAspectRatio,
|
||||||
bool enableHighBitrateVideo,
|
bool enableHighBitrateVideo,
|
||||||
std::vector<std::string> preferredCodecs);
|
std::vector<std::string> preferredCodecs,
|
||||||
|
std::shared_ptr<PlatformContext> platformContext);
|
||||||
~MediaManager();
|
~MediaManager();
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
@ -140,6 +141,8 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<MediaManager::NetworkInterfaceImpl> _audioNetworkInterface;
|
std::unique_ptr<MediaManager::NetworkInterfaceImpl> _audioNetworkInterface;
|
||||||
std::unique_ptr<MediaManager::NetworkInterfaceImpl> _videoNetworkInterface;
|
std::unique_ptr<MediaManager::NetworkInterfaceImpl> _videoNetworkInterface;
|
||||||
|
|
||||||
|
std::shared_ptr<PlatformContext> _platformContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tgcalls
|
} // namespace tgcalls
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace rtc {
|
||||||
class BasicPacketSocketFactory;
|
class BasicPacketSocketFactory;
|
||||||
class BasicNetworkManager;
|
class BasicNetworkManager;
|
||||||
class PacketTransportInternal;
|
class PacketTransportInternal;
|
||||||
class NetworkRoute;
|
struct NetworkRoute;
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
|
|
|
@ -35,6 +35,9 @@ public:
|
||||||
virtual void setState(VideoState state) = 0;
|
virtual void setState(VideoState state) = 0;
|
||||||
virtual void setPreferredAspectRatio(float aspectRatio) = 0;
|
virtual void setPreferredAspectRatio(float aspectRatio) = 0;
|
||||||
virtual void setOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) = 0;
|
virtual void setOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) = 0;
|
||||||
|
virtual std::shared_ptr<PlatformContext> getPlatformContext() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ VideoCaptureInterfaceObject::VideoCaptureInterfaceObject(std::shared_ptr<Platfor
|
||||||
if (this->_stateUpdated) {
|
if (this->_stateUpdated) {
|
||||||
this->_stateUpdated(state);
|
this->_stateUpdated(state);
|
||||||
}
|
}
|
||||||
}, platformContext, _videoCapturerResolution);
|
}, _platformContext, _videoCapturerResolution);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ void VideoCaptureInterfaceObject::setStateUpdated(std::function<void(VideoState)
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoCaptureInterfaceImpl::VideoCaptureInterfaceImpl(std::shared_ptr<PlatformContext> platformContext) :
|
VideoCaptureInterfaceImpl::VideoCaptureInterfaceImpl(std::shared_ptr<PlatformContext> platformContext) :
|
||||||
|
_platformContext(platformContext),
|
||||||
_impl(Manager::getMediaThread(), [platformContext]() {
|
_impl(Manager::getMediaThread(), [platformContext]() {
|
||||||
return new VideoCaptureInterfaceObject(platformContext);
|
return new VideoCaptureInterfaceObject(platformContext);
|
||||||
}) {
|
}) {
|
||||||
|
@ -117,6 +118,10 @@ void VideoCaptureInterfaceImpl::setOutput(std::shared_ptr<rtc::VideoSinkInterfac
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<PlatformContext> VideoCaptureInterfaceImpl::getPlatformContext() {
|
||||||
|
return _platformContext;
|
||||||
|
}
|
||||||
|
|
||||||
ThreadLocalObject<VideoCaptureInterfaceObject> *VideoCaptureInterfaceImpl::object() {
|
ThreadLocalObject<VideoCaptureInterfaceObject> *VideoCaptureInterfaceImpl::object() {
|
||||||
return &_impl;
|
return &_impl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,13 @@ public:
|
||||||
void setState(VideoState state) override;
|
void setState(VideoState state) override;
|
||||||
void setPreferredAspectRatio(float aspectRatio) override;
|
void setPreferredAspectRatio(float aspectRatio) override;
|
||||||
void setOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) override;
|
void setOutput(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) override;
|
||||||
|
std::shared_ptr<PlatformContext> getPlatformContext() override;
|
||||||
|
|
||||||
ThreadLocalObject<VideoCaptureInterfaceObject> *object();
|
ThreadLocalObject<VideoCaptureInterfaceObject> *object();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ThreadLocalObject<VideoCaptureInterfaceObject> _impl;
|
ThreadLocalObject<VideoCaptureInterfaceObject> _impl;
|
||||||
|
std::shared_ptr<PlatformContext> _platformContext;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,9 @@ public:
|
||||||
virtual float getDisplayAspectRatio() {
|
virtual float getDisplayAspectRatio() {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
virtual std::unique_ptr<webrtc::VideoEncoderFactory> makeVideoEncoderFactory() = 0;
|
virtual std::unique_ptr<webrtc::VideoEncoderFactory> makeVideoEncoderFactory(std::shared_ptr<PlatformContext> platformContext) = 0;
|
||||||
virtual std::unique_ptr<webrtc::VideoDecoderFactory> makeVideoDecoderFactory() = 0;
|
virtual std::unique_ptr<webrtc::VideoDecoderFactory> makeVideoDecoderFactory(std::shared_ptr<PlatformContext> platformContext) = 0;
|
||||||
virtual bool supportsEncoding(const std::string &codecName) = 0;
|
virtual bool supportsEncoding(const std::string &codecName, std::shared_ptr<PlatformContext> platformContext) = 0;
|
||||||
virtual rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> makeVideoSource(rtc::Thread *signalingThread, rtc::Thread *workerThread) = 0;
|
virtual rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> makeVideoSource(rtc::Thread *signalingThread, rtc::Thread *workerThread) = 0;
|
||||||
virtual void adaptVideoSource(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> videoSource, int width, int height, int fps) = 0;
|
virtual void adaptVideoSource(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> videoSource, int width, int height, int fps) = 0;
|
||||||
virtual std::unique_ptr<VideoCapturerInterface> makeVideoCapturer(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source, bool useFrontCamera, std::function<void(VideoState)> stateUpdated, std::shared_ptr<PlatformContext> platformContext, std::pair<int, int> &outResolution) = 0;
|
virtual std::unique_ptr<VideoCapturerInterface> makeVideoCapturer(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source, bool useFrontCamera, std::function<void(VideoState)> stateUpdated, std::shared_ptr<PlatformContext> platformContext, std::pair<int, int> &outResolution) = 0;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "api/video_codecs/builtin_video_encoder_factory.h"
|
#include "api/video_codecs/builtin_video_encoder_factory.h"
|
||||||
#include "api/video_codecs/builtin_video_decoder_factory.h"
|
#include "api/video_codecs/builtin_video_decoder_factory.h"
|
||||||
#include "api/video_track_source_proxy.h"
|
#include "api/video_track_source_proxy.h"
|
||||||
|
#include "AndroidContext.h"
|
||||||
|
|
||||||
|
|
||||||
namespace tgcalls {
|
namespace tgcalls {
|
||||||
|
@ -28,29 +29,29 @@ float AndroidInterface::getDisplayAspectRatio() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<webrtc::VideoEncoderFactory> AndroidInterface::makeVideoEncoderFactory() {
|
std::unique_ptr<webrtc::VideoEncoderFactory> AndroidInterface::makeVideoEncoderFactory(std::shared_ptr<PlatformContext> platformContext) {
|
||||||
JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded();
|
JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded();
|
||||||
webrtc::ScopedJavaLocalRef<jclass> factory_class =
|
|
||||||
webrtc::GetClass(env, "org/webrtc/DefaultVideoEncoderFactory");
|
AndroidContext *context = (AndroidContext *) platformContext.get();
|
||||||
jmethodID factory_constructor = env->GetMethodID(
|
jmethodID methodId = env->GetMethodID(context->getJavaCapturerClass(), "getSharedEGLContext", "()Lorg/webrtc/EglBase$Context;");
|
||||||
factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
|
jobject eglContext = env->CallObjectMethod(context->getJavaCapturer(), methodId);
|
||||||
webrtc::ScopedJavaLocalRef<jobject> factory_object(
|
|
||||||
env, env->NewObject(factory_class.obj(), factory_constructor,
|
webrtc::ScopedJavaLocalRef<jclass> factory_class = webrtc::GetClass(env, "org/webrtc/DefaultVideoEncoderFactory");
|
||||||
nullptr /* shared_context */,
|
jmethodID factory_constructor = env->GetMethodID(factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
|
||||||
false /* enable_intel_vp8_encoder */,
|
webrtc::ScopedJavaLocalRef<jobject> factory_object(env, env->NewObject(factory_class.obj(), factory_constructor, eglContext, false, true));
|
||||||
true /* enable_h264_high_profile */));
|
|
||||||
return webrtc::JavaToNativeVideoEncoderFactory(env, factory_object.obj());
|
return webrtc::JavaToNativeVideoEncoderFactory(env, factory_object.obj());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<webrtc::VideoDecoderFactory> AndroidInterface::makeVideoDecoderFactory() {
|
std::unique_ptr<webrtc::VideoDecoderFactory> AndroidInterface::makeVideoDecoderFactory(std::shared_ptr<PlatformContext> platformContext) {
|
||||||
JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded();
|
JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded();
|
||||||
webrtc::ScopedJavaLocalRef<jclass> factory_class =
|
|
||||||
webrtc::GetClass(env, "org/webrtc/DefaultVideoDecoderFactory");
|
AndroidContext *context = (AndroidContext *) platformContext.get();
|
||||||
jmethodID factory_constructor = env->GetMethodID(
|
jmethodID methodId = env->GetMethodID(context->getJavaCapturerClass(), "getSharedEGLContext", "()Lorg/webrtc/EglBase$Context;");
|
||||||
factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;)V");
|
jobject eglContext = env->CallObjectMethod(context->getJavaCapturer(), methodId);
|
||||||
webrtc::ScopedJavaLocalRef<jobject> factory_object(
|
|
||||||
env, env->NewObject(factory_class.obj(), factory_constructor,
|
webrtc::ScopedJavaLocalRef<jclass> factory_class = webrtc::GetClass(env, "org/webrtc/DefaultVideoDecoderFactory");
|
||||||
nullptr /* shared_context */));
|
jmethodID factory_constructor = env->GetMethodID(factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;)V");
|
||||||
|
webrtc::ScopedJavaLocalRef<jobject> factory_object(env, env->NewObject(factory_class.obj(), factory_constructor, eglContext));
|
||||||
return webrtc::JavaToNativeVideoDecoderFactory(env, factory_object.obj());
|
return webrtc::JavaToNativeVideoDecoderFactory(env, factory_object.obj());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,18 +65,17 @@ rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> AndroidInterface::makeVide
|
||||||
return webrtc::VideoTrackSourceProxy::Create(signalingThread, workerThread, _source);
|
return webrtc::VideoTrackSourceProxy::Create(signalingThread, workerThread, _source);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidInterface::supportsEncoding(const std::string &codecName) {
|
bool AndroidInterface::supportsEncoding(const std::string &codecName, std::shared_ptr<PlatformContext> platformContext) {
|
||||||
if (hardwareVideoEncoderFactory == nullptr) {
|
if (hardwareVideoEncoderFactory == nullptr) {
|
||||||
JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded();
|
JNIEnv *env = webrtc::AttachCurrentThreadIfNeeded();
|
||||||
webrtc::ScopedJavaLocalRef<jclass> factory_class =
|
|
||||||
webrtc::GetClass(env, "org/webrtc/HardwareVideoEncoderFactory");
|
AndroidContext *context = (AndroidContext *) platformContext.get();
|
||||||
jmethodID factory_constructor = env->GetMethodID(
|
jmethodID methodId = env->GetMethodID(context->getJavaCapturerClass(), "getSharedEGLContext", "()Lorg/webrtc/EglBase$Context;");
|
||||||
factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
|
jobject eglContext = env->CallObjectMethod(context->getJavaCapturer(), methodId);
|
||||||
webrtc::ScopedJavaLocalRef<jobject> factory_object(
|
|
||||||
env, env->NewObject(factory_class.obj(), factory_constructor,
|
webrtc::ScopedJavaLocalRef<jclass> factory_class = webrtc::GetClass(env, "org/webrtc/HardwareVideoEncoderFactory");
|
||||||
nullptr,
|
jmethodID factory_constructor = env->GetMethodID(factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
|
||||||
false,
|
webrtc::ScopedJavaLocalRef<jobject> factory_object(env, env->NewObject(factory_class.obj(), factory_constructor, eglContext, false, true));
|
||||||
true));
|
|
||||||
hardwareVideoEncoderFactory = webrtc::JavaToNativeVideoEncoderFactory(env, factory_object.obj());
|
hardwareVideoEncoderFactory = webrtc::JavaToNativeVideoEncoderFactory(env, factory_object.obj());
|
||||||
}
|
}
|
||||||
auto formats = hardwareVideoEncoderFactory->GetSupportedFormats();
|
auto formats = hardwareVideoEncoderFactory->GetSupportedFormats();
|
||||||
|
|
|
@ -11,9 +11,9 @@ class AndroidInterface : public PlatformInterface {
|
||||||
public:
|
public:
|
||||||
void configurePlatformAudio() override;
|
void configurePlatformAudio() override;
|
||||||
float getDisplayAspectRatio() override;
|
float getDisplayAspectRatio() override;
|
||||||
std::unique_ptr<webrtc::VideoEncoderFactory> makeVideoEncoderFactory() override;
|
std::unique_ptr<webrtc::VideoEncoderFactory> makeVideoEncoderFactory(std::shared_ptr<PlatformContext> platformContext) override;
|
||||||
std::unique_ptr<webrtc::VideoDecoderFactory> makeVideoDecoderFactory() override;
|
std::unique_ptr<webrtc::VideoDecoderFactory> makeVideoDecoderFactory(std::shared_ptr<PlatformContext> platformContext) override;
|
||||||
bool supportsEncoding(const std::string &codecName) override;
|
bool supportsEncoding(const std::string &codecName, std::shared_ptr<PlatformContext> platformContext) override;
|
||||||
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> makeVideoSource(rtc::Thread *signalingThread, rtc::Thread *workerThread) override;
|
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> makeVideoSource(rtc::Thread *signalingThread, rtc::Thread *workerThread) override;
|
||||||
void adaptVideoSource(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> videoSource, int width, int height, int fps) override;
|
void adaptVideoSource(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> videoSource, int width, int height, int fps) override;
|
||||||
std::unique_ptr<VideoCapturerInterface> makeVideoCapturer(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source, bool useFrontCamera, std::function<void(VideoState)> stateUpdated, std::shared_ptr<PlatformContext> platformContext, std::pair<int, int> &outResolution) override;
|
std::unique_ptr<VideoCapturerInterface> makeVideoCapturer(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source, bool useFrontCamera, std::function<void(VideoState)> stateUpdated, std::shared_ptr<PlatformContext> platformContext, std::pair<int, int> &outResolution) override;
|
||||||
|
|
|
@ -241,7 +241,8 @@ public:
|
||||||
_videoCapture(descriptor.videoCapture),
|
_videoCapture(descriptor.videoCapture),
|
||||||
_localPreferredVideoAspectRatio(descriptor.config.preferredAspectRatio),
|
_localPreferredVideoAspectRatio(descriptor.config.preferredAspectRatio),
|
||||||
_state(State::Reconnecting),
|
_state(State::Reconnecting),
|
||||||
_videoState(_videoCapture ? VideoState::Active : VideoState::Inactive) {
|
_videoState(_videoCapture ? VideoState::Active : VideoState::Inactive),
|
||||||
|
_platformContext(descriptor.platformContext) {
|
||||||
assert(getMediaThread()->IsCurrent());
|
assert(getMediaThread()->IsCurrent());
|
||||||
|
|
||||||
rtc::LogMessage::LogToDebug(rtc::LS_INFO);
|
rtc::LogMessage::LogToDebug(rtc::LS_INFO);
|
||||||
|
@ -304,8 +305,8 @@ public:
|
||||||
mediaDeps.task_queue_factory = dependencies.task_queue_factory.get();
|
mediaDeps.task_queue_factory = dependencies.task_queue_factory.get();
|
||||||
mediaDeps.audio_encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
|
mediaDeps.audio_encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
|
||||||
mediaDeps.audio_decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
|
mediaDeps.audio_decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
|
||||||
mediaDeps.video_encoder_factory = PlatformInterface::SharedInstance()->makeVideoEncoderFactory();
|
mediaDeps.video_encoder_factory = PlatformInterface::SharedInstance()->makeVideoEncoderFactory(_platformContext);
|
||||||
mediaDeps.video_decoder_factory = PlatformInterface::SharedInstance()->makeVideoDecoderFactory();
|
mediaDeps.video_decoder_factory = PlatformInterface::SharedInstance()->makeVideoDecoderFactory(_platformContext);
|
||||||
|
|
||||||
webrtc::AudioProcessing *apm = webrtc::AudioProcessingBuilder().Create();
|
webrtc::AudioProcessing *apm = webrtc::AudioProcessingBuilder().Create();
|
||||||
webrtc::AudioProcessing::Config audioConfig;
|
webrtc::AudioProcessing::Config audioConfig;
|
||||||
|
@ -926,6 +927,8 @@ private:
|
||||||
|
|
||||||
bool _didSetRemoteDescription = false;
|
bool _didSetRemoteDescription = false;
|
||||||
std::vector<std::shared_ptr<IceCandidateData>> _pendingRemoteIceCandidates;
|
std::vector<std::shared_ptr<IceCandidateData>> _pendingRemoteIceCandidates;
|
||||||
|
|
||||||
|
std::shared_ptr<PlatformContext> _platformContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
InstanceImplReference::InstanceImplReference(Descriptor &&descriptor) :
|
InstanceImplReference::InstanceImplReference(Descriptor &&descriptor) :
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class BuildVars {
|
||||||
public static boolean USE_CLOUD_STRINGS = true;
|
public static boolean USE_CLOUD_STRINGS = true;
|
||||||
public static boolean CHECK_UPDATES = true;
|
public static boolean CHECK_UPDATES = true;
|
||||||
public static boolean TON_WALLET_STANDALONE = false;
|
public static boolean TON_WALLET_STANDALONE = false;
|
||||||
public static int BUILD_VERSION = 2064;
|
public static int BUILD_VERSION = 2065;
|
||||||
public static String BUILD_VERSION_STRING = "7.0.0";
|
public static String BUILD_VERSION_STRING = "7.0.0";
|
||||||
public static int APP_ID = 4;
|
public static int APP_ID = 4;
|
||||||
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
|
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
|
||||||
|
|
|
@ -880,7 +880,12 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
|
||||||
roundRect.set(drawRegion);
|
roundRect.set(drawRegion);
|
||||||
|
|
||||||
if (isRoundRect) {
|
if (isRoundRect) {
|
||||||
|
try {
|
||||||
canvas.drawRoundRect(roundRect,roundRadius[0], roundRadius[0],roundPaint);
|
canvas.drawRoundRect(roundRect,roundRadius[0], roundRadius[0],roundPaint);
|
||||||
|
} catch (Exception e) {
|
||||||
|
onBitmapException(bitmapDrawable);
|
||||||
|
FileLog.e(e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int a = 0; a < roundRadius.length; a++) {
|
for (int a = 0; a < roundRadius.length; a++) {
|
||||||
radii[a * 2] = roundRadius[a];
|
radii[a * 2] = roundRadius[a];
|
||||||
|
@ -930,7 +935,12 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
|
||||||
roundPaint.setAlpha(alpha);
|
roundPaint.setAlpha(alpha);
|
||||||
|
|
||||||
if (isRoundRect) {
|
if (isRoundRect) {
|
||||||
|
try {
|
||||||
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
|
canvas.drawRoundRect(roundRect, roundRadius[0], roundRadius[0], roundPaint);
|
||||||
|
} catch (Exception e) {
|
||||||
|
onBitmapException(bitmapDrawable);
|
||||||
|
FileLog.e(e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int a = 0; a < roundRadius.length; a++) {
|
for (int a = 0; a < roundRadius.length; a++) {
|
||||||
radii[a * 2] = roundRadius[a];
|
radii[a * 2] = roundRadius[a];
|
||||||
|
|
|
@ -3187,8 +3187,14 @@ public class NotificationsController extends BaseController {
|
||||||
int selfUserId = getUserConfig().getClientUserId();
|
int selfUserId = getUserConfig().getClientUserId();
|
||||||
boolean waitingForPasscode = AndroidUtilities.needShowPasscode() || SharedConfig.isWaitingForPasscodeEnter;
|
boolean waitingForPasscode = AndroidUtilities.needShowPasscode() || SharedConfig.isWaitingForPasscodeEnter;
|
||||||
|
|
||||||
|
int maxCount;
|
||||||
|
if (UserConfig.getActivatedAccountsCount() >= 3) {
|
||||||
|
maxCount = 7;
|
||||||
|
} else {
|
||||||
|
maxCount = 10;
|
||||||
|
}
|
||||||
for (int b = 0, size = sortedDialogs.size(); b < size; b++) {
|
for (int b = 0, size = sortedDialogs.size(); b < size; b++) {
|
||||||
if (holders.size() >= 15) {
|
if (holders.size() >= maxCount) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
long dialog_id = sortedDialogs.get(b);
|
long dialog_id = sortedDialogs.get(b);
|
||||||
|
|
|
@ -11,7 +11,6 @@ import androidx.annotation.Nullable;
|
||||||
import org.telegram.messenger.ApplicationLoader;
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a very dirty hack to allow Telegram calls to respect user's DND settings.
|
* This is a very dirty hack to allow Telegram calls to respect user's DND settings.
|
||||||
|
@ -66,20 +65,20 @@ public class CallNotificationSoundProvider extends ContentProvider {
|
||||||
throw new FileNotFoundException("Unexpected application state");
|
throw new FileNotFoundException("Unexpected application state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
VoIPBaseService srv = VoIPBaseService.getSharedInstance();
|
VoIPBaseService srv = VoIPBaseService.getSharedInstance();
|
||||||
if (srv != null) {
|
if (srv != null) {
|
||||||
srv.startRingtoneAndVibration();
|
srv.startRingtoneAndVibration();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
|
ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
|
||||||
ParcelFileDescriptor.AutoCloseOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
|
ParcelFileDescriptor.AutoCloseOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
|
||||||
byte[] silentWav = {82, 73, 70, 70, 41, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0, 0, 1, 0, 1, 0, 68, (byte) 172, 0, 0, 16, (byte) 177, 2, 0, 2, 0, 16, 0, 100, 97, 116, 97, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
byte[] silentWav = {82, 73, 70, 70, 41, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0, 0, 1, 0, 1, 0, 68, (byte) 172, 0, 0, 16, (byte) 177, 2, 0, 2, 0, 16, 0, 100, 97, 116, 97, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
outputStream.write(silentWav);
|
outputStream.write(silentWav);
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
return pipe[0];
|
return pipe[0];
|
||||||
} catch (IOException x) {
|
} catch (Exception e) {
|
||||||
throw new FileNotFoundException(x.getMessage());
|
throw new FileNotFoundException(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,6 +330,15 @@ public final class Instance {
|
||||||
public final boolean useSystemAec;
|
public final boolean useSystemAec;
|
||||||
public final double hangupUiTimeout;
|
public final double hangupUiTimeout;
|
||||||
|
|
||||||
|
public final boolean enable_vp8_encoder;
|
||||||
|
public final boolean enable_vp8_decoder;
|
||||||
|
public final boolean enable_vp9_encoder;
|
||||||
|
public final boolean enable_vp9_decoder;
|
||||||
|
public final boolean enable_h265_encoder;
|
||||||
|
public final boolean enable_h265_decoder;
|
||||||
|
public final boolean enable_h264_encoder;
|
||||||
|
public final boolean enable_h264_decoder;
|
||||||
|
|
||||||
private final JSONObject jsonObject;
|
private final JSONObject jsonObject;
|
||||||
|
|
||||||
private ServerConfig(JSONObject jsonObject) {
|
private ServerConfig(JSONObject jsonObject) {
|
||||||
|
@ -337,6 +346,15 @@ public final class Instance {
|
||||||
this.useSystemNs = jsonObject.optBoolean("use_system_ns", true);
|
this.useSystemNs = jsonObject.optBoolean("use_system_ns", true);
|
||||||
this.useSystemAec = jsonObject.optBoolean("use_system_aec", true);
|
this.useSystemAec = jsonObject.optBoolean("use_system_aec", true);
|
||||||
this.hangupUiTimeout = jsonObject.optDouble("hangup_ui_timeout", 5);
|
this.hangupUiTimeout = jsonObject.optDouble("hangup_ui_timeout", 5);
|
||||||
|
|
||||||
|
this.enable_vp8_encoder = jsonObject.optBoolean("enable_vp8_encoder", true);
|
||||||
|
this.enable_vp8_decoder = jsonObject.optBoolean("enable_vp8_decoder", true);
|
||||||
|
this.enable_vp9_encoder = jsonObject.optBoolean("enable_vp9_encoder", true);
|
||||||
|
this.enable_vp9_decoder = jsonObject.optBoolean("enable_vp9_decoder", true);
|
||||||
|
this.enable_h265_encoder = jsonObject.optBoolean("enable_h265_encoder", true);
|
||||||
|
this.enable_h265_decoder = jsonObject.optBoolean("enable_h265_decoder", true);
|
||||||
|
this.enable_h264_encoder = jsonObject.optBoolean("enable_h264_encoder", true);
|
||||||
|
this.enable_h264_decoder = jsonObject.optBoolean("enable_h264_decoder", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(String key) {
|
public String getString(String key) {
|
||||||
|
|
|
@ -5,6 +5,8 @@ import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
|
|
||||||
|
import com.google.android.datatransport.runtime.logging.Logging;
|
||||||
|
|
||||||
import org.telegram.messenger.AndroidUtilities;
|
import org.telegram.messenger.AndroidUtilities;
|
||||||
import org.telegram.messenger.ApplicationLoader;
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
import org.telegram.messenger.FileLog;
|
import org.telegram.messenger.FileLog;
|
||||||
|
@ -44,6 +46,7 @@ public class VideoCameraCapturer {
|
||||||
if (Build.VERSION.SDK_INT < 18) {
|
if (Build.VERSION.SDK_INT < 18) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Logging.i("VideoCameraCapturer", "device model = " + Build.MANUFACTURER + Build.MODEL);
|
||||||
AndroidUtilities.runOnUIThread(() -> {
|
AndroidUtilities.runOnUIThread(() -> {
|
||||||
instance = this;
|
instance = this;
|
||||||
thread = new HandlerThread("CallThread");
|
thread = new HandlerThread("CallThread");
|
||||||
|
@ -192,5 +195,12 @@ public class VideoCameraCapturer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EglBase.Context getSharedEGLContext() {
|
||||||
|
if (eglBase == null) {
|
||||||
|
eglBase = EglBase.create(null, EglBase.CONFIG_PLAIN);
|
||||||
|
}
|
||||||
|
return eglBase != null ? eglBase.getEglBaseContext() : null;
|
||||||
|
}
|
||||||
|
|
||||||
private static native CapturerObserver nativeGetJavaVideoCapturerObserver(long ptr);
|
private static native CapturerObserver nativeGetJavaVideoCapturerObserver(long ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,7 +160,7 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
|
||||||
protected long callStartTime;
|
protected long callStartTime;
|
||||||
protected boolean playingSound;
|
protected boolean playingSound;
|
||||||
protected boolean isOutgoing;
|
protected boolean isOutgoing;
|
||||||
protected boolean videoCall;
|
public boolean videoCall;
|
||||||
protected long videoCapturer;
|
protected long videoCapturer;
|
||||||
protected Runnable timeoutRunnable;
|
protected Runnable timeoutRunnable;
|
||||||
|
|
||||||
|
@ -1511,7 +1511,7 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
|
||||||
}
|
}
|
||||||
// some non-Google devices don't implement the ConnectionService API correctly so, sadly,
|
// some non-Google devices don't implement the ConnectionService API correctly so, sadly,
|
||||||
// we'll have to whitelist only a handful of known-compatible devices for now
|
// we'll have to whitelist only a handful of known-compatible devices for now
|
||||||
return "angler".equals(Build.PRODUCT) // Nexus 6P
|
return false;/*"angler".equals(Build.PRODUCT) // Nexus 6P
|
||||||
|| "bullhead".equals(Build.PRODUCT) // Nexus 5X
|
|| "bullhead".equals(Build.PRODUCT) // Nexus 5X
|
||||||
|| "sailfish".equals(Build.PRODUCT) // Pixel
|
|| "sailfish".equals(Build.PRODUCT) // Pixel
|
||||||
|| "marlin".equals(Build.PRODUCT) // Pixel XL
|
|| "marlin".equals(Build.PRODUCT) // Pixel XL
|
||||||
|
@ -1519,7 +1519,7 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
|
||||||
|| "taimen".equals(Build.PRODUCT) // Pixel 2 XL
|
|| "taimen".equals(Build.PRODUCT) // Pixel 2 XL
|
||||||
|| "blueline".equals(Build.PRODUCT) // Pixel 3
|
|| "blueline".equals(Build.PRODUCT) // Pixel 3
|
||||||
|| "crosshatch".equals(Build.PRODUCT) // Pixel 3 XL
|
|| "crosshatch".equals(Build.PRODUCT) // Pixel 3 XL
|
||||||
|| MessagesController.getGlobalMainSettings().getBoolean("dbg_force_connection_service", false);
|
|| MessagesController.getGlobalMainSettings().getBoolean("dbg_force_connection_service", false);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface StateListener {
|
public interface StateListener {
|
||||||
|
|
|
@ -941,6 +941,7 @@ public class VoIPService extends VoIPBaseService {
|
||||||
PendingIntent.getActivity(VoIPService.this, 0, new Intent(VoIPService.this, VoIPFeedbackActivity.class)
|
PendingIntent.getActivity(VoIPService.this, 0, new Intent(VoIPService.this, VoIPFeedbackActivity.class)
|
||||||
.putExtra("call_id", call.id)
|
.putExtra("call_id", call.id)
|
||||||
.putExtra("call_access_hash", call.access_hash)
|
.putExtra("call_access_hash", call.access_hash)
|
||||||
|
.putExtra("call_video", call.video)
|
||||||
.putExtra("account", currentAccount)
|
.putExtra("account", currentAccount)
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP), 0).send();
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP), 0).send();
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
|
|
|
@ -76,6 +76,12 @@ public class AcceptDeclineView extends View {
|
||||||
|
|
||||||
boolean retryMod;
|
boolean retryMod;
|
||||||
Drawable rippleDrawable;
|
Drawable rippleDrawable;
|
||||||
|
private boolean screenWasWakeup;
|
||||||
|
Paint linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
|
||||||
|
Drawable arrowDrawable;
|
||||||
|
|
||||||
|
float arrowProgress;
|
||||||
|
|
||||||
public AcceptDeclineView(@NonNull Context context) {
|
public AcceptDeclineView(@NonNull Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
@ -107,12 +113,14 @@ public class AcceptDeclineView extends View {
|
||||||
cancelDrawable = ContextCompat.getDrawable(context, R.drawable.ic_close_white).mutate();
|
cancelDrawable = ContextCompat.getDrawable(context, R.drawable.ic_close_white).mutate();
|
||||||
cancelDrawable.setColorFilter(new PorterDuffColorFilter(Color.BLACK, PorterDuff.Mode.MULTIPLY));
|
cancelDrawable.setColorFilter(new PorterDuffColorFilter(Color.BLACK, PorterDuff.Mode.MULTIPLY));
|
||||||
|
|
||||||
|
|
||||||
acceptCirclePaint.setColor(0x3f45bc4d);
|
acceptCirclePaint.setColor(0x3f45bc4d);
|
||||||
rippleDrawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(52), 0, ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * 0.3f)));
|
rippleDrawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(52), 0, ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * 0.3f)));
|
||||||
rippleDrawable.setCallback(this);
|
rippleDrawable.setCallback(this);
|
||||||
|
|
||||||
|
arrowDrawable = ContextCompat.getDrawable(context, R.drawable.call_arrow_right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
@ -122,6 +130,8 @@ public class AcceptDeclineView extends View {
|
||||||
callDrawable.setBounds(padding, padding, padding + AndroidUtilities.dp(28), padding + AndroidUtilities.dp(28));
|
callDrawable.setBounds(padding, padding, padding + AndroidUtilities.dp(28), padding + AndroidUtilities.dp(28));
|
||||||
cancelDrawable.setBounds(padding, padding, padding + AndroidUtilities.dp(28), padding + AndroidUtilities.dp(28));
|
cancelDrawable.setBounds(padding, padding, padding + AndroidUtilities.dp(28), padding + AndroidUtilities.dp(28));
|
||||||
|
|
||||||
|
linePaint.setStrokeWidth(AndroidUtilities.dp(3));
|
||||||
|
linePaint.setColor(Color.WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -200,7 +210,7 @@ public class AcceptDeclineView extends View {
|
||||||
animator.start();
|
animator.start();
|
||||||
leftAnimator = animator;
|
leftAnimator = animator;
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
if ((!startDrag && Math.abs(dy) < touchSlop) || leftOffsetX > maxOffset * 0.8f) {
|
if ((!startDrag && Math.abs(dy) < touchSlop && !screenWasWakeup) || leftOffsetX > maxOffset * 0.8f) {
|
||||||
listener.onDicline();
|
listener.onDicline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +224,7 @@ public class AcceptDeclineView extends View {
|
||||||
animator.start();
|
animator.start();
|
||||||
rightAnimator = animator;
|
rightAnimator = animator;
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
if ((!startDrag && Math.abs(dy) < touchSlop) || -rigthOffsetX > maxOffset * 0.8f) {
|
if ((!startDrag && Math.abs(dy) < touchSlop && !screenWasWakeup) || -rigthOffsetX > maxOffset * 0.8f) {
|
||||||
listener.onAccept();
|
listener.onAccept();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,6 +273,49 @@ public class AcceptDeclineView extends View {
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float k = 0.6f;
|
||||||
|
if (screenWasWakeup && !retryMod) {
|
||||||
|
|
||||||
|
arrowProgress += 16 / 1500f;
|
||||||
|
if (arrowProgress > 1) {
|
||||||
|
arrowProgress = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cY = (int) (AndroidUtilities.dp(40) + buttonWidth / 2f);
|
||||||
|
float startX = AndroidUtilities.dp(46) + buttonWidth + AndroidUtilities.dp(8);
|
||||||
|
float endX = getMeasuredWidth() / 2f - AndroidUtilities.dp(8);
|
||||||
|
|
||||||
|
float lineLength = AndroidUtilities.dp(10);
|
||||||
|
|
||||||
|
float stepProgress = (1f - k) / 3f;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
int x = (int) (startX + (endX - startX - lineLength) / 3 * i);
|
||||||
|
|
||||||
|
float alpha = 0.5f;
|
||||||
|
float startAlphaFrom = i * stepProgress;
|
||||||
|
if (arrowProgress > startAlphaFrom && arrowProgress < startAlphaFrom + k) {
|
||||||
|
float p = (arrowProgress - startAlphaFrom) / k;
|
||||||
|
if (p > 0.5) p = 1f - p;
|
||||||
|
alpha = 0.5f + p;
|
||||||
|
}
|
||||||
|
canvas.save();
|
||||||
|
canvas.clipRect(leftOffsetX + AndroidUtilities.dp(46) + buttonWidth / 2,0,getMeasuredHeight(),getMeasuredWidth() >> 1);
|
||||||
|
arrowDrawable.setAlpha((int) (255 * alpha));
|
||||||
|
arrowDrawable.setBounds(x, cY - arrowDrawable.getIntrinsicHeight() / 2, x + arrowDrawable.getIntrinsicWidth(), cY + arrowDrawable.getIntrinsicHeight() / 2);
|
||||||
|
arrowDrawable.draw(canvas);
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
x = (int) (getMeasuredWidth() - (startX + (endX - startX - lineLength) / 3 * i));
|
||||||
|
canvas.save();
|
||||||
|
canvas.clipRect(getMeasuredWidth() >> 1, 0, rigthOffsetX + getMeasuredWidth() - AndroidUtilities.dp(46) - buttonWidth / 2, getMeasuredHeight());
|
||||||
|
canvas.rotate(180, x - arrowDrawable.getIntrinsicWidth() / 2f, cY);
|
||||||
|
arrowDrawable.setBounds(x - arrowDrawable.getIntrinsicWidth(), cY - arrowDrawable.getIntrinsicHeight() / 2, x, cY + arrowDrawable.getIntrinsicHeight() / 2);
|
||||||
|
arrowDrawable.draw(canvas);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
bigRadius += AndroidUtilities.dp(8) * 0.005f;
|
bigRadius += AndroidUtilities.dp(8) * 0.005f;
|
||||||
canvas.save();
|
canvas.save();
|
||||||
canvas.translate(0, AndroidUtilities.dp(40));
|
canvas.translate(0, AndroidUtilities.dp(40));
|
||||||
|
@ -330,6 +383,7 @@ public class AcceptDeclineView extends View {
|
||||||
|
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
void onAccept();
|
void onAccept();
|
||||||
|
|
||||||
void onDicline();
|
void onDicline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +391,7 @@ public class AcceptDeclineView extends View {
|
||||||
this.retryMod = retryMod;
|
this.retryMod = retryMod;
|
||||||
if (retryMod) {
|
if (retryMod) {
|
||||||
declineDrawable.setColor(Color.WHITE);
|
declineDrawable.setColor(Color.WHITE);
|
||||||
|
screenWasWakeup = false;
|
||||||
} else {
|
} else {
|
||||||
declineDrawable.setColor(0xFFe61e44);
|
declineDrawable.setColor(0xFFe61e44);
|
||||||
}
|
}
|
||||||
|
@ -421,6 +476,10 @@ public class AcceptDeclineView extends View {
|
||||||
return accessibilityNodeProvider;
|
return accessibilityNodeProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setScreenWasWakeup(boolean screenWasWakeup) {
|
||||||
|
this.screenWasWakeup = screenWasWakeup;
|
||||||
|
}
|
||||||
|
|
||||||
private static abstract class AcceptDeclineAccessibilityNodeProvider extends AccessibilityNodeProvider {
|
private static abstract class AcceptDeclineAccessibilityNodeProvider extends AccessibilityNodeProvider {
|
||||||
|
|
||||||
private final View hostView;
|
private final View hostView;
|
||||||
|
@ -514,7 +573,9 @@ public class AcceptDeclineView extends View {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract CharSequence getVirtualViewText(int virtualViewId);
|
protected abstract CharSequence getVirtualViewText(int virtualViewId);
|
||||||
|
|
||||||
protected abstract void getVirtualViewBoundsInScreen(int virtualViewId, Rect outRect);
|
protected abstract void getVirtualViewBoundsInScreen(int virtualViewId, Rect outRect);
|
||||||
|
|
||||||
protected abstract void getVirtualViewBoundsInParent(int virtualViewId, Rect outRect);
|
protected abstract void getVirtualViewBoundsInParent(int virtualViewId, Rect outRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,11 @@ public class VoIPHelper {
|
||||||
bldr.setNeutralButton(LocaleController.getString("VoipOfflineOpenSettings", R.string.VoipOfflineOpenSettings), (dialog, which) -> activity.startActivity(settingsIntent));
|
bldr.setNeutralButton(LocaleController.getString("VoipOfflineOpenSettings", R.string.VoipOfflineOpenSettings), (dialog, which) -> activity.startActivity(settingsIntent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
bldr.show();
|
bldr.show();
|
||||||
|
} catch (Exception e) {
|
||||||
|
FileLog.e(e);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +215,7 @@ public class VoIPHelper {
|
||||||
if (d[0].equals(call.call_id + "")) {
|
if (d[0].equals(call.call_id + "")) {
|
||||||
try {
|
try {
|
||||||
long accessHash = Long.parseLong(d[1]);
|
long accessHash = Long.parseLong(d[1]);
|
||||||
showRateAlert(context, null, call.call_id, accessHash, UserConfig.selectedAccount, true);
|
showRateAlert(context, null, call.video, call.call_id, accessHash, UserConfig.selectedAccount, true);
|
||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -219,7 +223,7 @@ public class VoIPHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showRateAlert(final Context context, final Runnable onDismiss, final long callID, final long accessHash, final int account, final boolean userInitiative) {
|
public static void showRateAlert(final Context context, final Runnable onDismiss, boolean isVideo, final long callID, final long accessHash, final int account, final boolean userInitiative) {
|
||||||
final File log = getLogFile(callID);
|
final File log = getLogFile(callID);
|
||||||
final int[] page = {0};
|
final int[] page = {0};
|
||||||
LinearLayout alertView = new LinearLayout(context);
|
LinearLayout alertView = new LinearLayout(context);
|
||||||
|
@ -246,32 +250,41 @@ public class VoIPHelper {
|
||||||
check.setChecked(!check.isChecked(), true);
|
check.setChecked(!check.isChecked(), true);
|
||||||
};
|
};
|
||||||
|
|
||||||
final String[] problems = {"echo", "noise", "interruptions", "distorted_speech", "silent_local", "silent_remote", "dropped"};
|
final String[] problems = {isVideo ? "distorted_video" : null, isVideo ? "pixelated_video" : null, "echo", "noise", "interruptions", "distorted_speech", "silent_local", "silent_remote", "dropped"};
|
||||||
for (int i = 0; i < problems.length; i++) {
|
for (int i = 0; i < problems.length; i++) {
|
||||||
|
if (problems[i] == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
CheckBoxCell check = new CheckBoxCell(context, 1);
|
CheckBoxCell check = new CheckBoxCell(context, 1);
|
||||||
check.setClipToPadding(false);
|
check.setClipToPadding(false);
|
||||||
check.setTag(problems[i]);
|
check.setTag(problems[i]);
|
||||||
String label = null;
|
String label = null;
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
label = LocaleController.getString("RateCallEcho", R.string.RateCallEcho);
|
label = LocaleController.getString("RateCallVideoDistorted", R.string.RateCallVideoDistorted);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
label = LocaleController.getString("RateCallNoise", R.string.RateCallNoise);
|
label = LocaleController.getString("RateCallVideoPixelated", R.string.RateCallVideoPixelated);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
label = LocaleController.getString("RateCallInterruptions", R.string.RateCallInterruptions);
|
label = LocaleController.getString("RateCallEcho", R.string.RateCallEcho);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
label = LocaleController.getString("RateCallDistorted", R.string.RateCallDistorted);
|
label = LocaleController.getString("RateCallNoise", R.string.RateCallNoise);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
label = LocaleController.getString("RateCallSilentLocal", R.string.RateCallSilentLocal);
|
label = LocaleController.getString("RateCallInterruptions", R.string.RateCallInterruptions);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
label = LocaleController.getString("RateCallSilentRemote", R.string.RateCallSilentRemote);
|
label = LocaleController.getString("RateCallDistorted", R.string.RateCallDistorted);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
|
label = LocaleController.getString("RateCallSilentLocal", R.string.RateCallSilentLocal);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
label = LocaleController.getString("RateCallSilentRemote", R.string.RateCallSilentRemote);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
label = LocaleController.getString("RateCallDropped", R.string.RateCallDropped);
|
label = LocaleController.getString("RateCallDropped", R.string.RateCallDropped);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -367,10 +380,11 @@ public class VoIPHelper {
|
||||||
problemTags.add("#" + check.getTag());
|
problemTags.add("#" + check.getTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.rating < 5)
|
if (req.rating < 5) {
|
||||||
req.comment = commentBox.getText().toString();
|
req.comment = commentBox.getText().toString();
|
||||||
else
|
} else {
|
||||||
req.comment = "";
|
req.comment = "";
|
||||||
|
}
|
||||||
if (!problemTags.isEmpty() && !includeLogs[0]) {
|
if (!problemTags.isEmpty() && !includeLogs[0]) {
|
||||||
req.comment += " " + TextUtils.join(" ", problemTags);
|
req.comment += " " + TextUtils.join(" ", problemTags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.telegram.messenger.AndroidUtilities;
|
||||||
import org.telegram.messenger.ApplicationLoader;
|
import org.telegram.messenger.ApplicationLoader;
|
||||||
import org.telegram.messenger.FileLog;
|
import org.telegram.messenger.FileLog;
|
||||||
import org.telegram.messenger.LocaleController;
|
import org.telegram.messenger.LocaleController;
|
||||||
|
import org.telegram.messenger.NotificationCenter;
|
||||||
import org.telegram.messenger.R;
|
import org.telegram.messenger.R;
|
||||||
import org.telegram.messenger.voip.Instance;
|
import org.telegram.messenger.voip.Instance;
|
||||||
import org.telegram.messenger.voip.VideoCameraCapturer;
|
import org.telegram.messenger.voip.VideoCameraCapturer;
|
||||||
|
@ -44,7 +45,7 @@ import org.telegram.ui.Components.LayoutHelper;
|
||||||
import org.telegram.ui.LaunchActivity;
|
import org.telegram.ui.LaunchActivity;
|
||||||
import org.telegram.ui.VoIPFragment;
|
import org.telegram.ui.VoIPFragment;
|
||||||
|
|
||||||
public class VoIPPiPView implements VoIPBaseService.StateListener {
|
public class VoIPPiPView implements VoIPBaseService.StateListener, NotificationCenter.NotificationCenterDelegate {
|
||||||
|
|
||||||
public final static int ANIMATION_ENTER_TYPE_SCALE = 0;
|
public final static int ANIMATION_ENTER_TYPE_SCALE = 0;
|
||||||
public final static int ANIMATION_ENTER_TYPE_TRANSITION = 1;
|
public final static int ANIMATION_ENTER_TYPE_TRANSITION = 1;
|
||||||
|
@ -148,6 +149,7 @@ public class VoIPPiPView implements VoIPBaseService.StateListener {
|
||||||
float y = preferences.getFloat("relativeY", 0f);
|
float y = preferences.getFloat("relativeY", 0f);
|
||||||
|
|
||||||
instance.setRelativePosition(x, y);
|
instance.setRelativePosition(x, y);
|
||||||
|
NotificationCenter.getGlobalInstance().addObserver(instance, NotificationCenter.didEndCall);
|
||||||
wm.addView(instance.windowView, windowLayoutParams);
|
wm.addView(instance.windowView, windowLayoutParams);
|
||||||
|
|
||||||
instance.currentUserTextureView.renderer.init(VideoCameraCapturer.eglBase.getEglBaseContext(), null);
|
instance.currentUserTextureView.renderer.init(VideoCameraCapturer.eglBase.getEglBaseContext(), null);
|
||||||
|
@ -324,6 +326,8 @@ public class VoIPPiPView implements VoIPBaseService.StateListener {
|
||||||
VoIPService service = VoIPService.getSharedInstance();
|
VoIPService service = VoIPService.getSharedInstance();
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
service.hangUp();
|
service.hangUp();
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -353,6 +357,8 @@ public class VoIPPiPView implements VoIPBaseService.StateListener {
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
service.unregisterStateListener(this);
|
service.unregisterStateListener(this);
|
||||||
}
|
}
|
||||||
|
windowView.setVisibility(View.GONE);
|
||||||
|
if (windowView.getParent() != null) {
|
||||||
floatingView.getRelativePosition(point);
|
floatingView.getRelativePosition(point);
|
||||||
float x = Math.min(1f, Math.max(0f, point[0]));
|
float x = Math.min(1f, Math.max(0f, point[0]));
|
||||||
float y = Math.min(1f, Math.max(0f, point[1]));
|
float y = Math.min(1f, Math.max(0f, point[1]));
|
||||||
|
@ -361,15 +367,14 @@ public class VoIPPiPView implements VoIPBaseService.StateListener {
|
||||||
.putFloat("relativeX", x)
|
.putFloat("relativeX", x)
|
||||||
.putFloat("relativeY", y)
|
.putFloat("relativeY", y)
|
||||||
.apply();
|
.apply();
|
||||||
windowView.setVisibility(View.GONE);
|
|
||||||
if (windowView.getParent() != null) {
|
|
||||||
try {
|
try {
|
||||||
windowManager.removeView(windowView);
|
windowManager.removeView(windowView);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
FileLog.e(e);
|
FileLog.e(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
instance = null;
|
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didEndCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -477,6 +482,13 @@ public class VoIPPiPView implements VoIPBaseService.StateListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void didReceivedNotification(int id, int account, Object... args) {
|
||||||
|
if (id == NotificationCenter.didEndCall) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private class FloatingView extends FrameLayout {
|
private class FloatingView extends FrameLayout {
|
||||||
|
|
||||||
|
@ -762,12 +774,7 @@ public class VoIPPiPView implements VoIPBaseService.StateListener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
expandedInstance.windowView.setAlpha(0);
|
expandedInstance.windowView.setAlpha(0);
|
||||||
try {
|
expandedInstance.finishInternal();
|
||||||
windowManager.removeView(expandedInstance.windowView);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
FileLog.e(e);
|
|
||||||
}
|
|
||||||
expandedInstance = null;
|
|
||||||
expandedAnimationInProgress = false;
|
expandedAnimationInProgress = false;
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
AndroidUtilities.runOnUIThread(collapseRunnable, 3000);
|
AndroidUtilities.runOnUIThread(collapseRunnable, 3000);
|
||||||
|
|
|
@ -19,18 +19,21 @@ import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.telegram.messenger.AndroidUtilities;
|
import org.telegram.messenger.AndroidUtilities;
|
||||||
|
import org.telegram.messenger.LocaleController;
|
||||||
|
import org.telegram.messenger.R;
|
||||||
import org.telegram.ui.Components.CubicBezierInterpolator;
|
import org.telegram.ui.Components.CubicBezierInterpolator;
|
||||||
import org.telegram.ui.Components.LayoutHelper;
|
import org.telegram.ui.Components.LayoutHelper;
|
||||||
|
|
||||||
public class VoIPStatusTextView extends FrameLayout {
|
public class VoIPStatusTextView extends FrameLayout {
|
||||||
|
|
||||||
TextView[] textView = new TextView[2];
|
TextView[] textView = new TextView[2];
|
||||||
|
TextView reconnectTextView;
|
||||||
VoIPTimerView timerView;
|
VoIPTimerView timerView;
|
||||||
|
|
||||||
CharSequence nextTextToSet;
|
CharSequence nextTextToSet;
|
||||||
boolean animationInProgress;
|
boolean animationInProgress;
|
||||||
|
|
||||||
private TextAlphaSpan[] ellSpans = ellSpans = new TextAlphaSpan[]{new TextAlphaSpan(), new TextAlphaSpan(), new TextAlphaSpan()};
|
private TextAlphaSpan[] ellSpans = new TextAlphaSpan[]{new TextAlphaSpan(), new TextAlphaSpan(), new TextAlphaSpan()};
|
||||||
private AnimatorSet ellAnimator;
|
private AnimatorSet ellAnimator;
|
||||||
private boolean attachedToWindow;
|
private boolean attachedToWindow;
|
||||||
|
|
||||||
|
@ -47,6 +50,23 @@ public class VoIPStatusTextView extends FrameLayout {
|
||||||
textView[i].setGravity(Gravity.CENTER_HORIZONTAL);
|
textView[i].setGravity(Gravity.CENTER_HORIZONTAL);
|
||||||
addView(textView[i]);
|
addView(textView[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reconnectTextView = new TextView(context);
|
||||||
|
reconnectTextView.setTextSize(15);
|
||||||
|
reconnectTextView.setShadowLayer(AndroidUtilities.dp(3), 0, AndroidUtilities.dp(.666666667f), 0x4C000000);
|
||||||
|
reconnectTextView.setTextColor(Color.WHITE);
|
||||||
|
reconnectTextView.setGravity(Gravity.CENTER_HORIZONTAL);
|
||||||
|
addView(reconnectTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 22, 0, 0));
|
||||||
|
|
||||||
|
SpannableStringBuilder ssb = new SpannableStringBuilder(LocaleController.getString("VoipReconnecting", R.string.VoipReconnecting));
|
||||||
|
SpannableString ell = new SpannableString("...");
|
||||||
|
ell.setSpan(ellSpans[0], 0, 1, 0);
|
||||||
|
ell.setSpan(ellSpans[1], 1, 2, 0);
|
||||||
|
ell.setSpan(ellSpans[2], 2, 3, 0);
|
||||||
|
ssb.append(ell);
|
||||||
|
reconnectTextView.setText(ssb);
|
||||||
|
reconnectTextView.setVisibility(View.GONE);
|
||||||
|
|
||||||
timerView = new VoIPTimerView(context);
|
timerView = new VoIPTimerView(context);
|
||||||
addView(timerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
addView(timerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||||
|
|
||||||
|
@ -97,7 +117,6 @@ public class VoIPStatusTextView extends FrameLayout {
|
||||||
animated = false;
|
animated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!animated) {
|
if (!animated) {
|
||||||
if (animator != null) {
|
if (animator != null) {
|
||||||
animator.cancel();
|
animator.cancel();
|
||||||
|
@ -230,6 +249,9 @@ public class VoIPStatusTextView extends FrameLayout {
|
||||||
textView[0].invalidate();
|
textView[0].invalidate();
|
||||||
textView[1].invalidate();
|
textView[1].invalidate();
|
||||||
}
|
}
|
||||||
|
if (reconnectTextView.getVisibility() == View.VISIBLE) {
|
||||||
|
reconnectTextView.invalidate();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
a.setDuration(duration);
|
a.setDuration(duration);
|
||||||
a.setStartDelay(startDelay);
|
a.setStartDelay(startDelay);
|
||||||
|
@ -237,6 +259,29 @@ public class VoIPStatusTextView extends FrameLayout {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showReconnect(boolean showReconnecting, boolean animated) {
|
||||||
|
if (!animated) {
|
||||||
|
reconnectTextView.animate().setListener(null).cancel();
|
||||||
|
reconnectTextView.setVisibility(showReconnecting ? View.VISIBLE : View.GONE);
|
||||||
|
} else {
|
||||||
|
if (showReconnecting) {
|
||||||
|
if (reconnectTextView.getVisibility() != View.VISIBLE) {
|
||||||
|
reconnectTextView.setVisibility(View.VISIBLE);
|
||||||
|
reconnectTextView.setAlpha(0);
|
||||||
|
}
|
||||||
|
reconnectTextView.animate().setListener(null).cancel();
|
||||||
|
reconnectTextView.animate().alpha(1f).setDuration(150).start();
|
||||||
|
} else {
|
||||||
|
reconnectTextView.animate().alpha(0).setListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
reconnectTextView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}).setDuration(150).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class TextAlphaSpan extends CharacterStyle {
|
private class TextAlphaSpan extends CharacterStyle {
|
||||||
private int alpha;
|
private int alpha;
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,8 @@ public class VoIPToggleButton extends FrameLayout {
|
||||||
textView[0].setText(text);
|
textView[0].setText(text);
|
||||||
crossProgress = drawCross ? 1f : 0;
|
crossProgress = drawCross ? 1f : 0;
|
||||||
iconChangeColor = false;
|
iconChangeColor = false;
|
||||||
|
replaceProgress = 0f;
|
||||||
|
invalidate();
|
||||||
} else {
|
} else {
|
||||||
if (!iconChangeColor) {
|
if (!iconChangeColor) {
|
||||||
icon[1] = ContextCompat.getDrawable(getContext(), iconRes).mutate();
|
icon[1] = ContextCompat.getDrawable(getContext(), iconRes).mutate();
|
||||||
|
@ -299,6 +301,7 @@ public class VoIPToggleButton extends FrameLayout {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
replaceAnimator.setDuration(150).start();
|
replaceAnimator.setDuration(150).start();
|
||||||
|
invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -673,7 +673,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||||
if (BuildVars.LOGS_ENABLED) {
|
if (BuildVars.LOGS_ENABLED) {
|
||||||
FileLog.d("OS name " + os1 + " " + os2);
|
FileLog.d("OS name " + os1 + " " + os2);
|
||||||
}
|
}
|
||||||
if (os1.contains("flyme") || os2.contains("flyme")) {
|
if ((os1.contains("flyme") || os2.contains("flyme")) && Build.VERSION.SDK_INT <= 24) {
|
||||||
AndroidUtilities.incorrectDisplaySizeFix = true;
|
AndroidUtilities.incorrectDisplaySizeFix = true;
|
||||||
final View view = getWindow().getDecorView().getRootView();
|
final View view = getWindow().getDecorView().getRootView();
|
||||||
view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener = () -> {
|
view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener = () -> {
|
||||||
|
|
|
@ -364,7 +364,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
|
||||||
currentItemName = message.messageOwner.media.title;
|
currentItemName = message.messageOwner.media.title;
|
||||||
validateRequest = request;
|
validateRequest = request;
|
||||||
saveShippingInfo = true;
|
saveShippingInfo = true;
|
||||||
if (saveCard) {
|
if (saveCard || currentStep == 4) {
|
||||||
saveCardInfo = saveCard;
|
saveCardInfo = saveCard;
|
||||||
} else {
|
} else {
|
||||||
saveCardInfo = paymentForm.saved_credentials != null;
|
saveCardInfo = paymentForm.saved_credentials != null;
|
||||||
|
|
|
@ -3415,6 +3415,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
|
||||||
color2 = Theme.getColor(Theme.key_windowBackgroundWhite);
|
color2 = Theme.getColor(Theme.key_windowBackgroundWhite);
|
||||||
verifiedCheckDrawable.setColorFilter(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f), PorterDuff.Mode.MULTIPLY);
|
verifiedCheckDrawable.setColorFilter(AndroidUtilities.getOffsetColor(color1, color2, value, 1.0f), PorterDuff.Mode.MULTIPLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (avatarsViewPagerIndicatorView.getSecondaryMenuItem() != null && videoCallItemVisible) {
|
||||||
|
needLayoutText(Math.min(1f, extraHeight / AndroidUtilities.dp(88f)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3932,7 +3936,8 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
|
||||||
}
|
}
|
||||||
|
|
||||||
int viewWidth = AndroidUtilities.isTablet() ? AndroidUtilities.dp(490) : AndroidUtilities.displaySize.x;
|
int viewWidth = AndroidUtilities.isTablet() ? AndroidUtilities.dp(490) : AndroidUtilities.displaySize.x;
|
||||||
int buttonsWidth = AndroidUtilities.dp(118 + 8 + (40 + (callItemVisible || editItemVisible || searchItem != null ? 48 : 0) + (videoCallItemVisible ? 48 : 0)));
|
ActionBarMenuItem item = avatarsViewPagerIndicatorView.getSecondaryMenuItem();
|
||||||
|
int buttonsWidth = AndroidUtilities.dp(118 + 8 + (40 + (item != null ? 48 * (1.0f - mediaHeaderAnimationProgress) : 0) + (videoCallItemVisible ? 48 * (1.0f - mediaHeaderAnimationProgress) : 0)));
|
||||||
int minWidth = viewWidth - buttonsWidth;
|
int minWidth = viewWidth - buttonsWidth;
|
||||||
|
|
||||||
int width = (int) (viewWidth - buttonsWidth * Math.max(0.0f, 1.0f - (diff != 1.0f ? diff * 0.15f / (1.0f - diff) : 1.0f)) - nameTextView[1].getTranslationX());
|
int width = (int) (viewWidth - buttonsWidth * Math.max(0.0f, 1.0f - (diff != 1.0f ? diff * 0.15f / (1.0f - diff) : 1.0f)) - nameTextView[1].getTranslationX());
|
||||||
|
|
|
@ -16,12 +16,7 @@ public class VoIPFeedbackActivity extends Activity {
|
||||||
|
|
||||||
setContentView(new View(this));
|
setContentView(new View(this));
|
||||||
|
|
||||||
VoIPHelper.showRateAlert(this, new Runnable(){
|
VoIPHelper.showRateAlert(this, this::finish, getIntent().getBooleanExtra("call_video", false), getIntent().getLongExtra("call_id", 0), getIntent().getLongExtra("call_access_hash", 0), getIntent().getIntExtra("account", 0), false);
|
||||||
@Override
|
|
||||||
public void run(){
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}, getIntent().getLongExtra("call_id", 0), getIntent().getLongExtra("call_access_hash", 0), getIntent().getIntExtra("account", 0), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -202,6 +202,9 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private boolean lockOnScreen;
|
private boolean lockOnScreen;
|
||||||
|
private boolean screenWasWakeup;
|
||||||
|
|
||||||
|
private boolean isVideoCall;
|
||||||
|
|
||||||
public static void show(Activity activity) {
|
public static void show(Activity activity) {
|
||||||
show(activity, false);
|
show(activity, false);
|
||||||
|
@ -252,6 +255,15 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
instance.deviceIsLocked = ((KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE)).inKeyguardRestrictedInputMode();
|
instance.deviceIsLocked = ((KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE)).inKeyguardRestrictedInputMode();
|
||||||
|
|
||||||
|
PowerManager pm = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
|
||||||
|
boolean screenOn;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
|
||||||
|
screenOn = pm.isInteractive();
|
||||||
|
} else {
|
||||||
|
screenOn = pm.isScreenOn();
|
||||||
|
}
|
||||||
|
instance.screenWasWakeup = !screenOn;
|
||||||
windowView.setLockOnScreen(instance.deviceIsLocked);
|
windowView.setLockOnScreen(instance.deviceIsLocked);
|
||||||
fragment.windowView = windowView;
|
fragment.windowView = windowView;
|
||||||
|
|
||||||
|
@ -406,6 +418,10 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
public void didReceivedNotification(int id, int account, Object... args) {
|
public void didReceivedNotification(int id, int account, Object... args) {
|
||||||
if (id == NotificationCenter.voipServiceCreated) {
|
if (id == NotificationCenter.voipServiceCreated) {
|
||||||
if (currentState == VoIPService.STATE_BUSY && VoIPService.getSharedInstance() != null) {
|
if (currentState == VoIPService.STATE_BUSY && VoIPService.getSharedInstance() != null) {
|
||||||
|
currentUserTextureView.renderer.release();
|
||||||
|
callingUserTextureView.renderer.release();
|
||||||
|
callingUserMiniTextureRenderer.release();
|
||||||
|
initRenderers();
|
||||||
VoIPService.getSharedInstance().registerStateListener(this);
|
VoIPService.getSharedInstance().registerStateListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,6 +446,9 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
@Override
|
@Override
|
||||||
public void onMediaStateUpdated(int audioState, int videoState) {
|
public void onMediaStateUpdated(int audioState, int videoState) {
|
||||||
previousState = currentState;
|
previousState = currentState;
|
||||||
|
if (videoState == Instance.VIDEO_STATE_ACTIVE && !isVideoCall) {
|
||||||
|
isVideoCall = true;
|
||||||
|
}
|
||||||
updateViewState();
|
updateViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +461,9 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
@Override
|
@Override
|
||||||
public void onVideoAvailableChange(boolean isAvailable) {
|
public void onVideoAvailableChange(boolean isAvailable) {
|
||||||
previousState = currentState;
|
previousState = currentState;
|
||||||
|
if (isAvailable && !isVideoCall) {
|
||||||
|
isVideoCall = true;
|
||||||
|
}
|
||||||
updateViewState();
|
updateViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,7 +581,7 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
lastContentTapTime = System.currentTimeMillis();
|
lastContentTapTime = System.currentTimeMillis();
|
||||||
callingUserMiniFloatingLayout.setRelativePosition(currentUserCameraFloatingLayout);
|
callingUserMiniFloatingLayout.setRelativePosition(currentUserCameraFloatingLayout);
|
||||||
cameraForceExpanded = true;
|
cameraForceExpanded = true;
|
||||||
currentState = previousState;
|
previousState = currentState;
|
||||||
updateViewState();
|
updateViewState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -585,7 +607,7 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
lastContentTapTime = System.currentTimeMillis();
|
lastContentTapTime = System.currentTimeMillis();
|
||||||
currentUserCameraFloatingLayout.setRelativePosition(callingUserMiniFloatingLayout);
|
currentUserCameraFloatingLayout.setRelativePosition(callingUserMiniFloatingLayout);
|
||||||
cameraForceExpanded = false;
|
cameraForceExpanded = false;
|
||||||
currentState = previousState;
|
previousState = currentState;
|
||||||
updateViewState();
|
updateViewState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -700,7 +722,6 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
bottomButtons[i] = new VoIPToggleButton(context);
|
bottomButtons[i] = new VoIPToggleButton(context);
|
||||||
buttonsLayout.addView(bottomButtons[i]);
|
buttonsLayout.addView(bottomButtons[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptDeclineView = new AcceptDeclineView(context);
|
acceptDeclineView = new AcceptDeclineView(context);
|
||||||
acceptDeclineView.setListener(new AcceptDeclineView.Listener() {
|
acceptDeclineView.setListener(new AcceptDeclineView.Listener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -710,6 +731,8 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
intent.putExtra("user_id", callingUser.id);
|
intent.putExtra("user_id", callingUser.id);
|
||||||
intent.putExtra("is_outgoing", true);
|
intent.putExtra("is_outgoing", true);
|
||||||
intent.putExtra("start_incall_activity", false);
|
intent.putExtra("start_incall_activity", false);
|
||||||
|
intent.putExtra("video_call", isVideoCall);
|
||||||
|
intent.putExtra("can_video_call", isVideoCall);
|
||||||
intent.putExtra("account", UserConfig.selectedAccount);
|
intent.putExtra("account", UserConfig.selectedAccount);
|
||||||
try {
|
try {
|
||||||
activity.startService(intent);
|
activity.startService(intent);
|
||||||
|
@ -741,6 +764,7 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
acceptDeclineView.setScreenWasWakeup(screenWasWakeup);
|
||||||
|
|
||||||
frameLayout.addView(buttonsLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
|
frameLayout.addView(buttonsLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
|
||||||
frameLayout.addView(acceptDeclineView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 186, Gravity.BOTTOM));
|
frameLayout.addView(acceptDeclineView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 186, Gravity.BOTTOM));
|
||||||
|
@ -789,11 +813,19 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
|
|
||||||
VoIPService service = VoIPService.getSharedInstance();
|
VoIPService service = VoIPService.getSharedInstance();
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
|
if (!isVideoCall) {
|
||||||
|
isVideoCall = service.call != null && service.call.video;
|
||||||
|
}
|
||||||
|
initRenderers();
|
||||||
|
}
|
||||||
|
|
||||||
|
return frameLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initRenderers() {
|
||||||
if (VideoCameraCapturer.eglBase == null) {
|
if (VideoCameraCapturer.eglBase == null) {
|
||||||
VideoCameraCapturer.eglBase = EglBase.create(null, EglBase.CONFIG_PLAIN);
|
VideoCameraCapturer.eglBase = EglBase.create(null, EglBase.CONFIG_PLAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentUserTextureView.renderer.init(VideoCameraCapturer.eglBase.getEglBaseContext(), new RendererCommon.RendererEvents() {
|
currentUserTextureView.renderer.init(VideoCameraCapturer.eglBase.getEglBaseContext(), new RendererCommon.RendererEvents() {
|
||||||
@Override
|
@Override
|
||||||
public void onFirstFrameRendered() {
|
public void onFirstFrameRendered() {
|
||||||
|
@ -822,9 +854,6 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
callingUserMiniTextureRenderer.init(VideoCameraCapturer.eglBase.getEglBaseContext(), null);
|
callingUserMiniTextureRenderer.init(VideoCameraCapturer.eglBase.getEglBaseContext(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void switchToPip() {
|
public void switchToPip() {
|
||||||
if (isFinished || !AndroidUtilities.checkInlinePermissions(activity) || instance == null) {
|
if (isFinished || !AndroidUtilities.checkInlinePermissions(activity) || instance == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -907,6 +936,7 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
notificationsLayout.setAlpha(0f);
|
notificationsLayout.setAlpha(0f);
|
||||||
callingUserPhotoView.setAlpha(0f);
|
callingUserPhotoView.setAlpha(0f);
|
||||||
|
|
||||||
|
currentUserCameraFloatingLayout.switchingToPip = true;
|
||||||
AndroidUtilities.runOnUIThread(() -> {
|
AndroidUtilities.runOnUIThread(() -> {
|
||||||
VoIPPiPView.switchingToPip = false;
|
VoIPPiPView.switchingToPip = false;
|
||||||
VoIPPiPView.finish();
|
VoIPPiPView.finish();
|
||||||
|
@ -921,7 +951,6 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
notificationsLayout.animate().alpha(1f).setDuration(350).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
notificationsLayout.animate().alpha(1f).setDuration(350).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
||||||
callingUserPhotoView.animate().alpha(1f).setDuration(350).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
callingUserPhotoView.animate().alpha(1f).setDuration(350).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
||||||
|
|
||||||
currentUserCameraFloatingLayout.switchingToPip = true;
|
|
||||||
animator.addListener(new AnimatorListenerAdapter() {
|
animator.addListener(new AnimatorListenerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
@ -936,8 +965,8 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
animator.setDuration(350);
|
animator.setDuration(350);
|
||||||
animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||||
animator.start();
|
animator.start();
|
||||||
}, 64);
|
}, 32);
|
||||||
}, 64);
|
}, 32);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,6 +1142,7 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
boolean animated = previousState != -1;
|
boolean animated = previousState != -1;
|
||||||
boolean showAcceptDeclineView = false;
|
boolean showAcceptDeclineView = false;
|
||||||
boolean showTimer = false;
|
boolean showTimer = false;
|
||||||
|
boolean showReconnecting = false;
|
||||||
boolean showCallingAvatarMini = false;
|
boolean showCallingAvatarMini = false;
|
||||||
int statusLayoutOffset = 0;
|
int statusLayoutOffset = 0;
|
||||||
|
|
||||||
|
@ -1120,6 +1150,9 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
callingUserIsVideo = service.getCurrentVideoState() == Instance.VIDEO_STATE_ACTIVE;
|
callingUserIsVideo = service.getCurrentVideoState() == Instance.VIDEO_STATE_ACTIVE;
|
||||||
currentUserIsVideo = service.getVideoState() == Instance.VIDEO_STATE_ACTIVE || service.getVideoState() == Instance.VIDEO_STATE_PAUSED;
|
currentUserIsVideo = service.getVideoState() == Instance.VIDEO_STATE_ACTIVE || service.getVideoState() == Instance.VIDEO_STATE_PAUSED;
|
||||||
|
if (currentUserIsVideo && !isVideoCall) {
|
||||||
|
isVideoCall = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animated) {
|
if (animated) {
|
||||||
|
@ -1134,7 +1167,7 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
statusLayoutOffset = AndroidUtilities.dp(24);
|
statusLayoutOffset = AndroidUtilities.dp(24);
|
||||||
acceptDeclineView.setRetryMod(false);
|
acceptDeclineView.setRetryMod(false);
|
||||||
if (service != null && service.call.video) {
|
if (service != null && service.call.video) {
|
||||||
if (currentUserIsVideo) {
|
if (currentUserIsVideo && callingUser.photo != null) {
|
||||||
showCallingAvatarMini = true;
|
showCallingAvatarMini = true;
|
||||||
} else {
|
} else {
|
||||||
showCallingAvatarMini = false;
|
showCallingAvatarMini = false;
|
||||||
|
@ -1177,6 +1210,9 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
updateKeyView(animated);
|
updateKeyView(animated);
|
||||||
}
|
}
|
||||||
showTimer = true;
|
showTimer = true;
|
||||||
|
if (currentState == VoIPService.STATE_RECONNECTING) {
|
||||||
|
showReconnecting = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case VoIPBaseService.STATE_ENDED:
|
case VoIPBaseService.STATE_ENDED:
|
||||||
currentUserTextureView.saveCameraLastBitmap();
|
currentUserTextureView.saveCameraLastBitmap();
|
||||||
|
@ -1192,9 +1228,42 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
final String message = LocaleController.formatString("VoipPeerIncompatible", R.string.VoipPeerIncompatible, name);
|
final String message = LocaleController.formatString("VoipPeerIncompatible", R.string.VoipPeerIncompatible, name);
|
||||||
showErrorDialog(AndroidUtilities.replaceTags(message));
|
showErrorDialog(AndroidUtilities.replaceTags(message));
|
||||||
} else if (TextUtils.equals(lastError, Instance.ERROR_PEER_OUTDATED)) {
|
} else if (TextUtils.equals(lastError, Instance.ERROR_PEER_OUTDATED)) {
|
||||||
final String name = ContactsController.formatName(callingUser.first_name, callingUser.last_name);
|
if (isVideoCall) {
|
||||||
|
final String name = UserObject.getFirstName(callingUser);
|
||||||
|
final String message = LocaleController.formatString("VoipPeerVideoOutdated", R.string.VoipPeerVideoOutdated, name);
|
||||||
|
boolean[] callAgain = new boolean[1];
|
||||||
|
AlertDialog dlg = new DarkAlertDialog.Builder(activity)
|
||||||
|
.setTitle(LocaleController.getString("VoipFailed", R.string.VoipFailed))
|
||||||
|
.setMessage(AndroidUtilities.replaceTags(message))
|
||||||
|
.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), (dialogInterface, i) -> windowView.finish())
|
||||||
|
.setPositiveButton(LocaleController.getString("VoipPeerVideoOutdatedMakeVoice", R.string.VoipPeerVideoOutdatedMakeVoice), (dialogInterface, i) -> {
|
||||||
|
callAgain[0] = true;
|
||||||
|
currentState = VoIPService.STATE_BUSY;
|
||||||
|
Intent intent = new Intent(activity, VoIPService.class);
|
||||||
|
intent.putExtra("user_id", callingUser.id);
|
||||||
|
intent.putExtra("is_outgoing", true);
|
||||||
|
intent.putExtra("start_incall_activity", false);
|
||||||
|
intent.putExtra("video_call", false);
|
||||||
|
intent.putExtra("can_video_call", false);
|
||||||
|
intent.putExtra("account", UserConfig.selectedAccount);
|
||||||
|
try {
|
||||||
|
activity.startService(intent);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
FileLog.e(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
dlg.setCanceledOnTouchOutside(true);
|
||||||
|
dlg.setOnDismissListener(dialog -> {
|
||||||
|
if (!callAgain[0]) {
|
||||||
|
windowView.finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
final String name = UserObject.getFirstName(callingUser);
|
||||||
final String message = LocaleController.formatString("VoipPeerOutdated", R.string.VoipPeerOutdated, name);
|
final String message = LocaleController.formatString("VoipPeerOutdated", R.string.VoipPeerOutdated, name);
|
||||||
showErrorDialog(AndroidUtilities.replaceTags(message));
|
showErrorDialog(AndroidUtilities.replaceTags(message));
|
||||||
|
}
|
||||||
} else if (TextUtils.equals(lastError, Instance.ERROR_PRIVACY)) {
|
} else if (TextUtils.equals(lastError, Instance.ERROR_PRIVACY)) {
|
||||||
final String name = ContactsController.formatName(callingUser.first_name, callingUser.last_name);
|
final String name = ContactsController.formatName(callingUser.first_name, callingUser.last_name);
|
||||||
final String message = LocaleController.formatString("CallNotAvailable", R.string.CallNotAvailable, name);
|
final String message = LocaleController.formatString("CallNotAvailable", R.string.CallNotAvailable, name);
|
||||||
|
@ -1286,12 +1355,17 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
backIcon.setAlpha(lockOnScreen ? 0 : 1f);
|
backIcon.setAlpha(lockOnScreen ? 0 : 1f);
|
||||||
notificationsLayout.setTranslationY(-AndroidUtilities.dp(16) - (uiVisible ? AndroidUtilities.dp(80) : 0));
|
notificationsLayout.setTranslationY(-AndroidUtilities.dp(16) - (uiVisible ? AndroidUtilities.dp(80) : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentState != VoIPService.STATE_HANGING_UP && currentState != VoIPService.STATE_ENDED) {
|
||||||
updateButtons(animated);
|
updateButtons(animated);
|
||||||
|
}
|
||||||
|
|
||||||
if (showTimer) {
|
if (showTimer) {
|
||||||
statusTextView.showTimer(animated);
|
statusTextView.showTimer(animated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statusTextView.showReconnect(showReconnecting, animated);
|
||||||
|
|
||||||
if (animated) {
|
if (animated) {
|
||||||
if (statusLayoutOffset != statusLayoutAnimateToOffset) {
|
if (statusLayoutOffset != statusLayoutAnimateToOffset) {
|
||||||
statusLayout.animate().translationY(statusLayoutOffset).setDuration(150).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
statusLayout.animate().translationY(statusLayoutOffset).setDuration(150).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
||||||
|
@ -1749,6 +1823,7 @@ public class VoIPFragment implements VoIPBaseService.StateListener, Notification
|
||||||
view.announceForAccessibility(text);
|
view.announceForAccessibility(text);
|
||||||
}
|
}
|
||||||
serviceInstance.setMicMute(micMute);
|
serviceInstance.setMicMute(micMute);
|
||||||
|
previousState = currentState;
|
||||||
updateViewState();
|
updateViewState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -63,9 +63,9 @@ public class GlShader {
|
||||||
// part of the program object."
|
// part of the program object."
|
||||||
// But in practice, detaching shaders from the program seems to break some devices. Deleting the
|
// But in practice, detaching shaders from the program seems to break some devices. Deleting the
|
||||||
// shaders are fine however - it will delete them when they are no longer attached to a program.
|
// shaders are fine however - it will delete them when they are no longer attached to a program.
|
||||||
GLES20.glDeleteShader(vertexShader);
|
//GLES20.glDeleteShader(vertexShader); delete crashes on xiaomi
|
||||||
GLES20.glDeleteShader(fragmentShader);
|
//GLES20.glDeleteShader(fragmentShader);
|
||||||
GlUtil.checkNoGLES2Error("Creating GlShader");
|
//GlUtil.checkNoGLES2Error("Creating GlShader");
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAttribLocation(String label) {
|
public int getAttribLocation(String label) {
|
||||||
|
|
|
@ -11,8 +11,10 @@
|
||||||
package org.webrtc;
|
package org.webrtc;
|
||||||
|
|
||||||
import android.media.MediaCodecInfo;
|
import android.media.MediaCodecInfo;
|
||||||
|
|
||||||
|
import org.telegram.messenger.voip.Instance;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/** Factory for Android hardware VideoDecoders. */
|
/** Factory for Android hardware VideoDecoders. */
|
||||||
public class HardwareVideoDecoderFactory extends MediaCodecVideoDecoderFactory {
|
public class HardwareVideoDecoderFactory extends MediaCodecVideoDecoderFactory {
|
||||||
|
@ -20,7 +22,27 @@ public class HardwareVideoDecoderFactory extends MediaCodecVideoDecoderFactory {
|
||||||
new Predicate<MediaCodecInfo>() {
|
new Predicate<MediaCodecInfo>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(MediaCodecInfo arg) {
|
public boolean test(MediaCodecInfo arg) {
|
||||||
return MediaCodecUtils.isHardwareAccelerated(arg);
|
if (!MediaCodecUtils.isHardwareAccelerated(arg)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String[] types = arg.getSupportedTypes();
|
||||||
|
if (types == null || types.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Instance.ServerConfig config = Instance.getGlobalServerConfig();
|
||||||
|
for (int a = 0; a < types.length; a++) {
|
||||||
|
switch (types[a]) {
|
||||||
|
case "video/x-vnd.on2.vp8":
|
||||||
|
return config.enable_vp8_decoder;
|
||||||
|
case "video/x-vnd.on2.vp9":
|
||||||
|
return config.enable_vp9_decoder;
|
||||||
|
case "video/avc":
|
||||||
|
return config.enable_h264_decoder;
|
||||||
|
case "video/hevc":
|
||||||
|
return config.enable_h265_decoder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@ import static org.webrtc.MediaCodecUtils.HISI_PREFIX;
|
||||||
import android.media.MediaCodecInfo;
|
import android.media.MediaCodecInfo;
|
||||||
import android.media.MediaCodecList;
|
import android.media.MediaCodecList;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
|
import org.telegram.messenger.voip.Instance;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/** Factory for android hardware video encoders. */
|
/** Factory for android hardware video encoders. */
|
||||||
@SuppressWarnings("deprecation") // API 16 requires the use of deprecated methods.
|
@SuppressWarnings("deprecation") // API 16 requires the use of deprecated methods.
|
||||||
|
@ -40,63 +40,6 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||||
private final boolean enableH264HighProfile;
|
private final boolean enableH264HighProfile;
|
||||||
@Nullable private final Predicate<MediaCodecInfo> codecAllowedPredicate;
|
@Nullable private final Predicate<MediaCodecInfo> codecAllowedPredicate;
|
||||||
|
|
||||||
private static final List<String> H264_HW_EXCEPTION_MODELS =
|
|
||||||
Arrays.asList("samsung-sgh-i337", "nexus7", "nexus4", "pixel3xl", "pixel3");
|
|
||||||
|
|
||||||
private static final List<String> VP8_HW_EXCEPTION_MODELS =
|
|
||||||
Arrays.asList("pixel3xl", "pixel3");
|
|
||||||
|
|
||||||
private static Set<String> HW_EXCEPTION_MODELS = new HashSet<String>() {{
|
|
||||||
add("sm-a310f");
|
|
||||||
add("sm-a310f/ds");
|
|
||||||
add("sm-a310y");
|
|
||||||
add("sm-a310m");
|
|
||||||
add("sm-g920f");
|
|
||||||
add("sm-g920fd");
|
|
||||||
add("sm-g920fq");
|
|
||||||
add("sm-g920i");
|
|
||||||
add("sm-g920a");
|
|
||||||
add("sm-g920t");
|
|
||||||
add("sm-g930f");
|
|
||||||
add("sm-g930fd");
|
|
||||||
add("sm-g930w8");
|
|
||||||
add("sm-g930s");
|
|
||||||
add("sm-g930k");
|
|
||||||
add("sm-g930l");
|
|
||||||
add("sm-g935f");
|
|
||||||
add("sm-g935fd");
|
|
||||||
add("sm-g935w8");
|
|
||||||
add("sm-g935s");
|
|
||||||
add("sm-g935k");
|
|
||||||
add("sm-g935l");
|
|
||||||
|
|
||||||
add("i537");
|
|
||||||
add("sgh-i537");
|
|
||||||
add("gt-i9295");
|
|
||||||
add("sgh-i337");
|
|
||||||
add("gt-i9505g");
|
|
||||||
add("gt-i9505");
|
|
||||||
add("gt-i9515");
|
|
||||||
add("f240");
|
|
||||||
add("e980");
|
|
||||||
add("ls980");
|
|
||||||
add("e988");
|
|
||||||
add("e986");
|
|
||||||
add("f240l");
|
|
||||||
add("f240s");
|
|
||||||
add("v9815");
|
|
||||||
add("nx403a");
|
|
||||||
add("f310l");
|
|
||||||
add("f310lr");
|
|
||||||
add("onem7");
|
|
||||||
add("onemax");
|
|
||||||
add("pn071");
|
|
||||||
add("htc6500lvw");
|
|
||||||
add("butterflys");
|
|
||||||
add("mi2s");
|
|
||||||
add("n1");
|
|
||||||
}};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a HardwareVideoEncoderFactory that supports surface texture encoding.
|
* Creates a HardwareVideoEncoderFactory that supports surface texture encoding.
|
||||||
*
|
*
|
||||||
|
@ -249,13 +192,9 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||||
|
|
||||||
// Returns true if the given MediaCodecInfo indicates a hardware module that is supported on the
|
// Returns true if the given MediaCodecInfo indicates a hardware module that is supported on the
|
||||||
// current SDK.
|
// current SDK.
|
||||||
|
|
||||||
private static String getModel() {
|
|
||||||
return Build.MODEL != null ? Build.MODEL.toLowerCase().replace(" ", "") : "nomodel";
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isHardwareSupportedInCurrentSdk(MediaCodecInfo info, VideoCodecMimeType type) {
|
private boolean isHardwareSupportedInCurrentSdk(MediaCodecInfo info, VideoCodecMimeType type) {
|
||||||
if (HW_EXCEPTION_MODELS.contains(getModel())) {
|
Instance.ServerConfig config = Instance.getGlobalServerConfig();
|
||||||
|
if (!config.enable_h264_encoder && !config.enable_h265_encoder && !config.enable_vp8_encoder && !config.enable_vp9_encoder) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -272,7 +211,7 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHardwareSupportedInCurrentSdkVp8(MediaCodecInfo info) {
|
private boolean isHardwareSupportedInCurrentSdkVp8(MediaCodecInfo info) {
|
||||||
if (VP8_HW_EXCEPTION_MODELS.contains(getModel())) {
|
if (!Instance.getGlobalServerConfig().enable_vp8_encoder) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String name = info.getName();
|
String name = info.getName();
|
||||||
|
@ -288,6 +227,9 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHardwareSupportedInCurrentSdkVp9(MediaCodecInfo info) {
|
private boolean isHardwareSupportedInCurrentSdkVp9(MediaCodecInfo info) {
|
||||||
|
if (!Instance.getGlobalServerConfig().enable_vp9_encoder) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
String name = info.getName();
|
String name = info.getName();
|
||||||
return (name.startsWith(QCOM_PREFIX) || name.startsWith(EXYNOS_PREFIX) || name.startsWith(HISI_PREFIX))
|
return (name.startsWith(QCOM_PREFIX) || name.startsWith(EXYNOS_PREFIX) || name.startsWith(HISI_PREFIX))
|
||||||
// Both QCOM and Exynos VP9 encoders are supported in N or later.
|
// Both QCOM and Exynos VP9 encoders are supported in N or later.
|
||||||
|
@ -295,8 +237,7 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHardwareSupportedInCurrentSdkH264(MediaCodecInfo info) {
|
private boolean isHardwareSupportedInCurrentSdkH264(MediaCodecInfo info) {
|
||||||
// First, H264 hardware might perform poorly on this model.
|
if (!Instance.getGlobalServerConfig().enable_h264_encoder) {
|
||||||
if (H264_HW_EXCEPTION_MODELS.contains(getModel())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String name = info.getName();
|
String name = info.getName();
|
||||||
|
@ -308,6 +249,9 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHardwareSupportedInCurrentSdkH265(MediaCodecInfo info) {
|
private boolean isHardwareSupportedInCurrentSdkH265(MediaCodecInfo info) {
|
||||||
|
if (!Instance.getGlobalServerConfig().enable_h265_encoder) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
String name = info.getName();
|
String name = info.getName();
|
||||||
// QCOM H265 encoder is supported in KITKAT or later.
|
// QCOM H265 encoder is supported in KITKAT or later.
|
||||||
return (name.startsWith(QCOM_PREFIX) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
return (name.startsWith(QCOM_PREFIX) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||||
|
|
BIN
TMessagesProj/src/main/res/drawable-hdpi/call_arrow_right.png
Normal file
BIN
TMessagesProj/src/main/res/drawable-hdpi/call_arrow_right.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 294 B |
BIN
TMessagesProj/src/main/res/drawable-mdpi/call_arrow_right.png
Normal file
BIN
TMessagesProj/src/main/res/drawable-mdpi/call_arrow_right.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 212 B |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/call_arrow_right.png
Normal file
BIN
TMessagesProj/src/main/res/drawable-xhdpi/call_arrow_right.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 B |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/call_arrow_right.png
Normal file
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/call_arrow_right.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 516 B |
|
@ -3023,6 +3023,8 @@
|
||||||
<string name="NoCallLog">You haven\'t made any calls yet.</string>
|
<string name="NoCallLog">You haven\'t made any calls yet.</string>
|
||||||
<string name="VoipPeerIncompatible">**%1$s**\'s app is using an incompatible protocol. They need to update their app before you can call them.</string>
|
<string name="VoipPeerIncompatible">**%1$s**\'s app is using an incompatible protocol. They need to update their app before you can call them.</string>
|
||||||
<string name="VoipPeerOutdated">**%1$s**\'s app does not support calls. They need to update their app before you can call them.</string>
|
<string name="VoipPeerOutdated">**%1$s**\'s app does not support calls. They need to update their app before you can call them.</string>
|
||||||
|
<string name="VoipPeerVideoOutdated">Sorry, **%1$s** is using an old version of Telegram that doesn\'t support video calls.</string>
|
||||||
|
<string name="VoipPeerVideoOutdatedMakeVoice">Make a voice call</string>
|
||||||
<string name="VoipRateCallAlert">Please rate the quality of your Telegram call</string>
|
<string name="VoipRateCallAlert">Please rate the quality of your Telegram call</string>
|
||||||
<string name="VoipNeedMicPermission">Telegram needs access to your microphone so that you can make calls.</string>
|
<string name="VoipNeedMicPermission">Telegram needs access to your microphone so that you can make calls.</string>
|
||||||
<string name="VoipNeedMicCameraPermission">Telegram needs access to your microphone and camera so that you can make video calls.</string>
|
<string name="VoipNeedMicCameraPermission">Telegram needs access to your microphone and camera so that you can make video calls.</string>
|
||||||
|
@ -3065,6 +3067,8 @@
|
||||||
<string name="RateCallSilentLocal">I couldn\'t hear the other side</string>
|
<string name="RateCallSilentLocal">I couldn\'t hear the other side</string>
|
||||||
<string name="RateCallSilentRemote">The other side couldn\'t hear me</string>
|
<string name="RateCallSilentRemote">The other side couldn\'t hear me</string>
|
||||||
<string name="RateCallDropped">Call ended unexpectedly</string>
|
<string name="RateCallDropped">Call ended unexpectedly</string>
|
||||||
|
<string name="RateCallVideoDistorted">Video was distorted</string>
|
||||||
|
<string name="RateCallVideoPixelated">Video was pixelated</string>
|
||||||
<string name="TapToTurnCamera">Tap here to turn on your camera</string>
|
<string name="TapToTurnCamera">Tap here to turn on your camera</string>
|
||||||
<string name="VoipUnmute">Unmute</string>
|
<string name="VoipUnmute">Unmute</string>
|
||||||
<string name="VoipMute">Mute</string>
|
<string name="VoipMute">Mute</string>
|
||||||
|
@ -3676,4 +3680,5 @@
|
||||||
<string name="RemindTodayAt">\'Remind today at\' HH:mm</string>
|
<string name="RemindTodayAt">\'Remind today at\' HH:mm</string>
|
||||||
<string name="RemindDayAt">\'Remind on\' MMM d \'at\' HH:mm</string>
|
<string name="RemindDayAt">\'Remind on\' MMM d \'at\' HH:mm</string>
|
||||||
<string name="RemindDayYearAt">\'Remind on\' MMM d yyyy \'at\' HH:mm</string>
|
<string name="RemindDayYearAt">\'Remind on\' MMM d yyyy \'at\' HH:mm</string>
|
||||||
|
<string name="VoipReconnecting">Reconnecting</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue