ref: 0818148b0432a1b11d2feb72cca47156a603e884
dir: /gui-android/cpp/devandroid.c/
#include "u.h" #include "lib.h" #include "dat.h" #include "fns.h" #include "error.h" //#include <android/log.h> #include <android/sensor.h> void show_notification(char *buf); void take_picture(int id); int num_cameras(); long getlocation(char *a, long n); int Ncameras = 0; uchar *cambuf = nil; int camlen = 0; static char camopen = 0; ASensorManager *sensorManager = NULL; enum { Qdir = 0, Qaccel, Qcompass, Qnotify, Qlocation, Ntab, Qcam = 8, }; Dirtab androiddir[] = { ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, "accel", {Qaccel}, 0, 0444, "compass", {Qcompass}, 0, 0444, "notify", {Qnotify}, 0, 0222, "location", {Qlocation}, 0, 0444, "camNNNN", {Qcam}, 0, 0444, }; static void androidinit(void); static void androidinit(void) { sensorManager = ASensorManager_getInstance(); Ncameras = num_cameras(); } static Chan* androidattach(char *param) { return devattach('N', param); } int androidgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp) { Qid q; if(tab == 0) return -1; if(i == DEVDOTDOT){ /* nothing */ }else if(name){ // __android_log_print(ANDROID_LOG_WARN, "drawterm", "androidgen name %s", name); for(i=1; i<Ntab; i++) if(strcmp(tab[i].name, name) == 0) break; if (i == Ntab) { if (strncmp("cam", name, 3) == 0 && name[3] >= '0' && name[3] <= '9' && strspn(&name[3], "0123456789") == (strlen(name) - 3) && (i = atoi(&name[3])) < Ncameras) i += Ntab; else return -1; } if(i > Ntab) tab += Ntab; else tab += i; }else{ // __android_log_print(ANDROID_LOG_WARN, "drawterm", "androidgen i %d", i); /* skip over the first element, that for . itself */ i++; if(i >= ntab) return -1; if(i >= Ntab) tab += Ntab; else tab += i; } if (i >= Ntab) { q = tab->qid; q.path |= ((i - Ntab) << 16); sprintf(up->genbuf, "cam%d", i - Ntab); devdir(c, q, up->genbuf, tab->length, eve, tab->perm, dp); return 1; } devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); return 1; } static Walkqid* androidwalk(Chan *c, Chan *nc, char **name, int nname) { return devwalk(c, nc, name, nname, androiddir, nelem(androiddir) + Ncameras - 1, androidgen); } static int androidstat(Chan *c, uchar *db, int n) { return devstat(c, db, n, androiddir, nelem(androiddir) + Ncameras - 1, androidgen); } static Chan* androidopen(Chan *c, int omode) { int i; if (c->qid.path & Qcam) { if (camopen != 0) { error(Einuse); } else { camopen = 1; i = c->qid.path >> 16; take_picture(i); } } c = devopen(c, omode, androiddir, nelem(androiddir) + Ncameras - 1, androidgen); return c; } static void androidclose(Chan *c) { if (c->qid.path & Qcam && camopen != 0) { free(cambuf); cambuf = nil; camlen = 0; camopen = 0; } } long readsensor(char *a, long n, int type) { long l; const ASensor *sensor; ASensorEventQueue *queue = NULL; ASensorEvent data; queue = ASensorManager_createEventQueue(sensorManager, ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS), 1, NULL, NULL); if (queue == NULL) return 0; sensor = ASensorManager_getDefaultSensor(sensorManager, type); if (sensor == NULL) { ASensorManager_destroyEventQueue(sensorManager, queue); return 0; } if (ASensorEventQueue_enableSensor(queue, sensor)) { ASensorEventQueue_disableSensor(queue, sensor); ASensorManager_destroyEventQueue(sensorManager, queue); return 0; } l = 0; if (ALooper_pollAll(1000, NULL, NULL, NULL) == 1) { if (ASensorEventQueue_getEvents(queue, &data, 1)) { l = snprint(a, n, "%11f %11f %11f\n", data.vector.x, data.vector.y, data.vector.z); } } ASensorEventQueue_disableSensor(queue, sensor); ASensorManager_destroyEventQueue(sensorManager, queue); return l; } static long androidread(Chan *c, void *v, long n, vlong off) { char *a = v; long l; switch((ulong)c->qid.path & 0xF) { default: error(Eperm); return -1; case Qcam: while(camlen == 0) usleep(10 * 1000); if(camlen < 0) { error(Eio); return -1; } l = camlen - off; if (l > n) l = n; if (l > 0) memcpy(a, cambuf + off, l); return l; case Qaccel: return readsensor(a, n, ASENSOR_TYPE_ACCELEROMETER); case Qcompass: return readsensor(a, n, ASENSOR_TYPE_MAGNETIC_FIELD); case Qlocation: return getlocation(a, n); case Qdir: return devdirread(c, a, n, androiddir, nelem(androiddir) + Ncameras - 1, androidgen); } } static long androidwrite(Chan *c, void *vp, long n, vlong off) { char *a = vp; char *str; switch((ulong)c->qid.path) { case Qnotify: str = malloc(n+1); memcpy(str, a, n); str[n] = '\0'; show_notification(str); free(str); return n; default: error(Eperm); break; } return -1; } Dev androiddevtab = { 'N', "android", devreset, androidinit, devshutdown, androidattach, androidwalk, androidstat, androidopen, devcreate, androidclose, androidread, devbread, androidwrite, devbwrite, devremove, devwstat, };