sensor的FRAMEWORK分析(一)

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是个接口,里面就是对于应用层的两个方法:onSensorChangedonAccuracyChanged

 

public interfaceSensorEventListener {

 

    /**

     * Called when sensor values have changed.

     * <p>See {@linkandroid.hardware.SensorManager SensorManager}

     * for details on possible sensor types.

     * <p>See also {@linkandroid.hardware.SensorEvent SensorEvent}.

     *

     * <p><b>NOTE:</b> 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.

     *

     * <p>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<SensorManager*>(sensorManager);

   ScopedUtfChars packageUtf(env, packageName);

   String8 clientName(packageUtf.c_str());

   sp<SensorEventQueue> queue(mgr->createEventQueue(clientName,mode));

 

   sp<MessageQueue> messageQueue =android_os_MessageQueue_getMessageQueue(env, msgQ);

   if (messageQueue == NULL) {

       jniThrowRuntimeException(env, "MessageQueue is notinitialized.");

       return 0;

    }

 

    sp<Receiver> receiver = newReceiver(queue, messageQueue, eventQWeak, scratch);

   receiver->incStrong((void*)nativeInitSensorEventQueue);

   return jlong(receiver.get());

}

 

step 6.1.4:

/*

Receiver创建后会自动执行onFirstRef, onFirstRef中,再执行mMessageQueue->getLooper()->addFd用来启动LoopCallback这句最关键了,
channelfd, 加到了looperfd集合里,并且传递了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<SensorEventQueue> q =reinterpret_cast<SensorEventQueue *>(data);

       ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env,mReceiverWeakGlobal));

 

       ssize_t n;

       ASensorEvent buffer[16];

       while ((n = q->read(buffer, 16)) >0) {

            for (int i=0 ; i<n ; 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<size_t>(err);

        mConsumed = 0;

    }

   size_t count = min(numEvents, mAvailable);

   memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));

   mAvailable -= count;

   mConsumed += count;

   return static_cast<ssize_t>(count);

}

 

SensorEventQueueaddSensor如下:

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<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));

   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<SensorEventConnection>& connection,

       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 &reg_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<structsensors_poll_device_t *> (mSensorDevice), handle, enabled);

       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<structsensors_poll_device_t *>(mSensorDevice),

                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<size_t(count) ; i++) {

               mActivationCount.add(list[i].handle, model);

               mSensorDevice->activate(

                       reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),

                       list[i].handle, 0);

            }

        }

    }

}

*/

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值