mirror of
https://github.com/wrwrabbit/Partisan-Telegram-Android.git
synced 2026-10-19 09:35:24 +00:00
update to 12.10.1 (7038)
This commit is contained in:
parent
4f25852f9e
commit
62b56a07ca
46 changed files with 1119 additions and 609 deletions
63
Dockerfile
63
Dockerfile
|
|
@ -1,43 +1,50 @@
|
|||
FROM gradle:8.7.0-jdk17
|
||||
FROM gradle:8.11.1-jdk17
|
||||
|
||||
ENV ANDROID_SDK_URL https://dl.google.com/android/repository/commandlinetools-linux-7302050_latest.zip
|
||||
ENV ANDROID_API_LEVEL android-35
|
||||
ENV ANDROID_BUILD_TOOLS_VERSION 35.0.0
|
||||
ENV ANDROID_HOME /usr/local/android-sdk-linux
|
||||
ENV ANDROID_NDK_VERSION 21.4.7075529
|
||||
ENV ANDROID_VERSION 35
|
||||
ENV ANDROID_NDK_HOME ${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}/
|
||||
ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
|
||||
ENV ANDROID_CMDLINE_TOOLS_VERSION=15859902
|
||||
ENV ANDROID_SDK_URL=https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_CMDLINE_TOOLS_VERSION}_latest.zip
|
||||
|
||||
RUN mkdir "$ANDROID_HOME" .android && \
|
||||
cd "$ANDROID_HOME" && \
|
||||
curl -o sdk.zip $ANDROID_SDK_URL && \
|
||||
unzip sdk.zip && \
|
||||
rm sdk.zip
|
||||
ENV ANDROID_HOME=/usr/local/android-sdk-linux
|
||||
|
||||
RUN yes | ${ANDROID_HOME}/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_HOME --licenses
|
||||
RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_HOME --update
|
||||
RUN $ANDROID_HOME/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_HOME "build-tools;30.0.3" \
|
||||
ENV ANDROID_API_LEVEL=android-36
|
||||
ENV ANDROID_VERSION=36
|
||||
ENV ANDROID_BUILD_TOOLS_VERSION=36.0.0
|
||||
|
||||
ENV ANDROID_NDK_VERSION=27.2.12479018
|
||||
ENV ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/${ANDROID_NDK_VERSION}
|
||||
|
||||
ENV PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools
|
||||
ENV PATH=${PATH}:${ANDROID_NDK_HOME}
|
||||
ENV PATH=${PATH}:${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin
|
||||
|
||||
RUN mkdir -p "${ANDROID_HOME}/cmdline-tools" /home/gradle/.android && \
|
||||
cd /tmp && \
|
||||
curl -fL "${ANDROID_SDK_URL}" -o commandlinetools.zip && \
|
||||
unzip commandlinetools.zip && \
|
||||
mv cmdline-tools "${ANDROID_HOME}/cmdline-tools/latest" && \
|
||||
rm commandlinetools.zip
|
||||
|
||||
RUN yes | sdkmanager --sdk_root="${ANDROID_HOME}" --licenses
|
||||
RUN sdkmanager \
|
||||
--sdk_root="${ANDROID_HOME}" \
|
||||
"build-tools;36.0.0" \
|
||||
"build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
|
||||
"platforms;android-${ANDROID_VERSION}" \
|
||||
"platform-tools" \
|
||||
"ndk;$ANDROID_NDK_VERSION"
|
||||
RUN cp $ANDROID_HOME/build-tools/30.0.3/dx $ANDROID_HOME/build-tools/35.0.0/dx
|
||||
RUN cp $ANDROID_HOME/build-tools/30.0.3/lib/dx.jar $ANDROID_HOME/build-tools/35.0.0/lib/dx.jar
|
||||
ENV PATH ${ANDROID_NDK_HOME}:$PATH
|
||||
ENV PATH ${ANDROID_NDK_HOME}/prebuilt/linux-x86_64/bin/:$PATH
|
||||
"ndk;${ANDROID_NDK_VERSION}" \
|
||||
"cmake;3.22.1"
|
||||
|
||||
CMD mkdir -p /home/source/TMessagesProj/build/outputs/apk && \
|
||||
mkdir -p /home/gradle/TMessagesProj/build/outputs/bundle && \
|
||||
mkdir -p /home/source/TMessagesProj/build/outputs/native-debug-symbols && \
|
||||
cp -R /home/source/. /home/gradle && \
|
||||
cd /home/gradle && \
|
||||
gradle :TMessagesProj_App:bundleBundleAfat_SDK23Release && \
|
||||
gradle :TMessagesProj_App:bundleBundleAfatRelease && \
|
||||
gradle :TMessagesProj_AppStandalone:assembleAfatStandalone && \
|
||||
gradle :TMessagesProj_App:assembleAfatRelease && \
|
||||
gradle :TMessagesProj_AppHuawei:assembleAfatRelease && \
|
||||
gradle --parallel \
|
||||
:TMessagesProj_App:bundleBundleAfat_SDK23Release \
|
||||
:TMessagesProj_App:bundleBundleAfatRelease \
|
||||
:TMessagesProj_AppStandalone:assembleAfatStandalone \
|
||||
:TMessagesProj_App:assembleAfatRelease \
|
||||
:TMessagesProj_AppHuawei:assembleAfatRelease --stacktrace && \
|
||||
cp -R /home/gradle/TMessagesProj_App/build/outputs/apk/. /home/source/TMessagesProj/build/outputs/apk && \
|
||||
cp -R /home/gradle/TMessagesProj_AppHuawei/build/outputs/apk/. /home/source/TMessagesProj/build/outputs/apk && \
|
||||
cp -R /home/gradle/TMessagesProj_AppStandalone/build/outputs/apk/. /home/source/TMessagesProj/build/outputs/apk && \
|
||||
cp -R /home/gradle/TMessagesProj_App/build/outputs/bundle/. /home/source/TMessagesProj/build/outputs/bundle
|
||||
cp -R /home/gradle/TMessagesProj_App/build/outputs/bundle/. /home/source/TMessagesProj/build/outputs/bundle
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ MTproto protocol manuals: https://core.telegram.org/mtproto
|
|||
|
||||
**Note**: In order to support [reproducible builds](https://core.telegram.org/reproducible-builds), this repo contains dummy release.keystore, google-services.json and filled variables inside BuildVars.java. Before publishing your own APKs please make sure to replace all these files with your own.
|
||||
|
||||
You will require Android Studio 2025.1.4, Android NDK 27.2.12479018 and Android SDK 35.
|
||||
You will require Android Studio 2025.1.4, Android NDK 27.2.12479018 and Android SDK 36.
|
||||
|
||||
1. Clone the Telegram source code with its submodules:
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ dependencies {
|
|||
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
|
||||
implementation 'com.stripe:stripe-android:2.0.2'
|
||||
implementation 'com.google.mlkit:language-id:17.0.6'
|
||||
implementation 'com.android.billingclient:billing:7.1.1'
|
||||
implementation 'com.android.billingclient:billing:8.0.0'
|
||||
implementation 'com.google.code.gson:gson:2.11.0'
|
||||
implementation 'com.google.guava:guava:31.1-android'
|
||||
implementation 'com.google.android.play:integrity:1.3.0'
|
||||
|
|
@ -99,8 +99,8 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 35
|
||||
buildToolsVersion '35.0.0'
|
||||
compileSdkVersion 36
|
||||
buildToolsVersion '36.0.0'
|
||||
ndkVersion "27.2.12479018"
|
||||
|
||||
sourceSets.main.jniLibs.srcDirs = ['./jni/']
|
||||
|
|
@ -127,7 +127,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 35
|
||||
targetSdkVersion 36
|
||||
|
||||
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']
|
||||
|
||||
|
|
@ -135,8 +135,9 @@ android {
|
|||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.10.2'
|
||||
version '3.22.1'
|
||||
arguments '-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-21' //, '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'
|
||||
targets 'tmessages.49'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.10.2)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-std=c++14 -DANDROID -g")
|
||||
set(CMAKE_C_FLAGS "-w -std=c11 -DANDROID -D_LARGEFILE_SOURCE=1 -g -Wno-error=implicit-function-declaration")
|
||||
|
|
@ -13,6 +13,12 @@ else()
|
|||
enable_language(ASM_NASM)
|
||||
endif()
|
||||
|
||||
set(CAN_COMPILE_SME FALSE CACHE INTERNAL "Disable libyuv SME" FORCE)
|
||||
add_subdirectory(
|
||||
third_party/libyuv
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libyuv
|
||||
EXCLUDE_FROM_ALL)
|
||||
|
||||
add_library(avutil STATIC IMPORTED)
|
||||
set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${CMAKE_HOME_DIRECTORY}/ffmpeg/${ANDROID_ABI}/libavutil.a)
|
||||
|
||||
|
|
@ -84,7 +90,7 @@ target_link_libraries(tgnet
|
|||
# tlottie (prebuilt Rust static library)
|
||||
add_library(tlottie STATIC IMPORTED)
|
||||
set_target_properties(tlottie PROPERTIES
|
||||
IMPORTED_LOCATION ${CMAKE_HOME_DIRECTORY}/tlottie_lib/${ANDROID_ABI}/libtlottie.a)
|
||||
IMPORTED_LOCATION ${CMAKE_HOME_DIRECTORY}/prebuild/${ANDROID_ABI}/libtlottie.a)
|
||||
|
||||
#sqlite
|
||||
add_library(sqlite STATIC
|
||||
|
|
@ -157,32 +163,6 @@ target_compile_options(${NATIVE_LIB} PUBLIC
|
|||
target_compile_definitions(${NATIVE_LIB} PUBLIC
|
||||
BSD=1 NULL=0 SOCKLEN_T=socklen_t ANDROID_NDK DISABLE_IMPORTGL AVOID_TABLES ANDROID_TILE_BASED_DECODE __STDC_CONSTANT_MACROS ANDROID_ARMV6_IDCT OPUS_BUILD FIXED_POINT USE_ALLOCA restrict= __EMX__ LOCALE_NOT_USED HAVE_LRINT HAVE_LRINTF)
|
||||
|
||||
if (${ANDROID_ABI} STREQUAL "armeabi-v7a")
|
||||
set_target_properties(${NATIVE_LIB} PROPERTIES
|
||||
ANDROID_ARM_NEON FALSE
|
||||
ANDROID_ARM_MODE arm)
|
||||
target_compile_definitions(${NATIVE_LIB} PUBLIC
|
||||
ANDROID_ARM_NEON=false)
|
||||
target_sources(${NATIVE_LIB} PRIVATE
|
||||
third_party/libyuv/source/compare_neon.cc
|
||||
third_party/libyuv/source/rotate_neon.cc
|
||||
third_party/libyuv/source/row_neon.cc
|
||||
third_party/libyuv/source/scale_neon.cc)
|
||||
else()
|
||||
set_target_properties(${NATIVE_LIB} PROPERTIES
|
||||
ANDROID_ARM_NEON FALSE
|
||||
ANDROID_ARM_MODE arm)
|
||||
endif()
|
||||
|
||||
if (${ANDROID_ABI} STREQUAL "armeabi-v7a" OR ${ANDROID_ABI} STREQUAL "arm64-v8a")
|
||||
target_compile_definitions(${NATIVE_LIB} PUBLIC
|
||||
LIBYUV_NEON)
|
||||
|
||||
elseif(${ANDROID_ABI} STREQUAL "x86")
|
||||
target_compile_definitions(${NATIVE_LIB} PUBLIC
|
||||
x86fix)
|
||||
endif()
|
||||
|
||||
target_sources(${NATIVE_LIB} PRIVATE
|
||||
|
||||
third_party/xiph/opusfile/src/info.c
|
||||
|
|
@ -190,49 +170,7 @@ target_sources(${NATIVE_LIB} PRIVATE
|
|||
third_party/xiph/opusfile/src/opusfile.c
|
||||
third_party/xiph/opusfile/src/stream.c
|
||||
third_party/xiph/ogg/src/bitwise.c
|
||||
third_party/xiph/ogg/src/framing.c
|
||||
third_party/libyuv/source/compare_common.cc
|
||||
third_party/libyuv/source/compare_gcc.cc
|
||||
third_party/libyuv/source/compare_neon64.cc
|
||||
third_party/libyuv/source/compare_win.cc
|
||||
third_party/libyuv/source/compare.cc
|
||||
third_party/libyuv/source/convert_argb.cc
|
||||
third_party/libyuv/source/convert_from_argb.cc
|
||||
third_party/libyuv/source/convert_from.cc
|
||||
third_party/libyuv/source/convert_jpeg.cc
|
||||
third_party/libyuv/source/convert_to_argb.cc
|
||||
third_party/libyuv/source/convert_to_i420.cc
|
||||
third_party/libyuv/source/convert.cc
|
||||
third_party/libyuv/source/cpu_id.cc
|
||||
third_party/libyuv/source/mjpeg_decoder.cc
|
||||
third_party/libyuv/source/mjpeg_validate.cc
|
||||
third_party/libyuv/source/planar_functions.cc
|
||||
third_party/libyuv/source/rotate_any.cc
|
||||
third_party/libyuv/source/rotate_argb.cc
|
||||
third_party/libyuv/source/rotate_common.cc
|
||||
third_party/libyuv/source/rotate_gcc.cc
|
||||
third_party/libyuv/source/rotate_neon64.cc
|
||||
third_party/libyuv/source/rotate_win.cc
|
||||
third_party/libyuv/source/rotate.cc
|
||||
third_party/libyuv/source/row_any.cc
|
||||
third_party/libyuv/source/row_common.cc
|
||||
third_party/libyuv/source/row_gcc.cc
|
||||
third_party/libyuv/source/row_neon64.cc
|
||||
third_party/libyuv/source/row_win.cc
|
||||
third_party/libyuv/source/scale_any.cc
|
||||
third_party/libyuv/source/scale_argb.cc
|
||||
third_party/libyuv/source/scale_common.cc
|
||||
third_party/libyuv/source/scale_gcc.cc
|
||||
third_party/libyuv/source/scale_neon64.cc
|
||||
third_party/libyuv/source/scale_win.cc
|
||||
third_party/libyuv/source/scale.cc
|
||||
third_party/libyuv/source/video_common.cc
|
||||
third_party/libyuv/source/scale_uv.cc
|
||||
third_party/libyuv/source/rotate_lsx.cc
|
||||
third_party/libyuv/source/row_lasx.cc
|
||||
third_party/libyuv/source/row_lsx.cc
|
||||
third_party/libyuv/source/scale_lsx.cc
|
||||
third_party/libyuv/source/scale_rgb.cc)
|
||||
third_party/xiph/ogg/src/framing.c)
|
||||
|
||||
target_include_directories(${NATIVE_LIB} PUBLIC
|
||||
third_party/xiph/opus/include
|
||||
|
|
@ -274,6 +212,7 @@ target_link_libraries(${NATIVE_LIB}
|
|||
libopus
|
||||
tde2e
|
||||
tdutils
|
||||
yuv
|
||||
avutil
|
||||
ssl
|
||||
crypto
|
||||
|
|
|
|||
BIN
TMessagesProj/jni/prebuild/arm64-v8a/libopenh264.a
Normal file
BIN
TMessagesProj/jni/prebuild/arm64-v8a/libopenh264.a
Normal file
Binary file not shown.
Binary file not shown.
BIN
TMessagesProj/jni/prebuild/armeabi-v7a/libopenh264.a
Normal file
BIN
TMessagesProj/jni/prebuild/armeabi-v7a/libopenh264.a
Normal file
Binary file not shown.
Binary file not shown.
66
TMessagesProj/jni/prebuild/build.sh
Executable file
66
TMessagesProj/jni/prebuild/build.sh
Executable file
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Top-level orchestrator for the tlottie Android build.
|
||||
#
|
||||
# Responsibilities kept here (outside the container):
|
||||
# 1. remove stale libtlottie.a files, so a failed build can never leave a
|
||||
# previous artifact looking up to date
|
||||
# 2. build the tlottie Docker image
|
||||
# 3. run it with the right mounts and platform pin
|
||||
#
|
||||
# Everything about *how* tlottie itself is compiled (rustc flags, profile,
|
||||
# features, per-ABI loop) lives in scripts/tlottie/entrypoint.sh, which runs
|
||||
# inside the container - see that file to change build settings.
|
||||
#
|
||||
# No environment variables are read - paths and settings are hardcoded
|
||||
# below. Layout this script expects (relative to this file):
|
||||
# arm64-v8a/, armeabi-v7a/, x86/, x86_64/ - output directories
|
||||
# scripts/tlottie/Dockerfile - build environment for tlottie
|
||||
# ../tlottie - tlottie source (sibling of
|
||||
# this repo checkout)
|
||||
|
||||
set -eu
|
||||
|
||||
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
tlottie_dir=$(CDPATH= cd -- "$script_dir/../tlottie" && pwd)
|
||||
dockerfile_dir="$script_dir/scripts/tlottie"
|
||||
image_tag=tlottie-build
|
||||
platform=linux/amd64
|
||||
|
||||
if [ ! -f "$tlottie_dir/Cargo.toml" ]; then
|
||||
echo "error: tlottie Cargo.toml not found at $tlottie_dir/Cargo.toml" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Removing previous tlottie archives"
|
||||
for abi in arm64-v8a armeabi-v7a x86 x86_64; do
|
||||
dest="$script_dir/$abi/libtlottie.a"
|
||||
if [ -f "$dest" ]; then
|
||||
rm -f "$dest"
|
||||
echo " removed $dest"
|
||||
fi
|
||||
if [ ! -d "$script_dir/$abi" ]; then
|
||||
echo "error: output directory does not exist: $script_dir/$abi" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Building tlottie build image ($platform)"
|
||||
# Plain "docker build" already uses BuildKit (and loads the result into the
|
||||
# local image store) on any reasonably current Docker install. Swap for
|
||||
# "docker buildx build --load ..." if your setup needs an explicit builder.
|
||||
docker build \
|
||||
--platform "$platform" \
|
||||
-t "$image_tag" \
|
||||
"$dockerfile_dir"
|
||||
|
||||
echo "Running tlottie build in container"
|
||||
docker run --rm \
|
||||
--platform "$platform" \
|
||||
-v "$script_dir:/work" \
|
||||
-v "$tlottie_dir:/tlottie:ro" \
|
||||
-e HOST_UID="$(id -u)" \
|
||||
-e HOST_GID="$(id -g)" \
|
||||
"$image_tag"
|
||||
|
||||
echo "All tlottie Android archives are ready."
|
||||
123
TMessagesProj/jni/prebuild/build_openh264.sh
Executable file
123
TMessagesProj/jni/prebuild/build_openh264.sh
Executable file
|
|
@ -0,0 +1,123 @@
|
|||
#!/usr/bin/env bash
|
||||
# Compile static OpenH264 libraries for Android.
|
||||
#
|
||||
# The resulting archives are placed in ABI directories next to this script:
|
||||
#
|
||||
# arm64-v8a/libopenh264.a
|
||||
# armeabi-v7a/libopenh264.a
|
||||
# x86_64/libopenh264.a
|
||||
# x86/libopenh264.a
|
||||
#
|
||||
# build_openh264/ is used as temporary workspace. It is removed after all
|
||||
# architectures are built successfully and preserved if the build fails.
|
||||
#
|
||||
# OpenH264 is built with its upstream Makefile, which selects the appropriate
|
||||
# sources and architecture-specific optimizations (including NEON/assembly).
|
||||
#
|
||||
# Optional environment overrides:
|
||||
# OPENH264_SOURCE_DIR=/path/to/openh264
|
||||
# ANDROID_NDK_HOME=/path/to/ndk
|
||||
# NDK_VERSION=27.2.12479018
|
||||
# API=21
|
||||
# ABIS="arm64-v8a armeabi-v7a x86_64 x86"
|
||||
# JOBS=16
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
NDK_VERSION="${NDK_VERSION:-27.2.12479018}"
|
||||
API="${API:-21}"
|
||||
ABIS="${ABIS:-arm64-v8a armeabi-v7a x86_64 x86}"
|
||||
JOBS="${JOBS:-$(nproc)}"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
OPENH264_SRC="${OPENH264_SOURCE_DIR:-$SCRIPT_DIR/../third_party/openh264}"
|
||||
BUILD_DIR="$SCRIPT_DIR/build_openh264"
|
||||
|
||||
: "${ANDROID_NDK_HOME:=${ANDROID_SDK_ROOT:-$HOME/Android/Sdk}/ndk/$NDK_VERSION}"
|
||||
|
||||
[ -d "$ANDROID_NDK_HOME" ] || {
|
||||
echo "ERROR: Android NDK not found: $ANDROID_NDK_HOME" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ -f "$OPENH264_SRC/Makefile" ] || {
|
||||
echo "ERROR: OpenH264 Makefile not found: $OPENH264_SRC/Makefile" >&2
|
||||
echo " Set OPENH264_SOURCE_DIR if the source tree is elsewhere." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
command -v make >/dev/null || {
|
||||
echo "ERROR: make is required" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ " $ABIS " == *" x86 "* || " $ABIS " == *" x86_64 "* ]]; then
|
||||
command -v nasm >/dev/null || {
|
||||
echo "ERROR: nasm is required for OpenH264 x86/x86_64 builds" >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
abi_to_arch() {
|
||||
case "$1" in
|
||||
armeabi-v7a) echo arm ;;
|
||||
arm64-v8a) echo arm64 ;;
|
||||
x86) echo x86 ;;
|
||||
x86_64) echo x86_64 ;;
|
||||
*)
|
||||
echo "ERROR: unsupported ABI: $1" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
copy_source_tree() {
|
||||
local dst="$1"
|
||||
rm -rf "$dst"
|
||||
mkdir -p "$dst"
|
||||
cp -a --reflink=auto "$OPENH264_SRC/." "$dst/"
|
||||
}
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
for abi in $ABIS; do
|
||||
arch="$(abi_to_arch "$abi")"
|
||||
work_src="$BUILD_DIR/$abi"
|
||||
|
||||
echo
|
||||
echo "==> Building OpenH264 for $abi (ARCH=$arch, API=$API)"
|
||||
|
||||
copy_source_tree "$work_src"
|
||||
|
||||
make -C "$work_src" \
|
||||
-j"$JOBS" \
|
||||
V=No \
|
||||
OS=android \
|
||||
ARCH="$arch" \
|
||||
NDKROOT="$ANDROID_NDK_HOME" \
|
||||
TARGET="android-$API" \
|
||||
NDKLEVEL="$API" \
|
||||
BUILDTYPE=Release \
|
||||
ENABLEPIC=Yes \
|
||||
libopenh264.a
|
||||
|
||||
[ -f "$work_src/libopenh264.a" ] || {
|
||||
echo "ERROR: build succeeded but libopenh264.a was not produced for $abi" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
install -D -m 644 \
|
||||
"$work_src/libopenh264.a" \
|
||||
"$SCRIPT_DIR/$abi/libopenh264.a"
|
||||
|
||||
echo "==> $SCRIPT_DIR/$abi/libopenh264.a"
|
||||
done
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
|
||||
echo
|
||||
echo "OpenH264 static build completed."
|
||||
for abi in $ABIS; do
|
||||
echo " $SCRIPT_DIR/$abi/libopenh264.a"
|
||||
done
|
||||
38
TMessagesProj/jni/prebuild/scripts/tlottie/Dockerfile
Normal file
38
TMessagesProj/jni/prebuild/scripts/tlottie/Dockerfile
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
ARG RUST_VERSION=1.98.0
|
||||
|
||||
FROM --platform=linux/amd64 debian:bookworm-slim
|
||||
|
||||
ARG RUST_VERSION
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
RUSTUP_HOME=/opt/rustup \
|
||||
CARGO_HOME=/opt/cargo \
|
||||
PATH=/opt/cargo/bin:/opt/rustup/bin:$PATH \
|
||||
TZ=UTC \
|
||||
LC_ALL=C \
|
||||
SOURCE_DATE_EPOCH=1 \
|
||||
CARGO_INCREMENTAL=0
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
||||
sh -s -- -y \
|
||||
--profile minimal \
|
||||
--default-toolchain "$RUST_VERSION" \
|
||||
--no-modify-path \
|
||||
&& chmod -R a+rX /opt/rustup /opt/cargo
|
||||
|
||||
RUN rustup target add \
|
||||
aarch64-linux-android \
|
||||
armv7-linux-androideabi \
|
||||
i686-linux-android \
|
||||
x86_64-linux-android
|
||||
|
||||
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
WORKDIR /work
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
103
TMessagesProj/jni/prebuild/scripts/tlottie/entrypoint.sh
Executable file
103
TMessagesProj/jni/prebuild/scripts/tlottie/entrypoint.sh
Executable file
|
|
@ -0,0 +1,103 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Runs inside the tlottie build container. /work is the host repo root
|
||||
# (bind-mounted read-write, so output ABI directories live at
|
||||
# /work/<abi>/), /tlottie is the tlottie source (bind-mounted read-only).
|
||||
# The toolchain itself (rustc, cargo, Android targets, build-essential)
|
||||
# is already baked into the image at `docker build` time - see Dockerfile.
|
||||
|
||||
set -eu
|
||||
|
||||
tlottie_dir=/tlottie
|
||||
manifest="$tlottie_dir/Cargo.toml"
|
||||
profile=release-nostd
|
||||
features=cpu,no-std,c-api
|
||||
out_root=/work
|
||||
|
||||
if [ ! -f "$manifest" ]; then
|
||||
echo "error: tlottie Cargo.toml not found at $manifest" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Keep cargo's target dir inside the container, not on the bind-mounted
|
||||
# host repo - it's build-only scratch space and would otherwise leave a
|
||||
# large, host-owned cache sitting in the checkout.
|
||||
target_dir=/build/target
|
||||
mkdir -p "$target_dir"
|
||||
export CARGO_TARGET_DIR="$target_dir"
|
||||
|
||||
rust_sysroot=$(rustc --print sysroot)
|
||||
|
||||
# Do not inherit per-machine compiler flags. CARGO_ENCODED_RUSTFLAGS takes
|
||||
# precedence over RUSTFLAGS and safely supports spaces in paths.
|
||||
unset RUSTFLAGS
|
||||
CARGO_ENCODED_RUSTFLAGS=
|
||||
append_rustflag() {
|
||||
if [ -n "$CARGO_ENCODED_RUSTFLAGS" ]; then
|
||||
CARGO_ENCODED_RUSTFLAGS="$CARGO_ENCODED_RUSTFLAGS$(printf '\037')"
|
||||
fi
|
||||
CARGO_ENCODED_RUSTFLAGS="$CARGO_ENCODED_RUSTFLAGS$1"
|
||||
}
|
||||
append_rustflag "--remap-path-prefix=$tlottie_dir=/tlottie"
|
||||
append_rustflag "--remap-path-prefix=$target_dir=/tlottie-target"
|
||||
append_rustflag "--remap-path-prefix=$rust_sysroot=/rust-sysroot"
|
||||
append_rustflag "--remap-path-prefix=$CARGO_HOME=/cargo-home"
|
||||
export CARGO_ENCODED_RUSTFLAGS
|
||||
|
||||
echo "Building tlottie Android archives"
|
||||
echo " source: $tlottie_dir"
|
||||
echo " rustc: $(rustc --version)"
|
||||
echo " profile: $profile"
|
||||
echo " features: $features"
|
||||
|
||||
for target_spec in \
|
||||
arm64-v8a:aarch64-linux-android \
|
||||
armeabi-v7a:armv7-linux-androideabi \
|
||||
x86:i686-linux-android \
|
||||
x86_64:x86_64-linux-android
|
||||
do
|
||||
abi=${target_spec%%:*}
|
||||
rust_target=${target_spec#*:}
|
||||
destination="$out_root/$abi/libtlottie.a"
|
||||
|
||||
echo "Building $abi ($rust_target)"
|
||||
cargo rustc \
|
||||
--manifest-path "$manifest" \
|
||||
--locked \
|
||||
--profile "$profile" \
|
||||
--target "$rust_target" \
|
||||
--lib \
|
||||
--no-default-features \
|
||||
--features "$features" \
|
||||
--crate-type staticlib \
|
||||
-- \
|
||||
-C metadata=tlottie-staticlib
|
||||
|
||||
artifact="$target_dir/$rust_target/$profile/libtlottie.a"
|
||||
if [ ! -f "$artifact" ]; then
|
||||
echo "error: cargo did not emit $artifact" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "$out_root/$abi" ]; then
|
||||
echo "error: output directory does not exist: $out_root/$abi" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy through a file in the destination directory so replacement is atomic.
|
||||
tmp=$(mktemp "$out_root/$abi/.libtlottie.a.XXXXXX")
|
||||
cp "$artifact" "$tmp"
|
||||
chmod 0644 "$tmp"
|
||||
mv -f "$tmp" "$destination"
|
||||
|
||||
# The container runs as root, so without this the archive would land in
|
||||
# the host checkout owned by root on native Linux hosts. HOST_UID/GID are
|
||||
# passed in by the top-level build.sh.
|
||||
if [ -n "${HOST_UID:-}" ] && [ -n "${HOST_GID:-}" ]; then
|
||||
chown "$HOST_UID:$HOST_GID" "$destination"
|
||||
fi
|
||||
|
||||
bytes=$(wc -c < "$destination" | tr -d ' ')
|
||||
echo "Wrote $destination ($bytes bytes)"
|
||||
done
|
||||
|
||||
echo "All tlottie Android archives are ready."
|
||||
BIN
TMessagesProj/jni/prebuild/x86/libopenh264.a
Normal file
BIN
TMessagesProj/jni/prebuild/x86/libopenh264.a
Normal file
Binary file not shown.
Binary file not shown.
BIN
TMessagesProj/jni/prebuild/x86_64/libopenh264.a
Normal file
BIN
TMessagesProj/jni/prebuild/x86_64/libopenh264.a
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -1,117 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
tlottie_dir=${TLOTTIE_SOURCE_DIR:-"$script_dir/../tlottie"}
|
||||
manifest="$tlottie_dir/Cargo.toml"
|
||||
profile=release-nostd
|
||||
features=cpu,no-std,c-api
|
||||
|
||||
if [ ! -f "$manifest" ]; then
|
||||
echo "error: tlottie Cargo.toml not found at $manifest" >&2
|
||||
echo "set TLOTTIE_SOURCE_DIR if the source is not next to tlottie_lib" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rustup_toolchain=
|
||||
if command -v rustup >/dev/null 2>&1; then
|
||||
rustup_toolchain=${TLOTTIE_RUST_TOOLCHAIN:-stable}
|
||||
fi
|
||||
|
||||
run_cargo() {
|
||||
if [ -n "$rustup_toolchain" ]; then
|
||||
rustup run "$rustup_toolchain" cargo "$@"
|
||||
else
|
||||
cargo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
run_rustc() {
|
||||
if [ -n "$rustup_toolchain" ]; then
|
||||
rustup run "$rustup_toolchain" rustc "$@"
|
||||
else
|
||||
rustc "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -n "$rustup_toolchain" ]; then
|
||||
missing_targets=
|
||||
for target in \
|
||||
aarch64-linux-android \
|
||||
armv7-linux-androideabi \
|
||||
i686-linux-android \
|
||||
x86_64-linux-android
|
||||
do
|
||||
if ! rustup target list --toolchain "$rustup_toolchain" --installed | grep -qx "$target"; then
|
||||
missing_targets="$missing_targets $target"
|
||||
fi
|
||||
done
|
||||
if [ -n "$missing_targets" ]; then
|
||||
echo "error: Rust Android targets are not installed:$missing_targets" >&2
|
||||
echo "install them with: rustup target add --toolchain $rustup_toolchain$missing_targets" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
target_dir=${CARGO_TARGET_DIR:-"$tlottie_dir/target/no-std-android"}
|
||||
export CARGO_TARGET_DIR="$target_dir"
|
||||
|
||||
echo "Building tlottie Android archives"
|
||||
echo " source: $tlottie_dir"
|
||||
echo " rustc: $(run_rustc --version)"
|
||||
echo " profile: $profile"
|
||||
echo " features: $features"
|
||||
echo " target dir: $target_dir"
|
||||
|
||||
temporary_archive=
|
||||
cleanup() {
|
||||
if [ -n "$temporary_archive" ] && [ -f "$temporary_archive" ]; then
|
||||
unlink "$temporary_archive"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT HUP INT TERM
|
||||
|
||||
for target_spec in \
|
||||
arm64-v8a:aarch64-linux-android \
|
||||
armeabi-v7a:armv7-linux-androideabi \
|
||||
x86:i686-linux-android \
|
||||
x86_64:x86_64-linux-android
|
||||
do
|
||||
abi=${target_spec%%:*}
|
||||
rust_target=${target_spec#*:}
|
||||
destination="$script_dir/$abi/libtlottie.a"
|
||||
|
||||
echo "Building $abi ($rust_target)"
|
||||
run_cargo rustc \
|
||||
--manifest-path "$manifest" \
|
||||
--locked \
|
||||
--profile "$profile" \
|
||||
--target "$rust_target" \
|
||||
--lib \
|
||||
--no-default-features \
|
||||
--features "$features" \
|
||||
--crate-type staticlib
|
||||
|
||||
artifact="$target_dir/$rust_target/$profile/libtlottie.a"
|
||||
if [ ! -f "$artifact" ]; then
|
||||
echo "error: Cargo did not emit $artifact" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "$script_dir/$abi" ]; then
|
||||
echo "error: output directory does not exist: $script_dir/$abi" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy through a file in the destination directory so replacement is atomic.
|
||||
temporary_archive=$(mktemp "$script_dir/$abi/.libtlottie.a.XXXXXX")
|
||||
cp "$artifact" "$temporary_archive"
|
||||
chmod 0644 "$temporary_archive"
|
||||
mv -f "$temporary_archive" "$destination"
|
||||
temporary_archive=
|
||||
|
||||
bytes=$(wc -c < "$destination" | tr -d ' ')
|
||||
echo "Wrote $destination ($bytes bytes)"
|
||||
done
|
||||
|
||||
echo "All tlottie Android archives are ready."
|
||||
|
|
@ -74,133 +74,10 @@ elseif(${ANDROID_ABI} STREQUAL "x86_64")
|
|||
HAVE_SSE2)
|
||||
endif()
|
||||
|
||||
#openh264
|
||||
add_library(openh264 STATIC
|
||||
third_party/openh264/src/codec/encoder/core/src/au_set.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/deblocking.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/decode_mb_aux.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/encode_mb_aux.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/encoder_data_tables.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/encoder_ext.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/encoder.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/get_intra_predictor.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/md.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/mv_pred.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/nal_encap.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/paraset_strategy.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/picture_handle.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/ratectl.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/ref_list_mgr_svc.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/sample.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/set_mb_syn_cabac.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/set_mb_syn_cavlc.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/slice_multi_threading.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/svc_base_layer_md.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/svc_enc_slice_segment.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/svc_encode_mb.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/svc_encode_slice.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/svc_mode_decision.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/svc_motion_estimate.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/svc_set_mb_syn_cabac.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/svc_set_mb_syn_cavlc.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/wels_preprocess.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/wels_task_base.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/wels_task_encoder.cpp
|
||||
third_party/openh264/src/codec/encoder/core/src/wels_task_management.cpp
|
||||
third_party/openh264/src/codec/encoder/plus/src/welsEncoderExt.cpp
|
||||
third_party/openh264/src/codec/common/src/welsCodecTrace.cpp
|
||||
third_party/openh264/src/codec/common/src/common_tables.cpp
|
||||
third_party/openh264/src/codec/common/src/copy_mb.cpp
|
||||
third_party/openh264/src/codec/common/src/cpu.cpp
|
||||
third_party/openh264/src/codec/common/src/crt_util_safe_x.cpp
|
||||
third_party/openh264/src/codec/common/src/deblocking_common.cpp
|
||||
third_party/openh264/src/codec/common/src/expand_pic.cpp
|
||||
third_party/openh264/src/codec/common/src/intra_pred_common.cpp
|
||||
third_party/openh264/src/codec/common/src/mc.cpp
|
||||
third_party/openh264/src/codec/common/src/memory_align.cpp
|
||||
third_party/openh264/src/codec/common/src/sad_common.cpp
|
||||
third_party/openh264/src/codec/common/src/WelsTaskThread.cpp
|
||||
third_party/openh264/src/codec/common/src/WelsThread.cpp
|
||||
third_party/openh264/src/codec/common/src/WelsThreadLib.cpp
|
||||
third_party/openh264/src/codec/common/src/WelsThreadPool.cpp
|
||||
third_party/openh264/src/codec/common/src/utils.cpp
|
||||
third_party/openh264/src/codec/processing/src/adaptivequantization/AdaptiveQuantization.cpp
|
||||
third_party/openh264/src/codec/processing/src/backgrounddetection/BackgroundDetection.cpp
|
||||
third_party/openh264/src/codec/processing/src/common/memory.cpp
|
||||
third_party/openh264/src/codec/processing/src/common/WelsFrameWork.cpp
|
||||
third_party/openh264/src/codec/processing/src/common/WelsFrameWorkEx.cpp
|
||||
third_party/openh264/src/codec/processing/src/complexityanalysis/ComplexityAnalysis.cpp
|
||||
third_party/openh264/src/codec/processing/src/denoise/denoise.cpp
|
||||
third_party/openh264/src/codec/processing/src/denoise/denoise_filter.cpp
|
||||
third_party/openh264/src/codec/processing/src/downsample/downsample.cpp
|
||||
third_party/openh264/src/codec/processing/src/downsample/downsamplefuncs.cpp
|
||||
third_party/openh264/src/codec/processing/src/imagerotate/imagerotate.cpp
|
||||
third_party/openh264/src/codec/processing/src/imagerotate/imagerotatefuncs.cpp
|
||||
third_party/openh264/src/codec/processing/src/scenechangedetection/SceneChangeDetection.cpp
|
||||
third_party/openh264/src/codec/processing/src/scrolldetection/ScrollDetection.cpp
|
||||
third_party/openh264/src/codec/processing/src/scrolldetection/ScrollDetectionFuncs.cpp
|
||||
third_party/openh264/src/codec/processing/src/vaacalc/vaacalcfuncs.cpp
|
||||
third_party/openh264/src/codec/processing/src/vaacalc/vaacalculation.cpp)
|
||||
target_compile_options(openh264 PUBLIC
|
||||
-Wall -finline-functions -fno-strict-aliasing -O3 -frtti -Wno-unknown-pragmas -funroll-loops -fexceptions -fno-math-errno)
|
||||
#openh264 (prebuilt static library)
|
||||
add_library(openh264 STATIC IMPORTED)
|
||||
set_target_properties(openh264 PROPERTIES
|
||||
ANDROID_ARM_MODE arm)
|
||||
target_compile_definitions(openh264 PRIVATE
|
||||
)
|
||||
target_compile_definitions(openh264 PUBLIC
|
||||
)
|
||||
target_include_directories(openh264 PUBLIC
|
||||
third_party/openh264/src/codec/encoder/core/inc
|
||||
third_party/openh264/src/codec/encoder/plus/inc
|
||||
third_party/openh264/src/codec/decoder/plus/inc
|
||||
third_party/openh264/src/codec/common/inc
|
||||
third_party/openh264/src/codec/api/svc
|
||||
third_party/openh264/src/codec/processing/interface
|
||||
third_party/openh264/src/codec/processing/src/common)
|
||||
|
||||
if (${ANDROID_ABI} STREQUAL "armeabi-v7a")
|
||||
target_sources(openh264 PRIVATE
|
||||
third_party/openh264/src/codec/encoder/core/arm/intra_pred_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm/intra_pred_sad_3_opt_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm/memory_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm/pixel_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm/reconstruct_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm/svc_motion_estimation.S
|
||||
third_party/openh264/src/codec/common/arm/copy_mb_neon.S
|
||||
third_party/openh264/src/codec/common/arm/deblocking_neon.S
|
||||
third_party/openh264/src/codec/common/arm/expand_picture_neon.S
|
||||
third_party/openh264/src/codec/common/arm/intra_pred_common_neon.S
|
||||
third_party/openh264/src/codec/common/arm/mc_neon.S
|
||||
third_party/openh264/src/codec/processing/src/arm/adaptive_quantization.S
|
||||
third_party/openh264/src/codec/processing/src/arm/down_sample_neon.S
|
||||
third_party/openh264/src/codec/processing/src/arm/pixel_sad_neon.S
|
||||
third_party/openh264/src/codec/processing/src/arm/vaa_calc_neon.S)
|
||||
target_include_directories(openh264 PUBLIC
|
||||
third_party/openh264/src/codec/common/arm)
|
||||
target_compile_definitions(openh264 PUBLIC
|
||||
HAVE_NEON=1)
|
||||
elseif(${ANDROID_ABI} STREQUAL "arm64-v8a")
|
||||
target_sources(openh264 PRIVATE
|
||||
third_party/openh264/src/codec/encoder/core/arm64/intra_pred_aarch64_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm64/intra_pred_sad_3_opt_aarch64_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm64/memory_aarch64_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm64/pixel_aarch64_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm64/reconstruct_aarch64_neon.S
|
||||
third_party/openh264/src/codec/encoder/core/arm64/svc_motion_estimation_aarch64_neon.S
|
||||
third_party/openh264/src/codec/common/arm64/copy_mb_aarch64_neon.S
|
||||
third_party/openh264/src/codec/common/arm64/deblocking_aarch64_neon.S
|
||||
third_party/openh264/src/codec/common/arm64/expand_picture_aarch64_neon.S
|
||||
third_party/openh264/src/codec/common/arm64/intra_pred_common_aarch64_neon.S
|
||||
third_party/openh264/src/codec/common/arm64/mc_aarch64_neon.S
|
||||
third_party/openh264/src/codec/processing/src/arm64/adaptive_quantization_aarch64_neon.S
|
||||
third_party/openh264/src/codec/processing/src/arm64/down_sample_aarch64_neon.S
|
||||
third_party/openh264/src/codec/processing/src/arm64/pixel_sad_aarch64_neon.S
|
||||
third_party/openh264/src/codec/processing/src/arm64/vaa_calc_aarch64_neon.S)
|
||||
target_include_directories(openh264 PUBLIC
|
||||
third_party/openh264/src/codec/common/arm64)
|
||||
target_compile_definitions(openh264 PUBLIC
|
||||
HAVE_NEON_AARCH64=1)
|
||||
endif()
|
||||
IMPORTED_LOCATION ${CMAKE_HOME_DIRECTORY}/prebuild/${ANDROID_ABI}/libopenh264.a)
|
||||
|
||||
#rnnoise
|
||||
add_library(rnnoise STATIC
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@
|
|||
#include "system_wrappers/include/metrics.h"
|
||||
#include "third_party/libyuv/include/libyuv/convert.h"
|
||||
#include "third_party/libyuv/include/libyuv/scale.h"
|
||||
#include "third_party/openh264/src/codec/api/svc/codec_api.h"
|
||||
#include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
|
||||
#include "third_party/openh264/src/codec/api/svc/codec_def.h"
|
||||
#include "third_party/openh264/src/codec/api/svc/codec_ver.h"
|
||||
#include "third_party/openh264/codec/api/wels/codec_app_def.h"
|
||||
#include "third_party/openh264/codec/api/wels/codec_api.h"
|
||||
#include "third_party/openh264/codec/api/wels/codec_def.h"
|
||||
#include "third_party/openh264/codec/api/wels/codec_ver.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "modules/video_coding/codecs/h264/include/h264.h"
|
||||
#include "modules/video_coding/svc/scalable_video_controller.h"
|
||||
#include "modules/video_coding/utility/quality_scaler.h"
|
||||
#include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
|
||||
#include "third_party/openh264/codec/api/wels/codec_app_def.h"
|
||||
|
||||
class ISVCEncoder;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,224 @@
|
|||
package org.telegram.messenger;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
|
||||
import org.telegram.ui.Components.ForegroundDetector;
|
||||
|
||||
public class ANRDetector implements ForegroundDetector.Listener {
|
||||
|
||||
private static final long TIMEOUT_MS = 5000;
|
||||
|
||||
private static final int MSG_UI_PING = 1;
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
private final Handler mainHandler;
|
||||
private final Thread detectorThread;
|
||||
private final Runnable anrDetected;
|
||||
|
||||
private volatile boolean foreground;
|
||||
private volatile boolean destroyed;
|
||||
|
||||
/**
|
||||
* Changes on every foreground/background transition.
|
||||
*/
|
||||
private volatile int generation;
|
||||
|
||||
/**
|
||||
* Monotonically increasing id of each UI ping.
|
||||
*/
|
||||
private int nextPingId;
|
||||
|
||||
/**
|
||||
* Last ping actually executed by the main thread.
|
||||
*/
|
||||
private volatile int acknowledgedPingId = -1;
|
||||
|
||||
/**
|
||||
* Prevents reporting the same freeze repeatedly.
|
||||
*
|
||||
* Reset only after the main thread becomes responsive again.
|
||||
*/
|
||||
private volatile boolean anrReported;
|
||||
|
||||
public ANRDetector(Runnable anrDetected) {
|
||||
this.anrDetected = anrDetected;
|
||||
|
||||
mainHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (msg.what != MSG_UI_PING) {
|
||||
return;
|
||||
}
|
||||
|
||||
acknowledgedPingId = msg.arg1;
|
||||
|
||||
/*
|
||||
* If we previously detected an ANR, execution of this
|
||||
* message means that the UI thread has recovered.
|
||||
*/
|
||||
anrReported = false;
|
||||
}
|
||||
};
|
||||
|
||||
ForegroundDetector foregroundDetector = ForegroundDetector.getInstance();
|
||||
|
||||
foreground = foregroundDetector.isForeground();
|
||||
|
||||
foregroundDetector.addListener(this);
|
||||
|
||||
detectorThread = new Thread(this::run, "ANRDetector");
|
||||
detectorThread.start();
|
||||
}
|
||||
|
||||
private void run() {
|
||||
while (true) {
|
||||
final int checkGeneration;
|
||||
final int pingId;
|
||||
|
||||
synchronized (lock) {
|
||||
/*
|
||||
* Do absolutely nothing while the application is in
|
||||
* background.
|
||||
*/
|
||||
while (!foreground && !destroyed) {
|
||||
try {
|
||||
lock.wait();
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkGeneration = generation;
|
||||
pingId = ++nextPingId;
|
||||
}
|
||||
|
||||
/*
|
||||
* Post a ping to the main thread.
|
||||
*/
|
||||
Message message = mainHandler.obtainMessage(
|
||||
MSG_UI_PING,
|
||||
pingId,
|
||||
checkGeneration
|
||||
);
|
||||
message.sendToTarget();
|
||||
|
||||
try {
|
||||
Thread.sleep(TIMEOUT_MS);
|
||||
} catch (InterruptedException ignore) {
|
||||
/*
|
||||
* Usually means foreground/background transition
|
||||
* or destroy().
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore this check if application state changed while
|
||||
* we were waiting.
|
||||
*/
|
||||
if (!foreground || generation != checkGeneration) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main thread processed our ping in time.
|
||||
*/
|
||||
if (acknowledgedPingId == pingId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* UI thread did not process the ping within TIMEOUT_MS.
|
||||
*
|
||||
* Report only once until the UI actually recovers.
|
||||
*/
|
||||
if (!anrReported) {
|
||||
anrReported = true;
|
||||
|
||||
try {
|
||||
anrDetected.run();
|
||||
} catch (Throwable e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBecameForeground() {
|
||||
synchronized (lock) {
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
generation++;
|
||||
foreground = true;
|
||||
|
||||
/*
|
||||
* A previous ANR belongs to the previous foreground
|
||||
* session.
|
||||
*/
|
||||
anrReported = false;
|
||||
|
||||
lock.notifyAll();
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt any timeout that may belong to an old generation.
|
||||
*/
|
||||
detectorThread.interrupt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBecameBackground() {
|
||||
synchronized (lock) {
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
generation++;
|
||||
foreground = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Old UI pings are no longer interesting.
|
||||
*/
|
||||
mainHandler.removeMessages(MSG_UI_PING);
|
||||
|
||||
/*
|
||||
* Wake the detector from Thread.sleep() immediately so it can
|
||||
* enter lock.wait() and consume no periodic CPU in background.
|
||||
*/
|
||||
detectorThread.interrupt();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
synchronized (lock) {
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
destroyed = true;
|
||||
foreground = false;
|
||||
generation++;
|
||||
|
||||
lock.notifyAll();
|
||||
}
|
||||
|
||||
ForegroundDetector.getInstance().removeListener(this);
|
||||
|
||||
mainHandler.removeMessages(MSG_UI_PING);
|
||||
|
||||
detectorThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
|
@ -6693,6 +6693,10 @@ public class AndroidUtilities {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static String getHelloWorld() {
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
public static String getBuildVersionInfo() {
|
||||
try {
|
||||
PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
|
||||
|
|
|
|||
|
|
@ -289,7 +289,11 @@ public class ApplicationLoader extends Application {
|
|||
|
||||
super.onCreate();
|
||||
|
||||
// AndroidUtilities must be initialized before FileLog
|
||||
final String helloWorld = AndroidUtilities.getHelloWorld();
|
||||
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d(helloWorld);
|
||||
FileLog.d("app start time = " + (startTime = SystemClock.elapsedRealtime()));
|
||||
try {
|
||||
final PackageInfo info = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
|
||||
|
|
@ -335,6 +339,10 @@ public class ApplicationLoader extends Application {
|
|||
}
|
||||
}
|
||||
};
|
||||
if (BuildConfig.DEBUG_VERSION) {
|
||||
new ANRDetector(FileLog::dumpANR);
|
||||
}
|
||||
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("load libs time = " + (SystemClock.elapsedRealtime() - startTime));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ import com.android.billingclient.api.BillingClientStateListener;
|
|||
import com.android.billingclient.api.BillingFlowParams;
|
||||
import com.android.billingclient.api.BillingResult;
|
||||
import com.android.billingclient.api.ConsumeParams;
|
||||
import com.android.billingclient.api.PendingPurchasesParams;
|
||||
import com.android.billingclient.api.ProductDetails;
|
||||
import com.android.billingclient.api.ProductDetailsResponseListener;
|
||||
import com.android.billingclient.api.Purchase;
|
||||
import com.android.billingclient.api.PurchasesResponseListener;
|
||||
import com.android.billingclient.api.PurchasesUpdatedListener;
|
||||
|
|
@ -79,7 +79,7 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
|
|||
|
||||
private BillingController(Context ctx) {
|
||||
billingClient = BillingClient.newBuilder(ctx)
|
||||
.enablePendingPurchases()
|
||||
.enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build())
|
||||
.setListener(this)
|
||||
.build();
|
||||
}
|
||||
|
|
@ -160,7 +160,7 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
|
|||
return;
|
||||
}
|
||||
billingClientEmpty = true;
|
||||
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.billingProductDetailsUpdated);
|
||||
NotificationCenter.getGlobalInstance().postNotificationNameOnUIThread(NotificationCenter.billingProductDetailsUpdated);
|
||||
}
|
||||
|
||||
private void switchBackFromInvoice() {
|
||||
|
|
@ -168,18 +168,23 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
|
|||
return;
|
||||
}
|
||||
billingClientEmpty = false;
|
||||
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.billingProductDetailsUpdated);
|
||||
NotificationCenter.getGlobalInstance().postNotificationNameOnUIThread(NotificationCenter.billingProductDetailsUpdated);
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return billingClient.isReady();
|
||||
}
|
||||
|
||||
public void queryProductDetails(List<QueryProductDetailsParams.Product> products, ProductDetailsResponseListener responseListener) {
|
||||
public interface ProductDetailsResponseListenerLegacy {
|
||||
void onProductDetailsResponse(BillingResult billingResult, List<ProductDetails> list);
|
||||
}
|
||||
|
||||
public void queryProductDetails(List<QueryProductDetailsParams.Product> products, ProductDetailsResponseListenerLegacy responseListener) {
|
||||
if (!isReady()) {
|
||||
throw new IllegalStateException("Billing: Controller should be ready for this call!");
|
||||
}
|
||||
billingClient.queryProductDetailsAsync(QueryProductDetailsParams.newBuilder().setProductList(products).build(), responseListener);
|
||||
billingClient.queryProductDetailsAsync(QueryProductDetailsParams.newBuilder().setProductList(products).build(), (billingResult, queryProductDetailsResult) ->
|
||||
responseListener.onProductDetailsResponse(billingResult, queryProductDetailsResult.getProductDetailsList()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -293,10 +293,37 @@ public class BotForumHelper extends BaseController {
|
|||
|
||||
public boolean hasBotForumDrafts(long userId, int topicId) {
|
||||
LongSparseArray<BotDraftMessage> messages = botTextDraftsByRandomIds.get(userId, topicId);
|
||||
return messages != null && messages.size() > 0;
|
||||
if (messages != null && messages.size() > 0) {
|
||||
for (int a = 0, N = messages.size(); a < N; a++) {
|
||||
if (!messages.valueAt(a).removed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeAllMarkedAsRemovedMessages(long userId, int topicId) {
|
||||
LongSparseArray<BotDraftMessage> messages = botTextDraftsByRandomIds.get(userId, topicId);
|
||||
if (messages == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int a = 0, N = messages.size(); a < N; a++) {
|
||||
BotDraftMessage draftMessage = messages.valueAt(a);
|
||||
if (draftMessage.removed) {
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.botForumDraftDelete,
|
||||
new BotForumTextDraftDeleteNotification(userId, topicId, draftMessage.localMessageId));
|
||||
botTextDraftsByRandomIds.remove(userId, topicId, draftMessage.randomId);
|
||||
a--;
|
||||
N--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MessageObject onBotForumDraftCheckNewMessages(long userId, int topicId, int messageId, String message) {
|
||||
removeAllMarkedAsRemovedMessages(userId, topicId);
|
||||
|
||||
LongSparseArray<BotDraftMessage> messages = botTextDraftsByRandomIds.get(userId, topicId);
|
||||
if (messages == null) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ public class FileLog {
|
|||
private File networkFile = null;
|
||||
private File tonlibFile = null;
|
||||
private boolean initied;
|
||||
private boolean initiing;
|
||||
public static boolean databaseIsMalformed = false;
|
||||
|
||||
private OutputStreamWriter tlStreamWriter = null;
|
||||
|
|
@ -71,17 +72,17 @@ public class FileLog {
|
|||
localInstance = Instance;
|
||||
if (localInstance == null) {
|
||||
Instance = localInstance = new FileLog();
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
localInstance.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return localInstance;
|
||||
}
|
||||
|
||||
public FileLog() {
|
||||
if (!BuildVars.LOGS_ENABLED) {
|
||||
return;
|
||||
}
|
||||
init();
|
||||
private FileLog() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -297,10 +298,17 @@ public class FileLog {
|
|||
}
|
||||
|
||||
|
||||
public void init() {
|
||||
private void init() {
|
||||
if (initied) {
|
||||
return;
|
||||
}
|
||||
if (initiing) {
|
||||
if (BuildConfig.DEBUG_PRIVATE_VERSION) {
|
||||
throw new IllegalStateException("double init call");
|
||||
}
|
||||
}
|
||||
initiing = true;
|
||||
|
||||
dateFormat = FastDateFormat.getInstance("dd_MM_yyyy_HH_mm_ss.SSS", Locale.US);
|
||||
fileDateFormat = FastDateFormat.getInstance("dd_MM_yyyy_HH_mm_ss", Locale.US);
|
||||
String date = fileDateFormat.format(System.currentTimeMillis());
|
||||
|
|
@ -329,9 +337,6 @@ public class FileLog {
|
|||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (BuildVars.DEBUG_VERSION) {
|
||||
new ANRDetector(this::dumpANR);
|
||||
}
|
||||
initied = true;
|
||||
}
|
||||
|
||||
|
|
@ -483,7 +488,7 @@ public class FileLog {
|
|||
}
|
||||
}
|
||||
|
||||
private void dumpANR() {
|
||||
public static void dumpANR() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Map<Thread, StackTraceElement[]> allThreads = Thread.getAllStackTraces();
|
||||
|
||||
|
|
@ -499,7 +504,7 @@ public class FileLog {
|
|||
}
|
||||
|
||||
FileLog.e("ANR thread dump\n" + sb.toString());
|
||||
dumpMemory(false);
|
||||
getInstance().dumpMemory(false);
|
||||
}
|
||||
|
||||
public static void fatal(final Throwable e, boolean logToAppCenter) {
|
||||
|
|
@ -624,31 +629,4 @@ public class FileLog {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public class ANRDetector {
|
||||
private final long TIMEOUT_MS = 5000; // ANR threshold (5 seconds)
|
||||
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
private boolean isUIThreadResponsive = true;
|
||||
|
||||
public ANRDetector(Runnable anrDetected) {
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
isUIThreadResponsive = false;
|
||||
|
||||
// Post a task to the main thread
|
||||
mainHandler.post(() -> isUIThreadResponsive = true);
|
||||
|
||||
try {
|
||||
Thread.sleep(TIMEOUT_MS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!isUIThreadResponsive) {
|
||||
anrDetected.run();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10131,6 +10131,9 @@ public class MessageObject {
|
|||
}
|
||||
|
||||
public boolean canSetReaction() {
|
||||
if (isEphemeral()) {
|
||||
return false;
|
||||
}
|
||||
if (messageOwner instanceof TLRPC.TL_messageService)
|
||||
return messageOwner.reactions_are_possible;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ public class RichMessageLayout {
|
|||
private static final int ORDERED_LIST_MARKER_START_DP = 6;
|
||||
|
||||
public final ArrayList<RichUnsupportedBlock> unsupportedBlocks = new ArrayList<>();
|
||||
public final ArrayList<RichUnsupportedBlock> unsupportedBlocksRoot = new ArrayList<>();
|
||||
public final ArrayList<RichBlock> blocks = new ArrayList<>();
|
||||
public final ArrayList<QuoteBackground> quotes = new ArrayList<>();
|
||||
private Drawable pullquoteIcon;
|
||||
|
|
@ -353,6 +354,7 @@ public class RichMessageLayout {
|
|||
}
|
||||
|
||||
unsupportedBlocks.clear();
|
||||
unsupportedBlocksRoot.clear();
|
||||
blocks.clear();
|
||||
quotes.clear();
|
||||
anchors.clear();
|
||||
|
|
@ -1144,11 +1146,15 @@ public class RichMessageLayout {
|
|||
}
|
||||
return null;
|
||||
} else if (pageBlock instanceof TL_iv.pageBlockUnsupported) {
|
||||
final int o = BitwiseUtils.hasFlag(textFlags, TEXT_FLAG_BLOCK_QUOTE) ? dp(6) : level > 0 ? dp(4) : 0;
|
||||
final RichUnsupportedBlock block = new RichUnsupportedBlock(this, new Rect(
|
||||
-dp(7), Math.max(dp(14), padding.top),
|
||||
-dp(7), Math.max(dp(14), padding.bottom)
|
||||
), maxWidth, blocks.size());
|
||||
padding.left + o - dp(7), Math.max(dp(14), padding.top),
|
||||
padding.right + o - dp(7), Math.max(dp(14), padding.bottom)
|
||||
), maxWidth, blocks.size(), level);
|
||||
unsupportedBlocks.add(block);
|
||||
if (level == 0) {
|
||||
unsupportedBlocksRoot.add(block);
|
||||
}
|
||||
blocks.add(block);
|
||||
return block;
|
||||
} else if (pageBlock instanceof TL_iv.pageBlockDetails) {
|
||||
|
|
@ -1210,10 +1216,19 @@ public class RichMessageLayout {
|
|||
return !unsupportedBlocks.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasRootUnsupportedBlocks() {
|
||||
return !unsupportedBlocksRoot.isEmpty();
|
||||
|
||||
}
|
||||
|
||||
public ArrayList<RichUnsupportedBlock> getUnsupportedHoles() {
|
||||
return unsupportedBlocks;
|
||||
}
|
||||
|
||||
public ArrayList<RichUnsupportedBlock> getUnsupportedHolesRoot() {
|
||||
return unsupportedBlocksRoot;
|
||||
}
|
||||
|
||||
public int getMinWidth() {
|
||||
return minWidth;
|
||||
}
|
||||
|
|
@ -2766,6 +2781,31 @@ public class RichMessageLayout {
|
|||
private int pressedLinkStart, pressedLinkEnd;
|
||||
private AnimatedEmojiSpan pressedEmoji;
|
||||
private RichButtonSpan pressedButtonSpan;
|
||||
private final RectF soleButtonHitBounds = new RectF();
|
||||
|
||||
private RichButtonSpan getSoleButtonSpan() {
|
||||
if (!(layout.getText() instanceof Spanned)) return null;
|
||||
final Spanned text = (Spanned) layout.getText();
|
||||
final RichButtonSpan[] spans = text.getSpans(0, text.length(), RichButtonSpan.class);
|
||||
if (spans.length != 1) return null;
|
||||
final int spanStart = text.getSpanStart(spans[0]);
|
||||
final int spanEnd = text.getSpanEnd(spans[0]);
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
if ((i < spanStart || i >= spanEnd) && !Character.isWhitespace(text.charAt(i))) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return spans[0];
|
||||
}
|
||||
|
||||
private void setSoleButtonHitBounds(float left, float top, float right, float bottom) {
|
||||
soleButtonHitBounds.set(left, top, right, bottom);
|
||||
}
|
||||
|
||||
private boolean buttonContains(RichButtonSpan span, float x, float y) {
|
||||
return span.contains(x, y, dp(8))
|
||||
|| (span == getSoleButtonSpan() && soleButtonHitBounds.contains(x, y));
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
final int act = event.getActionMasked();
|
||||
|
|
@ -2789,7 +2829,7 @@ public class RichMessageLayout {
|
|||
final RichButtonSpan[] buttonSpans = getButtonSpans();
|
||||
if (buttonSpans != null) {
|
||||
for (RichButtonSpan span : buttonSpans) {
|
||||
if (span.contains(lx, ly)) {
|
||||
if (buttonContains(span, lx, ly)) {
|
||||
if (span.isDisabled()) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2891,7 +2931,7 @@ public class RichMessageLayout {
|
|||
if (act == MotionEvent.ACTION_MOVE) {
|
||||
if (pressedButtonSpan != null) {
|
||||
// drop the press once the finger leaves the pill, same as a bot button row
|
||||
if (!pressedButtonSpan.contains(lx, ly)) {
|
||||
if (!buttonContains(pressedButtonSpan, lx, ly)) {
|
||||
cancelLongPress();
|
||||
pressedButtonSpan.setPressed(false);
|
||||
pressedButtonSpan = null;
|
||||
|
|
@ -4479,6 +4519,11 @@ public class RichMessageLayout {
|
|||
pressedCellText = (Text) cell.textLayout;
|
||||
cellDx = cell.getTextX() - scrollX;
|
||||
cellDy = titleHeight + cell.getTextY();
|
||||
pressedCellText.setSoleButtonHitBounds(
|
||||
cell.x - cell.getTextX(), cell.y - cell.getTextY(),
|
||||
cell.x + cell.getMeasuredWidth() - cell.getTextX(),
|
||||
cell.y + cell.getMeasuredHeight() - cell.getTextY()
|
||||
);
|
||||
event.offsetLocation(-cellDx, -cellDy);
|
||||
textHandlingTouch = pressedCellText.onTouchEvent(event);
|
||||
event.offsetLocation(cellDx, cellDy);
|
||||
|
|
@ -4704,13 +4749,15 @@ public class RichMessageLayout {
|
|||
public final int unsupportedBlockWidth;
|
||||
public final int unsupportedBlockHeight;
|
||||
public final int index;
|
||||
public final int level;
|
||||
|
||||
public TornEdge.Params tornParams;
|
||||
public Bitmap tornBitmap;
|
||||
|
||||
public RichUnsupportedBlock(RichMessageLayout root, Rect padding, int maxWidth, int index) {
|
||||
public RichUnsupportedBlock(RichMessageLayout root, Rect padding, int maxWidth, int index, int level) {
|
||||
super(root, padding, maxWidth);
|
||||
this.index = index;
|
||||
this.level = level;
|
||||
|
||||
unsupportedBlockDrawable = new UnsupportedBlockDrawable(root.resourcesProvider);
|
||||
unsupportedBlockDrawable.setCallback(this);
|
||||
|
|
@ -5737,6 +5784,11 @@ public class RichMessageLayout {
|
|||
return bounds.contains(x, y);
|
||||
}
|
||||
|
||||
public boolean contains(float x, float y, float padding) {
|
||||
return x >= bounds.left - padding && x < bounds.right + padding
|
||||
&& y >= bounds.top - padding && y < bounds.bottom + padding;
|
||||
}
|
||||
|
||||
public void setPressed(boolean pressed) {
|
||||
button.setPressed(pressed);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.text.TextUtils;
|
|||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.telegram.tgnet.NativeByteBuffer;
|
||||
import org.telegram.tgnet.TLObject;
|
||||
|
||||
import org.telegram.messenger.MediaDataController;
|
||||
|
|
@ -277,4 +278,49 @@ public class TlUtils {
|
|||
poll.shuffled_answers.sort((a1, a2) -> Long.compareUnsigned(a1.shuffle_hash, a2.shuffle_hash));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean tlEquals(TLObject object1, TLObject object2) {
|
||||
if (object1 == object2) {
|
||||
return true;
|
||||
}
|
||||
if (object1 == null || object2 == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int size1 = object1.getObjectSize();
|
||||
final int size2 = object2.getObjectSize();
|
||||
if (size1 != size2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
NativeByteBuffer data1 = new NativeByteBuffer(size1);
|
||||
object1.serializeToStream(data1);
|
||||
data1.rewind();
|
||||
|
||||
NativeByteBuffer data2 = new NativeByteBuffer(size2);
|
||||
object2.serializeToStream(data2);
|
||||
data2.rewind();
|
||||
|
||||
int remaining = size1;
|
||||
|
||||
while (remaining >= 8) {
|
||||
if (data1.readInt64(true) != data2.readInt64(true)) {
|
||||
return false;
|
||||
}
|
||||
remaining -= 8;
|
||||
}
|
||||
|
||||
while (remaining > 0) {
|
||||
if (data1.readByte(true) != data2.readByte(true)) {
|
||||
return false;
|
||||
}
|
||||
remaining--;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ import org.telegram.ui.Components.SnowflakesEffect;
|
|||
import org.telegram.ui.Components.blur3.BlurredBackgroundDrawableViewFactory;
|
||||
import org.telegram.ui.Components.blur3.drawable.BlurredBackgroundDrawable;
|
||||
import org.telegram.ui.Components.blur3.drawable.color.BlurredBackgroundColorProvider;
|
||||
import org.telegram.ui.MainTabsLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
|
@ -1859,6 +1860,47 @@ public class ActionBar extends FrameLayout implements FactorAnimator.Target, The
|
|||
return castShadows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (chatAvatarContainer != null && glassMode) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
final int x = (int) ev.getX();
|
||||
final int y = (int) ev.getY();
|
||||
View child = findChildUnder(this, x, y, chatAvatarContainer);
|
||||
if (child == null) {
|
||||
child = findChildUnder(this, x, y, null);
|
||||
}
|
||||
|
||||
boolean contains = false;
|
||||
contains |= glassDrawable != null && glassDrawable.getBounds().contains(x, y);
|
||||
if (child != null && child != chatAvatarContainer) {
|
||||
contains |= glassDrawableBack != null && glassDrawableBack.getBounds().contains(x, y);
|
||||
contains |= glassDrawableMenu != null && glassDrawableMenu.getBounds().contains(x, y);
|
||||
}
|
||||
|
||||
if (!contains) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
public static View findChildUnder(ViewGroup parent, float x, float y, View exclude) {
|
||||
for (int i = parent.getChildCount() - 1; i >= 0; i--) {
|
||||
View child = parent.getChildAt(i);
|
||||
|
||||
if (child.getVisibility() != View.VISIBLE || child == exclude) continue;
|
||||
|
||||
if (x >= child.getX() && x <= (child.getX() + child.getWidth())
|
||||
&& y >= child.getTop() && y <= child.getBottom()) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (forceSkipTouches) {
|
||||
|
|
@ -2110,7 +2152,7 @@ public class ActionBar extends FrameLayout implements FactorAnimator.Target, The
|
|||
final boolean hasAvatar = chatAvatarContainer.hasVisibleAvatar();
|
||||
int visualWidth = chatAvatarContainer.getVisualWidth();
|
||||
if (hasAvatar) {
|
||||
visualWidth = Math.max(visualWidth, dp(192));
|
||||
//visualWidth = Math.max(visualWidth, dp(168));
|
||||
}
|
||||
|
||||
final int width = Math.min(getMeasuredWidth() - dp(6 + 46 + 6 + 6 + 46 + 6), visualWidth);
|
||||
|
|
@ -2136,7 +2178,9 @@ public class ActionBar extends FrameLayout implements FactorAnimator.Target, The
|
|||
}
|
||||
|
||||
private int forcedMenuWidth;
|
||||
private int forcedMenuMinWidth;
|
||||
private boolean hasForcedMenuWidth;
|
||||
private boolean hasForcedMenuMinWidth;
|
||||
|
||||
public void setForcedMenuWidth(int width) {
|
||||
hasForcedMenuWidth = true;
|
||||
|
|
@ -2146,6 +2190,14 @@ public class ActionBar extends FrameLayout implements FactorAnimator.Target, The
|
|||
}
|
||||
}
|
||||
|
||||
public void setForcedMenuMinWidth(int width) {
|
||||
hasForcedMenuMinWidth = true;
|
||||
if (forcedMenuMinWidth != width) {
|
||||
forcedMenuMinWidth = width;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAnimationsAllowed;
|
||||
|
||||
public void checkMenuItemsWidth() {
|
||||
|
|
@ -2172,7 +2224,8 @@ public class ActionBar extends FrameLayout implements FactorAnimator.Target, The
|
|||
final int s = dp(46);
|
||||
|
||||
final float actionModeFactor = getActionModeFactor();
|
||||
final int menuWidth = hasForcedMenuWidth ? forcedMenuWidth : (int) animatorMenuItemsWidth.getFactor();
|
||||
final int menuWidthA = hasForcedMenuWidth ? forcedMenuWidth : (int) animatorMenuItemsWidth.getFactor();
|
||||
final int menuWidth = hasForcedMenuMinWidth ? Math.max((int) (forcedMenuMinWidth * (1f - searchFactor)), menuWidthA) : menuWidthA;
|
||||
|
||||
final boolean hasBackButton = backButtonImageView != null && backButtonImageView.getVisibility() == View.VISIBLE;
|
||||
|
||||
|
|
@ -2180,7 +2233,7 @@ public class ActionBar extends FrameLayout implements FactorAnimator.Target, The
|
|||
final int b = t + s + p * 2;
|
||||
|
||||
if (glassDrawable != null && !glassOnlyBack) {
|
||||
final int menuWidthWithPadding = menuWidth + (hasForcedMenuWidth ? (menuWidth > 0 ? p : 0) : (int) (p * animatorHasMenuItems.getFloatValue()));
|
||||
final int menuWidthWithPadding = menuWidth + ((hasForcedMenuWidth || hasForcedMenuMinWidth) ? (menuWidth > 0 ? p : 0) : (int) (p * animatorHasMenuItems.getFloatValue()));
|
||||
final int rightOffset = lerp(menuWidthWithPadding, Math.max(menuWidthWithPadding, p + s), chatAvatarContainer == null ? 0f : 1f - animatorAvatarContainerHasAvatar.getFloatValue());
|
||||
|
||||
final int leftDefault = lerp(hasBackButton ? s + p : 0, s + p, chatAvatarContainer == null? 0f : 1f - animatorAvatarContainerHasAvatar.getFloatValue());
|
||||
|
|
@ -2191,10 +2244,13 @@ public class ActionBar extends FrameLayout implements FactorAnimator.Target, The
|
|||
final int width = lerp(Math.min(widthDefault, (int) animatorAvatarContainerWidth.getFactor() + p * 2), widthDefault, Math.max(searchFactor, actionModeFactor));
|
||||
left = (rightDefault + leftDefault - width) / 2;
|
||||
right = left + width;
|
||||
chatAvatarContainer.setTranslationX(left
|
||||
|
||||
final float translationX = left
|
||||
- ((MarginLayoutParams)(chatAvatarContainer.getLayoutParams())).leftMargin
|
||||
- chatAvatarContainer.getLeftPadding()
|
||||
+ p + dp(3));
|
||||
+ p + dp(3);
|
||||
chatAvatarContainer.setTranslationX(translationX);
|
||||
chatAvatarContainer.setPivotX((chatAvatarContainer.getMeasuredWidth()) / 2f - translationX );
|
||||
} else {
|
||||
left = leftDefault;
|
||||
right = rightDefault;
|
||||
|
|
|
|||
|
|
@ -12059,7 +12059,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
flagSecure = new FlagSecureReason(window, () ->
|
||||
currentMessageObject != null && currentMessageObject.messageOwner != null && (
|
||||
currentMessageObject.type == MessageObject.TYPE_PAID_MEDIA && (groupMedia == null || !groupMedia.hidden) ||
|
||||
currentMessageObject.messageOwner.noforwards ||
|
||||
currentMessageObject.messageOwner.noforwards && !currentMessageObject.isEphemeral() ||
|
||||
currentMessageObject.isVoiceOnce() ||
|
||||
currentMessageObject.hasRevealedExtendedMedia()
|
||||
)
|
||||
|
|
@ -20377,12 +20377,15 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
|
||||
|
||||
final boolean hasUnsupportedBlocks = currentMessageObject.richLayout != null && currentMessageObject.richLayout.hasUnsupportedBlocks();
|
||||
final boolean hasRootUnsupportedBlocks = currentMessageObject.richLayout != null && currentMessageObject.richLayout.hasRootUnsupportedBlocks();
|
||||
ArrayList<RichMessageLayout.RichUnsupportedBlock> holes = null;
|
||||
ArrayList<RichMessageLayout.RichUnsupportedBlock> holesRoot = null;
|
||||
if (!internal && hasUnsupportedBlocks) {
|
||||
holes = currentMessageObject.richLayout.getUnsupportedHoles();
|
||||
holesRoot = currentMessageObject.richLayout.getUnsupportedHolesRoot();
|
||||
}
|
||||
|
||||
if (!internal && hasUnsupportedBlocks && holes != null && !holes.isEmpty()) {
|
||||
if (!internal && hasRootUnsupportedBlocks && holes != null && !holes.isEmpty()) {
|
||||
//if (transitionParams != null && transitionParams.animateChange || currentMessageObject.richLayout.blockquoteAnimating || currentMessageObject.richLayout.detailsAnimating) {
|
||||
layoutTextXY(false);
|
||||
//}
|
||||
|
|
@ -20391,8 +20394,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
|
||||
boolean result = false;
|
||||
int bY = 0;
|
||||
for (int a = 0, N = holes.size(); a <= N; a++) {
|
||||
RichMessageLayout.RichUnsupportedBlock hole = a < N ? holes.get(a) : null;
|
||||
for (int a = 0, N = holesRoot.size(); a <= N; a++) {
|
||||
RichMessageLayout.RichUnsupportedBlock hole = a < N ? holesRoot.get(a) : null;
|
||||
canvas.save();
|
||||
if (hole != null) {
|
||||
canvas.clipRect(0, a == 0 ? Integer.MIN_VALUE : textY + bY, getWidth(), textY + (int) hole.getY(transitionParams));
|
||||
|
|
@ -20449,24 +20452,25 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
|
||||
if (drawBackground) {
|
||||
for (int a = 0, N = holes.size(); a < N; a++) {
|
||||
RichMessageLayout.RichUnsupportedBlock hole = holes.get(a);
|
||||
final int tornWidth = backgroundRight - backgroundLeft;
|
||||
if (hole.tornBitmap == null || hole.tornBitmap.getWidth() < tornWidth) {
|
||||
hole.tornParams = new TornEdge.Params();
|
||||
hole.tornBitmap = TornEdge.createTearBitmap(hole.tornParams, tornWidth,
|
||||
currentMessageObject.getId() * 100 + hole.index);
|
||||
}
|
||||
|
||||
final RichMessageLayout.RichUnsupportedBlock hole = holes.get(a);
|
||||
final float t = textY + hole.getY(transitionParams);
|
||||
final float b = t + hole.getHeight(transitionParams);
|
||||
canvas.save();
|
||||
canvas.clipRect(backgroundLeft, 0, backgroundRight, getHeight());
|
||||
TornEdge.drawTopEdge(canvas, hole.tornBitmap, hole.tornParams, tornWidth, backgroundLeft, t, paint);
|
||||
TornEdge.drawBottomEdge(canvas, hole.tornBitmap, hole.tornParams, tornWidth, backgroundLeft, b, paint);
|
||||
canvas.restore();
|
||||
if (hole.level == 0) {
|
||||
final int tornWidth = backgroundRight - backgroundLeft;
|
||||
if (hole.tornBitmap == null || hole.tornBitmap.getWidth() < tornWidth) {
|
||||
hole.tornParams = new TornEdge.Params();
|
||||
hole.tornBitmap = TornEdge.createTearBitmap(hole.tornParams, tornWidth,
|
||||
currentMessageObject.getId() * 100 + hole.index);
|
||||
}
|
||||
canvas.save();
|
||||
canvas.clipRect(backgroundLeft, 0, backgroundRight, getHeight());
|
||||
TornEdge.drawTopEdge(canvas, hole.tornBitmap, hole.tornParams, tornWidth, backgroundLeft, t, paint);
|
||||
TornEdge.drawBottomEdge(canvas, hole.tornBitmap, hole.tornParams, tornWidth, backgroundLeft, b, paint);
|
||||
canvas.restore();
|
||||
}
|
||||
AndroidUtilities.rectTmp.set(
|
||||
backgroundLeft + dp(3.33f), t + hole.padding.top,
|
||||
backgroundRight - dp(3.33f), b - hole.padding.bottom);
|
||||
backgroundLeft + (hole.padding.left + dp(7)) + dp(3.33f), t + hole.padding.top,
|
||||
backgroundRight - (hole.padding.right + dp(7)) - dp(3.33f), b - hole.padding.bottom);
|
||||
drawServiceBackground(canvas, AndroidUtilities.rectTmp, dp(18), 1f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2058,6 +2058,7 @@ public class ChatActivity extends BaseFragment implements
|
|||
@Override
|
||||
public void didPressStreamingStop() {
|
||||
BotForumHelper.getInstance(currentAccount).stopStreaming(dialog_id, (int) getTopicId());
|
||||
checkSendButtonBlockedByTyping(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -4577,11 +4578,18 @@ public class ChatActivity extends BaseFragment implements
|
|||
BlurredBackgroundProviderImpl.topPanelChatActivity(themeDelegate),
|
||||
ChatObject.isForum(currentChat));
|
||||
|
||||
if (chatMode == MODE_WELCOME_MESSAGES) {
|
||||
if (chatMode == MODE_PINNED) {
|
||||
actionBar.setChatAvatarContainer(avatarContainer);
|
||||
avatarContainer.setActionBar(actionBar);
|
||||
} else if (chatMode == MODE_WELCOME_MESSAGES) {
|
||||
actionBar.setChatAvatarContainer(avatarContainer);
|
||||
actionBar.setForcedMenuWidth(dp(46));
|
||||
actionBar.doNotDrawGlassMenu = true;
|
||||
avatarContainer.setActionBar(actionBar);
|
||||
} else if (isComments) {
|
||||
actionBar.setChatAvatarContainer(avatarContainer);
|
||||
actionBar.setForcedMenuMinWidth(dp(46));
|
||||
avatarContainer.setActionBar(actionBar);
|
||||
}
|
||||
|
||||
chatInputViewsContainer = new ChatInputViewsContainer(context);
|
||||
|
|
@ -7113,7 +7121,8 @@ public class ChatActivity extends BaseFragment implements
|
|||
jumpToDate((int) (calendar.getTime().getTime() / 1000));
|
||||
});
|
||||
|
||||
if (currentChat != null) {
|
||||
if (currentChat != null && chatMode != MODE_WELCOME_MESSAGES) {
|
||||
// todo: only for default mode ??
|
||||
pendingRequestsDelegate = new ChatActivityMemberRequestsDelegate(this, currentChat);
|
||||
topPanelLayout.addView(pendingRequestsDelegate.getView(), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 40));
|
||||
topPanelLayout.setPriority(pendingRequestsDelegate.getView(), 3);
|
||||
|
|
@ -25494,9 +25503,12 @@ public class ChatActivity extends BaseFragment implements
|
|||
if (!arr.isEmpty()) {
|
||||
if ((chatMode == MODE_SCHEDULED || chatMode == MODE_QUICK_REPLIES)) {
|
||||
replaceMessageObjects(arr, 0, true);
|
||||
} else if (UserObject.isBot(currentUser) && BotForumHelper.getInstance(currentAccount).hasBotForumDrafts(currentUser.id, (int) getTopicId())) {
|
||||
replaceMessageObjects(arr, 0, false);
|
||||
hasDraftsReplaces = !BotForumHelper.getInstance(currentAccount).hasBotForumDrafts(currentUser.id, (int) getTopicId());
|
||||
} else if (UserObject.isBot(currentUser)) {
|
||||
BotForumHelper.getInstance(currentAccount).removeAllMarkedAsRemovedMessages(currentUser.id, (int) getTopicId());
|
||||
if (BotForumHelper.getInstance(currentAccount).hasBotForumDrafts(currentUser.id, (int) getTopicId())) {
|
||||
replaceMessageObjects(arr, 0, false);
|
||||
hasDraftsReplaces = !BotForumHelper.getInstance(currentAccount).hasBotForumDrafts(currentUser.id, (int) getTopicId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -26083,6 +26095,20 @@ public class ChatActivity extends BaseFragment implements
|
|||
scrollToTopOnResume = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (chatMode == MODE_DEFAULT) {
|
||||
for (MessageObject messageObject : arr) {
|
||||
if (messageObject != null && !messageObject.isOut() && messageObject.messageOwner != null) {
|
||||
if (messageObject.messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup) {
|
||||
if (messageObject.messageOwner.reply_markup.force_reply) {
|
||||
showFieldPanelForReply(messageObject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chatMode == MODE_SCHEDULED && !arr.isEmpty()) {
|
||||
MessageObject messageObject = arr.get(0);
|
||||
int mid = messageObject.getId();
|
||||
|
|
|
|||
|
|
@ -250,7 +250,13 @@ public class ChatAvatarContainer extends FrameLayout implements FactorAnimator.T
|
|||
if (parentFragment == null || (parentFragment.getChatMode() != ChatActivity.MODE_QUICK_REPLIES && parentFragment.getChatMode() != ChatActivity.MODE_WELCOME_MESSAGES && parentFragment.getChatMode() != ChatActivity.MODE_EDIT_BUSINESS_LINK) && parentFragment.getChatMode() != ChatActivity.MODE_SUGGESTIONS && !parentFragment.isInBotForumMode()) {
|
||||
sharedMediaPreloader = new SharedMediaLayout.SharedMediaPreloader(baseFragment);
|
||||
}
|
||||
avatarImageIsHidden = parentFragment != null && (parentFragment.isThreadChat() || parentFragment.getChatMode() == ChatActivity.MODE_PINNED || parentFragment.getChatMode() == ChatActivity.MODE_QUICK_REPLIES || parentFragment.getChatMode() == ChatActivity.MODE_WELCOME_MESSAGES || parentFragment.getChatMode() == ChatActivity.MODE_EDIT_BUSINESS_LINK);
|
||||
avatarImageIsHidden = parentFragment != null && (
|
||||
parentFragment.isThreadChat() && !parentFragment.isReplyChatComment() ||
|
||||
parentFragment.getChatMode() == ChatActivity.MODE_PINNED ||
|
||||
parentFragment.getChatMode() == ChatActivity.MODE_QUICK_REPLIES ||
|
||||
parentFragment.getChatMode() == ChatActivity.MODE_WELCOME_MESSAGES ||
|
||||
parentFragment.getChatMode() == ChatActivity.MODE_EDIT_BUSINESS_LINK
|
||||
);
|
||||
if (avatarImageIsHidden) {
|
||||
avatarImageView.setVisibility(GONE);
|
||||
}
|
||||
|
|
@ -414,7 +420,7 @@ public class ChatAvatarContainer extends FrameLayout implements FactorAnimator.T
|
|||
protected void dispatchDraw(Canvas canvas) {
|
||||
canvas.save();
|
||||
final float s = bounce.getScale(.02f);
|
||||
canvas.scale(s, s, getWidth() / 2f, getHeight() - ActionBar.getCurrentActionBarHeight() / 2f);
|
||||
canvas.scale(s, s, getPivotX(), getHeight() - ActionBar.getCurrentActionBarHeight() / 2f);
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
|
@ -1719,7 +1725,7 @@ public class ChatAvatarContainer extends FrameLayout implements FactorAnimator.T
|
|||
width = Math.max(width, subtitleTextView.getExactWidthIncludeDrawables());
|
||||
}
|
||||
if (hasVisibleAvatar()) {
|
||||
width += dp(52 + 16);
|
||||
width += dp(52 + 18);
|
||||
} else {
|
||||
width += dp(34);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1716,7 +1716,10 @@ public class FilterTabsView extends FrameLayout {
|
|||
invalidated = true;
|
||||
requestLayout();
|
||||
allTabsWidth = 0;
|
||||
findDefaultTab().setTitle(LocaleController.getString(R.string.FilterAllChats), null, false);
|
||||
final FilterTabsView.Tab defaultTab = findDefaultTab();
|
||||
if (defaultTab != null) {
|
||||
defaultTab.setTitle(LocaleController.getString(R.string.FilterAllChats), null, false);
|
||||
}
|
||||
for (int b = 0; b < N; b++) {
|
||||
allTabsWidth += tabs.get(b).getWidth(true) + dp(TAB_PADDING_WIDTH);
|
||||
}
|
||||
|
|
@ -1745,9 +1748,14 @@ public class FilterTabsView extends FrameLayout {
|
|||
invalidated = true;
|
||||
requestLayout();
|
||||
listView.setItemAnimator(itemAnimator);
|
||||
adapter.notifyDataSetChanged();
|
||||
if (adapter != null) {
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
allTabsWidth = 0;
|
||||
findDefaultTab().setTitle(LocaleController.getString(R.string.FilterAllChats), null, false);
|
||||
final FilterTabsView.Tab defaultTab = findDefaultTab();
|
||||
if (defaultTab != null) {
|
||||
defaultTab.setTitle(LocaleController.getString(R.string.FilterAllChats), null, false);
|
||||
}
|
||||
for (int b = 0, N = tabs.size(); b < N; b++) {
|
||||
allTabsWidth += tabs.get(b).getWidth(true) + dp(TAB_PADDING_WIDTH);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.telegram.messenger.R;
|
|||
import org.telegram.messenger.Utilities;
|
||||
import org.telegram.messenger.browser.Browser;
|
||||
import org.telegram.tgnet.ConnectionsManager;
|
||||
import org.telegram.tgnet.TLMethod;
|
||||
import org.telegram.tgnet.TLObject;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.tgnet.tl.TL_ephemeral;
|
||||
|
|
@ -847,7 +848,7 @@ public class ReportBottomSheet extends BottomSheet {
|
|||
) {
|
||||
if (context == null || messageIds == null) return;
|
||||
final boolean[] done = new boolean[] { false };
|
||||
final TLObject request;
|
||||
final TLMethod<TLRPC.ReportResult> request;
|
||||
if (stories) {
|
||||
TL_stories.TL_stories_report req = new TL_stories.TL_stories_report();
|
||||
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId);
|
||||
|
|
@ -872,69 +873,65 @@ public class ReportBottomSheet extends BottomSheet {
|
|||
req.message = TextUtils.isEmpty(message) ? "" : message;
|
||||
request = req;
|
||||
}
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequest(request, (response, error) -> {
|
||||
if (response != null) {
|
||||
if (response instanceof TLRPC.TL_reportResultChooseOption || response instanceof TLRPC.TL_reportResultAddComment) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
final ReportBottomSheet sheet = new ReportBottomSheet(context, resourceProvider, stories, ephemeral, dialogId, messageIds);
|
||||
if (response instanceof TLRPC.TL_reportResultChooseOption) {
|
||||
sheet.setReportChooseOption((TLRPC.TL_reportResultChooseOption) response);
|
||||
} else if (response instanceof TLRPC.TL_reportResultAddComment) {
|
||||
sheet.setReportChooseOption((TLRPC.TL_reportResultAddComment) response);
|
||||
}
|
||||
sheet.setListener(new ReportBottomSheet.Listener() {
|
||||
@Override
|
||||
public void onReported() {
|
||||
if (!done[0] && whenDone != null) {
|
||||
done[0] = true;
|
||||
whenDone.run(true);
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (LaunchActivity.getSafeLastFragment() == null) return;
|
||||
final BulletinFactory bf = bulletinFactory == null ? BulletinFactory.of(LaunchActivity.getSafeLastFragment()) : bulletinFactory;
|
||||
if (bf == null) return;
|
||||
bf
|
||||
.createSimpleBulletin(
|
||||
R.raw.msg_antispam,
|
||||
LocaleController.getString(R.string.ReportChatSent),
|
||||
LocaleController.getString(R.string.Reported2)
|
||||
)
|
||||
.setDuration(Bulletin.DURATION_PROLONG)
|
||||
.show();
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
sheet.setOnDismissListener(() -> {
|
||||
if (!done[0] && whenDone != null) {
|
||||
done[0] = true;
|
||||
whenDone.run(false);
|
||||
}
|
||||
});
|
||||
sheet.show();
|
||||
});
|
||||
} else if (response instanceof TLRPC.TL_reportResultReported) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequestTyped(request, AndroidUtilities::runOnUIThread, (response, error) -> {
|
||||
if (response instanceof TLRPC.TL_reportResultChooseOption || response instanceof TLRPC.TL_reportResultAddComment) {
|
||||
final ReportBottomSheet sheet = new ReportBottomSheet(context, resourceProvider, stories, ephemeral, dialogId, messageIds);
|
||||
if (response instanceof TLRPC.TL_reportResultChooseOption) {
|
||||
sheet.setReportChooseOption((TLRPC.TL_reportResultChooseOption) response);
|
||||
} else if (response instanceof TLRPC.TL_reportResultAddComment) {
|
||||
sheet.setReportChooseOption((TLRPC.TL_reportResultAddComment) response);
|
||||
}
|
||||
sheet.setListener(new ReportBottomSheet.Listener() {
|
||||
@Override
|
||||
public void onReported() {
|
||||
if (!done[0] && whenDone != null) {
|
||||
done[0] = true;
|
||||
whenDone.run(true);
|
||||
}
|
||||
Runnable showToast = () -> {
|
||||
BaseFragment fragment = LaunchActivity.getSafeLastFragment();
|
||||
if (fragment == null) return;
|
||||
final BulletinFactory bf = BulletinFactory.of(fragment);
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (LaunchActivity.getSafeLastFragment() == null) return;
|
||||
final BulletinFactory bf = bulletinFactory == null ? BulletinFactory.of(LaunchActivity.getSafeLastFragment()) : bulletinFactory;
|
||||
if (bf == null) return;
|
||||
bf
|
||||
.createSimpleBulletin(
|
||||
R.raw.msg_antispam,
|
||||
LocaleController.getString(R.string.ReportChatSent),
|
||||
LocaleController.getString(R.string.Reported2)
|
||||
R.raw.msg_antispam,
|
||||
LocaleController.getString(R.string.ReportChatSent),
|
||||
LocaleController.getString(R.string.Reported2)
|
||||
)
|
||||
.setDuration(Bulletin.DURATION_PROLONG)
|
||||
.show();
|
||||
};
|
||||
AndroidUtilities.runOnUIThread(showToast, 220);
|
||||
}, 200);
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
sheet.setOnDismissListener(() -> {
|
||||
if (!done[0] && whenDone != null) {
|
||||
done[0] = true;
|
||||
whenDone.run(false);
|
||||
}
|
||||
});
|
||||
sheet.show();
|
||||
} else if (response instanceof TLRPC.TL_reportResultReported || true) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (!done[0] && whenDone != null) {
|
||||
done[0] = true;
|
||||
whenDone.run(true);
|
||||
}
|
||||
Runnable showToast = () -> {
|
||||
BaseFragment fragment = LaunchActivity.getSafeLastFragment();
|
||||
if (fragment == null) return;
|
||||
final BulletinFactory bf = BulletinFactory.of(fragment);
|
||||
if (bf == null) return;
|
||||
bf
|
||||
.createSimpleBulletin(
|
||||
R.raw.msg_antispam,
|
||||
LocaleController.getString(R.string.ReportChatSent),
|
||||
LocaleController.getString(R.string.Reported2)
|
||||
)
|
||||
.setDuration(Bulletin.DURATION_PROLONG)
|
||||
.show();
|
||||
};
|
||||
AndroidUtilities.runOnUIThread(showToast, 220);
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import org.telegram.messenger.Emoji;
|
|||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.utils.tlutils.TLKeyboardHelper;
|
||||
import org.telegram.messenger.utils.tlutils.TlUtils;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.tgnet.tl.TL_keyboard;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
|
|
@ -127,6 +128,10 @@ public class BotKeyboardView extends LinearLayout implements InAppKeyboardInsetV
|
|||
}
|
||||
|
||||
public void setButtons(TLRPC.TL_replyKeyboardMarkup buttons) {
|
||||
if (TlUtils.tlEquals(buttons, botButtons)) {
|
||||
return;
|
||||
}
|
||||
|
||||
botButtons = buttons;
|
||||
buttonViews.clear();
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 35
|
||||
buildToolsVersion '35.0.0'
|
||||
compileSdkVersion 36
|
||||
buildToolsVersion '36.0.0'
|
||||
|
||||
defaultConfig.applicationId = APP_PACKAGE
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 35
|
||||
targetSdkVersion 36
|
||||
versionName APP_VERSION_NAME
|
||||
ndkVersion "27.2.12479018"
|
||||
|
||||
|
|
@ -182,8 +182,9 @@ android {
|
|||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.10.2'
|
||||
version '3.22.1'
|
||||
arguments '-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-21' // , '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'
|
||||
targets 'tmessages.49'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 35
|
||||
buildToolsVersion '35.0.0'
|
||||
compileSdkVersion 36
|
||||
buildToolsVersion '36.0.0'
|
||||
|
||||
defaultConfig.applicationId = APP_PACKAGE
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 35
|
||||
targetSdkVersion 36
|
||||
versionName APP_VERSION_NAME
|
||||
ndkVersion "27.2.12479018"
|
||||
|
||||
|
|
@ -178,8 +178,9 @@ android {
|
|||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.10.2'
|
||||
version '3.22.1'
|
||||
arguments '-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-21' // , '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'
|
||||
targets 'tmessages.49'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 35
|
||||
buildToolsVersion '35.0.0'
|
||||
compileSdkVersion 36
|
||||
buildToolsVersion '36.0.0'
|
||||
|
||||
defaultConfig.applicationId = APP_PACKAGE
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 35
|
||||
targetSdkVersion 36
|
||||
versionName APP_VERSION_NAME
|
||||
ndkVersion "27.2.12479018"
|
||||
|
||||
|
|
@ -147,8 +147,9 @@ android {
|
|||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.10.2'
|
||||
version '3.22.1'
|
||||
arguments '-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-21' //, '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'
|
||||
targets 'tmessages.49'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 35
|
||||
buildToolsVersion '35.0.0'
|
||||
compileSdkVersion 36
|
||||
buildToolsVersion '36.0.0'
|
||||
|
||||
defaultConfig.applicationId = APP_PACKAGE
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 35
|
||||
targetSdkVersion 36
|
||||
versionName APP_VERSION_NAME
|
||||
ndkVersion "27.2.12479018"
|
||||
|
||||
|
|
@ -138,8 +138,9 @@ android {
|
|||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.10.2'
|
||||
version '3.22.1'
|
||||
arguments '-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-21' //, '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'
|
||||
targets 'tmessages.49'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 35
|
||||
buildToolsVersion '35.0.0'
|
||||
compileSdkVersion 36
|
||||
buildToolsVersion '36.0.0'
|
||||
|
||||
defaultConfig.applicationId = APP_PACKAGE
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 35
|
||||
targetSdkVersion 36
|
||||
versionName APP_VERSION_NAME
|
||||
ndkVersion "27.2.12479018"
|
||||
|
||||
|
|
@ -148,8 +148,9 @@ android {
|
|||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.10.2'
|
||||
version '3.22.1'
|
||||
arguments '-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-21' //, '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'
|
||||
targets 'tmessages.49'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
22
build.gradle
22
build.gradle
|
|
@ -6,13 +6,31 @@ buildscript {
|
|||
maven { url 'https://developer.huawei.com/repo/' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.6.1'
|
||||
classpath 'com.android.tools.build:gradle:8.10.1'
|
||||
classpath 'com.google.gms:google-services:4.3.15'
|
||||
classpath 'com.huawei.agconnect:agcp:1.9.1.301'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0"
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
}
|
||||
|
||||
// Strip JLatexMath fonts we don't ship (transitive AAR assets from
|
||||
// io.noties.markwon:ext-latex -> ru.noties:jlatexmath-android, ~764 KB total under
|
||||
// assets/org/scilab/forge/jlatexmath/fonts/). Has to live in the APK modules — a
|
||||
// library's androidResources.ignoreAssetsPattern doesn't filter packaging in apps
|
||||
// that consume it. Using subprojects keeps it in one place.
|
||||
// keep: base/, latin/, maths/, euler/ (\mathbb, \mathcal, \mathfrak still work)
|
||||
// drop: latin/optional/, maths/optional/ (~290 KB; \textbf/\textit/\mathds fall back)
|
||||
// licences/ (~20 KB; pure license text files)
|
||||
subprojects {
|
||||
plugins.withId('com.android.application') {
|
||||
android {
|
||||
androidResources {
|
||||
ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~:!optional:!licences:!*stmary*:!*eufb*'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ import org.gradle.api.tasks.TaskAction
|
|||
import org.telegram.tlrpc.SchemeAllLayersParser
|
||||
import org.telegram.tlrpc.SchemeCodeGen
|
||||
import org.telegram.tlrpc.SchemeTlValidator
|
||||
import org.telegram.tlrpc.models.RULES
|
||||
import org.telegram.tlrpc.models.RulesHolder
|
||||
import org.telegram.tlrpc.models.TlObjectWithLayer
|
||||
import org.telegram.tlrpc.schema.TlSchemaJsonParser
|
||||
import org.telegram.tlrpc.telegram.TelegramCodeParser
|
||||
|
|
@ -64,7 +64,7 @@ abstract class GenerateSchemeTask : DefaultTask() {
|
|||
|
||||
val telegramClasses = TelegramCodeParser.parse(files)
|
||||
val tlSchemaFull = TlSchemaJsonParser.parse(resourcesDir, LAYER)
|
||||
val tlSchemaFilter = tlSchemaFull.applyRules(RULES.rules)
|
||||
val tlSchemaFilter = tlSchemaFull.applyRules(RulesHolder.rules)
|
||||
|
||||
val undefinedTelegramClasses = telegramClasses.groupedByConstructorAll.filterKeys {
|
||||
it !in tlSchemaFull.magicsAll
|
||||
|
|
@ -77,7 +77,7 @@ abstract class GenerateSchemeTask : DefaultTask() {
|
|||
val classesByUniqueIds = telegramClasses.groupedByConstructorUnique
|
||||
val schema = SchemeAllLayersParser.parseAllLayers(resourcesDir)
|
||||
|
||||
val dep = RULES.rules.databaseTypes
|
||||
val dep = RulesHolder.rules.databaseTypes
|
||||
val legacyConstrKeys = schema.schemes.map { s ->
|
||||
val types = dep
|
||||
.mapNotNull { s.dependenciesTransitive[it] }
|
||||
|
|
@ -181,7 +181,7 @@ abstract class GenerateSchemeTask : DefaultTask() {
|
|||
) {
|
||||
needSuper = false
|
||||
}
|
||||
if (!RULES.rules.filterConstructor(constructor.tl.key.name)) continue
|
||||
if (!RulesHolder.rules.filterConstructor(constructor.tl.key.name)) continue
|
||||
|
||||
sealedClassBuilder.addType(
|
||||
SchemeCodeGen.generateDataClass(
|
||||
|
|
@ -230,7 +230,7 @@ abstract class GenerateSchemeTask : DefaultTask() {
|
|||
var testIndex = 0;
|
||||
|
||||
for (constructor in constructorsSorted) {
|
||||
if (!RULES.rules.filterConstructor(constructor.tl.key.name)) continue
|
||||
if (!RulesHolder.rules.filterConstructor(constructor.tl.key.name)) continue
|
||||
|
||||
val isEncrypted = constructor in encrypted
|
||||
val isLegacy = constructor.layerLast < LAYER
|
||||
|
|
|
|||
|
|
@ -1,91 +1,5 @@
|
|||
package org.telegram.tlrpc.models
|
||||
|
||||
object RULES {
|
||||
val rules = Rules(
|
||||
databaseTypes = setOf(
|
||||
"Message", "StoryItem", "Theme",
|
||||
"Chat", "User",
|
||||
"UserFull", "ChatFull",
|
||||
"StarsTransaction", "StarGift",
|
||||
"SavedStarGift", "InputStorePaymentPurpose", //, "ChatTheme"
|
||||
"ForumTopic", "EphemeralMessage"
|
||||
),
|
||||
ignoredTypes = setOf(
|
||||
"True",
|
||||
"Vector t",
|
||||
"smsjobs.Status",
|
||||
"smsjobs.EligibilityToJoin",
|
||||
"SmsJob",
|
||||
|
||||
"InputMessage",
|
||||
"BotBusinessConnection",
|
||||
"BotCommandScope",
|
||||
"CdnConfig",
|
||||
"CdnPublicKey",
|
||||
"InputBotInlineMessage",
|
||||
"InputBotInlineResult",
|
||||
"InputBusinessAwayMessage",
|
||||
"InputBusinessGreetingMessage",
|
||||
"RequestedPeer",
|
||||
"SavedContact",
|
||||
"messages.BotPreparedInlineMessage",
|
||||
"bots.BotInfo",
|
||||
"AutoSaveException",
|
||||
"AutoSaveSettings",
|
||||
"account.AutoSaveSettings",
|
||||
"account.Takeout",
|
||||
"InputClientProxy",
|
||||
"InputStarsTransaction",
|
||||
"InputStickerSetItem",
|
||||
"bots.AccessSettings"
|
||||
),
|
||||
ignoredConstructors = mapOf(
|
||||
"Update" to setOf(
|
||||
"updateAutoSaveSettings",
|
||||
"updateBotBusinessConnect",
|
||||
"updateBotCallbackQuery",
|
||||
"updateBotChatBoost",
|
||||
"updateBotChatInviteRequester",
|
||||
"updateBotDeleteBusinessMessage",
|
||||
"updateBotEditBusinessMessage",
|
||||
"updateBotInlineQuery",
|
||||
"updateBotInlineSend",
|
||||
"updateBotMessageReaction",
|
||||
"updateBotMessageReactions",
|
||||
"updateBotNewBusinessMessage",
|
||||
"updateBotPrecheckoutQuery",
|
||||
"updateBotShippingQuery",
|
||||
"updateBotStopped",
|
||||
"updateBotWebhookJSON",
|
||||
"updateBotWebhookJSONQuery",
|
||||
"updateBusinessBotCallbackQuery",
|
||||
"updateChatParticipant",
|
||||
"updateInlineBotCallbackQuery",
|
||||
"updatePtsChanged",
|
||||
"updateSmsJob",
|
||||
"updateBotGuestChatQuery",
|
||||
"updateBotStarsSubscription"
|
||||
),
|
||||
"MessageAction" to setOf(
|
||||
"messageActionRequestedPeerSentMe",
|
||||
"messageActionSecureValuesSentMe"
|
||||
),
|
||||
"InputFileLocation" to setOf(
|
||||
"inputTakeoutFileLocation",
|
||||
"inputPhotoLegacyFileLocation"
|
||||
),
|
||||
"InputPaymentCredentials" to setOf("inputPaymentCredentialsApplePay"),
|
||||
"InputStickerSet" to setOf("inputStickerSetAnimatedEmojiAnimations"),
|
||||
"InputWebFileLocation" to setOf("inputWebFileAudioAlbumThumbLocation"),
|
||||
"InputInvoice" to setOf("inputInvoiceBusinessBotTransferStars"),
|
||||
"InputBotInlineMessageID" to setOf("inputBotInlineMessageID64"),
|
||||
"InputPasskeyCredential" to setOf("inputPasskeyCredentialFirebasePNV"),
|
||||
"InputRichMessage" to setOf("inputRichMessageHTML", "inputRichMessageMarkdown"),
|
||||
"SendMessageAction" to setOf("inputSendMessageRichMessageDraftAction")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
data class Rules(
|
||||
val databaseTypes: Set<String>,
|
||||
val ignoredTypes: Set<String>,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
package org.telegram.tlrpc.models
|
||||
|
||||
object RulesHolder {
|
||||
val rules = Rules(
|
||||
databaseTypes = setOf(
|
||||
"Message", "StoryItem", "Theme",
|
||||
"Chat", "User",
|
||||
"UserFull", "ChatFull",
|
||||
"StarsTransaction", "StarGift",
|
||||
"SavedStarGift", "InputStorePaymentPurpose", //, "ChatTheme"
|
||||
"ForumTopic", "EphemeralMessage"
|
||||
),
|
||||
ignoredTypes = setOf(
|
||||
"True",
|
||||
"Vector t",
|
||||
"smsjobs.Status",
|
||||
"smsjobs.EligibilityToJoin",
|
||||
"SmsJob",
|
||||
|
||||
"InputMessage",
|
||||
"BotBusinessConnection",
|
||||
"BotCommandScope",
|
||||
"CdnConfig",
|
||||
"CdnPublicKey",
|
||||
"InputBotInlineMessage",
|
||||
"InputBotInlineResult",
|
||||
"InputBusinessAwayMessage",
|
||||
"InputBusinessGreetingMessage",
|
||||
"RequestedPeer",
|
||||
"SavedContact",
|
||||
"messages.BotPreparedInlineMessage",
|
||||
"bots.BotInfo",
|
||||
"AutoSaveException",
|
||||
"AutoSaveSettings",
|
||||
"account.AutoSaveSettings",
|
||||
"account.Takeout",
|
||||
"InputClientProxy",
|
||||
"InputStarsTransaction",
|
||||
"InputStickerSetItem",
|
||||
"bots.AccessSettings"
|
||||
),
|
||||
ignoredConstructors = mapOf(
|
||||
"Update" to setOf(
|
||||
"updateAutoSaveSettings",
|
||||
"updateBotBusinessConnect",
|
||||
"updateBotCallbackQuery",
|
||||
"updateBotChatBoost",
|
||||
"updateBotChatInviteRequester",
|
||||
"updateBotDeleteBusinessMessage",
|
||||
"updateBotEditBusinessMessage",
|
||||
"updateBotInlineQuery",
|
||||
"updateBotInlineSend",
|
||||
"updateBotMessageReaction",
|
||||
"updateBotMessageReactions",
|
||||
"updateBotNewBusinessMessage",
|
||||
"updateBotPrecheckoutQuery",
|
||||
"updateBotShippingQuery",
|
||||
"updateBotStopped",
|
||||
"updateBotWebhookJSON",
|
||||
"updateBotWebhookJSONQuery",
|
||||
"updateBusinessBotCallbackQuery",
|
||||
"updateChatParticipant",
|
||||
"updateInlineBotCallbackQuery",
|
||||
"updatePtsChanged",
|
||||
"updateSmsJob",
|
||||
"updateBotGuestChatQuery",
|
||||
"updateBotStarsSubscription"
|
||||
),
|
||||
"MessageAction" to setOf(
|
||||
"messageActionRequestedPeerSentMe",
|
||||
"messageActionSecureValuesSentMe"
|
||||
),
|
||||
"InputFileLocation" to setOf(
|
||||
"inputTakeoutFileLocation",
|
||||
"inputPhotoLegacyFileLocation"
|
||||
),
|
||||
"InputPaymentCredentials" to setOf("inputPaymentCredentialsApplePay"),
|
||||
"InputStickerSet" to setOf("inputStickerSetAnimatedEmojiAnimations"),
|
||||
"InputWebFileLocation" to setOf("inputWebFileAudioAlbumThumbLocation"),
|
||||
"InputInvoice" to setOf("inputInvoiceBusinessBotTransferStars"),
|
||||
"InputBotInlineMessageID" to setOf("inputBotInlineMessageID64"),
|
||||
"InputPasskeyCredential" to setOf("inputPasskeyCredentialFirebasePNV"),
|
||||
"InputRichMessage" to setOf("inputRichMessageHTML", "inputRichMessageMarkdown"),
|
||||
"SendMessageAction" to setOf("inputSendMessageRichMessageDraftAction")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -13,14 +13,14 @@
|
|||
# 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_CODE=7031
|
||||
APP_VERSION_NAME=12.10.0
|
||||
APP_VERSION_CODE=7038
|
||||
APP_VERSION_NAME=12.10.1
|
||||
APP_PACKAGE=org.telegram.messenger
|
||||
IS_PRIVATE=false
|
||||
RELEASE_KEY_PASSWORD=android
|
||||
RELEASE_KEY_ALIAS=androidkey
|
||||
RELEASE_STORE_PASSWORD=android
|
||||
org.gradle.jvmargs=-Xmx4096M
|
||||
org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=1g
|
||||
org.gradle.daemon=true
|
||||
org.gradle.parallel=true
|
||||
org.gradle.configureondemand=false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue