From c0d040a78083557a1625b32689c639d7594ed95a Mon Sep 17 00:00:00 2001 From: nift4 Date: Thu, 1 Aug 2024 22:14:29 +0200 Subject: [PATCH] simulator io support --- app/src/main/cpp/app.cpp | 4 +- app/src/main/cpp/droidboot_gui | 2 +- .../main/java/org/andbootmgr/app/Simulator.kt | 113 ++++++++++++++++++ .../org/andbootmgr/app/util/RootFsService.kt | 12 ++ 4 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/org/andbootmgr/app/util/RootFsService.kt diff --git a/app/src/main/cpp/app.cpp b/app/src/main/cpp/app.cpp index 00a6052a..4fdf8f40 100644 --- a/app/src/main/cpp/app.cpp +++ b/app/src/main/cpp/app.cpp @@ -4,7 +4,7 @@ #include -extern "C" void simulator_start(JNIEnv* env, jobject bitmap, jint w, jint h); +extern "C" void simulator_start(JNIEnv* env, jobject thiz, jobject bitmap, jint w, jint h); extern "C" void simulator_stop(JNIEnv* env); extern "C" void simulator_key(jint key); @@ -17,5 +17,5 @@ extern "C" JNIEXPORT void JNICALL Java_org_andbootmgr_app_Simulator_stop(JNIEnv* } extern "C" JNIEXPORT void JNICALL Java_org_andbootmgr_app_Simulator_start(JNIEnv* env, jobject thiz, jobject bitmap, jint w, jint h) { - simulator_start(env, bitmap, w, h); + simulator_start(env, thiz, bitmap, w, h); } \ No newline at end of file diff --git a/app/src/main/cpp/droidboot_gui b/app/src/main/cpp/droidboot_gui index 30ebee1b..53f82146 160000 --- a/app/src/main/cpp/droidboot_gui +++ b/app/src/main/cpp/droidboot_gui @@ -1 +1 @@ -Subproject commit 30ebee1b42dbf609939f7d09f6c9c64e4cb6d9ec +Subproject commit 53f821466c8e7a1bd2e6476ab9def1f9f382ce90 diff --git a/app/src/main/java/org/andbootmgr/app/Simulator.kt b/app/src/main/java/org/andbootmgr/app/Simulator.kt index e72cd850..a710d64a 100644 --- a/app/src/main/java/org/andbootmgr/app/Simulator.kt +++ b/app/src/main/java/org/andbootmgr/app/Simulator.kt @@ -8,6 +8,15 @@ import android.view.View import android.view.ViewGroup import android.widget.LinearLayout import androidx.appcompat.app.AppCompatActivity +import com.topjohnwu.superuser.Shell +import com.topjohnwu.superuser.io.SuFile +import com.topjohnwu.superuser.io.SuFileInputStream +import com.topjohnwu.superuser.nio.ExtendedFile +import java.io.EOFException +import java.io.File +import java.io.IOException +import java.io.InputStream +import java.util.Arrays import kotlin.math.min @@ -22,12 +31,14 @@ class Simulator : AppCompatActivity() { private lateinit var bitmap: Bitmap private var w: Int = 0 private var h: Int = 0 + private lateinit var f: File override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) w = 1080 h = 1920 bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888) + f = File("/dev/block/mmcblk1") val l = LinearLayout(this) l.addView(object : View(this) { override fun onDraw(canvas: Canvas) { @@ -57,4 +68,106 @@ class Simulator : AppCompatActivity() { start() } } + + private fun blockCount(): Long { + return Shell.cmd("blockdev --getsz ${f.absolutePath}").exec().out.join("\n").toLong().also { + Log.i("Simulator", "block count: $it") + } + } + + private fun readBlocks(offset: Long, count: Int): ByteArray { + val fo = SuFileInputStream.open(f) + fo.skipNBytesSupport(offset) + val b = fo.readNBytesSupport(count)!! + fo.close() + return b + } + + @Throws(IOException::class) + private fun InputStream.skipNBytesSupport(nn: Long) { + var n = nn + while (n > 0) { + val ns: Long = skip(n) + if (ns in 1..n) { + // adjust number to skip + n -= ns + } else if (ns == 0L) { // no bytes skipped + // read one byte to check for EOS + if (read() == -1) { + throw EOFException() + } + // one byte read so decrement number to skip + n-- + } else { // skipped negative or too many bytes + throw IOException("Unable to skip exactly") + } + } + } + + @Throws(IOException::class) + fun InputStream.readNBytesSupport(len: Int): ByteArray? { + require(len >= 0) { "len < 0" } + + var bufs: MutableList? = null + var result: ByteArray? = null + var total = 0 + var remaining = len + var n: Int + do { + var buf = ByteArray( + min(remaining, 8192) + ) + var nread = 0 + + // read to EOF which may read more or less than buffer size + while ((read( + buf, nread, + min((buf.size - nread), remaining) + ).also { n = it }) > 0 + ) { + nread += n + remaining -= n + } + + if (nread > 0) { + if (8192 - total < nread) { + throw OutOfMemoryError("Required array size too large") + } + if (nread < buf.size) { + buf = Arrays.copyOfRange(buf, 0, nread) + } + total += nread + if (result == null) { + result = buf + } else { + if (bufs == null) { + bufs = ArrayList() + bufs.add(result) + } + bufs.add(buf) + } + } + // if the last call to read returned -1 or the number of bytes + // requested have been read then break + } while (n >= 0 && remaining > 0) + + if (bufs == null) { + if (result == null) { + return ByteArray(0) + } + return if (result.size == total) result else result.copyOf(total) + } + + result = ByteArray(total) + var offset = 0 + remaining = total + for (b in bufs) { + val count = min(b.size.toDouble(), remaining.toDouble()).toInt() + System.arraycopy(b, 0, result, offset, count) + offset += count + remaining -= count + } + + return result + } } \ No newline at end of file diff --git a/app/src/main/java/org/andbootmgr/app/util/RootFsService.kt b/app/src/main/java/org/andbootmgr/app/util/RootFsService.kt new file mode 100644 index 00000000..41a90782 --- /dev/null +++ b/app/src/main/java/org/andbootmgr/app/util/RootFsService.kt @@ -0,0 +1,12 @@ +package org.andbootmgr.app.util + +import android.content.Intent +import android.os.IBinder +import com.topjohnwu.superuser.ipc.RootService +import com.topjohnwu.superuser.nio.FileSystemManager + +class RootFsService : RootService() { + override fun onBind(intent: Intent): IBinder { + return FileSystemManager.getService() + } +} \ No newline at end of file