update to 11.2.3 (5335)

This commit is contained in:
dkaraush 2024-10-18 00:04:16 +04:00
parent 1e89182699
commit 9b78d437de
188 changed files with 14155 additions and 4829 deletions

View file

@ -116,7 +116,7 @@ android {
minifyEnabled false
shrinkResources false
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"\""
@ -129,7 +129,7 @@ android {
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PRIVATE") + "\""
@ -142,7 +142,7 @@ android {
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PUBLIC") + "\""
@ -155,7 +155,7 @@ android {
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_HARDCORE") + "\""

View file

@ -100,7 +100,7 @@ jint getTimeDifference(JNIEnv *env, jclass c, jint instanceNum) {
void sendRequest(JNIEnv *env, jclass c, jint instanceNum, jlong object, jint flags, jint datacenterId, jint connectionType, jboolean immediate, jint token) {
TL_api_request *request = new TL_api_request();
request->request = (NativeByteBuffer *) (intptr_t) object;
ConnectionsManager::getInstance(instanceNum).sendRequest(request, ([instanceNum, token](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
ConnectionsManager::getInstance(instanceNum).sendRequest(request, ([instanceNum, token](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
TL_api_response *resp = (TL_api_response *) response;
jlong ptr = 0;
jint errorCode = 0;
@ -117,7 +117,7 @@ void sendRequest(JNIEnv *env, jclass c, jint instanceNum, jlong object, jint fla
errorText = jniEnv[instanceNum]->NewStringUTF("UTF-8 ERROR");
}
}
jniEnv[instanceNum]->CallStaticVoidMethod(jclass_ConnectionsManager, jclass_ConnectionsManager_onRequestComplete, instanceNum, token, ptr, errorCode, errorText, networkType, responseTime, msgId);
jniEnv[instanceNum]->CallStaticVoidMethod(jclass_ConnectionsManager, jclass_ConnectionsManager_onRequestComplete, instanceNum, token, ptr, errorCode, errorText, networkType, responseTime, msgId, dcId);
if (errorText != nullptr) {
jniEnv[instanceNum]->DeleteLocalRef(errorText);
}
@ -561,7 +561,7 @@ extern "C" int registerNativeTgNetFunctions(JavaVM *vm, JNIEnv *env) {
if (jclass_ConnectionsManager_onRequestClear == 0) {
return JNI_FALSE;
}
jclass_ConnectionsManager_onRequestComplete = env->GetStaticMethodID(jclass_ConnectionsManager, "onRequestComplete", "(IIJILjava/lang/String;IJJ)V");
jclass_ConnectionsManager_onRequestComplete = env->GetStaticMethodID(jclass_ConnectionsManager, "onRequestComplete", "(IIJILjava/lang/String;IJJI)V");
if (jclass_ConnectionsManager_onRequestComplete == 0) {
return JNI_FALSE;
}

View file

@ -624,7 +624,8 @@ void ConnectionsManager::cleanUp(bool resetKeys, int32_t datacenterId) {
auto error = new TL_error();
error->code = -1000;
error->text = "";
request->onComplete(nullptr, error, 0, 0, request->messageId);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(nullptr, error, 0, 0, request->messageId, dcId);
delete error;
}
iter = requestsQueue.erase(iter);
@ -646,7 +647,8 @@ void ConnectionsManager::cleanUp(bool resetKeys, int32_t datacenterId) {
auto error = new TL_error();
error->code = -1000;
error->text = "";
request->onComplete(nullptr, error, 0, 0, request->messageId);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(nullptr, error, 0, 0, request->messageId, dcId);
delete error;
}
DEBUG_D("1) erase request %d 0x%" PRIx64, request->requestToken, request->messageId);
@ -1205,7 +1207,8 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
for (auto iter = runningRequests.begin(); iter != runningRequests.end(); iter++) {
Request *request = iter->get();
if (request->respondsToMessageId(requestMid)) {
request->onComplete(response, nullptr, connection->currentNetworkType, timeMessage, requestMid);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(response, nullptr, connection->currentNetworkType, timeMessage, requestMid, dcId);
request->completed = true;
DEBUG_D("4) erase request %d 0x%" PRIx64, request->requestToken, request->messageId);
runningRequests.erase(iter);
@ -1450,12 +1453,13 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
}
if (!discardResponse) {
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
if (implicitError != nullptr || error2 != nullptr) {
isError = true;
request->onComplete(nullptr, implicitError != nullptr ? implicitError : error2, connection->currentNetworkType, timeMessage, request->messageId);
request->onComplete(nullptr, implicitError != nullptr ? implicitError : error2, connection->currentNetworkType, timeMessage, request->messageId, dcId);
delete error2;
} else {
request->onComplete(response->result.get(), nullptr, connection->currentNetworkType, timeMessage, request->messageId);
request->onComplete(response->result.get(), nullptr, connection->currentNetworkType, timeMessage, request->messageId, dcId);
}
}
@ -2104,7 +2108,7 @@ bool ConnectionsManager::cancelRequestInternal(int32_t token, int64_t messageId,
auto dropAnswer = new TL_rpc_drop_answer();
dropAnswer->req_msg_id = request->messageId;
if (onCancelled != nullptr) {
sendRequest(dropAnswer, ([onCancelled](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) -> void {
sendRequest(dropAnswer, ([onCancelled](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) -> void {
if (onCancelled != nullptr) {
onCancelled();
}
@ -2161,7 +2165,8 @@ void ConnectionsManager::failNotRunningRequest(int32_t token) {
auto error = new TL_error();
error->code = -2000;
error->text = "CANCELLED_REQUEST";
request->onComplete(nullptr, error, 0, 0, request->messageId);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(nullptr, error, 0, 0, request->messageId, dcId);
request->cancelled = true;
if (LOGS_ENABLED) DEBUG_D("cancelled queued rpc request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
@ -2304,7 +2309,7 @@ void ConnectionsManager::requestSaltsForDatacenter(Datacenter *datacenter, bool
requestingSaltsForDc.push_back(id);
auto request = new TL_get_future_salts();
request->num = 32;
sendRequest(request, [&, datacenter, id, media](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
sendRequest(request, [&, datacenter, id, media](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
auto iter = std::find(requestingSaltsForDc.begin(), requestingSaltsForDc.end(), id);
if (iter != requestingSaltsForDc.end()) {
requestingSaltsForDc.erase(iter);
@ -2339,7 +2344,7 @@ void ConnectionsManager::registerForInternalPushUpdates() {
request->token_type = 7;
request->token = to_string_uint64((uint64_t) pushSessionId);
sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (error == nullptr) {
registeredForInternalPush = true;
if (LOGS_ENABLED) DEBUG_D("registered for internal push");
@ -2562,7 +2567,8 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
auto error = new TL_error();
error->code = -123;
error->text = "RETRY_LIMIT";
request->onComplete(nullptr, error, connection->currentNetworkType, 0, request->messageId);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(nullptr, error, connection->currentNetworkType, 0, request->messageId, dcId);
delete error;
DEBUG_D("12) erase request %d 0x%" PRIx64, request->requestToken, request->messageId);
iter = runningRequests.erase(iter);
@ -3273,7 +3279,7 @@ void ConnectionsManager::updateDcSettings(uint32_t dcNum, bool workaround, bool
}
auto request = new TL_help_getConfig();
sendRequest(request, [&, workaround](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
sendRequest(request, [&, workaround](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if ((!workaround && !updatingDcSettings) || (workaround && !updatingDcSettingsWorkaround)) {
return;
}
@ -3422,7 +3428,7 @@ void ConnectionsManager::authorizeOnMovingDatacenter() {
auto request = new TL_auth_importAuthorization();
request->id = currentUserId;
request->bytes = std::move(movingAuthorization);
sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (error == nullptr) {
authorizedOnMovingDatacenter();
} else {

View file

@ -1447,14 +1447,14 @@ void Datacenter::exportAuthorization() {
auto request = new TL_auth_exportAuthorization();
request->dc_id = datacenterId;
if (LOGS_ENABLED) DEBUG_D("dc%u begin export authorization", datacenterId);
ConnectionsManager::getInstance(instanceNum).sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
ConnectionsManager::getInstance(instanceNum).sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (error == nullptr) {
auto res = (TL_auth_exportedAuthorization *) response;
auto request2 = new TL_auth_importAuthorization();
request2->bytes = std::move(res->bytes);
request2->id = res->id;
if (LOGS_ENABLED) DEBUG_D("dc%u begin import authorization", datacenterId);
ConnectionsManager::getInstance(instanceNum).sendRequest(request2, [&](TLObject *response2, TL_error *error2, int32_t networkType, int64_t responseTime, int64_t msgId) {
ConnectionsManager::getInstance(instanceNum).sendRequest(request2, [&](TLObject *response2, TL_error *error2, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (error2 == nullptr) {
authorized = true;
ConnectionsManager::getInstance(instanceNum).onDatacenterExportAuthorizationComplete(this);

View file

@ -47,7 +47,7 @@ class NativeByteBuffer;
class Handshake;
class ConnectionSocket;
typedef std::function<void(TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId)> onCompleteFunc;
typedef std::function<void(TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId)> onCompleteFunc;
typedef std::function<void()> onQuickAckFunc;
typedef std::function<void()> onWriteToSocketFunc;
typedef std::function<void()> onRequestClearFunc;

View file

@ -873,7 +873,7 @@ void Handshake::processHandshakeResponse_serverDHParamsAnswer(TLObject *message,
request->encrypted_message = currentDatacenter->createRequestsData(array, nullptr, connection, true);
};
authKeyPendingRequestId = ConnectionsManager::getInstance(currentDatacenter->instanceNum).sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
authKeyPendingRequestId = ConnectionsManager::getInstance(currentDatacenter->instanceNum).sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
authKeyPendingMessageId = 0;
authKeyPendingRequestId = 0;
if (response != nullptr && typeid(*response) == typeid(TL_boolTrue)) {
@ -989,7 +989,7 @@ void Handshake::loadCdnConfig(Datacenter *datacenter) {
loadingCdnKeys = true;
auto request = new TL_help_getCdnConfig();
ConnectionsManager::getInstance(datacenter->instanceNum).sendRequest(request, [&, datacenter](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
ConnectionsManager::getInstance(datacenter->instanceNum).sendRequest(request, [&, datacenter](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (response != nullptr) {
auto config = (TL_cdnConfig *) response;
size_t count = config->public_keys.size();

View file

@ -52,10 +52,10 @@ void Request::clear(bool time) {
}
}
void Request::onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t requestMsgId) {
void Request::onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t requestMsgId, int32_t dcId) {
if (onCompleteRequestCallback != nullptr && (result != nullptr || error != nullptr)) {
completedSent = true;
onCompleteRequestCallback(result, error, networkType, responseTime, requestMsgId);
onCompleteRequestCallback(result, error, networkType, responseTime, requestMsgId, dcId);
}
}

View file

@ -66,7 +66,7 @@ public:
void addRespondMessageId(int64_t id);
bool respondsToMessageId(int64_t id);
void clear(bool time);
void onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msg_id);
void onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msg_id, int32_t dcId);
void onQuickAck();
void onWriteToSocket();
bool isMediaRequest();

View file

@ -401,6 +401,14 @@
</intent-filter>
</receiver>
<receiver
android:name=".CopyCodeReceiver"
android:exported="false">
<intent-filter>
<action android:name="org.telegram.messenger.ACTION_COPY_CODE"/>
</intent-filter>
</receiver>
<receiver
android:name=".NotificationsDisabledReceiver"
android:exported="false">

View file

@ -446,3 +446,4 @@ iv_backgroundGray=-14737633
iv_navigationBackground=-16777216
table_background=177390847
table_border=436207615
dialogCardShadow=1073741824

View file

@ -471,3 +471,4 @@ iv_backgroundGray=-14737633
iv_navigationBackground=-16777216
table_background=177390847
table_border=436207615
dialogCardShadow=1073741824

View file

@ -16,12 +16,16 @@
package androidx.recyclerview.widget;
import android.text.TextUtils;
import android.util.Log;
import androidx.core.util.Pools;
import org.telegram.messenger.BuildVars;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
@ -68,6 +72,29 @@ class AdapterHelper implements OpReorderer.Callback {
private int mExistingUpdateTypes = 0;
private final ArrayList<String> lastNotifies = BuildVars.DEBUG_VERSION ? new ArrayList<String>() : null;
private void logNotify(String name) {
if (lastNotifies == null) return;
while (lastNotifies.size() > 5) lastNotifies.remove(0);
final StringBuilder sb = new StringBuilder();
sb.append(new Date().toString()).append(" ").append(name).append("\n");
final StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0, j = 0; i < trace.length && j < 5; ++i) {
final String traceElement = trace[i].toString();
if (traceElement.startsWith("androidx.recyclerview.widget.") && j == 0) {
continue;
}
sb.append("\n").append(traceElement).append("\n");
j++;
}
lastNotifies.add(sb.toString());
}
public String getLastNotifies() {
if (lastNotifies == null) return null;
return TextUtils.join("\n\n", lastNotifies);
}
AdapterHelper(Callback callback) {
this(callback, false);
}
@ -504,6 +531,9 @@ class AdapterHelper implements OpReorderer.Callback {
if (itemCount < 1) {
return false;
}
if (BuildVars.DEBUG_VERSION) {
logNotify("onItemRangeChanged(" + positionStart + ", " + itemCount + ", " + payload + ")");
}
mPendingUpdates.add(obtainUpdateOp(UpdateOp.UPDATE, positionStart, itemCount, payload));
mExistingUpdateTypes |= UpdateOp.UPDATE;
return mPendingUpdates.size() == 1;
@ -516,6 +546,9 @@ class AdapterHelper implements OpReorderer.Callback {
if (itemCount < 1) {
return false;
}
if (BuildVars.DEBUG_VERSION) {
logNotify("onItemRangeInserted(" + positionStart + ", " + itemCount + ")");
}
mPendingUpdates.add(obtainUpdateOp(UpdateOp.ADD, positionStart, itemCount, null));
mExistingUpdateTypes |= UpdateOp.ADD;
return mPendingUpdates.size() == 1;
@ -528,6 +561,9 @@ class AdapterHelper implements OpReorderer.Callback {
if (itemCount < 1) {
return false;
}
if (BuildVars.DEBUG_VERSION) {
logNotify("onItemRangeRemoved(" + positionStart + ", " + itemCount + ")");
}
mPendingUpdates.add(obtainUpdateOp(UpdateOp.REMOVE, positionStart, itemCount, null));
mExistingUpdateTypes |= UpdateOp.REMOVE;
return mPendingUpdates.size() == 1;
@ -543,6 +579,9 @@ class AdapterHelper implements OpReorderer.Callback {
if (itemCount != 1) {
throw new IllegalArgumentException("Moving more than 1 item is not supported yet");
}
if (BuildVars.DEBUG_VERSION) {
logNotify("onItemRangeMoved(" + from + ", " + to + ", " + itemCount + ")");
}
mPendingUpdates.add(obtainUpdateOp(UpdateOp.MOVE, from, to, null));
mExistingUpdateTypes |= UpdateOp.MOVE;
return mPendingUpdates.size() == 1;

View file

@ -63,6 +63,11 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
ArrayList<RecyclerView.ViewHolder> mChangeAnimations = new ArrayList<>();
protected boolean delayAnimations = true;
private long delayIncrement = 0;
public void setDelayIncrement(long increment) {
this.delayIncrement = increment;
}
protected static class MoveInfo {
public RecyclerView.ViewHolder holder;
@ -121,6 +126,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
for (RecyclerView.ViewHolder holder : mPendingRemovals) {
animateRemoveImpl(holder);
}
final long[] delay = new long[] { 0 };
mPendingRemovals.clear();
// Next, move stuff
if (movesPending) {
@ -179,8 +185,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
Runnable adder = new Runnable() {
@Override
public void run() {
for (RecyclerView.ViewHolder holder : additions) {
animateAddImpl(holder);
for (int i = additions.size() - 1; i >= 0; --i) {
// for (int i = 0; i < additions.size(); ++i) {
final RecyclerView.ViewHolder holder = additions.get(i);
animateAddImpl(holder, delay[0] += delayIncrement);
}
additions.clear();
mAdditionsList.remove(additions);
@ -224,6 +232,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
animateRemoveImpl(holder, 0);
}
public void animateRemoveImpl(final RecyclerView.ViewHolder holder, long delay) {
final View view = holder.itemView;
final ViewPropertyAnimator animation = view.animate();
mRemoveAnimations.add(holder);
@ -233,7 +245,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
animation
.setDuration(getRemoveDuration())
.setStartDelay(getRemoveDelay())
.setStartDelay(getRemoveDelay() + delay)
.setInterpolator(getRemoveInterpolator())
.alpha(0)
.scaleX(1f - animateByScale(view))
@ -280,6 +292,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
public void animateAddImpl(final RecyclerView.ViewHolder holder) {
animateAddImpl(holder, 0);
}
public void animateAddImpl(final RecyclerView.ViewHolder holder, long delay) {
final View view = holder.itemView;
final ViewPropertyAnimator animation = view.animate();
mAddAnimations.add(holder);
@ -288,7 +304,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
.scaleX(1f)
.scaleY(1f)
.setDuration(getAddDuration())
.setStartDelay(getAddDelay())
.setStartDelay(getAddDelay() + delay)
.setInterpolator(getAddInterpolator());
if (Build.VERSION.SDK_INT >= 19) {
animation.setUpdateListener(animation1 -> onAddAnimationUpdate(holder));
@ -376,6 +392,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
protected void animateMoveImpl(final RecyclerView.ViewHolder holder, MoveInfo moveInfo) {
animateMoveImpl(holder, moveInfo, 0);
}
public void animateMoveImpl(final RecyclerView.ViewHolder holder, MoveInfo moveInfo, long delay) {
int fromX = moveInfo.fromX;
int fromY = moveInfo.fromY;
int toX = moveInfo.toX;
@ -405,7 +425,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
beforeAnimateMoveImpl(holder);
animation
.setDuration(getMoveDuration())
.setStartDelay(getMoveDelay())
.setStartDelay(getMoveDelay() + delay)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
@ -470,6 +490,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
public void animateChangeImpl(final ChangeInfo changeInfo) {
animateChangeImpl(changeInfo, 0);
}
public void animateChangeImpl(final ChangeInfo changeInfo, long delay) {
final RecyclerView.ViewHolder holder = changeInfo.oldHolder;
final View view = holder == null ? null : holder.itemView;
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;
@ -491,6 +515,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
oldViewAnim.setUpdateListener(animation1 -> onChangeAnimationUpdate(changeInfo.oldHolder));
}
oldViewAnim
.setStartDelay(delay)
.setInterpolator(getChangeInterpolator())
.setListener(new AnimatorListenerAdapter() {
@Override
@ -520,7 +545,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
newViewAnimation
.translationX(0).translationY(0)
.setDuration(getChangeAddDuration())
.setStartDelay(getChangeDelay() + (getChangeDuration() - getChangeAddDuration()))
.setStartDelay(getChangeDelay() + (getChangeDuration() - getChangeAddDuration()) + delay)
.setInterpolator(getChangeInterpolator())
.alpha(1);
if (animateByScale(newView) > 0) {

View file

@ -774,10 +774,16 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
* hitting an exception.
*/
String exceptionLabel() {
return " " + super.toString()
+ ", adapter:" + mAdapter
+ ", layout:" + mLayout
+ ", context:" + getContext();
final StringBuilder sb = new StringBuilder();
sb.append(" ").append(super.toString())
.append(", adapter:").append(mAdapter)
.append(", layout:").append(mLayout)
.append(", context:").append(getContext());
final String lastNotifies = mAdapterHelper.getLastNotifies();
if (lastNotifies != null) {
sb.append(", last notifies:\n").append(lastNotifies);
}
return sb.toString();
}
/**

View file

@ -634,7 +634,7 @@ public final class MediaCodecUtil {
* The result of {@link android.media.MediaCodecInfo#isHardwareAccelerated()} for API levels 29+,
* or a best-effort approximation for lower levels.
*/
private static boolean isHardwareAccelerated(
public static boolean isHardwareAccelerated(
android.media.MediaCodecInfo codecInfo, String mimeType) {
if (Util.SDK_INT >= 29) {
return isHardwareAcceleratedV29(codecInfo);

View file

@ -427,7 +427,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
initDataSource,
initDataSpec,
initSegmentEncrypted,
/* initializeTimestampAdjuster= */ false);
/* initializeTimestampAdjuster= */ true);
nextLoadPosition = 0;
initDataLoadRequired = false;
}

View file

@ -25,6 +25,8 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

View file

@ -19,6 +19,9 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Log;
import java.util.ArrayList;
/**

View file

@ -319,7 +319,7 @@ public final class DataSpec {
}
/** A {@link Uri} from which data belonging to the resource can be read. */
public final Uri uri;
public Uri uri;
/**
* The offset of the data located at {@link #uri} within the resource.

View file

@ -53,7 +53,7 @@ public final class DefaultHttpDataSourceFactory extends BaseFactory {
*/
public DefaultHttpDataSourceFactory(String userAgent, @Nullable TransferListener listener) {
this(userAgent, listener, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, false);
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, true);
}
/**

View file

@ -500,6 +500,17 @@ public class AndroidUtilities {
return spannableStringBuilder;
}
public static Activity getActivity() {
return getActivity(null);
}
public static Activity getActivity(Context context) {
Activity activity = findActivity(context);
if (activity == null || activity.isFinishing()) activity = LaunchActivity.instance;
if (activity == null || activity.isFinishing()) activity = findActivity(ApplicationLoader.applicationContext);
return activity;
}
public static Activity findActivity(Context context) {
if (context instanceof Activity) {
return (Activity) context;
@ -533,7 +544,7 @@ public class AndroidUtilities {
index = startIndex;
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(str);
if (index >= 0) {
if (runnable != null && index >= 0) {
if (type == REPLACING_TAG_TYPE_LINK_NBSP) {
spannableStringBuilder.replace(index, index + len, AndroidUtilities.replaceMultipleCharSequence(" ", spannableStringBuilder.subSequence(index, index + len), " "));
}
@ -574,6 +585,43 @@ public class AndroidUtilities {
return spannableStringBuilder;
}
public static SpannableStringBuilder makeClickable(String str, int type, Runnable runnable, Theme.ResourcesProvider resourcesProvider) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(str);
if (type == REPLACING_TAG_TYPE_LINK || type == REPLACING_TAG_TYPE_LINK_NBSP || type == REPLACING_TAG_TYPE_LINKBOLD || type == REPLACING_TAG_TYPE_UNDERLINE) {
spannableStringBuilder.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(type == REPLACING_TAG_TYPE_UNDERLINE);
if (type == REPLACING_TAG_TYPE_LINKBOLD) {
ds.setTypeface(AndroidUtilities.bold());
}
}
@Override
public void onClick(@NonNull View view) {
if (runnable != null) {
runnable.run();
}
}
}, 0, spannableStringBuilder.length(), 0);
} else {
spannableStringBuilder.setSpan(new CharacterStyle() {
@Override
public void updateDrawState(TextPaint textPaint) {
textPaint.setTypeface(AndroidUtilities.bold());
int wasAlpha = textPaint.getAlpha();
textPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText, resourcesProvider));
textPaint.setAlpha(wasAlpha);
}
}, 0, spannableStringBuilder.length(), 0);
}
return spannableStringBuilder;
}
public static SpannableStringBuilder makeClickable(String str, Runnable runnable) {
return makeClickable(str, 0, runnable, null);
}
public static SpannableStringBuilder replaceMultipleTags(String str, Runnable ...runnables) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(str);

View file

@ -50,6 +50,7 @@ import org.telegram.ui.LauncherIconController;
import java.io.File;
import java.util.ArrayList;
import java.util.Locale;
public class ApplicationLoader extends Application {
@ -267,7 +268,23 @@ public class ApplicationLoader extends Application {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("app start time = " + (startTime = SystemClock.elapsedRealtime()));
try {
FileLog.d("buildVersion = " + ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0).versionCode);
final PackageInfo info = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
final String abi;
switch (info.versionCode % 10) {
case 1:
case 2:
abi = "store bundled " + Build.CPU_ABI + " " + Build.CPU_ABI2;
break;
default:
case 9:
if (ApplicationLoader.isStandaloneBuild()) {
abi = "direct " + Build.CPU_ABI + " " + Build.CPU_ABI2;
} else {
abi = "universal " + Build.CPU_ABI + " " + Build.CPU_ABI2;
}
break;
}
FileLog.d("buildVersion = " + String.format(Locale.US, "v%s (%d[%d]) %s", info.versionName, info.versionCode / 10, info.versionCode % 10, abi));
} catch (Exception e) {
FileLog.e(e);
}

View file

@ -43,6 +43,11 @@ public class BuildVars {
if (ApplicationLoader.applicationContext != null) {
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("systemConfig", Context.MODE_PRIVATE);
LOGS_ENABLED = DEBUG_VERSION || sharedPreferences.getBoolean("logsEnabled", DEBUG_VERSION);
if (LOGS_ENABLED) {
Thread.setDefaultUncaughtExceptionHandler((thread, exception) -> {
FileLog.fatal(exception, true);
});
}
}
}

View file

@ -1801,6 +1801,15 @@ public class ChatObject {
return isChannel(chat) && !isMegagroup(chat);
}
public static boolean isDiscussionGroup(int currentAccount, long chatId) {
final MessagesController messagesController = MessagesController.getInstance(currentAccount);
return isDiscussionGroup(messagesController.getChat(chatId), messagesController.getChatFull(chatId));
}
public static boolean isDiscussionGroup(TLRPC.Chat chat, TLRPC.ChatFull chatFull) {
return isMegagroup(chat) && chatFull != null && chatFull.linked_chat_id != 0;
}
public static boolean isBoostSupported(TLRPC.Chat chat) {
return isChannelAndNotMegaGroup(chat) || isMegagroup(chat);
}
@ -1906,6 +1915,9 @@ public class ChatObject {
}
public static boolean canSendMessages(TLRPC.Chat chat) {
if (isNotInChat(chat) && chat != null && chat.join_to_send) {
return false;
}
if (isIgnoredChatRestrictionsForBoosters(chat)) {
return true;
}

View file

@ -0,0 +1,15 @@
package org.telegram.messenger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class CopyCodeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String text = intent.getStringExtra("text");
AndroidUtilities.addToClipboard(text);
}
}

View file

@ -1522,6 +1522,19 @@ public class DatabaseMigrationHelper {
version = 156;
}
if (version == 156 || version == 157) {
database.executeFast("CREATE TABLE star_gifts2(id INTEGER PRIMARY KEY, data BLOB, hash INTEGER, time INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 158").stepThis().dispose();
version = 158;
}
if (version == 158) {
database.executeFast("DELETE FROM star_gifts2").stepThis().dispose();
database.executeFast("ALTER TABLE star_gifts2 ADD COLUMN pos INTEGER default 0;").stepThis().dispose();
database.executeFast("PRAGMA user_version = 159").stepThis().dispose();
version = 159;
}
return version;
}

View file

@ -169,6 +169,9 @@ public class DialogObject {
}
public static long getEmojiStatusDocumentId(TLRPC.EmojiStatus emojiStatus) {
if (MessagesController.getInstance(UserConfig.selectedAccount).premiumFeaturesBlocked()) {
return 0;
}
if (emojiStatus instanceof TLRPC.TL_emojiStatus) {
return ((TLRPC.TL_emojiStatus) emojiStatus).document_id;
} else if (emojiStatus instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) emojiStatus).until > (int) (System.currentTimeMillis() / 1000)) {

View file

@ -397,14 +397,14 @@ public class FactCheckController {
menu.removeItem(android.R.id.shareText);
}
int order = 6;
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(getString("Bold", R.string.Bold));
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(getString(R.string.Bold));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.bold()), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_bold, order++, stringBuilder);
stringBuilder = new SpannableStringBuilder(getString("Italic", R.string.Italic));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/ritalic.ttf")), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder = new SpannableStringBuilder(getString(R.string.Italic));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM_ITALIC)), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_italic, order++, stringBuilder);
menu.add(R.id.menu_groupbolditalic, R.id.menu_link, order++, getString("CreateLink", R.string.CreateLink));
menu.add(R.id.menu_groupbolditalic, R.id.menu_regular, order++, getString("Regular", R.string.Regular));
menu.add(R.id.menu_groupbolditalic, R.id.menu_link, order++, getString(R.string.CreateLink));
menu.add(R.id.menu_groupbolditalic, R.id.menu_regular, order++, getString(R.string.Regular));
}
@Override

View file

@ -8,8 +8,6 @@
package org.telegram.messenger;
import android.util.Log;
import org.telegram.messenger.utils.ImmutableByteArrayOutputStream;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.NativeByteBuffer;
@ -51,7 +49,7 @@ public class FileLoadOperation {
public volatile boolean caughtPremiumFloodWait;
public void setStream(FileLoadOperationStream stream, boolean streamPriority, long streamOffset) {
FileLog.e("FileLoadOperation " + getFileName() + " setStream(" + stream + ")");
// FileLog.e("FileLoadOperation " + getFileName() + " setStream(" + stream + ")");
this.stream = stream;
this.streamOffset = streamOffset;
this.streamPriority = streamPriority;
@ -240,6 +238,7 @@ public class FileLoadOperation {
private byte[] cdnCheckBytes;
private boolean requestingCdnOffsets;
public final ArrayList<Integer> uiRequestTokens = new ArrayList<>();
public ArrayList<RequestInfo> requestInfos;
private ArrayList<RequestInfo> cancelledRequestInfos;
private ArrayList<RequestInfo> delayedRequestInfos;
@ -249,6 +248,7 @@ public class FileLoadOperation {
private File cacheFileFinal;
private File cacheIvTemp;
private File cacheFileParts;
private boolean cacheFileFinalReady;
private String ext;
private RandomAccessFile fileOutputStream;
@ -686,7 +686,7 @@ public class FileLoadOperation {
}
protected File getCurrentFileFast() {
if (state == stateFinished && !preloadFinished) {
if (state == stateFinished && !preloadFinished && cacheFileFinalReady) {
return cacheFileFinal;
} else {
return cacheFileTemp;
@ -836,7 +836,9 @@ public class FileLoadOperation {
if (streamPriority) {
long offset = (streamOffset / (long) currentDownloadChunkSize) * (long) currentDownloadChunkSize;
if (priorityRequestInfo != null && priorityRequestInfo.offset != offset) {
final int requestToken = priorityRequestInfo.requestToken;
requestInfos.remove(priorityRequestInfo);
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.remove((Integer) requestToken));
requestedBytesCount -= currentDownloadChunkSize;
removePart(notRequestedBytesRanges, priorityRequestInfo.offset, priorityRequestInfo.offset + currentDownloadChunkSize);
if (priorityRequestInfo.requestToken != 0) {
@ -978,7 +980,7 @@ public class FileLoadOperation {
cacheFileFinal = new File(storePath, fileNameFinal);
}
}
boolean finalFileExist = cacheFileFinal.exists();
boolean finalFileExist = cacheFileFinalReady = cacheFileFinal.exists();
if (finalFileExist && (parentObject instanceof TLRPC.TL_theme || (totalBytesCount != 0 && !ungzip && totalBytesCount != cacheFileFinal.length())) && !delegate.isLocallyCreatedFile(cacheFileFinal.toString())) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("debug_loading: delete existing file cause file size mismatch " + cacheFileFinal.getName() + " totalSize=" + totalBytesCount + " existingFileSize=" + cacheFileFinal.length());
@ -1626,7 +1628,9 @@ public class FileLoadOperation {
return;
}
cacheFileFinal = cacheFileTempLocal;
cacheFileFinalReady = false;
} else {
cacheFileFinalReady = true;
if (pathSaveData != null && cacheFileFinal.exists()) {
delegate.saveFilePath(pathSaveData, cacheFileFinal);
}
@ -1779,7 +1783,9 @@ public class FileLoadOperation {
}
return false;
}
final int requestToken = requestInfo.requestToken;
requestInfos.remove(requestInfo);
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.remove((Integer) requestToken));
if (error == null) {
try {
if (notLoadedBytesRanges == null && downloadedBytes != requestInfo.offset) {
@ -2149,6 +2155,7 @@ public class FileLoadOperation {
}
}
requestInfos.clear();
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.clear());
for (int a = 0; a < delayedRequestInfos.size(); a++) {
RequestInfo info = delayedRequestInfos.get(a);
if (isPreloadVideoOperation) {
@ -2406,7 +2413,7 @@ public class FileLoadOperation {
}
flags |= ConnectionsManager.RequestFlagListenAfterCancel;
int datacenterId = isCdn ? cdnDatacenterId : this.datacenterId;
requestInfo.requestToken = ConnectionsManager.getInstance(currentAccount).sendRequestSync(request, (response, error) -> {
final int requestToken = requestInfo.requestToken = ConnectionsManager.getInstance(currentAccount).sendRequestSync(request, (response, error) -> {
if (requestInfo.cancelled) {
FileLog.e("received chunk but definitely cancelled offset=" + requestInfo.offset + " size=" + requestInfo.chunkSize + " token=" + requestInfo.requestToken);
return;
@ -2573,6 +2580,7 @@ public class FileLoadOperation {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("debug_loading: " + cacheFileFinal.getName() + " dc=" + datacenterId + " send reqId " + requestInfo.requestToken + " offset=" + requestInfo.offset + " conType=" + connectionType + " priority=" + priority);
}
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.add(requestToken));
requestsCount++;
}
}

View file

@ -682,11 +682,8 @@ public class FileLoader extends BaseController {
public FileUploadOperation findUploadOperationByRequestToken(final int requestToken) {
for (FileUploadOperation operation : uploadOperationPaths.values()) {
if (operation == null) continue;
for (int i = 0; i < operation.requestTokens.size(); ++i) {
if (operation.requestTokens.valueAt(i) == requestToken) {
return operation;
}
if (operation != null && operation.uiRequestTokens.contains(requestToken)) {
return operation;
}
}
return null;
@ -704,11 +701,8 @@ public class FileLoader extends BaseController {
public FileLoadOperation findLoadOperationByRequestToken(final int requestToken) {
for (FileLoadOperation operation : loadOperationPaths.values()) {
if (operation == null || operation.requestInfos == null) continue;
for (FileLoadOperation.RequestInfo requestInfo : operation.requestInfos) {
if (requestInfo != null && requestInfo.requestToken == requestToken) {
return operation;
}
if (operation != null && operation.uiRequestTokens.contains(requestToken)) {
return operation;
}
}
return null;
@ -821,7 +815,7 @@ public class FileLoader extends BaseController {
if (priorityChanged) {
operation.getQueue().checkLoadingOperations();
}
FileLog.d("load operation update position fileName=" + finalFileName + " position in queue " + operation.getPositionInQueue() + " preloadFinish " + operation.isPreloadFinished() + " priority=" + operation.getPriority());
// FileLog.d("load operation update position fileName=" + finalFileName + " position in queue " + operation.getPositionInQueue() + " preloadFinish " + operation.isPreloadFinished() + " priority=" + operation.getPriority());
return operation;
}

View file

@ -83,7 +83,7 @@ public class FileLog {
private static HashSet