twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

mobileinit_android.go (1911B)


      1 // Copyright 2014 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package mobileinit
      6 
      7 /*
      8 To view the log output run:
      9 adb logcat GoLog:I *:S
     10 */
     11 
     12 // Android redirects stdout and stderr to /dev/null.
     13 // As these are common debugging utilities in Go,
     14 // we redirect them to logcat.
     15 //
     16 // Unfortunately, logcat is line oriented, so we must buffer.
     17 
     18 /*
     19 #cgo LDFLAGS: -landroid -llog
     20 
     21 #include <android/log.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 */
     25 import "C"
     26 
     27 import (
     28 	"bufio"
     29 	"log"
     30 	"os"
     31 	"syscall"
     32 	"unsafe"
     33 )
     34 
     35 var (
     36 	ctag = C.CString("GoLog")
     37 	// Store the writer end of the redirected stderr and stdout
     38 	// so that they are not garbage collected and closed.
     39 	stderr, stdout *os.File
     40 )
     41 
     42 type infoWriter struct{}
     43 
     44 func (infoWriter) Write(p []byte) (n int, err error) {
     45 	cstr := C.CString(string(p))
     46 	C.__android_log_write(C.ANDROID_LOG_INFO, ctag, cstr)
     47 	C.free(unsafe.Pointer(cstr))
     48 	return len(p), nil
     49 }
     50 
     51 func lineLog(f *os.File, priority C.int) {
     52 	const logSize = 1024 // matches android/log.h.
     53 	r := bufio.NewReaderSize(f, logSize)
     54 	for {
     55 		line, _, err := r.ReadLine()
     56 		str := string(line)
     57 		if err != nil {
     58 			str += " " + err.Error()
     59 		}
     60 		cstr := C.CString(str)
     61 		C.__android_log_write(priority, ctag, cstr)
     62 		C.free(unsafe.Pointer(cstr))
     63 		if err != nil {
     64 			break
     65 		}
     66 	}
     67 }
     68 
     69 func init() {
     70 	log.SetOutput(infoWriter{})
     71 	// android logcat includes all of log.LstdFlags
     72 	log.SetFlags(log.Flags() &^ log.LstdFlags)
     73 
     74 	r, w, err := os.Pipe()
     75 	if err != nil {
     76 		panic(err)
     77 	}
     78 	stderr = w
     79 	if err := syscall.Dup3(int(w.Fd()), int(os.Stderr.Fd()), 0); err != nil {
     80 		panic(err)
     81 	}
     82 	go lineLog(r, C.ANDROID_LOG_ERROR)
     83 
     84 	r, w, err = os.Pipe()
     85 	if err != nil {
     86 		panic(err)
     87 	}
     88 	stdout = w
     89 	if err := syscall.Dup3(int(w.Fd()), int(os.Stdout.Fd()), 0); err != nil {
     90 		panic(err)
     91 	}
     92 	go lineLog(r, C.ANDROID_LOG_INFO)
     93 }