update to 9.4.6

This commit is contained in:
xaxtix 2023-02-26 06:55:06 +04:00
parent 810bc4ae67
commit 116092e32d
24 changed files with 267 additions and 138 deletions

View file

@ -301,7 +301,7 @@ public:
return webrtc::DtlsSrtpTransport::SendRtpPacket(packet, options, flags); 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); _processRtpPacket(packet, isUnresolved);
} }

View file

@ -37,7 +37,6 @@ std::unique_ptr<webrtc::VideoEncoderFactory> AndroidInterface::makeVideoEncoderF
webrtc::ScopedJavaLocalRef<jclass> factory_class = webrtc::GetClass(env, "org/webrtc/DefaultVideoEncoderFactory"); webrtc::ScopedJavaLocalRef<jclass> factory_class = webrtc::GetClass(env, "org/webrtc/DefaultVideoEncoderFactory");
jmethodID factory_constructor = env->GetMethodID(factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V"); jmethodID factory_constructor = env->GetMethodID(factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
webrtc::ScopedJavaLocalRef<jobject> factory_object(env, env->NewObject(factory_class.obj(), factory_constructor, eglContext, false, true)); webrtc::ScopedJavaLocalRef<jobject> factory_object(env, env->NewObject(factory_class.obj(), factory_constructor, eglContext, false, true));
return webrtc::JavaToNativeVideoEncoderFactory(env, factory_object.obj()); return webrtc::JavaToNativeVideoEncoderFactory(env, factory_object.obj());
} }

View file

@ -879,6 +879,7 @@ public:
"WebRTC-DataChannel-Dcsctp/Enabled/" "WebRTC-DataChannel-Dcsctp/Enabled/"
"WebRTC-Audio-MinimizeResamplingOnMobile/Enabled/" "WebRTC-Audio-MinimizeResamplingOnMobile/Enabled/"
"WebRTC-Audio-iOS-Holding/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) { if (descriptor.config.logPath.data.size() != 0) {
_logSink = std::make_unique<LogSinkImpl>(descriptor.config.logPath); _logSink = std::make_unique<LogSinkImpl>(descriptor.config.logPath);
} }
#ifdef DEBUG
rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE);
#else
rtc::LogMessage::LogToDebug(rtc::LS_INFO); rtc::LogMessage::LogToDebug(rtc::LS_INFO);
#endif
rtc::LogMessage::SetLogToStderr(false); rtc::LogMessage::SetLogToStderr(false);
if (_logSink) { if (_logSink) {
rtc::LogMessage::AddLogToStream(_logSink.get(), rtc::LS_INFO); rtc::LogMessage::AddLogToStream(_logSink.get(), rtc::LS_INFO);

View file

@ -364,7 +364,17 @@ cricket::Connection* ReflectorPort::CreateConnection(const cricket::Candidate& r
if (!SupportsProtocol(remote_candidate.protocol())) { if (!SupportsProtocol(remote_candidate.protocol())) {
return nullptr; 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; return nullptr;
} }
@ -424,9 +434,44 @@ int ReflectorPort::SendTo(const void* data,
const rtc::PacketOptions& options, const rtc::PacketOptions& options,
bool payload) { bool payload) {
rtc::CopyOnWriteBuffer targetPeerTag; 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(peer_tag_.data(), peer_tag_.size() - 4);
targetPeerTag.AppendData((uint8_t *)&ipAddress, 4); targetPeerTag.AppendData((uint8_t *)&resolvedPeerTag, 4);
rtc::ByteBufferWriter bufferWriter; rtc::ByteBufferWriter bufferWriter;
bufferWriter.WriteBytes((const char *)targetPeerTag.data(), targetPeerTag.size()); bufferWriter.WriteBytes((const char *)targetPeerTag.data(), targetPeerTag.size());
@ -505,7 +550,13 @@ bool ReflectorPort::HandleIncomingPacket(rtc::AsyncPacketSocket* socket,
if (state_ != STATE_READY) { if (state_ != STATE_READY) {
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. // For relayed candidate, Base is the candidate itself.
AddAddress(candidateAddress, // Candidate address. AddAddress(candidateAddress, // Candidate address.
@ -545,7 +596,10 @@ bool ReflectorPort::HandleIncomingPacket(rtc::AsyncPacketSocket* socket,
<< ToString() << ToString()
<< ": Received data packet with invalid size tag"; << ": Received data packet with invalid size tag";
} else { } 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); DispatchPacket(data + 16 + 4 + 4, dataSize, candidateAddress, cricket::ProtocolType::PROTO_UDP, packet_time_us);
} }

View file

@ -210,6 +210,8 @@ private:
cricket::ProtocolAddress server_address_; cricket::ProtocolAddress server_address_;
uint8_t serverId_ = 0; uint8_t serverId_ = 0;
std::map<std::string, uint32_t> resolved_peer_tags_by_hostname_;
cricket::RelayCredentials credentials_; cricket::RelayCredentials credentials_;
AttemptedServerSet attempted_server_addresses_; AttemptedServerSet attempted_server_addresses_;

View file

@ -24,8 +24,8 @@ public class BuildVars {
public static boolean USE_CLOUD_STRINGS = true; public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true; public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29; public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 3152; public static int BUILD_VERSION = 3155;
public static String BUILD_VERSION_STRING = "9.4.5"; public static String BUILD_VERSION_STRING = "9.4.6";
public static int APP_ID = 4; public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103"; public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";

View file

@ -8,6 +8,7 @@
package org.telegram.messenger; package org.telegram.messenger;
import org.telegram.messenger.utils.ImmutableByteArrayOutputStream;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.NativeByteBuffer; import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
@ -35,6 +36,7 @@ public class FileLoadOperation {
long streamOffset; long streamOffset;
public static volatile DispatchQueue filesQueue = new DispatchQueue("writeFileQueue"); public static volatile DispatchQueue filesQueue = new DispatchQueue("writeFileQueue");
public static ImmutableByteArrayOutputStream filesQueueByteBuffer;
private boolean forceSmallChunk; private boolean forceSmallChunk;
public void setStream(FileLoadOperationStream stream, boolean streamPriority, long streamOffset) { public void setStream(FileLoadOperationStream stream, boolean streamPriority, long streamOffset) {
@ -518,18 +520,28 @@ public class FileLoadOperation {
filesQueue.postRunnable(() -> { filesQueue.postRunnable(() -> {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
try { 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) { synchronized (FileLoadOperation.this) {
if (filePartsStream == null) { if (filePartsStream == null) {
return; return;
} }
filePartsStream.seek(0); filePartsStream.seek(0);
int countFinal = rangesFinal.size(); filePartsStream.write(filesQueueByteBuffer.buf, 0, bufferSize);
filePartsStream.writeInt(countFinal);
for (int a = 0; a < countFinal; a++) {
Range rangeFinal = rangesFinal.get(a);
filePartsStream.writeLong(rangeFinal.start);
filePartsStream.writeLong(rangeFinal.end);
}
} }
} catch (Exception e) { } catch (Exception e) {
if (AndroidUtilities.isENOSPC(e)) { if (AndroidUtilities.isENOSPC(e)) {

View file

@ -259,9 +259,9 @@ public class FileUploadOperation {
started = true; started = true;
if (stream == null) { if (stream == null) {
File cacheFile = new File(uploadingFilePath); File cacheFile = new File(uploadingFilePath);
if (AndroidUtilities.isInternalUri(Uri.fromFile(cacheFile))) { // if (AndroidUtilities.isInternalUri(Uri.fromFile(cacheFile))) {
throw new FileLog.IgnoreSentException("trying to upload internal file"); // throw new FileLog.IgnoreSentException("trying to upload internal file");
} // }
stream = new RandomAccessFile(cacheFile, "r"); stream = new RandomAccessFile(cacheFile, "r");
boolean isInternalFile = false; boolean isInternalFile = false;
try { try {

View file

@ -30,11 +30,18 @@ public class LiteMode {
public static final int FLAG_AUTOPLAY_VIDEOS = 1024; public static final int FLAG_AUTOPLAY_VIDEOS = 1024;
public static final int FLAG_AUTOPLAY_GIFS = 2048; 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_LOW = 0;
public static final int PRESET_MEDIUM = ( public static final int PRESET_MEDIUM = (
FLAG_ANIMATED_STICKERS_CHAT | FLAGS_ANIMATED_STICKERS |
FLAG_ANIMATED_EMOJI_CHAT | FLAGS_ANIMATED_EMOJI |
FLAG_CHAT_FORUM_TWOCOLUMN | FLAGS_CHAT |
FLAG_CALLS_ANIMATIONS | FLAG_CALLS_ANIMATIONS |
FLAG_AUTOPLAY_VIDEOS | FLAG_AUTOPLAY_VIDEOS |
FLAG_AUTOPLAY_GIFS FLAG_AUTOPLAY_GIFS
@ -111,6 +118,14 @@ public class LiteMode {
final SharedPreferences preferences = MessagesController.getGlobalMainSettings(); final SharedPreferences preferences = MessagesController.getGlobalMainSettings();
if (!preferences.contains("lite_mode")) { 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 // migrate settings
if (preferences.contains("loopStickers")) { if (preferences.contains("loopStickers")) {
boolean loopStickers = preferences.getBoolean("loopStickers", true); boolean loopStickers = preferences.getBoolean("loopStickers", true);

View file

@ -3647,8 +3647,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
recordStartRunnable = null; recordStartRunnable = null;
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.recordStartError, guid); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.recordStartError, guid);
NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.audioDidSent, recordingGuid, null, null);
}); });
return; return;
} }
@ -3657,7 +3655,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
recordStartRunnable = null; recordStartRunnable = null;
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.recordStarted, guid, true); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.recordStarted, guid, true);
NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.audioDidSent, recordingGuid, null, null);
}); });
}, paused ? 500 : 50); }, paused ? 500 : 50);
} }

View file

@ -2360,6 +2360,7 @@ public class MessageObject {
messageOwner.peer_id.channel_id = chat.id; messageOwner.peer_id.channel_id = chat.id;
messageOwner.unread = false; messageOwner.unread = false;
MediaController mediaController = MediaController.getInstance(); MediaController mediaController = MediaController.getInstance();
isOutOwnerCached = null;
if (message instanceof TLRPC.TL_messageEmpty) { if (message instanceof TLRPC.TL_messageEmpty) {
message = null; message = null;
@ -5608,7 +5609,7 @@ public class MessageObject {
return messageOwner.out; return messageOwner.out;
} }
Boolean isOutOwnerCached; public Boolean isOutOwnerCached;
public boolean isOutOwner() { public boolean isOutOwner() {
if (preview) { if (preview) {
return true; return true;

View file

@ -945,7 +945,7 @@ public class SharedConfig {
} }
public static void toggleAutoplayVideo() { public static void toggleAutoplayVideo() {
LiteMode.toggleFlag(LiteMode.FLAG_AUTOPLAY_VIDEOS, !isAutoplayVideo()); LiteMode.toggleFlag(LiteMode.FLAG_AUTOPLAY_VIDEOS);
} }
public static boolean isSecretMapPreviewSet() { public static boolean isSecretMapPreviewSet() {

View file

@ -16,11 +16,9 @@ import org.telegram.ui.Components.RLottieDrawable;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -224,7 +222,7 @@ public class BitmapsCache {
} }
sharedTools.allocate(h, w); sharedTools.allocate(h, w);
Bitmap[] bitmap = sharedTools.bitmap; Bitmap[] bitmap = sharedTools.bitmap;
ByteArrayOutputStream[] byteArrayOutputStream = sharedTools.byteArrayOutputStream; ImmutableByteArrayOutputStream[] byteArrayOutputStream = sharedTools.byteArrayOutputStream;
CountDownLatch[] countDownLatch = new CountDownLatch[N]; CountDownLatch[] countDownLatch = new CountDownLatch[N];
ArrayList<FrameOffset> frameOffsets = new ArrayList<>(); ArrayList<FrameOffset> frameOffsets = new ArrayList<>();
@ -587,82 +585,6 @@ public class BitmapsCache {
Bitmap getFirstFrame(Bitmap bitmap); 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 static class Metadata {
public int frame; public int frame;
} }
@ -674,7 +596,7 @@ public class BitmapsCache {
} }
private static class CacheGeneratorSharedTools { private static class CacheGeneratorSharedTools {
ByteArrayOutputStream[] byteArrayOutputStream = new ByteArrayOutputStream[N]; ImmutableByteArrayOutputStream[] byteArrayOutputStream = new ImmutableByteArrayOutputStream[N];
private Bitmap[] bitmap = new Bitmap[N]; private Bitmap[] bitmap = new Bitmap[N];
private int lastSize; private int lastSize;
@ -701,7 +623,7 @@ public class BitmapsCache {
bitmap[i] = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); bitmap[i] = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
} }
if (byteArrayOutputStream[i] == null) { if (byteArrayOutputStream[i] == null) {
byteArrayOutputStream[i] = new ByteArrayOutputStream(w * h * 2); byteArrayOutputStream[i] = new ImmutableByteArrayOutputStream(w * h * 2);
} }
} }
} }

View file

@ -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;
}
}

View file

@ -4055,7 +4055,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!loadDocumentFromImageReceiver) { if (!loadDocumentFromImageReceiver) {
TLRPC.PhotoSize photo = document == null ? FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.photoThumbs, AndroidUtilities.getPhotoSize()) : null; TLRPC.PhotoSize photo = document == null ? FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.photoThumbs, AndroidUtilities.getPhotoSize()) : null;
if (canDownload == 2 || canDownload == 1 && currentMessageObject.isVideo()) { 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); FileLoader.getInstance(currentAccount).loadFile(document, currentMessageObject, FileLoader.PRIORITY_NORMAL, 0);
} }
} else if (canDownload != 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) { if (messageObject.checkLayout() || currentPosition != null && lastHeight != AndroidUtilities.displaySize.y) {
currentMessageObject = null; currentMessageObject = null;
} }
messageObject.isOutOwnerCached = null;
boolean widthChanged = lastWidth != getParentWidth(); boolean widthChanged = lastWidth != getParentWidth();
lastHeight = AndroidUtilities.displaySize.y; lastHeight = AndroidUtilities.displaySize.y;
lastWidth = getParentWidth(); lastWidth = getParentWidth();

View file

@ -16726,6 +16726,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
obj.messageOwner = newMsgObj; obj.messageOwner = newMsgObj;
if (fwdHeader != null && newMsgObj.fwd_from != null && !TextUtils.isEmpty(newMsgObj.fwd_from.from_name)) { if (fwdHeader != null && newMsgObj.fwd_from != null && !TextUtils.isEmpty(newMsgObj.fwd_from.from_name)) {
obj.messageOwner.fwd_from = fwdHeader; obj.messageOwner.fwd_from = fwdHeader;
obj.isOutOwnerCached = null;
} }
obj.generateThumbs(true); obj.generateThumbs(true);
obj.setType(); obj.setType();

View file

@ -856,6 +856,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
fragment.setDelegate(new GroupCreateActivity.ContactsAddActivityDelegate() { fragment.setDelegate(new GroupCreateActivity.ContactsAddActivityDelegate() {
@Override @Override
public void didSelectUsers(ArrayList<TLRPC.User> users, int fwdCount) { public void didSelectUsers(ArrayList<TLRPC.User> users, int fwdCount) {
if (fragment.getParentActivity() == null) {
return;
}
final int count = users.size(); final int count = users.size();
final int[] processed = new int[1]; final int[] processed = new int[1];
final ArrayList<TLRPC.User> userRestrictedPrivacy = new ArrayList<>(); final ArrayList<TLRPC.User> userRestrictedPrivacy = new ArrayList<>();
@ -879,7 +882,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
title = LocaleController.getString("InviteToGroupErrorTitleSomeUsers", R.string.InviteToGroupErrorTitleSomeUsers); title = LocaleController.getString("InviteToGroupErrorTitleSomeUsers", R.string.InviteToGroupErrorTitleSomeUsers);
description = LocaleController.getString("InviteToGroupErrorMessageMultipleSome", R.string.InviteToGroupErrorMessageMultipleSome); description = LocaleController.getString("InviteToGroupErrorMessageMultipleSome", R.string.InviteToGroupErrorMessageMultipleSome);
} }
new AlertDialog.Builder(fragment.getContext()) new AlertDialog.Builder(fragment.getParentActivity())
.setTitle(title) .setTitle(title)
.setMessage(description) .setMessage(description)
.setPositiveButton(LocaleController.getString("OK", R.string.OK), null) .setPositiveButton(LocaleController.getString("OK", R.string.OK), null)

View file

@ -592,7 +592,6 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
} }
MediaController.getInstance().pauseMessage(MediaController.getInstance().getPlayingMessageObject()); 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") { cameraFile = new File(FileLoader.getDirectory(FileLoader.MEDIA_DIR_DOCUMENT), System.currentTimeMillis() + "_" + SharedConfig.getLastLocalId() + ".mp4") {
@Override @Override
public boolean delete() { public boolean delete() {

View file

@ -376,10 +376,10 @@ public class PipVideoOverlay {
private void onDismissedInternal() { private void onDismissedInternal() {
try { try {
if (controlsView.getParent() != null) { if (contentView != null && contentView.getParent() != null) {
windowManager.removeViewImmediate(contentView); windowManager.removeViewImmediate(contentView);
} }
} catch (IllegalArgumentException ignored) {} } catch (Exception ignored) {}
if (photoViewerWebView != null) { if (photoViewerWebView != null) {
photoViewerWebView.showControls(); photoViewerWebView.showControls();

View file

@ -499,7 +499,7 @@ public class DataSettingsActivity extends BaseFragment {
} else if (position == autoplayVideoRow) { } else if (position == autoplayVideoRow) {
SharedConfig.toggleAutoplayVideo(); SharedConfig.toggleAutoplayVideo();
if (view instanceof TextCheckCell) { if (view instanceof TextCheckCell) {
((TextCheckCell) view).setChecked(SharedConfig.isAutoplayGifs()); ((TextCheckCell) view).setChecked(SharedConfig.isAutoplayVideo());
} }
} else if (position == clearDraftsRow) { } else if (position == clearDraftsRow) {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());

View file

@ -1130,13 +1130,23 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
@Override @Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type, int[] consumed) { public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type, int[] consumed) {
if (target == listView && sharedMediaLayoutAttached) { try {
RecyclerListView innerListView = sharedMediaLayout.getCurrentListView(); if (target == listView && sharedMediaLayoutAttached) {
int top = sharedMediaLayout.getTop(); RecyclerListView innerListView = sharedMediaLayout.getCurrentListView();
if (top == 0) { int top = sharedMediaLayout.getTop();
consumed[1] = dyUnconsumed; if (top == 0) {
innerListView.scrollBy(0, dyUnconsumed); 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; break;
case PHONE_OPTION_TELEGRAM_CALL: case PHONE_OPTION_TELEGRAM_CALL:
case PHONE_OPTION_TELEGRAM_VIDEO_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()); VoIPHelper.startCall(user, action == PHONE_OPTION_TELEGRAM_VIDEO_CALL, userInfo != null && userInfo.video_calls_available, getParentActivity(), userInfo, getAccountInstance());
break; break;
} }

View file

@ -1159,9 +1159,11 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No
((TextCheckCell) view).setChecked(SharedConfig.chatBlurEnabled()); ((TextCheckCell) view).setChecked(SharedConfig.chatBlurEnabled());
} }
} else if (position == lightModeRow) { } 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) { if (view instanceof TextCheckCell) {
((TextCheckCell) view).setChecked(LiteMode.getValue() == LiteMode.PRESET_LOW); ((TextCheckCell) view).setChecked((LiteMode.getValue() & LiteMode.ENABLED) == 0);
} }
} else if (position == nightThemeRow) { } else if (position == nightThemeRow) {
if (LocaleController.isRTL && x <= AndroidUtilities.dp(76) || !LocaleController.isRTL && x >= view.getMeasuredWidth() - AndroidUtilities.dp(76)) { 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) { } else if (position == chatBlurRow) {
textCheckCell.setTextAndCheck(LocaleController.getString("BlurInChat", R.string.BlurInChat), SharedConfig.chatBlurEnabled(), true); textCheckCell.setTextAndCheck(LocaleController.getString("BlurInChat", R.string.BlurInChat), SharedConfig.chatBlurEnabled(), true);
} else if (position == lightModeRow) { } 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; break;
} }

View file

@ -21,6 +21,7 @@ import android.os.Process;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.telegram.messenger.FileLog;
import org.webrtc.ContextUtils; import org.webrtc.ContextUtils;
import org.webrtc.Logging; import org.webrtc.Logging;
import org.webrtc.ThreadUtils; import org.webrtc.ThreadUtils;
@ -334,21 +335,30 @@ public class WebRtcAudioTrack {
} }
private boolean stopPlayout() { private boolean stopPlayout() {
threadChecker.checkIsOnValidThread(); try {
Logging.d(TAG, "stopPlayout"); threadChecker.checkIsOnValidThread();
assertTrue(audioThread != null); Logging.d(TAG, "stopPlayout");
logUnderrunCount(); assertTrue(audioThread != null);
audioThread.stopThread(); logUnderrunCount();
audioThread.stopThread();
Logging.d(TAG, "Stopping the AudioTrackThread..."); Logging.d(TAG, "Stopping the AudioTrackThread...");
audioThread.interrupt(); audioThread.interrupt();
if (!ThreadUtils.joinUninterruptibly(audioThread, AUDIO_TRACK_THREAD_JOIN_TIMEOUT_MS)) { if (!ThreadUtils.joinUninterruptibly(audioThread, AUDIO_TRACK_THREAD_JOIN_TIMEOUT_MS)) {
Logging.e(TAG, "Join of AudioTrackThread timed out."); Logging.e(TAG, "Join of AudioTrackThread timed out.");
WebRtcAudioUtils.logAudioState(TAG); 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; return true;
} }

View file

@ -13,8 +13,8 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true # org.gradle.parallel=true
#Sat Mar 12 05:53:50 MSK 2016 #Sat Mar 12 05:53:50 MSK 2016
APP_VERSION_NAME=9.4.5 APP_VERSION_NAME=9.4.6
APP_VERSION_CODE=3152 APP_VERSION_CODE=3155
APP_PACKAGE=org.telegram.messenger APP_PACKAGE=org.telegram.messenger
RELEASE_KEY_PASSWORD=android RELEASE_KEY_PASSWORD=android
RELEASE_KEY_ALIAS=androidkey RELEASE_KEY_ALIAS=androidkey