Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
ae0063f
create BaseSystemBridge
sds100 Nov 3, 2025
9e7589d
create separate evdev module
sds100 Nov 3, 2025
34f5a2d
setup Rust project for evdev_manager
sds100 Nov 3, 2025
bb28631
Merge branch 'develop' into rust-system-bridge
sds100 Nov 11, 2025
d882b94
#1897 create boilerplate code for Rust evdev manager
sds100 Nov 12, 2025
bce9b3d
#1897 create C wrapper for KeyLayoutMap
sds100 Nov 12, 2025
325facb
style: reformat
sds100 Nov 15, 2025
d122e26
#1897 manage the IEvdevCallback in C++ with JNI world and expose simp…
sds100 Nov 15, 2025
5bf7870
#1897 WIP: refactor libevdev_jni.cpp into Rust
sds100 Nov 15, 2025
0df08c8
#1897 skip rustfmt for bindings
sds100 Nov 15, 2025
252f48e
#1897 WIP: use tokio tasks for reading evdev devices
sds100 Nov 15, 2025
9530bb7
#1897 WIP: parse key layout files with Rust
sds100 Nov 15, 2025
d07cb7e
#1897 skip rustfmt for bindings
sds100 Nov 15, 2025
25fe47b
#1897 create android_codes.rs
sds100 Nov 15, 2025
428a36a
#1897 create crate based off evdev_rs
sds100 Nov 15, 2025
ce1e8d9
#1897 WIP: fix errors and clean up AI generated code
sds100 Nov 15, 2025
001b8a2
Merge branch 'rust-keylayoutmap' into 1897-rust-system-bridge
sds100 Nov 15, 2025
bc6755e
#1897 WIP: fix compilation errors and refactor
sds100 Nov 17, 2025
1efe624
#1897 WIP: refactor and remove tokio code
sds100 Nov 17, 2025
00adf3c
#1897 WIP: use mio for evdev event loop
sds100 Nov 18, 2025
6b7324a
Merge branch 'develop' into 1897-rust-system-bridge
sds100 Nov 20, 2025
0d636cf
fix: do not show usb mode warning on rooted system bridge
sds100 Nov 20, 2025
3f8903a
#1897 WIP: proof of concept mio epoll event loop works in rust
sds100 Nov 20, 2025
b9c03ec
#1897 comment out evdevcallback_binder_observer
sds100 Nov 21, 2025
b80af19
#1897 add mio token to GrabbedDevice struct
sds100 Nov 21, 2025
a2e5c14
#1897 fix key layout map tests
sds100 Nov 21, 2025
e2881fd
#1897 refactor evdev_manager into separate core and jni crates so tes…
sds100 Nov 21, 2025
e629fa3
#1897 fix and write input_event_lookup.rs tests
sds100 Nov 21, 2025
6d5eafa
#1897 fix key layout map tests
sds100 Nov 21, 2025
9eb7f35
#1897 fix some style warnings in evdev_callback_binder_observer.rs
sds100 Nov 21, 2025
cd78c1b
#1897 format rust on commit
sds100 Nov 21, 2025
dd43974
#1897 WIP: use tokio to run evdev event loop
sds100 Nov 22, 2025
cec8d73
#1897 almost working tokio implementation of epoll and grabbing devices
sds100 Nov 22, 2025
510ae06
#1897 block with timeout for evdev loop to start
sds100 Nov 22, 2025
35205bb
#1897 working epoll with tokio
sds100 Nov 22, 2025
e4fb257
#1897 fix bugs starting/stopping the evdev event loop
sds100 Nov 22, 2025
8e153d4
#1897 rust system bridge WIP
sds100 Nov 25, 2025
e13732a
Merge branch 'develop' into 1897-rust-system-bridge
sds100 Nov 25, 2025
70b1815
#1897 rust system bridge compiles with more jni methods completed
sds100 Nov 25, 2025
aa3a017
#1897 fix linking issue with c++ static library
sds100 Nov 25, 2025
d9b1170
#1897 just use JNI for the evdev callback
sds100 Nov 26, 2025
55c2465
#1897 implement grabbing and ungrabbing
sds100 Nov 26, 2025
f007a62
#1897 fix reading evdev events
sds100 Nov 26, 2025
c1b1738
#1897 put grabbed_devices in EventLoopManager
sds100 Nov 26, 2025
a3b86e6
#1897 fix various race conditions in the event loop
sds100 Nov 27, 2025
2f405cc
#1897 WIP: refactor grabbing evdev devices
sds100 Nov 28, 2025
ec55019
#1897 WIP: refactor grabbing evdev devices
sds100 Nov 28, 2025
6c153dc
#1897 refactor Rust event loop to use a single method for setting the…
sds100 Nov 28, 2025
6027e6c
#1897 only listen to connected input devices if system bridge is conn…
sds100 Nov 28, 2025
3500bd7
#1897 do not open evdev devices with write permission because only pe…
sds100 Nov 28, 2025
578e1a7
#1897 fix rust code style
sds100 Nov 28, 2025
aba55a0
#1897 run Rust tests and format check in GitHub actions and fastlane
sds100 Nov 28, 2025
fb809bb
#1897 style: remove unused import in build.gradle
sds100 Nov 28, 2025
dd36ea8
#1897 ci: setup Android NDK
sds100 Nov 28, 2025
d3c553a
Merge branch 'develop' into 1897-rust-system-bridge
sds100 Nov 28, 2025
499fd6d
#1897 fix tests
sds100 Nov 28, 2025
9150447
#1897 use NDK version in Ubuntu 24.04 github actions runner
sds100 Nov 28, 2025
1e0a218
#1897 fix build issues with 32 bit toolchain
sds100 Nov 28, 2025
03f4300
ci: do not setup Android SDK in github actions because the runner alr…
sds100 Nov 28, 2025
868f719
ci: setup all the Android rust targets
sds100 Nov 28, 2025
58238e1
#1897 log the evdev device path when failing to open
sds100 Nov 28, 2025
0178f17
#1897 fix: do not lock up when handling power button emergency kill
sds100 Nov 28, 2025
3433950
#1897 attach permanently to JNI thread from event loop
sds100 Nov 28, 2025
4c84c29
#1897 add proguard rules for AIDL parcelables
sds100 Nov 28, 2025
147e401
chore: bump version code
sds100 Nov 28, 2025
9264153
fastlane: run format checks and tests before asking for passwords
sds100 Nov 28, 2025
686278a
#1897 only build arm64 cargo for debug builds to reduce build time
sds100 Nov 28, 2025
2e6f61a
fix: do not crash when Shizuku is connected on Android 10 or older
sds100 Nov 28, 2025
d10e587
#1897 use constant for RequiresApi annotation on SystemBridgeConnecti…
sds100 Nov 28, 2025
cc938c3
#1897 update command for why system bridge only supports Android 10+
sds100 Nov 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 51 additions & 6 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ jobs:
java-version: 17
cache: 'gradle'

- name: Setup Android SDK
uses: android-actions/setup-android@v2

- name: Unit tests
run: bash ./gradlew testDebugUnitTest

Expand All @@ -46,12 +43,48 @@ jobs:
java-version: 17
cache: 'gradle'

- name: Setup Android SDK
uses: android-actions/setup-android@v2

- name: Ktlint check
run: ./gradlew ktlintCheck

rust:
name: Rust code style and tests
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Install Android Rust targets
run: |
rustup target add armv7-linux-androideabi
rustup target add aarch64-linux-android
rustup target add i686-linux-android
rustup target add x86_64-linux-android

- uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
evdev/src/main/rust/evdev_manager/target/
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-rust-

- name: Check Rust formatting
working-directory: evdev/src/main/rust/evdev_manager
run: cargo fmt --check

- name: Run Rust tests
working-directory: evdev/src/main/rust/evdev_manager
run: cargo test --package evdev_manager_core

apk:
name: Build APK
runs-on: ubuntu-latest
Expand All @@ -77,6 +110,18 @@ jobs:

- name: Setup Android SDK
uses: android-actions/setup-android@v2
with:
ndk-version: "27.2.12479018"

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Install Android Rust targets
run: |
rustup target add armv7-linux-androideabi
rustup target add aarch64-linux-android
rustup target add i686-linux-android
rustup target add x86_64-linux-android

- name: set up Ruby for fastlane
uses: ruby/setup-ruby@v1
Expand Down
57 changes: 51 additions & 6 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ jobs:
java-version: 17
cache: 'gradle'

- name: Setup Android SDK
uses: android-actions/setup-android@v2

- name: Unit tests
run: bash ./gradlew testDebugUnitTest

Expand All @@ -52,12 +49,48 @@ jobs:
java-version: 17
cache: 'gradle'

- name: Setup Android SDK
uses: android-actions/setup-android@v2

- name: Ktlint check
run: ./gradlew ktlintCheck

rust:
name: Rust code style and tests
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Install Android Rust targets
run: |
rustup target add armv7-linux-androideabi
rustup target add aarch64-linux-android
rustup target add i686-linux-android
rustup target add x86_64-linux-android

- uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
evdev/src/main/rust/evdev_manager/target/
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-rust-

- name: Check Rust formatting
working-directory: evdev/src/main/rust/evdev_manager
run: cargo fmt --check

- name: Run Rust tests
working-directory: evdev/src/main/rust/evdev_manager
run: cargo test --package evdev_manager_core

apk:
name: Generate and upload APK to Discord
runs-on: ubuntu-latest
Expand Down Expand Up @@ -89,6 +122,18 @@ jobs:

- name: Setup Android SDK
uses: android-actions/setup-android@v2
with:
ndk-version: "27.2.12479018"

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Install Android Rust targets
run: |
rustup target add armv7-linux-androideabi
rustup target add aarch64-linux-android
rustup target add i686-linux-android
rustup target add x86_64-linux-android

- name: set up Ruby for fastlane
uses: ruby/setup-ruby@v1
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ dependencies {
implementation(project(":data"))
implementation(project(":sysbridge"))
implementation(project(":system"))
implementation(project(":evdev"))
compileOnly(project(":systemstubs"))

coreLibraryDesugaring(libs.desugar.jdk.libs)
Expand Down
5 changes: 3 additions & 2 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@

# Keep all AIDL interface classes and their methods
-keep class io.github.sds100.keymapper.sysbridge.ISystemBridge** { *; }
-keep class io.github.sds100.keymapper.sysbridge.IEvdevCallback** { *; }
-keep class io.github.sds100.keymapper.evdev.IEvdevCallback** { *; }
-keep class io.github.sds100.keymapper.sysbridge.IShizukuStarterService** { *; }

-keepclassmembers class io.github.sds100.keymapper.sysbridge.shizuku.ShizukuStarterService {
Expand All @@ -138,7 +138,8 @@
-keep class io.github.sds100.keymapper.sysbridge.** extends android.content.ContentProvider { *; }

# Keep parcelable classes used in AIDL
-keep class io.github.sds100.keymapper.common.models.EvdevDeviceHandle { *; }
-keep class io.github.sds100.keymapper.common.models.GrabbedDeviceHandle { *; }
-keep class io.github.sds100.keymapper.common.models.EvdevDeviceInfo { *; }

# Keep all rikka.hidden classes and interfaces as they contain AIDL files
-keep class rikka.hidden.** { *; }
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<!-- This is required because sysbridge has a min sdk of 29 since it depends
on the binder-ndk library. Building will fail without this because the min sdk
of the app is 26.-->
<uses-sdk tools:overrideLibrary="io.github.sds100.keymapper.sysbridge" />
<uses-sdk tools:overrideLibrary="io.github.sds100.keymapper.sysbridge, io.github.sds100.keymapper.evdev" />

<application
android:name="io.github.sds100.keymapper.KeyMapperApp"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.github.sds100.keymapper.sysbridge.service

import android.os.Looper

class SystemBridge : BaseSystemBridge() {

companion object {
@JvmStatic
fun main(args: Array<String>) {
@Suppress("DEPRECATION")
Looper.prepareMainLooper()
SystemBridge()
Looper.loop()
}
}
}
2 changes: 1 addition & 1 deletion app/version.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
VERSION_NAME=5.0.0-alpha
VERSION_CODE=197
VERSION_CODE=198
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import io.github.sds100.keymapper.data.repositories.PreferenceRepository
import io.github.sds100.keymapper.system.popup.ToastAdapter
import io.github.sds100.keymapper.system.vibrator.VibratorAdapter
import io.github.sds100.keymapper.system.volume.VolumeAdapter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
Expand All @@ -49,17 +48,12 @@ class DetectKeyMapsUseCaseImpl @AssistedInject constructor(
private val toastAdapter: ToastAdapter,
private val resourceProvider: ResourceProvider,
private val vibrator: VibratorAdapter,
@Assisted
private val coroutineScope: CoroutineScope,
private val inputEventHub: InputEventHub,
) : DetectKeyMapsUseCase {

@AssistedFactory
interface Factory {
fun create(
accessibilityService: IAccessibilityService,
coroutineScope: CoroutineScope,
): DetectKeyMapsUseCaseImpl
fun create(accessibilityService: IAccessibilityService): DetectKeyMapsUseCaseImpl
}

companion object {
Expand Down Expand Up @@ -228,15 +222,15 @@ class DetectKeyMapsUseCaseImpl @AssistedInject constructor(
}
}

override fun imitateEvdevEvent(devicePath: String, type: Int, code: Int, value: Int) {
override fun imitateEvdevEvent(deviceId: Int, type: Int, code: Int, value: Int) {
if (inputEventHub.isSystemBridgeConnected()) {
Timber.d(
"Imitate evdev event, device path: $devicePath, type: $type, code: $code, value: $value",
"Imitate evdev event, device id: $deviceId, type: $type, code: $code, value: $value",
)
inputEventHub.injectEvdevEvent(devicePath, type, code, value)
inputEventHub.injectEvdevEvent(deviceId, type, code, value)
} else {
Timber.w(
"Cannot imitate evdev event without system bridge connected. Device path: $devicePath, type: $type, code: $code, value: $value",
"Cannot imitate evdev event without system bridge connected.",
)
}
}
Expand Down Expand Up @@ -268,5 +262,5 @@ interface DetectKeyMapsUseCase {
source: Int = InputDevice.SOURCE_UNKNOWN,
)

fun imitateEvdevEvent(devicePath: String, type: Int, code: Int, value: Int)
fun imitateEvdevEvent(deviceId: Int, type: Int, code: Int, value: Int)
}
Original file line number Diff line number Diff line change
Expand Up @@ -648,13 +648,8 @@ class KeyMapAlgorithm(
val event = EvdevEventAlgo(
keyCode = inputEvent.androidCode,
clickType = null,
devicePath = inputEvent.device.path,
device = EvdevDeviceInfo(
name = inputEvent.device.name,
bus = inputEvent.device.bus,
vendor = inputEvent.device.vendor,
product = inputEvent.device.product,
),
deviceId = inputEvent.deviceId,
device = inputEvent.deviceInfo,
scanCode = inputEvent.code,
)

Expand Down Expand Up @@ -1490,14 +1485,14 @@ class KeyMapAlgorithm(
)
} else if (event is EvdevEventAlgo) {
useCase.imitateEvdevEvent(
devicePath = event.devicePath,
deviceId = event.deviceId,
KMEvdevEvent.TYPE_KEY_EVENT,
event.scanCode,
KMEvdevEvent.VALUE_DOWN,
)

useCase.imitateEvdevEvent(
devicePath = event.devicePath,
deviceId = event.deviceId,
KMEvdevEvent.TYPE_KEY_EVENT,
event.scanCode,
KMEvdevEvent.VALUE_UP,
Expand Down Expand Up @@ -1544,20 +1539,20 @@ class KeyMapAlgorithm(
} else if (event is EvdevEventAlgo) {
if (imitateUpKeyEvent) {
useCase.imitateEvdevEvent(
devicePath = event.devicePath,
deviceId = event.deviceId,
type = KMEvdevEvent.TYPE_KEY_EVENT,
code = event.scanCode,
value = KMEvdevEvent.VALUE_UP,
)
} else {
useCase.imitateEvdevEvent(
devicePath = event.devicePath,
deviceId = event.deviceId,
type = KMEvdevEvent.TYPE_KEY_EVENT,
code = event.scanCode,
value = KMEvdevEvent.VALUE_DOWN,
)
useCase.imitateEvdevEvent(
devicePath = event.devicePath,
deviceId = event.deviceId,
type = KMEvdevEvent.TYPE_KEY_EVENT,
code = event.scanCode,
value = KMEvdevEvent.VALUE_UP,
Expand Down Expand Up @@ -1944,7 +1939,7 @@ class KeyMapAlgorithm(
}

private data class EvdevEventAlgo(
val devicePath: String,
val deviceId: Int,
val device: EvdevDeviceInfo,
val scanCode: Int,
val keyCode: Int,
Expand Down
Loading
Loading