Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 13 additions & 4 deletions Android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ android {
vectorDrawables {
useSupportLibrary = true
}

ndk {
abiFilters += listOf("arm64-v8a")
}
}

signingConfigs {
Expand Down Expand Up @@ -185,6 +189,15 @@ android {
compose = true
}

externalNativeBuild {
cmake {
path = file("src/main/cpp/CMakeLists.txt")
version = "3.22.1+"
}
}

ndkVersion = "26.1.10909125"

composeOptions {
kotlinCompilerExtensionVersion = "1.5.8"
}
Expand Down Expand Up @@ -299,10 +312,6 @@ dependencies {
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")

// Root execution - libsu
implementation("com.github.topjohnwu.libsu:core:5.2.1")
implementation("com.github.topjohnwu.libsu:service:5.2.1")
implementation("com.github.topjohnwu.libsu:io:5.2.1")

// Coroutines - latest version for better performance
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
Expand Down
Binary file not shown.
Binary file added Android/app/src/main/assets/binaries/runner-armhf
Binary file not shown.
Binary file added Android/app/src/main/assets/binaries/runner-x86
Binary file not shown.
Binary file not shown.
148 changes: 148 additions & 0 deletions Android/app/src/main/cpp/android.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Droidspaces v6 - High-performance Container Runtime
*
* Copyright (C) 2026 ravindu644 <droidcasts@protonmail.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/

#include "droidspace.h"

/* ---------------------------------------------------------------------------
* Android detection
* ---------------------------------------------------------------------------*/

int is_android(void) {
static int cached_result = -1;
if (cached_result != -1)
return cached_result;

/* Priority 1: Check for recovery environment (e.g., TWRP) */
if (access("/system/bin/recovery", F_OK) == 0) {
cached_result = 0;
}
/* Priority 2: Check for core Android system markers */
else if (access("/system/build.prop", F_OK) == 0 ||
access("/system/bin/app_process", F_OK) == 0) {
cached_result = 1;
}
/* Fallback: Not a standard Android environment */
else {
cached_result = 0;
}

return cached_result;
}

/* ---------------------------------------------------------------------------
* Android optimizations
* ---------------------------------------------------------------------------*/

void android_optimizations(int enable) {
if (!is_android())
return;

if (enable) {
ds_log("Applying Android system optimizations...");
char *args1[] = {"cmd",
"device_config",
"put",
"activity_manager",
"max_phantom_processes",
"2147483647",
NULL};
run_command_quiet(args1);
char *args2[] = {"cmd", "device_config", "set_sync_disabled_for_tests",
"persistent", NULL};
run_command_quiet(args2);
char *args3[] = {"dumpsys", "deviceidle", "disable", NULL};
run_command_quiet(args3);
} else {
char *args1[] = {"cmd",
"device_config",
"put",
"activity_manager",
"max_phantom_processes",
"32",
NULL};
run_command_quiet(args1);
char *args2[] = {"cmd", "device_config", "set_sync_disabled_for_tests",
"none", NULL};
run_command_quiet(args2);
char *args3[] = {"dumpsys", "deviceidle", "enable", NULL};
run_command_quiet(args3);
}
}

/* ---------------------------------------------------------------------------
* Data partition remount (for suid support)
* ---------------------------------------------------------------------------*/

void android_remount_data_suid(void) {
if (!is_android())
return;

ds_log("Ensuring /data is mounted with suid support...");
/* On some Android versions, /data is mounted nosuid. We need suid for
* sudo/su/ping within the container if it's stored on /data. */
char *args[] = {"mount", "-o", "remount,suid", "/data", NULL};
if (run_command_quiet(args) != 0) {
ds_warn(
"Failed to remount /data with suid support. su/sudo might not work.");
}
}

/* ---------------------------------------------------------------------------
* Storage
* ---------------------------------------------------------------------------*/

int android_setup_storage(const char *rootfs_path) {
if (!is_android()) {
return 0;
}

if (!rootfs_path) {
ds_warn("android_setup_storage called with NULL rootfs_path");
return -1;
}

struct stat st;

if (stat(DS_ANDROID_STORAGE_PATH, &st) < 0 || !S_ISDIR(st.st_mode) ||
access(DS_ANDROID_STORAGE_PATH, R_OK) < 0) {
ds_warn("Android storage not found or not readable at %s",
DS_ANDROID_STORAGE_PATH);
return -1;
}

/* Create target directories inside rootfs: storage/, storage/emulated/,
* storage/emulated/0 */
char path[PATH_MAX];
int ret;

ret = snprintf(path, sizeof(path), "%s/storage", rootfs_path);
if (ret < 0 || (size_t)ret >= sizeof(path))
return -1;
if (mkdir(path, 0755) < 0 && errno != EEXIST)
return -1;

ret = snprintf(path, sizeof(path), "%s/storage/emulated", rootfs_path);
if (ret < 0 || (size_t)ret >= sizeof(path))
return -1;
if (mkdir(path, 0755) < 0 && errno != EEXIST)
return -1;

ret = snprintf(path, sizeof(path), "%s" DS_ANDROID_STORAGE_PATH, rootfs_path);
if (ret < 0 || (size_t)ret >= sizeof(path))
return -1;
if (mkdir(path, 0755) < 0 && errno != EEXIST)
return -1;

ds_log("Mounting Android internal storage to " DS_ANDROID_STORAGE_PATH "...");
if (mount(DS_ANDROID_STORAGE_PATH, path, NULL, MS_BIND | MS_REC, NULL) < 0) {
ds_warn("Failed to bind-mount Android storage %s -> %s: %s",
DS_ANDROID_STORAGE_PATH, path, strerror(errno));
return -1;
}

return 0;
}
Loading