blob: 22f7fbbf35ef987927a15ec0ff4c0e161c58ecab [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build android
package discovery
import (
"runtime"
"v.io/v23/context"
"v.io/x/ref/lib/discovery"
jutil "v.io/x/jni/util"
jcontext "v.io/x/jni/v23/context"
)
// #include "jni.h"
import "C"
func NewBleCreator(env jutil.Env, context jutil.Object) func(string) (discovery.Plugin, error) {
// Reference Android Context; it will be de-referenced when the plugin
// created below is garbage-collected (through the finalizer callback we
// setup in the function below). This function should only be executed once.
jContext := jutil.NewGlobalRef(env, context)
return func(host string) (discovery.Plugin, error) {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jPlugin, err := jutil.NewObject(env, jBlePluginClass, []jutil.Sign{androidContextSign}, jContext)
jutil.DeleteGlobalRef(env, jContext)
if err != nil {
return nil, err
}
// Reference Android BlePlugin; it will be de-referenced when the plugin
// created below is garbage-collected (through the finalizer callback we
// setup below).
jPlugin = jutil.NewGlobalRef(env, jPlugin)
p := &plugin{
trigger: discovery.NewTrigger(),
jPlugin: jPlugin,
}
runtime.SetFinalizer(p, func(p *plugin) {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jutil.DeleteGlobalRef(env, p.jPlugin)
})
return p, nil
}
}
type plugin struct {
trigger *discovery.Trigger
jPlugin jutil.Object
}
func (p *plugin) Advertise(ctx *context.T, ad discovery.Advertisement, done func()) error {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jContext, err := jcontext.JavaContext(env, ctx, nil)
if err != nil {
return err
}
jAdv, err := jutil.JVomCopy(env, ad, jAdvertisementClass)
if err != nil {
return err
}
err = jutil.CallVoidMethod(env, p.jPlugin, "addAdvertisement", []jutil.Sign{contextSign, advertisementSign}, jContext, jAdv)
p.trigger.Add(done, ctx.Done())
return err
}
func (p *plugin) Scan(ctx *context.T, interfaceName string, ch chan<- discovery.Advertisement, done func()) error {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jContext, err := jcontext.JavaContext(env, ctx, nil)
if err != nil {
return err
}
jutil.GoRef(&ch)
jNativeScanHandler, err := jutil.NewObject(env, jNativeScanHandlerClass, []jutil.Sign{jutil.LongSign}, int64(jutil.PtrValue(&ch)))
if err != nil {
return err
}
err = jutil.CallVoidMethod(env, p.jPlugin, "addScanner", []jutil.Sign{contextSign, jutil.StringSign, scanHandlerSign}, jContext, interfaceName, jNativeScanHandler)
if err != nil {
return err
}
p.trigger.Add(done, ctx.Done())
return nil
}