I've been trying to access GPIO on Raspberry Pi with Android things using NDK, but after trying several approaches I always find some kind of security wall preventing me from accessing it.
The motivation is the sluggish speed I'm getting from GPIO using the Java API. As a basic reference I was able to toggle it on and off at about 2KHz, which happens to be the poorest among this list. See also What is Android Things Raspberry Pi GPIO max frequency?, where so far there's no answer and where I added a comment about java speed. In fact this work was motivated by the results I got when checking for that question.
The best approach so far is trying something similar to what would take for sysfs under Debian. To that extent, the code seems fair but after running as root, installing the app as system app (by moving it to /system/app) and chmod a+rw several different things under both /sys/class/gpio/
and /sys/class/gpio/gpio24/
and also /dev/gpiomem
this was what I got:
01-27 12:54:47.069 8412 8412 I NativeHelper: Call native = hello from helper java class
01-27 12:54:47.079 8412 8412 I NativeHelper: Open pin true
01-27 12:54:47.080 8412 8412 F libc : Fatal signal 4 (SIGILL), code 1, fault addr 0xaf2e039c in tid 8412 (le.thingssample)
01-27 12:54:47.081 128 128 W : debuggerd: handling request: pid=8412 uid=10028 gid=10028 tid=8412
01-27 12:54:47.066 8412 8412 I le.thingssample: type=1400 audit(0.0:211): avc: denied { write } for name="export" dev="sysfs" ino=854 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1
01-27 12:54:47.076 8412 8412 I le.thingssample: type=1400 audit(0.0:212): avc: denied { open } for path="/sys/class/gpio/export" dev="sysfs" ino=854 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1
01-27 12:54:47.166 8427 8427 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-27 12:54:47.166 8427 8427 F DEBUG : Build fingerprint: 'generic/iot_rpi3/rpi3:7.0/NIF73/3565696:userdebug/test-keys'
01-27 12:54:47.166 8427 8427 F DEBUG : Revision: '0'
01-27 12:54:47.166 8427 8427 F DEBUG : ABI: 'arm'
01-27 12:54:47.167 8427 8427 F DEBUG : pid: 8412, tid: 8412, name: le.thingssample >>> com.amazingapps.sample.thingssample <<<
01-27 12:54:47.167 8427 8427 F DEBUG : signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 0xaf2e039c
01-27 12:54:47.167 8427 8427 F DEBUG : r0 00000000 r1 b1f5e59f r2 b1f5e59f r3 af2e1c55
01-27 12:54:47.167 8427 8427 F DEBUG : r4 00000000 r5 be8e35fc r6 acca3230 r7 be8e35d8
01-27 12:54:47.167 8427 8427 F DEBUG : r8 be8e36f8 r9 acc85400 sl 00000000 fp be8e3684
01-27 12:54:47.168 8427 8427 F DEBUG : ip be8e3590 sp be8e3598 lr ae7fbd2b pc af2e039c cpsr 60000030
01-27 12:54:47.170 8427 8427 F DEBUG :
01-27 12:54:47.170 8427 8427 F DEBUG : backtrace:
01-27 12:54:47.170 8427 8427 F DEBUG : #00 pc 0000139c /data/app/com.amazingapps.sample.thingssample-1/lib/arm/libsample.so (Java_com_amazingapps_sample_thingssample_ndk_NativeHelper_doAll+59)
01-27 12:54:47.170 8427 8427 F DEBUG : #01 pc 002c8cb3 /data/app/com.amazingapps.sample.thingssample-1/oat/arm/base.odex (offset 0x2af000)
01-27 12:54:48.133 408 8432 W ActivityManager: Force finishing activity com.amazingapps.sample.thingssample/.view.MainActivity
01-27 12:54:48.137 128 128 W : debuggerd: resuming target 8412
01-27 12:54:48.138 408 427 I BootReceiver: Copying /data/tombstones/tombstone_02 to DropBox (SYSTEM_TOMBSTONE)
01-27 12:54:48.228 8433 8433 W crash_reporter: Received crash notification for app_process32[8412] sig 4, user 10028 (handling)
01-27 12:54:48.233 8433 8433 I crash_reporter: State of crashed process [8412]: S (sleeping)
01-27 12:54:48.226 8433 8433 I crash_reporter: type=1400 audit(0.0:213): avc: denied { search } for name="8412" dev="proc" ino=214991 scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=dir permissive=1
01-27 12:54:48.226 8433 8433 I crash_reporter: type=1400 audit(0.0:214): avc: denied { read } for name="exe" dev="proc" ino=217417 scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=lnk_file permissive=1
01-27 12:54:48.226 8433 8433 I crash_reporter: type=1400 audit(0.0:215): avc: denied { read } for scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=file permissive=1
01-27 12:54:48.226 8433 8433 I crash_reporter: type=1400 audit(0.0:216): avc: denied { open } for path="/proc/8412/status" dev="proc" ino=216902 scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=file permissive=1
01-27 12:54:48.226 8433 8433 I crash_reporter: type=1400 audit(0.0:217): avc: denied { getattr } for path="/proc/8412/status" dev="proc" ino=216902 scontext=u:r:crash_reporter:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=file permissive=1
01-27 12:54:48.672 408 422 W ActivityManager: Activity pause timeout for ActivityRecord{f2233fb u0 com.amazingapps.sample.thingssample/.view.MainActivity t86 f}
By chmod a+rw /sys/class/gpio/export
at least I got a difference and could open and close the pin, verified by the method return value and also checking the creation of /sys/class/gpio/gpio24
.
I'm trying on a Raspberry Pi 3 with the following code: https://github.com/fmatosqg/androidthings_ndk/tree/SO_question
In another approach I tried loading libperipheralman.so
directly in java in the hopes of making calls to its functions (apparently that's where GPIO setValue() lives), but this time I ran into a different kind of problem where a subset of the libraries were denied being loaded by some security problem. See Nougat documentation about them not allowing developers to access all .so because of back/future compatibility purposes.
I guess that any implementation that skips using Java VM/Dalvik has also the potential of gettting me closer to my goal, which is getting decent GPIO speed on an .apk, but I'm unaware if any of the approaches that work on rpi3 + debian can be used here.