Esempio n. 1
0
func show(message string, long bool) {
	err := mobileinit.RunOnJVM(func(vm, env, ctx uintptr) error {
		cMessage := C.CString(message)
		defer C.free(unsafe.Pointer(cMessage))
		duration := C.jint(0) // TOAST_SHORT
		if long {
			duration = C.jint(1) // TOAST_LONG
		}
		C.toast_show(C.uintptr_t(vm), C.uintptr_t(env), C.uintptr_t(ctx), cMessage, duration)
		return nil
	})
	if err != nil {
		log.Fatalf("showToast: %v", err)
	}
}
Esempio n. 2
0
func (self *Environment) setIntField(z interface{}, static bool, name string, val int) (err error) {
	jval, field, err := self.getField(z, static, name, types.Basic(types.IntKind))
	if err != nil {
		return
	}
	if static {
		C.envSetStaticIntField(self.env, C.valObject(jval), field.field, C.jint(val))
	} else {
		C.envSetIntField(self.env, C.valObject(jval), field.field, C.jint(val))
	}
	if self.ExceptionCheck() {
		err = self.ExceptionOccurred()
	}
	return
}
Esempio n. 3
0
func (self *Environment) newByteObject(bts []byte) (o *Object, err error) {
	ja := C.envNewByteArray(self.env, C.jint(len(bts)))
	if ja == nil {
		err = errors.New("Error allocating byte array")
	}
	if err == nil && len(bts) > 0 {
		bptr := make([]byte, len(bts))
		copy(bptr, bts)
		//log.Printf("bptr: %s %p %p", bptr,bptr, &bptr[0] )
		C.envSetByteArrayRegion(self.env, ja, 0, C.jint(len(bptr)), unsafe.Pointer(&bptr[0]))
	}
	if err == nil {
		o = newObject(C.jobject(ja))
	}
	return
}
Esempio n. 4
0
func jIntValue(v interface{}) (C.jvalue, error) {
	val, ok := intValue(v)
	if !ok {
		return errJValue, fmt.Errorf("%#v isn't int", v)
	}
	return C.jIntValue(C.jint(val)), nil
}
Esempio n. 5
0
func (an *androidNotification) Close() {
	err := mobileinit.RunOnJVM(func(vm, env, ctx uintptr) error {
		C.notification_close(C.uintptr_t(vm), C.uintptr_t(env), C.uintptr_t(ctx), C.jint(an.id))
		return nil
	})
	if err != nil {
		log.Fatalf("Notification.Close: %v", err)
	}
}
Esempio n. 6
0
func (self *Environment) newObjectArray(sz int, klass *Class, init C.jobject) (o *Object, err error) {
	ja := C.envNewObjectArray(self.env, C.jint(sz), klass.class, init)
	if ja == nil {
		err = self.ExceptionOccurred()
	}
	if err == nil {
		o = newObject(C.jobject(ja))
	}
	return
}
Esempio n. 7
0
File: jvm.c.go Progetto: timob/gojvm
func defaultJVMArgs(ver int) (args *C.JavaVMInitArgs, err error) {
	if ver == 0 {
		ver = DEFAULT_JVM_VERSION
	}
	args = new(C.JavaVMInitArgs)
	//print("Default args\t", ver,"\n")
	args.version = C.jint(ver)
	if 0 != C.JNI_GetDefaultJavaVMInitArgs(unsafe.Pointer(args)) {
		err = errors.New("Couldn't contruct default JVM args")
	}
	return
}
Esempio n. 8
0
// C callbacks actually start in the 'generifiedX' calls (see the .c files)
// Next, goCallbackNArgs is used to determine the number of variadic paramers to expect (
// java doesn't inform us of this, and we can't force any of the callback parameters.
//
// Finally, goCallback looks up the 'fId' - our internal function reference ID (the X in generified),
// un(re) marshalls all the parameters appropriately, calls our function, and returns
// any underlying value back to generified who will return it to the JVM.
// The initial jbool indicates success, and any failure should check for exceptions.
//
//export goCallback
func goCallback(envp, obj uintptr, fId int, nargs int, argp uintptr) (ok C.jboolean, val interface{}) {
	args := C.ArgListPtr(unsafe.Pointer(argp))
	env := AllEnvs.Find(envp)
	if env == nil {
		panic("Got a nil environment")
	}
	if env.jvm == nil {
		panic("Environment pointer has no JVM")
	}
	var cd callbackDescriptor
	var _ok bool
	if cd, _ok = env.jvm.registered[fId]; !_ok {
		print("Unknown callbackId: \t", fId, "\n")
		return
	}
	// TODO: pack argp somehow...
	if nargs != len(cd.Signature.Params) {
		panic("callback/signature length mismatch")
	}
	inCall := []reflect.Value{reflect.ValueOf(env), reflect.ValueOf(newObject(C.jobject(unsafe.Pointer(obj))))}
	var err error
	for i := 0; i < nargs; i++ {
		switch cd.Signature.Params[i].Kind() {
		case types.BoolKind:
			inCall = append(inCall, reflect.ValueOf(bool(0 != C.valBool(C.getArg(args, C.int(i))))))
		case types.LongKind:
			inCall = append(inCall, reflect.ValueOf(int64(C.valLong(C.getArg(args, C.int(i))))))
		case types.IntKind:
			inCall = append(inCall, reflect.ValueOf(int(C.valInt(C.getArg(args, C.int(i))))))
		case types.ShortKind:
			inCall = append(inCall, reflect.ValueOf(int16(C.valShort(C.getArg(args, C.int(i))))))
		case types.FloatKind:
			inCall = append(inCall, reflect.ValueOf(float32(C.valFloat(C.getArg(args, C.int(i))))))
		case types.DoubleKind:
			inCall = append(inCall, reflect.ValueOf(float64(C.valDouble(C.getArg(args, C.int(i))))))
		case types.ClassKind:
			inCall = append(inCall, reflect.ValueOf(newObject(C.valObject(C.getArg(args, C.int(i))))))
		default:
			err = errors.New("Couldn't reflect kind " + cd.Signature.Params[i].Kind().TypeString())
		}
		if err != nil {
			break
		}
	}
	if err != nil {
		return
	}
	outCall := reflect.ValueOf(cd.F).Call(inCall)
	switch cd.Signature.Return.Kind() {
	case types.VoidKind:
		return 1, nil
	}
	switch cd.Signature.Return.Kind() {
	case types.BoolKind:
		if outCall[0].Interface().(bool) {
			return 1, C.jboolean(C.JNI_TRUE)
		} else {
			return 1, C.jboolean(C.JNI_FALSE)
		}
	case types.ByteKind:
		return 1, C.jbyte(outCall[0].Interface().(byte))
	case types.CharKind:
		return 1, C.jchar(outCall[0].Interface().(int))
	case types.IntKind:
		return 1, C.jint(outCall[0].Interface().(int))
	case types.ShortKind:
		return 1, C.jshort(outCall[0].Interface().(int16))
	case types.LongKind:
		return 1, C.jint(outCall[0].Interface().(int64))
	case types.FloatKind:
		return 1, C.jfloat(outCall[0].Interface().(float32))
	case types.DoubleKind:
		return 1, C.jdouble(outCall[0].Interface().(float64))
	case types.ClassKind:
		klass := cd.Signature.Return.(types.Class).Klass
		if klass.Cmp(types.JavaLangString) == 0 {
			var obj *Object
			str := outCall[0].Interface().(string)
			obj, err = env.NewStringObject(str)
			if err == nil {
				return 1, C.jstring(obj.object)
			} // else, exception occurred
			// not needed as callbacks will reap their own refs.
			// env.DeleteLocalRef(obj)
			print("String Error\t", err.Error())
			return 0, nil
		}
		return 1, C.jobject(outCall[0].Interface().(*Object).object)
	default:
		panic("array return type not yet supported")
	}

	panic("not reached")
}
Esempio n. 9
0
//	TODO(refcounting): any constructed objects will be leaked on call return,
//	as nothing cleans up proxy objects.  I'm also torn on how to differentiate
//	the objects made here  and those coming in from other references.
//
//	Refcounting attempt 1, objects _we_ construct will be returned in the objStack,
//	otherwise refcounts of 'pass-through' java natives are untouched by the call to newArgList.
//
//	On error, the stack has already been blown (and will be empty).
func newArgList(ctx *Environment, params ...interface{}) (alp argList, objStack []*Object, err error) {
	alp = make(argList, 0)
	defer func() {
		if err != nil {
			blowStack(ctx, objStack)
			objStack = []*Object{}
		}
	}()
	for i, param := range params {
		var ok C.int
		switch v := param.(type) {
		case int:
			alp = append(alp, C.intValue(C.jint(v)))
		case int64:
			alp = append(alp, C.longValue(C.jlong(v)))
		case C.jstring:
			alp = append(alp, C.objValue(v))
		case C.jboolean:
			alp = append(alp, C.boolValue(v))
		case C.jint:
			alp = append(alp, C.intValue(v))
		case C.jobject:
			alp = append(alp, C.objValue(v))
		case *Object:
			alp = append(alp, C.objValue(v.object))
		case *Class:
			alp = append(alp, C.objValue(v.class))
		case C.jvalue:
			alp = append(alp, v)
		case string:
			var str *Object
			str, err = ctx.NewStringObject(v)
			if err == nil {
				objStack = append(objStack, str)
				alp = append(alp, C.objValue(str.object))
			}
		case []string:
			var klass *Class
			var obj *Object
			klass, err = ctx.GetClassStr("java/lang/String")
			// classes via this channel are cached and globally referenced by gojvm, not stacked.
			if err == nil {
				obj, err = ctx.newObjectArray(len(v), klass, nil)
			}
			if err == nil {
				objStack = append(objStack, obj)
				for i, s := range v {
					var str *Object
					str, err = ctx.NewStringObject(s)
					if err == nil {
						// I'm assuming stuffing the array adds a reference inside the JVM.
						defer ctx.DeleteLocalRef(str)
						ctx.setObjectArrayElement(obj, i, str)
						if ctx.ExceptionCheck() {
							err = ctx.ExceptionOccurred()
						}

					}
					if err != nil {
						break
					}
				}
			}
			if err == nil {
				alp = append(alp, C.objValue(obj.object))
			}
		case []byte:
			var obj *Object
			obj, err = ctx.newByteObject(v)
			if err == nil {
				alp = append(alp, C.objValue(obj.object))
			}
			objStack = append(objStack, obj)
		case bool:
			val := C.jboolean(C.JNI_FALSE)
			if v {
				val = C.JNI_TRUE
			}
			alp = append(alp, C.boolValue(val))
		default:
			err = errors.New(fmt.Sprintf("Unknown type: %T/%s", v, v))
		}
		if ok != 0 {
			err = errors.New("Couldn't parse arg #" + strconv.Itoa(i+1))
		}
		if err != nil {
			break
		}
	}
	return
}
Esempio n. 10
0
func (self *Environment) setObjectArrayElement(arr *Object, pos int, item *Object) (err error) {
	C.envSetObjectArrayElement(self.env, arr.object, C.jint(pos), item.object)
	return
}
Esempio n. 11
0
// PushLocalFrame pushes a new local reference frame onto the reference frame
// stack. If the return value is >= 0, the new frame will have capacity for at
// least the specified number of local references. If the return value is < 0,
// the reference frame could not be created.
func PushLocalFrame(env Env, capacity int) int {
	return int(C.PushLocalFrame(env.value(), C.jint(capacity)))
}