jni,cmd/tailscale: replace jni.JVMFor with direct cast

The JVMFor function converted an uintptr to a pointer, which is not
guaranteed to work in general. This change removes JVMFor, forcing the
unsafe conversion to the user of the jni packge.

Updates tailscale/tailscale#1195

Signed-off-by: Elias Naur <mail@eliasnaur.com>
pull/6/head
Elias Naur 5 years ago
parent d3dc208237
commit 61d9733b24

@ -38,7 +38,7 @@ type backend struct {
// when no nameservers are provided by Tailscale. // when no nameservers are provided by Tailscale.
avoidEmptyDNS bool avoidEmptyDNS bool
jvm jni.JVM jvm *jni.JVM
} }
type androidRouter struct { type androidRouter struct {
@ -64,7 +64,7 @@ var fallbackNameservers = []netaddr.IP{netaddr.IPv4(8, 8, 8, 8), netaddr.IPv4(8,
// VPN status was revoked. // VPN status was revoked.
var errVPNNotPrepared = errors.New("VPN service not prepared or was revoked") var errVPNNotPrepared = errors.New("VPN service not prepared or was revoked")
func newBackend(dataDir string, jvm jni.JVM, store *stateStore, settings func(*router.Config) error) (*backend, error) { func newBackend(dataDir string, jvm *jni.JVM, store *stateStore, settings func(*router.Config) error) (*backend, error) {
logf := logger.RusagePrefixLog(log.Printf) logf := logger.RusagePrefixLog(log.Printf)
b := &backend{ b := &backend{
jvm: jvm, jvm: jvm,

@ -12,6 +12,7 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"unsafe"
"gioui.org/app" "gioui.org/app"
"gioui.org/io/system" "gioui.org/io/system"
@ -29,7 +30,7 @@ import (
//go:generate go run github.com/go-bindata/go-bindata/go-bindata -nocompress -o logo.go tailscale.png google.png //go:generate go run github.com/go-bindata/go-bindata/go-bindata -nocompress -o logo.go tailscale.png google.png
type App struct { type App struct {
jvm jni.JVM jvm *jni.JVM
// appCtx is a global reference to the com.tailscale.ipn.App instance. // appCtx is a global reference to the com.tailscale.ipn.App instance.
appCtx jni.Object appCtx jni.Object
@ -116,7 +117,7 @@ var backendEvents = make(chan UIEvent)
func main() { func main() {
a := &App{ a := &App{
jvm: jni.JVMFor(app.JavaVM()), jvm: (*jni.JVM)(unsafe.Pointer(app.JavaVM())),
appCtx: jni.Object(app.AppContext()), appCtx: jni.Object(app.AppContext()),
updates: make(chan struct{}, 1), updates: make(chan struct{}, 1),
} }

@ -16,7 +16,7 @@ import (
// backend by androidx.security.crypto.EncryptedSharedPreferences (see // backend by androidx.security.crypto.EncryptedSharedPreferences (see
// App.java). // App.java).
type stateStore struct { type stateStore struct {
jvm jni.JVM jvm *jni.JVM
// appCtx is the global Android app context. // appCtx is the global Android app context.
appCtx jni.Object appCtx jni.Object
@ -25,7 +25,7 @@ type stateStore struct {
decrypt jni.MethodID decrypt jni.MethodID
} }
func newStateStore(jvm jni.JVM, appCtx jni.Object) *stateStore { func newStateStore(jvm *jni.JVM, appCtx jni.Object) *stateStore {
s := &stateStore{ s := &stateStore{
jvm: jvm, jvm: jvm,
appCtx: appCtx, appCtx: appCtx,

@ -50,9 +50,7 @@ __attribute__ ((visibility ("hidden"))) jsize _jni_GetArrayLength(JNIEnv *env, j
*/ */
import "C" import "C"
type JVM struct { type JVM C.JavaVM
jvm *C.JavaVM
}
type Env struct { type Env struct {
env *C.JNIEnv env *C.JNIEnv
@ -73,32 +71,30 @@ const (
False Boolean = C.JNI_FALSE False Boolean = C.JNI_FALSE
) )
func JVMFor(jvmPtr uintptr) JVM {
return JVM{
jvm: (*C.JavaVM)(unsafe.Pointer(jvmPtr)),
}
}
func EnvFor(envPtr uintptr) Env { func EnvFor(envPtr uintptr) Env {
return Env{ return Env{
env: (*C.JNIEnv)(unsafe.Pointer(envPtr)), env: (*C.JNIEnv)(unsafe.Pointer(envPtr)),
} }
} }
func javavm(vm *JVM) *C.JavaVM {
return (*C.JavaVM)(unsafe.Pointer(vm))
}
// Do invokes a function with a temporary JVM environment. The // Do invokes a function with a temporary JVM environment. The
// environment is not valid after the function returns. // environment is not valid after the function returns.
func Do(vm JVM, f func(env Env) error) error { func Do(vm *JVM, f func(env Env) error) error {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
var env *C.JNIEnv var env *C.JNIEnv
if res := C._jni_GetEnv(vm.jvm, &env, C.JNI_VERSION_1_6); res != C.JNI_OK { if res := C._jni_GetEnv(javavm(vm), &env, C.JNI_VERSION_1_6); res != C.JNI_OK {
if res != C.JNI_EDETACHED { if res != C.JNI_EDETACHED {
panic(fmt.Errorf("JNI GetEnv failed with error %d", res)) panic(fmt.Errorf("JNI GetEnv failed with error %d", res))
} }
if C._jni_AttachCurrentThread(vm.jvm, &env, nil) != C.JNI_OK { if C._jni_AttachCurrentThread(javavm(vm), &env, nil) != C.JNI_OK {
panic(errors.New("runInJVM: AttachCurrentThread failed")) panic(errors.New("runInJVM: AttachCurrentThread failed"))
} }
defer C._jni_DetachCurrentThread(vm.jvm) defer C._jni_DetachCurrentThread(javavm(vm))
} }
return f(Env{env}) return f(Env{env})

Loading…
Cancel
Save