Search code examples
androidandroid-ndkandroid-sourceandroid-framework

How JNI .cpp files sending events to Java framework in Android


I have registered a listener on , MotionSensors, now whenever Motion change Method "onSensorChange()" will be called.

I know these calls intitates from SensorManager.java class. I want to know how these sensors change events comes from JNI, How JNI trigger change Event and send it to Framework(SensorManager.java).


Solution

  • If you know where exactly is the code it is not difficult to check how it works. So the main part is here:

           while (true) {
                // wait for an event
                final int sensor = sensors_data_poll(sQueue, values, status, timestamp);
    
                int accuracy = status[0];
                synchronized (sListeners) {
                    if (sensor == -1 || sListeners.isEmpty()) {
                        // we lost the connection to the event stream. this happens
                        // when the last listener is removed or if there is an error
                        if (sensor == -1 && !sListeners.isEmpty()) {
                            // log a warning in case of abnormal termination
                            Log.e(TAG, "_sensors_data_poll() failed, we bail out: sensors=" + sensor);
                        }
                        // we have no more listeners or polling failed, terminate the thread
                        sensors_destroy_queue(sQueue);
                        sQueue = 0;
                        mThread = null;
                        break;
                    }
                    final Sensor sensorObject = sHandleToSensor.get(sensor);
                    if (sensorObject != null) {
                        // report the sensor event to all listeners that
                        // care about it.
                        final int size = sListeners.size();
                        for (int i=0 ; i<size ; i++) {
                            ListenerDelegate listener = sListeners.get(i);
                            if (listener.hasSensor(sensorObject)) {
                                // this is asynchronous (okay to call
                                // with sListeners lock held).
                                listener.onSensorChangedLocked(sensorObject,
                                        values, timestamp, accuracy);
                            }
                        }
                    }
                }
            }
            //Log.d(TAG, "exiting main sensor thread");
        }
    

    This code is run in a separate thread SensorThreadRunnable constantly (while (true)). At first it calls native function sensors_data_poll which returns the identifier of the sensor that have changed it's value (or -1 if there is no such sensors). If it returns -1 the cycle is started from the beginning. If the sensor values have been changed then from the sensor identifier created sensorObject (final Sensor sensorObject = sHandleToSensor.get(sensor);). After that there is a cycle that runs across all the registered listener and if a listener is listen to this sensor object it is notified that the value of the sensor has been changed.