diff --git a/.gitignore b/.gitignore index 551803b..361cda8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,11 @@ *.ast *.apk -*.jar *.dex *.class +examples/jni/AClass.jar +examples/pgp/PgpConnect.jar examples/sensors/sensors examples/jni/jni examples/dex/dex +examples/pgp/pgp examples/permissions/permissions diff --git a/examples/pgp/PgpConnect.java b/examples/pgp/PgpConnect.java new file mode 100644 index 0000000..0e5b525 --- /dev/null +++ b/examples/pgp/PgpConnect.java @@ -0,0 +1,61 @@ +package st.wow.git.pgp; + +import java.lang.Runnable; +import java.lang.String; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import android.os.Handler; +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import org.openintents.openpgp.OpenPgpError; +import org.openintents.openpgp.OpenPgpSignatureResult; +import org.openintents.openpgp.util.OpenPgpApi; +import org.openintents.openpgp.util.OpenPgpServiceConnection; +import android.content.Context; +import android.content.Intent; +import android.util.Log; +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.app.PendingIntent; +import android.content.IntentSender; +import android.content.IntentSender.OnFinished; +import android.content.IntentSender.SendIntentException; +import android.os.Bundle; + +public class PgpConnect { + //OpenPgpServiceConnection mServiceConnection; + Activity act; + Context ctx; + Handler handler; + PgpFragment frag; + + PgpConnect(Activity act) { + act = act; + ctx = act.getApplicationContext(); + this.handler = new Handler(ctx.getMainLooper()); + //this.mServiceConnection = new OpenPgpServiceConnection(ctx, "org.sufficientlysecure.keychain"); + //this.mServiceConnection.bindToService(); + + final FragmentManager fm = act.getFragmentManager(); + frag = new PgpFragment(); + handler.post(new Runnable() { + public void run() { + FragmentTransaction ft = fm.beginTransaction(); + ft.add(frag, "PgpFragment"); + ft.commitNow(); + } + }); + } + + public String Decrypt(byte[] dat, int chint) { + return frag.Decrypt(dat, chint); + } + + public String Encrypt(byte[] id, byte[] dat, int chint) { + return frag.Encrypt(id, dat, chint); + } +} diff --git a/examples/pgp/PgpFragment.java b/examples/pgp/PgpFragment.java new file mode 100644 index 0000000..c03fe9c --- /dev/null +++ b/examples/pgp/PgpFragment.java @@ -0,0 +1,170 @@ +package st.wow.git.pgp; + +import android.util.Log; +import android.content.Context; +import android.app.Fragment; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import org.openintents.openpgp.OpenPgpError; +import org.openintents.openpgp.OpenPgpSignatureResult; +import org.openintents.openpgp.util.OpenPgpApi; +import org.openintents.openpgp.util.OpenPgpServiceConnection; +import android.content.Intent; +import android.app.PendingIntent; +import android.content.IntentSender; +import android.content.IntentSender.SendIntentException; +import android.os.Handler; + +public class PgpFragment extends Fragment { + OpenPgpServiceConnection mServiceConnection; + Context ctx; + Handler handler; + + @Override public void onAttach(Context ctx) { + super.onAttach(ctx); + this.ctx = ctx; + this.handler = new Handler(ctx.getMainLooper()); + Log.d("PgpFragment", "onAttach()"); + mServiceConnection = new OpenPgpServiceConnection(ctx, "org.sufficientlysecure.keychain"); + mServiceConnection.bindToService(); + } + + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { + Log.d("PgpFragment", "onActivityResult(" + requestCode + "): " + resultCode); + super.onActivityResult(requestCode, resultCode, data); + activityResult(requestCode, resultCode); + } + + public String Decrypt(byte []dat, int chint) { + if (handler == null) { + return ""; + } + final BlockingQueue q = new LinkedBlockingQueue(); + handler.post(new Runnable() { + public void run() { + try { + q.put(_decrypt(dat, chint)); + } catch (InterruptedException e) { + Log.e("gio", "InterruptedException", e); + } + } + }); + try { + return q.take(); + } catch (InterruptedException e) { + Log.e("gio", "InterruptedException", e); + } + return ""; + } + + private String _decrypt(byte []dat, int chint) { + String ret = ""; + Intent data = new Intent(); + data.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY); + InputStream is = new ByteArrayInputStream(dat); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + OpenPgpApi api = new OpenPgpApi(this.ctx, mServiceConnection.getService()); + Intent result = api.executeApi(data, is, os); + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: { + try { + ret = os.toString("UTF-8"); + Log.d(OpenPgpApi.TAG, "output: " + ret); + } catch (UnsupportedEncodingException e) { + ret = ""; + Log.e("gio", "UnsupportedEncodingException", e); + } + break; + } + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: { + PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT); + try { + startIntentSenderForResult(pi.getIntentSender(), chint, null, 0, 0, 0, null); + } catch (IntentSender.SendIntentException e) { + Log.e("gio", "SendIntentException", e); + } + break; + } + case OpenPgpApi.RESULT_CODE_ERROR: { + OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); + break; + } + } + return ret; + } + + public String Encrypt(byte[] id, byte[] dat, int chint) { + if (handler == null) { + return ""; + } + final BlockingQueue q = new LinkedBlockingQueue(); + handler.post(new Runnable() { + public void run() { + try { + q.put(_encrypt(id, dat, chint)); + } catch (InterruptedException e) { + Log.e("gio", "InterruptedException", e); + } + } + }); + try { + return q.take(); + } catch (InterruptedException e) { + Log.e("gio", "InterruptedException", e); + } + return ""; + } + + private String _encrypt(byte[] id, byte[] dat, int chint) { + String ret = ""; + Intent data = new Intent(); + data.setAction(OpenPgpApi.ACTION_ENCRYPT); + data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{new String(id)}); + data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); + InputStream is = new ByteArrayInputStream(dat); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + OpenPgpApi api = new OpenPgpApi(this.ctx, mServiceConnection.getService()); + Intent result = api.executeApi(data, is, os); + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: { + try { + ret = os.toString("UTF-8"); + Log.d(OpenPgpApi.TAG, "output: " + ret); + } catch (UnsupportedEncodingException e) { + Log.e("gio", "UnsupportedEncodingException", e); + } + + if (result.hasExtra(OpenPgpApi.RESULT_SIGNATURE)) { + OpenPgpSignatureResult sigResult + = result.getParcelableExtra(OpenPgpApi.RESULT_SIGNATURE); + } + break; + } + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: { + PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT); + try { + IntentSender sender = pi.getIntentSender(); + Log.d("PgpConnect", "IntentSender:" + sender.toString()); + startIntentSenderForResult(sender, chint, null, 0, 0, 0, null); + } catch (IntentSender.SendIntentException e) { + Log.e("gio", "SendIntentException", e); + } + break; + } + case OpenPgpApi.RESULT_CODE_ERROR: { + OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); + break; + } + } + return ret; + } + + static private native void activityResult(int requestCode, int resultCode); + static private native void stringResult(int requestCode, String result); +} diff --git a/examples/pgp/jni_android.c b/examples/pgp/jni_android.c new file mode 100644 index 0000000..6267bca --- /dev/null +++ b/examples/pgp/jni_android.c @@ -0,0 +1,143 @@ + +#include +#include +#include +#include "jni_android.h" +#include "_cgo_export.h" + +static jobject gClassLoader; +static jmethodID gFindClassMethod; + +void +SetLoader(JNIEnv* env, jobject context) { + jclass cclass = (*env)->GetObjectClass(env, context); + jmethodID gcl_id = (*env)->GetMethodID(env, cclass, "getClassLoader", "()Ljava/lang/ClassLoader;"); + jobject loader = (*env)->CallObjectMethod(env, context, gcl_id); + gClassLoader = (*env)->NewGlobalRef(env, loader); + jclass lclass = (*env)->GetObjectClass(env, loader); + gFindClassMethod = (*env)->GetMethodID(env, lclass, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;"); +} + +jclass +FindClass(JNIEnv* env, char* name) { + jstring strClassName = (*env)->NewStringUTF(env, name); + return (*env)->CallObjectMethod(env, gClassLoader, gFindClassMethod, strClassName); +} + +jobject +CreateObject(JNIEnv* env, jclass cls) { + jmethodID init = (*env)->GetMethodID(env, cls, "", "()V"); + return (*env)->NewObject(env, cls, init); +} + +void +AddFragment(JNIEnv* env, jobject act, jobject frag) { + jclass cls = (*env)->GetObjectClass(env, act); + jmethodID mid = (*env)->GetMethodID(env, cls, "getFragmentManager", "()Landroid/app/FragmentManager;"); + jobject fm = (*env)->CallObjectMethod(env, act, mid); + cls = (*env)->GetObjectClass(env, fm); + mid = (*env)->GetMethodID(env, cls, "beginTransaction", "()Landroid/app/FragmentTransaction;"); + jobject ft = (*env)->CallObjectMethod(env, fm, mid); + cls = (*env)->GetObjectClass(env, ft); + mid = (*env)->GetMethodID(env, cls, "add", "(Landroid/app/Fragment;)V"); + (*env)->CallVoidMethod(env, ft, mid, frag); + mid = (*env)->GetMethodID(env, cls, "commitNow", "()V"); + (*env)->CallVoidMethod(env, ft, mid); + + cls = (*env)->GetObjectClass(env, frag); + static const JNINativeMethod fragMethods[] = { + { + .name = "activityResult", + .signature = "(II)V", + .fnPtr = activityResult + }, + { + .name = "stringResult", + .signature = "(ILjava/lang/String;)V", + .fnPtr = stringResult + }, + }; + + (*env)->RegisterNatives(env, cls, fragMethods, sizeof(fragMethods)/sizeof(fragMethods[0])); +} + +jobject +NewPgpConnect(JNIEnv* env, jobject act) { + jclass cls = FindClass(env, "st/wow/git/pgp/PgpConnect"); + jmethodID init = (*env)->GetMethodID(env, cls, "", "(Landroid/app/Activity;)V"); + jobject ret = (*env)->NewObject(env, cls, init, act); + + cls = FindClass(env, "st/wow/git/pgp/PgpFragment"); + static const JNINativeMethod actMethods[] = { + { + .name = "activityResult", + .signature = "(II)V", + .fnPtr = activityResult + }, + { + .name = "stringResult", + .signature = "(ILjava/lang/String;)V", + .fnPtr = stringResult + }, + }; + + (*env)->RegisterNatives(env, cls, actMethods, sizeof(actMethods)/sizeof(actMethods[0])); + + return (*env)->NewGlobalRef(env, ret); +} + +const char* +Decrypt(JNIEnv* env, jobject p, char* cdata, int datalen, int chint) { + jbyteArray data = (*env)->NewByteArray(env, datalen); + (*env)->SetByteArrayRegion(env, data, 0, datalen, cdata); + jclass cls = (*env)->GetObjectClass(env, p); + jmethodID mid = (*env)->GetMethodID(env, cls, "Decrypt", "([BI)Ljava/lang/String;"); + jstring ret = (*env)->CallObjectMethod(env, p, mid, data, chint); + return (*env)->GetStringUTFChars(env, ret, NULL); +} + +void stringResult(JNIEnv* env, jclass cls, jint requestCode, jobject response) { + char* str = (*env)->GetStringUTFChars(env, response, NULL); + goStringResult(env, cls, requestCode, str); +} + +const char* +Encrypt(JNIEnv* env, jobject p, char* cid, int idlen, char* cdata, int datalen, int chint) { + jbyteArray id = (*env)->NewByteArray(env, idlen); + (*env)->SetByteArrayRegion(env, id, 0, idlen, cid); + jbyteArray data = (*env)->NewByteArray(env, datalen); + (*env)->SetByteArrayRegion(env, data, 0, datalen, cdata); + jclass cls = (*env)->GetObjectClass(env, p); + jmethodID mid = (*env)->GetMethodID(env, cls, "Encrypt", "([B[BI)Ljava/lang/String;"); + jstring ret = (*env)->CallObjectMethod(env, p, mid, id, data, chint); + return (*env)->GetStringUTFChars(env, ret, NULL); +} + +void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID) { + (*env)->CallVoidMethod(env, obj, methodID); +} + +void CallVoidMethod1(JNIEnv *env, jobject obj, jmethodID methodID, jobject arg) { + (*env)->CallVoidMethod(env, obj, methodID, arg); +} + +jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID) { + return (*env)->CallIntMethod(env, obj, methodID); +} + +jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) { + return (*env)->GetMethodID(env, clazz, name, sig); +} + +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); +} + diff --git a/examples/pgp/jni_android.go b/examples/pgp/jni_android.go new file mode 100644 index 0000000..1a55611 --- /dev/null +++ b/examples/pgp/jni_android.go @@ -0,0 +1,158 @@ +package main + +/* +#cgo LDFLAGS: -landroid + +#include +#include "jni_android.h" +*/ +import "C" + +import ( + "errors" + "fmt" + "log" + "runtime" + "unsafe" + "sync" +) + +var theJVM *C.JavaVM +type JNIEnv = C.JNIEnv + +func SetJVM(jvm, context uintptr) { + log.Print("set theJVM") + theJVM = (*C.JavaVM)(unsafe.Pointer(jvm)) + RunInJVM(func(env *C.JNIEnv) { + C.SetLoader(env, (C.jobject)(context)) + }) +} + +func FindClass(env *C.JNIEnv, name string) C.jclass { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + return C.FindClass((*C.JNIEnv)(env), cname) +} + +func AddFragment(env *C.JNIEnv, act C.jobject, frag C.jobject) { + C.AddFragment(env, act, frag); +} + +func JniCallVoidMethod(env *C.JNIEnv, obj C.jobject, methodID C.jmethodID) { + C.CallVoidMethod(env, obj, methodID) +} + +func JniCallVoidMethod1(env *C.JNIEnv, obj C.jobject, methodID C.jmethodID, arg uintptr) { + C.CallVoidMethod1(env, obj, methodID, C.jobject(unsafe.Pointer(arg))) +} + +func JniCallIntMethod(env *C.JNIEnv, obj C.jobject, methodID C.jmethodID) int { + return (int)(C.CallIntMethod(env, obj, methodID)) +} + +func JniGetMethodID(env *C.JNIEnv, cls C.jclass, name, sig string) C.jmethodID { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + csig := C.CString(sig) + defer C.free(unsafe.Pointer(csig)) + return C.GetMethodID(env, cls, cname, csig) +} + +func CreateObject(env *C.JNIEnv, cls C.jclass) C.jobject { + return C.CreateObject(env, (C.jclass)(cls)) +} + +type PGP C.jobject + +func NewPgpConnect(env *C.JNIEnv, act uintptr) PGP { + return (PGP)(C.NewPgpConnect(env, (C.jobject)(unsafe.Pointer(act)))) +} + +var ( + fragChans map[int]chan string + chmux sync.Mutex + chint int +) + +func (p PGP) Decrypt(data string) string { + ch := make(chan string) + chmux.Lock() + if fragChans == nil { + fragChans = make(map[int]chan string) + } + fragChans[chint] = ch + curint := chint + chint++ + chmux.Unlock() + + cdata := C.CString(data) + defer C.free(unsafe.Pointer(cdata)) + var ret string + RunInJVM(func(env *JNIEnv) { + retc := C.Decrypt(env, (C.jobject)(p), (*C.char)(unsafe.Pointer(cdata)), (C.int)(len(data)), C.int(curint)) + defer C.free(unsafe.Pointer(retc)) + ret = C.GoString(retc) + }) + return ret +} + +func (p PGP) Encrypt(id, data string) string { + ch := make(chan string) + chmux.Lock() + if fragChans == nil { + fragChans = make(map[int]chan string) + } + fragChans[chint] = ch + curint := chint + chint++ + chmux.Unlock() + + cid := C.CString(id) + defer C.free(unsafe.Pointer(cid)) + cdata := C.CString(data) + defer C.free(unsafe.Pointer(cdata)) + var ret string + RunInJVM(func(env *JNIEnv) { + retc := C.Encrypt(env, (C.jobject)(p), (*C.char)(unsafe.Pointer(cid)), (C.int)(len(id)), (*C.char)(unsafe.Pointer(cdata)), (C.int)(len(data)), C.int(curint)) + defer C.free(unsafe.Pointer(retc)) + ret = C.GoString(retc) + }) + return ret +} + +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) +} + +//export activityResult +func activityResult(env *C.JNIEnv, class C.jclass, request, result C.jint) { + log.Printf("activityResult (%d): %d", request, result) +} + +//export goStringResult +func goStringResult(env *C.JNIEnv, class C.jclass, request C.jint, str *C.char) { + fragChans[int(request)] <- C.GoString(str) + C.free(unsafe.Pointer(str)) + chmux.Lock() + delete(fragChans, int(request)) + chmux.Unlock() +} diff --git a/examples/pgp/jni_android.h b/examples/pgp/jni_android.h new file mode 100644 index 0000000..b595d45 --- /dev/null +++ b/examples/pgp/jni_android.h @@ -0,0 +1,17 @@ +#include + +void SetLoader(JNIEnv* env, jobject context); +jclass FindClass(JNIEnv* env, char* name); +jobject CreateObject(JNIEnv* env, jclass cls); +void AddFragment(JNIEnv* env, jobject act, jobject frag); +jobject NewPgpConnect(JNIEnv* env, jobject act); +const char* Decrypt(JNIEnv* env, jobject p, char* cdata, int datalen, int chint); +const char* Encrypt(JNIEnv* env, jobject p, char* cid, int idlen, char* cdata, int datalen, int chint); +void stringResult(JNIEnv* env, jclass cls, jint requestCode, jobject response); +void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID); +void CallVoidMethod1(JNIEnv *env, jobject obj, jmethodID methodID, jobject arg); +jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID); +jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); +jint GetEnv(JavaVM *vm, JNIEnv **env, jint version); +jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args); +jint DetachCurrentThread(JavaVM *vm); diff --git a/examples/pgp/main.go b/examples/pgp/main.go new file mode 100644 index 0000000..c04c03f --- /dev/null +++ b/examples/pgp/main.go @@ -0,0 +1,79 @@ +// +build darwin linux + +package main + +import ( + "log" + + "gioui.org/app" + "gioui.org/io/system" + "gioui.org/layout" + "gioui.org/unit" + "gioui.org/widget/material" + + "gioui.org/font/gofont" +) + +var ( + labchan chan string +) + +func main() { + labchan = make(chan string) + log.Print("Staring event loop") + go eventloop() + app.Main() + log.Print("app.Main() returned") +} + +func eventloop() { + gofont.Register() + w := app.NewWindow( + app.Size(unit.Dp(400), unit.Dp(400)), + app.Title("Hello")) + th := material.NewTheme() + gtx := &layout.Context{Queue: w.Queue()} + + sysinset := &layout.Inset{} + margin := layout.UniformInset(unit.Dp(10)) + labels := []material.Label{} + list := &layout.List{Axis: layout.Vertical} + + resetSysinset := func(x system.Insets) { + sysinset.Top = x.Top + sysinset.Bottom = x.Bottom + sysinset.Left = x.Left + sysinset.Right = x.Right + } + go func() { + labchan <- "Starting" + callJni() + }() + for { + select { + case x := <-labchan: + labels = append(labels, th.Body1(x)) + w.Invalidate() + case e := <-w.Events(): + switch e := e.(type) { + case system.DestroyEvent: + return + case system.FrameEvent: + gtx.Reset(e.Config, e.Size) + resetSysinset(e.Insets) + sysinset.Layout(gtx, func() { + margin.Layout(gtx, func() { + list.Layout(gtx, len(labels), func(i int) { + labels[i].Layout(gtx) + }) + }) + }) + e.Frame(gtx.Ops) + case system.StageEvent: + log.Printf("stage event -- %s", e.Stage) + case *system.CommandEvent: + log.Print("command event") + } + } + } +} diff --git a/examples/pgp/openpgp-api.jar b/examples/pgp/openpgp-api.jar new file mode 100644 index 0000000..0ff1dc0 Binary files /dev/null and b/examples/pgp/openpgp-api.jar differ diff --git a/examples/pgp/os_android.go b/examples/pgp/os_android.go new file mode 100644 index 0000000..c35119a --- /dev/null +++ b/examples/pgp/os_android.go @@ -0,0 +1,56 @@ +//go:generate mkdir -p classes +//go:generate javac -bootclasspath $ANDROID_HOME/platforms/android-29/android.jar -classpath openpgp-api.jar -d classes PgpConnect.java PgpFragment.java +//go:generate jar cf PgpConnect.jar -C classes . +//go:generate rm -rf classes + +package main + +import ( + "fmt" + "log" + "time" + + "gioui.org/app" +) + +var ( + h *app.Handle + connected bool + pgp PGP +) + + +func connect() { + if !connected { + log.Print("PlatformHandle()") + h = app.PlatformHandle() + log.Print("SetJVM()") + SetJVM(h.JVM, h.Activity) + log.Print("SetJVM() returned") + RunInJVM(func(env *JNIEnv) { + log.Print("NewPgpConnect()") + pgp = NewPgpConnect(env, h.Activity) + }) + connected = true + } +} + +func checkPermission() bool { + connect() + //return pgp.CheckPermission(env) + return false +} + +func callJni() { + connect() + labchan <- fmt.Sprintf("JVM = %d", h.JVM) + labchan <- fmt.Sprintf("Activity = %d", h.Activity) + time.Sleep(time.Second / 5) + + val := pgp.Encrypt("greg_pomerantz@yahoo.com", "hi there") + //val := pgp.Encrypt("root@example.com", "hi there") + log.Print("val = ", val) + val2 := pgp.Decrypt(val) + labchan <- "result = " + val2 +} + diff --git a/examples/pgp/os_other.go b/examples/pgp/os_other.go new file mode 100644 index 0000000..2f6fa48 --- /dev/null +++ b/examples/pgp/os_other.go @@ -0,0 +1,7 @@ +// +build !android + +package main + +func callJni() { +} +