func (i *invoker) Signature(ctx *context.T, call rpc.ServerCall) ([]signature.Interface, error) { env, freeFunc := jutil.GetEnv() jContext, err := jcontext.JavaContext(env, ctx, nil) if err != nil { freeFunc() return nil, err } // This method will invoke the freeFunc(). jInterfaces, err := jutil.CallFutureMethod(env, freeFunc, i.jInvoker, "getSignature", []jutil.Sign{contextSign}, jContext) if err != nil { return nil, err } env, freeFunc = jutil.GetEnv() defer freeFunc() defer jutil.DeleteGlobalRef(env, jInterfaces) interfacesArr, err := jutil.GoObjectArray(env, jInterfaces) if err != nil { return nil, err } result := make([]signature.Interface, len(interfacesArr)) for i, jInterface := range interfacesArr { err = jutil.GoVomCopy(env, jInterface, jInterfaceClass, &result[i]) if err != nil { return nil, err } } return result, nil }
func (i *invoker) Prepare(ctx *context.T, method string, numArgs int) (argptrs []interface{}, tags []*vdl.Value, err error) { env, freeFunc := jutil.GetEnv() jContext, err := jcontext.JavaContext(env, ctx, nil) if err != nil { freeFunc() return nil, nil, err } // Have all input arguments be decoded into *vdl.Value. argptrs = make([]interface{}, numArgs) for i := 0; i < numArgs; i++ { value := new(vdl.Value) argptrs[i] = &value } // This method will invoke the freeFunc(). jVomTags, err := jutil.CallStaticFutureMethod(env, freeFunc, jServerRPCHelperClass, "prepare", []jutil.Sign{invokerSign, contextSign, jutil.StringSign}, i.jInvoker, jContext, jutil.CamelCase(method)) if err != nil { return nil, nil, err } env, freeFunc = jutil.GetEnv() defer freeFunc() defer jutil.DeleteGlobalRef(env, jVomTags) vomTags, err := jutil.GoByteArrayArray(env, jVomTags) if err != nil { return nil, nil, err } tags = make([]*vdl.Value, len(vomTags)) for i, vomTag := range vomTags { var err error if tags[i], err = jutil.VomDecodeToValue(vomTag); err != nil { return nil, nil, err } } return }
func initDriverFactory(env jutil.Env) error { jDriverClass, err := jutil.JFindClass(env, "io/v/android/impl/google/discovery/plugins/ble/Driver") if err != nil { return err } factory := func(ctx *context.T, _ string) (ble.Driver, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jCtx, err := jcontext.JavaContext(env, ctx, nil) if err != nil { return nil, err } jDriver, err := jutil.NewObject(env, jDriverClass, []jutil.Sign{contextSign}, jCtx) if err != nil { return nil, err } // Reference the driver; it will be de-referenced when the driver is garbage-collected. jDriver = jutil.NewGlobalRef(env, jDriver) d := &driver{jDriver} runtime.SetFinalizer(d, func(*driver) { env, freeFunc := jutil.GetEnv() jutil.DeleteGlobalRef(env, d.jDriver) freeFunc() }) return d, nil } ble.SetDriverFactory(factory) return nil }
func (l *bleListener) Accept(ctx *context.T) (flow.Conn, error) { env, freeFunc := jutil.GetEnv() // This method will invoke the freeFunc(). jStream, err := jutil.CallCallbackMethod(env, freeFunc, l.jListener, "accept", nil) if err != nil { return nil, err } env, freeFunc = jutil.GetEnv() defer freeFunc() return newConnection(env, jStream), nil }
func (c *bleReadWriteCloser) Read(b []byte) (n int, err error) { env, freeFunc := jutil.GetEnv() // This method will invoke the freeFunc(). jResult, err := jutil.CallCallbackMethod(env, freeFunc, c.jStream, "read", []jutil.Sign{jutil.IntSign}, len(b)) if err != nil { return 0, err } env, freeFunc = jutil.GetEnv() defer freeFunc() defer jutil.DeleteGlobalRef(env, jResult) data := jutil.GoByteArray(env, jResult) return copy(b, data), nil }
func (bleProtocol) Dial(ctx *context.T, protocol, address string, timeout time.Duration) (flow.Conn, error) { env, freeFunc := jutil.GetEnv() jContext, err := jcontext.JavaContext(env, ctx, nil) if err != nil { freeFunc() return nil, err } // This method will invoke the freeFunc(). jStream, err := jutil.CallStaticCallbackMethod(env, freeFunc, jBleClass, "dial", []jutil.Sign{contextSign, jutil.StringSign, jutil.DurationSign}, jContext, address, timeout) if err != nil { return nil, err } env, freeFunc = jutil.GetEnv() defer freeFunc() return newConnection(env, jStream), nil }
// GoBlessingRoots creates an instance of security.BlessingRoots that uses the // provided Java BlessingRoots as its underlying implementation. func GoBlessingRoots(env jutil.Env, jBlessingRoots jutil.Object) (security.BlessingRoots, error) { if jBlessingRoots.IsNull() { return nil, nil } if jutil.IsInstanceOf(env, jBlessingRoots, jBlessingRootsImplClass) { // Called with our implementation of BlessingRoots, which maintains a Go reference - use it. ref, err := jutil.CallLongMethod(env, jBlessingRoots, "nativeRef", nil) if err != nil { return nil, err } return (*(*security.BlessingRoots)(jutil.GoRefValue(jutil.Ref(ref)))), nil } // Reference Java BlessingRoots; it will be de-referenced when the Go // BlessingRoots created below is garbage-collected (through the finalizer // callback we setup just below). jBlessingRoots = jutil.NewGlobalRef(env, jBlessingRoots) r := &blessingRoots{ jBlessingRoots: jBlessingRoots, } runtime.SetFinalizer(r, func(r *blessingRoots) { env, freeFunc := jutil.GetEnv() defer freeFunc() jutil.DeleteGlobalRef(env, r.jBlessingRoots) }) return r, nil }
//export Java_io_v_impl_google_lib_discovery_UpdateImpl_nativeAttachment func Java_io_v_impl_google_lib_discovery_UpdateImpl_nativeAttachment(jenv *C.JNIEnv, _ C.jobject, goRef C.jlong, jCtx C.jobject, jName C.jstring, jCbObj C.jobject) { env := jutil.Env(uintptr(unsafe.Pointer(jenv))) ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx)))) if err != nil { jutil.JThrowV(env, err) return } update := *(*discovery.Update)(jutil.GoRefValue(jutil.Ref(goRef))) name := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName)))) jCb := jutil.Object(uintptr(unsafe.Pointer(jCbObj))) jutil.DoAsyncCall(env, jCb, func() (jutil.Object, error) { dataOrErr := <-update.Attachment(ctx, name) if dataOrErr.Error != nil { return jutil.NullObject, err } env, freeFunc := jutil.GetEnv() defer freeFunc() jData, err := jutil.JByteArray(env, dataOrErr.Data) if err != nil { return jutil.NullObject, err } // Must grab a global reference as we free up the env and all local references that come // along with it. return jutil.NewGlobalRef(env, jData), nil // Un-refed in DoAsyncCall }) }
func (d *driver) DebugString() string { env, freeFunc := jutil.GetEnv() defer freeFunc() s, _ := jutil.CallStringMethod(env, d.jDriver, "debugString", nil) return s }
//export Java_io_v_impl_google_rpc_StreamImpl_nativeRecv func Java_io_v_impl_google_rpc_StreamImpl_nativeRecv(jenv *C.JNIEnv, jStream C.jobject, goRef C.jlong, jCallbackObj C.jobject) { env := jutil.Env(uintptr(unsafe.Pointer(jenv))) jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj))) result := new(vdl.Value) jutil.DoAsyncCall(env, jCallback, func() (jutil.Object, error) { if err := (*(*rpc.Stream)(jutil.GoRefValue(jutil.Ref(goRef)))).Recv(&result); err != nil { if err == io.EOF { // Java uses EndOfFile error to detect EOF. err = verror.NewErrEndOfFile(nil) } return jutil.NullObject, err } vomResult, err := vom.Encode(result) if err != nil { return jutil.NullObject, err } env, freeFunc := jutil.GetEnv() defer freeFunc() jResult, err := jutil.JByteArray(env, vomResult) if err != nil { return jutil.NullObject, err } // Must grab a global reference as we free up the env and all local references that come along // with it. return jutil.NewGlobalRef(env, jResult), nil // Un-refed in DoAsyncCall }) }
// GoAuthorizer converts the given Java authorizer into a Go authorizer. func GoAuthorizer(env jutil.Env, jAuth jutil.Object) (security.Authorizer, error) { if jAuth.IsNull() { return nil, nil } if jutil.IsInstanceOf(env, jAuth, jPermissionsAuthorizerClass) { // Called with our implementation of Authorizer, which maintains a Go reference - use it. ref, err := jutil.JLongField(env, jAuth, "nativeRef") if err != nil { return nil, err } return *(*security.Authorizer)(jutil.GoRefValue(jutil.Ref(ref))), nil } // Reference Java dispatcher; it will be de-referenced when the go // dispatcher created below is garbage-collected (through the finalizer // callback we setup below). jAuth = jutil.NewGlobalRef(env, jAuth) a := &authorizer{ jAuth: jAuth, } runtime.SetFinalizer(a, func(a *authorizer) { env, freeFunc := jutil.GetEnv() defer freeFunc() jutil.DeleteGlobalRef(env, a.jAuth) }) return a, nil }
func (d *dispatcher) Lookup(ctx *context.T, suffix string) (interface{}, security.Authorizer, error) { // Get Java environment. env, freeFunc := jutil.GetEnv() defer freeFunc() result, err := jutil.CallStaticLongArrayMethod(env, jServerRPCHelperClass, "lookup", []jutil.Sign{dispatcherSign, jutil.StringSign}, d.jDispatcher, suffix) if err != nil { return nil, nil, fmt.Errorf("error invoking Java dispatcher's lookup() method: %v", err) } if result == nil { // Lookup returned null, which means that the dispatcher isn't handling the object - // this is not an error. return nil, nil, nil } if len(result) != 2 { return nil, nil, fmt.Errorf("lookup returned %d elems, want 2", len(result)) } invoker := *(*rpc.Invoker)(jutil.GoRefValue(jutil.Ref(result[0]))) jutil.GoDecRef(jutil.Ref(result[0])) authorizer := security.Authorizer(nil) if result[1] != 0 { authorizer = *(*security.Authorizer)(jutil.GoRefValue(jutil.Ref(result[1]))) jutil.GoDecRef(jutil.Ref(result[1])) } return invoker, authorizer, nil }
func caveatValidator(context *context.T, call security.Call, sets [][]security.Caveat) []error { env, freeFunc := jutil.GetEnv() defer freeFunc() jContext, err := jcontext.JavaContext(env, context, nil) if err != nil { return errors(err, len(sets)) } jCall, err := JavaCall(env, call) if err != nil { return errors(err, len(sets)) } ret := make([]error, len(sets)) for i, set := range sets { for _, caveat := range set { // NOTE(spetrovic): We validate system caveats in Go as it is significantly faster. if _, ok := systemCaveats[caveat.Id]; ok { if err := caveat.Validate(context, call); err != nil { ret[i] = err break } } else { jCaveat, err := JavaCaveat(env, caveat) if err != nil { ret[i] = err break } if err := jutil.CallStaticVoidMethod(env, jCaveatRegistryClass, "validate", []jutil.Sign{contextSign, callSign, caveatSign}, jContext, jCall, jCaveat); err != nil { ret[i] = err break } } } } return ret }
func doFinish(goRef C.jlong, numResults int) (jutil.Object, error) { // Have all the results be decoded into *vdl.Value. resultPtrs := make([]interface{}, numResults) for i := 0; i < numResults; i++ { value := new(vdl.Value) resultPtrs[i] = &value } if err := (*(*rpc.ClientCall)(jutil.GoRefValue(jutil.Ref(goRef)))).Finish(resultPtrs...); err != nil { // Invocation error. return jutil.NullObject, err } // VOM-encode the results. vomResults := make([][]byte, numResults) for i, resultPtr := range resultPtrs { // Remove the pointer from the result. Simply *resultPtr doesn't work // as resultPtr is of type interface{}. result := interface{}(jutil.DerefOrDie(resultPtr)) var err error if vomResults[i], err = vom.Encode(result); err != nil { return jutil.NullObject, err } } env, freeFunc := jutil.GetEnv() defer freeFunc() jArr, err := jutil.JByteArrayArray(env, vomResults) if err != nil { return jutil.NullObject, err } // Must grab a global reference as we free up the env and all local references that come along // with it. return jutil.NewGlobalRef(env, jArr), nil // Un-refed in DoAsyncCall }
// GoBlessingStore creates an instance of security.BlessingStore that uses the // provided Java BlessingStore as its underlying implementation. func GoBlessingStore(env jutil.Env, jBlessingStore jutil.Object) (security.BlessingStore, error) { if jBlessingStore.IsNull() { return nil, nil } if jutil.IsInstanceOf(env, jBlessingStore, jBlessingStoreImplClass) { // Called with our implementation of BlessingStore, which maintains a Go reference - use it. ref, err := jutil.JLongField(env, jBlessingStore, "nativeRef") if err != nil { return nil, err } return (*(*security.BlessingStore)(jutil.GoRefValue(jutil.Ref(ref)))), nil } // Reference Java BlessingStore; it will be de-referenced when the Go // BlessingStore created below is garbage-collected (through the finalizer // callback we setup just below). jBlessingStore = jutil.NewGlobalRef(env, jBlessingStore) s := &blessingStore{ jBlessingStore: jBlessingStore, } runtime.SetFinalizer(s, func(s *blessingStore) { env, freeFunc := jutil.GetEnv() defer freeFunc() jutil.DeleteGlobalRef(env, s.jBlessingStore) }) return s, nil }
// TODO(sjr): support cachedTime in Java func (s *blessingStore) Discharge(caveat security.Caveat, impetus security.DischargeImpetus) (security.Discharge, time.Time) { env, freeFunc := jutil.GetEnv() defer freeFunc() jCaveat, err := JavaCaveat(env, caveat) if err != nil { log.Printf("Couldn't get Java caveat: %v", err) return security.Discharge{}, time.Time{} } jImpetus, err := jutil.JVomCopy(env, impetus, jDischargeImpetusClass) if err != nil { log.Printf("Couldn't get Java DischargeImpetus: %v", err) return security.Discharge{}, time.Time{} } jDischarge, err := jutil.CallObjectMethod(env, s.jBlessingStore, "discharge", []jutil.Sign{caveatSign, dischargeImpetusSign}, dischargeSign, jCaveat, jImpetus) if err != nil { log.Printf("Couldn't call Java discharge method: %v", err) return security.Discharge{}, time.Time{} } discharge, err := GoDischarge(env, jDischarge) if err != nil { log.Printf("Couldn't convert Java discharge to Go: %v", err) return security.Discharge{}, time.Time{} } return discharge, time.Time{} }
func (p *principal) Bless(key security.PublicKey, with security.Blessings, extension string, caveat security.Caveat, additionalCaveats ...security.Caveat) (security.Blessings, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jKey, err := JavaPublicKey(env, key) if err != nil { return security.Blessings{}, err } jWith, err := JavaBlessings(env, with) if err != nil { return security.Blessings{}, err } jCaveat, err := JavaCaveat(env, caveat) if err != nil { return security.Blessings{}, err } jAdditionalCaveats, err := JavaCaveatArray(env, additionalCaveats) if err != nil { return security.Blessings{}, err } jBlessings, err := jutil.CallObjectMethod(env, p.jPrincipal, "bless", []jutil.Sign{publicKeySign, blessingsSign, jutil.StringSign, caveatSign, jutil.ArraySign(caveatSign)}, blessingsSign, jKey, jWith, extension, jCaveat, jAdditionalCaveats) if err != nil { return security.Blessings{}, err } return GoBlessings(env, jBlessings) }
// GoPrincipal converts the provided Java VPrincipal object into a Go Principal. func GoPrincipal(env jutil.Env, jPrincipal jutil.Object) (security.Principal, error) { if jPrincipal.IsNull() { return nil, nil } if jutil.IsInstanceOf(env, jPrincipal, jVPrincipalImplClass) { // Called with our implementation of VPrincipal, which maintains a Go reference - use it. ref, err := jutil.CallLongMethod(env, jPrincipal, "nativeRef", nil) if err != nil { return nil, err } return (*(*security.Principal)(jutil.GoRefValue(jutil.Ref(ref)))), nil } // Reference Java VPrincipal; it will be de-referenced when the Go Principal // created below is garbage-collected (through the finalizer callback we // setup just below). jPrincipal = jutil.NewGlobalRef(env, jPrincipal) // Create Go Principal. p := &principal{ jPrincipal: jPrincipal, } runtime.SetFinalizer(p, func(p *principal) { env, freeFunc := jutil.GetEnv() defer freeFunc() jutil.DeleteGlobalRef(env, p.jPrincipal) }) return p, nil }
// GoCall creates instance of security.Call that uses the provided Java // Call as its underlying implementation. func GoCall(env jutil.Env, jCall jutil.Object) (security.Call, error) { if jCall.IsNull() { return nil, nil } if jutil.IsInstanceOf(env, jCall, jCallImplClass) { // Called with our implementation of Call, which maintains a Go reference - use it. ref, err := jutil.CallLongMethod(env, jCall, "nativeRef", nil) if err != nil { return nil, err } return (*(*security.Call)(jutil.GoRefValue(jutil.Ref(ref)))), nil } // Reference Java call; it will be de-referenced when the go call // created below is garbage-collected (through the finalizer callback we // setup just below). jCall = jutil.NewGlobalRef(env, jCall) call := &callImpl{ jCall: jCall, } runtime.SetFinalizer(call, func(c *callImpl) { env, freeFunc := jutil.GetEnv() defer freeFunc() jutil.DeleteGlobalRef(env, c.jCall) }) return call, nil }
func (s *blessingStore) PeerBlessings() map[security.BlessingPattern]security.Blessings { env, freeFunc := jutil.GetEnv() defer freeFunc() jBlessingsMap, err := jutil.CallObjectMethod(env, s.jBlessingStore, "peerBlessings", nil, jutil.MapSign) if err != nil { log.Printf("Couldn't get Java peer blessings: %v", err) return nil } bmap, err := jutil.GoObjectMap(env, jBlessingsMap) if err != nil { log.Printf("Couldn't convert Java object map into a Go object map: %v", err) return nil } ret := make(map[security.BlessingPattern]security.Blessings) for jPattern, jBlessings := range bmap { pattern, err := GoBlessingPattern(env, jPattern) if err != nil { log.Printf("Couldn't convert Java pattern into Go: %v", err) return nil } blessings, err := GoBlessings(env, jBlessings) if err != nil { log.Printf("Couldn't convert Java blessings into Go: %v", err) return nil } ret[pattern] = blessings } return ret }
func (r *blessingRoots) Dump() map[security.BlessingPattern][]security.PublicKey { env, freeFunc := jutil.GetEnv() defer freeFunc() ret, err := jutil.CallMultimapMethod(env, r.jBlessingRoots, "dump", []jutil.Sign{}) if err != nil { log.Printf("Couldn't get Java Dump: %v", err) return nil } result := make(map[security.BlessingPattern][]security.PublicKey) for jPattern, jKeys := range ret { pattern, err := GoBlessingPattern(env, jPattern) if err != nil { log.Printf("Couldn't convert Java BlessingPattern: %v", err) return nil } var entry []security.PublicKey for _, jKey := range jKeys { key, err := GoPublicKey(env, jKey) if err != nil { log.Printf("Couldn't convert Java PublicKey: %v", err) return nil } entry = append(entry, key) } result[pattern] = entry } return result }
func (w *javaOutputWriter) Write(b []byte) (int, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() if err := jutil.CallVoidMethod(env, w.obj, "write", []jutil.Sign{jutil.StringSign}, string(b)); err != nil { return 0, err } return len(b), nil }
func (c *bleReadWriteCloser) Write(b []byte) (n int, err error) { env, freeFunc := jutil.GetEnv() // This method will invoke the freeFunc(). if _, err := jutil.CallCallbackMethod(env, freeFunc, c.jStream, "write", []jutil.Sign{jutil.ByteArraySign}, b); err != nil { return 0, err } return len(b), nil }
// javaOutputWriter translates an implementation of the Java Vango.OutputWriter interface to Go's io.Writer func newJavaOutputWriter(env jutil.Env, o jutil.Object) io.Writer { ret := &javaOutputWriter{jutil.NewGlobalRef(env, o)} runtime.SetFinalizer(ret, func(w *javaOutputWriter) { env, freeFunc := jutil.GetEnv() defer freeFunc() jutil.DeleteGlobalRef(env, w.obj) }) return ret }
func (p *principal) Sign(message []byte) (security.Signature, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jSig, err := jutil.CallObjectMethod(env, p.jPrincipal, "sign", []jutil.Sign{jutil.ArraySign(jutil.ByteSign)}, signatureSign, message) if err != nil { return security.Signature{}, err } return GoSignature(env, jSig) }
func (l *bleListener) Addr() net.Addr { env, freeFunc := jutil.GetEnv() defer freeFunc() addr, err := jutil.CallStringMethod(env, l.jListener, "address", nil) if err != nil { return bleAddr("") } return bleAddr(addr) }
func (s *blessingStore) SetDefault(blessings security.Blessings) error { env, freeFunc := jutil.GetEnv() defer freeFunc() jBlessings, err := JavaBlessings(env, blessings) if err != nil { return err } return jutil.CallVoidMethod(env, s.jBlessingStore, "setDefaultBlessings", []jutil.Sign{blessingsSign}, jBlessings) }
func (c *btReadWriteCloser) Write(b []byte) (n int, err error) { env, freeFunc := jutil.GetEnv() defer freeFunc() if err := jutil.CallVoidMethod(env, c.jStream, "write", []jutil.Sign{jutil.ByteArraySign}, b); err != nil { return 0, err } return len(b), nil }
func (l *btListener) Addr() net.Addr { env, freeFunc := jutil.GetEnv() defer freeFunc() addr, err := jutil.CallStringMethod(env, l.jListener, "address", nil) if err != nil { return &btAddr{""} } return &btAddr{addr} }
func (r *blessingRoots) Recognized(root []byte, blessing string) error { env, freeFunc := jutil.GetEnv() defer freeFunc() jRoot, err := JavaPublicKeyFromDER(env, root) if err != nil { return err } return jutil.CallVoidMethod(env, r.jBlessingRoots, "recognized", []jutil.Sign{publicKeySign, jutil.StringSign}, jRoot, blessing) }