// init inits the manager and creates a goroutine to proxy the CGO calls. // All actions related to an ALooper needs to be performed from the same // OS thread. The goroutine proxy locks itself to an OS thread and handles the // CGO traffic on the same thread. func init() { go func() { runtime.LockOSThread() C.GoAndroid_createManager() for { v := <-inout switch s := v.in.(type) { case enableSignal: usecsDelay := s.delay.Nanoseconds() / 1000 code := int(C.GoAndroid_enableSensor(typeToInt(s.t), C.int32_t(usecsDelay))) if code != 0 { *s.err = fmt.Errorf("sensor: no default %v sensor on the device", s.t) } case disableSignal: C.GoAndroid_disableSensor(typeToInt(s.t)) case readSignal: n := readEvents(s.dst) *s.n = n case closeSignal: C.GoAndroid_destroyManager() close(v.out) return // we don't need this goroutine anymore } close(v.out) } }() }
// initialize inits the manager and creates a goroutine to proxy the CGO calls. // All actions related to an ALooper needs to be performed from the same // OS thread. The goroutine proxy locks itself to an OS thread and handles the // CGO traffic on the same thread. func (m *manager) initialize() { m.inout = make(chan inOut) go func() { runtime.LockOSThread() for { v := <-m.inout switch s := v.in.(type) { case initSignal: id := atomic.AddInt64(&nextLooperID, 1) var mgr C.GoAndroid_SensorManager C.GoAndroid_createManager(C.int(id), &mgr) m.m = &mgr case enableSignal: usecsDelay := s.delay.Nanoseconds() / 1000 code := int(C.GoAndroid_enableSensor(m.m.queue, typeToInt(s.t), C.int32_t(usecsDelay))) if code != 0 { *s.err = fmt.Errorf("sensor: no default %v sensor on the device", s.t) } case disableSignal: C.GoAndroid_disableSensor(m.m.queue, typeToInt(s.t)) case readSignal: n, err := readEvents(m, s.dst) *s.n = n *s.err = err case closeSignal: C.GoAndroid_destroyManager(m.m) close(v.out) return // we don't need this goroutine anymore } close(v.out) } }() if m.m == nil { done := make(chan struct{}) m.inout <- inOut{ in: initSignal{}, out: done, } <-done } }