ZaStoGram/TMessagesProj/jni/mtproxy/MtProxyPhaseClassification.h
loop-uh 8a5c466c82 Refactor MTProxy recorder and emoji animation scheduler
Extract MTProxy endpoint recording logic into MtProxyEndpointRecorder and MtProxyProbeLease helper classes, and introduce EmojiPanelAnimationScheduler for controlled animation playback in emoji panels.

Key changes:
- Move endpoint failure/handshake/data-path recording from ConnectionSocket to MtProxyEndpointRecorder
- Replace probe lease management methods with MtProxyProbeLease member class
- Add EmojiPanelAnimationScheduler to manage GIF/sticker playback based on visibility and scroll state
- Add animation FPS limiting and invalidation delegate hooks to ImageReceiver
- Update Java proxy event handling to route connected/connect_start/usable_success through ProxyEventReducer
- Update verification tools to reflect new architecture
2026-07-02 21:01:55 +03:00

94 lines
4.5 KiB
C++

// AUTOGENERATED by Tools/generate_mtproxy_phase_classification.py - DO NOT EDIT.
// Source of truth: Tools/mtproxy_phase_contract.py. After editing the contract
// run the generator; check_mtproxy_all.py fails while this file is stale.
#ifndef MTPROXYPHASECLASSIFICATION_H
#define MTPROXYPHASECLASSIFICATION_H
#include <string.h>
namespace MtProxyPhase {
// Terminal verdicts that can be assigned before the socket performs any
// real I/O (secret validation, DNS verdict caches, probe-coordinator
// backoff decisions). deriveMtProxyTerminalDiagnostic must preserve these
// across closeSocket: re-deriving from the startup timeline would replace
// them with "connection_not_started", which is on the local-scheduler
// skip list, so neither endpoint cooldown nor reconnect backoff would
// engage and connect() would hot-loop.
inline bool isPreIoTerminalVerdict(const char *phase) {
if (phase == nullptr) {
return false;
}
return strcmp(phase, "dns_negative_cache_hit") == 0
|| strcmp(phase, "dns_blocked_zero_address") == 0
|| strcmp(phase, "secret_parse_invalid_domain_control_char") == 0
|| strcmp(phase, "secret_parse_invalid_domain") == 0
|| strcmp(phase, "faketls_not_mtproxy_response") == 0
|| strcmp(phase, "faketls_no_server_hello_terminal") == 0
|| strcmp(phase, "faketls_server_closed_terminal") == 0
|| strcmp(phase, "handshake_profiles_exhausted") == 0;
}
// Failure verdicts that must hold the next reconnect attempt
// (Connection::onDisconnectedInternal exponential backoff).
inline bool needsReconnectBackoff(const char *phase) {
if (phase == nullptr) {
return false;
}
return strcmp(phase, "host_resolve_failed") == 0
|| strcmp(phase, "host_resolve_timeout") == 0
|| strcmp(phase, "tcp_not_connected") == 0
|| strcmp(phase, "tcp_connection_refused") == 0
|| strcmp(phase, "tcp_connect_timeout") == 0
|| strcmp(phase, "tcp_connected_no_pong") == 0
|| strcmp(phase, "secret_parse_invalid_domain_control_char") == 0
|| strcmp(phase, "secret_parse_invalid_domain") == 0
|| strcmp(phase, "faketls_not_mtproxy_response") == 0
|| strcmp(phase, "faketls_no_server_hello_terminal") == 0
|| strcmp(phase, "faketls_server_closed_terminal") == 0
|| strcmp(phase, "handshake_profiles_exhausted") == 0
|| strcmp(phase, "mtproxy_packet_sent_no_response") == 0
|| strcmp(phase, "post_handshake_no_appdata") == 0
|| strcmp(phase, "dropped_early_after_appdata") == 0;
}
// Phases published through the MtProxySocketObservation facade
// (mtProxySocketObservationIsHighRiskPhase): failures that must record
// an endpoint failure at close, plus the data-path success markers
// routed the same way.
inline bool isObservationFacadePhase(const char *phase) {
if (phase == nullptr) {
return false;
}
return strcmp(phase, "first_tls_app_recv") == 0
|| strcmp(phase, "first_mtproxy_packet_recv") == 0
|| strcmp(phase, "dns_blocked_zero_address") == 0
|| strcmp(phase, "secret_parse_invalid_domain_control_char") == 0
|| strcmp(phase, "secret_parse_invalid_domain") == 0
|| strcmp(phase, "faketls_not_mtproxy_response") == 0
|| strcmp(phase, "faketls_no_server_hello_terminal") == 0
|| strcmp(phase, "faketls_server_closed_terminal") == 0
|| strcmp(phase, "handshake_profiles_exhausted") == 0
|| strcmp(phase, "post_handshake_no_appdata") == 0
|| strcmp(phase, "recipe_failed") == 0;
}
// Local scheduler/gate timeouts: the wait was produced by our own
// pre-TCP machinery (admission queue, endpoint cooldown, gates), not
// by the network. MtProxyEndpointRecorder::recordFailure skips these so a local
// wake-up never counts as an endpoint failure. Deliberately excludes
// mtproxy_probe_wait_timeout and includes background_handshake_aborted.
inline bool isLocalSchedulerTimeout(const char *phase) {
if (phase == nullptr) {
return false;
}
return strcmp(phase, "connection_not_started") == 0
|| strcmp(phase, "admission_timeout") == 0
|| strcmp(phase, "endpoint_cooldown_timeout") == 0
|| strcmp(phase, "dns_coalesce_timeout") == 0
|| strcmp(phase, "tcp_connect_gate_timeout") == 0
|| strcmp(phase, "background_handshake_aborted") == 0;
}
}
#endif