Merge changes If43cb264,I5d08f3d1 into main

* changes:
  introduce $PACKAGE_NAME in vm_config
  build ttyd with client cert patch
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
index e278165..0b130f5 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
@@ -72,6 +72,7 @@
 import java.security.PrivateKey;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
+import java.util.Enumeration;
 
 public class MainActivity extends BaseActivity
         implements VmLauncherServices.VmLauncherServiceCallback,
@@ -116,8 +117,8 @@
         mAccessibilityManager = getSystemService(AccessibilityManager.class);
         mAccessibilityManager.addTouchExplorationStateChangeListener(this);
 
-        connectToTerminalService();
         readClientCertificate();
+        connectToTerminalService();
 
         manageExternalStorageActivityResultLauncher =
                 registerForActivityResult(
@@ -184,15 +185,19 @@
                 getClass().getResourceAsStream("/assets/client.p12")) {
             KeyStore keyStore = KeyStore.getInstance("PKCS12");
             String password = "1234";
-            String alias = "1";
 
             keyStore.load(keystoreFileStream, password != null ? password.toCharArray() : null);
-            Key key = keyStore.getKey(alias, password.toCharArray());
-            if (key instanceof PrivateKey) {
-                mPrivateKey = (PrivateKey) key;
-                Certificate cert = keyStore.getCertificate(alias);
-                mCertificates = new X509Certificate[1];
-                mCertificates[0] = (X509Certificate) cert;
+            Enumeration<String> enumeration = keyStore.aliases();
+            while (enumeration.hasMoreElements()) {
+                String alias = enumeration.nextElement();
+                Key key = keyStore.getKey(alias, password.toCharArray());
+                if (key instanceof PrivateKey) {
+                    mPrivateKey = (PrivateKey) key;
+                    Certificate cert = keyStore.getCertificate(alias);
+                    mCertificates = new X509Certificate[1];
+                    mCertificates[0] = (X509Certificate) cert;
+                    return;
+                }
             }
         } catch (Exception e) {
             Log.e(TAG, e.getMessage());
diff --git a/build/debian/build.sh b/build/debian/build.sh
index b4e8b2f..5829ecc 100755
--- a/build/debian/build.sh
+++ b/build/debian/build.sh
@@ -50,15 +50,21 @@
 install_prerequisites() {
 	apt update
 	packages=(
+		automake
 		binfmt-support
 		build-essential
 		ca-certificates
+		cmake
 		curl
 		debsums
 		dosfstools
 		fai-server
 		fai-setup-storage
 		fdisk
+		git
+		libjson-c-dev
+		libtool
+		libwebsockets-dev
 		make
 		protobuf-compiler
 		python3
@@ -121,6 +127,23 @@
 	popd > /dev/null
 }
 
+build_ttyd() {
+	local ttyd_version=1.7.7
+	local url="https://github.com/tsl0922/ttyd/archive/refs/tags/${ttyd_version}.tar.gz"
+	cp -r $(dirname $0)/ttyd ${workdir}/ttyd
+
+	pushd "${workdir}" > /dev/null
+	wget "${url}" -O - | tar xz
+	cp ttyd/* ttyd-${ttyd_version}/scripts
+	pushd "$workdir/ttyd-${ttyd_version}" > /dev/null
+	bash -c "env BUILD_TARGET=${arch} ./scripts/cross-build.sh"
+	mkdir -p "${dst}/files/usr/local/bin/ttyd"
+	cp /tmp/stage/${arch}-linux-musl/bin/ttyd "${dst}/files/usr/local/bin/ttyd/AVF"
+	chmod 777 "${dst}/files/usr/local/bin/ttyd/AVF"
+	popd > /dev/null
+	popd > /dev/null
+}
+
 copy_android_config() {
 	local src="$(dirname "$0")/fai_config"
 	local dst="${config_space}"
@@ -128,12 +151,7 @@
 	cp -R "${src}"/* "${dst}"
 	cp "$(dirname "$0")/image.yaml" "${resources_dir}"
 
-	local ttyd_version=1.7.7
-	local url="https://github.com/tsl0922/ttyd/releases/download/${ttyd_version}/ttyd.${arch}"
-	mkdir -p "${dst}/files/usr/local/bin/ttyd"
-	wget "${url}" -O "${dst}/files/usr/local/bin/ttyd/AVF"
-	chmod 777 "${dst}/files/usr/local/bin/ttyd/AVF"
-
+	build_ttyd
 	build_rust_binary_and_copy forwarder_guest
 	build_rust_binary_and_copy forwarder_guest_launcher
 	build_rust_binary_and_copy ip_addr_reporter
diff --git a/build/debian/ttyd/client_cert.patch b/build/debian/ttyd/client_cert.patch
new file mode 100644
index 0000000..93b8aed
--- /dev/null
+++ b/build/debian/ttyd/client_cert.patch
@@ -0,0 +1,41 @@
+diff --git a/lib/tls/mbedtls/mbedtls-server.c b/lib/tls/mbedtls/mbedtls-server.c
+index efd7fc8b..ca5ebc15 100644
+--- a/lib/tls/mbedtls/mbedtls-server.c
++++ b/lib/tls/mbedtls/mbedtls-server.c
+@@ -39,7 +39,7 @@ lws_tls_server_client_cert_verify_config(struct lws_vhost *vh)
+ 	}
+ 
+ 	if (!lws_check_opt(vh->options, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
+-		verify_options = SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
++		verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ 
+ 	lwsl_notice("%s: vh %s requires client cert %d\n", __func__, vh->name,
+ 		    verify_options);
+diff --git a/lib/tls/mbedtls/wrapper/platform/ssl_pm.c b/lib/tls/mbedtls/wrapper/platform/ssl_pm.c
+index 3879e977..e47d4c13 100755
+--- a/lib/tls/mbedtls/wrapper/platform/ssl_pm.c
++++ b/lib/tls/mbedtls/wrapper/platform/ssl_pm.c
+@@ -255,9 +255,9 @@ static int ssl_pm_reload_crt(SSL *ssl)
+     struct pkey_pm *pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm;
+     struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm;
+ 
+-    if (ssl->verify_mode == SSL_VERIFY_PEER)
++    if ((ssl->verify_mode & SSL_VERIFY_PEER) > 0)
+         mode = MBEDTLS_SSL_VERIFY_REQUIRED;
+-    else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
++    else if ((ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) > 0)
+         mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
+     else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE)
+         mode = MBEDTLS_SSL_VERIFY_UNSET;
+@@ -980,9 +980,9 @@ void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
+ 
+ #if defined(LWS_HAVE_mbedtls_ssl_set_hs_authmode)
+ 
+-	if (ctx->verify_mode == SSL_VERIFY_PEER)
++	if ((ctx->verify_mode & SSL_VERIFY_PEER) > 0)
+ 		mode = MBEDTLS_SSL_VERIFY_REQUIRED;
+-	else if (ctx->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
++	else if ((ctx->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) > 0)
+ 		mode = MBEDTLS_SSL_VERIFY_REQUIRED;
+ 	else if (ctx->verify_mode == SSL_VERIFY_CLIENT_ONCE)
+ 		mode = MBEDTLS_SSL_VERIFY_UNSET;
diff --git a/build/debian/ttyd/cross-build.sh b/build/debian/ttyd/cross-build.sh
new file mode 100755
index 0000000..dda8f78
--- /dev/null
+++ b/build/debian/ttyd/cross-build.sh
@@ -0,0 +1,193 @@
+#!/bin/bash
+#
+# Example:
+#         env BUILD_TARGET=mips ./scripts/cross-build.sh
+#
+set -eo pipefail
+
+CROSS_ROOT="${CROSS_ROOT:-/tmp/cross}"
+STAGE_ROOT="${STAGE_ROOT:-/tmp/stage}"
+BUILD_ROOT="${BUILD_ROOT:-/tmp/build}"
+BUILD_TARGET="${BUILD_TARGET:-x86_64}"
+
+ZLIB_VERSION="${ZLIB_VERSION:-1.3.1}"
+JSON_C_VERSION="${JSON_C_VERSION:-0.17}"
+MBEDTLS_VERSION="${MBEDTLS_VERSION:-2.28.5}"
+LIBUV_VERSION="${LIBUV_VERSION:-1.44.2}"
+LIBWEBSOCKETS_VERSION="${LIBWEBSOCKETS_VERSION:-4.3.3}"
+
+build_zlib() {
+    echo "=== Building zlib-${ZLIB_VERSION} (${TARGET})..."
+    curl -fSsLo- "https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+    pushd "${BUILD_DIR}"/zlib-"${ZLIB_VERSION}"
+        env CHOST="${TARGET}" ./configure --static --archs="-fPIC" --prefix="${STAGE_DIR}"
+        make -j"$(nproc)" install
+    popd
+}
+
+build_json-c() {
+    echo "=== Building json-c-${JSON_C_VERSION} (${TARGET})..."
+    curl -fSsLo- "https://s3.amazonaws.com/json-c_releases/releases/json-c-${JSON_C_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+    pushd "${BUILD_DIR}/json-c-${JSON_C_VERSION}"
+        rm -rf build && mkdir -p build && cd build
+        cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
+            -DCMAKE_BUILD_TYPE=RELEASE \
+            -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \
+            -DBUILD_SHARED_LIBS=OFF \
+            -DBUILD_TESTING=OFF \
+            -DDISABLE_THREAD_LOCAL_STORAGE=ON \
+            ..
+        make -j"$(nproc)" install
+    popd
+}
+
+build_mbedtls() {
+    echo "=== Building mbedtls-${MBEDTLS_VERSION} (${TARGET})..."
+    curl -fSsLo- "https://github.com/ARMmbed/mbedtls/archive/v${MBEDTLS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+    pushd "${BUILD_DIR}/mbedtls-${MBEDTLS_VERSION}"
+        rm -rf build && mkdir -p build && cd build
+        cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
+            -DCMAKE_BUILD_TYPE=RELEASE \
+            -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \
+            -DENABLE_TESTING=OFF \
+            ..
+        make -j"$(nproc)" install
+    popd
+}
+
+build_libuv() {
+    echo "=== Building libuv-${LIBUV_VERSION} (${TARGET})..."
+    curl -fSsLo- "https://dist.libuv.org/dist/v${LIBUV_VERSION}/libuv-v${LIBUV_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+    pushd "${BUILD_DIR}/libuv-v${LIBUV_VERSION}"
+        ./autogen.sh
+        env CFLAGS=-fPIC ./configure --disable-shared --enable-static --prefix="${STAGE_DIR}" --host="${TARGET}"
+        make -j"$(nproc)" install
+    popd
+}
+
+install_cmake_cross_file() {
+    cat << EOF > "${BUILD_DIR}/cross-${TARGET}.cmake"
+SET(CMAKE_SYSTEM_NAME $1)
+
+set(CMAKE_C_COMPILER "${TARGET}-gcc")
+set(CMAKE_CXX_COMPILER "${TARGET}-g++")
+
+set(CMAKE_FIND_ROOT_PATH "${STAGE_DIR}")
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(OPENSSL_USE_STATIC_LIBS TRUE)
+EOF
+}
+
+build_libwebsockets() {
+    echo "=== Building libwebsockets-${LIBWEBSOCKETS_VERSION} (${TARGET})..."
+    curl -fSsLo- "https://github.com/warmcat/libwebsockets/archive/v${LIBWEBSOCKETS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+    cp "$(dirname $0)/client_cert.patch" ${BUILD_DIR}/libwebsockets-${LIBWEBSOCKETS_VERSION}
+    pushd "${BUILD_DIR}/libwebsockets-${LIBWEBSOCKETS_VERSION}"
+        patch -p1 < client_cert.patch
+        sed -i 's/ websockets_shared//g' cmake/libwebsockets-config.cmake.in
+        sed -i 's/ OR PC_OPENSSL_FOUND//g' lib/tls/CMakeLists.txt
+        sed -i '/PC_OPENSSL/d' lib/tls/CMakeLists.txt
+        rm -rf build && mkdir -p build && cd build
+        cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
+            -DCMAKE_BUILD_TYPE=RELEASE \
+            -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \
+            -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" \
+            -DCMAKE_EXE_LINKER_FLAGS="-static" \
+            -DLWS_WITHOUT_TESTAPPS=ON \
+            -DLWS_WITH_MBEDTLS=ON \
+            -DLWS_WITH_LIBUV=ON \
+            -DLWS_STATIC_PIC=ON \
+            -DLWS_WITH_SHARED=OFF \
+            -DLWS_UNIX_SOCK=ON \
+            -DLWS_IPV6=ON \
+            -DLWS_ROLE_RAW_FILE=OFF \
+            -DLWS_WITH_HTTP2=ON \
+            -DLWS_WITH_HTTP_BASIC_AUTH=OFF \
+            -DLWS_WITH_UDP=OFF \
+            -DLWS_WITHOUT_CLIENT=ON \
+            -DLWS_WITHOUT_EXTENSIONS=OFF \
+            -DLWS_WITH_LEJP=OFF \
+            -DLWS_WITH_LEJP_CONF=OFF \
+            -DLWS_WITH_LWSAC=OFF \
+            -DLWS_WITH_SEQUENCER=OFF \
+            ..
+        make -j"$(nproc)" install
+    popd
+}
+
+build_ttyd() {
+    echo "=== Building ttyd (${TARGET})..."
+    rm -rf build && mkdir -p build && cd build
+    cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
+        -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \
+        -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" \
+        -DCMAKE_C_FLAGS="-Os -ffunction-sections -fdata-sections -fno-unwind-tables -fno-asynchronous-unwind-tables -flto" \
+        -DCMAKE_EXE_LINKER_FLAGS="-static -no-pie -Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections" \
+        -DCMAKE_BUILD_TYPE=RELEASE \
+        ..
+    make install
+}
+
+build() {
+    TARGET="$1"
+    ALIAS="$2"
+    STAGE_DIR="${STAGE_ROOT}/${TARGET}"
+    BUILD_DIR="${BUILD_ROOT}/${TARGET}"
+    MUSL_CC_URL="https://github.com/tsl0922/musl-toolchains/releases/download/2021-11-23"
+    COMPONENTS="1"
+    SYSTEM="Linux"
+
+    if [ "$ALIAS" = "win32" ]; then
+        COMPONENTS=2
+        SYSTEM="Windows"
+    fi
+
+    echo "=== Installing toolchain ${ALIAS} (${TARGET})..."
+
+    mkdir -p "${CROSS_ROOT}" && export PATH="${PATH}:${CROSS_ROOT}/bin"
+    curl -fSsLo- "${MUSL_CC_URL}/${TARGET}-cross.tgz" | tar xz -C "${CROSS_ROOT}" --strip-components=${COMPONENTS}
+
+    echo "=== Building target ${ALIAS} (${TARGET})..."
+
+    rm -rf "${STAGE_DIR}" "${BUILD_DIR}"
+    mkdir -p "${STAGE_DIR}" "${BUILD_DIR}"
+    export PKG_CONFIG_PATH="${STAGE_DIR}/lib/pkgconfig"
+
+    install_cmake_cross_file ${SYSTEM}
+
+    build_zlib
+    build_json-c
+    build_libuv
+    build_mbedtls
+    build_libwebsockets
+    build_ttyd
+}
+
+case ${BUILD_TARGET} in
+    amd64) BUILD_TARGET="x86_64" ;;
+    arm64) BUILD_TARGET="aarch64" ;;
+    armv7) BUILD_TARGET="armv7l" ;;
+esac
+
+case ${BUILD_TARGET} in
+    i686|x86_64|aarch64|mips|mipsel|mips64|mips64el|s390x)
+        build "${BUILD_TARGET}-linux-musl" "${BUILD_TARGET}"
+        ;;
+    arm)
+        build "${BUILD_TARGET}-linux-musleabi" "${BUILD_TARGET}"
+        ;;
+    armhf)
+        build arm-linux-musleabihf "${BUILD_TARGET}"
+        ;;
+    armv7l)
+        build armv7l-linux-musleabihf "${BUILD_TARGET}"
+        ;;
+    win32)
+        build x86_64-w64-mingw32 "${BUILD_TARGET}"
+        ;;
+    *)
+        echo "unknown cross target: ${BUILD_TARGET}" && exit 1
+esac
diff --git a/build/debian/vm_config.json.aarch64 b/build/debian/vm_config.json.aarch64
index 5b7489e..f31c5b7 100644
--- a/build/debian/vm_config.json.aarch64
+++ b/build/debian/vm_config.json.aarch64
@@ -12,7 +12,7 @@
             "sharedPath": "/storage/emulated"
         },
         {
-            "sharedPath": "/data/data/com.google.android.virtualization.terminal/files"
+            "sharedPath": "/data/data/$PACKAGE_NAME/files"
         }
     ],
     "protected": false,
diff --git a/build/debian/vm_config.json.x86_64 b/build/debian/vm_config.json.x86_64
index 8a491e4..12f99c3 100644
--- a/build/debian/vm_config.json.x86_64
+++ b/build/debian/vm_config.json.x86_64
@@ -12,7 +12,7 @@
             "sharedPath": "/storage/emulated"
         },
         {
-            "sharedPath": "/data/data/com.google.android.virtualization.terminal/files"
+            "sharedPath": "/data/data/$PACKAGE_NAME/files"
         }
     ],
     "kernel": "$PAYLOAD_DIR/vmlinuz",
diff --git a/libs/vm_launcher_lib/java/com/android/virtualization/vmlauncher/InstallUtils.java b/libs/vm_launcher_lib/java/com/android/virtualization/vmlauncher/InstallUtils.java
index a4e7809..1febe27 100644
--- a/libs/vm_launcher_lib/java/com/android/virtualization/vmlauncher/InstallUtils.java
+++ b/libs/vm_launcher_lib/java/com/android/virtualization/vmlauncher/InstallUtils.java
@@ -130,6 +130,7 @@
     private static Function<String, String> getReplacer(Context context) {
         Map<String, String> rules = new HashMap<>();
         rules.put("\\$PAYLOAD_DIR", new File(context.getFilesDir(), PAYLOAD_DIR).toString());
+        rules.put("\\$PACKAGE_NAME", context.getPackageName());
         return (s) -> {
             for (Map.Entry<String, String> rule : rules.entrySet()) {
                 s = s.replaceAll(rule.getKey(), rule.getValue());