1==== Summary ====
2
3android.frameworks.sensorservice@1.0 is a package that mimics the sensors API in
4NDK (sensor.h). It includes a subset of these APIs and introduces a few
5adaptations.
6
7=== Design Details ===
8
9- ISensorManager
10ISensorMangaer includes member functions that adapts the ASensorManager_*
11series in NDK. An instance of ISensorManager must be able to
12    - retrieve sensors
13    - create direct report channel
14    - create event queue
15
16- IDirectReportChannel
17IDirectReportChannel corresponds to a channel ID, an integer obtained in
18ASensorManager_createSharedMemoryDirectChannel and
19ASensorManager_createHardwareBufferDirectChannel. An instance of
20IDirectReportChannel must also destroy it against the sensor manager. An
21IDirectReportChannel must be able to configure itself (an adaptation to
22ASensorManager_configureDirectReport). The implementation must also call
23ASensorManager_destroyEventQueue on destruction of IDirectReportChannel.
24
25Usage typically looks like this (transaction errors are not handled):
26
27    sp<ISensorManager> manager = ISensorManager::getService();
28    int32_t sensorHandle;
29    manager->getDefaultSensor(SensorType::GYROSCOPE,
30            [&sensorHandle] (const auto &info) {
31                sensorHandle = info.sensorHandle;
32            });
33    hidl_memory mem;
34    const uint64_t size = 4096;
35    ::android::hidl::memory::V1_0::IAllocator::getService()->allocate(size,
36            [&](auto, const auto &m) { mem = m; });
37    if (!mem.handle()) {
38        /* error handling */
39    }
40    sp<IDirectChannel> chan;
41    Result res;
42    manager->createAshmemDirectChannel(mem, size,
43            [&chan, &res] (const auto &c, auto r) {
44                chan = c; res = r;
45            });
46    if (res != Result::OK) { /* error handling */ }
47    chan->configure(sensorHandle, RateLevel::FAST, [&](auto token, auto result) {
48        if (result != Result::OK) {
49            /* error handling */
50        }
51    });
52
53    /* obtain sensor events from shared memory */
54
55    chan->configure(sensorHandle, RateLevel::STOP, [&](auto token, auto result) {
56        if (result != Result::OK) {
57            /* error handling */
58        }
59    });
60
61    /*
62     * Free the channel.
63     * kernel calls decStrong() on server side implementation of IDirectChannel,
64     * hence resources are freed as well.
65     */
66     chan = nullptr;
67
68- IEventQueue, IEventQueueCallback
69IEventQueue includes member functions that adapts some of the
70ASensorEventQueue_* seeries in NDK. An instance of IEventQueue must be able to
71    - enable  selected sensors (adapts ASensorEventQueue_registerSensor)
72    - disable selected sensors (adapts ASensorEventQueue_disableSensor)
73
74The implementation must free all resources related to this IEventQueue instance
75and call ASensorManager_destroyEventQueue on destruction of IEventQueue.
76
77Unlike NDK ASensorEventQueue_hasEvents and ASensorEventQueue_getEvents, which
78implies a poll model for sensor events, IEventQueue uses a push model by using
79callbacks. When creating an event queue, client must provide an instance of
80IEventQueueCallback. The implementation of IEventQueue must either use a global
81looper or create a new looper to call on ASensorManager_createEventQueue. The
82server implementation must use this looper to constantly poll for events, then
83invoke the callback when any event is fired.
84
85IEventQueueCallback.onEvent is designed to be oneway, because the server should
86not wait for the client to finish handling the event. The callback
87should finish in a predictably short time, and should not block or run for an
88extended period of time. The callbacks can be invoked in a very high frequency;
89a long running callback means delay in handling of subsequent events and filling
90up the (kernel binder buffer) memory space of the client process, eventually the
91server sees a transaction error when issuing the callback. It is up to the
92client to be configured single-threaded or multi-threaded to handle these
93callbacks.
94    - Single-threaded clients receive events in the correct order in the same
95      thread.
96    - Multi-threaded clients receive events in the correct order but in
97      different threads; it is the clients' responsibility to deal with
98      concurrency issues and handle events in the expected order to avoid race
99      conditions.
100
101Usage typically looks like this (transaction errors are not handled):
102
103    struct Callback : IEventQueueCallback {
104        Return<void> onEvent(const Event &e) {
105            /* handle sensor event e */
106        }
107    };
108    sp<ISensorManager> manager = ISensorManager::getService();
109    int32_t sensorHandle;
110    manager->getDefaultSensor(SensorType::GYROSCOPE,
111            [&sensorHandle] (const auto &info) {
112                sensorHandle = info.sensorHandle;
113            });
114    sp<IEventQueue> queue;
115    Result res;
116    manager->createEventQueue(new Callback(),
117            [&queue, &res] (const auto &q, auto r) {
118                queue = q; res = r;
119            });
120    /* Server side implementation of IEventQueue holds a strong reference to
121     * the callback. */
122    if (res != Result::OK) { /* error handling */ }
123
124    if (q->enableSensor(sensorHandle,
125            20000 /* sample period */, 0 /* latency */) != Result::OK) {
126        /* error handling */
127    }
128
129    /* start receiving events via onEvent */
130
131    if (q->disableSensor(sensorHandle) != Result::OK) {
132        /* error handling */
133    }
134
135    /*
136     * Free the event queue.
137     * kernel calls decStrong() on server side implementation of IEventQueue,
138     * hence resources (including the callback) are freed as well.
139     */
140    queue = nullptr;
141