- Rust 88.4%
- Kotlin 5.8%
- Python 3.4%
- Shell 1.7%
- Swift 0.5%
- Other 0.1%
|
|
||
|---|---|---|
| .cargo | ||
| .circleci | ||
| .github | ||
| .vscode | ||
| automation | ||
| build-scripts | ||
| components | ||
| docs | ||
| examples | ||
| gradle | ||
| libs | ||
| megazords | ||
| taskcluster | ||
| testing | ||
| tools | ||
| .buildconfig-android.yml | ||
| .cron.yml | ||
| .detekt.yml | ||
| .editorconfig | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| .gitmodules | ||
| .mailmap | ||
| .mergify.yml | ||
| .taskcluster.yml | ||
| build.gradle | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| clippy.toml | ||
| CODE_OF_CONDUCT.md | ||
| COPYRIGHT | ||
| DEPENDENCIES.md | ||
| detekt-baseline.xml | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| install-nimbus-cli.sh | ||
| LICENSE | ||
| license.template | ||
| moz.build | ||
| proguard-rules-consumer-jna.pro | ||
| publish.gradle | ||
| README.md | ||
| rust-toolchain.toml | ||
| settings.gradle | ||
| version.txt | ||
Application Services
This repository contains the fork of application-services used by Tor Browser for Android.
The main differences from this project to the original are a few patches that allow it to be built in tor-browser-build and patches that disable most of the features from application-services either run time or build time.
Structure
tl;dr; It's a bunch of Rust components grouped together in the "megazord" crate and exposed to Android code through auto-generated Kotlin bindings.
The bulk of the logic implemented in application-services is written in Rust and
separated into components. All components are in the /components directory.
This components are gathered in the "megazord" Rust crate, to be conveniently
added into application as a single library. There are multiple "megazord" crates
in /megazord, but the only one we care about is the one under megazords/full.
The features exposed by the megazord have to be accessed from Android applications -- and iOS, but for us that is not supported and thus irrelevant. For that, Kotlin bindings are generated using Uniffi when building each component.
Building
The process to build this project is similar to the original build steps of application-services with a few tweaks.
Note
own documentation at the Application Services Book.
Also, you might want to check the original README in the upstream repository, or have a look at upstream's build instructions.
Setup
uniffi-rs
Before building application-services it's necessary to procure a build of our fork of uniffi-rs. There are two possibilities for that, either you build it yourself:
git clone https://gitlab.torproject.org/tpo/applications/uniffi-rs.git
cd uniffi-rs
cargo build [--release]
Or you can grab a build from https://tb-build-06.torproject.org/~tb-builder/tor-browser-build/out/uniffi-rs/
Toolchain setup
This project requires specific versions of the Android toolchain to be available. The exact versions of each component can be checked in settings.gradle (search for ndkVersion).
Android SDK
After all the required components are downloaded, it is recommended to set the location of the Android SDK in local.properties, like so:
sdk.dir=/path/to/android-sdk
This is recommended because it will always prefer this path, even if building from a different folder with different toolchain defaults -- which is the case when substituting a-s for a local build of tor-browser.
Note
: Usually application-services uses the same SDK and NDK versions as required by tor-browser. When using
./mach bootstrapto download toolchains in tor-browser, you can setsdk.dirto$HOME/.mozbuild/android-sdk-linux:sdk.dir=/home/<you>/.mozbuild/android-sdk-linux
Android NDK
The build expects the ndk to be located inside /path/to/android-sdk/ndk/XX.X.XXXXXX (where XX.X.XXXXXX is the version found in settings.gradle for the NDK).
You can easily find it with this command:
grep ndkVersion settings.gradle
If you are using Firefox's SDK and NDK, you will need to create a symlink to it, as the NDK is not inside the SDK folder, but next to it:
mkdir -p ~/.mozbuild/android-sdk-linux/ndk
cd ~/.mozbuild/android-sdk-linux/ndk
ln -s ../../android-ndk-rXYZ XX.X.XXXXXX
Rust
Make sure all the Android Rust targets are available, before building:
rustup target add aarch64-linux-android
rustup target add x86_64-linux-android
rustup target add armv7-linux-androideabi
rustup target add i686-linux-android
gyp
For some reason, NSS uses the gyp project generator rather than some more common tool such as CMake.
On Linux, you should find it in your distribution:
# Debian, Ubuntu, and derivatives
apt install gyp
# Arch Linux and derivatives
pacman -Sy gyp
On macOS, you can install gyp-next from pip:
python3 -m pip install gyp-next
gyp in turn uses ninja, but it is very likely you already have it in your system.
Build
The first part of the build happens in the libs directory:
cd libs
./build-all.sh desktop
This builds both some dependencies (such as NSS) and the unpatched megazord.
We need to do it, as the no-op version grabs the interfaces to create from the unpatched one.
After that, we need to build NSS for Android:
export ANDROID_HOME=$HOME/.mozbuild/android-sdk-linux/
export ANDROID_NDK_HOME=$HOME/.mozbuild/android-ndk-r29/
export ANDROID_NDK_ROOT=$ANDROID_NDK_HOME
./build-all.sh android
And then the Android bindings:
cd .. # Assuming you were in the libs directory, otherwise go to the repo root.
./gradlew -PuniffiBindgenNoop="/path/to/the/uniffi-bindgen/binary" assemble(Release|Debug)
The uniffi binary is usually .../uniffi-rs/target/release/bindgen.
Note
: the shell won't escape
~, so be sure not to use it to specify this path. Instead you can use$HOME.
Note
: This command can fail when calling
linker-wrapper.shwhich is hardcoded to callpython. If you are in an env with onlypython3it will fail. You can appendenv RUST_ANDROID_GRADLE_PYTHON_COMMAND=python3to the front of this command to tell it to usepython3
If you want to package it:
./gradlew -PuniffiBindgenNoop="/path/to/the/uniffi-bindgen/binary" publish
That will create a new local maven repository in build/maven.
You can merge it to your existing local repo with this command:
cp -R build/maven/org ~/.m2/repository/
Troubleshooting
Cleanup
Just running clean in gradle is not enough, as it will not delete the binaries built with Cargo.
There isn't an official cleanup script for the libs directory.
So, in doubt, you might run rm -rf android desktop.
It might be useful also to remove the various target directories (one is in the root of the repository, the other one is megazords/full/target).
After the cleanup, be sure to re-run also the steps in the libs directory!
Failed to open file .../libmegazord.so
Re-run ./build-all.sh desktop in the libs directory.