blob: 0b44f750b112fc09a88d7f5e925fc720f5006285 [file] [log] [blame]
Srdjan Petrovic6f6b2c02014-07-11 12:36:23 -07001// +build android
2
3package jni
4
5import (
6 "fmt"
7 "runtime"
8
9 "veyron/runtimes/google/jni/util"
10 "veyron2/security"
11)
12
13// #cgo LDFLAGS: -ljniwrapper
14// #include "jni_wrapper.h"
15//
16// // CGO doesn't support variadic functions so we have to hard-code these
17// // functions to match the invoking code. Ugh!
18// static jobject CallCaveatNewContextObject(JNIEnv* env, jclass class, jmethodID id, jlong goContextPtr) {
19// return (*env)->NewObject(env, class, id, goContextPtr);
20// }
21// static void CallCaveatValidateMethod(JNIEnv* env, jobject obj, jmethodID id, jobject context) {
22// return (*env)->CallVoidMethod(env, obj, id, context);
23// }
24import "C"
25
26func newCaveat(env *C.JNIEnv, jCaveat C.jobject) *caveat {
27 // We cannot cache Java environments as they are only valid in the current
28 // thread. We can, however, cache the Java VM and obtain an environment
29 // from it in whatever thread happens to be running at the time.
30 var jVM *C.JavaVM
31 if status := C.GetJavaVM(env, &jVM); status != 0 {
32 panic("couldn't get Java VM from the (Java) environment")
33 }
34 // Reference Java service caveat; it will be de-referenced when the go
35 // service caveat created below is garbage-collected (through the finalizer
36 // callback we setup just below).
37 jCaveat = C.NewGlobalRef(env, jCaveat)
38 c := &caveat{
39 jVM: jVM,
40 jCaveat: jCaveat,
41 }
42 runtime.SetFinalizer(c, func(c *caveat) {
43 var env *C.JNIEnv
44 C.AttachCurrentThread(c.jVM, &env, nil)
45 defer C.DetachCurrentThread(c.jVM)
46 C.DeleteGlobalRef(env, c.jCaveat)
47 })
48 return c
49}
50
51type caveat struct {
52 jVM *C.JavaVM
53 jCaveat C.jobject
54}
55
56func (c *caveat) Validate(context security.Context) error {
57 var env *C.JNIEnv
58 C.AttachCurrentThread(c.jVM, &env, nil)
59 defer C.DetachCurrentThread(c.jVM)
60 util.GoRef(&context) // un-refed when the Java Context object is finalized.
Benjamin Prosnitzb06a93b2014-07-15 15:43:18 -070061 cid := C.jmethodID(util.JMethodIDPtrOrDie(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
Srdjan Petrovicec6f5112014-07-22 14:41:54 -070062 jContext := C.CallCaveatNewContextObject(env, jContextImplClass, cid, C.jlong(util.PtrValue(&context)))
Srdjan Petrovic6f6b2c02014-07-11 12:36:23 -070063 contextSign := "Lcom/veyron2/security/Context;"
Benjamin Prosnitzb06a93b2014-07-15 15:43:18 -070064 mid := C.jmethodID(util.JMethodIDPtrOrDie(env, C.GetObjectClass(env, c.jCaveat), "validate", fmt.Sprintf("(%s)%s", contextSign, util.VoidSign)))
Srdjan Petrovic6f6b2c02014-07-11 12:36:23 -070065 C.CallCaveatValidateMethod(env, c.jCaveat, mid, jContext)
66 return util.JExceptionMsg(env)
67}