framework是android的核心架构,主要对JAVA提供相应的接口。sensor部分上节中说了几个接口,我们跟进下去学习下。
localSensorManager.registerListener(this,localSensor, 3);
step 1:
\frameworks\base\core\java\android\hardware\SensorManager.java
public boolean registerListener(SensorListener listener, int sensors,int rate) {
return getLegacySensorManager().registerListener(listener,sensors, rate);
}
step 2:
frameworks\base\core\java\android\hardware\LegacySensorManager.java
public boolean registerListener(SensorListener listener, int sensors,int rate) {
if (listener == null) {
return false;
}
boolean result = false;
result = registerLegacyListener(SensorManager.SENSOR_ACCELEROMETER,
Sensor.TYPE_ACCELEROMETER,listener, sensors, rate) || result;
result = registerLegacyListener(SensorManager.SENSOR_MAGNETIC_FIELD,
Sensor.TYPE_MAGNETIC_FIELD,listener, sensors, rate) || result;
result = registerLegacyListener(SensorManager.SENSOR_ORIENTATION_RAW,
Sensor.TYPE_ORIENTATION,listener, sensors, rate) || result;
result = registerLegacyListener(SensorManager.SENSOR_ORIENTATION,
Sensor.TYPE_ORIENTATION,listener, sensors, rate) || result;
result = registerLegacyListener(SensorManager.SENSOR_TEMPERATURE,
Sensor.TYPE_TEMPERATURE,listener, sensors, rate) || result;
return result;
}
step 3:
frameworks\base\core\java\android\hardware\LegacySensorManager.java
private boolean registerLegacyListener(int legacyType, int type,
SensorListener listener, int sensors, int rate) {
boolean result = false;
// Are we activating this legacy sensor?
if ((sensors & legacyType) != 0) {
// if so, find a suitable Sensor
Sensor sensor = mSensorManager.getDefaultSensor(type);
if (sensor != null) {
// We do all of this workholding the legacy listener lock to ensure
// that the invariants aroundlisteners are maintained. This is safe
// because neitherregisterLegacyListener nor unregisterLegacyListener
// are called reentrantly whilesensors are being registered or unregistered.
synchronized(mLegacyListenersMap) {
// If we don't already haveone, create a LegacyListener
// to wrap this listenerand process the events as
// they are expected bylegacy apps.
LegacyListenerlegacyListener = mLegacyListenersMap.get(listener);
if (legacyListener == null){
// we didn't find aLegacyListener for this client,
// create one, and putit in our list.
legacyListener = newLegacyListener(listener);
mLegacyListenersMap.put(listener,legacyListener);
}
// register this legacysensor with this legacy listener
if(legacyListener.registerSensor(legacyType)) {
// and finally,register the legacy listener with the new apis
/*
有回调到SensorManager中的registerListener,但是注意这次带的参数类型为:
LegacyListenerimplements SensorEventListener
SensorEventListener是个接口,里面就是对于应用层的两个方法:onSensorChanged和onAccuracyChanged
public interfaceSensorEventListener {
/**
* Called when sensor values have changed.
* See {@linkandroid.hardware.SensorManager SensorManager}
* for details on possible sensor types.
* See also {@linkandroid.hardware.SensorEvent SensorEvent}.
*
* NOTE: Theapplication doesn't own the
* {@link android.hardware.SensorEventevent}
* object passed as a parameter andtherefore cannot hold on to it.
* The object may be part of an internalpool and may be reused by
* the framework.
*
* @param event the {@linkandroid.hardware.SensorEvent SensorEvent}.
*/
public void onSensorChanged(SensorEventevent);
/**
* Called when the accuracy of theregistered sensor has changed.
*
* See the SENSOR_STATUS_* constantsin
* {@link android.hardware.SensorManagerSensorManager} for details.
*
* @param accuracy The new accuracy of thissensor, one of
* {@code SensorManager.SENSOR_STATUS_*}
*/
public void onAccuracyCh
*/
result =mSensorManager.registerListener(legacyListener, sensor, rate);
} else {
result = true; //sensor already enabled
}
}
}
}
return result;
}
step 4:
\frameworks\base\core\java\android\hardware\SensorManager.java
public boolean registerListener(SensorEventListener listener, Sensorsensor, int samplingPeriodUs,
int maxReportLatencyUs, Handler handler) {
int delayUs = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor,delayUs, handler, maxReportLatencyUs, 0);
}
step 5:
\frameworks\base\core\java\android\hardware\SystemSensorManager.java
protected boolean registerListenerImpl(SensorEventListener listener,Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, intreservedFlags) {
if (listener == null || sensor == null) {
Log.e(TAG, "sensor or listener is null");
return false;
}
// Trigger Sensors should use the requestTriggerSensor call.
if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
return false;
}
if (maxBatchReportLatencyUs < 0 || delayUs < 0) {
Log.e(TAG, "maxBatchReportLatencyUs and delayUs should benon-negative");
return false;
}
// Invariants to preserve:
// - one Looper per SensorEventListener
// - one Looper per SensorEventQueue
// We map SensorEventListener to a SensorEventQueue, which holds thelooper
synchronized (mSensorListeners) {
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
/*
这里会给监听器创建一个进程,用来一直监听事件的发生。
*/
Looper looper = (handler !=null) ? handler.getLooper() : mMainLooper;
final String fullClassName =listener.getClass().getEnclosingClass() != null ?
listener.getClass().getEnclosingClass().getName() :
listener.getClass().getName();
/*
这里分开分析SensorEventQueue的创建和其addSensor方法。
*/
queue = new SensorEventQueue(listener, looper,this, fullClassName);
if (!queue.addSensor(sensor,delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener,queue);
return true;
} else {
return queue.addSensor(sensor,delayUs, maxBatchReportLatencyUs);
}
}
}
SensorEventQueue的创建如下:
step 6.1.1:
\frameworks\base\core\java\android\hardware\SystemSensorManager.java
public SensorEventQueue(SensorEventListener listener, Looper looper,
SystemSensorManager manager,String packageName) {
/*
SensorEventQueue的父类为BaseEventQueue,所以调用其父类的方法,也在该文档中。
BaseEventQueue里面有很多本地方法的调用。快到本地层了。
*/
super(looper, manager, OPERATING_MODE_NORMAL,packageName);
mListener = listener;
}
STEP 6.1.2:
\frameworks\base\core\java\android\hardware\SystemSensorManager.java
BaseEventQueue(Looper looper, SystemSensorManager manager, int mode,String packageName) {
if (packageName == null) packageName = "";
nSensorEventQueue =nativeInitBaseEventQueue(manager.mNativeInstance,
new WeakReference<>(this),looper.getQueue(), mScratch,
packageName, mode,manager.mContext.getOpPackageName());
mCloseGuard.open("dispose");
mManager = manager;
}
step 6.1.3:
\frameworks\base\core\jni\android_hardware_SensorManager.cpp
static jlongnativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
jobject eventQWeak, jobject msgQ, jfloatArray scratch, jstringpackageName, jint mode) {
SensorManager* mgr =reinterpret_cast
ScopedUtfChars packageUtf(env, packageName);
String8 clientName(packageUtf.c_str());
sp
sp
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is notinitialized.");
return 0;
}
sp
receiver->incStrong((void*)nativeInitSensorEventQueue);
return jlong(receiver.get());
}
step 6.1.4:
/*
Receiver创建后会自动执行onFirstRef, 在onFirstRef中,再执行mMessageQueue->getLooper()->addFd用来启动LoopCallback这句最关键了,
把channel的fd, 加到了looper的fd集合里,并且传递了this进入,本身class Receiver : public LooperCallback
就是继承LooperCallback, 所以server端的fd动作(SendEvent),都会被looper回调到Receiver的接口里, 实际
上是:Receiver::handleEvent.
*/
virtual void onFirstRef() {
LooperCallback::onFirstRef();
mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(),0,
ALOOPER_EVENT_INPUT, this,mSensorQueue.get());
}
virtual int handleEvent(int fd, int events,void* data) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
sp
ScopedLocalRef
ssize_t n;
ASensorEvent buffer[16];
while ((n = q->read(buffer, 16)) >0) {
for (int i=0 ; i if (buffer[i].type ==SENSOR_TYPE_STEP_COUNTER) { // step-counter returns auint64, but the java API only deals with floats float value =float(buffer[i].u64.step_counter); env->SetFloatArrayRegion(mScratch, 0, 1, &value); } else { env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data); } if (buffer[i].type ==SENSOR_TYPE_META_DATA) { // This is a flush completesensor event. Call dispatchFlushCompleteEvent // method. if (receiverObj.get()) { env->CallVoidMethod(receiverObj.get(), gBaseEventQueueClassInfo.dispatchFlushCompleteEvent, buffer[i].meta_data.sensor); } } else { int8_t status; switch (buffer[i].type) { caseSENSOR_TYPE_ORIENTATION: caseSENSOR_TYPE_MAGNETIC_FIELD: caseSENSOR_TYPE_ACCELEROMETER: case SENSOR_TYPE_GYROSCOPE: caseSENSOR_TYPE_GRAVITY: caseSENSOR_TYPE_LINEAR_ACCELERATION: status =buffer[i].vector.status; break; caseSENSOR_TYPE_HEART_RATE: status = buffer[i].heart_rate.status; break; default: status =SENSOR_STATUS_ACCURACY_HIGH; break; } if (receiverObj.get()) { env->CallVoidMethod(receiverObj.get(), gBaseEventQueueClassInfo.dispatchSensorEvent, buffer[i].sensor, mScratch, status, buffer[i].timestamp); } } if (env->ExceptionCheck()) { mSensorQueue->sendAck(buffer, n); ALOGE("Exceptiondispatching input event."); return 1; } } mSensorQueue->sendAck(buffer, n); } if (n<0 && n != -EAGAIN) { // FIXME: error receiving events, what to do in this case? } return 1; } }; step 6.1.5: frameworks\native\libs\gui\SensorEventQueue.cpp ssize_tSensorEventQueue::read(ASensorEvent* events, size_t numEvents) { if (mAvailable == 0) { ssize_t err = BitTube::recvObjects(mSensorChannel, mRecBuffer,MAX_RECEIVE_BUFFER_EVENT_COUNT); if (err < 0) { return err; } mAvailable = static_cast mConsumed = 0; } size_t count = min(numEvents, mAvailable); memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent)); mAvailable -= count; mConsumed += count; return static_cast } SensorEventQueue的addSensor如下: step :6.2.1 \frameworks\base\core\java\android\hardware\SystemSensorManager.java public boolean addSensor( Sensor sensor, int delayUs, intmaxBatchReportLatencyUs) { // Check if already present. int handle = sensor.getHandle(); if (mActiveSensors.get(handle)) return false; // Get ready to receive events before calling enable. mActiveSensors.put(handle, true); addSensorEvent(sensor); if (enableSensor(sensor, delayUs,maxBatchReportLatencyUs) != 0) { // Try continuous mode ifbatching fails. if (maxBatchReportLatencyUs ==0 || maxBatchReportLatencyUs> 0 && enableSensor(sensor, delayUs, 0) != 0) { removeSensor(sensor, false); return false; } } return true; } step 6.2.2: \frameworks\base\core\java\android\hardware\SystemSensorManager.java private int enableSensor( Sensor sensor, int rateUs, intmaxBatchReportLatencyUs) { if (nSensorEventQueue == 0) throw new NullPointerException(); if (sensor == null) throw newNullPointerException(); return nativeEnableSensor(nSensorEventQueue,sensor.getHandle(), rateUs, maxBatchReportLatencyUs); } step 6.2.3: \frameworks\base\core\jni\android_hardware_SensorManager.cpp static jint nativeEnableSensor(JNIEnv *env,jclass clazz, jlong eventQ, jint handle, jint rate_us, jintmaxBatchReportLatency) { sp return receiver->getSensorEventQueue()->enableSensor(handle,rate_us, maxBatchReportLatency, 0); } step 6.2.4: \frameworks\native\libs\gui\SensorEventQueue.cpp status_t SensorEventQueue::enableSensor(Sensorconst* sensor) const { return mSensorEventConnection->enableDisable(sensor->getHandle(),true, 0, 0, false); } step 6.2.5: \frameworks\native\libs\gui\SurfaceComposerClient.cpp virtual status_t enableDisable(int handle, bool enabled, nsecs_tsamplingPeriodNs, nsecs_tmaxBatchReportLatencyNs, int reservedFlags) { Parcel data, reply; data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor()); data.writeInt32(handle); data.writeInt32(enabled); data.writeInt64(samplingPeriodNs); data.writeInt64(maxBatchReportLatencyNs); data.writeInt32(reservedFlags); remote()->transact(ENABLE_DISABLE, data, &reply); return reply.readInt32(); } step 6.2.6: frameworks\native\services\sensorservice\SensorService.cpp status_tSensorService::SensorEventConnection::enableDisable( int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_tmaxBatchReportLatencyNs, int reservedFlags) { status_t err; if (enabled) { err = mService->enable(this, handle,samplingPeriodNs, maxBatchReportLatencyNs, reservedFlags,mOpPackageName); }else { err = mService->disable(this, handle); } return err; } step 6.2.7: frameworks\native\services\sensorservice\SensorService.cpp status_t SensorService::enable(constsp int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,int reservedFlags, const String16& opPackageName) { if (mInitCheck != NO_ERROR) return mInitCheck; SensorInterface* sensor = mSensorMap.valueFor(handle); if (sensor == NULL) { return BAD_VALUE; } if (!canAccessSensor(sensor->getSensor(), "Tried enabling",opPackageName)) { return BAD_VALUE; } Mutex::Autolock _l(mLock); if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode ==DATA_INJECTION) && !isWhiteListedPackage(connection->getPackageName())) { return INVALID_OPERATION; } SensorRecord* rec = mActiveSensors.valueFor(handle); if (rec == 0) { rec = new SensorRecord(connection); mActiveSensors.add(handle, rec); if (sensor->isVirtual()) { mActiveVirtualSensors.add(handle, sensor); } }else { if (rec->addConnection(connection)) { // this sensor is already activated, but we are adding a connection thatuses it. // Immediately send down the last known value of the requested sensor ifit's not a // "continuous" sensor. if (sensor->getSensor().getReportingMode() ==AREPORTING_MODE_ON_CHANGE) { // NOTE: The wake_up flag ofthis event may get set to //WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event. CircularBuffer *circular_buf =mLastEventSeen.valueFor(handle); if (circular_buf) { sensors_event_t event; memset(&event, 0,sizeof(event)); // It is unlikely that thisbuffer is empty as the sensor is already active. // One possible corner casemay be two applications activating an on-change // sensor at the same time. if(circular_buf->populateLastEvent(&event)) { event.sensor = handle; if (event.version ==sizeof(sensors_event_t)) { if(isWakeUpSensorEvent(event) && !mWakeLockAcquired) { setWakeLockAcquiredLocked(true); } connection->sendEvents(&event, 1, NULL); if(!connection->needsWakeLock() && mWakeLockAcquired) { checkWakeLockStateLocked(); } } } } } } } if (connection->addSensor(handle)) { BatteryService::enableSensor(connection->getUid(), handle); // the sensor was added (which means it wasn't already there) // so, see if this connection becomes active if (mActiveConnections.indexOf(connection) < 0) { mActiveConnections.add(connection); } }else { ALOGW("sensor %08x already enabled in connection %p(ignoring)", handle, connection.get()); } nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); if (samplingPeriodNs < minDelayNs) { samplingPeriodNs = minDelayNs; } ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%dflags=%d" "rate=%" PRId64 " timeout== %" PRId64"", handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs); status_t err = sensor->batch(connection.get(), handle, 0,samplingPeriodNs, maxBatchReportLatencyNs); // Call flush() before calling activate() on the sensor. Wait for afirst flush complete // event before sending events on this connection. Ignore one-shotsensors which don't // support flush(). Also if this sensor isn't already active, don't callflush(). if (err == NO_ERROR && sensor->getSensor().getReportingMode()!= AREPORTING_MODE_ONE_SHOT && rec->getNumConnections() > 1) { connection->setFirstFlushPending(handle, true); status_t err_flush = sensor->flush(connection.get(), handle); // Flush may return error if the underlying h/w sensor uses an olderHAL. if (err_flush == NO_ERROR) { rec->addPendingFlushConnection(connection.get()); } else { connection->setFirstFlushPending(handle, false); } } if (err == NO_ERROR) { ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle); err =sensor->activate(connection.get(), true); } if (err == NO_ERROR) { connection->updateLooperRegistration(mLooper); SensorRegistrationInfo ®_info = mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex); reg_info.mSensorHandle = handle; reg_info.mSamplingRateUs = samplingPeriodNs/1000; reg_info.mMaxReportLatencyUs = maxBatchReportLatencyNs/1000; reg_info.mActivated = true; reg_info.mPackageName = connection->getPackageName(); time_t rawtime = time(NULL); struct tm * timeinfo = localtime(&rawtime); reg_info.mHour = timeinfo->tm_hour; reg_info.mMin = timeinfo->tm_min; reg_info.mSec = timeinfo->tm_sec; mNextSensorRegIndex = (mNextSensorRegIndex + 1) %SENSOR_REGISTRATIONS_BUF_SIZE; } if (err != NO_ERROR) { // batch/activate has failed, reset our state. cleanupWithoutDisableLocked(connection, handle); } return err; } step 6.2.8: frameworks\native\services\sensorservice\SensorInterface.cpp status_t HardwareSensor::activate(void*ident, bool enabled) { return mSensorDevice.activate(ident,mSensor.getHandle(), enabled); } step 6.2.9: frameworks\native\services\sensorservice\SensorDevice.cpp status_t SensorDevice::activate(void*ident, int handle, int enabled) { if (!mSensorDevice) return NO_INIT; status_t err(NO_ERROR); bool actuateHardware = false; Mutex::Autolock _l(mLock); Info& info( mActivationCount.editValueFor(handle) ); ALOGD_IF(DEBUG_CONNECTIONS, "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d,count=%zu", ident, handle, enabled, info.batchParams.size()); if (enabled) { ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd",info.batchParams.indexOfKey(ident)); if (isClientDisabledLocked(ident)) { return INVALID_OPERATION; } if (info.batchParams.indexOfKey(ident) >= 0) { if (info.numActiveClients() == 1) { // This is the first connection,we need to activate the underlying h/w sensor. actuateHardware = true; } } else { // Log error. Every activate call should be preceded by a batch() call. ALOGE("\t >>>ERROR: activate called without batch"); } }else { ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd",info.batchParams.indexOfKey(ident)); if (info.removeBatchParamsForIdent(ident) >= 0) { if (info.numActiveClients() == 0) { // This is the last connection,we need to de-activate the underlying h/w sensor. actuateHardware = true; } else { const int halVersion =getHalDeviceVersion(); if (halVersion >=SENSORS_DEVICE_API_VERSION_1_1) { // Call batch for thissensor with the previously calculated best effort // batch_rate and timeout.One of the apps has unregistered for sensor // events, and the besteffort batch parameters might have changed. ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w batch %d %d %" PRId64 "%" PRId64, handle, info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); mSensorDevice->batch(mSensorDevice,handle,info.bestBatchParams.flags, info.bestBatchParams.batchDelay, info.bestBatchParams.batchTimeout); } } } else { // sensor wasn't enabled for this ident } if (isClientDisabledLocked(ident)) { return NO_ERROR; } } if (actuateHardware) { ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activatehandle=%d enabled=%d", handle, enabled); err = mSensorDevice->activate( reinterpret_cast ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ?"activating" : "disabling", handle, strerror(-err)); if (err != NO_ERROR && enabled) { // Failure when enabling the sensor. Clean up on failure. info.removeBatchParamsForIdent(ident); } } // On older devices which do not support batch, call setDelay(). if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 &&info.numActiveClients() > 0) { ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay%d %" PRId64, handle, info.bestBatchParams.batchDelay); mSensorDevice->setDelay( reinterpret_cast handle,info.bestBatchParams.batchDelay); } return err; } /* mSensorDevice会从HAL层获取到各个sensor 的相关信息。mSensorDevice->activate就是对应的各个SENSOR驱动里面的enable.具体可以看HAL层的分析。 SensorDevice::SensorDevice() : mSensorDevice(0), mSensorModule(0) { status_t err =hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule); ALOGE_IF(err,"couldn't load %s module (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); if(mSensorModule) { err =sensors_open_1(&mSensorModule->common, &mSensorDevice); ALOGE_IF(err, "couldn't open device for module %s (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); if(mSensorDevice) { if(mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_1 || mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_2) { ALOGE(">>>> WARNING <<< Upgrade sensor HAL toversion 1_3"); } sensor_t const* list; ssize_tcount = mSensorModule->get_sensors_list(mSensorModule, &list); mActivationCount.setCapacity(count); Infomodel; for (size_t i=0 ; i mActivationCount.add(list[i].handle, model); mSensorDevice->activate( reinterpret_cast list[i].handle, 0); } } } } */