blob: 0424cbf75e37955913e660a2ec20282270b649f8 [file] [log] [blame]
// Copyright 2016 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 ble
import (
"runtime"
"v.io/v23/context"
"v.io/x/ref/lib/discovery/plugins/ble"
jutil "v.io/x/jni/util"
jcontext "v.io/x/jni/v23/context"
)
// #include "jni.h"
import "C"
type driver struct {
jDriver jutil.Object
}
func (d *driver) AddService(uuid string, characteristics map[string][]byte) error {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
csObjMap := make(map[jutil.Object]jutil.Object, len(characteristics))
for uuid, characteristic := range characteristics {
jUuid := jutil.JString(env, uuid)
jCharacteristic, err := jutil.JByteArray(env, characteristic)
if err != nil {
return err
}
csObjMap[jUuid] = jCharacteristic
}
jCharacteristics, err := jutil.JObjectMap(env, csObjMap)
if err != nil {
return err
}
return jutil.CallVoidMethod(env, d.jDriver, "addService", []jutil.Sign{jutil.StringSign, jutil.MapSign}, uuid, jCharacteristics)
}
func (d *driver) RemoveService(uuid string) {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jutil.CallVoidMethod(env, d.jDriver, "removeService", []jutil.Sign{jutil.StringSign}, uuid)
}
func (d *driver) StartScan(uuids []string, baseUuid, maskUuid string, handler ble.ScanHandler) error {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
handlerRef := jutil.GoNewRef(&handler) // Un-refed when jNativeScanHandler is finalized.
jNativeScanHandler, err := jutil.NewObject(env, jNativeScanHandlerClass, []jutil.Sign{jutil.LongSign}, int64(handlerRef))
if err != nil {
jutil.GoDecRef(handlerRef)
return err
}
err = jutil.CallVoidMethod(env, d.jDriver, "startScan", []jutil.Sign{jutil.ArraySign(jutil.StringSign), jutil.StringSign, jutil.StringSign, scanHandlerSign}, uuids, baseUuid, maskUuid, jNativeScanHandler)
if err != nil {
jutil.GoDecRef(handlerRef)
return err
}
return nil
}
func (d *driver) StopScan() {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
jutil.CallVoidMethod(env, d.jDriver, "stopScan", nil)
}
func (d *driver) DebugString() string {
env, freeFunc := jutil.GetEnv()
defer freeFunc()
s, _ := jutil.CallStringMethod(env, d.jDriver, "debugString", nil)
return s
}
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
}