Работающие звонки
This commit is contained in:
@@ -9,7 +9,8 @@ Stock `io.github.webrtc-sdk:android:125.6422.07` can call audio frame encryptor
|
||||
`additional_data` (`ad=0`), so nonce derivation based on timestamp is unavailable.
|
||||
|
||||
Desktop uses frame timestamp for nonce. This patch aligns Android with that approach by passing
|
||||
an 8-byte big-endian timestamp payload in `additional_data`:
|
||||
an 8-byte big-endian timestamp payload in `additional_data` (absolute RTP timestamp,
|
||||
including sender start offset):
|
||||
|
||||
- bytes `0..3` = `0`
|
||||
- bytes `4..7` = RTP timestamp (big-endian)
|
||||
@@ -18,10 +19,14 @@ an 8-byte big-endian timestamp payload in `additional_data`:
|
||||
|
||||
- `build_custom_webrtc.sh` — reproducible build script
|
||||
- `patches/0001-audio-e2ee-pass-rtp-timestamp-as-additional-data.patch` — WebRTC patch
|
||||
- `patches/0002-android-build-on-mac-host.patch` — allows Android target build on macOS host
|
||||
- `patches/0003-macos-host-java-ijar.patch` — enables host tools (`ijar`/`jdk`) on macOS
|
||||
- `patches/0004-macos-linker-missing-L-dirs.patch` — skips invalid host `-L...` paths for lld
|
||||
- `patches/0005-macos-server-utils-socket.patch` — handles macOS socket errno in Android Java compile helper
|
||||
|
||||
## Build
|
||||
|
||||
Recommended on Linux (macOS can work but is less predictable for long WebRTC builds).
|
||||
Recommended on Linux (macOS is supported via additional patches in this folder).
|
||||
|
||||
Bootstrap `depot_tools` first:
|
||||
|
||||
@@ -47,6 +52,7 @@ Optional env vars:
|
||||
- `SYNC_JOBS` — `gclient sync` jobs (default: `1`, safer for googlesource limits)
|
||||
- `SYNC_RETRIES` — sync retry attempts (default: `8`)
|
||||
- `SYNC_RETRY_BASE_SEC` — base retry delay in seconds (default: `20`)
|
||||
- `MAC_ANDROID_NDK_ROOT` — local Android NDK path on macOS (default: `~/Library/Android/sdk/ndk/27.1.12297006`)
|
||||
|
||||
## Troubleshooting (HTTP 429 / RESOURCE_EXHAUSTED)
|
||||
|
||||
|
||||
@@ -9,7 +9,13 @@ set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROSETTA_ANDROID_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
||||
PATCH_FILE="${SCRIPT_DIR}/patches/0001-audio-e2ee-pass-rtp-timestamp-as-additional-data.patch"
|
||||
PATCH_FILES=(
|
||||
"${SCRIPT_DIR}/patches/0001-audio-e2ee-pass-rtp-timestamp-as-additional-data.patch"
|
||||
"${SCRIPT_DIR}/patches/0002-android-build-on-mac-host.patch"
|
||||
"${SCRIPT_DIR}/patches/0003-macos-host-java-ijar.patch"
|
||||
"${SCRIPT_DIR}/patches/0004-macos-linker-missing-L-dirs.patch"
|
||||
"${SCRIPT_DIR}/patches/0005-macos-server-utils-socket.patch"
|
||||
)
|
||||
|
||||
# Default target: WebRTC M125 family used by app dependency 125.6422.07.
|
||||
WEBRTC_BRANCH="${WEBRTC_BRANCH:-branch-heads/6422}"
|
||||
@@ -132,21 +138,63 @@ sync_with_retry
|
||||
|
||||
echo "[webrtc-custom] applying Rosetta patch..."
|
||||
git reset --hard
|
||||
git apply --check "${PATCH_FILE}"
|
||||
git apply "${PATCH_FILE}"
|
||||
for patch in "${PATCH_FILES[@]}"; do
|
||||
echo "[webrtc-custom] apply $(basename "${patch}")"
|
||||
git apply --check "${patch}"
|
||||
git apply "${patch}"
|
||||
done
|
||||
|
||||
# macOS host tweaks:
|
||||
# - point third_party/jdk/current to local JDK
|
||||
# - use locally installed Android NDK (darwin toolchain)
|
||||
if [[ "$(uname -s)" == "Darwin" ]]; then
|
||||
if [[ -z "${JAVA_HOME:-}" ]]; then
|
||||
JAVA_HOME="$(/usr/libexec/java_home 2>/dev/null || true)"
|
||||
fi
|
||||
if [[ -z "${JAVA_HOME:-}" || ! -d "${JAVA_HOME}" ]]; then
|
||||
echo "[webrtc-custom] ERROR: JAVA_HOME not found on macOS"
|
||||
exit 1
|
||||
fi
|
||||
JAVA_HOME_CANDIDATE="${JAVA_HOME}"
|
||||
if [[ ! -f "${JAVA_HOME_CANDIDATE}/conf/logging.properties" ]] && [[ -d "${JAVA_HOME_CANDIDATE}/libexec/openjdk.jdk/Contents/Home" ]]; then
|
||||
JAVA_HOME_CANDIDATE="${JAVA_HOME_CANDIDATE}/libexec/openjdk.jdk/Contents/Home"
|
||||
fi
|
||||
if [[ ! -f "${JAVA_HOME_CANDIDATE}/conf/logging.properties" ]]; then
|
||||
echo "[webrtc-custom] ERROR: invalid JAVA_HOME (conf/logging.properties not found): ${JAVA_HOME}"
|
||||
exit 1
|
||||
fi
|
||||
JAVA_HOME="${JAVA_HOME_CANDIDATE}"
|
||||
ln -sfn "${JAVA_HOME}" "${WEBRTC_SRC}/third_party/jdk/current"
|
||||
echo "[webrtc-custom] macOS JDK linked: ${WEBRTC_SRC}/third_party/jdk/current -> ${JAVA_HOME}"
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "${OUT_AAR}")"
|
||||
|
||||
echo "[webrtc-custom] building AAR (this can take a while)..."
|
||||
GN_ARGS=(
|
||||
is_debug=false
|
||||
is_component_build=false
|
||||
rtc_include_tests=false
|
||||
rtc_build_examples=false
|
||||
)
|
||||
|
||||
if [[ "$(uname -s)" == "Darwin" ]]; then
|
||||
MAC_ANDROID_NDK_ROOT="${MAC_ANDROID_NDK_ROOT:-$HOME/Library/Android/sdk/ndk/27.1.12297006}"
|
||||
if [[ ! -d "${MAC_ANDROID_NDK_ROOT}" ]]; then
|
||||
echo "[webrtc-custom] ERROR: Android NDK not found at ${MAC_ANDROID_NDK_ROOT}"
|
||||
echo "[webrtc-custom] Set MAC_ANDROID_NDK_ROOT to your local NDK path."
|
||||
exit 1
|
||||
fi
|
||||
GN_ARGS+=("android_ndk_root=\"${MAC_ANDROID_NDK_ROOT}\"")
|
||||
GN_ARGS+=("android_ndk_version=\"27.1.12297006\"")
|
||||
echo "[webrtc-custom] macOS Android NDK: ${MAC_ANDROID_NDK_ROOT}"
|
||||
fi
|
||||
|
||||
python3 tools_webrtc/android/build_aar.py \
|
||||
--build-dir out_rosetta_aar \
|
||||
--output "${OUT_AAR}" \
|
||||
--arch "${ARCHS[@]}" \
|
||||
--extra-gn-args \
|
||||
is_debug=false \
|
||||
is_component_build=false \
|
||||
rtc_include_tests=false \
|
||||
rtc_build_examples=false
|
||||
--extra-gn-args "${GN_ARGS[@]}"
|
||||
|
||||
echo "[webrtc-custom] done"
|
||||
echo "[webrtc-custom] AAR: ${OUT_AAR}"
|
||||
|
||||
@@ -25,22 +25,24 @@ index 17cf859ed8..b9d9ab14c8 100644
|
||||
decrypted_audio_payload);
|
||||
|
||||
diff --git a/audio/channel_send.cc b/audio/channel_send.cc
|
||||
index 4a2700177b..93283c2e78 100644
|
||||
index 4a2700177b..7ebb501704 100644
|
||||
--- a/audio/channel_send.cc
|
||||
+++ b/audio/channel_send.cc
|
||||
@@ -320,10 +320,21 @@ int32_t ChannelSend::SendRtpAudio(AudioFrameType frameType,
|
||||
@@ -320,10 +320,23 @@ int32_t ChannelSend::SendRtpAudio(AudioFrameType frameType,
|
||||
|
||||
// Encrypt the audio payload into the buffer.
|
||||
size_t bytes_written = 0;
|
||||
+ const uint32_t additional_data_timestamp =
|
||||
+ rtp_timestamp_without_offset + rtp_rtcp_->StartTimestamp();
|
||||
+ const uint8_t additional_data_bytes[8] = {
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ 0,
|
||||
+ static_cast<uint8_t>((rtp_timestamp_without_offset >> 24) & 0xff),
|
||||
+ static_cast<uint8_t>((rtp_timestamp_without_offset >> 16) & 0xff),
|
||||
+ static_cast<uint8_t>((rtp_timestamp_without_offset >> 8) & 0xff),
|
||||
+ static_cast<uint8_t>(rtp_timestamp_without_offset & 0xff),
|
||||
+ static_cast<uint8_t>((additional_data_timestamp >> 24) & 0xff),
|
||||
+ static_cast<uint8_t>((additional_data_timestamp >> 16) & 0xff),
|
||||
+ static_cast<uint8_t>((additional_data_timestamp >> 8) & 0xff),
|
||||
+ static_cast<uint8_t>(additional_data_timestamp & 0xff),
|
||||
+ };
|
||||
+
|
||||
int encrypt_status = frame_encryptor_->Encrypt(
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
|
||||
index 26fad5adf..7a614f334 100644
|
||||
--- a/build/config/BUILDCONFIG.gn
|
||||
+++ b/build/config/BUILDCONFIG.gn
|
||||
@@ -239,7 +239,8 @@ if (host_toolchain == "") {
|
||||
_default_toolchain = ""
|
||||
|
||||
if (target_os == "android") {
|
||||
- assert(host_os == "linux", "Android builds are only supported on Linux.")
|
||||
+ assert(host_os == "linux" || host_os == "mac",
|
||||
+ "Android builds are only supported on Linux/macOS.")
|
||||
_default_toolchain = "//build/toolchain/android:android_clang_$target_cpu"
|
||||
} else if (target_os == "chromeos" || target_os == "linux") {
|
||||
# See comments in build/toolchain/cros/BUILD.gn about board compiles.
|
||||
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
|
||||
index 427739d70..6a5ab0594 100644
|
||||
--- a/build/config/android/config.gni
|
||||
+++ b/build/config/android/config.gni
|
||||
@@ -327,7 +327,7 @@ if (is_android || is_chromeos) {
|
||||
|
||||
# Defines the name the Android build gives to the current host CPU
|
||||
# architecture, which is different than the names GN uses.
|
||||
- if (host_cpu == "x64") {
|
||||
+ if (host_cpu == "x64" || host_cpu == "arm64") {
|
||||
android_host_arch = "x86_64"
|
||||
} else if (host_cpu == "x86") {
|
||||
android_host_arch = "x86"
|
||||
34
tools/webrtc-custom/patches/0003-macos-host-java-ijar.patch
Normal file
34
tools/webrtc-custom/patches/0003-macos-host-java-ijar.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
diff --git a/third_party/ijar/BUILD.gn b/third_party/ijar/BUILD.gn
|
||||
index 8dc9fe21cf8..49c50e6636f 100644
|
||||
--- a/third_party/ijar/BUILD.gn
|
||||
+++ b/third_party/ijar/BUILD.gn
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
# A tool that removes all non-interface-specific parts from a .jar file.
|
||||
|
||||
-if (is_linux || is_chromeos) {
|
||||
+if (is_linux || is_chromeos || is_mac) {
|
||||
config("ijar_compiler_flags") {
|
||||
if (is_clang) {
|
||||
cflags = [
|
||||
diff --git a/third_party/jdk/BUILD.gn b/third_party/jdk/BUILD.gn
|
||||
index e003eef94d7..ec49922942b 100644
|
||||
--- a/third_party/jdk/BUILD.gn
|
||||
+++ b/third_party/jdk/BUILD.gn
|
||||
@@ -3,10 +3,12 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
config("jdk") {
|
||||
- include_dirs = [
|
||||
- "current/include",
|
||||
- "current/include/linux",
|
||||
- ]
|
||||
+ include_dirs = [ "current/include" ]
|
||||
+ if (host_os == "mac") {
|
||||
+ include_dirs += [ "current/include/darwin" ]
|
||||
+ } else {
|
||||
+ include_dirs += [ "current/include/linux" ]
|
||||
+ }
|
||||
}
|
||||
|
||||
group("java_data") {
|
||||
@@ -0,0 +1,102 @@
|
||||
diff --git a/build/toolchain/apple/linker_driver.py b/build/toolchain/apple/linker_driver.py
|
||||
index 0632230cf..798442534 100755
|
||||
--- a/build/toolchain/apple/linker_driver.py
|
||||
+++ b/build/toolchain/apple/linker_driver.py
|
||||
@@ -7,6 +7,7 @@
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
+import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -113,6 +114,53 @@ class LinkerDriver(object):
|
||||
# The temporary directory for intermediate LTO object files. If it
|
||||
# exists, it will clean itself up on script exit.
|
||||
self._object_path_lto = None
|
||||
+ self._temp_rsp_files = []
|
||||
+
|
||||
+ def _sanitize_rsp_arg(self, arg):
|
||||
+ if not arg.startswith('@'):
|
||||
+ return arg
|
||||
+ rsp_path = arg[1:]
|
||||
+ if not os.path.isfile(rsp_path):
|
||||
+ return arg
|
||||
+
|
||||
+ try:
|
||||
+ with open(rsp_path, 'r', encoding='utf-8') as f:
|
||||
+ rsp_content = f.read()
|
||||
+ except OSError:
|
||||
+ return arg
|
||||
+
|
||||
+ tokens = shlex.split(rsp_content, posix=True)
|
||||
+ sanitized = []
|
||||
+ changed = False
|
||||
+ i = 0
|
||||
+ while i < len(tokens):
|
||||
+ tok = tokens[i]
|
||||
+ if tok == '-L' and i + 1 < len(tokens):
|
||||
+ lib_dir = tokens[i + 1]
|
||||
+ if not os.path.isdir(lib_dir):
|
||||
+ changed = True
|
||||
+ i += 2
|
||||
+ continue
|
||||
+ elif tok.startswith('-L') and len(tok) > 2:
|
||||
+ lib_dir = tok[2:]
|
||||
+ if not os.path.isdir(lib_dir):
|
||||
+ changed = True
|
||||
+ i += 1
|
||||
+ continue
|
||||
+ sanitized.append(tok)
|
||||
+ i += 1
|
||||
+
|
||||
+ if not changed:
|
||||
+ return arg
|
||||
+
|
||||
+ fd, temp_path = tempfile.mkstemp(prefix='linker_driver_', suffix='.rsp')
|
||||
+ os.close(fd)
|
||||
+ with open(temp_path, 'w', encoding='utf-8') as f:
|
||||
+ for tok in sanitized:
|
||||
+ f.write(tok)
|
||||
+ f.write('\n')
|
||||
+ self._temp_rsp_files.append(temp_path)
|
||||
+ return '@' + temp_path
|
||||
|
||||
def run(self):
|
||||
"""Runs the linker driver, separating out the main compiler driver's
|
||||
@@ -135,11 +183,25 @@ class LinkerDriver(object):
|
||||
assert driver_action[0] not in linker_driver_actions
|
||||
linker_driver_actions[driver_action[0]] = driver_action[1]
|
||||
else:
|
||||
+ if arg.startswith('@'):
|
||||
+ arg = self._sanitize_rsp_arg(arg)
|
||||
# TODO(crbug.com/1446796): On Apple, the linker command line
|
||||
# produced by rustc for LTO includes these arguments, but the
|
||||
# Apple linker doesn't accept them.
|
||||
# Upstream bug: https://github.com/rust-lang/rust/issues/60059
|
||||
BAD_RUSTC_ARGS = '-Wl,-plugin-opt=O[0-9],-plugin-opt=mcpu=.*'
|
||||
+ if arg == '-Wl,-fatal_warnings':
|
||||
+ # Some host link steps on Apple Silicon produce benign
|
||||
+ # warnings from injected search paths (e.g. /usr/local/lib
|
||||
+ # missing). Don't fail the whole build on those warnings.
|
||||
+ continue
|
||||
+ if arg.startswith('-L') and len(arg) > 2:
|
||||
+ # Some environments inject non-existent library search
|
||||
+ # paths (e.g. /usr/local/lib on Apple Silicon). lld treats
|
||||
+ # them as hard errors, so skip missing -L entries.
|
||||
+ lib_dir = arg[2:]
|
||||
+ if not os.path.isdir(lib_dir):
|
||||
+ continue
|
||||
if not re.match(BAD_RUSTC_ARGS, arg):
|
||||
compiler_driver_args.append(arg)
|
||||
|
||||
@@ -185,6 +247,9 @@ class LinkerDriver(object):
|
||||
|
||||
# Re-report the original failure.
|
||||
raise
|
||||
+ finally:
|
||||
+ for path in self._temp_rsp_files:
|
||||
+ _remove_path(path)
|
||||
|
||||
def _get_linker_output(self):
|
||||
"""Returns the value of the output argument to the linker."""
|
||||
@@ -0,0 +1,15 @@
|
||||
diff --git a/build/android/gyp/util/server_utils.py b/build/android/gyp/util/server_utils.py
|
||||
index 6d5ed79d3..c05b57529 100644
|
||||
--- a/build/android/gyp/util/server_utils.py
|
||||
+++ b/build/android/gyp/util/server_utils.py
|
||||
@@ -36,7 +36,9 @@ def MaybeRunCommand(name, argv, stamp_file, force):
|
||||
except socket.error as e:
|
||||
# [Errno 111] Connection refused. Either the server has not been started
|
||||
# or the server is not currently accepting new connections.
|
||||
- if e.errno == 111:
|
||||
+ # [Errno 2] Abstract Unix sockets are unsupported on macOS, so treat
|
||||
+ # this the same way (build server unavailable).
|
||||
+ if e.errno in (111, 2):
|
||||
if force:
|
||||
raise RuntimeError(
|
||||
'\n\nBuild server is not running and '
|
||||
Reference in New Issue
Block a user