diff --git a/TMessagesProj/jni/voip/tgcalls/group/GroupNetworkManager.cpp b/TMessagesProj/jni/voip/tgcalls/group/GroupNetworkManager.cpp index a771d011f..c96da3bba 100644 --- a/TMessagesProj/jni/voip/tgcalls/group/GroupNetworkManager.cpp +++ b/TMessagesProj/jni/voip/tgcalls/group/GroupNetworkManager.cpp @@ -301,7 +301,7 @@ public: return webrtc::DtlsSrtpTransport::SendRtpPacket(packet, options, flags); } - void ProcessRtpPacket(webrtc::RtpPacketReceived const &packet, bool isUnresolved) { + void ProcessRtpPacket(webrtc::RtpPacketReceived const &packet, bool isUnresolved) override { _processRtpPacket(packet, isUnresolved); } diff --git a/TMessagesProj/jni/voip/tgcalls/platform/android/AndroidInterface.cpp b/TMessagesProj/jni/voip/tgcalls/platform/android/AndroidInterface.cpp index d8a2f1f98..307bd02f6 100644 --- a/TMessagesProj/jni/voip/tgcalls/platform/android/AndroidInterface.cpp +++ b/TMessagesProj/jni/voip/tgcalls/platform/android/AndroidInterface.cpp @@ -37,7 +37,6 @@ std::unique_ptr AndroidInterface::makeVideoEncoderF webrtc::ScopedJavaLocalRef factory_class = webrtc::GetClass(env, "org/webrtc/DefaultVideoEncoderFactory"); jmethodID factory_constructor = env->GetMethodID(factory_class.obj(), "", "(Lorg/webrtc/EglBase$Context;ZZ)V"); webrtc::ScopedJavaLocalRef factory_object(env, env->NewObject(factory_class.obj(), factory_constructor, eglContext, false, true)); - return webrtc::JavaToNativeVideoEncoderFactory(env, factory_object.obj()); } diff --git a/TMessagesProj/jni/voip/tgcalls/v2/InstanceV2Impl.cpp b/TMessagesProj/jni/voip/tgcalls/v2/InstanceV2Impl.cpp index 0af84f1d2..92bb98cee 100644 --- a/TMessagesProj/jni/voip/tgcalls/v2/InstanceV2Impl.cpp +++ b/TMessagesProj/jni/voip/tgcalls/v2/InstanceV2Impl.cpp @@ -879,6 +879,7 @@ public: "WebRTC-DataChannel-Dcsctp/Enabled/" "WebRTC-Audio-MinimizeResamplingOnMobile/Enabled/" "WebRTC-Audio-iOS-Holding/Enabled/" + "WebRTC-IceFieldTrials/skip_relay_to_non_relay_connections:true/" ); } @@ -2146,7 +2147,11 @@ InstanceV2Impl::InstanceV2Impl(Descriptor &&descriptor) { if (descriptor.config.logPath.data.size() != 0) { _logSink = std::make_unique(descriptor.config.logPath); } +#ifdef DEBUG + rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE); +#else rtc::LogMessage::LogToDebug(rtc::LS_INFO); +#endif rtc::LogMessage::SetLogToStderr(false); if (_logSink) { rtc::LogMessage::AddLogToStream(_logSink.get(), rtc::LS_INFO); diff --git a/TMessagesProj/jni/voip/tgcalls/v2/ReflectorPort.cpp b/TMessagesProj/jni/voip/tgcalls/v2/ReflectorPort.cpp index bb9f5d55b..0827b9a0a 100644 --- a/TMessagesProj/jni/voip/tgcalls/v2/ReflectorPort.cpp +++ b/TMessagesProj/jni/voip/tgcalls/v2/ReflectorPort.cpp @@ -364,7 +364,17 @@ cricket::Connection* ReflectorPort::CreateConnection(const cricket::Candidate& r if (!SupportsProtocol(remote_candidate.protocol())) { return nullptr; } - if (remote_candidate.address().port() != serverId_) { + + auto remoteHostname = remote_candidate.address().hostname(); + if (remoteHostname.empty()) { + return nullptr; + } + std::ostringstream ipFormat; + ipFormat << "reflector-" << (uint32_t)serverId_ << "-"; + if (!absl::StartsWith(remoteHostname, ipFormat.str()) || !absl::EndsWith(remoteHostname, ".reflector")) { + return nullptr; + } + if (remote_candidate.address().port() != server_address_.address.port()) { return nullptr; } @@ -424,9 +434,44 @@ int ReflectorPort::SendTo(const void* data, const rtc::PacketOptions& options, bool payload) { rtc::CopyOnWriteBuffer targetPeerTag; - uint32_t ipAddress = addr.ip(); + + auto syntheticHostname = addr.hostname(); + + uint32_t resolvedPeerTag = 0; + auto resolvedPeerTagIt = resolved_peer_tags_by_hostname_.find(syntheticHostname); + if (resolvedPeerTagIt != resolved_peer_tags_by_hostname_.end()) { + resolvedPeerTag = resolvedPeerTagIt->second; + } else { + std::ostringstream prefixFormat; + prefixFormat << "reflector-" << (uint32_t)serverId_ << "-"; + std::string suffixFormat = ".reflector"; + if (!absl::StartsWith(syntheticHostname, prefixFormat.str()) || !absl::EndsWith(syntheticHostname, suffixFormat)) { + RTC_LOG(LS_ERROR) << ToString() + << ": Discarding SendTo request with destination " + << addr.ToString(); + + return -1; + } + + auto startPosition = prefixFormat.str().size(); + auto tagString = syntheticHostname.substr(startPosition, syntheticHostname.size() - suffixFormat.size() - startPosition); + + std::stringstream tagStringStream(tagString); + tagStringStream >> resolvedPeerTag; + + if (resolvedPeerTag == 0) { + RTC_LOG(LS_ERROR) << ToString() + << ": Discarding SendTo request with destination " + << addr.ToString() << " (could not parse peer tag)"; + + return -1; + } + + resolved_peer_tags_by_hostname_.insert(std::make_pair(syntheticHostname, resolvedPeerTag)); + } + targetPeerTag.AppendData(peer_tag_.data(), peer_tag_.size() - 4); - targetPeerTag.AppendData((uint8_t *)&ipAddress, 4); + targetPeerTag.AppendData((uint8_t *)&resolvedPeerTag, 4); rtc::ByteBufferWriter bufferWriter; bufferWriter.WriteBytes((const char *)targetPeerTag.data(), targetPeerTag.size()); @@ -505,7 +550,13 @@ bool ReflectorPort::HandleIncomingPacket(rtc::AsyncPacketSocket* socket, if (state_ != STATE_READY) { state_ = STATE_READY; - rtc::SocketAddress candidateAddress(randomTag_, serverId_); + RTC_LOG(LS_INFO) + << ToString() + << ": REFLECTOR " << server_address_.address.ToString() << " is now ready"; + + std::ostringstream ipFormat; + ipFormat << "reflector-" << (uint32_t)serverId_ << "-" << randomTag_ << ".reflector"; + rtc::SocketAddress candidateAddress(ipFormat.str(), server_address_.address.port()); // For relayed candidate, Base is the candidate itself. AddAddress(candidateAddress, // Candidate address. @@ -545,7 +596,10 @@ bool ReflectorPort::HandleIncomingPacket(rtc::AsyncPacketSocket* socket, << ToString() << ": Received data packet with invalid size tag"; } else { - rtc::SocketAddress candidateAddress(senderTag, serverId_); + std::ostringstream ipFormat; + ipFormat << "reflector-" << (uint32_t)serverId_ << "-" << senderTag << ".reflector"; + rtc::SocketAddress candidateAddress(ipFormat.str(), server_address_.address.port()); + candidateAddress.SetResolvedIP(server_address_.address.ipaddr()); DispatchPacket(data + 16 + 4 + 4, dataSize, candidateAddress, cricket::ProtocolType::PROTO_UDP, packet_time_us); } diff --git a/TMessagesProj/jni/voip/tgcalls/v2/ReflectorPort.h b/TMessagesProj/jni/voip/tgcalls/v2/ReflectorPort.h index 1d2c0f7a5..8f0a3a12e 100644 --- a/TMessagesProj/jni/voip/tgcalls/v2/ReflectorPort.h +++ b/TMessagesProj/jni/voip/tgcalls/v2/ReflectorPort.h @@ -210,6 +210,8 @@ private: cricket::ProtocolAddress server_address_; uint8_t serverId_ = 0; + std::map resolved_peer_tags_by_hostname_; + cricket::RelayCredentials credentials_; AttemptedServerSet attempted_server_addresses_; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index a78a2c3b6..8e6e48b2d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -24,8 +24,8 @@ public class BuildVars { public static boolean USE_CLOUD_STRINGS = true; public static boolean CHECK_UPDATES = true; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; - public static int BUILD_VERSION = 3152; - public static String BUILD_VERSION_STRING = "9.4.5"; + public static int BUILD_VERSION = 3155; + public static String BUILD_VERSION_STRING = "9.4.6"; public static int APP_ID = 4; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java index 280ca8bfe..6e7f49f09 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java @@ -8,6 +8,7 @@ package org.telegram.messenger; +import org.telegram.messenger.utils.ImmutableByteArrayOutputStream; import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.NativeByteBuffer; import org.telegram.tgnet.TLObject; @@ -35,6 +36,7 @@ public class FileLoadOperation { long streamOffset; public static volatile DispatchQueue filesQueue = new DispatchQueue("writeFileQueue"); + public static ImmutableByteArrayOutputStream filesQueueByteBuffer; private boolean forceSmallChunk; public void setStream(FileLoadOperationStream stream, boolean streamPriority, long streamOffset) { @@ -518,18 +520,28 @@ public class FileLoadOperation { filesQueue.postRunnable(() -> { long time = System.currentTimeMillis(); try { + if (filePartsStream == null) { + return; + } + int countFinal = rangesFinal.size(); + int bufferSize = 4 + 8 * 2 * countFinal; + if (filesQueueByteBuffer == null) { + filesQueueByteBuffer = new ImmutableByteArrayOutputStream(bufferSize); + } else { + filesQueueByteBuffer.reset(); + } + filesQueueByteBuffer.writeInt(countFinal); + for (int a = 0; a < countFinal; a++) { + Range rangeFinal = rangesFinal.get(a); + filesQueueByteBuffer.writeLong(rangeFinal.start); + filesQueueByteBuffer.writeLong(rangeFinal.end); + } synchronized (FileLoadOperation.this) { if (filePartsStream == null) { return; } filePartsStream.seek(0); - int countFinal = rangesFinal.size(); - filePartsStream.writeInt(countFinal); - for (int a = 0; a < countFinal; a++) { - Range rangeFinal = rangesFinal.get(a); - filePartsStream.writeLong(rangeFinal.start); - filePartsStream.writeLong(rangeFinal.end); - } + filePartsStream.write(filesQueueByteBuffer.buf, 0, bufferSize); } } catch (Exception e) { if (AndroidUtilities.isENOSPC(e)) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java index cb9816c5a..c41a34d58 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java @@ -259,9 +259,9 @@ public class FileUploadOperation { started = true; if (stream == null) { File cacheFile = new File(uploadingFilePath); - if (AndroidUtilities.isInternalUri(Uri.fromFile(cacheFile))) { - throw new FileLog.IgnoreSentException("trying to upload internal file"); - } +// if (AndroidUtilities.isInternalUri(Uri.fromFile(cacheFile))) { +// throw new FileLog.IgnoreSentException("trying to upload internal file"); +// } stream = new RandomAccessFile(cacheFile, "r"); boolean isInternalFile = false; try { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/LiteMode.java b/TMessagesProj/src/main/java/org/telegram/messenger/LiteMode.java index d3cf3a91c..fa11f4f23 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/LiteMode.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/LiteMode.java @@ -30,11 +30,18 @@ public class LiteMode { public static final int FLAG_AUTOPLAY_VIDEOS = 1024; public static final int FLAG_AUTOPLAY_GIFS = 2048; + public static final int ENABLED = ( + FLAGS_ANIMATED_STICKERS | + FLAGS_ANIMATED_EMOJI | + FLAGS_CHAT | + FLAG_CALLS_ANIMATIONS + ); + public static final int PRESET_LOW = 0; public static final int PRESET_MEDIUM = ( - FLAG_ANIMATED_STICKERS_CHAT | - FLAG_ANIMATED_EMOJI_CHAT | - FLAG_CHAT_FORUM_TWOCOLUMN | + FLAGS_ANIMATED_STICKERS | + FLAGS_ANIMATED_EMOJI | + FLAGS_CHAT | FLAG_CALLS_ANIMATIONS | FLAG_AUTOPLAY_VIDEOS | FLAG_AUTOPLAY_GIFS @@ -111,6 +118,14 @@ public class LiteMode { final SharedPreferences preferences = MessagesController.getGlobalMainSettings(); if (!preferences.contains("lite_mode")) { + if (preferences.contains("light_mode")) { + boolean prevLiteModeEnabled = (preferences.getInt("light_mode", SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW ? 1 : 0) & 1) > 0; + if (prevLiteModeEnabled) { + defaultValue = PRESET_LOW; + } else { + defaultValue = PRESET_HIGH; + } + } // migrate settings if (preferences.contains("loopStickers")) { boolean loopStickers = preferences.getBoolean("loopStickers", true); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java index dabf93186..c2463ad46 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MediaController.java @@ -3647,8 +3647,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener, AndroidUtilities.runOnUIThread(() -> { recordStartRunnable = null; NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.recordStartError, guid); - NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.audioDidSent, recordingGuid, null, null); - }); return; } @@ -3657,7 +3655,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener, AndroidUtilities.runOnUIThread(() -> { recordStartRunnable = null; NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.recordStarted, guid, true); - NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.audioDidSent, recordingGuid, null, null); }); }, paused ? 500 : 50); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java index bb827e91f..b365371e4 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessageObject.java @@ -2360,6 +2360,7 @@ public class MessageObject { messageOwner.peer_id.channel_id = chat.id; messageOwner.unread = false; MediaController mediaController = MediaController.getInstance(); + isOutOwnerCached = null; if (message instanceof TLRPC.TL_messageEmpty) { message = null; @@ -5608,7 +5609,7 @@ public class MessageObject { return messageOwner.out; } - Boolean isOutOwnerCached; + public Boolean isOutOwnerCached; public boolean isOutOwner() { if (preview) { return true; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java index ab1cf9957..a355abdfd 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java @@ -945,7 +945,7 @@ public class SharedConfig { } public static void toggleAutoplayVideo() { - LiteMode.toggleFlag(LiteMode.FLAG_AUTOPLAY_VIDEOS, !isAutoplayVideo()); + LiteMode.toggleFlag(LiteMode.FLAG_AUTOPLAY_VIDEOS); } public static boolean isSecretMapPreviewSet() { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java b/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java index b7bc980f8..1614c5c08 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/utils/BitmapsCache.java @@ -16,11 +16,9 @@ import org.telegram.ui.Components.RLottieDrawable; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.OutputStream; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.concurrent.ConcurrentHashMap; @@ -224,7 +222,7 @@ public class BitmapsCache { } sharedTools.allocate(h, w); Bitmap[] bitmap = sharedTools.bitmap; - ByteArrayOutputStream[] byteArrayOutputStream = sharedTools.byteArrayOutputStream; + ImmutableByteArrayOutputStream[] byteArrayOutputStream = sharedTools.byteArrayOutputStream; CountDownLatch[] countDownLatch = new CountDownLatch[N]; ArrayList frameOffsets = new ArrayList<>(); @@ -587,82 +585,6 @@ public class BitmapsCache { Bitmap getFirstFrame(Bitmap bitmap); } - public static class ByteArrayOutputStream extends OutputStream { - - protected byte buf[]; - - protected int count; - - public ByteArrayOutputStream() { - this(32); - } - - public ByteArrayOutputStream(int size) { - buf = new byte[size]; - } - - private void ensureCapacity(int minCapacity) { - if (minCapacity - buf.length > 0) { - grow(minCapacity); - } - } - - private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; - - private void grow(int minCapacity) { - int oldCapacity = buf.length; - int newCapacity = oldCapacity << 1; - if (newCapacity - minCapacity < 0) - newCapacity = minCapacity; - if (newCapacity - MAX_ARRAY_SIZE > 0) - newCapacity = hugeCapacity(minCapacity); - buf = Arrays.copyOf(buf, newCapacity); - } - - private static int hugeCapacity(int minCapacity) { - if (minCapacity < 0) // overflow - throw new OutOfMemoryError(); - return (minCapacity > MAX_ARRAY_SIZE) ? - Integer.MAX_VALUE : - MAX_ARRAY_SIZE; - } - - public synchronized void write(int b) { - ensureCapacity(count + 1); - buf[count] = (byte) b; - count += 1; - } - - public void writeInt(int value) { - ensureCapacity(count + 4); - buf[count] = (byte) (value >>> 24); - buf[count + 1] = (byte) (value >>> 16); - buf[count + 2] = (byte) (value >>> 8); - buf[count + 3] = (byte) (value); - count += 4; - } - - public synchronized void write(byte b[], int off, int len) { - if ((off < 0) || (off > b.length) || (len < 0) || - ((off + len) - b.length > 0)) { - throw new IndexOutOfBoundsException(); - } - ensureCapacity(count + len); - System.arraycopy(b, off, buf, count, len); - count += len; - } - - public synchronized void writeTo(OutputStream out) throws IOException { - out.write(buf, 0, count); - } - - public synchronized void reset() { - count = 0; - } - - - } - public static class Metadata { public int frame; } @@ -674,7 +596,7 @@ public class BitmapsCache { } private static class CacheGeneratorSharedTools { - ByteArrayOutputStream[] byteArrayOutputStream = new ByteArrayOutputStream[N]; + ImmutableByteArrayOutputStream[] byteArrayOutputStream = new ImmutableByteArrayOutputStream[N]; private Bitmap[] bitmap = new Bitmap[N]; private int lastSize; @@ -701,7 +623,7 @@ public class BitmapsCache { bitmap[i] = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); } if (byteArrayOutputStream[i] == null) { - byteArrayOutputStream[i] = new ByteArrayOutputStream(w * h * 2); + byteArrayOutputStream[i] = new ImmutableByteArrayOutputStream(w * h * 2); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/utils/ImmutableByteArrayOutputStream.java b/TMessagesProj/src/main/java/org/telegram/messenger/utils/ImmutableByteArrayOutputStream.java new file mode 100644 index 000000000..38b6b98a3 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/messenger/utils/ImmutableByteArrayOutputStream.java @@ -0,0 +1,93 @@ +package org.telegram.messenger.utils; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; + +public class ImmutableByteArrayOutputStream extends OutputStream { + + public byte buf[]; + + protected int count; + + public ImmutableByteArrayOutputStream() { + this(32); + } + + public ImmutableByteArrayOutputStream(int size) { + buf = new byte[size]; + } + + private void ensureCapacity(int minCapacity) { + if (minCapacity - buf.length > 0) { + grow(minCapacity); + } + } + + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + + private void grow(int minCapacity) { + int oldCapacity = buf.length; + int newCapacity = oldCapacity << 1; + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + buf = Arrays.copyOf(buf, newCapacity); + } + + private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError(); + return (minCapacity > MAX_ARRAY_SIZE) ? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; + } + + public synchronized void write(int b) { + ensureCapacity(count + 1); + buf[count] = (byte) b; + count += 1; + } + + public void writeInt(int value) { + ensureCapacity(count + 4); + buf[count] = (byte) (value >>> 24); + buf[count + 1] = (byte) (value >>> 16); + buf[count + 2] = (byte) (value >>> 8); + buf[count + 3] = (byte) (value); + count += 4; + } + + public void writeLong(long value) { + ensureCapacity(count + 8); + buf[count] = (byte) (value >>> 56); + buf[count + 1] = (byte) (value >>> 48); + buf[count + 2] = (byte) (value >>> 40); + buf[count + 3] = (byte) (value >>> 32); + buf[count + 4] = (byte) (value >>> 24); + buf[count + 5] = (byte) (value >>> 16); + buf[count + 6] = (byte) (value >>> 8); + buf[count + 7] = (byte) (value); + count += 8; + } + + public synchronized void write(byte b[], int off, int len) { + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) - b.length > 0)) { + throw new IndexOutOfBoundsException(); + } + ensureCapacity(count + len); + System.arraycopy(b, off, buf, count, len); + count += len; + } + + public synchronized void writeTo(OutputStream out) throws IOException { + out.write(buf, 0, count); + } + + public synchronized void reset() { + count = 0; + } + +} 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 9f731558f..01642a9c1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -4055,7 +4055,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (!loadDocumentFromImageReceiver) { TLRPC.PhotoSize photo = document == null ? FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.photoThumbs, AndroidUtilities.getPhotoSize()) : null; if (canDownload == 2 || canDownload == 1 && currentMessageObject.isVideo()) { - if (document != null && !currentMessageObject.shouldEncryptPhotoOrVideo() && currentMessageObject.canStreamVideo()) { + if (canDownload != 2 && document != null && !currentMessageObject.shouldEncryptPhotoOrVideo() && currentMessageObject.canStreamVideo()) { FileLoader.getInstance(currentAccount).loadFile(document, currentMessageObject, FileLoader.PRIORITY_NORMAL, 0); } } else if (canDownload != 0) { @@ -4113,6 +4113,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate if (messageObject.checkLayout() || currentPosition != null && lastHeight != AndroidUtilities.displaySize.y) { currentMessageObject = null; } + messageObject.isOutOwnerCached = null; boolean widthChanged = lastWidth != getParentWidth(); lastHeight = AndroidUtilities.displaySize.y; lastWidth = getParentWidth(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index f71803e50..d257ff0bb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -16726,6 +16726,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not obj.messageOwner = newMsgObj; if (fwdHeader != null && newMsgObj.fwd_from != null && !TextUtils.isEmpty(newMsgObj.fwd_from.from_name)) { obj.messageOwner.fwd_from = fwdHeader; + obj.isOutOwnerCached = null; } obj.generateThumbs(true); obj.setType(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java index e2f07b4bf..c404ae3c9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java @@ -856,6 +856,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente fragment.setDelegate(new GroupCreateActivity.ContactsAddActivityDelegate() { @Override public void didSelectUsers(ArrayList users, int fwdCount) { + if (fragment.getParentActivity() == null) { + return; + } final int count = users.size(); final int[] processed = new int[1]; final ArrayList userRestrictedPrivacy = new ArrayList<>(); @@ -879,7 +882,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente title = LocaleController.getString("InviteToGroupErrorTitleSomeUsers", R.string.InviteToGroupErrorTitleSomeUsers); description = LocaleController.getString("InviteToGroupErrorMessageMultipleSome", R.string.InviteToGroupErrorMessageMultipleSome); } - new AlertDialog.Builder(fragment.getContext()) + new AlertDialog.Builder(fragment.getParentActivity()) .setTitle(title) .setMessage(description) .setPositiveButton(LocaleController.getString("OK", R.string.OK), null) 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 8c11d149f..1856d2cd6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/InstantCameraView.java @@ -592,7 +592,6 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter } MediaController.getInstance().pauseMessage(MediaController.getInstance().getPlayingMessageObject()); - FileLoader.getDirectory(FileLoader.MEDIA_DIR_DOCUMENT).mkdirs(); cameraFile = new File(FileLoader.getDirectory(FileLoader.MEDIA_DIR_DOCUMENT), System.currentTimeMillis() + "_" + SharedConfig.getLastLocalId() + ".mp4") { @Override public boolean delete() { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/PipVideoOverlay.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/PipVideoOverlay.java index eb8b87125..70c2054bb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/PipVideoOverlay.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/PipVideoOverlay.java @@ -376,10 +376,10 @@ public class PipVideoOverlay { private void onDismissedInternal() { try { - if (controlsView.getParent() != null) { + if (contentView != null && contentView.getParent() != null) { windowManager.removeViewImmediate(contentView); } - } catch (IllegalArgumentException ignored) {} + } catch (Exception ignored) {} if (photoViewerWebView != null) { photoViewerWebView.showControls(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DataSettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DataSettingsActivity.java index 61837674e..cf569b09e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DataSettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DataSettingsActivity.java @@ -499,7 +499,7 @@ public class DataSettingsActivity extends BaseFragment { } else if (position == autoplayVideoRow) { SharedConfig.toggleAutoplayVideo(); if (view instanceof TextCheckCell) { - ((TextCheckCell) view).setChecked(SharedConfig.isAutoplayGifs()); + ((TextCheckCell) view).setChecked(SharedConfig.isAutoplayVideo()); } } else if (position == clearDraftsRow) { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index 8eb486d5d..4eea77ac8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -1130,13 +1130,23 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. @Override public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type, int[] consumed) { - if (target == listView && sharedMediaLayoutAttached) { - RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); - int top = sharedMediaLayout.getTop(); - if (top == 0) { - consumed[1] = dyUnconsumed; - innerListView.scrollBy(0, dyUnconsumed); + try { + if (target == listView && sharedMediaLayoutAttached) { + RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); + int top = sharedMediaLayout.getTop(); + if (top == 0) { + consumed[1] = dyUnconsumed; + innerListView.scrollBy(0, dyUnconsumed); + } } + } catch (Throwable e) { + FileLog.e(e); + AndroidUtilities.runOnUIThread(() -> { + RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); + if (innerListView != null && innerListView.getAdapter() != null) { + innerListView.getAdapter().notifyDataSetChanged(); + } + }); } } @@ -4975,6 +4985,9 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. break; case PHONE_OPTION_TELEGRAM_CALL: case PHONE_OPTION_TELEGRAM_VIDEO_CALL: + if (getParentActivity() == null) { + return; + } VoIPHelper.startCall(user, action == PHONE_OPTION_TELEGRAM_VIDEO_CALL, userInfo != null && userInfo.video_calls_available, getParentActivity(), userInfo, getAccountInstance()); break; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java index e5cf4a015..104c60e97 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ThemeActivity.java @@ -1159,9 +1159,11 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No ((TextCheckCell) view).setChecked(SharedConfig.chatBlurEnabled()); } } else if (position == lightModeRow) { - LiteMode.setAllFlags(LiteMode.getValue() == LiteMode.PRESET_LOW ? LiteMode.PRESET_HIGH : LiteMode.PRESET_LOW); + boolean liteModeEnabled = (LiteMode.getValue() & LiteMode.ENABLED) == 0; + int newFlags = (liteModeEnabled ? LiteMode.ENABLED : 0) | (LiteMode.getValue() & ~LiteMode.ENABLED); + LiteMode.setAllFlags(newFlags); if (view instanceof TextCheckCell) { - ((TextCheckCell) view).setChecked(LiteMode.getValue() == LiteMode.PRESET_LOW); + ((TextCheckCell) view).setChecked((LiteMode.getValue() & LiteMode.ENABLED) == 0); } } else if (position == nightThemeRow) { if (LocaleController.isRTL && x <= AndroidUtilities.dp(76) || !LocaleController.isRTL && x >= view.getMeasuredWidth() - AndroidUtilities.dp(76)) { @@ -2254,7 +2256,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No } else if (position == chatBlurRow) { textCheckCell.setTextAndCheck(LocaleController.getString("BlurInChat", R.string.BlurInChat), SharedConfig.chatBlurEnabled(), true); } else if (position == lightModeRow) { - textCheckCell.setTextAndCheck(LocaleController.getString("LightMode", R.string.LightMode), LiteMode.getValue() == LiteMode.PRESET_LOW, true); + textCheckCell.setTextAndCheck(LocaleController.getString("LightMode", R.string.LightMode), (LiteMode.getValue() & LiteMode.ENABLED) == 0, true); } break; } diff --git a/TMessagesProj/src/main/java/org/webrtc/voiceengine/WebRtcAudioTrack.java b/TMessagesProj/src/main/java/org/webrtc/voiceengine/WebRtcAudioTrack.java index 3d7484661..7aa4729ec 100644 --- a/TMessagesProj/src/main/java/org/webrtc/voiceengine/WebRtcAudioTrack.java +++ b/TMessagesProj/src/main/java/org/webrtc/voiceengine/WebRtcAudioTrack.java @@ -21,6 +21,7 @@ import android.os.Process; import androidx.annotation.Nullable; +import org.telegram.messenger.FileLog; import org.webrtc.ContextUtils; import org.webrtc.Logging; import org.webrtc.ThreadUtils; @@ -334,21 +335,30 @@ public class WebRtcAudioTrack { } private boolean stopPlayout() { - threadChecker.checkIsOnValidThread(); - Logging.d(TAG, "stopPlayout"); - assertTrue(audioThread != null); - logUnderrunCount(); - audioThread.stopThread(); + try { + threadChecker.checkIsOnValidThread(); + Logging.d(TAG, "stopPlayout"); + assertTrue(audioThread != null); + logUnderrunCount(); + audioThread.stopThread(); - Logging.d(TAG, "Stopping the AudioTrackThread..."); - audioThread.interrupt(); - if (!ThreadUtils.joinUninterruptibly(audioThread, AUDIO_TRACK_THREAD_JOIN_TIMEOUT_MS)) { - Logging.e(TAG, "Join of AudioTrackThread timed out."); - WebRtcAudioUtils.logAudioState(TAG); + Logging.d(TAG, "Stopping the AudioTrackThread..."); + audioThread.interrupt(); + if (!ThreadUtils.joinUninterruptibly(audioThread, AUDIO_TRACK_THREAD_JOIN_TIMEOUT_MS)) { + Logging.e(TAG, "Join of AudioTrackThread timed out."); + WebRtcAudioUtils.logAudioState(TAG); + } + Logging.d(TAG, "AudioTrackThread has now been stopped."); + } catch (Throwable e) { + FileLog.e(e); + } finally { + audioThread = null; + } + try { + releaseAudioResources(); + } catch (Throwable e) { + FileLog.e(e); } - Logging.d(TAG, "AudioTrackThread has now been stopped."); - audioThread = null; - releaseAudioResources(); return true; } diff --git a/gradle.properties b/gradle.properties index f15308d20..96f835ba6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,8 +13,8 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Sat Mar 12 05:53:50 MSK 2016 -APP_VERSION_NAME=9.4.5 -APP_VERSION_CODE=3152 +APP_VERSION_NAME=9.4.6 +APP_VERSION_CODE=3155 APP_PACKAGE=org.telegram.messenger RELEASE_KEY_PASSWORD=android RELEASE_KEY_ALIAS=androidkey