diff --git a/.gitmodules b/.gitmodules index 369f288f1a7..b10fda5f0a6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -129,3 +129,6 @@ [submodule "vendor/nim-unicodedb"] path = vendor/nim-unicodedb url = https://github.com/nitely/nim-unicodedb +[submodule "vendor/status-keycard-qt"] + path = vendor/status-keycard-qt + url = https://github.com/status-im/status-keycard-qt diff --git a/BUILDING.md b/BUILDING.md index b73621e4ed9..5ccc7166129 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -294,6 +294,26 @@ make run ``` 🎉 +### Build Configuration Options + +The following environment variables can be used to customize the build: + +- INCLUDE_DEBUG_SYMBOLS (0,1) - Configure nim to include the debug symbols for desktop platforms. +- KDF_ITERATIONS (number) - Configure the KDF_ITERATIONS to use for the DB encryption +- KEYCARD_QT_SOURCE_DIR (path) - Point the build system to a local keycard-qt folder. Defaults to a new clone of the latest master in the `status-keycard-qt` build folder. +- MONITORING (true,false) - Enable/disable qml monitoring tools. The monitoring tools provide a suite of qml introspection tools to debug data transformations. Defaults to `false` +- NIM_SDS_SOURCE_DIR (path) - Point the build system to a local nim-sds folder. Defaults to `$(GIT_ROOT)/../nim-sds` +- PRODUCTION_PARAMETERS (string) - Configure the production arguments for nim compilation. Defaults to `-d:production` +- QMAKE (path to executable) - Point the build system to a different qt installation. Defaults to env configuration +- QML_DEBUG (true,false) - Enable qml debugger and profiler. Needs DOtherSide recompilation. Defaults to `false` +- QML_DEBUG_PORT (number) - Configure the qml debugger port. Defaults to `49152` +- QT_ARCH (string) - Configure the Qt architecture for macOS cross-compilation. Can be used to compile Intel builds on ARM64 OS. Defaults to `$(shell uname -m)` +- REBUILD_NIM (true,false) - Force nim recompilation +- REBUILD_UI (true,false) - Force qrc recompilation +- STATUS_KEYCARD_QT_SOURCE_DIR (path) - Point the build system to a local status-keycard-qt folder. Defaults to `vendor/status-keycard-qt` +- USE_STATUS_KEYCARD_QT (0,1) - Toggle to switch between `status-keycard-go` and `status-keycard-qt`. Defaults to `0` +- VCINSTALLDIR (path) - Visual Studio compiler installation path. Defaults to `C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\` + ## 🐞 Troubleshooting diff --git a/Makefile b/Makefile index 3aa9a292566..91c47008eeb 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ GIT_ROOT ?= $(shell git rev-parse --show-toplevel 2>/dev/null || echo .) tests-nim-linux \ status-go \ status-keycard-go \ + status-keycard-qt \ statusq-sanity-checker \ run-statusq-sanity-checker \ statusq-tests \ @@ -248,6 +249,9 @@ NIMSDS_LIBDIR := $(NIM_SDS_SOURCE_DIR)/build NIMSDS_LIBFILE := $(NIMSDS_LIBDIR)/libsds.$(LIB_EXT) NIM_EXTRA_PARAMS += --passL:"-L$(NIMSDS_LIBDIR)" --passL:"-lsds" STATUSGO_MAKE_PARAMS += NIM_SDS_SOURCE_DIR="$(NIM_SDS_SOURCE_DIR)" +# Keycard library selection: set to 1 to use status-keycard-qt (Qt/C++), 0 for status-keycard-go (Go) +# Default: use status-keycard-go for now (stable), switch to 1 to test status-keycard-qt +USE_STATUS_KEYCARD_QT ?= 0 INCLUDE_DEBUG_SYMBOLS ?= false ifeq ($(INCLUDE_DEBUG_SYMBOLS),true) @@ -501,6 +505,59 @@ $(STATUSKEYCARDGO): | deps $(if $(filter 1 true,$(USE_MOCKED_KEYCARD_LIB)), build-mocked-lib, build-lib) \ $(STATUSKEYCARDGO_MAKE_PARAMS) $(HANDLE_OUTPUT) +## +## status-keycard-qt (Qt/C++ based keycard library) +## + +# Allow using local status-keycard-qt for development +STATUS_KEYCARD_QT_SOURCE_DIR ?= vendor/status-keycard-qt +KEYCARD_QT_SOURCE_DIR ?= "" + +# Determine build directory based on platform +ifeq ($(mkspecs),macx) +STATUS_KEYCARD_QT_BUILD_DIR := $(STATUS_KEYCARD_QT_SOURCE_DIR)/build/macos +else ifeq ($(mkspecs),win32) +STATUS_KEYCARD_QT_BUILD_DIR := $(STATUS_KEYCARD_QT_SOURCE_DIR)/build/windows +else +STATUS_KEYCARD_QT_BUILD_DIR := $(STATUS_KEYCARD_QT_SOURCE_DIR)/build/linux +endif + +export STATUSKEYCARD_QT_LIB := $(STATUS_KEYCARD_QT_BUILD_DIR)/libstatus-keycard-qt.$(LIB_EXT) +export STATUSKEYCARD_QT_LIBDIR := $(STATUS_KEYCARD_QT_BUILD_DIR) + +status-keycard-qt: $(STATUSKEYCARD_QT_LIB) +$(STATUSKEYCARD_QT_LIB): | deps check-qt-dir + echo -e $(BUILD_MSG) "status-keycard-qt" + cmake -S "${STATUS_KEYCARD_QT_SOURCE_DIR}" -B "${STATUS_KEYCARD_QT_BUILD_DIR}" \ + $(COMMON_CMAKE_CONFIG_PARAMS) \ + -DBUILD_TESTING=OFF \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_SHARED_LIBS=ON \ + -DKEYCARD_QT_SOURCE_DIR=${KEYCARD_QT_SOURCE_DIR} \ + $(HANDLE_OUTPUT) + cmake --build $(STATUS_KEYCARD_QT_BUILD_DIR) --target status-keycard-qt $(HANDLE_OUTPUT) + +status-keycard-qt-clean: + echo -e "\033[92mCleaning:\033[39m status-keycard-qt" + rm -rf $(STATUS_KEYCARD_QT_BUILD_DIR) + +## +## Keycard library selection +## + +# Set the keycard library and paths based on USE_STATUS_KEYCARD_QT +ifeq ($(USE_STATUS_KEYCARD_QT),1) + KEYCARD_LIB := $(STATUSKEYCARD_QT_LIB) + KEYCARD_LIBDIR := $(STATUSKEYCARD_QT_LIBDIR) + KEYCARD_LINKNAME := status-keycard-qt + KEYCARD_DYLIB_NAME := libstatus-keycard-qt.dylib +else + KEYCARD_LIB := $(STATUSKEYCARDGO) + KEYCARD_LIBDIR := $(STATUSKEYCARDGO_LIBDIR) + KEYCARD_LINKNAME := keycard + KEYCARD_DYLIB_NAME := libkeycard.$(LIB_EXT) +endif + QRCODEGEN := vendor/QR-Code-generator/c/libqrcodegen.a $(QRCODEGEN): | deps @@ -611,7 +668,7 @@ $(NIM_STATUS_CLIENT): update-qmake-previous endif $(NIM_STATUS_CLIENT): NIM_PARAMS += $(RESOURCES_LAYOUT) -$(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSGO) $(STATUSKEYCARDGO) $(QRCODEGEN) rcc deps +$(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSGO) $(KEYCARD_LIB) $(QRCODEGEN) rcc deps echo -e $(BUILD_MSG) "$@" $(ENV_SCRIPT) nim c $(NIM_PARAMS) \ --mm:refc \ @@ -619,8 +676,8 @@ $(NIM_STATUS_CLIENT): $(NIM_SOURCES) | statusq dotherside check-qt-dir $(STATUSG --passL:"-lstatus" \ --passL:"-L$(STATUSQ_INSTALL_PATH)/StatusQ" \ --passL:"-lStatusQ" \ - --passL:"-L$(STATUSKEYCARDGO_LIBDIR)" \ - --passL:"-lkeycard" \ + --passL:"-L$(KEYCARD_LIBDIR)" \ + --passL:"-l$(KEYCARD_LINKNAME)" \ --passL:"$(QRCODEGEN)" \ --passL:"-lm" \ --parallelBuild:0 \ @@ -631,8 +688,8 @@ ifeq ($(mkspecs),macx) @rpath/libstatus.dylib \ bin/nim_status_client install_name_tool -change \ - libkeycard.dylib \ - @rpath/libkeycard.dylib \ + $(KEYCARD_DYLIB_NAME) \ + @rpath/$(KEYCARD_DYLIB_NAME) \ bin/nim_status_client endif @@ -850,7 +907,7 @@ zip-windows: check-pkg-target-windows $(STATUS_CLIENT_7Z) clean-destdir: rm -rf bin/* -clean: | clean-common clean-destdir statusq-clean status-go-clean dotherside-clean storybook-clean clean-translations +clean: | clean-common clean-destdir statusq-clean status-go-clean status-keycard-qt-clean dotherside-clean storybook-clean clean-translations rm -rf bottles/* pkg/* tmp/* $(STATUSKEYCARDGO) + $(MAKE) -C vendor/QR-Code-generator/c/ --no-print-directory clean @@ -868,12 +925,12 @@ run: $(RUN_TARGET) run-linux: nim_status_client echo -e "\033[92mRunning:\033[39m bin/nim_status_client" - LD_LIBRARY_PATH="$(QT_LIBDIR)":"$(LIBWAKU_LIBDIR)":"$(NIMSDS_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(STATUSKEYCARDGO_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(LD_LIBRARY_PATH)" \ + LD_LIBRARY_PATH="$(QT_LIBDIR)":"$(LIBWAKU_LIBDIR)":"$(NIMSDS_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(KEYCARD_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(LD_LIBRARY_PATH)" \ ./bin/nim_status_client $(ARGS) run-linux-gdb: nim_status_client echo -e "\033[92mRunning:\033[39m bin/nim_status_client" - LD_LIBRARY_PATH="$(QT_LIBDIR)":"$(LIBWAKU_LIBDIR)":"$(NIMSDS_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(STATUSKEYCARDGO_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(LD_LIBRARY_PATH)" \ + LD_LIBRARY_PATH="$(QT_LIBDIR)":"$(LIBWAKU_LIBDIR)":"$(NIMSDS_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(KEYCARD_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(LD_LIBRARY_PATH)" \ gdb -ex=r ./bin/nim_status_client $(ARGS) run-macos: nim_status_client @@ -884,12 +941,13 @@ run-macos: nim_status_client ln -fs ../../../nim_status_client ./ fileicon set bin/nim_status_client status-dev.icns echo -e "\033[92mRunning:\033[39m bin/StatusDev.app/Contents/MacOS/nim_status_client" + DYLD_LIBRARY_PATH="$(STATUSGO_LIBDIR)":"$(KEYCARD_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(DYLD_LIBRARY_PATH)" \ ./bin/StatusDev.app/Contents/MacOS/nim_status_client $(ARGS) run-windows: STATUS_RC_FILE = status-dev.rc run-windows: compile_windows_resources nim_status_client echo -e "\033[92mRunning:\033[39m bin/nim_status_client.exe" - PATH="$(DOTHERSIDE_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(STATUSKEYCARDGO_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(PATH)" \ + PATH="$(DOTHERSIDE_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(KEYCARD_LIBDIR)":"$(STATUSQ_INSTALL_PATH)/StatusQ":"$(PATH)" \ ./bin/nim_status_client.exe $(ARGS) NIM_TEST_FILES := $(wildcard test/nim/*.nim) @@ -908,11 +966,16 @@ endef export PATH := $(call qmkq,QT_INSTALL_BINS):$(call qmkq,QT_HOST_BINS):$(call qmkq,QT_HOST_LIBEXECS):$(PATH) export QTDIR := $(call qmkq,QT_INSTALL_PREFIX) +#Force keycard support for mobile builds +ifeq ($(USE_STATUS_KEYCARD_QT),1) + MOBILE_FLAGS += "FLAG_KEYCARD_ENABLED=1" +endif + mobile-run: deps-common echo -e "\033[92mRunning:\033[39m mobile app" - $(MAKE) -C mobile run + $(MAKE) -C mobile run DEBUG=1 $(MOBILE_FLAGS) -mobile-build: USE_SYSTEM_NIM=1 +mobile-build: USE_SYSTEM_NIM=1 $(MOBILE_FLAGS) mobile-build: | deps-common echo -e "\033[92mBuilding:\033[39m mobile app ($(or $(PACKAGE_TYPE),default))" ifeq ($(PACKAGE_TYPE),aab) diff --git a/mobile/DEV_SETUP.md b/mobile/DEV_SETUP.md index f4883603abd..f48e2026ab4 100644 --- a/mobile/DEV_SETUP.md +++ b/mobile/DEV_SETUP.md @@ -32,6 +32,22 @@ export QTDIR=$HOME/qt/6.9.2/ios make mobile-run ``` +Running the app requires a code sign identity. See [Signing](#signing) + +#### Keycard + +The keycard support is disabled by default in the mobile makefile for IOS. It requires a paid apple developer account to run the app with NFC enabled. + +To enable keycard use the `USE_STATUS_KEYCARD_QT=1` flag for the main Makefile and use a paid account by updating the `DEVELOPMENT_TEAM` flag and the bundle if (if the development team isn't Status). + +#### Signing + +By default the app isn't signed. + +To sign the app the `DEVELOPMENT_TEAM` flag needs to be provided. If the development team is not Status development team, then the app bundle id needs to be updated to a unique bundle id. + +#### + ### Android Development Setup #### Prerequisites - can be installed using the Android Studio diff --git a/mobile/Makefile b/mobile/Makefile index 99a8272f90d..4d164350dd0 100644 --- a/mobile/Makefile +++ b/mobile/Makefile @@ -3,6 +3,18 @@ STATUS_GO_LIB := $(LIB_PATH)/libstatus$(LIB_EXT) +# FLAG_KEYCARD_ENABLED: Controls NFC/Keycard support +# - iOS: Default 0 (disabled) - Build without NFC, works with free Apple Developer account +# - Android: Default 1 (enabled) - NFC support doesn't require paid account on Android +# - Set to 1: Build with NFC support (iOS requires paid Apple Developer account) +# - Set to 0: Build without NFC support +# Usage: make build-ios FLAG_KEYCARD_ENABLED=1 +ifeq ($(OS),android) + FLAG_KEYCARD_ENABLED ?= 1 +else + FLAG_KEYCARD_ENABLED ?= 0 +endif + $(info Configuring build system for $(OS) $(ARCH) with QT $(QT_MAJOR)) # default rule @@ -16,6 +28,7 @@ statusq: clean-statusq $(STATUS_Q_LIB) dotherside: clean-dotherside $(DOTHERSIDE_LIB) openssl: clean-openssl $(OPENSSL_LIB) qrcodegen: clean-qrcodegen $(QRCODEGEN_LIB) +status-keycard-qt: clean-status-keycard-qt $(STATUS_KEYCARD_QT_LIB) nim-status-client: clean-nim-status-client $(NIM_STATUS_CLIENT_LIB) status-desktop-rcc: clean-status-desktop-rcc $(STATUS_DESKTOP_RCC) @@ -62,6 +75,11 @@ $(QRCODEGEN_LIB): $(QRCODEGEN_FILES) @QRCODEGEN=$(QRCODEGEN) $(QRCODEGEN_SCRIPT) $(HANDLE_OUTPUT) @echo "QRCodeGen built $(QRCODEGEN_LIB)" +$(STATUS_KEYCARD_QT_LIB): $(STATUS_KEYCARD_QT_FILES) $(STATUS_KEYCARD_QT_SCRIPT) $(OPENSSL_LIB) + @echo "Building status-keycard-qt" + @STATUS_KEYCARD_QT=$(STATUS_KEYCARD_QT) KEYCARD_QT=$(KEYCARD_QT) BUILD_DIR=$(BUILD_PATH) $(STATUS_KEYCARD_QT_SCRIPT) $(HANDLE_OUTPUT) + @echo "status-keycard-qt built $(STATUS_KEYCARD_QT_LIB)" + $(STATUS_DESKTOP_RCC): $(STATUS_DESKTOP_UI_FILES) compile-translations @echo "Building Status Desktop rcc" @make -C $(STATUS_DESKTOP) rcc $(HANDLE_OUTPUT) @@ -69,16 +87,39 @@ $(STATUS_DESKTOP_RCC): $(STATUS_DESKTOP_UI_FILES) compile-translations $(NIM_STATUS_CLIENT_LIB): $(STATUS_DESKTOP_NIM_FILES) $(NIM_STATUS_CLIENT_SCRIPT) $(STATUS_DESKTOP_RCC) $(DOTHERSIDE_LIB) $(OPENSSL_LIB) $(STATUS_Q_LIB) $(STATUS_GO_LIB) $(QRCODEGEN_LIB) @echo "Building Status Desktop Lib" - @STATUS_DESKTOP=$(STATUS_DESKTOP) LIB_SUFFIX=$(LIB_SUFFIX) LIB_EXT=$(LIB_EXT) USE_QML_SERVER=$(USE_QML_SERVER) $(NIM_STATUS_CLIENT_SCRIPT) $(HANDLE_OUTPUT) + @STATUS_DESKTOP=$(STATUS_DESKTOP) \ + LIB_SUFFIX=$(LIB_SUFFIX) \ + LIB_EXT=$(LIB_EXT) \ + USE_QML_SERVER=$(USE_QML_SERVER) \ + BUNDLE_IDENTIFIER="$(BUNDLE_IDENTIFIER)" \ + DEBUG=$(DEBUG) \ + FLAG_DAPPS_ENABLED=$(FLAG_DAPPS_ENABLED) \ + FLAG_CONNECTOR_ENABLED=$(FLAG_CONNECTOR_ENABLED) \ + FLAG_KEYCARD_ENABLED=$(FLAG_KEYCARD_ENABLED) \ + FLAG_SINGLE_STATUS_INSTANCE_ENABLED=$(FLAG_SINGLE_STATUS_INSTANCE_ENABLED) \ + FLAG_BROWSER_ENABLED=$(FLAG_BROWSER_ENABLED) \ + $(NIM_STATUS_CLIENT_SCRIPT) $(HANDLE_OUTPUT) @echo "Status Desktop Lib built $(NIM_STATUS_CLIENT_LIB)" # non-phony targets -$(TARGET): $(APP_SCRIPT) $(STATUS_GO_LIB) $(STATUS_Q_LIB) $(DOTHERSIDE_LIB) $(OPENSSL_LIB) $(QRCODEGEN_LIB) $(NIM_STATUS_CLIENT_LIB) $(STATUS_DESKTOP_RCC) $(WRAPPER_APP_FILES) +$(TARGET): $(APP_SCRIPT) $(STATUS_GO_LIB) $(STATUS_Q_LIB) $(DOTHERSIDE_LIB) $(OPENSSL_LIB) $(QRCODEGEN_LIB) $(STATUS_KEYCARD_QT_LIB) $(NIM_STATUS_CLIENT_LIB) $(STATUS_DESKTOP_RCC) $(WRAPPER_APP_FILES) @echo "Building app" ifeq ($(OS),android) - @STATUS_DESKTOP=$(STATUS_DESKTOP) BUILD_TYPE=$(PACKAGE_TYPE) BIN_DIR=$(BIN_PATH) BUILD_DIR=$(BUILD_PATH) QT_MAJOR=$(QT_MAJOR) $(APP_SCRIPT) $(HANDLE_OUTPUT) + @STATUS_DESKTOP=$(STATUS_DESKTOP) \ + BUILD_TYPE=$(PACKAGE_TYPE) \ + BIN_DIR=$(BIN_PATH) \ + BUILD_DIR=$(BUILD_PATH) \ + QT_MAJOR=$(QT_MAJOR) \ + FLAG_KEYCARD_ENABLED=$(FLAG_KEYCARD_ENABLED) \ + $(APP_SCRIPT) $(HANDLE_OUTPUT) else - @STATUS_DESKTOP=$(STATUS_DESKTOP) BIN_DIR=$(BIN_PATH) BUILD_DIR=$(BUILD_PATH) QT_MAJOR=$(QT_MAJOR) $(APP_SCRIPT) $(HANDLE_OUTPUT) + @STATUS_DESKTOP=$(STATUS_DESKTOP) \ + BIN_DIR=$(BIN_PATH) \ + BUILD_DIR=$(BUILD_PATH) \ + QT_MAJOR=$(QT_MAJOR) \ + DEVELOPMENT_TEAM="$(DEVELOPMENT_TEAM)" \ + FLAG_KEYCARD_ENABLED=$(FLAG_KEYCARD_ENABLED) \ + $(APP_SCRIPT) $(HANDLE_OUTPUT) endif @echo "Built $(TARGET)" @@ -128,7 +169,7 @@ endif all: $(TARGET) .PHONY: clean -clean: clean-statusq clean-dotherside clean-openssl clean-qrcodegen clean-nim-status-client clean-status-desktop-rcc +clean: clean-statusq clean-dotherside clean-openssl clean-qrcodegen clean-status-keycard-qt clean-nim-status-client clean-status-desktop-rcc @echo "Cleaning" @rm -rf $(ROOT_DIR)/bin $(ROOT_DIR)/build $(ROOT_DIR)/lib @@ -158,6 +199,13 @@ clean-qrcodegen: @rm -f $(QRCODEGEN_LIB) @cd $(QRCODEGEN) && make clean +# keycard-qt is now automatically built by status-keycard-qt via CMake FetchContent +# Its build artifacts are cleaned as part of status-keycard-qt's build directory +.PHONY: clean-status-keycard-qt +clean-status-keycard-qt: + @rm -f $(STATUS_KEYCARD_QT_LIB) + @rm -rf $(STATUS_KEYCARD_QT)/build/$(OS) + .PHONY: clean-nim-status-client clean-nim-status-client: @rm -f $(NIM_STATUS_CLIENT_LIB) diff --git a/mobile/android/qt6/AndroidManifest.xml b/mobile/android/qt6/AndroidManifest.xml index 7305b3591a8..39f90e1954c 100644 --- a/mobile/android/qt6/AndroidManifest.xml +++ b/mobile/android/qt6/AndroidManifest.xml @@ -17,6 +17,7 @@ + diff --git a/mobile/android/qt6/src/app/status/mobile/StatusQtActivity.java b/mobile/android/qt6/src/app/status/mobile/StatusQtActivity.java index 64ebf16705f..3165138db2a 100644 --- a/mobile/android/qt6/src/app/status/mobile/StatusQtActivity.java +++ b/mobile/android/qt6/src/app/status/mobile/StatusQtActivity.java @@ -5,10 +5,20 @@ import android.os.Bundle; import androidx.core.splashscreen.SplashScreen; import java.util.concurrent.atomic.AtomicBoolean; +import android.content.Intent; +import android.app.PendingIntent; +import android.nfc.NfcAdapter; +import android.util.Log; public class StatusQtActivity extends QtActivity { + private static final String TAG = "StatusQtActivity"; private static final AtomicBoolean splashShouldHide = new AtomicBoolean(false); + // NFC Foreground Dispatch members + // CRITICAL: These enable NFC detection to work immediately at app startup + private NfcAdapter mNfcAdapter; + private PendingIntent mPendingIntent; + // QTBUG-140897: Android 16 keyboard workaround // Remove this line when Qt 6.10+ fixes the issue, and delete Android16KeyboardWorkaround.java private Android16KeyboardWorkaround mKeyboardWorkaround; @@ -25,6 +35,81 @@ public void onCreate(Bundle savedInstanceState) { // QTBUG-140897: Install Android 16 keyboard workaround // Remove this line when Qt 6.10+ fixes the issue mKeyboardWorkaround = Android16KeyboardWorkaround.install(this); + + // CRITICAL: Initialize NFC for Foreground Dispatch + // This ensures Qt NFC detection works immediately at app startup. + // Without this initialization, Qt's NFC detection fails until the app + // goes through a background→foreground cycle. + mNfcAdapter = NfcAdapter.getDefaultAdapter(this); + if (mNfcAdapter == null) { + Log.d(TAG, "NFC not available on this device"); + } else { + // Create a PendingIntent for NFC tag discovery + Intent intent = new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + int flags = PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT; + mPendingIntent = PendingIntent.getActivity(this, 0, intent, flags); + Log.d(TAG, "NFC Foreground Dispatch initialized"); + } + } + + // Track if foreground dispatch is enabled + private boolean mForegroundDispatchEnabled = false; + + // Static reference to the current activity instance + private static StatusQtActivity sInstance = null; + + @Override + protected void onResume() { + super.onResume(); + sInstance = this; + + Log.d(TAG, "===== onResume: Setting up NFC Foreground Dispatch ====="); + + // CRITICAL: Enable Foreground Dispatch here to fix Qt NFC startup issue + // + // Problem: Qt's NFC backend calls enableForegroundDispatch() during initialization, + // but this happens too early - before the Activity is fully ready. This causes + // Qt NFC detection to fail silently until the app goes background→foreground. + // + // Solution: We enable Foreground Dispatch here in onResume(), which is guaranteed + // to run after the Activity is fully ready. This ensures NFC detection works + // immediately at app startup. + // + // Note: Only enable if not already enabled to avoid disrupting active NFC connections + if (mNfcAdapter != null && mPendingIntent != null && !mForegroundDispatchEnabled) { + try { + mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); + mForegroundDispatchEnabled = true; + Log.d(TAG, "NFC Foreground Dispatch ENABLED (Qt detection will work)"); + } catch (Exception e) { + Log.e(TAG, "Error enabling Foreground Dispatch: " + e.getMessage()); + } + } else if (mForegroundDispatchEnabled) { + Log.d(TAG, "NFC Foreground Dispatch already enabled"); + } else { + Log.w(TAG, "Cannot enable Foreground Dispatch - adapter or intent is null"); + } + } + + @Override + protected void onPause() { + super.onPause(); + + // Disable Foreground Dispatch when activity is paused + // This is standard Android practice to allow other apps to receive NFC events + if (mNfcAdapter != null && mForegroundDispatchEnabled) { + try { + mNfcAdapter.disableForegroundDispatch(this); + mForegroundDispatchEnabled = false; + Log.d(TAG, "NFC Foreground Dispatch DISABLED"); + } catch (Exception e) { + Log.e(TAG, "Error disabling Foreground Dispatch: " + e.getMessage()); + } + } + + if (sInstance == this) { + sInstance = null; + } } @Override diff --git a/mobile/ios/Info.plist b/mobile/ios/Info.plist.template similarity index 84% rename from mobile/ios/Info.plist rename to mobile/ios/Info.plist.template index ca93a55d2a3..e39f6171873 100644 --- a/mobile/ios/Info.plist +++ b/mobile/ios/Info.plist.template @@ -66,5 +66,18 @@ Log in securely to your account. ITSAppUsesNonExemptEncryption + + + diff --git a/mobile/ios/Status-NoKeycard.entitlements b/mobile/ios/Status-NoKeycard.entitlements new file mode 100644 index 00000000000..35c3f6949d0 --- /dev/null +++ b/mobile/ios/Status-NoKeycard.entitlements @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile/ios/Status.entitlements b/mobile/ios/Status.entitlements new file mode 100644 index 00000000000..8e1b20cbd2b --- /dev/null +++ b/mobile/ios/Status.entitlements @@ -0,0 +1,16 @@ + + + + + + + com.apple.developer.nfc.readersession.formats + + TAG + + + + + + + diff --git a/mobile/scripts/Common.mk b/mobile/scripts/Common.mk index 896787f8dad..bd8364c62dd 100644 --- a/mobile/scripts/Common.mk +++ b/mobile/scripts/Common.mk @@ -33,6 +33,7 @@ STATUS_GO?=$(STATUS_DESKTOP)/vendor/status-go DOTHERSIDE?=$(STATUS_DESKTOP)/vendor/DOtherSide OPENSSL?=$(ROOT_DIR)/vendors/openssl QRCODEGEN?=$(STATUS_DESKTOP)/vendor/QR-Code-generator/c +STATUS_KEYCARD_QT?=$(STATUS_DESKTOP)/vendor/status-keycard-qt # compile macros TARGET_PREFIX := Status @@ -61,6 +62,7 @@ STATUS_GO_FILES := $(shell find $(STATUS_GO) -type f \( -iname '*.go' \)) DOTHERSIDE_FILES := $(shell find $(DOTHERSIDE) -type f \( -iname '*.cpp' -o -iname '*.h' \)) OPENSSL_FILES := $(shell find $(OPENSSL) -type f \( -iname '*.c' -o -iname '*.h' \)) QRCODEGEN_FILES := $(shell find $(QRCODEGEN) -type f \( -iname '*.c' -o -iname '*.h' \)) +STATUS_KEYCARD_QT_FILES := $(shell find $(STATUS_KEYCARD_QT) -type f \( -iname '*.cpp' -o -iname '*.h' \) 2>/dev/null || echo "") WRAPPER_APP_FILES := $(shell find $(WRAPPER_APP) -type f) # script files @@ -69,6 +71,7 @@ STATUS_GO_SCRIPT := $(SCRIPTS_PATH)/buildStatusGo.sh DOTHERSIDE_SCRIPT := $(SCRIPTS_PATH)/buildDOtherSide.sh OPENSSL_SCRIPT := $(SCRIPTS_PATH)/ios/buildOpenSSL.sh QRCODEGEN_SCRIPT := $(SCRIPTS_PATH)/buildQRCodeGen.sh +STATUS_KEYCARD_QT_SCRIPT := $(SCRIPTS_PATH)/buildStatusKeycardQt.sh NIM_STATUS_CLIENT_SCRIPT := $(SCRIPTS_PATH)/buildNimStatusClient.sh APP_SCRIPT := $(SCRIPTS_PATH)/buildApp.sh RUN_SCRIPT := $(SCRIPTS_PATH)/$(OS)/run.sh @@ -79,6 +82,7 @@ STATUS_Q_LIB := $(LIB_PATH)/libStatusQ$(LIB_SUFFIX)$(LIB_EXT) OPENSSL_LIB := $(LIB_PATH)/libssl_3$(LIB_EXT) QRCODEGEN_LIB := $(LIB_PATH)/libqrcodegen.a QZXING_LIB := $(LIB_PATH)/libqzxing.a +STATUS_KEYCARD_QT_LIB := $(LIB_PATH)/libstatus-keycard-qt$(LIB_EXT) NIM_STATUS_CLIENT_LIB := $(LIB_PATH)/libnim_status_client$(LIB_EXT) STATUS_DESKTOP_RCC := $(STATUS_DESKTOP)/ui/resources.qrc ifeq ($(OS), ios) diff --git a/mobile/scripts/buildApp.sh b/mobile/scripts/buildApp.sh index 3ec8de95c81..d516d344042 100755 --- a/mobile/scripts/buildApp.sh +++ b/mobile/scripts/buildApp.sh @@ -11,6 +11,7 @@ BUILD_DIR=${BUILD_DIR:-"$CWD/../build"} ANDROID_ABI=${ANDROID_ABI:-"arm64-v8a"} BUILD_TYPE=${BUILD_TYPE:-"apk"} SIGN_IOS=${SIGN_IOS:-"false"} +FLAG_KEYCARD_ENABLED=${FLAG_KEYCARD_ENABLED:-0} QMAKE_BIN="${QMAKE:-qmake}" QMAKE_CONFIG="CONFIG+=device CONFIG+=release" @@ -33,6 +34,12 @@ fi echo "Using version: $DESKTOP_VERSION; build version: $BUILD_VERSION" +# Configure qmake with keycard flag +QMAKE_DEFINES="" +if [[ "${FLAG_KEYCARD_ENABLED}" == "1" ]]; then + QMAKE_DEFINES="DEFINES+=FLAG_KEYCARD_ENABLED" +fi + if [[ "${OS}" == "android" ]]; then if [[ -z "${JAVA_HOME}" ]]; then echo "JAVA_HOME is not set. Please set JAVA_HOME to the path of your JDK 11 or later." @@ -42,7 +49,7 @@ if [[ "${OS}" == "android" ]]; then echo "Building for Android 35" ANDROID_PLATFORM=android-35 - "$QMAKE_BIN" "$CWD/../wrapperApp/Status.pro" "$QMAKE_CONFIG" -spec android-clang ANDROID_ABIS="$ANDROID_ABI" APP_VARIANT="${APP_VARIANT}" VERSION="$DESKTOP_VERSION" -after + "$QMAKE_BIN" "$CWD/../wrapperApp/Status.pro" "$QMAKE_CONFIG" -spec android-clang ANDROID_ABIS="$ANDROID_ABI" APP_VARIANT="${APP_VARIANT}" VERSION="$DESKTOP_VERSION" ${QMAKE_DEFINES} -after # Build the app make -j"$(nproc)" apk_install_target @@ -122,12 +129,35 @@ if [[ "${OS}" == "android" ]]; then fi fi else - "$QMAKE_BIN" "$CWD/../wrapperApp/Status.pro" "$QMAKE_CONFIG" -spec macx-ios-clang CONFIG+="$SDK" VERSION="$DESKTOP_VERSION" -after + # Generate Info.plist based on FLAG_KEYCARD_ENABLED + echo "Generating Info.plist (FLAG_KEYCARD_ENABLED=${FLAG_KEYCARD_ENABLED})..." + if [[ "${FLAG_KEYCARD_ENABLED}" == "1" ]]; then + # Enable NFC/Keycard support - uncomment NFC sections + sed -e '/$/d' \ + "$CWD/../ios/Info.plist.template" > "$BUILD_DIR/Info.plist" + else + # Disable NFC/Keycard support - remove NFC sections entirely + sed '/$/d' \ + "$CWD/../ios/Info.plist.template" > "$BUILD_DIR/Info.plist" + fi + + "$QMAKE_BIN" "$CWD/../wrapperApp/Status.pro" "$QMAKE_CONFIG" -spec macx-ios-clang CONFIG+="$SDK" VERSION="$DESKTOP_VERSION" ${QMAKE_DEFINES} -after + + # By default the app is not signed. Set the `DEVELOPMENT_TEAM` to the team ID to automatically sign the app. + SIGN_ARGS="CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO" + if [[ -n "${DEVELOPMENT_TEAM}" ]]; then + echo "Signing Configuration: ${SIGN_ARGS} DEVELOPMENT_TEAM=${DEVELOPMENT_TEAM}" + /usr/libexec/PlistBuddy -c "Set :objects:*:buildSettings:DEVELOPMENT_TEAM ${DEVELOPMENT_TEAM}" "$BUILD_DIR/Status.xcodeproj/project.pbxproj" 2>/dev/null || true + sed -i '' "s/DEVELOPMENT_TEAM = .*;/DEVELOPMENT_TEAM = ${DEVELOPMENT_TEAM};/g" "$BUILD_DIR/Status.xcodeproj/project.pbxproj" + SIGN_ARGS="CODE_SIGN_STYLE=Automatic DEVELOPMENT_TEAM=${DEVELOPMENT_TEAM} -allowProvisioningUpdates" + fi # Compile resources - xcodebuild -configuration Release -target "Qt Preprocess" -sdk "$SDK" -arch "$ARCH" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO CURRENT_PROJECT_VERSION=$BUILD_VERSION | xcbeautify - # Compile the app - xcodebuild -configuration Release -target Status install -sdk "$SDK" -arch "$ARCH" DSTROOT="$BIN_DIR" INSTALL_PATH="/" TARGET_BUILD_DIR="$BIN_DIR" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO CURRENT_PROJECT_VERSION=$BUILD_VERSION | xcbeautify + echo "Signing Configuration: ${SIGN_ARGS}" + xcodebuild -configuration Release -target "Qt Preprocess" -sdk "$SDK" -arch "$ARCH" ${SIGN_ARGS} | xcbeautify + + xcodebuild -configuration Release -target Status install -sdk "$SDK" -arch "$ARCH" DSTROOT="$BIN_DIR" INSTALL_PATH="/" TARGET_BUILD_DIR="$BIN_DIR" ${SIGN_ARGS} | xcbeautify if [[ ! -e "$BIN_DIR/Status.app/Info.plist" ]]; then echo "Build failed" diff --git a/mobile/scripts/buildNimStatusClient.sh b/mobile/scripts/buildNimStatusClient.sh index ca6aa116f9f..0f82e9e4253 100755 --- a/mobile/scripts/buildNimStatusClient.sh +++ b/mobile/scripts/buildNimStatusClient.sh @@ -8,6 +8,12 @@ ANDROID_ABI=${ANDROID_ABI:-"arm64-v8a"} LIB_DIR=${LIB_DIR} LIB_SUFFIX=${LIB_SUFFIX:-""} OS=${OS:-"android"} +DEBUG=${DEBUG:-0} +FLAG_DAPPS_ENABLED=${FLAG_DAPPS_ENABLED:-0} +FLAG_CONNECTOR_ENABLED=${FLAG_CONNECTOR_ENABLED:-0} +FLAG_KEYCARD_ENABLED=${FLAG_KEYCARD_ENABLED:-0} +FLAG_SINGLE_STATUS_INSTANCE_ENABLED=${FLAG_SINGLE_STATUS_INSTANCE_ENABLED:-0} +FLAG_BROWSER_ENABLED=${FLAG_BROWSER_ENABLED:-0} DESKTOP_VERSION=$(eval cd "$STATUS_DESKTOP" && git describe --tags --dirty="-dirty" --always) STATUSGO_VERSION=$(eval cd "$STATUS_DESKTOP/vendor/status-go" && git describe --tags --dirty="-dirty" --always) @@ -22,7 +28,7 @@ if [[ "$OS" == "ios" ]]; then PLATFORM_SPECIFIC=(--app:staticlib -d:ios --os:ios) else PLATFORM_SPECIFIC=(--app:lib --os:android -d:android -d:androidNDK -d:chronicles_sinks=textlines[logcat],textlines[nocolors,dynamic],textlines[file,nocolors] \ - --passL="-L$LIB_DIR" --passL="-lstatus" --passL="-lStatusQ$LIB_SUFFIX" --passL="-lDOtherSide$LIB_SUFFIX" --passL="-lqrcodegen" --passL="-lqzxing" --passL="-lssl_3" --passL="-lcrypto_3" -d:taskpool) + --passL="-L$LIB_DIR" --passL="-lstatus" --passL="-lStatusQ$LIB_SUFFIX" --passL="-lDOtherSide$LIB_SUFFIX" --passL="-lqrcodegen" --passL="-lqzxing" --passL="-lssl_3" --passL="-lcrypto_3" --passL="-lstatus-keycard-qt" -d:taskpool) fi if [ -n "$USE_QML_SERVER" ]; then @@ -37,7 +43,13 @@ cd "$STATUS_DESKTOP" # build nim compiler with host env # setting compile time feature flags -FEATURE_FLAGS="FLAG_DAPPS_ENABLED=0 FLAG_CONNECTOR_ENABLED=0 FLAG_KEYCARD_ENABLED=0 FLAG_SINGLE_STATUS_INSTANCE_ENABLED=0 FLAG_BROWSER_ENABLED=0" +FEATURE_FLAGS=( + FLAG_DAPPS_ENABLED=$FLAG_DAPPS_ENABLED + FLAG_CONNECTOR_ENABLED=$FLAG_CONNECTOR_ENABLED + FLAG_KEYCARD_ENABLED=$FLAG_KEYCARD_ENABLED + FLAG_SINGLE_STATUS_INSTANCE_ENABLED=$FLAG_SINGLE_STATUS_INSTANCE_ENABLED + FLAG_BROWSER_ENABLED=$FLAG_BROWSER_ENABLED +) # app configuration defines APP_CONFIG_DEFINES=( @@ -48,21 +60,28 @@ APP_CONFIG_DEFINES=( -d:GIT_COMMIT="$(git log --pretty=format:'%h' -n 1)" ) +NIM_FLAGS=( + --mm:orc + -d:useMalloc + --opt:size + --cc:clang + --cpu:"$CARCH" + --noMain:on + --clang.exe="$CC" + --clang.linkerexe="$CC" + --dynlibOverrideAll + --nimcache:"$STATUS_DESKTOP"/nimcache +) + +if [ "$DEBUG" -eq 1 ]; then + NIM_FLAGS+=(-d:debug -d:nimTypeNames) +else + NIM_FLAGS+=(-d:release -d:lto -d:production) +fi + # build status-client with feature flags -env $FEATURE_FLAGS ./vendor/nimbus-build-system/scripts/env.sh nim c "${PLATFORM_SPECIFIC[@]}" "${APP_CONFIG_DEFINES[@]}" ${QML_SERVER_DEFINES} \ - --mm:orc \ - -d:useMalloc \ - --opt:size \ - -d:lto \ - --cc:clang \ - --cpu:"$CARCH" \ - --noMain:on \ - -d:release \ - -d:production \ - --clang.exe="$CC" \ - --clang.linkerexe="$CC" \ - --dynlibOverrideAll \ - --nimcache:"$STATUS_DESKTOP"/nimcache \ +env "${FEATURE_FLAGS[@]}" ./vendor/nimbus-build-system/scripts/env.sh nim c "${PLATFORM_SPECIFIC[@]}" "${APP_CONFIG_DEFINES[@]}" ${QML_SERVER_DEFINES} \ + "${NIM_FLAGS[@]}" \ "$STATUS_DESKTOP"/src/nim_status_client.nim mkdir -p "$LIB_DIR" diff --git a/mobile/scripts/buildStatusKeycardQt.sh b/mobile/scripts/buildStatusKeycardQt.sh new file mode 100755 index 00000000000..f3d03b60b8e --- /dev/null +++ b/mobile/scripts/buildStatusKeycardQt.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +set -ef pipefail + +BASEDIR=$(dirname "$0") + +# Load common config variables +source "${BASEDIR}/commonCmakeConfig.sh" + +STATUS_KEYCARD_QT=${STATUS_KEYCARD_QT:="../vendors/status-desktop"} +KEYCARD_QT=${KEYCARD_QT:=""} +LIB_DIR=${LIB_DIR} +LIB_EXT=${LIB_EXT:=".a"} + +BUILD_DIR=${BUILD_DIR:="${STATUS_KEYCARD_QT}/build/${OS}/${ARCH}"} +BUILD_SHARED_LIBS=ON + +if [[ "${LIB_EXT}" == ".a" ]]; then + BUILD_SHARED_LIBS=OFF +fi + +echo "Building status-keycard-qt for ${ARCH} using compiler: ${CC}" +echo "BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}" + +printf 'COMMON_CMAKE_CONFIG: %s\n' "${COMMON_CMAKE_CONFIG[@]}" + +# Set OpenSSL paths (REQUIRED for key derivation in session_manager.cpp) +MOBILE_ROOT="$(cd "${BASEDIR}/.." && pwd)" +if [[ "$OS" == "android" ]]; then + OPENSSL_BUILD_DIR="${MOBILE_ROOT}/build/${OS}/qt6/openssl-${OS}-${ARCH}" +elif [[ "$OS" == "ios" ]]; then + # iOS OpenSSL is built per-architecture + OPENSSL_BUILD_DIR="${MOBILE_ROOT}/build/${OS}/qt6/openssl-${OS}-${ARCH}" +else + OPENSSL_BUILD_DIR="${MOBILE_ROOT}/build/${OS}/openssl-${OS}-${ARCH}" +fi +OPENSSL_BUILD_INCLUDE_DIR="${OPENSSL_BUILD_DIR}/include" +OPENSSL_SOURCE_INCLUDE_DIR="${MOBILE_ROOT}/vendors/openssl/include" +OPENSSL_CRYPTO_LIBRARY="${LIB_DIR}/libcrypto_3${LIB_EXT}" + +echo "OpenSSL paths:" +echo " Build include dir: ${OPENSSL_BUILD_INCLUDE_DIR}" +echo " Source include dir: ${OPENSSL_SOURCE_INCLUDE_DIR}" +echo " Crypto library: ${OPENSSL_CRYPTO_LIBRARY}" + +# Configure with CMake +# Use local keycard-qt for faster development builds (FetchContent will use this) +# If KEYCARD_QT path doesn't exist, FetchContent will clone from GitHub +if [[ -d "${KEYCARD_QT}" ]]; then + echo "Using local keycard-qt from: ${KEYCARD_QT}" + KEYCARD_QT_SOURCE_DIR_ARG="-DKEYCARD_QT_SOURCE_DIR=${KEYCARD_QT}" +else + echo "Local keycard-qt not found, will fetch from GitHub" + KEYCARD_QT_SOURCE_DIR_ARG="" +fi + +cmake -S "${STATUS_KEYCARD_QT}" -B "${BUILD_DIR}" \ + "${COMMON_CMAKE_CONFIG[@]}" \ + -DBUILD_TESTING=OFF \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} \ + ${KEYCARD_QT_SOURCE_DIR_ARG} \ + -DOPENSSL_BUILD_INCLUDE_DIR="${OPENSSL_BUILD_INCLUDE_DIR}" \ + -DOPENSSL_SOURCE_INCLUDE_DIR="${OPENSSL_SOURCE_INCLUDE_DIR}" \ + -DOPENSSL_CRYPTO_LIBRARY="${OPENSSL_CRYPTO_LIBRARY}" + +# Build the library +make -C "${BUILD_DIR}" status-keycard-qt -j "$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)" + +# Create lib directory +mkdir -p "${LIB_DIR}" + +# Find and copy the built library +# Note: keycard-qt is built as a static library and linked into libstatus-keycard-qt, +# so we only need to copy one library file +STATUS_KEYCARD_QT_LIB=$(find "${BUILD_DIR}" -name "libstatus-keycard-qt${LIB_EXT}" -o -name "libstatus-keycard-qt.dylib" | grep -v "\.so\." | head -n 1) + +if [[ -z "${STATUS_KEYCARD_QT_LIB}" ]]; then + # Try alternative patterns for static library + STATUS_KEYCARD_QT_LIB=$(find "${BUILD_DIR}" -name "libstatus-keycard-qt.a" | head -n 1) +fi + +if [[ -z "${STATUS_KEYCARD_QT_LIB}" ]]; then + echo "Error: Could not find status-keycard-qt library in ${BUILD_DIR}" + echo "Build directory contents:" + find "${BUILD_DIR}" -name "*.so" -o -name "*.a" -o -name "*.dylib" | head -20 + exit 1 +fi + +cp "${STATUS_KEYCARD_QT_LIB}" "${LIB_DIR}/libstatus-keycard-qt${LIB_EXT}" +echo "Copied ${STATUS_KEYCARD_QT_LIB} to ${LIB_DIR}/libstatus-keycard-qt${LIB_EXT}" + diff --git a/mobile/scripts/commonCmakeConfig.sh b/mobile/scripts/commonCmakeConfig.sh index d92d627be2d..31a927a3f26 100755 --- a/mobile/scripts/commonCmakeConfig.sh +++ b/mobile/scripts/commonCmakeConfig.sh @@ -2,7 +2,9 @@ set -ef pipefail ARCH=${ARCH:-"x86_64"} -QTDIR=${QTDIR:-$(qmake -query QT_INSTALL_PREFIX)} +# Use $QMAKE if set, otherwise fall back to system qmake +QMAKE_BIN=${QMAKE:-qmake} +QTDIR=${QTDIR:-$($QMAKE_BIN -query QT_INSTALL_PREFIX)} OS=${OS:-ios} ANDROID_NDK_ROOT=${ANDROID_NDK_ROOT:-""} @@ -46,4 +48,9 @@ COMMON_CMAKE_CONFIG+=( -DCMAKE_BUILD_TYPE=Release ) +# Add Android-specific flags only for Android +if [[ "$OS" == "android" ]]; then + COMMON_CMAKE_CONFIG+=(-DANDROID_PLATFORM=android-35) +fi + printf 'COMMON_CMAKE_CONFIG: %s\n' "${COMMON_CMAKE_CONFIG[@]}" diff --git a/mobile/scripts/ios/buildOpenSSL.sh b/mobile/scripts/ios/buildOpenSSL.sh index 1aeb294fd15..4aea7bcc459 100755 --- a/mobile/scripts/ios/buildOpenSSL.sh +++ b/mobile/scripts/ios/buildOpenSSL.sh @@ -56,7 +56,30 @@ mkdir -p ${SSL_BUILD_DIR} ( cd ${SSL_BUILD_DIR} - ${OPENSSL}/Configure --release "$TARGET" $PLATFORM_CONFIG_ARGS + + # - no-module: Makes legacy provider built-in to libcrypto (not a separate module) + # - enable-legacy: Enables legacy algorithms including DES + # This is required for GlobalPlatform SCP02 which uses single-DES + # Reference: https://github.com/openssl/openssl/discussions/25793 + + # Platform-specific config + if [[ "$OS" == "ios" ]]; then + # iOS uses static libraries (.a files) + SHARED_FLAG="no-shared" + else + # Android uses shared libraries (.so files) + SHARED_FLAG="shared" + fi + + ${OPENSSL}/Configure --release "$TARGET" $PLATFORM_CONFIG_ARGS \ + no-module \ + enable-legacy \ + enable-des \ + enable-md2 \ + enable-rc5 \ + $SHARED_FLAG \ + no-tests \ + no-ui-console # Rebuilding isn't working with the default target, so we need to clean and build again make clean make -j$(sysctl -n hw.ncpu) $PLATFORM_BUILD_ARGS build_libs diff --git a/mobile/wrapperApp/Status.pro b/mobile/wrapperApp/Status.pro index 4c974aa5397..526338ba62f 100644 --- a/mobile/wrapperApp/Status.pro +++ b/mobile/wrapperApp/Status.pro @@ -2,6 +2,14 @@ TEMPLATE = app QT += quick gui qml webview svg widgets multimedia +# Conditionally add NFC module only if keycard is enabled +contains(DEFINES, FLAG_KEYCARD_ENABLED) { + message("Building with Keycard/NFC support enabled") + QT += nfc +} else { + message("Building WITHOUT Keycard/NFC support (default for development)") +} + equals(QT_MAJOR_VERSION, 6) { message("qt 6 config!!") QT += core5compat core @@ -36,7 +44,10 @@ android { $$PWD/../lib/$$LIB_PREFIX/libDOtherSide$$(LIB_SUFFIX)$$(LIB_EXT) \ $$PWD/../lib/$$LIB_PREFIX/libstatus.so \ $$PWD/../lib/$$LIB_PREFIX/libsds.so \ - $$PWD/../lib/$$LIB_PREFIX/libStatusQ$$(LIB_SUFFIX)$$(LIB_EXT) \ + $$PWD/../lib/$$LIB_PREFIX/libStatusQ$$(LIB_SUFFIX)$$(LIB_EXT) + contains(DEFINES, FLAG_KEYCARD_ENABLED) { + ANDROID_EXTRA_LIBS += $$PWD/../lib/$$LIB_PREFIX/libstatus-keycard-qt.so + } OTHER_FILES += \ $$ANDROID_PACKAGE_SOURCE_DIR/src/app/status/mobile/SecureAndroidAuthentication.java @@ -45,18 +56,34 @@ android { ios { CONFIG += add_ios_ffmpeg_libraries - QMAKE_INFO_PLIST = $$PWD/../ios/Info.plist + QMAKE_INFO_PLIST = $$OUT_PWD/Info.plist QMAKE_IOS_DEPLOYMENT_TARGET=16.0 QMAKE_TARGET_BUNDLE_PREFIX = app.status QMAKE_BUNDLE = mobile QMAKE_ASSET_CATALOGS += $$PWD/../ios/Images.xcassets QMAKE_IOS_LAUNCH_SCREEN = $$PWD/../ios/launch-image-universal.storyboard - LIBS += -L$$PWD/../lib/$$LIB_PREFIX -lnim_status_client -lDOtherSideStatic -lstatusq -lstatus -lsds -lssl_3 -lcrypto_3 -lqzxing -lresolv -lqrcodegen - # --- iOS frameworks required by keychain_apple.mm --- LIBS += -framework LocalAuthentication \ -framework Security \ -framework UIKit \ -framework Foundation + + # Base libraries (always included) + LIBS += -L$$PWD/../lib/$$LIB_PREFIX -lnim_status_client -lDOtherSideStatic -lstatusq -lstatus -lsds -lssl_3 -lcrypto_3 -lqzxing -lresolv -lqrcodegen + + contains(DEFINES, FLAG_KEYCARD_ENABLED) { + # Use entitlements with NFC support (requires paid Apple Developer account) + MY_ENTITLEMENTS.name = CODE_SIGN_ENTITLEMENTS + MY_ENTITLEMENTS.value = $$PWD/../ios/Status.entitlements + QMAKE_MAC_XCODE_SETTINGS += MY_ENTITLEMENTS + + LIBS += -lstatus-keycard-qt -framework CoreNFC + + } else { + # Use entitlements without NFC (allows building with free Apple account) + MY_ENTITLEMENTS.name = CODE_SIGN_ENTITLEMENTS + MY_ENTITLEMENTS.value = $$PWD/../ios/Status-NoKeycard.entitlements + QMAKE_MAC_XCODE_SETTINGS += MY_ENTITLEMENTS + } } diff --git a/vendor/status-keycard-qt b/vendor/status-keycard-qt new file mode 160000 index 00000000000..40f56de84f8 --- /dev/null +++ b/vendor/status-keycard-qt @@ -0,0 +1 @@ +Subproject commit 40f56de84f80f45bccf2ba62fb3eee93196dbc45