diff --git a/Dockerfile b/Dockerfile index 0b2fdb403..91e717381 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ -FROM gradle:6.7.1-jdk8 +FROM gradle:6.7.1-jdk11 -ENV ANDROID_SDK_URL https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip -ENV ANDROID_API_LEVEL android-30 -ENV ANDROID_BUILD_TOOLS_VERSION 30.0.3 +ENV ANDROID_SDK_URL https://dl.google.com/android/repository/commandlinetools-linux-7302050_latest.zip +ENV ANDROID_API_LEVEL android-31 +ENV ANDROID_BUILD_TOOLS_VERSION 31.0.0 ENV ANDROID_HOME /usr/local/android-sdk-linux ENV ANDROID_NDK_VERSION 21.4.7075529 -ENV ANDROID_VERSION 30 +ENV ANDROID_VERSION 31 ENV ANDROID_NDK_HOME ${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}/ ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools @@ -15,12 +15,15 @@ RUN mkdir "$ANDROID_HOME" .android && \ unzip sdk.zip && \ rm sdk.zip -RUN yes | ${ANDROID_HOME}/tools/bin/sdkmanager --licenses -RUN $ANDROID_HOME/tools/bin/sdkmanager --update -RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \ +RUN yes | ${ANDROID_HOME}/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_HOME --licenses +RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_HOME --update +RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_HOME "build-tools;30.0.3" \ + "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \ "platforms;android-${ANDROID_VERSION}" \ "platform-tools" \ "ndk;$ANDROID_NDK_VERSION" +RUN cp $ANDROID_HOME/build-tools/30.0.3/dx $ANDROID_HOME/build-tools/31.0.0/dx +RUN cp $ANDROID_HOME/build-tools/30.0.3/lib/dx.jar $ANDROID_HOME/build-tools/31.0.0/lib/dx.jar ENV PATH ${ANDROID_NDK_HOME}:$PATH ENV PATH ${ANDROID_NDK_HOME}/prebuilt/linux-x86_64/bin/:$PATH diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 88a35410f..557fa34ec 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -42,8 +42,8 @@ dependencies { } android { - compileSdkVersion 30 - buildToolsVersion '30.0.3' + compileSdkVersion 31 + buildToolsVersion '31.0.0' ndkVersion "21.4.7075529" defaultConfig.applicationId = "org.telegram.messenger" @@ -299,7 +299,7 @@ android { } } - defaultConfig.versionCode = 2372 + defaultConfig.versionCode = 2376 applicationVariants.all { variant -> variant.outputs.all { output -> @@ -318,7 +318,7 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 29 - versionName "7.8.1" + versionName "7.8.2" vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi'] diff --git a/TMessagesProj/jni/tgnet/Handshake.cpp b/TMessagesProj/jni/tgnet/Handshake.cpp index 233b96902..a9fd6bf15 100644 --- a/TMessagesProj/jni/tgnet/Handshake.cpp +++ b/TMessagesProj/jni/tgnet/Handshake.cpp @@ -482,7 +482,7 @@ void Handshake::processHandshakeResponse(TLObject *message, int64_t messageId) { uint32_t paddedDataSize = 192; uint32_t encryptedDataSize = keySize + paddedDataSize + SHA256_DIGEST_LENGTH; uint32_t additionalSize = innerDataSize < paddedDataSize ? paddedDataSize - innerDataSize : 0; - NativeByteBuffer *innerDataBuffer = BuffersStorage::getInstance().getFreeBuffer(encryptedDataSize + paddedDataSize + ivSize + SHA256_DIGEST_LENGTH); + NativeByteBuffer *innerDataBuffer = BuffersStorage::getInstance().getFreeBuffer(encryptedDataSize + paddedDataSize + ivSize + SHA256_DIGEST_LENGTH + 256); innerDataBuffer->position(encryptedDataSize); innerData->serializeToStream(innerDataBuffer); @@ -518,12 +518,13 @@ void Handshake::processHandshakeResponse(TLObject *message, int64_t messageId) { } bool ok = false; - size_t resLen = BN_bn2bin(rsaKey->n, innerDataBuffer->bytes() + encryptedDataSize); + uint32_t offset = encryptedDataSize + paddedDataSize + ivSize + SHA256_DIGEST_LENGTH; + size_t resLen = BN_bn2bin(rsaKey->n, innerDataBuffer->bytes() + offset); const auto shift = (256 - resLen); for (auto i = 0; i != 256; ++i) { const auto a = innerDataBuffer->bytes()[i]; - const auto b = (i < shift) ? 0 : innerDataBuffer->bytes()[encryptedDataSize + i - shift]; + const auto b = (i < shift) ? 0 : innerDataBuffer->bytes()[offset + i - shift]; if (a > b) { break; } else if (a < b) { @@ -544,9 +545,9 @@ void Handshake::processHandshakeResponse(TLObject *message, int64_t messageId) { BN_mod_exp(r, a, rsaKey->e, rsaKey->n, bnContext); uint32_t size = BN_num_bytes(r); auto rsaEncryptedData = new ByteArray(size >= 256 ? size : 256); - size_t resLen = BN_bn2bin(r, rsaEncryptedData->bytes); - if (256 - resLen > 0) { - memset(rsaEncryptedData->bytes + resLen, 0, 256 - resLen); + BN_bn2bin(r, rsaEncryptedData->bytes + (size < 256 ? (256 - size) : 0)); + if (256 - size > 0) { + memset(rsaEncryptedData->bytes, 0, 256 - size); } BN_free(a); BN_free(r); diff --git a/TMessagesProj/jni/voip/CMakeLists.txt b/TMessagesProj/jni/voip/CMakeLists.txt index 6c3ca4fa0..b958ca0b9 100644 --- a/TMessagesProj/jni/voip/CMakeLists.txt +++ b/TMessagesProj/jni/voip/CMakeLists.txt @@ -911,6 +911,8 @@ add_library(tgcalls STATIC voip/tgcalls/VideoCaptureInterface.cpp voip/tgcalls/VideoCaptureInterfaceImpl.cpp voip/tgcalls/AudioDeviceHelper.cpp + voip/tgcalls/SctpDataChannelProviderInterfaceImpl.cpp + voip/tgcalls/TurnCustomizerImpl.cpp voip/tgcalls/reference/InstanceImplReference.cpp voip/tgcalls/legacy/InstanceImplLegacy.cpp voip/tgcalls/group/GroupNetworkManager.cpp diff --git a/TMessagesProj/jni/voip/tgcalls/CodecSelectHelper.cpp b/TMessagesProj/jni/voip/tgcalls/CodecSelectHelper.cpp index 7fe0f50d4..ebf30427f 100644 --- a/TMessagesProj/jni/voip/tgcalls/CodecSelectHelper.cpp +++ b/TMessagesProj/jni/voip/tgcalls/CodecSelectHelper.cpp @@ -45,7 +45,7 @@ int FormatPriority(const VideoFormat &format, const std::vector &pr } return result; }(); - + for (int i = 0; i < preferredCodecs.size(); i++) { for (const auto &name : kSupported) { if (absl::EqualsIgnoreCase(format.name, preferredCodecs[i]) && absl::EqualsIgnoreCase(format.name, name)) { @@ -114,12 +114,6 @@ std::vector::const_iterator FindEqualFormat( }); } -bool ContainsEqualFormat( - const std::vector &list, - const VideoFormat &format) { - return FindEqualFormat(list, format) != list.end(); -} - void AddDefaultFeedbackParams(cricket::VideoCodec *codec) { // Don't add any feedback params for RED and ULPFEC. if (codec->name == cricket::kRedCodecName || codec->name == cricket::kUlpfecCodecName) diff --git a/TMessagesProj/jni/voip/tgcalls/EncryptedConnection.cpp b/TMessagesProj/jni/voip/tgcalls/EncryptedConnection.cpp index d350299e4..61f561ca5 100644 --- a/TMessagesProj/jni/voip/tgcalls/EncryptedConnection.cpp +++ b/TMessagesProj/jni/voip/tgcalls/EncryptedConnection.cpp @@ -285,7 +285,6 @@ void EncryptedConnection::appendAdditionalMessages(rtc::CopyOnWriteBuffer &buffe } const auto now = rtc::TimeMillis(); - auto someWereNotAdded = false; for (auto &resending : _myNotYetAckedMessages) { const auto sent = resending.lastSent; const auto when = sent @@ -471,6 +470,7 @@ auto EncryptedConnection::processPacket( } const auto success = reader.ReadUInt32(¤tSeq); assert(success); + (void)success; currentCounter = CounterFromSeq(currentSeq); additionalMessage = true; diff --git a/TMessagesProj/jni/voip/tgcalls/Message.cpp b/TMessagesProj/jni/voip/tgcalls/Message.cpp index 56d9ead66..7ee4c5332 100644 --- a/TMessagesProj/jni/voip/tgcalls/Message.cpp +++ b/TMessagesProj/jni/voip/tgcalls/Message.cpp @@ -72,6 +72,7 @@ void Serialize(rtc::ByteBufferWriter &to, const cricket::Candidate &from) { std::string serialized; const auto success = iceCandidate.ToString(&serialized); assert(success); + (void)success; Serialize(to, serialized); } diff --git a/TMessagesProj/jni/voip/tgcalls/NetworkManager.cpp b/TMessagesProj/jni/voip/tgcalls/NetworkManager.cpp index 72f815664..f84fa54dc 100644 --- a/TMessagesProj/jni/voip/tgcalls/NetworkManager.cpp +++ b/TMessagesProj/jni/voip/tgcalls/NetworkManager.cpp @@ -12,6 +12,7 @@ #include "api/jsep_ice_candidate.h" #include "rtc_base/network_monitor_factory.h" +#include "TurnCustomizerImpl.h" #include "platform/PlatformInterface.h" extern "C" { @@ -61,24 +62,6 @@ private: std::string _value; }; -class TurnCustomizerImpl : public webrtc::TurnCustomizer { -public: - TurnCustomizerImpl() { - } - - virtual ~TurnCustomizerImpl() { - } - - void MaybeModifyOutgoingStunMessage(cricket::PortInterface* port, - cricket::StunMessage* message) override { - message->AddAttribute(std::make_unique(cricket::STUN_ATTR_SOFTWARE, "Telegram ")); - } - - bool AllowChannelData(cricket::PortInterface* port, const void *data, size_t size, bool payload) override { - return true; - } -}; - NetworkManager::NetworkManager( rtc::Thread *thread, EncryptionKey encryptionKey, diff --git a/TMessagesProj/jni/voip/tgcalls/SctpDataChannelProviderInterfaceImpl.cpp b/TMessagesProj/jni/voip/tgcalls/SctpDataChannelProviderInterfaceImpl.cpp new file mode 100644 index 000000000..27f7d063d --- /dev/null +++ b/TMessagesProj/jni/voip/tgcalls/SctpDataChannelProviderInterfaceImpl.cpp @@ -0,0 +1,158 @@ +#include "SctpDataChannelProviderInterfaceImpl.h" + +#include "p2p/base/dtls_transport.h" + +namespace tgcalls { + +SctpDataChannelProviderInterfaceImpl::SctpDataChannelProviderInterfaceImpl( + cricket::DtlsTransport *transportChannel, + bool isOutgoing, + std::function onStateChanged, + std::function onTerminated, + std::function onMessageReceived, + std::shared_ptr threads +) : +_threads(std::move(threads)), +_onStateChanged(onStateChanged), +_onTerminated(onTerminated), +_onMessageReceived(onMessageReceived) { + assert(_threads->getNetworkThread()->IsCurrent()); + + _sctpTransportFactory.reset(new cricket::SctpTransportFactory(_threads->getNetworkThread())); + + _sctpTransport = _sctpTransportFactory->CreateSctpTransport(transportChannel); + _sctpTransport->SignalReadyToSendData.connect(this, &SctpDataChannelProviderInterfaceImpl::sctpReadyToSendData); + _sctpTransport->SignalDataReceived.connect(this, &SctpDataChannelProviderInterfaceImpl::sctpDataReceived); + _sctpTransport->SignalClosedAbruptly.connect(this, &SctpDataChannelProviderInterfaceImpl::sctpClosedAbruptly); + + webrtc::InternalDataChannelInit dataChannelInit; + dataChannelInit.id = 0; + dataChannelInit.open_handshake_role = isOutgoing ? webrtc::InternalDataChannelInit::kOpener : webrtc::InternalDataChannelInit::kAcker; + _dataChannel = webrtc::SctpDataChannel::Create( + this, + "data", + dataChannelInit, + _threads->getNetworkThread(), + _threads->getNetworkThread() + ); + + _dataChannel->RegisterObserver(this); +} + + +SctpDataChannelProviderInterfaceImpl::~SctpDataChannelProviderInterfaceImpl() { + assert(_threads->getNetworkThread()->IsCurrent()); + + _dataChannel->UnregisterObserver(); + _dataChannel->Close(); + _dataChannel = nullptr; + + _sctpTransport = nullptr; + _sctpTransportFactory.reset(); +} + +void SctpDataChannelProviderInterfaceImpl::sendDataChannelMessage(std::string const &message) { + assert(_threads->getNetworkThread()->IsCurrent()); + + if (_isDataChannelOpen) { + RTC_LOG(LS_INFO) << "Outgoing DataChannel message: " << message; + + webrtc::DataBuffer buffer(message); + _dataChannel->Send(buffer); + } else { + RTC_LOG(LS_INFO) << "Could not send an outgoing DataChannel message: the channel is not open"; + } +} + +void SctpDataChannelProviderInterfaceImpl::OnStateChange() { + assert(_threads->getNetworkThread()->IsCurrent()); + + auto state = _dataChannel->state(); + bool isDataChannelOpen = state == webrtc::DataChannelInterface::DataState::kOpen; + if (_isDataChannelOpen != isDataChannelOpen) { + _isDataChannelOpen = isDataChannelOpen; + _onStateChanged(_isDataChannelOpen); + } +} + +void SctpDataChannelProviderInterfaceImpl::OnMessage(const webrtc::DataBuffer& buffer) { + assert(_threads->getNetworkThread()->IsCurrent()); + + if (!buffer.binary) { + std::string messageText(buffer.data.data(), buffer.data.data() + buffer.data.size()); + RTC_LOG(LS_INFO) << "Incoming DataChannel message: " << messageText; + + _onMessageReceived(messageText); + } +} + +void SctpDataChannelProviderInterfaceImpl::updateIsConnected(bool isConnected) { + assert(_threads->getNetworkThread()->IsCurrent()); + + if (isConnected) { + if (!_isSctpTransportStarted) { + _isSctpTransportStarted = true; + _sctpTransport->Start(5000, 5000, 262144); + } + } +} + +void SctpDataChannelProviderInterfaceImpl::sctpReadyToSendData() { + assert(_threads->getNetworkThread()->IsCurrent()); + + _dataChannel->OnTransportReady(true); +} + +void SctpDataChannelProviderInterfaceImpl::sctpClosedAbruptly() { + assert(_threads->getNetworkThread()->IsCurrent()); + + if (_onTerminated) { + _onTerminated(); + } +} + +void SctpDataChannelProviderInterfaceImpl::sctpDataReceived(const cricket::ReceiveDataParams& params, const rtc::CopyOnWriteBuffer& buffer) { + assert(_threads->getNetworkThread()->IsCurrent()); + + _dataChannel->OnDataReceived(params, buffer); +} + +bool SctpDataChannelProviderInterfaceImpl::SendData(int sid, const webrtc::SendDataParams& params, const rtc::CopyOnWriteBuffer& payload, cricket::SendDataResult* result) { + assert(_threads->getNetworkThread()->IsCurrent()); + + return _sctpTransport->SendData(sid, params, payload); +} + +bool SctpDataChannelProviderInterfaceImpl::ConnectDataChannel(webrtc::SctpDataChannel *data_channel) { + assert(_threads->getNetworkThread()->IsCurrent()); + + return true; +} + +void SctpDataChannelProviderInterfaceImpl::DisconnectDataChannel(webrtc::SctpDataChannel* data_channel) { + assert(_threads->getNetworkThread()->IsCurrent()); + + return; +} + +void SctpDataChannelProviderInterfaceImpl::AddSctpDataStream(int sid) { + assert(_threads->getNetworkThread()->IsCurrent()); + + _sctpTransport->OpenStream(sid); +} + +void SctpDataChannelProviderInterfaceImpl::RemoveSctpDataStream(int sid) { + assert(_threads->getNetworkThread()->IsCurrent()); + + _threads->getNetworkThread()->Invoke(RTC_FROM_HERE, [this, sid]() { + _sctpTransport->ResetStream(sid); + }); +} + +bool SctpDataChannelProviderInterfaceImpl::ReadyToSendData() const { + assert(_threads->getNetworkThread()->IsCurrent()); + + return _sctpTransport->ReadyToSendData(); +} + +} diff --git a/TMessagesProj/jni/voip/tgcalls/SctpDataChannelProviderInterfaceImpl.h b/TMessagesProj/jni/voip/tgcalls/SctpDataChannelProviderInterfaceImpl.h new file mode 100644 index 000000000..2ecaffc14 --- /dev/null +++ b/TMessagesProj/jni/voip/tgcalls/SctpDataChannelProviderInterfaceImpl.h @@ -0,0 +1,64 @@ +#ifndef TGCALLS_SCTP_DATA_CHANNEL_PROVIDER_IMPL_H +#define TGCALLS_SCTP_DATA_CHANNEL_PROVIDER_IMPL_H + +#include "media/sctp/sctp_transport_factory.h" +#include "api/turn_customizer.h" +#include "api/data_channel_interface.h" +#include "pc/sctp_data_channel.h" +#include "pc/sctp_transport.h" + +#include "StaticThreads.h" + +namespace cricket { +class DtlsTransport; +} // namespace cricket + +namespace tgcalls { + +class SctpDataChannelProviderInterfaceImpl : public sigslot::has_slots<>, public webrtc::SctpDataChannelProviderInterface, public webrtc::DataChannelObserver { +public: + SctpDataChannelProviderInterfaceImpl( + cricket::DtlsTransport *transportChannel, + bool isOutgoing, + std::function onStateChanged, + std::function onTerminated, + std::function onMessageReceived, + std::shared_ptr threads + ); + virtual ~SctpDataChannelProviderInterfaceImpl(); + + void updateIsConnected(bool isConnected); + void sendDataChannelMessage(std::string const &message); + + virtual void OnStateChange() override; + virtual void OnMessage(const webrtc::DataBuffer& buffer) override; + virtual bool SendData(int sid, const webrtc::SendDataParams& params, const rtc::CopyOnWriteBuffer& payload, cricket::SendDataResult* result = nullptr) override; + virtual bool ConnectDataChannel(webrtc::SctpDataChannel *data_channel) override; + virtual void DisconnectDataChannel(webrtc::SctpDataChannel* data_channel) override; + virtual void AddSctpDataStream(int sid) override; + virtual void RemoveSctpDataStream(int sid) override; + virtual bool ReadyToSendData() const override; + +private: + void sctpReadyToSendData(); + void sctpClosedAbruptly(); + void sctpDataReceived(const cricket::ReceiveDataParams& params, const rtc::CopyOnWriteBuffer& buffer); + +private: + std::shared_ptr _threads; + std::function _onStateChanged; + std::function _onTerminated; + std::function _onMessageReceived; + + std::unique_ptr _sctpTransportFactory; + std::unique_ptr _sctpTransport; + rtc::scoped_refptr _dataChannel; + + bool _isSctpTransportStarted = false; + bool _isDataChannelOpen = false; + +}; + +} // namespace tgcalls + +#endif diff --git a/TMessagesProj/jni/voip/tgcalls/StaticThreads.cpp b/TMessagesProj/jni/voip/tgcalls/StaticThreads.cpp index 4a88625d7..1d14b6fad 100644 --- a/TMessagesProj/jni/voip/tgcalls/StaticThreads.cpp +++ b/TMessagesProj/jni/voip/tgcalls/StaticThreads.cpp @@ -64,7 +64,6 @@ public: network_->DisallowAllInvokes(); media_ = create("tgc-media" + suffix); worker_ = create("tgc-work" + suffix); - process_ = create("tgc-process" + suffix); worker_->DisallowAllInvokes(); worker_->AllowInvokesToThread(network_.get()); } @@ -78,9 +77,6 @@ public: rtc::Thread *getWorkerThread() override { return worker_.get(); } - rtc::Thread *getProcessThread() override { - return process_.get(); - } rtc::scoped_refptr getSharedModuleThread() override { // This function must be called from a single thread because of SharedModuleThread implementation // So we don't care about making it thread safe @@ -96,7 +92,6 @@ private: Thread network_; Thread media_; Thread worker_; - Thread process_; rtc::scoped_refptr shared_module_thread_; static Thread create(const std::string &name) { @@ -146,10 +141,6 @@ rtc::Thread *getWorkerThread() { return getThreads()->getWorkerThread(); } -rtc::Thread *getProcessThread() { - return getThreads()->getProcessThread(); -} - std::shared_ptr &getThreads() { static std::shared_ptr threads = std::make_shared(0); return threads; diff --git a/TMessagesProj/jni/voip/tgcalls/StaticThreads.h b/TMessagesProj/jni/voip/tgcalls/StaticThreads.h index 08c8a9814..eb1c0358b 100644 --- a/TMessagesProj/jni/voip/tgcalls/StaticThreads.h +++ b/TMessagesProj/jni/voip/tgcalls/StaticThreads.h @@ -20,7 +20,6 @@ public: virtual rtc::Thread *getNetworkThread() = 0; virtual rtc::Thread *getMediaThread() = 0; virtual rtc::Thread *getWorkerThread() = 0; - virtual rtc::Thread *getProcessThread() = 0; virtual rtc::scoped_refptr getSharedModuleThread() = 0; // it is not possible to decrease pool size @@ -32,7 +31,6 @@ namespace StaticThreads { rtc::Thread *getNetworkThread(); rtc::Thread *getMediaThread(); rtc::Thread *getWorkerThread(); -rtc::Thread *getProcessThread(); rtc::scoped_refptr getSharedMoudleThread(); std::shared_ptr &getThreads(); } diff --git a/TMessagesProj/jni/voip/tgcalls/TurnCustomizerImpl.cpp b/TMessagesProj/jni/voip/tgcalls/TurnCustomizerImpl.cpp new file mode 100644 index 000000000..bab743c0b --- /dev/null +++ b/TMessagesProj/jni/voip/tgcalls/TurnCustomizerImpl.cpp @@ -0,0 +1,21 @@ +#include "TurnCustomizerImpl.h" + +#include "api/transport/stun.h" + +namespace tgcalls { + +TurnCustomizerImpl::TurnCustomizerImpl() { +} + +TurnCustomizerImpl::~TurnCustomizerImpl() { +} + +void TurnCustomizerImpl::MaybeModifyOutgoingStunMessage(cricket::PortInterface* port, cricket::StunMessage* message) { + message->AddAttribute(std::make_unique(cricket::STUN_ATTR_SOFTWARE, "Telegram ")); +} + +bool TurnCustomizerImpl::AllowChannelData(cricket::PortInterface* port, const void *data, size_t size, bool payload) { + return true; +} + +} diff --git a/TMessagesProj/jni/voip/tgcalls/TurnCustomizerImpl.h b/TMessagesProj/jni/voip/tgcalls/TurnCustomizerImpl.h new file mode 100644 index 000000000..6029f4815 --- /dev/null +++ b/TMessagesProj/jni/voip/tgcalls/TurnCustomizerImpl.h @@ -0,0 +1,19 @@ +#ifndef TGCALLS_TURN_CUSTOMIZER_H +#define TGCALLS_TURN_CUSTOMIZER_H + +#include "api/turn_customizer.h" + +namespace tgcalls { + +class TurnCustomizerImpl : public webrtc::TurnCustomizer { +public: + TurnCustomizerImpl(); + virtual ~TurnCustomizerImpl(); + + void MaybeModifyOutgoingStunMessage(cricket::PortInterface* port, cricket::StunMessage* message) override; + bool AllowChannelData(cricket::PortInterface* port, const void *data, size_t size, bool payload) override; +}; + +} // namespace tgcalls + +#endif diff --git a/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceCustomImpl.cpp b/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceCustomImpl.cpp index 1d9166e19..0cf852abd 100644 --- a/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceCustomImpl.cpp +++ b/TMessagesProj/jni/voip/tgcalls/group/GroupInstanceCustomImpl.cpp @@ -520,11 +520,14 @@ class AudioSinkImpl: public webrtc::AudioSinkInterface { public: struct Update { float level = 0.0f; - std::shared_ptr buffer; - std::shared_ptr vad; + bool hasSpeech = false; - Update(float level_, webrtc::AudioBuffer *buffer_, std::shared_ptr vad_) : - level(level_), buffer(std::shared_ptr(buffer_)), vad(vad_) { + Update(float level_, bool hasSpech_) : + level(level_), hasSpeech(hasSpech_) { + } + + Update(const Update &other) : + level(other.level), hasSpeech(other.hasSpeech) { } }; @@ -550,7 +553,7 @@ public: frame.ntp_time_ms = 0; _onAudioFrame(_channel_id.actualSsrc, frame); } - if (_update && audio.channels == 1) { + if (_update && audio.channels == 1) { const int16_t *samples = (const int16_t *)audio.data; int numberOfSamplesInFrame = (int)audio.samples_per_channel; @@ -573,17 +576,7 @@ public: float level = ((float)(_peak)) / 8000.0f; _peak = 0; _peakCount = 0; - - webrtc::AudioBuffer *buffer; - if (_vad->incWaitingFrames()) { - buffer = new webrtc::AudioBuffer(audio.sample_rate, 1, 48000, 1, 48000, 1); - webrtc::StreamConfig config(audio.sample_rate, 1); - buffer->CopyFrom(samples, config); - } else { - buffer = nullptr; - } - - _update(Update(level, buffer, _vad)); + _update(Update(level, level >= 1.0f)); } } } @@ -2929,12 +2922,6 @@ public: } void setIsMuted(bool isMuted) { - if (_videoContentType == VideoContentType::Screencast) { - if (isMuted) { - return; - } - } - if (_isMuted == isMuted) { return; } @@ -3011,23 +2998,23 @@ public: const auto weak = std::weak_ptr(shared_from_this()); std::function onAudioSinkUpdate; - /*if (_audioLevelsUpdated) { - onAudioSinkUpdate = [weak, ssrc = ssrc, threads = _threads](AudioSinkImpl::Update update) { - threads->getProcessThread()->PostTask(RTC_FROM_HERE, [weak, ssrc, update, threads]() { - bool voice = update.vad->update(update.buffer.get()); - threads->getMediaThread()->PostTask(RTC_FROM_HERE, [weak, ssrc, update, voice]() { - auto strong = weak.lock(); - if (!strong) { - return; - } - GroupLevelValue mappedUpdate; - mappedUpdate.level = update.level; - mappedUpdate.voice = voice; - strong->_audioLevels[ssrc] = mappedUpdate; - }); - }); - }; - }*/ + if (ssrc.actualSsrc != ssrc.networkSsrc) { + if (_audioLevelsUpdated) { + onAudioSinkUpdate = [weak, ssrc = ssrc, threads = _threads](AudioSinkImpl::Update update) { + threads->getMediaThread()->PostTask(RTC_FROM_HERE, [weak, ssrc, update]() { + auto strong = weak.lock(); + if (!strong) { + return; + } + InternalGroupLevelValue updated; + updated.value.level = update.level; + updated.value.voice = update.hasSpeech; + updated.timestamp = rtc::TimeMillis(); + strong->_audioLevels.insert(std::make_pair(ChannelId(ssrc), std::move(updated))); + }); + }; + } + } std::unique_ptr channel(new IncomingAudioChannel( _channelManager.get(), diff --git a/TMessagesProj/jni/voip/tgcalls/group/GroupNetworkManager.cpp b/TMessagesProj/jni/voip/tgcalls/group/GroupNetworkManager.cpp index 167046858..183a4d926 100644 --- a/TMessagesProj/jni/voip/tgcalls/group/GroupNetworkManager.cpp +++ b/TMessagesProj/jni/voip/tgcalls/group/GroupNetworkManager.cpp @@ -17,194 +17,12 @@ #include "modules/rtp_rtcp/source/rtp_utility.h" #include "modules/rtp_rtcp/source/byte_io.h" #include "platform/PlatformInterface.h" - +#include "TurnCustomizerImpl.h" +#include "SctpDataChannelProviderInterfaceImpl.h" #include "StaticThreads.h" namespace tgcalls { -class TurnCustomizerImpl : public webrtc::TurnCustomizer { -public: - TurnCustomizerImpl() { - } - - virtual ~TurnCustomizerImpl() { - } - - void MaybeModifyOutgoingStunMessage(cricket::PortInterface* port, - cricket::StunMessage* message) override { - message->AddAttribute(std::make_unique(cricket::STUN_ATTR_SOFTWARE, "Telegram ")); - } - - bool AllowChannelData(cricket::PortInterface* port, const void *data, size_t size, bool payload) override { - return true; - } -}; - -class SctpDataChannelProviderInterfaceImpl : public sigslot::has_slots<>, public webrtc::SctpDataChannelProviderInterface, public webrtc::DataChannelObserver { -public: - SctpDataChannelProviderInterfaceImpl( - cricket::DtlsTransport *transportChannel, - std::function onStateChanged, - std::function onTerminated, - std::function onMessageReceived, - std::shared_ptr threads - ) : - _threads(std::move(threads)), - _onStateChanged(onStateChanged), - _onTerminated(onTerminated), - _onMessageReceived(onMessageReceived) { - assert(_threads->getNetworkThread()->IsCurrent()); - - _sctpTransportFactory.reset(new cricket::SctpTransportFactory(_threads->getNetworkThread())); - - _sctpTransport = _sctpTransportFactory->CreateSctpTransport(transportChannel); - _sctpTransport->SignalReadyToSendData.connect(this, &SctpDataChannelProviderInterfaceImpl::sctpReadyToSendData); - _sctpTransport->SignalDataReceived.connect(this, &SctpDataChannelProviderInterfaceImpl::sctpDataReceived); - _sctpTransport->SignalClosedAbruptly.connect(this, &SctpDataChannelProviderInterfaceImpl::sctpClosedAbruptly); - - webrtc::InternalDataChannelInit dataChannelInit; - dataChannelInit.id = 0; - _dataChannel = webrtc::SctpDataChannel::Create( - this, - "data", - dataChannelInit, - _threads->getNetworkThread(), - _threads->getNetworkThread() - ); - - _dataChannel->RegisterObserver(this); - } - - virtual ~SctpDataChannelProviderInterfaceImpl() { - assert(_threads->getNetworkThread()->IsCurrent()); - - _dataChannel->UnregisterObserver(); - _dataChannel->Close(); - _dataChannel = nullptr; - - _sctpTransport = nullptr; - _sctpTransportFactory.reset(); - } - - void sendDataChannelMessage(std::string const &message) { - assert(_threads->getNetworkThread()->IsCurrent()); - - if (_isDataChannelOpen) { - RTC_LOG(LS_INFO) << "Outgoing DataChannel message: " << message; - - webrtc::DataBuffer buffer(message); - _dataChannel->Send(buffer); - } else { - RTC_LOG(LS_INFO) << "Could not send an outgoing DataChannel message: the channel is not open"; - } - } - - virtual void OnStateChange() override { - assert(_threads->getNetworkThread()->IsCurrent()); - - auto state = _dataChannel->state(); - bool isDataChannelOpen = state == webrtc::DataChannelInterface::DataState::kOpen; - if (_isDataChannelOpen != isDataChannelOpen) { - _isDataChannelOpen = isDataChannelOpen; - _onStateChanged(_isDataChannelOpen); - } - } - - virtual void OnMessage(const webrtc::DataBuffer& buffer) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - if (!buffer.binary) { - std::string messageText(buffer.data.data(), buffer.data.data() + buffer.data.size()); - RTC_LOG(LS_INFO) << "Incoming DataChannel message: " << messageText; - - _onMessageReceived(messageText); - } - } - - void updateIsConnected(bool isConnected) { - assert(_threads->getNetworkThread()->IsCurrent()); - - if (isConnected) { - if (!_isSctpTransportStarted) { - _isSctpTransportStarted = true; - _sctpTransport->Start(5000, 5000, 262144); - } - } - } - - void sctpReadyToSendData() { - assert(_threads->getNetworkThread()->IsCurrent()); - - _dataChannel->OnTransportReady(true); - } - - void sctpClosedAbruptly() { - assert(_threads->getNetworkThread()->IsCurrent()); - - if (_onTerminated) { - _onTerminated(); - } - } - - void sctpDataReceived(const cricket::ReceiveDataParams& params, const rtc::CopyOnWriteBuffer& buffer) { - assert(_threads->getNetworkThread()->IsCurrent()); - - _dataChannel->OnDataReceived(params, buffer); - } - - virtual bool SendData(int sid, const webrtc::SendDataParams& params, const rtc::CopyOnWriteBuffer& payload, cricket::SendDataResult* result) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - return _sctpTransport->SendData(sid, params, payload); - } - - virtual bool ConnectDataChannel(webrtc::SctpDataChannel *data_channel) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - return true; - } - - virtual void DisconnectDataChannel(webrtc::SctpDataChannel* data_channel) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - return; - } - - virtual void AddSctpDataStream(int sid) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - _sctpTransport->OpenStream(sid); - } - - virtual void RemoveSctpDataStream(int sid) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - _threads->getNetworkThread()->Invoke(RTC_FROM_HERE, [this, sid]() { - _sctpTransport->ResetStream(sid); - }); - } - - virtual bool ReadyToSendData() const override { - assert(_threads->getNetworkThread()->IsCurrent()); - - return _sctpTransport->ReadyToSendData(); - } - -private: - std::shared_ptr _threads; - std::function _onStateChanged; - std::function _onTerminated; - std::function _onMessageReceived; - - std::unique_ptr _sctpTransportFactory; - std::unique_ptr _sctpTransport; - rtc::scoped_refptr _dataChannel; - - bool _isSctpTransportStarted = false; - bool _isDataChannelOpen = false; - -}; - enum { kRtcpExpectedVersion = 2, kRtcpMinHeaderLength = 4, @@ -589,6 +407,7 @@ void GroupNetworkManager::restartDataChannel() { const auto weak = std::weak_ptr(shared_from_this()); _dataChannelInterface.reset(new SctpDataChannelProviderInterfaceImpl( _dtlsTransport.get(), + true, [weak, threads = _threads](bool state) { assert(threads->getNetworkThread()->IsCurrent()); const auto strong = weak.lock(); diff --git a/TMessagesProj/jni/voip/tgcalls/v2/NativeNetworkingImpl.cpp b/TMessagesProj/jni/voip/tgcalls/v2/NativeNetworkingImpl.cpp index fdd43b676..c9024c932 100644 --- a/TMessagesProj/jni/voip/tgcalls/v2/NativeNetworkingImpl.cpp +++ b/TMessagesProj/jni/voip/tgcalls/v2/NativeNetworkingImpl.cpp @@ -13,184 +13,12 @@ #include "p2p/base/dtls_transport_factory.h" #include "pc/dtls_srtp_transport.h" #include "pc/dtls_transport.h" - +#include "TurnCustomizerImpl.h" +#include "SctpDataChannelProviderInterfaceImpl.h" #include "StaticThreads.h" namespace tgcalls { -class TurnCustomizerImpl : public webrtc::TurnCustomizer { -public: - TurnCustomizerImpl() { - } - - virtual ~TurnCustomizerImpl() { - } - - void MaybeModifyOutgoingStunMessage(cricket::PortInterface* port, - cricket::StunMessage* message) override { - message->AddAttribute(std::make_unique(cricket::STUN_ATTR_SOFTWARE, "Telegram ")); - } - - bool AllowChannelData(cricket::PortInterface* port, const void *data, size_t size, bool payload) override { - return true; - } -}; - -class SctpDataChannelProviderInterfaceImpl : public sigslot::has_slots<>, public webrtc::SctpDataChannelProviderInterface, public webrtc::DataChannelObserver { -public: - SctpDataChannelProviderInterfaceImpl( - cricket::DtlsTransport *transportChannel, - bool isOutgoing, - std::function onStateChanged, - std::function onMessageReceived, - std::shared_ptr threads - ) : - _threads(std::move(threads)), - _onStateChanged(onStateChanged), - _onMessageReceived(onMessageReceived) { - assert(_threads->getNetworkThread()->IsCurrent()); - - _sctpTransportFactory.reset(new cricket::SctpTransportFactory(_threads->getNetworkThread())); - - _sctpTransport = _sctpTransportFactory->CreateSctpTransport(transportChannel); - _sctpTransport->SignalReadyToSendData.connect(this, &SctpDataChannelProviderInterfaceImpl::sctpReadyToSendData); - _sctpTransport->SignalDataReceived.connect(this, &SctpDataChannelProviderInterfaceImpl::sctpDataReceived); - - webrtc::InternalDataChannelInit dataChannelInit; - dataChannelInit.id = 0; - dataChannelInit.open_handshake_role = isOutgoing ? webrtc::InternalDataChannelInit::kOpener : webrtc::InternalDataChannelInit::kAcker; - _dataChannel = webrtc::SctpDataChannel::Create( - this, - "data", - dataChannelInit, - _threads->getNetworkThread(), - _threads->getNetworkThread() - ); - - _dataChannel->RegisterObserver(this); - } - - virtual ~SctpDataChannelProviderInterfaceImpl() { - assert(_threads->getNetworkThread()->IsCurrent()); - - _dataChannel->UnregisterObserver(); - _dataChannel->Close(); - _dataChannel = nullptr; - - _sctpTransport = nullptr; - _sctpTransportFactory.reset(); - } - - void sendDataChannelMessage(std::string const &message) { - assert(_threads->getNetworkThread()->IsCurrent()); - - if (_isDataChannelOpen) { - RTC_LOG(LS_INFO) << "Outgoing DataChannel message: " << message; - - webrtc::DataBuffer buffer(message); - _dataChannel->Send(buffer); - } else { - RTC_LOG(LS_INFO) << "Could not send an outgoing DataChannel message: the channel is not open"; - } - } - - virtual void OnStateChange() override { - assert(_threads->getNetworkThread()->IsCurrent()); - - auto state = _dataChannel->state(); - bool isDataChannelOpen = state == webrtc::DataChannelInterface::DataState::kOpen; - if (_isDataChannelOpen != isDataChannelOpen) { - _isDataChannelOpen = isDataChannelOpen; - _onStateChanged(_isDataChannelOpen); - } - } - - virtual void OnMessage(const webrtc::DataBuffer& buffer) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - if (!buffer.binary) { - std::string messageText(buffer.data.data(), buffer.data.data() + buffer.data.size()); - RTC_LOG(LS_INFO) << "Incoming DataChannel message: " << messageText; - - _onMessageReceived(messageText); - } - } - - void updateIsConnected(bool isConnected) { - assert(_threads->getNetworkThread()->IsCurrent()); - - if (isConnected) { - if (!_isSctpTransportStarted) { - _isSctpTransportStarted = true; - _sctpTransport->Start(5000, 5000, 262144); - } - } - } - - void sctpReadyToSendData() { - assert(_threads->getNetworkThread()->IsCurrent()); - - _dataChannel->OnTransportReady(true); - } - - void sctpDataReceived(const cricket::ReceiveDataParams& params, const rtc::CopyOnWriteBuffer& buffer) { - assert(_threads->getNetworkThread()->IsCurrent()); - - _dataChannel->OnDataReceived(params, buffer); - } - - virtual bool SendData(const cricket::SendDataParams& params, const rtc::CopyOnWriteBuffer& payload, cricket::SendDataResult* result) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - return _sctpTransport->SendData(params, payload); - } - - virtual bool ConnectDataChannel(webrtc::SctpDataChannel *data_channel) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - return true; - } - - virtual void DisconnectDataChannel(webrtc::SctpDataChannel* data_channel) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - return; - } - - virtual void AddSctpDataStream(int sid) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - _sctpTransport->OpenStream(sid); - } - - virtual void RemoveSctpDataStream(int sid) override { - assert(_threads->getNetworkThread()->IsCurrent()); - - _threads->getNetworkThread()->Invoke(RTC_FROM_HERE, [this, sid]() { - _sctpTransport->ResetStream(sid); - }); - } - - virtual bool ReadyToSendData() const override { - assert(_threads->getNetworkThread()->IsCurrent()); - - return _sctpTransport->ReadyToSendData(); - } - -private: - std::shared_ptr _threads; - std::function _onStateChanged; - std::function _onMessageReceived; - - std::unique_ptr _sctpTransportFactory; - std::unique_ptr _sctpTransport; - rtc::scoped_refptr _dataChannel; - - bool _isSctpTransportStarted = false; - bool _isDataChannelOpen = false; - -}; - webrtc::CryptoOptions NativeNetworkingImpl::getDefaulCryptoOptions() { auto options = webrtc::CryptoOptions(); options.srtp.enable_aes128_sha1_80_crypto_cipher = true; @@ -355,6 +183,14 @@ void NativeNetworkingImpl::start() { } strong->_dataChannelStateUpdated(state); }, + [weak, threads = _threads]() { + assert(threads->getNetworkThread()->IsCurrent()); + const auto strong = weak.lock(); + if (!strong) { + return; + } + //strong->restartDataChannel(); + }, [weak, threads = _threads](std::string const &message) { assert(threads->getNetworkThread()->IsCurrent()); const auto strong = weak.lock(); diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index d4f5bd6d7..cac5f8905 100644 --- a/TMessagesProj/src/main/AndroidManifest.xml +++ b/TMessagesProj/src/main/AndroidManifest.xml @@ -423,7 +423,7 @@ android:name=".voip.CallNotificationSoundProvider" android:exported="true"/> - + @@ -435,7 +435,7 @@ android:permission="android.permission.BIND_REMOTEVIEWS" android:exported="false" /> - + diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java index 8dad1b50a..0df9a4636 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java @@ -1747,6 +1747,9 @@ public class AndroidUtilities { } public static void runOnUIThread(Runnable runnable, long delay) { + if (ApplicationLoader.applicationHandler == null) { + return; + } if (delay == 0) { ApplicationLoader.applicationHandler.post(runnable); } else { @@ -1755,6 +1758,9 @@ public class AndroidUtilities { } public static void cancelRunOnUIThread(Runnable runnable) { + if (ApplicationLoader.applicationHandler == null) { + return; + } ApplicationLoader.applicationHandler.removeCallbacks(runnable); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 4fc163d1e..ad534f8c1 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -15,12 +15,12 @@ public class BuildVars { public static boolean DEBUG_VERSION = false; public static boolean DEBUG_PRIVATE_VERSION = false; - public static boolean LOGS_ENABLED = true; + public static boolean LOGS_ENABLED = false; public static boolean USE_CLOUD_STRINGS = true; public static boolean CHECK_UPDATES = true; public static boolean NO_SCOPED_STORAGE = true/* || Build.VERSION.SDK_INT <= 28*/; - public static int BUILD_VERSION = 2372; - public static String BUILD_VERSION_STRING = "7.8.0"; + public static int BUILD_VERSION = 2376; + public static String BUILD_VERSION_STRING = "7.8.2"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; public static String APPCENTER_HASH = "a5b5c4f5-51da-dedc-9918-d9766a22ca7c"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ChatsWidgetProvider.java b/TMessagesProj/src/main/java/org/telegram/messenger/ChatsWidgetProvider.java index 55a16aa58..a9f50cbc8 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ChatsWidgetProvider.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ChatsWidgetProvider.java @@ -28,13 +28,13 @@ public class ChatsWidgetProvider extends AppWidgetProvider { super.onUpdate(context, appWidgetManager, appWidgetIds); for (int i = 0; i < appWidgetIds.length; i++) { int appWidgetId = appWidgetIds[i]; - updateWidget(context, appWidgetManager, appWidgetId, false); + updateWidget(context, appWidgetManager, appWidgetId); } } @Override public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { - updateWidget(context, appWidgetManager, appWidgetId, true); + updateWidget(context, appWidgetManager, appWidgetId); super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); } @@ -65,7 +65,7 @@ public class ChatsWidgetProvider extends AppWidgetProvider { return n - 1; } - public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, boolean edit) { + public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { ApplicationLoader.postInitApplication(); Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId); int minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT); @@ -80,6 +80,11 @@ public class ChatsWidgetProvider extends AppWidgetProvider { int id; if (!deleted) { int accountId = preferences.getInt("account" + appWidgetId, -1); + if (accountId == -1) { + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("account" + appWidgetId, UserConfig.selectedAccount); + editor.putInt("type" + appWidgetId, EditWidgetActivity.TYPE_CHATS).commit(); + } ArrayList selectedDialogs = new ArrayList<>(); if (accountId >= 0) { AccountInstance.getInstance(accountId).getMessagesStorage().getWidgetDialogIds(appWidgetId, EditWidgetActivity.TYPE_CHATS, selectedDialogs, null, null, false); @@ -109,8 +114,6 @@ public class ChatsWidgetProvider extends AppWidgetProvider { rv.setPendingIntentTemplate(R.id.list_view, contentIntent); appWidgetManager.updateAppWidget(appWidgetId, rv); - if (edit) { - appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); - } + appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ChatsWidgetService.java b/TMessagesProj/src/main/java/org/telegram/messenger/ChatsWidgetService.java index bf9e66af3..f6615abea 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ChatsWidgetService.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ChatsWidgetService.java @@ -327,9 +327,11 @@ class ChatsRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { rv.setTextViewText(R.id.shortcut_widget_item_badge, String.format("%d", dialog.unread_count)); rv.setViewVisibility(R.id.shortcut_widget_item_badge, View.VISIBLE); if (accountInstance.getMessagesController().isDialogMuted(dialog.id)) { - rv.setInt(R.id.shortcut_widget_item_badge, "setBackgroundResource", R.drawable.widget_counter_muted); + rv.setBoolean(R.id.shortcut_widget_item_badge, "setEnabled", false); + rv.setInt(R.id.shortcut_widget_item_badge, "setBackgroundResource", R.drawable.widget_badge_muted_background); } else { - rv.setInt(R.id.shortcut_widget_item_badge, "setBackgroundResource", R.drawable.widget_counter); + rv.setBoolean(R.id.shortcut_widget_item_badge, "setEnabled", true); + rv.setInt(R.id.shortcut_widget_item_badge, "setBackgroundResource", R.drawable.widget_badge_background); } } else { rv.setViewVisibility(R.id.shortcut_widget_item_badge, View.GONE); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ContactsWidgetProvider.java b/TMessagesProj/src/main/java/org/telegram/messenger/ContactsWidgetProvider.java index d64cd3ec9..2a6c1eb22 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ContactsWidgetProvider.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ContactsWidgetProvider.java @@ -28,7 +28,7 @@ public class ContactsWidgetProvider extends AppWidgetProvider { super.onUpdate(context, appWidgetManager, appWidgetIds); for (int i = 0; i < appWidgetIds.length; i++) { int appWidgetId = appWidgetIds[i]; - updateWidget(context, appWidgetManager, appWidgetId, false); + updateWidget(context, appWidgetManager, appWidgetId); } } @@ -53,7 +53,7 @@ public class ContactsWidgetProvider extends AppWidgetProvider { @Override public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { - updateWidget(context, appWidgetManager, appWidgetId, true); + updateWidget(context, appWidgetManager, appWidgetId); super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); } @@ -65,7 +65,7 @@ public class ContactsWidgetProvider extends AppWidgetProvider { return n - 1; } - public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, boolean edit) { + public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { ApplicationLoader.postInitApplication(); Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId); int maxHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT); @@ -80,6 +80,11 @@ public class ContactsWidgetProvider extends AppWidgetProvider { int id; if (!deleted) { int accountId = preferences.getInt("account" + appWidgetId, -1); + if (accountId == -1) { + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("account" + appWidgetId, UserConfig.selectedAccount); + editor.putInt("type" + appWidgetId, EditWidgetActivity.TYPE_CHATS).commit(); + } ArrayList selectedDialogs = new ArrayList<>(); if (accountId >= 0) { AccountInstance.getInstance(accountId).getMessagesStorage().getWidgetDialogIds(appWidgetId, EditWidgetActivity.TYPE_CONTACTS, selectedDialogs, null, null, false); @@ -111,8 +116,6 @@ public class ContactsWidgetProvider extends AppWidgetProvider { rv.setPendingIntentTemplate(R.id.list_view, contentIntent); appWidgetManager.updateAppWidget(appWidgetId, rv); - if (edit) { - appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); - } + appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java index 7919674b5..fb5e143ca 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java @@ -899,7 +899,7 @@ public class MessageObject { } public MessageObject(int accountNum, TLRPC.Message message, MessageObject replyToMessage, AbstractMap users, AbstractMap chats, SparseArray sUsers, SparseArray sChats, boolean generateLayout, boolean checkMediaExists, long eid) { - Theme.createCommonChatResources(null); + Theme.createCommonChatResources(); currentAccount = accountNum; messageOwner = message; @@ -2363,7 +2363,7 @@ public class MessageObject { } wantedBotKeyboardWidth = 0; if (messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup || messageOwner.reactions != null && !messageOwner.reactions.results.isEmpty()) { - Theme.createCommonChatResources(null); + Theme.createCommonChatResources(); if (botButtonsLayout == null) { botButtonsLayout = new StringBuilder(); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index 65b648d7f..33806ba4b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -2474,12 +2474,12 @@ public class MessagesController extends BaseController implements NotificationCe } if (chatsWidgets != null) { for (int a = 0, N = chatsWidgets.size(); a < N; a++) { - ChatsWidgetProvider.updateWidget(ApplicationLoader.applicationContext, appWidgetManager, chatsWidgets.get(a), true); + ChatsWidgetProvider.updateWidget(ApplicationLoader.applicationContext, appWidgetManager, chatsWidgets.get(a)); } } if (contactsWidgets != null) { for (int a = 0, N = contactsWidgets.size(); a < N; a++) { - ContactsWidgetProvider.updateWidget(ApplicationLoader.applicationContext, appWidgetManager, contactsWidgets.get(a), true); + ContactsWidgetProvider.updateWidget(ApplicationLoader.applicationContext, appWidgetManager, contactsWidgets.get(a)); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsController.java b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsController.java index cc6f0b10d..4015d4bcb 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsController.java @@ -47,6 +47,7 @@ import androidx.core.app.NotificationManagerCompat; import androidx.core.app.Person; import androidx.core.app.RemoteInput; import androidx.core.content.FileProvider; +import androidx.core.content.LocusIdCompat; import androidx.core.content.pm.ShortcutInfoCompat; import androidx.core.content.pm.ShortcutManagerCompat; import androidx.core.graphics.drawable.IconCompat; @@ -2749,11 +2750,22 @@ public class NotificationsController extends BaseController { } try { String id = "ndid_" + did; + + Intent shortcutIntent = new Intent(ApplicationLoader.applicationContext, OpenChatReceiver.class); + shortcutIntent.setAction("com.tmessages.openchat" + Math.random() + Integer.MAX_VALUE); + if (did > 0) { + shortcutIntent.putExtra("userId", did); + } else { + shortcutIntent.putExtra("chatId", -did); + } + ShortcutInfoCompat.Builder shortcutBuilder = new ShortcutInfoCompat.Builder(ApplicationLoader.applicationContext, id) .setShortLabel(chat != null ? name : UserObject.getFirstName(user)) .setLongLabel(name) .setIntent(new Intent(Intent.ACTION_DEFAULT)) - .setLongLived(true); + .setIntent(shortcutIntent) + .setLongLived(true) + .setLocusId(new LocusIdCompat(id)); Bitmap avatar = null; if (person != null) { @@ -2763,11 +2775,9 @@ public class NotificationsController extends BaseController { avatar = person.getIcon().getBitmap(); } } - ArrayList arrayList = new ArrayList<>(1); - arrayList.add(shortcutBuilder.build()); - ShortcutManagerCompat.addDynamicShortcuts(ApplicationLoader.applicationContext, arrayList); - builder.setShortcutId(id); - NotificationCompat.BubbleMetadata.Builder bubbleBuilder = new NotificationCompat.BubbleMetadata.Builder(); + ShortcutInfoCompat shortcut = shortcutBuilder.build(); + ShortcutManagerCompat.pushDynamicShortcut(ApplicationLoader.applicationContext, shortcut); + builder.setShortcutInfo(shortcut); Intent intent = new Intent(ApplicationLoader.applicationContext, BubbleActivity.class); intent.setAction("com.tmessages.openchat" + Math.random() + Integer.MAX_VALUE); if (did > 0) { @@ -2776,19 +2786,21 @@ public class NotificationsController extends BaseController { intent.putExtra("chatId", -did); } intent.putExtra("currentAccount", currentAccount); - bubbleBuilder.setIntent(PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); + IconCompat icon; + if (avatar != null) { + icon = IconCompat.createWithAdaptiveBitmap(avatar); + } else if (user != null) { + icon = IconCompat.createWithResource(ApplicationLoader.applicationContext, user.bot ? R.drawable.book_bot : R.drawable.book_user); + } else { + icon = IconCompat.createWithResource(ApplicationLoader.applicationContext, R.drawable.book_group); + } + NotificationCompat.BubbleMetadata.Builder bubbleBuilder = + new NotificationCompat.BubbleMetadata.Builder( + PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT), + icon); bubbleBuilder.setSuppressNotification(opened_dialog_id == did); bubbleBuilder.setAutoExpandBubble(false); bubbleBuilder.setDesiredHeight(AndroidUtilities.dp(640)); - if (avatar != null) { - bubbleBuilder.setIcon(IconCompat.createWithAdaptiveBitmap(avatar)); - } else { - if (user != null) { - bubbleBuilder.setIcon(IconCompat.createWithResource(ApplicationLoader.applicationContext, user.bot ? R.drawable.book_bot : R.drawable.book_user)); - } else { - bubbleBuilder.setIcon(IconCompat.createWithResource(ApplicationLoader.applicationContext, R.drawable.book_group)); - } - } builder.setBubbleMetadata(bubbleBuilder.build()); return id; } catch (Exception e) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java index 27acfe327..1d4cf65b9 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java @@ -284,15 +284,22 @@ public class SharedConfig { } if (pendingAppUpdate != null) { long updateTime = 0; - int updateVerstion; + int updateVersion = 0; + String updateVersionString = null; try { PackageInfo packageInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0); - updateVerstion = packageInfo.versionCode; + updateVersion = packageInfo.versionCode; + updateVersionString = packageInfo.versionName; } catch (Exception e) { FileLog.e(e); - updateVerstion = BuildVars.BUILD_VERSION; } - if (pendingAppUpdateBuildVersion != updateVerstion) { + if (updateVersion == 0) { + updateVersion = BuildVars.BUILD_VERSION; + } + if (updateVersionString == null) { + updateVersionString = BuildVars.BUILD_VERSION_STRING; + } + if (pendingAppUpdateBuildVersion != updateVersion || pendingAppUpdate.version == null || updateVersionString.compareTo(pendingAppUpdate.version) >= 0) { pendingAppUpdate = null; AndroidUtilities.runOnUIThread(SharedConfig::saveConfig); } @@ -428,16 +435,29 @@ public class SharedConfig { return pendingAppUpdateBuildVersion == currentVersion; } - public static void setNewAppVersionAvailable(TLRPC.TL_help_appUpdate update) { - pendingAppUpdate = update; + public static boolean setNewAppVersionAvailable(TLRPC.TL_help_appUpdate update) { + String updateVersionString = null; + int versionCode = 0; try { PackageInfo packageInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0); - pendingAppUpdateBuildVersion = packageInfo.versionCode; + versionCode = packageInfo.versionCode; + updateVersionString = packageInfo.versionName; } catch (Exception e) { FileLog.e(e); - pendingAppUpdateBuildVersion = BuildVars.BUILD_VERSION; } + if (versionCode == 0) { + versionCode = BuildVars.BUILD_VERSION; + } + if (updateVersionString == null) { + updateVersionString = BuildVars.BUILD_VERSION_STRING; + } + if (update.version == null || updateVersionString.compareTo(update.version) >= 0) { + return false; + } + pendingAppUpdate = update; + pendingAppUpdateBuildVersion = versionCode; saveConfig(); + return true; } public static boolean checkPasscode(String passcode) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index cdb7c258e..e3cc31a17 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -65,16 +65,6 @@ public class UserConfig extends BaseController { public volatile byte[] savedSaltedPassword; public volatile long savedPasswordTime; - public String tonEncryptedData; - public String tonPublicKey; - public int tonPasscodeType = -1; - public byte[] tonPasscodeSalt; - public long tonPasscodeRetryInMs; - public long tonLastUptimeMillis; - public int tonBadPasscodeTries; - public String tonKeyName; - public boolean tonCreationFinished; - private static volatile UserConfig[] Instance = new UserConfig[UserConfig.MAX_ACCOUNT_COUNT]; public static UserConfig getInstance(int num) { UserConfig localInstance = Instance[num]; @@ -146,21 +136,6 @@ public class UserConfig extends BaseController { editor.putInt("sharingMyLocationUntil", sharingMyLocationUntil); editor.putInt("lastMyLocationShareTime", lastMyLocationShareTime); editor.putBoolean("filtersLoaded", filtersLoaded); - if (tonEncryptedData != null) { - editor.putString("tonEncryptedData", tonEncryptedData); - editor.putString("tonPublicKey", tonPublicKey); - editor.putString("tonKeyName", tonKeyName); - editor.putBoolean("tonCreationFinished", tonCreationFinished); - if (tonPasscodeSalt != null) { - editor.putInt("tonPasscodeType", tonPasscodeType); - editor.putString("tonPasscodeSalt", Base64.encodeToString(tonPasscodeSalt, Base64.DEFAULT)); - editor.putLong("tonPasscodeRetryInMs", tonPasscodeRetryInMs); - editor.putLong("tonLastUptimeMillis", tonLastUptimeMillis); - editor.putInt("tonBadPasscodeTries", tonBadPasscodeTries); - } - } else { - editor.remove("tonEncryptedData").remove("tonPublicKey").remove("tonKeyName").remove("tonPasscodeType").remove("tonPasscodeSalt").remove("tonPasscodeRetryInMs").remove("tonBadPasscodeTries").remove("tonLastUptimeMillis").remove("tonCreationFinished"); - } editor.putInt("6migrateOffsetId", migrateOffsetId); if (migrateOffsetId != -1) { @@ -282,25 +257,9 @@ public class UserConfig extends BaseController { notificationsSignUpSettingsLoaded = preferences.getBoolean("notificationsSignUpSettingsLoaded", false); autoDownloadConfigLoadTime = preferences.getLong("autoDownloadConfigLoadTime", 0); hasValidDialogLoadIds = preferences.contains("2dialogsLoadOffsetId") || preferences.getBoolean("hasValidDialogLoadIds", false); - tonEncryptedData = preferences.getString("tonEncryptedData", null); - tonPublicKey = preferences.getString("tonPublicKey", null); - tonKeyName = preferences.getString("tonKeyName", "walletKey" + currentAccount); - tonCreationFinished = preferences.getBoolean("tonCreationFinished", true); sharingMyLocationUntil = preferences.getInt("sharingMyLocationUntil", 0); lastMyLocationShareTime = preferences.getInt("lastMyLocationShareTime", 0); filtersLoaded = preferences.getBoolean("filtersLoaded", false); - String salt = preferences.getString("tonPasscodeSalt", null); - if (salt != null) { - try { - tonPasscodeSalt = Base64.decode(salt, Base64.DEFAULT); - tonPasscodeType = preferences.getInt("tonPasscodeType", -1); - tonPasscodeRetryInMs = preferences.getLong("tonPasscodeRetryInMs", 0); - tonLastUptimeMillis = preferences.getLong("tonLastUptimeMillis", 0); - tonBadPasscodeTries = preferences.getInt("tonBadPasscodeTries", 0); - } catch (Exception e) { - FileLog.e(e); - } - } try { String terms = preferences.getString("terms", null); @@ -388,21 +347,8 @@ public class UserConfig extends BaseController { } } - public void clearTonConfig() { - tonEncryptedData = null; - tonKeyName = null; - tonPublicKey = null; - tonPasscodeType = -1; - tonPasscodeSalt = null; - tonCreationFinished = false; - tonPasscodeRetryInMs = 0; - tonLastUptimeMillis = 0; - tonBadPasscodeTries = 0; - } - public void clearConfig() { getPreferences().edit().clear().commit(); - clearTonConfig(); sharingMyLocationUntil = 0; lastMyLocationShareTime = 0; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java index 6876c2de8..7b26e005c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarLayout.java @@ -644,9 +644,11 @@ public class ActionBarLayout extends FrameLayout { public boolean onTouchEvent(MotionEvent ev) { if (!checkTransitionAnimation() && !inActionMode && !animationInProgress) { if (fragmentsStack.size() > 1) { - if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && !maybeStartTracking) { + if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN) { BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1); if (!currentFragment.isSwipeBackEnabled(ev)) { + maybeStartTracking = false; + startedTracking = false; return false; } startedTrackingPointerId = ev.getPointerId(0); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java index 7775c20fc..d103f45cc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java @@ -358,7 +358,11 @@ public class AlertDialog extends Dialog implements Drawable.Callback { WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.copyFrom(window.getAttributes()); params.width = Math.min(maxWidth, calculatedWidth) + backgroundPaddings.left + backgroundPaddings.right; - window.setAttributes(params); + try { + window.setAttributes(params); + } catch (Throwable e) { + FileLog.e(e); + } }); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java index 3fd49c276..7e9e0faa9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java @@ -7369,7 +7369,7 @@ public class Theme { } } - public static void createCommonChatResources(Context context) { + public static void createCommonChatResources() { synchronized (sync) { if (chat_msgTextPaint == null) { chat_msgTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); @@ -7466,7 +7466,7 @@ public class Theme { } public static void createChatResources(Context context, boolean fontsOnly) { - createCommonChatResources(context); + createCommonChatResources(); if (!fontsOnly && chat_msgInDrawable == null) { @@ -8687,6 +8687,7 @@ public class Theme { Drawable drawable = wallpaper; AndroidUtilities.runOnUIThread(() -> { wallpaperLoadTask = null; + createCommonChatResources(); applyChatServiceMessageColor(null, null, drawable); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didSetNewWallpapper); }); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index 4d0a416d4..cd973314d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -8028,10 +8028,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (firstVisibleBlockNum >= 0) { int restore = Integer.MIN_VALUE; int oldAlpha = -1; + int oldLinkAlpha = -1; if (alpha != 1.0f) { if (drawOnlyText) { oldAlpha = Theme.chat_msgTextPaint.getAlpha(); + oldLinkAlpha = Color.alpha(Theme.chat_msgTextPaint.linkColor); Theme.chat_msgTextPaint.setAlpha((int) (oldAlpha * alpha)); + Theme.chat_msgTextPaint.linkColor = ColorUtils.setAlphaComponent(Theme.chat_msgTextPaint.linkColor, (int) (oldLinkAlpha * alpha)); } else { if (currentBackgroundDrawable != null) { int top = currentBackgroundDrawable.getBounds().top; @@ -8083,6 +8086,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate } if (oldAlpha >= 0) { Theme.chat_msgTextPaint.setAlpha(oldAlpha); + Theme.chat_msgTextPaint.linkColor = ColorUtils.setAlphaComponent(Theme.chat_msgTextPaint.linkColor, oldLinkAlpha); } if (restore != Integer.MIN_VALUE) { @@ -9817,6 +9821,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate return; } Theme.MessageDrawable drawable = a == 0 ? currentBackgroundDrawable : currentBackgroundSelectedDrawable; + if (drawable == null) { + continue; + } int h = parentHeight; if (h == 0) { h = AndroidUtilities.displaySize.y; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 1e6861555..279028988 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -3102,8 +3102,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (!SharedConfig.smoothKeyboard) { setBottomClip(paddingBottom); - } else if (!inPreviewMode) { + } else if (!inPreviewMode && chatActivityEnterView.getEmojiPadding() == 0) { setBottomClip(AndroidUtilities.dp(48)); + } else { + setBottomClip(0); } for (int i = 0; i < count; i++) { @@ -6936,13 +6938,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not searchUpButton.setOnClickListener(view -> { getMediaDataController().searchMessagesInChat(null, dialog_id, mergeDialogId, classGuid, 1, threadMessageId, searchingUserMessages, searchingChatMessages); showMessagesSearchListView(false); - //if (!SharedConfig.searchMessagesAsListUsed && SharedConfig.searchMessagesAsListHintShows < 3 && !searchAsListHintShown && Math.random() <= 0.25) { - if (!searchAsListHintShown) { + if (!SharedConfig.searchMessagesAsListUsed && SharedConfig.searchMessagesAsListHintShows < 3 && !searchAsListHintShown && Math.random() <= 0.25) { showSearchAsListHint(); - // searchAsListHintShown = true; + searchAsListHintShown = true; + SharedConfig.increaseSearchAsListHintShows(); } -// SharedConfig.increaseSearchAsListHintShows(); -// } }); searchUpButton.setContentDescription(LocaleController.getString("AccDescrSearchNext", R.string.AccDescrSearchNext)); @@ -6997,9 +6997,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not searchCalendarButton.setContentDescription(LocaleController.getString("JumpToDate", R.string.JumpToDate)); searchCountText = new SearchCounterView(context); -// searchCountText.setTextColor(Theme.getColor(Theme.key_chat_searchPanelText)); -// searchCountText.setTextSize(15); -// searchCountText.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); searchCountText.setGravity(Gravity.LEFT); searchContainer.addView(searchCountText, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 0, 0, 108, 0)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatsWidgetConfigActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatsWidgetConfigActivity.java index cd502ffff..abe812fa4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatsWidgetConfigActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatsWidgetConfigActivity.java @@ -25,7 +25,7 @@ public class ChatsWidgetConfigActivity extends ExternalActionActivity { args.putBoolean("onlySelect", true); args.putInt("dialogsType", 10); args.putBoolean("allowSwitchAccount", true); - EditWidgetActivity fragment = new EditWidgetActivity(EditWidgetActivity.TYPE_CHATS, creatingAppWidgetId, false); + EditWidgetActivity fragment = new EditWidgetActivity(EditWidgetActivity.TYPE_CHATS, creatingAppWidgetId); fragment.setDelegate(dialogs -> { Intent resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, creatingAppWidgetId); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/BotCommandsMenuView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/BotCommandsMenuView.java index 216a47007..581d0b216 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/BotCommandsMenuView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/BotCommandsMenuView.java @@ -4,6 +4,7 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; +import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.text.Layout; import android.text.StaticLayout; @@ -31,6 +32,7 @@ import java.util.ArrayList; public class BotCommandsMenuView extends View { + final RectF rectTmp = new RectF(); final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); final TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); final MenuDrawable backDrawable = new MenuDrawable() { @@ -74,7 +76,7 @@ public class BotCommandsMenuView extends View { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int size = MeasureSpec.getSize(widthMeasureSpec) + MeasureSpec.getSize(heightMeasureSpec) << 16; - if (lastSize != size) { + if (lastSize != size || menuText == null) { backDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); textPaint.setTextSize(AndroidUtilities.dp(15)); lastSize = size; @@ -93,49 +95,49 @@ public class BotCommandsMenuView extends View { @Override protected void dispatchDraw(Canvas canvas) { - boolean update = false; - if (expanded && expandProgress != 1f) { - expandProgress += 16f / 150f; - if (expandProgress > 1) { - expandProgress = 1f; - } else { - invalidate(); + if (menuText != null) { + boolean update = false; + if (expanded && expandProgress != 1f) { + expandProgress += 16f / 150f; + if (expandProgress > 1) { + expandProgress = 1f; + } else { + invalidate(); + } + update = true; + } else if (!expanded && expandProgress != 0) { + expandProgress -= 16f / 150f; + if (expandProgress < 0) { + expandProgress = 0; + } else { + invalidate(); + } + update = true; } - update = true; - } else if (!expanded && expandProgress != 0) { - expandProgress -= 16f / 150f; - if (expandProgress < 0) { - expandProgress = 0; - } else { - invalidate(); + + float expandProgress = CubicBezierInterpolator.DEFAULT.getInterpolation(this.expandProgress); + if (update && expandProgress > 0) { + textPaint.setAlpha((int) (255 * expandProgress)); } - update = true; - } - - float expandProgress = CubicBezierInterpolator.DEFAULT.getInterpolation(this.expandProgress); - if (update && expandProgress > 0) { - textPaint.setAlpha((int) (255 * expandProgress)); - } - AndroidUtilities.rectTmp.set(0, 0, AndroidUtilities.dp(40) + (menuText.getWidth() + AndroidUtilities.dp(4)) * expandProgress, getMeasuredHeight()); - canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(16), AndroidUtilities.dp(16), paint); - backgroundDrawable.setBounds((int) AndroidUtilities.rectTmp.left, (int) AndroidUtilities.rectTmp.top, (int) AndroidUtilities.rectTmp.right, (int) AndroidUtilities.rectTmp.bottom); - backgroundDrawable.draw(canvas); - canvas.save(); - canvas.translate(AndroidUtilities.dp(8), AndroidUtilities.dp(4)); - backDrawable.draw(canvas); - canvas.restore(); - - - - if (expandProgress > 0) { + rectTmp.set(0, 0, AndroidUtilities.dp(40) + (menuText.getWidth() + AndroidUtilities.dp(4)) * expandProgress, getMeasuredHeight()); + canvas.drawRoundRect(rectTmp, AndroidUtilities.dp(16), AndroidUtilities.dp(16), paint); + backgroundDrawable.setBounds((int) rectTmp.left, (int) rectTmp.top, (int) rectTmp.right, (int) rectTmp.bottom); + backgroundDrawable.draw(canvas); canvas.save(); - canvas.translate(AndroidUtilities.dp(34), (getMeasuredHeight() - menuText.getHeight()) / 2f); - menuText.draw(canvas); + canvas.translate(AndroidUtilities.dp(8), AndroidUtilities.dp(4)); + backDrawable.draw(canvas); canvas.restore(); - } - if (update) { - onTranslationChanged((menuText.getWidth() + AndroidUtilities.dp(4)) * expandProgress); + if (expandProgress > 0) { + canvas.save(); + canvas.translate(AndroidUtilities.dp(34), (getMeasuredHeight() - menuText.getHeight()) / 2f); + menuText.draw(canvas); + canvas.restore(); + } + + if (update) { + onTranslationChanged((menuText.getWidth() + AndroidUtilities.dp(4)) * expandProgress); + } } super.dispatchDraw(canvas); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java index 9230bb929..4a3f6a981 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -144,8 +144,6 @@ import java.util.Locale; public class ChatActivityEnterView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate, SizeNotifierFrameLayout.SizeNotifierFrameLayoutDelegate, StickersAlert.StickersAlertDelegate { - boolean textTransitionIsRunning; - public interface ChatActivityEnterViewDelegate { void onMessageSend(CharSequence message, boolean notify, int scheduleDate); @@ -243,6 +241,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe private Runnable moveToSendStateRunnable; boolean messageTransitionIsRunning; + boolean textTransitionIsRunning; private BotCommandsMenuView botCommandsMenuButton; public BotCommandsMenuContainer botCommandsMenuContainer; @@ -4121,7 +4120,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe } } if (processSendingText(message, notify, scheduleDate)) { - if (delegate.hasForwardingMessages()) { + if (delegate.hasForwardingMessages() || (scheduleDate != 0 && !isInScheduleMode()) || isInScheduleMode()) { messageEditText.setText(""); if (delegate != null) { delegate.onMessageSend(message, notify, scheduleDate); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java index aba64d97d..f8f0a4759 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatAttachAlertPhotoLayout.java @@ -2874,7 +2874,7 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou @Override public boolean onSheetKeyDown(int keyCode, KeyEvent event) { - if (cameraOpened && (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) { + if (cameraOpened && (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_HEADSETHOOK || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)) { shutterButton.getDelegate().shutterReleased(); return true; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java index d6a59a78d..6a323af66 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java @@ -209,6 +209,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter float pinchScale; boolean isInPinchToZoomTouchMode; + boolean maybePinchToZoomTouchMode; private int pointerId1, pointerId2; @@ -2497,7 +2498,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter } if (ev.getActionMasked() == MotionEvent.ACTION_DOWN || ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { - if (!isInPinchToZoomTouchMode && ev.getPointerCount() == 2 && finishZoomTransition == null && recording) { + if (maybePinchToZoomTouchMode && !isInPinchToZoomTouchMode && ev.getPointerCount() == 2 && finishZoomTransition == null && recording) { pinchStartDistance = (float) Math.hypot(ev.getX(1) - ev.getX(0), ev.getY(1) - ev.getY(0)); pinchScale = 1f; @@ -2508,7 +2509,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter } if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { AndroidUtilities.rectTmp.set(cameraContainer.getX(), cameraContainer.getY(), cameraContainer.getX() + cameraContainer.getMeasuredWidth(), cameraContainer.getY() + cameraContainer.getMeasuredHeight()); - return AndroidUtilities.rectTmp.contains(ev.getX(), ev.getY()); + maybePinchToZoomTouchMode = AndroidUtilities.rectTmp.contains(ev.getX(), ev.getY()); } return true; } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE && isInPinchToZoomTouchMode) { @@ -2536,7 +2537,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter isInPinchToZoomTouchMode = false; finishZoom(); } - return isInPinchToZoomTouchMode; + return true; } ValueAnimator finishZoomTransition; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/MotionBackgroundDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/MotionBackgroundDrawable.java index 99f331925..db45718b3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/MotionBackgroundDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/MotionBackgroundDrawable.java @@ -314,7 +314,7 @@ public class MotionBackgroundDrawable extends Drawable { if (Build.VERSION.SDK_INT < 28 && intensity < 0) { int w = right - left; int h = bottom - top; - if (legacyBitmap == null || legacyBitmap.getWidth() != w || legacyBitmap.getHeight() != h) { + if (w > 0 && h > 0 && (legacyBitmap == null || legacyBitmap.getWidth() != w || legacyBitmap.getHeight() != h)) { if (legacyBitmap != null) { legacyBitmap.recycle(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java index 3a001953d..c606c0ede 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PasscodeView.java @@ -1090,14 +1090,22 @@ public class PasscodeView extends FrameLayout { FingerprintManagerCompat fingerprintManager = FingerprintManagerCompat.from(ApplicationLoader.applicationContext); if (fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints()) { fingerprintView.setVisibility(VISIBLE); + } else { + fingerprintView.setVisibility(GONE); } } catch (Throwable e) { FileLog.e(e); + fingerprintView.setVisibility(GONE); } + } else { + fingerprintView.setVisibility(GONE); } if (SharedConfig.passcodeType == 1) { fingerprintImage.setVisibility(fingerprintView.getVisibility()); } + if (numberFrameLayouts.size() >= 11) { + numberFrameLayouts.get(11).setVisibility(fingerprintView.getVisibility()); + } } public void onShow(boolean fingerprint, boolean animated, int x, int y, Runnable onShow, Runnable onStart) { @@ -1363,7 +1371,7 @@ public class PasscodeView extends FrameLayout { layoutParams = (LayoutParams) numbersFrameLayout.getLayoutParams(); layoutParams.height = height; layoutParams.leftMargin = width / 2; - layoutParams.topMargin = height - layoutParams.height; + layoutParams.topMargin = height - layoutParams.height + (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0); layoutParams.width = width / 2; numbersFrameLayout.setLayoutParams(layoutParams); } else { @@ -1390,10 +1398,10 @@ public class PasscodeView extends FrameLayout { passwordFrameLayout.setLayoutParams(layoutParams); layoutParams = (LayoutParams) numbersFrameLayout.getLayoutParams(); - layoutParams.height = height / 3 * 2 + AndroidUtilities.dp(20); + layoutParams.height = height / 3 * 2; layoutParams.leftMargin = left; if (AndroidUtilities.isTablet()) { - layoutParams.topMargin = height - layoutParams.height + top; + layoutParams.topMargin = height - layoutParams.height + top + AndroidUtilities.dp(20); } else { layoutParams.topMargin = height - layoutParams.height + top + (SharedConfig.passcodeType == 0 ? AndroidUtilities.dp(40) : 0); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/SearchCounterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/SearchCounterView.java index c1774ff85..6f0133a04 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/SearchCounterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/SearchCounterView.java @@ -237,13 +237,13 @@ public class SearchCounterView extends View { boolean increment = countAnimationIncrement; if (countAnimationInLayout != null) { canvas.save(); - canvas.translate(countLeft, countTop + AndroidUtilities.dp(4) + (increment ? AndroidUtilities.dp(13) : -AndroidUtilities.dp(13)) * (1f - countChangeProgress)); + canvas.translate(countLeft, countTop + AndroidUtilities.dp(2) + (increment ? AndroidUtilities.dp(13) : -AndroidUtilities.dp(13)) * (1f - countChangeProgress)); textPaint.setAlpha((int) (255 * countChangeProgress)); countAnimationInLayout.draw(canvas); canvas.restore(); } else if (countLayout != null) { canvas.save(); - canvas.translate(countLeft, countTop + AndroidUtilities.dp(4) + (increment ? AndroidUtilities.dp(13) : -AndroidUtilities.dp(13)) * (1f - countChangeProgress)); + canvas.translate(countLeft, countTop + AndroidUtilities.dp(2) + (increment ? AndroidUtilities.dp(13) : -AndroidUtilities.dp(13)) * (1f - countChangeProgress)); textPaint.setAlpha((int) (255 * countChangeProgress)); countLayout.draw(canvas); canvas.restore(); @@ -251,7 +251,7 @@ public class SearchCounterView extends View { if (countOldLayout != null) { canvas.save(); - canvas.translate(countLeft, countTop + AndroidUtilities.dp(4) + (increment ? -AndroidUtilities.dp(13) : AndroidUtilities.dp(13)) * (countChangeProgress)); + canvas.translate(countLeft, countTop + AndroidUtilities.dp(2) + (increment ? -AndroidUtilities.dp(13) : AndroidUtilities.dp(13)) * (countChangeProgress)); textPaint.setAlpha((int) (255 * (1f - countChangeProgress))); countOldLayout.draw(canvas); canvas.restore(); @@ -259,7 +259,7 @@ public class SearchCounterView extends View { if (countAnimationStableLayout != null) { canvas.save(); - canvas.translate(countLeft + dx * (1f - countChangeProgress), countTop + AndroidUtilities.dp(4)); + canvas.translate(countLeft + dx * (1f - countChangeProgress), countTop + AndroidUtilities.dp(2)); textPaint.setAlpha(255); countAnimationStableLayout.draw(canvas); canvas.restore(); @@ -267,7 +267,7 @@ public class SearchCounterView extends View { if (countAnimationStableLayout2 != null) { canvas.save(); - canvas.translate(countLeft, countTop + AndroidUtilities.dp(4)); + canvas.translate(countLeft, countTop + AndroidUtilities.dp(2)); textPaint.setAlpha(255); countAnimationStableLayout2.draw(canvas); canvas.restore(); @@ -299,7 +299,7 @@ public class SearchCounterView extends View { updateX(countWidth); if (countLayout != null) { canvas.save(); - canvas.translate(countLeft, countTop + AndroidUtilities.dp(4)); + canvas.translate(countLeft, countTop + AndroidUtilities.dp(2)); countLayout.draw(canvas); canvas.restore(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/voip/GroupCallMiniTextureView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/voip/GroupCallMiniTextureView.java index ada1502fd..b6745d826 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/voip/GroupCallMiniTextureView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/voip/GroupCallMiniTextureView.java @@ -254,18 +254,20 @@ public class GroupCallMiniTextureView extends FrameLayout implements GroupCallSt if (animateToFullscreen || showingInFullscreen) { size += (AndroidUtilities.dp(10) + AndroidUtilities.dp(39) * parentContainer.progressToFullscreenMode); } else { - size += AndroidUtilities.dp(10) * (1.0f - parentContainer.progressToFullscreenMode); + size += AndroidUtilities.dp(10) * Math.max(1.0f - parentContainer.progressToFullscreenMode, showingAsScrimView || animateToScrimView ? parentContainer.progressToScrimView : 0.0f); } int x = (getMeasuredWidth() - size) / 2; float smallProgress; + float smallProgress2; float scrimProgress = (showingAsScrimView || animateToScrimView ? parentContainer.progressToScrimView : 0); if (showingInFullscreen) { - smallProgress = progressToFullscreen; + smallProgress = smallProgress2 = progressToFullscreen; } else { smallProgress = animateToFullscreen ? parentContainer.progressToFullscreenMode : scrimProgress; + smallProgress2 = showingAsScrimView || animateToScrimView ? parentContainer.progressToScrimView : parentContainer.progressToFullscreenMode; } - int y = (int) ((getMeasuredHeight() - size) / 2 - AndroidUtilities.dp(11) - (AndroidUtilities.dp(17) + AndroidUtilities.dp(74) * parentContainer.progressToFullscreenMode) * smallProgress); + int y = (int) ((getMeasuredHeight() - size) / 2 - AndroidUtilities.dp(28) - (AndroidUtilities.dp(17) + AndroidUtilities.dp(74) * (showingInFullscreen || animateToFullscreen ? parentContainer.progressToFullscreenMode : 0.0f)) * smallProgress + AndroidUtilities.dp(17) * smallProgress2); castingScreenDrawable.setBounds(x, y, x + size, y + size); castingScreenDrawable.draw(canvas); @@ -1102,8 +1104,14 @@ public class GroupCallMiniTextureView extends FrameLayout implements GroupCallSt } boolean pausedInternal = false; - if (participant.participant.video != null && participant.participant.video.paused) { - pausedInternal = true; + if (participant.presentation) { + if (participant.participant.presentation != null && participant.participant.presentation.paused) { + pausedInternal = true; + } + } else { + if (participant.participant.video != null && participant.participant.video.paused) { + pausedInternal = true; + } } if (videoIsPaused != pausedInternal) { videoIsPaused = pausedInternal; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactsWidgetConfigActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactsWidgetConfigActivity.java index 3255f777e..127320b18 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsWidgetConfigActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsWidgetConfigActivity.java @@ -25,7 +25,7 @@ public class ContactsWidgetConfigActivity extends ExternalActionActivity { args.putBoolean("onlySelect", true); args.putInt("dialogsType", 10); args.putBoolean("allowSwitchAccount", true); - EditWidgetActivity fragment = new EditWidgetActivity(EditWidgetActivity.TYPE_CONTACTS, creatingAppWidgetId, false); + EditWidgetActivity fragment = new EditWidgetActivity(EditWidgetActivity.TYPE_CONTACTS, creatingAppWidgetId); fragment.setDelegate(dialogs -> { Intent resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, creatingAppWidgetId); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/EditWidgetActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/EditWidgetActivity.java index f4df734b4..9b68adf27 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/EditWidgetActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/EditWidgetActivity.java @@ -104,7 +104,6 @@ public class EditWidgetActivity extends BaseFragment { private int widgetType; private int currentWidgetId; - private boolean isEdit; private EditWidgetActivityDelegate delegate; @@ -733,18 +732,15 @@ public class EditWidgetActivity extends BaseFragment { } } - public EditWidgetActivity(int type, int widgetId, boolean edit) { + public EditWidgetActivity(int type, int widgetId) { super(); widgetType = type; currentWidgetId = widgetId; - isEdit = edit; - if (edit) { - ArrayList users = new ArrayList<>(); - ArrayList chats = new ArrayList<>(); - getMessagesStorage().getWidgetDialogIds(currentWidgetId, widgetType, selectedDialogs, users, chats, true); - getMessagesController().putUsers(users, true); - getMessagesController().putChats(chats, true); - } + ArrayList users = new ArrayList<>(); + ArrayList chats = new ArrayList<>(); + getMessagesStorage().getWidgetDialogIds(currentWidgetId, widgetType, selectedDialogs, users, chats, true); + getMessagesController().putUsers(users, true); + getMessagesController().putChats(chats, true); updateRows(); } @@ -810,14 +806,16 @@ public class EditWidgetActivity extends BaseFragment { getMessagesStorage().putWidgetDialogs(currentWidgetId, selectedDialogs); SharedPreferences preferences = getParentActivity().getSharedPreferences("shortcut_widget", Activity.MODE_PRIVATE); - preferences.edit().putInt("account" + currentWidgetId, currentAccount).commit(); - preferences.edit().putInt("type" + currentWidgetId, widgetType).commit(); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("account" + currentWidgetId, currentAccount); + editor.putInt("type" + currentWidgetId, widgetType); + editor.commit(); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getParentActivity()); if (widgetType == TYPE_CHATS) { - ChatsWidgetProvider.updateWidget(getParentActivity(), appWidgetManager, currentWidgetId, isEdit); + ChatsWidgetProvider.updateWidget(getParentActivity(), appWidgetManager, currentWidgetId); } else { - ContactsWidgetProvider.updateWidget(getParentActivity(), appWidgetManager, currentWidgetId, isEdit); + ContactsWidgetProvider.updateWidget(getParentActivity(), appWidgetManager, currentWidgetId); } if (delegate != null) { delegate.didSelectDialogs(selectedDialogs); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/FeedWidgetConfigActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/FeedWidgetConfigActivity.java index 8adfd46fa..c6272347c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/FeedWidgetConfigActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/FeedWidgetConfigActivity.java @@ -35,8 +35,10 @@ public class FeedWidgetConfigActivity extends ExternalActionActivity { AccountInstance.getInstance(fragment1.getCurrentAccount()).getMessagesStorage().putWidgetDialogs(creatingAppWidgetId, dids); SharedPreferences preferences = FeedWidgetConfigActivity.this.getSharedPreferences("shortcut_widget", Activity.MODE_PRIVATE); - preferences.edit().putInt("account" + creatingAppWidgetId, fragment1.getCurrentAccount()).commit(); - preferences.edit().putLong("dialogId" + creatingAppWidgetId, dids.get(0)).commit(); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt("account" + creatingAppWidgetId, fragment1.getCurrentAccount()); + editor.putLong("dialogId" + creatingAppWidgetId, dids.get(0)); + editor.commit(); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(FeedWidgetConfigActivity.this); FeedWidgetProvider.updateWidget(FeedWidgetConfigActivity.this, appWidgetManager, creatingAppWidgetId); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index a77a35e53..ea3b2e5c9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -308,7 +308,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa if (Build.VERSION.SDK_INT >= 24) { AndroidUtilities.isInMultiwindow = isInMultiWindowMode(); } - Theme.createCommonChatResources(this); + Theme.createCommonChatResources(); Theme.createDialogsResources(this); if (SharedConfig.passcodeHash.length() != 0 && SharedConfig.appLocked) { SharedConfig.lastPauseTime = (int) (SystemClock.elapsedRealtime() / 1000); @@ -2273,7 +2273,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa fragment = new ActionIntroActivity(ActionIntroActivity.ACTION_TYPE_CHANGE_PHONE_NUMBER); closePrevious = true; } else if (open_settings == 6) { - fragment = new EditWidgetActivity(open_widget_edit_type, open_widget_edit, true); + fragment = new EditWidgetActivity(open_widget_edit_type, open_widget_edit); } else { fragment = null; } @@ -3657,18 +3657,19 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa if (SharedConfig.pendingAppUpdate != null && SharedConfig.pendingAppUpdate.version.equals(res.version)) { return; } - SharedConfig.setNewAppVersionAvailable(res); - if (res.can_not_skip) { - showUpdateActivity(accountNum, res, false); - } else { - drawerLayoutAdapter.notifyDataSetChanged(); - try { - (new UpdateAppAlertDialog(LaunchActivity.this, res, accountNum)).show(); - } catch (Exception e) { - FileLog.e(e); + if (SharedConfig.setNewAppVersionAvailable(res)) { + if (res.can_not_skip) { + showUpdateActivity(accountNum, res, false); + } else { + drawerLayoutAdapter.notifyDataSetChanged(); + try { + (new UpdateAppAlertDialog(LaunchActivity.this, res, accountNum)).show(); + } catch (Exception e) { + FileLog.e(e); + } } + NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.appUpdateAvailable); } - NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.appUpdateAvailable); }); } }); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index 83cf4d4d9..8e3f44531 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -676,7 +676,12 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat BulletinFactory.of(containerView).createSimpleBulletin(R.raw.voip_invite, bulletinMessage).show(); } }); - builder.create().show(); + BottomSheet bottomSheet = builder.create(); + bottomSheet.show(); + bottomSheet.setItemColor(0,0xffffffff, 0xffffffff); + bottomSheet.setItemColor(1,0xffffffff, 0xffffffff); + bottomSheet.setBackgroundColor(0xff1C2229); + bottomSheet.setTitleColor(0xff8A8A8A); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index b147a8793..5cc2f1fd4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -1480,6 +1480,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override public View createView(Context context) { Theme.createProfileResources(context); + Theme.createChatResources(context, false); searchTransitionOffset = 0; searchTransitionProgress = 1f; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/TextMessageEnterTransition.java b/TMessagesProj/src/main/java/org/telegram/ui/TextMessageEnterTransition.java index d457d8ed7..47278b3a4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/TextMessageEnterTransition.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/TextMessageEnterTransition.java @@ -16,6 +16,7 @@ import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.os.Build; import android.text.Layout; +import android.text.Spannable; import android.text.SpannableString; import android.text.StaticLayout; import android.text.TextPaint; @@ -114,6 +115,9 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain enterView = chatActivity.getChatActivityEnterView(); ChatActivityEnterView chatActivityEnterView = chatActivity.getChatActivityEnterView(); + if (chatActivityEnterView == null || chatActivityEnterView.getEditField() == null || chatActivityEnterView.getEditField().getLayout() == null) { + return; + } fromRadius = chatActivityEnterView.getRecordCicle().drawingCircleRadius; bitmapPaint.setFilterBitmap(true); @@ -145,7 +149,18 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain emojiSize = AndroidUtilities.dp(24); } } - if (editText.length() != text.length()) { + boolean containsSpans = false; + if (text instanceof Spannable) { + Spannable spannable = (Spannable) text; + Object[] objects = spannable.getSpans(0, text.length(), Object.class); + for (int i = 0; i < objects.length; i++) { + if (!(objects[i] instanceof Emoji.EmojiSpan)) { + containsSpans = true; + break; + } + } + } + if (editText.length() != text.length() || containsSpans) { crossfade = true; String str = editText.toString(); String trimmedStr = str.trim(); @@ -543,78 +558,78 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain } canvas.save(); - { - canvas.clipRect(drawableX + AndroidUtilities.dp(4), drawableTop + AndroidUtilities.dp(4), drawableRight - AndroidUtilities.dp(4), drawableBottom - AndroidUtilities.dp(4)); - float scale = progressX + scaleFrom * (1f - progressX); - float scale2; - if (drawBitmaps) { - scale2 = progressX + scaleY * (1f - progressX); + canvas.clipRect(drawableX + AndroidUtilities.dp(4), drawableTop + AndroidUtilities.dp(4), drawableRight - AndroidUtilities.dp(4), drawableBottom - AndroidUtilities.dp(4)); + + float scale = progressX + scaleFrom * (1f - progressX); + float scale2; + if (drawBitmaps) { + scale2 = progressX + scaleY * (1f - progressX); + } else { + scale2 = 1f; + } + + canvas.save(); + canvas.translate(fromX * (1f - progressX) + (toX - toXOffset) * progressX, fromY * (1f - progress) + (toY + textLayoutBlock.textYOffset) * progress); + canvas.scale(scale, scale * scale2, 0, 0); + // canvas.translate(0, textLayoutBlock.textYOffset / 2); + if (drawBitmaps) { + if (crossfade) { + bitmapPaint.setAlpha((int) (255 * (1f - alphaProgress))); + } + canvas.drawBitmap(textLayoutBitmap, 0, 0, bitmapPaint); + } else { + if (crossfade) { + int oldAlpha = Theme.chat_msgTextPaint.getAlpha(); + Theme.chat_msgTextPaint.setAlpha((int) (oldAlpha * (1f - alphaProgress))); + layout.draw(canvas); + Theme.chat_msgTextPaint.setAlpha(oldAlpha); } else { - scale2 = 1f; + layout.draw(canvas); } + } + canvas.restore(); + + if (rtlLayout != null) { canvas.save(); - canvas.translate(fromX * (1f - progressX) + (toX - toXOffset) * progressX, fromY * (1f - progress) + (toY + textLayoutBlock.textYOffset) * progress); + canvas.translate(fromX * (1f - progressX) + (toX - toXOffsetRtl) * progressX, fromY * (1f - progress) + (toY + textLayoutBlock.textYOffset) * progress); canvas.scale(scale, scale * scale2, 0, 0); - // canvas.translate(0, textLayoutBlock.textYOffset / 2); if (drawBitmaps) { if (crossfade) { bitmapPaint.setAlpha((int) (255 * (1f - alphaProgress))); } - canvas.drawBitmap(textLayoutBitmap, 0, 0, bitmapPaint); + canvas.drawBitmap(textLayoutBitmapRtl, 0, 0, bitmapPaint); } else { if (crossfade) { int oldAlpha = Theme.chat_msgTextPaint.getAlpha(); Theme.chat_msgTextPaint.setAlpha((int) (oldAlpha * (1f - alphaProgress))); - layout.draw(canvas); + rtlLayout.draw(canvas); Theme.chat_msgTextPaint.setAlpha(oldAlpha); } else { - layout.draw(canvas); + rtlLayout.draw(canvas); } } canvas.restore(); - - if (rtlLayout != null) { - canvas.save(); - canvas.translate(fromX * (1f - progressX) + (toX - toXOffsetRtl) * progressX, fromY * (1f - progress) + (toY + textLayoutBlock.textYOffset) * progress); - canvas.scale(scale, scale * scale2, 0, 0); - if (drawBitmaps) { - if (crossfade) { - bitmapPaint.setAlpha((int) (255 * (1f - alphaProgress))); - } - canvas.drawBitmap(textLayoutBitmapRtl, 0, 0, bitmapPaint); - } else { - if (crossfade) { - int oldAlpha = Theme.chat_msgTextPaint.getAlpha(); - Theme.chat_msgTextPaint.setAlpha((int) (oldAlpha * (1f - alphaProgress))); - rtlLayout.draw(canvas); - Theme.chat_msgTextPaint.setAlpha(oldAlpha); - } else { - rtlLayout.draw(canvas); - } - - } - canvas.restore(); - } - - if (crossfade) { - canvas.save(); - canvas.translate(messageView.getLeft() + listView.getX() - container.getX() + (fromX - toX) * (1f - progressX), messageViewY + (fromY - toY) * (1f - progress)); - canvas.scale(scale, scale * scale2, messageView.getTextX(), messageView.getTextY()); - canvas.translate(0, -crossfadeTextOffset); - - if (drawBitmaps) { - bitmapPaint.setAlpha((int) (255 * alphaProgress)); - canvas.drawBitmap(crossfadeTextBitmap, 0, 0, bitmapPaint); - } else { - messageView.drawMessageText(canvas, messageView.getMessageObject().textLayoutBlocks, true, alphaProgress, true); - } - canvas.restore(); - } - } + + if (crossfade) { + canvas.save(); + canvas.translate(messageView.getLeft() + listView.getX() - container.getX() + (fromX - toX) * (1f - progressX), messageViewY + (fromY - toY) * (1f - progress)); + canvas.scale(scale, scale * scale2, messageView.getTextX(), messageView.getTextY()); + canvas.translate(0, -crossfadeTextOffset); + + if (crossfadeTextBitmap != null) { + bitmapPaint.setAlpha((int) (255 * alphaProgress)); + canvas.drawBitmap(crossfadeTextBitmap, 0, 0, bitmapPaint); + } else { + messageView.drawMessageText(canvas, messageView.getMessageObject().textLayoutBlocks, true, alphaProgress, true); + } + canvas.restore(); + } + + canvas.restore(); if (clipBottomWithAlpha) { @@ -631,8 +646,8 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain } if (enterView.getSendButton().getVisibility() == View.VISIBLE && sendProgress < 1f) { canvas.save(); - canvas.translate(enterView.getX() + enterView.getSendButton().getX() + ((View) enterView.getSendButton().getParent()).getX() + ((View) enterView.getSendButton().getParent().getParent()).getX() - container.getX() + AndroidUtilities.dp(52) * sendProgress, enterView.getY() + enterView.getSendButton().getY() + ((View) enterView.getSendButton().getParent()).getY() + ((View) enterView.getSendButton().getParent().getParent()).getY()- container.getY()); - // canvas.saveLayerAlpha(0, 0, enterView.getSendButton().getWidth(), enterView.getSendButton().getHeight(), (int) (enterView.getSendButton().getAlpha() * 255), Canvas.ALL_SAVE_FLAG); + canvas.translate(enterView.getX() + enterView.getSendButton().getX() + ((View) enterView.getSendButton().getParent()).getX() + ((View) enterView.getSendButton().getParent().getParent()).getX() - container.getX() + AndroidUtilities.dp(52) * sendProgress, enterView.getY() + enterView.getSendButton().getY() + ((View) enterView.getSendButton().getParent()).getY() + ((View) enterView.getSendButton().getParent().getParent()).getY() - container.getY()); + // canvas.saveLayerAlpha(0, 0, enterView.getSendButton().getWidth(), enterView.getSendButton().getHeight(), (int) (enterView.getSendButton().getAlpha() * 255), Canvas.ALL_SAVE_FLAG); //canvas.scale(enterView.getSendButton().getScaleX(), enterView.getSendButton().getScaleY(), enterView.getSendButton().getWidth() / 2f, enterView.getSendButton().getHeight() / 2f); enterView.getSendButton().draw(canvas); canvas.restore(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/VoIPPermissionActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/VoIPPermissionActivity.java index 8f9bb335b..a223f5017 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/VoIPPermissionActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/VoIPPermissionActivity.java @@ -29,7 +29,7 @@ public class VoIPPermissionActivity extends Activity { if (isVideoCall && checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { permissions.add(Manifest.permission.CAMERA); } - if (permissions.isEmpty()) { + if (!permissions.isEmpty()) { try { requestPermissions(permissions.toArray(new String[0]), isVideoCall ? 102 : 101); } catch (Exception e) { diff --git a/TMessagesProj/src/main/res/drawable-v21/widget_background.xml b/TMessagesProj/src/main/res/drawable-v21/widget_background.xml new file mode 100644 index 000000000..ecee3cc35 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-v21/widget_background.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/TMessagesProj/src/main/res/drawable-v31/widget_badge_background.xml b/TMessagesProj/src/main/res/drawable-v31/widget_badge_background.xml new file mode 100644 index 000000000..2ace851a0 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-v31/widget_badge_background.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/TMessagesProj/src/main/res/drawable-v31/widget_badge_muted_background.xml b/TMessagesProj/src/main/res/drawable-v31/widget_badge_muted_background.xml new file mode 100644 index 000000000..1423bfd62 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable-v31/widget_badge_muted_background.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/TMessagesProj/src/main/res/drawable/widget_avatar_1.png b/TMessagesProj/src/main/res/drawable/widget_avatar_1.png new file mode 100644 index 000000000..9fc96833e Binary files /dev/null and b/TMessagesProj/src/main/res/drawable/widget_avatar_1.png differ diff --git a/TMessagesProj/src/main/res/drawable/widget_avatar_2.png b/TMessagesProj/src/main/res/drawable/widget_avatar_2.png new file mode 100644 index 000000000..b160967c5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable/widget_avatar_2.png differ diff --git a/TMessagesProj/src/main/res/drawable/widget_avatar_3.png b/TMessagesProj/src/main/res/drawable/widget_avatar_3.png new file mode 100644 index 000000000..ab69d9d4a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable/widget_avatar_3.png differ diff --git a/TMessagesProj/src/main/res/drawable/widget_avatar_4.png b/TMessagesProj/src/main/res/drawable/widget_avatar_4.png new file mode 100644 index 000000000..c8f15afb9 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable/widget_avatar_4.png differ diff --git a/TMessagesProj/src/main/res/drawable/widget_avatar_5.png b/TMessagesProj/src/main/res/drawable/widget_avatar_5.png new file mode 100644 index 000000000..e48bf6c73 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable/widget_avatar_5.png differ diff --git a/TMessagesProj/src/main/res/drawable/widget_avatar_6.png b/TMessagesProj/src/main/res/drawable/widget_avatar_6.png new file mode 100644 index 000000000..6d2b8dcf7 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable/widget_avatar_6.png differ diff --git a/TMessagesProj/src/main/res/drawable/widget_avatar_7.png b/TMessagesProj/src/main/res/drawable/widget_avatar_7.png new file mode 100644 index 000000000..52d3775e5 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable/widget_avatar_7.png differ diff --git a/TMessagesProj/src/main/res/drawable/widget_badge_background.xml b/TMessagesProj/src/main/res/drawable/widget_badge_background.xml new file mode 100644 index 000000000..e826fef66 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/widget_badge_background.xml @@ -0,0 +1,3 @@ + + diff --git a/TMessagesProj/src/main/res/drawable/widget_badge_muted_background.xml b/TMessagesProj/src/main/res/drawable/widget_badge_muted_background.xml new file mode 100644 index 000000000..63f9c4693 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/widget_badge_muted_background.xml @@ -0,0 +1,3 @@ + + diff --git a/TMessagesProj/src/main/res/layout/contacts_widget_item.xml b/TMessagesProj/src/main/res/layout/contacts_widget_item.xml index 9ac5fdc75..2173d26dc 100644 --- a/TMessagesProj/src/main/res/layout/contacts_widget_item.xml +++ b/TMessagesProj/src/main/res/layout/contacts_widget_item.xml @@ -1,121 +1,15 @@ + android:baselineAligned="false" + android:minHeight="72dp" + android:orientation="horizontal" + android:weightSum="1"> - + - + - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/contacts_widget_item_1.xml b/TMessagesProj/src/main/res/layout/contacts_widget_item_1.xml new file mode 100644 index 000000000..3abe22faf --- /dev/null +++ b/TMessagesProj/src/main/res/layout/contacts_widget_item_1.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/contacts_widget_item_2.xml b/TMessagesProj/src/main/res/layout/contacts_widget_item_2.xml new file mode 100644 index 000000000..872aa8af2 --- /dev/null +++ b/TMessagesProj/src/main/res/layout/contacts_widget_item_2.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/contacts_widget_layout_1.xml b/TMessagesProj/src/main/res/layout/contacts_widget_layout_1.xml index 543980ae3..f55980bcb 100644 --- a/TMessagesProj/src/main/res/layout/contacts_widget_layout_1.xml +++ b/TMessagesProj/src/main/res/layout/contacts_widget_layout_1.xml @@ -1,11 +1,10 @@ - + android:orientation="vertical" + android:theme="@style/Theme.TMessages.AppWidget"> - + android:orientation="vertical" + android:theme="@style/Theme.TMessages.AppWidget"> - + android:orientation="vertical" + android:theme="@style/Theme.TMessages.AppWidget"> - + android:orientation="vertical" + android:theme="@style/Theme.TMessages.AppWidget"> + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/shortcut_widget_item.xml b/TMessagesProj/src/main/res/layout/shortcut_widget_item.xml index 87f48d98b..4248ce2d0 100644 --- a/TMessagesProj/src/main/res/layout/shortcut_widget_item.xml +++ b/TMessagesProj/src/main/res/layout/shortcut_widget_item.xml @@ -1,9 +1,10 @@ + android:layout_width="match_parent" + android:layout_height="72dp" + android:minHeight="72dp" + android:theme="@style/Theme.TMessages.AppWidget"> @@ -65,22 +69,16 @@ android:autoLink="none" android:textColorLink="@color/widget_text" android:layout_alignParentStart="true" + android:text="?attr/widgetPreviewContent" android:layout_toStartOf="@+id/shortcut_widget_item_badge"/> - + android:layout_marginStart="4dp" + android:text="2" + android:visibility="?attr/widgetPreviewDot" /> diff --git a/TMessagesProj/src/main/res/layout/shortcut_widget_layout_1.xml b/TMessagesProj/src/main/res/layout/shortcut_widget_layout_1.xml index 48a635f8c..a069cacc4 100644 --- a/TMessagesProj/src/main/res/layout/shortcut_widget_layout_1.xml +++ b/TMessagesProj/src/main/res/layout/shortcut_widget_layout_1.xml @@ -1,10 +1,10 @@ + android:orientation="vertical" + android:theme="@style/Theme.TMessages.AppWidget"> + android:orientation="vertical" + android:theme="@style/Theme.TMessages.AppWidget"> + android:orientation="vertical" + android:theme="@style/Theme.TMessages.AppWidget"> + android:orientation="vertical" + android:theme="@style/Theme.TMessages.AppWidget"> + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-v31/styles.xml b/TMessagesProj/src/main/res/values-v31/styles.xml new file mode 100644 index 000000000..8c12783b0 --- /dev/null +++ b/TMessagesProj/src/main/res/values-v31/styles.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + diff --git a/TMessagesProj/src/main/res/values-v31/values.xml b/TMessagesProj/src/main/res/values-v31/values.xml new file mode 100644 index 000000000..a28bad5e6 --- /dev/null +++ b/TMessagesProj/src/main/res/values-v31/values.xml @@ -0,0 +1,4 @@ + + + @android:dimen/system_app_widget_background_radius + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values/attrs.xml b/TMessagesProj/src/main/res/values/attrs.xml new file mode 100644 index 000000000..e622e06f0 --- /dev/null +++ b/TMessagesProj/src/main/res/values/attrs.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values/styles.xml b/TMessagesProj/src/main/res/values/styles.xml index a1f892932..f3a3ed764 100644 --- a/TMessagesProj/src/main/res/values/styles.xml +++ b/TMessagesProj/src/main/res/values/styles.xml @@ -130,4 +130,94 @@ false + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TMessagesProj/src/main/res/values/values.xml b/TMessagesProj/src/main/res/values/values.xml index d249ac5ac..640e58101 100644 --- a/TMessagesProj/src/main/res/values/values.xml +++ b/TMessagesProj/src/main/res/values/values.xml @@ -2,4 +2,5 @@ false 2dip + 16dp \ No newline at end of file diff --git a/TMessagesProj/src/main/res/xml/chats_widget_info.xml b/TMessagesProj/src/main/res/xml/chats_widget_info.xml index de15ba7a4..c441f762e 100644 --- a/TMessagesProj/src/main/res/xml/chats_widget_info.xml +++ b/TMessagesProj/src/main/res/xml/chats_widget_info.xml @@ -1,13 +1,20 @@ \ No newline at end of file diff --git a/TMessagesProj/src/main/res/xml/contacts_widget_info.xml b/TMessagesProj/src/main/res/xml/contacts_widget_info.xml index 46f69d980..c1c2ad848 100644 --- a/TMessagesProj/src/main/res/xml/contacts_widget_info.xml +++ b/TMessagesProj/src/main/res/xml/contacts_widget_info.xml @@ -3,11 +3,18 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="110dp" android:minHeight="86dp" + android:minResizeHeight="40dp" + android:maxResizeHeight="110dp" + android:targetCellWidth="2" + android:targetCellHeight="2" android:updatePeriodMillis="3600000" android:initialLayout="@layout/contacts_widget_layout_2" android:autoAdvanceViewId="@id/list_view" android:resizeMode="vertical" android:widgetCategory="home_screen" + android:description="@string/EditWidgetContactsInfo" android:previewImage="@drawable/contacts_widget_preview" + android:previewLayout="@layout/contacts_widget_layout_preview" + android:widgetFeatures="reconfigurable|configuration_optional" android:configure="org.telegram.ui.ContactsWidgetConfigActivity"> \ No newline at end of file