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 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 (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 }
//export Java_io_v_android_v23_V_nativeInitGlobalAndroid func Java_io_v_android_v23_V_nativeInitGlobalAndroid(jenv *C.JNIEnv, _ C.jclass, jOptions C.jobject) { env := jutil.Env(uintptr(unsafe.Pointer(jenv))) jOpts := jutil.Object(uintptr(unsafe.Pointer(jOptions))) // Don't allow broken stderr/out to kill our program due to // sigpipe. Note that we just ignore all these signals. ch := make(chan os.Signal) signal.Notify(ch, syscall.SIGPIPE) if err := Init(env); err != nil { jutil.JThrowV(env, err) return } // Setup logging. _, _, level, vmodule, err := loggingOpts(env, jOpts) if err != nil { jutil.JThrowV(env, err) return } // Disable any logging to STDERR. // This assumes that vlog.Log is the underlying logging system for. vlog.Log.Configure(vlog.OverridePriorConfiguration(true), vlog.LogToStderr(false), vlog.AlsoLogToStderr(false), level, vmodule) // Setup discovery plugins. if err := jdplugins.Init(env); err != nil { jutil.JThrowV(env, err) return } // Setup namespace. android.SetNamespaceFactory(func(ctx *context.T, ns namespace.T, _ ...string) (namespace.T, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jContext, err := jcontext.JavaContext(env, ctx, nil) if err != nil { return nil, err } contextSign := jutil.ClassSign("io.v.v23.context.VContext") wakeupMountRoot, err := jutil.CallStaticStringMethod(env, jVClass, "getWakeupMountRoot", []jutil.Sign{contextSign}, jContext) if err != nil { return nil, err } if wakeupMountRoot == "" { return ns, nil } if !naming.Rooted(wakeupMountRoot) { return nil, fmt.Errorf("wakeup mount root %s must be ... rooted.", wakeupMountRoot) } return &wakeupNamespace{ wakeupMountRoot: wakeupMountRoot, ns: ns, }, nil }) }
func (btProtocol) Listen(ctx *context.T, protocol, address string) (flow.Listener, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jContext, err := jcontext.JavaContext(env, ctx, nil) if err != nil { return nil, err } jListener, err := jutil.CallStaticObjectMethod(env, jBluetoothClass, "listen", []jutil.Sign{contextSign, jutil.StringSign}, listenerSign, jContext, address) if err != nil { return nil, err } return newListener(env, jListener), nil }
// JavaInputChannel creates a new Java InputChannel object given the provided Go recv function. // // All objects returned by the recv function must be globally references. // // The recv function must return verror.ErrEndOfFile when there are no more elements // to receive. func JavaInputChannel(env jutil.Env, ctx *context.T, ctxCancel func(), recv func() (jutil.Object, error)) (jutil.Object, error) { jContext, err := jcontext.JavaContext(env, ctx, ctxCancel) if err != nil { return jutil.NullObject, err } ref := jutil.GoNewRef(&recv) // Un-refed when jInputChannel is finalized. jInputChannel, err := jutil.NewObject(env, jInputChannelImplClass, []jutil.Sign{contextSign, jutil.LongSign}, jContext, int64(ref)) if err != nil { jutil.GoDecRef(ref) return jutil.NullObject, err } return jInputChannel, 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 }
// JavaOutputChannel creates a new Java OutputChannel object given the provided Go convert, send // and close functions. Send is invoked with the result of convert, which must be non-blocking. func JavaOutputChannel(env jutil.Env, ctx *context.T, ctxCancel func(), convert func(jutil.Object) (interface{}, error), send func(interface{}) error, close func() error) (jutil.Object, error) { jContext, err := jcontext.JavaContext(env, ctx, ctxCancel) if err != nil { return jutil.NullObject, err } convertRef := jutil.GoNewRef(&convert) // Un-refed when jOutputChannel is finalized. sendRef := jutil.GoNewRef(&send) // Un-refed when jOutputChannel is finalized. closeRef := jutil.GoNewRef(&close) // Un-refed when jOutputChannel is finalized. jOutputChannel, err := jutil.NewObject(env, jOutputChannelImplClass, []jutil.Sign{contextSign, jutil.LongSign, jutil.LongSign, jutil.LongSign}, jContext, int64(convertRef), int64(sendRef), int64(closeRef)) if err != nil { jutil.GoDecRef(convertRef) jutil.GoDecRef(sendRef) jutil.GoDecRef(closeRef) return jutil.NullObject, err } return jOutputChannel, nil }
func (a *authorizer) Authorize(ctx *context.T, call security.Call) error { env, freeFunc := jutil.GetEnv() defer freeFunc() jCtx, err := jcontext.JavaContext(env, ctx, nil) if err != nil { return err } jCall, err := JavaCall(env, call) if err != nil { return err } // Run Java Authorizer. return jutil.CallVoidMethod(env, a.jAuth, "authorize", []jutil.Sign{contextSign, callSign}, jCtx, jCall) }
func (btProtocol) Dial(ctx *context.T, protocol, address string, timeout time.Duration) (flow.Conn, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jContext, err := jcontext.JavaContext(env, ctx, nil) if err != nil { return nil, err } jStream, err := jutil.CallStaticObjectMethod(env, jBluetoothClass, "dial", []jutil.Sign{contextSign, jutil.StringSign, jutil.DurationSign}, streamSign, jContext, address, timeout) if err != nil { return nil, err } // Reference Java Stream; it will be de-referenced when the Go connection // created below is garbage-collected (through the finalizer callback we // setup just below). jStream = jutil.NewGlobalRef(env, jStream) return newConnection(env, jStream), nil }
func (j javaGlobber) Glob__(ctx *context.T, call rpc.GlobServerCall, g *glob.Glob) error { // TODO(sjr,rthellend): Update the Java API to match the new GO API. env, freeFunc := jutil.GetEnv() jContext, err := jcontext.JavaContext(env, ctx, nil) if err != nil { freeFunc() return err } jServerCall, err := JavaServerCall(env, call) if err != nil { freeFunc() return err } convert := func(input jutil.Object) (interface{}, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() var reply naming.GlobReply if err := jutil.GoVomCopy(env, input, jGlobReplyClass, &reply); err != nil { return nil, err } return reply, nil } send := func(item interface{}) error { reply, ok := item.(naming.GlobReply) if !ok { return fmt.Errorf("Expected item of type naming.GlobReply, got: %T", reply) } return call.SendStream().Send(reply) } close := func() error { return nil } jOutputChannel, err := jchannel.JavaOutputChannel(env, ctx, nil, convert, send, close) if err != nil { freeFunc() return err } channelSign := jutil.ClassSign("io.v.v23.OutputChannel") // This method will invoke the freeFunc(). _, err = jutil.CallStaticFutureMethod(env, freeFunc, jServerRPCHelperClass, "glob", []jutil.Sign{invokerSign, contextSign, serverCallSign, jutil.StringSign, channelSign}, j.i.jInvoker, jContext, jServerCall, g.String(), jOutputChannel) return err }
func (i *invoker) Invoke(ctx *context.T, call rpc.StreamServerCall, method string, argptrs []interface{}) (results []interface{}, err error) { env, freeFunc := jutil.GetEnv() jContext, err := jcontext.JavaContext(env, ctx, nil) if err != nil { freeFunc() return nil, err } jStreamServerCall, err := javaStreamServerCall(env, jContext, call) if err != nil { freeFunc() return nil, err } vomArgs := make([][]byte, len(argptrs)) for i, argptr := range argptrs { arg := interface{}(jutil.DerefOrDie(argptr)) var err error if vomArgs[i], err = vom.Encode(arg); err != nil { freeFunc() return nil, err } } // This method will invoke the freeFunc(). jResult, err := jutil.CallStaticFutureMethod(env, freeFunc, jServerRPCHelperClass, "invoke", []jutil.Sign{invokerSign, contextSign, streamServerCallSign, jutil.StringSign, jutil.ArraySign(jutil.ArraySign(jutil.ByteSign))}, i.jInvoker, jContext, jStreamServerCall, jutil.CamelCase(method), vomArgs) if err != nil { return nil, err } env, freeFunc = jutil.GetEnv() defer freeFunc() defer jutil.DeleteGlobalRef(env, jResult) vomResults, err := jutil.GoByteArrayArray(env, jResult) if err != nil { return nil, err } results = make([]interface{}, len(vomResults)) for i, vomResult := range vomResults { var err error if results[i], err = jutil.VomDecodeToValue(vomResult); err != nil { return nil, err } } return results, nil }
func doStartCall(context *context.T, cancel func(), name, method string, opts []rpc.CallOpt, goRef C.jlong, args []interface{}) (jutil.Object, error) { // Invoke StartCall call, err := (*(*rpc.Client)(jutil.GoRefValue(jutil.Ref(goRef)))).StartCall(context, name, method, args, opts...) if err != nil { return jutil.NullObject, err } env, freeFunc := jutil.GetEnv() defer freeFunc() jContext, err := jcontext.JavaContext(env, context, cancel) if err != nil { return jutil.NullObject, err } jCall, err := javaCall(env, jContext, call) 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, jCall), nil // Un-refed in DoAsyncCall }
func (i *invoker) MethodSignature(ctx *context.T, call rpc.ServerCall, method string) (signature.Method, error) { env, freeFunc := jutil.GetEnv() jContext, err := jcontext.JavaContext(env, ctx, nil) if err != nil { freeFunc() return signature.Method{}, err } // This method will invoke the freeFunc(). jMethod, err := jutil.CallFutureMethod(env, freeFunc, i.jInvoker, "getMethodSignature", []jutil.Sign{contextSign, jutil.StringSign}, jContext, method) if err != nil { return signature.Method{}, err } env, freeFunc = jutil.GetEnv() defer freeFunc() defer jutil.DeleteGlobalRef(env, jMethod) var result signature.Method err = jutil.GoVomCopy(env, jMethod, jMethodClass, &result) if err != nil { return signature.Method{}, err } return result, nil }
//export Java_io_v_impl_google_services_mounttable_MountTableServer_nativeWithNewServer func Java_io_v_impl_google_services_mounttable_MountTableServer_nativeWithNewServer(jenv *C.JNIEnv, jMountTableServerClass C.jclass, jContext C.jobject, jMountTableServerParams C.jobject) C.jobject { env := jutil.Env(uintptr(unsafe.Pointer(jenv))) jCtx := jutil.Object(uintptr(unsafe.Pointer(jContext))) jParams := jutil.Object(uintptr(unsafe.Pointer(jMountTableServerParams))) // Read and translate all of the server params. mountName, err := jutil.CallStringMethod(env, jParams, "getName", nil) if err != nil { jutil.JThrowV(env, err) return nil } rootDir, err := jutil.CallStringMethod(env, jParams, "getStorageRootDir", nil) if err != nil { jutil.JThrowV(env, err) return nil } permsJMap, err := jutil.CallMapMethod(env, jParams, "getPermissions", nil) if err != nil { jutil.JThrowV(env, err) return nil } permsMap := make(map[string]access.Permissions) for jPath, jPerms := range permsJMap { path := jutil.GoString(env, jPath) perms, err := jaccess.GoPermissions(env, jPerms) if err != nil { jutil.JThrowV(env, err) return nil } permsMap[path] = perms } // Write JSON-encoded permissions to a file. jsonPerms, err := json.Marshal(permsMap) if err != nil { jutil.JThrowV(env, fmt.Errorf("Couldn't JSON-encode path-permissions: %v", err)) return nil } permsFile, err := ioutil.TempFile(rootDir, "jni_permissions") if err != nil { jutil.JThrowV(env, fmt.Errorf("Couldn't create permissions file: %v", err)) return nil } w := bufio.NewWriter(permsFile) if _, err := w.Write(jsonPerms); err != nil { jutil.JThrowV(env, fmt.Errorf("Couldn't write to permissions file: %v", err)) return nil } if err := w.Flush(); err != nil { jutil.JThrowV(env, fmt.Errorf("Couldn't flush to permissions file: %v", err)) } statsPrefix, err := jutil.CallStringMethod(env, jParams, "getStatsPrefix", nil) if err != nil { jutil.JThrowV(env, err) return nil } // Start the mounttable server. ctx, cancel, err := jcontext.GoContext(env, jCtx) if err != nil { jutil.JThrowV(env, err) return nil } d, err := mounttablelib.NewMountTableDispatcher(ctx, permsFile.Name(), rootDir, statsPrefix) if err != nil { jutil.JThrowV(env, err) return nil } newCtx, s, err := v23.WithNewDispatchingServer(ctx, mountName, d, options.ServesMountTable(true)) if err != nil { jutil.JThrowV(env, err) return nil } jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel) if err != nil { jutil.JThrowV(env, err) return nil } jServer, err := jrpc.JavaServer(env, s) if err != nil { jutil.JThrowV(env, err) return nil } // Attach a server to the new context. jServerAttCtx, err := jutil.CallStaticObjectMethod(env, jVRuntimeImplClass, "withServer", []jutil.Sign{contextSign, serverSign}, contextSign, jNewCtx, jServer) if err != nil { jutil.JThrowV(env, err) return nil } return C.jobject(unsafe.Pointer(jServerAttCtx)) }
//export Java_io_v_impl_google_services_syncbase_SyncbaseServer_nativeWithNewServer func Java_io_v_impl_google_services_syncbase_SyncbaseServer_nativeWithNewServer(jenv *C.JNIEnv, jSyncbaseServerClass C.jclass, jContext C.jobject, jSyncbaseServerParams C.jobject) C.jobject { env := jutil.Env(uintptr(unsafe.Pointer(jenv))) jCtx := jutil.Object(uintptr(unsafe.Pointer(jContext))) jParams := jutil.Object(uintptr(unsafe.Pointer(jSyncbaseServerParams))) // Read and translate all of the server params. jPerms, err := jutil.CallObjectMethod(env, jParams, "getPermissions", nil, permissionsSign) if err != nil { jutil.JThrowV(env, err) return nil } perms, err := jaccess.GoPermissions(env, jPerms) if err != nil { jutil.JThrowV(env, err) return nil } name, err := jutil.CallStringMethod(env, jParams, "getName", nil) if err != nil { jutil.JThrowV(env, err) return nil } rootDir, err := jutil.CallStringMethod(env, jParams, "getStorageRootDir", nil) if err != nil { jutil.JThrowV(env, err) return nil } if rootDir == "" { rootDir = filepath.Join(os.TempDir(), "syncbaseserver") if err := os.Mkdir(rootDir, 0755); err != nil && !os.IsExist(err) { jutil.JThrowV(env, err) return nil } } jEngine, err := jutil.CallObjectMethod(env, jParams, "getStorageEngine", nil, storageEngineSign) if err != nil { jutil.JThrowV(env, err) return nil } engine, err := GoStorageEngine(env, jEngine) if err != nil { jutil.JThrowV(env, err) return nil } ctx, cancel, err := jcontext.GoContext(env, jCtx) if err != nil { jutil.JThrowV(env, err) return nil } // Create the rpc server before the service so that connections are shared between // clients in the service and the rpc server. (i.e. connections are shared if the // context returned from WithNewDispatchingServer is used for client calls). d := dispatcher.NewDispatcherWrapper() ctx, s, err := v23.WithNewDispatchingServer(ctx, name, d, options.ChannelTimeout(vsync.NeighborConnectionTimeout)) if err != nil { cancel() jutil.JThrowV(env, err) return nil } service, err := server.NewService(ctx, server.ServiceOptions{ Perms: perms, RootDir: rootDir, Engine: engine, }) if err != nil { cancel() jutil.JThrowV(env, err) return nil } // Set the dispatcher in the dispatcher wrapper for the server to start responding // to incoming rpcs. d.SetDispatcher(server.NewDispatcher(service)) if err := service.AddNames(ctx, s); err != nil { cancel() jutil.JThrowV(env, err) return nil } jNewCtx, err := jcontext.JavaContext(env, ctx, cancel) if err != nil { jutil.JThrowV(env, err) return nil } jServer, err := jrpc.JavaServer(env, s) if err != nil { jutil.JThrowV(env, err) return nil } // Attach a server to the new context. jServerAttCtx, err := jutil.CallStaticObjectMethod(env, jVRuntimeImplClass, "withServer", []jutil.Sign{contextSign, serverSign}, contextSign, jNewCtx, jServer) if err != nil { jutil.JThrowV(env, err) return nil } return C.jobject(unsafe.Pointer(jServerAttCtx)) }
//export Java_io_v_impl_google_services_groups_GroupServer_nativeWithNewServer func Java_io_v_impl_google_services_groups_GroupServer_nativeWithNewServer(jenv *C.JNIEnv, jGroupServerClass C.jclass, jContext C.jobject, jGroupServerParams C.jobject) C.jobject { env := jutil.Env(uintptr(unsafe.Pointer(jenv))) jCtx := jutil.Object(uintptr(unsafe.Pointer(jContext))) jParams := jutil.Object(uintptr(unsafe.Pointer(jGroupServerParams))) // Read and translate all of the server params. name, err := jutil.CallStringMethod(env, jParams, "getName", nil) if err != nil { jutil.JThrowV(env, err) return nil } rootDir, err := jutil.CallStringMethod(env, jParams, "getStorageRootDir", nil) if err != nil { jutil.JThrowV(env, err) return nil } if rootDir == "" { rootDir = filepath.Join(os.TempDir(), "groupserver") if err := os.Mkdir(rootDir, 0755); err != nil && !os.IsExist(err) { jutil.JThrowV(env, err) return nil } } jEngine, err := jutil.CallObjectMethod(env, jParams, "getStorageEngine", nil, storageEngineSign) if err != nil { jutil.JThrowV(env, err) return nil } engine, err := GoStorageEngine(env, jEngine) if err != nil { jutil.JThrowV(env, err) return nil } // Start the server. ctx, cancel, err := jcontext.GoContext(env, jCtx) if err != nil { jutil.JThrowV(env, err) return nil } dispatcher, err := lib.NewGroupsDispatcher(rootDir, engine) if err != nil { jutil.JThrowV(env, err) return nil } newCtx, s, err := v23.WithNewDispatchingServer(ctx, name, dispatcher) if err != nil { jutil.JThrowV(env, err) return nil } jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel) if err != nil { jutil.JThrowV(env, err) return nil } jServer, err := jrpc.JavaServer(env, s) if err != nil { jutil.JThrowV(env, err) return nil } // Attach a server to the new context. jServerAttCtx, err := jutil.CallStaticObjectMethod(env, jVRuntimeImplClass, "withServer", []jutil.Sign{contextSign, serverSign}, contextSign, jNewCtx, jServer) if err != nil { jutil.JThrowV(env, err) return nil } return C.jobject(unsafe.Pointer(jServerAttCtx)) }