Files
firezone/kotlin/android
Thomas Eizinger a4a8221b8b refactor(connlib): explicitly initialise Tun (#5839)
Connlib's routing logic and networking code is entirely platform
agnostic. The only platform-specific bit is how we interact with the TUN
device. From connlib's perspective though, all it needs is an interface
for reading and writing. How the device gets initialised and updated is
client-business.

For the most part, this is the same on all platforms: We call callbacks
and the client updates the state accordingly. The only annoying bit here
is that Android recreates the TUN interface on every update and thus our
old file descriptor is invalid. The current design works around this by
returning the new file descriptor on Android. This is a problematic
design for several reasons:

- It forces the callback handler to finish synchronously, and halting
connlib until this is complete.
- The synchronous nature also means we cannot replace the callbacks with
events as events don't have a return value.

To fix this, we introduce a new `set_tun` method on `Tunnel`. This moves
the business of how the `Tun` device is created up to the client. The
clients are already platform-specific so this makes sense. In a future
iteration, we can move all the various `Tun` implementations all the way
up to the client-specific crates, thus co-locating the platform-specific
code.

Initialising `Tun` from the outside surfaces another issue: The routes
are still set via the `Tun` handle on Windows. To fix this, we introduce
a `make_tun` function on `TunDeviceManager` in order for it to remember
the interface index on Windows and being able to move the setting of
routes to `TunDeviceManager`.

This simplifies several of connlib's APIs which are now infallible.

Resolves: #4473.

---------

Co-authored-by: Reactor Scram <ReactorScram@users.noreply.github.com>
Co-authored-by: conectado <gabrielalejandro7@gmail.com>
2024-07-12 23:54:15 +00:00
..
2024-03-08 01:55:27 +00:00
2024-02-20 15:01:17 -06:00

Firezone Android client

This README contains instructions for building and testing the Android client locally.

Dev Setup

  1. Install Rust

  2. Install Android Studio

  3. Install your JDK 17 of choice. We recommend just updating your CLI environment to use the JDK bundled in Android Studio to ensure you're using the same JDK on the CLI as Android Studio.

  4. Install the Android SDK through Android Studio.

    • Open Android studio, go to Android Studio > Preferences
    • Search for sdk
    • Find the Android SDK nav item under System Settings and select
    • Click the Edit button next to the Android SDK Location field
    • Follow the steps presented to install Android SDK
  5. Install NDK using Android Studio

    To see which version is installed, make sure to select the Show Package Details checkbox in the Android SDK settings page in Android Studio

    Android SDK Tools

    Make sure the correct NDK version is installed by looking at: ../../rust/connlib/clients/android/connlib/build.gradle.kts

  6. Set the following ENV variables in the start up config for your shell:

    JAVA_HOME=/Applications/Android\ Studio.app/Contents/jbr/Contents/Home
    ANDROID_HOME=/Users/<username>/Library/Android/sdk
    NDK_HOME=$ANDROID_HOME/ndk-bundle
    PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin
    
  7. Make sure the following Rust targets are installed into the correct toolchain.

    aarch64-linux-android
    arm-linux-androideabi
    armv7-linux-androideabi
    i686-linux-android
    x86_64-linux-android
    

    Ensure you've activated the correct toolchain version for your local environment with rustup default <toolchain> (find this from the root /rust/rust-toolchain.toml file), then run:

    rustup target add aarch64-linux-android arm-linux-androideabi armv7-linux-androideabi i686-linux-android x86_64-linux-android
    
  8. Perform a test build: ./gradlew assembleDebug.

Release Setup

We release from GitHub CI, so this shouldn't be necessary. But if you're looking to test the release variant locally:

  1. Download the keystore from 1Pass and save to app/.signing/keystore.jks dir.
  2. Download firebase credentials from 1Pass and save to app/.signing/firebase.json
  3. Now you can execute the *Release tasks with:
export KEYSTORE_PATH="$(pwd)/app/.signing/keystore.jks"
export FIREBASE_CREDENTIALS_PATH="$(pwd)/app/.signing/firebase.json"
HISTCONTROL=ignorespace # prevents saving the next line in shell history
 KEYSTORE_PASSWORD='keystore_password' KEYSTORE_KEY_PASSWORD='keystore_key_password' ./gradlew assembleRelease