Fixed Android 10 and x86_64 support

This commit is contained in:
Dominic Letz 2021-09-15 18:20:53 +02:00
parent 138a39d306
commit 3a0fb5a3c0
10 changed files with 53 additions and 31 deletions

View file

@ -14,10 +14,6 @@ This Android Studio project wraps the [Desktop Sample App](https://github.com/el
## Known todos
### The x86_64 emulator does not work
So you've got to run on your phone or you the slow ARM emulator. If you have an idea how to fix the issue. Please send a pull request to the [Desktop Runtime](https://github.com/elixir-desktop/runtimes) project.
### Initial Startup time is slow
Running the app for the first time it will extract the full Elixir & App runtime at start. On my Phone this takes anywhere from 10-20 seconds. After that the startup is releatively quick.

View file

@ -23,7 +23,7 @@ android {
versionName "1.0"
ndk {
abiFilters "armeabi-v7a", "arm64-v8a" // , "x86_64" -- currently not working
abiFilters "armeabi-v7a", "arm64-v8a" , "x86_64"
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -59,6 +59,8 @@ android {
}
dependencies {
implementation fileTree(dir: "libs", include: '*.jar')
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
@ -67,4 +69,4 @@ dependencies {
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
}

BIN
app/libs/erlang.jar Normal file

Binary file not shown.

View file

@ -11,7 +11,8 @@
android:usesCleartextTraffic="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Default">
android:theme="@style/Theme.Default"
android:extractNativeLibs="true">
<activity android:name="io.elixirdesktop.example.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Binary file not shown.

Binary file not shown.

View file

@ -55,28 +55,27 @@ const char* startErlang(std::string root_dir, std::string log_dir)
if (!app_version) ERROR("Could not idenfity app version in start_erl.data file");
std::string bin_dir = root_dir + "erts-" + erts_version + "/bin/";
std::string bin_dir = getenv("BINDIR");
// keeping it static to keep the environment variable alive
static std::string env_bin_dir = std::string("BINDIR=").append(bin_dir);
char *path = getenv("PATH");
// keeping it static to keep the environment variable alive
static std::string env_path = std::string("PATH=").append(path).append(":").append(bin_dir);
chdir(root_dir.c_str());
putenv((char *)env_bin_dir.c_str());
putenv((char *)env_path.c_str());
start_logger();
// does not work on android
std::string liberlang = getenv("LIBERLANG");
// RTLD_GLOBAL does not work on android
// https://android-ndk.narkive.com/iNWj05IV/weak-symbol-linking-when-loading-dynamic-libraries
// https://android.googlesource.com/platform/bionic/+/30b17e32f0b403a97cef7c4d1fcab471fa316340/linker/linker_namespaces.cpp#100
std::string liberlang = bin_dir + "liberlang.so";
void* lib = dlopen(liberlang.c_str(), RTLD_NOW | RTLD_GLOBAL);
if (!lib) ERROR("Failed opening liberlang.so\n")
std::string nif = root_dir + "lib/exqlite-0.5.1/priv/sqlite3_nif.so";
test_nif(nif);
// std::string nif = root_dir + "lib/exqlite-0.5.1/priv/sqlite3_nif.so";
// test_nif(nif);
startfun = (void (*)(int, char**)) dlsym(lib, "erl_start");
if (!startfun) ERROR("Failed loading erlang startfun\n")
@ -97,7 +96,7 @@ const char* startErlang(std::string root_dir, std::string log_dir)
"-sbwt",
"none",
"--",
"-init_debug",
// "-init_debug",
"-root",
root_dir.c_str(),
"-progname",

View file

@ -6,7 +6,6 @@ import android.system.Os
import android.util.Log
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import org.json.JSONArray
import java.net.ServerSocket
import java.net.Socket
@ -39,7 +38,7 @@ class Bridge(private val applicationContext : Context, private var webview : Web
var prefix = ""
for (abi in Build.SUPPORTED_ABIS) {
when (abi) {
"arm64-v8a", "armeabi-v7a" -> { //, "x86_64" -> {
"arm64-v8a", "armeabi-v7a", "x86_64" -> {
prefix = abi
break
}
@ -57,16 +56,39 @@ class Bridge(private val applicationContext : Context, private var webview : Web
val runtime = "$prefix-runtime.zip"
Log.d("RUNTIME", runtime)
val lastUpdateTime: Long = applicationContext.packageManager
.getPackageInfo(applicationContext.packageName, 0).lastUpdateTime / 1000
thread(start = true) {
val assets = applicationContext.assets.list("")
val packageInfo = applicationContext.packageManager
.getPackageInfo(applicationContext.packageName, 0)
val nativeDir = packageInfo.applicationInfo.nativeLibraryDir
val lastUpdateTime: Long = packageInfo.lastUpdateTime / 1000
val releasedir = applicationContext.filesDir.absolutePath + "/build-${lastUpdateTime}"
var bindir = "$releasedir/bin"
Os.setenv("BINDIR", bindir, false);
Os.setenv("LIBERLANG", "$nativeDir/liberlang.so", false);
val donefile = File("$releasedir/done")
if (!donefile.exists()) {
// Creating symlinks for binaries
// https://github.com/JeromeDeBretagne/erlanglauncher/issues/2
File(bindir).mkdirs()
for (file in File(nativeDir).list()) {
if (file.startsWith("lib__")) {
var name = File(file).name
name = name.substring(5, name.length - 3)
Log.d("BIN", "$nativeDir/$file -> $bindir/$name")
Os.symlink("$nativeDir/$file", "$bindir/$name")
}
}
if (unpackZip(releasedir, applicationContext.assets.open("app.zip")) &&
unpackZip(releasedir, applicationContext.assets.open(runtime))) {
val assets = applicationContext.assets.list("")
for (lib in File("$releasedir/lib").list()) {
val parts = lib.split("-")
val name = parts[0]
@ -126,10 +148,7 @@ class Bridge(private val applicationContext : Context, private var webview : Web
}
Log.d("FILE", fullpath)
var isBinary = filename.contains("/bin/") || filename.endsWith(".so")
val fout = FileOutputStream(fullpath)
var count = zis.read(buffer)
while (count != -1) {
fout.write(buffer, 0, count)
@ -137,12 +156,6 @@ class Bridge(private val applicationContext : Context, private var webview : Web
}
fout.close()
if (isBinary) {
File(fullpath).setExecutable(true)
}
zis.closeEntry()
ze = zis.nextEntry
}
@ -201,12 +214,23 @@ class Bridge(private val applicationContext : Context, private var webview : Web
webview.post { webview.loadUrl(lastURL) }
}
val response = ref + "use_mock".toByteArray()
var response = ref
response += if (method == ":getOsDescription") {
val info = "Android ${Build.DEVICE} ${Build.BRAND} ${Build.VERSION.BASE_OS} ${Build.SUPPORTED_ABIS.joinToString(",")}"
stringToList(info).toByteArray()
} else {
"use_mock".toByteArray()
}
writer.writeInt(response.size)
writer.write(response)
}
}
private fun stringToList(str : String): String {
val numbers = str.toByteArray().map { it.toInt().toString() }
return "[${numbers.joinToString(",")}]"
}
/**
* A native method that is implemented by the 'native-lib' native library,
@ -220,4 +244,4 @@ class Bridge(private val applicationContext : Context, private var webview : Web
System.loadLibrary("native-lib")
}
}
}
}