Wow, is that a proper Android build system?
[tripe-android] / toy-activity.scala
diff --git a/toy-activity.scala b/toy-activity.scala
new file mode 100644 (file)
index 0000000..868b3d2
--- /dev/null
@@ -0,0 +1,93 @@
+package uk.org.distorted.tripe;
+
+import java.io.{File, FileOutputStream, InputStream, IOException};
+
+import android.app.{Activity, Application};
+import android.content.Context; import Context.MODE_WORLD_READABLE;
+import android.content.res.AssetManager;
+import android.os.Build; import Build.{CPU_ABI, CPU_ABI2};
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+
+import scala.util.control.Breaks;
+
+object Setup {
+  private final val TAG = "Setup";
+  private val BREAK = new Breaks;
+  import BREAK.{breakable, break};
+
+  def setup(ctx: Context) {
+    val bindir = ctx.getDir("bin", MODE_WORLD_READABLE);
+    val assets = ctx.getAssets;
+
+    val abis =
+      try { classOf[Build].getField("SUPPORTED_ABIS").get(null).asInstanceOf[Array[String]] }
+      catch {
+       case _: NoSuchFieldException => Array(CPU_ABI, CPU_ABI2) flatMap {
+         case null | "" => None
+         case s => Some(s)
+       }
+      };
+
+    Log.d(TAG, s"abis = ${abis.mkString(", ")}");
+    Log.d(TAG, s"assets: ${assets.list("bin").mkString(", ")}");
+
+    for (abi <- abis) {
+      val binsrc = s"bin/$abi";
+      for (base <- assets.list(binsrc)) {
+       val prog = new File(bindir, base);
+       if (!prog.exists) try {
+         Log.d(TAG, s"creating $prog...");
+         val in = assets.open(s"$binsrc/$base");
+         Log.d(TAG, "opened source...");
+         val out = new FileOutputStream(prog);
+         Log.d(TAG, "opened target...");
+         val buf = new Array[Byte](4096);
+         breakable {
+           while (true) {
+             val n = in.read(buf);
+             Log.d(TAG, s"read $n bytes...");
+             if (n <= 0) break;
+             out.write(buf, 0, n);
+           }
+         }
+         in.close();
+         out.close();
+         Log.d(TAG, "set permissions...");
+         if (!prog.setReadable(true, false) ||
+             !prog.setExecutable(true, false))
+           throw new IOException("failed to set program permissions");
+       } catch {
+         case exc: IOException =>
+           Log.wtf(TAG, "fuck, failed to create prog", exc);
+       }
+      }
+    }
+    Log.d(TAG, "all OK");
+  }
+}
+
+object ToyActivity {
+  private final val TAG = "ToyActivity";
+  System.loadLibrary("jni");
+  @native protected def foo();
+}
+
+class ToyActivity extends Activity {
+  import ToyActivity._;
+
+  override protected def onCreate(joy: Bundle) {
+    super.onCreate(joy);
+    Setup.setup(this);
+    setContentView(R.layout.toy);
+  }
+  def clickOk(v: View) {
+    Log.d(TAG, "OK, OK.  (Scala was here.)");
+    foo();
+
+    val bindir = getDir("bin", MODE_WORLD_READABLE);
+    Runtime.getRuntime.exec(Array(new File(bindir, "prog").getPath,
+                                 "testing", "1", "2", "3"));
+  }
+}