feat(android): add native controls and continuous multi-touch
This commit is contained in:
1 parent
3dd96078db
commit
4b12ae7728
70 files changed
+13105
-179
No files matched your search
@@ -0,0 +1,151 @@
|
||||
"""Build the disposable native fixture using an existing Android SDK/JDK only."""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
|
||||
def build(output: Path) -> Path:
|
||||
sdk = Path(
|
||||
os.environ.get("ANDROID_HOME")
|
||||
or os.environ.get("ANDROID_SDK_ROOT")
|
||||
or Path.home() / "AppData/Local/Android/Sdk"
|
||||
)
|
||||
versions = sorted(
|
||||
(sdk / "build-tools").glob("*"),
|
||||
key=lambda p: tuple(int(v) for v in p.name.split(".") if v.isdigit()),
|
||||
)
|
||||
platforms = sorted(
|
||||
(sdk / "platforms").glob("android-*"), key=lambda p: int(p.name.split("-")[-1])
|
||||
)
|
||||
if not versions or not platforms:
|
||||
raise RuntimeError("An existing Android SDK with platform and build-tools is required.")
|
||||
tools = versions[-1]
|
||||
android = platforms[-1] / "android.jar"
|
||||
executable = ".exe" if os.name == "nt" else ""
|
||||
|
||||
def run(*args: object) -> None:
|
||||
subprocess.run([str(arg) for arg in args], check=True, timeout=90)
|
||||
|
||||
java = shutil.which("java")
|
||||
javac = shutil.which("javac")
|
||||
keytool = shutil.which("keytool")
|
||||
if not java or not javac or not keytool:
|
||||
raise RuntimeError("An existing JDK (java, javac and keytool) is required.")
|
||||
output = output.resolve()
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
with tempfile.TemporaryDirectory(prefix="artemis-native-fixture-") as temporary:
|
||||
scratch = Path(temporary)
|
||||
classes = scratch / "classes"
|
||||
classes.mkdir()
|
||||
manifest = scratch / "AndroidManifest.xml"
|
||||
manifest.write_text(
|
||||
"""<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.artemis.fixture">
|
||||
<application android:label="ARTEMIS Native Fixture" android:debuggable="true" android:allowBackup="false" android:theme="@android:style/Theme.Material.Light.NoActionBar">
|
||||
<activity android:name=".MainActivity" android:exported="true" android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
unsigned = scratch / "unsigned.apk"
|
||||
run(
|
||||
tools / ("aapt2" + executable),
|
||||
"link",
|
||||
"-I",
|
||||
android,
|
||||
"--manifest",
|
||||
manifest,
|
||||
"--min-sdk-version",
|
||||
26,
|
||||
"--target-sdk-version",
|
||||
35,
|
||||
"--version-code",
|
||||
1,
|
||||
"--version-name",
|
||||
"1.0",
|
||||
"-o",
|
||||
unsigned,
|
||||
)
|
||||
run(
|
||||
javac,
|
||||
"-encoding",
|
||||
"UTF-8",
|
||||
"-source",
|
||||
8,
|
||||
"-target",
|
||||
8,
|
||||
"-Xlint:-options",
|
||||
"-cp",
|
||||
android,
|
||||
"-d",
|
||||
classes,
|
||||
Path(__file__).with_name("MainActivity.java"),
|
||||
)
|
||||
run(
|
||||
java,
|
||||
"-cp",
|
||||
tools / "lib/d8.jar",
|
||||
"com.android.tools.r8.D8",
|
||||
"--lib",
|
||||
android,
|
||||
"--min-api",
|
||||
26,
|
||||
"--output",
|
||||
scratch,
|
||||
*classes.rglob("*.class"),
|
||||
)
|
||||
with zipfile.ZipFile(unsigned, "a", compression=zipfile.ZIP_DEFLATED) as archive:
|
||||
archive.write(scratch / "classes.dex", "classes.dex")
|
||||
aligned = scratch / "aligned.apk"
|
||||
run(tools / ("zipalign" + executable), "-f", "-p", 4, unsigned, aligned)
|
||||
key = scratch / "fixture.keystore"
|
||||
# Public throwaway debug signing material, never reused for distribution.
|
||||
run(
|
||||
keytool,
|
||||
"-genkeypair",
|
||||
"-keystore",
|
||||
key,
|
||||
"-storepass",
|
||||
"android",
|
||||
"-keypass",
|
||||
"android",
|
||||
"-alias",
|
||||
"fixture",
|
||||
"-keyalg",
|
||||
"RSA",
|
||||
"-validity",
|
||||
365,
|
||||
"-dname",
|
||||
"CN=ARTEMIS Test Fixture",
|
||||
"-noprompt",
|
||||
)
|
||||
run(
|
||||
java,
|
||||
"-jar",
|
||||
tools / "lib/apksigner.jar",
|
||||
"sign",
|
||||
"--ks",
|
||||
key,
|
||||
"--ks-pass",
|
||||
"pass:android",
|
||||
"--key-pass",
|
||||
"pass:android",
|
||||
"--ks-key-alias",
|
||||
"fixture",
|
||||
"--out",
|
||||
output,
|
||||
aligned,
|
||||
)
|
||||
return output
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
print(build(parser.parse_args().output))
|
||||
Reference in new issue
Block a user