Adding upstream version 0.0~git20250520.a1d9079+dfsg.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
590ac7ff5f
commit
20149b7f3a
456 changed files with 70406 additions and 0 deletions
124
internal/mobileinit/ctx_android.go
Normal file
124
internal/mobileinit/ctx_android.go
Normal file
|
@ -0,0 +1,124 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package mobileinit
|
||||
|
||||
/*
|
||||
#include <jni.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char* lockJNI(JavaVM *vm, uintptr_t* envp, int* attachedp) {
|
||||
JNIEnv* env;
|
||||
|
||||
if (vm == NULL) {
|
||||
return "no current JVM";
|
||||
}
|
||||
|
||||
*attachedp = 0;
|
||||
switch ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6)) {
|
||||
case JNI_OK:
|
||||
break;
|
||||
case JNI_EDETACHED:
|
||||
if ((*vm)->AttachCurrentThread(vm, &env, 0) != 0) {
|
||||
return "cannot attach to JVM";
|
||||
}
|
||||
*attachedp = 1;
|
||||
break;
|
||||
case JNI_EVERSION:
|
||||
return "bad JNI version";
|
||||
default:
|
||||
return "unknown JNI error from GetEnv";
|
||||
}
|
||||
|
||||
*envp = (uintptr_t)env;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char* checkException(uintptr_t jnienv) {
|
||||
jthrowable exc;
|
||||
JNIEnv* env = (JNIEnv*)jnienv;
|
||||
|
||||
if (!(*env)->ExceptionCheck(env)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
exc = (*env)->ExceptionOccurred(env);
|
||||
(*env)->ExceptionClear(env);
|
||||
|
||||
jclass clazz = (*env)->FindClass(env, "java/lang/Throwable");
|
||||
jmethodID toString = (*env)->GetMethodID(env, clazz, "toString", "()Ljava/lang/String;");
|
||||
jobject msgStr = (*env)->CallObjectMethod(env, exc, toString);
|
||||
return (char*)(*env)->GetStringUTFChars(env, msgStr, 0);
|
||||
}
|
||||
|
||||
static void unlockJNI(JavaVM *vm) {
|
||||
(*vm)->DetachCurrentThread(vm);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// currentVM is stored to initialize other cgo packages.
|
||||
//
|
||||
// As all the Go packages in a program form a single shared library,
|
||||
// there can only be one JNI_OnLoad function for initialization. In
|
||||
// OpenJDK there is JNI_GetCreatedJavaVMs, but this is not available
|
||||
// on android.
|
||||
var currentVM *C.JavaVM
|
||||
|
||||
// currentCtx is Android's android.context.Context. May be NULL.
|
||||
var currentCtx C.jobject
|
||||
|
||||
// SetCurrentContext populates the global Context object with the specified
|
||||
// current JavaVM instance (vm) and android.context.Context object (ctx).
|
||||
// The android.context.Context object must be a global reference.
|
||||
func SetCurrentContext(vm unsafe.Pointer, ctx uintptr) {
|
||||
currentVM = (*C.JavaVM)(vm)
|
||||
currentCtx = (C.jobject)(ctx)
|
||||
}
|
||||
|
||||
// RunOnJVM runs fn on a new goroutine locked to an OS thread with a JNIEnv.
|
||||
//
|
||||
// RunOnJVM blocks until the call to fn is complete. Any Java
|
||||
// exception or failure to attach to the JVM is returned as an error.
|
||||
//
|
||||
// The function fn takes vm, the current JavaVM*,
|
||||
// env, the current JNIEnv*, and
|
||||
// ctx, a jobject representing the global android.context.Context.
|
||||
func RunOnJVM(fn func(vm, env, ctx uintptr) error) error {
|
||||
errch := make(chan error)
|
||||
go func() {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
env := C.uintptr_t(0)
|
||||
attached := C.int(0)
|
||||
if errStr := C.lockJNI(currentVM, &env, &attached); errStr != nil {
|
||||
errch <- errors.New(C.GoString(errStr))
|
||||
return
|
||||
}
|
||||
if attached != 0 {
|
||||
defer C.unlockJNI(currentVM)
|
||||
}
|
||||
|
||||
vm := uintptr(unsafe.Pointer(currentVM))
|
||||
if err := fn(vm, uintptr(env), uintptr(currentCtx)); err != nil {
|
||||
errch <- err
|
||||
return
|
||||
}
|
||||
|
||||
if exc := C.checkException(env); exc != nil {
|
||||
errch <- errors.New(C.GoString(exc))
|
||||
C.free(unsafe.Pointer(exc))
|
||||
return
|
||||
}
|
||||
errch <- nil
|
||||
}()
|
||||
return <-errch
|
||||
}
|
11
internal/mobileinit/mobileinit.go
Normal file
11
internal/mobileinit/mobileinit.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package mobileinit contains common initialization logic for mobile platforms
|
||||
// that is relevant to both all-Go apps and gobind-based apps.
|
||||
//
|
||||
// Long-term, some code in this package should consider moving into Go stdlib.
|
||||
package mobileinit
|
||||
|
||||
import "C"
|
93
internal/mobileinit/mobileinit_android.go
Normal file
93
internal/mobileinit/mobileinit_android.go
Normal file
|
@ -0,0 +1,93 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package mobileinit
|
||||
|
||||
/*
|
||||
To view the log output run:
|
||||
adb logcat GoLog:I *:S
|
||||
*/
|
||||
|
||||
// Android redirects stdout and stderr to /dev/null.
|
||||
// As these are common debugging utilities in Go,
|
||||
// we redirect them to logcat.
|
||||
//
|
||||
// Unfortunately, logcat is line oriented, so we must buffer.
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -landroid -llog
|
||||
|
||||
#include <android/log.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
ctag = C.CString("GoLog")
|
||||
// Store the writer end of the redirected stderr and stdout
|
||||
// so that they are not garbage collected and closed.
|
||||
stderr, stdout *os.File
|
||||
)
|
||||
|
||||
type infoWriter struct{}
|
||||
|
||||
func (infoWriter) Write(p []byte) (n int, err error) {
|
||||
cstr := C.CString(string(p))
|
||||
C.__android_log_write(C.ANDROID_LOG_INFO, ctag, cstr)
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func lineLog(f *os.File, priority C.int) {
|
||||
const logSize = 1024 // matches android/log.h.
|
||||
r := bufio.NewReaderSize(f, logSize)
|
||||
for {
|
||||
line, _, err := r.ReadLine()
|
||||
str := string(line)
|
||||
if err != nil {
|
||||
str += " " + err.Error()
|
||||
}
|
||||
cstr := C.CString(str)
|
||||
C.__android_log_write(priority, ctag, cstr)
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
log.SetOutput(infoWriter{})
|
||||
// android logcat includes all of log.LstdFlags
|
||||
log.SetFlags(log.Flags() &^ log.LstdFlags)
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
stderr = w
|
||||
if err := syscall.Dup3(int(w.Fd()), int(os.Stderr.Fd()), 0); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go lineLog(r, C.ANDROID_LOG_ERROR)
|
||||
|
||||
r, w, err = os.Pipe()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
stdout = w
|
||||
if err := syscall.Dup3(int(w.Fd()), int(os.Stdout.Fd()), 0); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go lineLog(r, C.ANDROID_LOG_INFO)
|
||||
}
|
41
internal/mobileinit/mobileinit_ios.go
Normal file
41
internal/mobileinit/mobileinit_ios.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package mobileinit
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include <os/log.h>
|
||||
|
||||
os_log_t create_os_log() {
|
||||
return os_log_create("org.golang.mobile", "os_log");
|
||||
}
|
||||
|
||||
void os_log_wrap(os_log_t log, const char *str) {
|
||||
os_log(log, "%s", str);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type osWriter struct {
|
||||
w C.os_log_t
|
||||
}
|
||||
|
||||
func (o osWriter) Write(p []byte) (n int, err error) {
|
||||
cstr := C.CString(string(p))
|
||||
C.os_log_wrap(o.w, cstr)
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
log.SetOutput(io.MultiWriter(os.Stderr, osWriter{C.create_os_log()}))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue