diff --git a/.gitignore b/.gitignore index 9975874..d544b2d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,47 +8,9 @@ # build files *.apk *.idsig -pad - -# IDE -.idea/ -.vscode/ - -# OS files -.DS_Store -Thumbs.db - -# Syncthing -.stfolder/ - -# Go test cache -*.test -*.out - -# build files -*.apk -*.idsig -pad - -# IDE -.idea/ -.vscode/ - -# OS files -.DS_Store -Thumbs.db - -# Syncthing -.stfolder/ - -# Go test cache -*.test -*.out - -# build files -*.apk -*.idsig -pad +*.jar +./pad +cmd/pad/pad # IDE .idea/ diff --git a/cmd/pad/Permissions.java b/cmd/pad/Permissions.java new file mode 100644 index 0000000..fac9484 --- /dev/null +++ b/cmd/pad/Permissions.java @@ -0,0 +1,67 @@ +package st.wow.git.logbook; + +import java.lang.Runnable; +import java.lang.String; +import android.os.Environment; +import android.os.Handler; +import android.content.Context; +import android.util.Log; +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.content.Intent; +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.provider.Settings; +import android.view.View; + +public class Permissions extends Fragment { + Context ctx; + Handler handler; + final int PERMISSIONS_REQUEST = 1; + + public Permissions(View view) { + Log.d("gio", "Permissions()"); + this.ctx = view.getContext(); + this.handler = new Handler(this.ctx.getMainLooper()); + Permissions inst = this; + handler.post(new Runnable() { + public void run() { + Activity act = (Activity)ctx; + FragmentTransaction ft = act.getFragmentManager().beginTransaction(); + ft.add(inst, "Permissions"); + ft.commitNow(); + } + }); + } + + @Override public void onAttach(Context ctx) { + super.onAttach(ctx); + Log.d("gio", "onAttach()"); + if (ctx instanceof Activity) { + Log.d("gio", "It's an Activity!"); + } + if (ctx.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ctx.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + Log.d("gio", "Requesting permissions"); + requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST); + } + if (!Environment.isExternalStorageManager()){ + Intent intent = new Intent(); + intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); + Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null); + intent.setData(uri); + startActivity(intent); + } + Log.d("gio", "Loading gio library"); + System.loadLibrary("gio"); + } + + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { + Log.d("gio", "onActivityResult(" + requestCode + "): " + resultCode); + super.onActivityResult(requestCode, resultCode, data); + } +} diff --git a/cmd/pad/impl_android.go b/cmd/pad/impl_android.go index 2cb1713..be6195f 100644 --- a/cmd/pad/impl_android.go +++ b/cmd/pad/impl_android.go @@ -2,10 +2,66 @@ package main +/* +#cgo LDFLAGS: -landroid -llog + +#include +#include "jni_android.h" +*/ +import "C" + import ( - _ "gioui.org/app/permission/storage" + "errors" + "fmt" + "log" + "runtime" + "unsafe" + + "gioui.org/app" + "gioui.org/io/event" + _ "gioui.org/app/permission/storage" ) +type JNIEnv = C.JNIEnv var ( - startpath="/storage/emulated/0/Notes" + startpath="/storage/emulated/0/Documents" + jvm uintptr + theJVM *C.JavaVM ) + +func impl_start() { } + +func handleEvent(e event.Event) { + switch e := e.(type) { + case app.AndroidViewEvent: + log.Print("ViewEvent") + theJVM = (*C.JavaVM)(unsafe.Pointer(app.JavaVM())) + RunInJVM(func(env *JNIEnv) { + C.registerFragment(env, (C.jobject)(unsafe.Pointer(e.View))) + }) + } +} + +func RunInJVM(f func(env *C.JNIEnv)) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + var env *C.JNIEnv + var detach bool + if res := C.GetEnv(theJVM, &env, C.JNI_VERSION_1_6); res != C.JNI_OK { + if res != C.JNI_EDETACHED { + panic(fmt.Errorf("JNI GetEnv failed with error %d", res)) + } + if C.AttachCurrentThread(theJVM, &env, nil) != C.JNI_OK { + panic(errors.New("runInJVM: AttachCurrentThread failed")) + } + detach = true + } + + if detach { + defer func() { + C.DetachCurrentThread(theJVM) + }() + } + f(env) +} + diff --git a/cmd/pad/impl_other.go b/cmd/pad/impl_other.go index 1c90951..8518a48 100644 --- a/cmd/pad/impl_other.go +++ b/cmd/pad/impl_other.go @@ -2,6 +2,13 @@ package main +import ( + "gioui.org/io/event" +) + var ( startpath="." ) + +func handleEvent(e event.Event) { } + diff --git a/cmd/pad/jni_android.c b/cmd/pad/jni_android.c new file mode 100644 index 0000000..aa97721 --- /dev/null +++ b/cmd/pad/jni_android.c @@ -0,0 +1,43 @@ + +//#include +#include +#include +#include "jni_android.h" +#include "_cgo_export.h" + +void +registerFragment(JNIEnv *env, jobject view) { + jclass cls = (*env)->GetObjectClass(env, view); + jmethodID mid = (*env)->GetMethodID(env, cls, "getContext", "()Landroid/content/Context;"); + jobject ctx = (*env)->CallObjectMethod(env, view, mid); + cls = (*env)->GetObjectClass(env, ctx); + mid = (*env)->GetMethodID(env, cls, "getClassLoader", "()Ljava/lang/ClassLoader;"); + jobject loader = (*env)->CallObjectMethod(env, ctx, mid); + cls = (*env)->GetObjectClass(env, loader); + mid = (*env)->GetMethodID(env, cls, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;"); + jstring str = (*env)->NewStringUTF(env, "st/wow/git/logbook/Permissions"); + cls = (*env)->CallObjectMethod(env, loader, mid, str); + mid = (*env)->GetMethodID(env, cls, "", "(Landroid/view/View;)V"); + jobject inst = (*env)->NewObject(env, cls, mid, view); +} + +void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID) { + (*env)->CallVoidMethod(env, obj, methodID); +} + +jint GetEnv(JavaVM *vm, JNIEnv **env, jint version) { + return (*vm)->GetEnv(vm, (void **)env, version); +} + +jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args) { + return (*vm)->AttachCurrentThread(vm, p_env, thr_args); +} + +jint DetachCurrentThread(JavaVM *vm) { + return (*vm)->DetachCurrentThread(vm); +} + +jobject +NewGlobalRef(JNIEnv *env, jobject o) { + return (*env)->NewGlobalRef(env, o); +} diff --git a/cmd/pad/jni_android.h b/cmd/pad/jni_android.h new file mode 100644 index 0000000..ee5eb43 --- /dev/null +++ b/cmd/pad/jni_android.h @@ -0,0 +1,13 @@ +#include + +void registerFragment(JNIEnv *env, jobject view); +void GetId(JNIEnv* env, jobject p, int chint); +void Decrypt(JNIEnv* env, jobject p, char* cdata, int datalen, int chint); +void Encrypt(JNIEnv* env, jobject p, char* cid, int idlen, char* cdata, int datalen, int chint); +void Clip(JNIEnv* env, jobject p, char* cdata, int datalen); +void stringResult(JNIEnv* env, jclass cls, jint requestCode, jobject response); +void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID); +jint GetEnv(JavaVM *vm, JNIEnv **env, jint version); +jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args); +jint DetachCurrentThread(JavaVM *vm); +jobject NewGlobalRef(JNIEnv *env, jobject o); diff --git a/cmd/pad/main.go b/cmd/pad/main.go index 2e517d2..1bd5ac2 100644 --- a/cmd/pad/main.go +++ b/cmd/pad/main.go @@ -136,6 +136,9 @@ func run(w *app.Window) error { logic.SearchQueryChan() <- newQuery } logic.LayoutChan() <- glyphLayout + default: + log.Printf("pad: default event") + handleEvent(e) } } }