Android Sensor调用从上层到底层

  1. Sensor应用层调用
SensorManager mSensorManager;
Sensor mSensor;
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); //获取sensor服务
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); //获取默认sensor类型

mSensorManager.registerListener(mSensorEventListener, mSensor, SensorManager.SENSOR_DELAY_NORMAL);//注册sensor,提供sensor监听器,监听状态变化

mSensorManager.unregisterListener(mSensorEventListener,mSensor);//取消注册sensor监听器

2.SensorManager接口\frameworks\base\core\java\android\hardware\SensorManager.java
以registerListener举例

public boolean registerListener(SensorEventListener listener, Sensor sensor,
            int samplingPeriodUs) {
        return registerListener(listener, sensor, samplingPeriodUs, null);
    }
public boolean registerListener(SensorEventListener listener, Sensor sensor,
            int samplingPeriodUs, int maxReportLatencyUs) {
        int delay = getDelay(samplingPeriodUs);
        return registerListenerImpl(listener, sensor, delay, null, maxReportLatencyUs, 0);
    }

protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags);


3.frameworks\base\core\java\android\hardware\SystemSensorManager.java
SystemSensorManager.java继承SensorManager.java实现registerListenerImpl、unregisterListenerImpl等函数

    /** @hide */
    @Override
    protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
        android.util.SeempLog.record_sensor_rate(381, sensor, delayUs);
        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 be non-negative");
            return false;
        }
        if (mSensorListeners.size() >= MAX_LISTENER_COUNT) {
            throw new IllegalStateException("register failed, "
                + "the sensor listeners size has exceeded the maximum limit "
                + MAX_LISTENER_COUNT);
        }

        // Invariants to preserve:
        // - one Looper per SensorEventListener
        // - one Looper per SensorEventQueue
        // We map SensorEventListener to a SensorEventQueue, which holds the looper
        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();
                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);
            }
        }
    }


 /** @hide */
    @Override
    protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
        android.util.SeempLog.record_sensor(382, sensor);
        // Trigger Sensors should use the cancelTriggerSensor call.
        if (sensor != null && sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
            return;
        }

        synchronized (mSensorListeners) {
            SensorEventQueue queue = mSensorListeners.get(listener);
            if (queue != null) {
                boolean result;
                if (sensor == null) {
                    result = queue.removeAllSensors();
                } else {
                    result = queue.removeSensor(sensor, true);
                }
                if (result && !queue.hasSensors()) {
                    mSensorListeners.remove(listener);
                    queue.dispose();
                }
            }
        }
    }

3.在registerListenerImpl中创建SensorEventQueue(SensorEventQueue queue = mSensorListeners.get(listener);)
添加到mSensorListeners queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);

 static final class SensorEventQueue extends BaseEventQueue{
        private final SensorEventListener mListener;
        private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();

        public SensorEventQueue(SensorEventListener listener, Looper looper,
                SystemSensorManager manager, String packageName) {
            super(looper, manager, OPERATING_MODE_NORMAL, packageName);
            mListener = listener;
        }

        @Override
        public void addSensorEvent(Sensor sensor) {
            SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,
                    mManager.mTargetSdkLevel));
            synchronized (mSensorsEvents) {
                mSensorsEvents.put(sensor.getHandle(), t);
            }
        }

        @Override
        public void removeSensorEvent(Sensor sensor) {
            synchronized (mSensorsEvents) {
                mSensorsEvents.delete(sensor.getHandle());
            }
        }

        // Called from native code.
        @SuppressWarnings("unused")
        @Override
        protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
                long timestamp) {
            final Sensor sensor = mManager.mHandleToSensor.get(handle);
            if (sensor == null) {
                // sensor disconnected
                return;
            }

            SensorEvent t = null;
            synchronized (mSensorsEvents) {
                t = mSensorsEvents.get(handle);
            }

            if (t == null) {
                // This may happen if the client has unregistered and there are pending events in
                // the queue waiting to be delivered. Ignore.
                return;
            }
            // Copy from the values array.
            System.arraycopy(values, 0, t.values, 0, t.values.length);
            t.timestamp = timestamp;
            t.accuracy = inAccuracy;
            t.sensor = sensor;

            // call onAccuracyChanged() only if the value changes
            final int accuracy = mSensorAccuracies.get(handle);
            if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
                mSensorAccuracies.put(handle, t.accuracy);
                mListener.onAccuracyChanged(t.sensor, t.accuracy);
            }
            mListener.onSensorChanged(t);
        }

        // Called from native code.
        @SuppressWarnings("unused")
        @Override
        protected void dispatchFlushCompleteEvent(int handle) {
            if (mListener instanceof SensorEventListener2) {
                final Sensor sensor = mManager.mHandleToSensor.get(handle);
                if (sensor == null) {
                    // sensor disconnected
                    return;
                }
                ((SensorEventListener2) mListener).onFlushCompleted(sensor);
            }
            return;
        }

        // Called from native code.
        @SuppressWarnings("unused")
        @Override
        protected void dispatchAdditionalInfoEvent(
                int handle, int type, int serial, float[] floatValues, int[] intValues) {
            if (mListener instanceof SensorEventCallback) {
                final Sensor sensor = mManager.mHandleToSensor.get(handle);
                if (sensor == null) {
                    // sensor disconnected
                    return;
                }
                SensorAdditionalInfo info =
                        new SensorAdditionalInfo(sensor, type, serial, intValues, floatValues);
                ((SensorEventCallback) mListener).onSensorAdditionalInfo(info);
            }
        }
    }

4.nativeInitBaseEventQueue()方法里边,通过jni调用\frameworks\base\core\jni\android_hardware_SensorManager.cpp中创建一个接收数据的Receiver对象

public boolean addSensor(
                Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
            // 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 if batching fails.
                if (maxBatchReportLatencyUs == 0
                        || maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
                    removeSensor(sensor, false);
                    return false;
                }
            }
            return true;
        }

private int enableSensor(Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
	if (mNativeSensorEventQueue == 0) throw new NullPointerException();
	if (sensor == null) throw new NullPointerException();
	return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
			maxBatchReportLatencyUs);
}

5.通过jni调用到frameworks\base\core\jni\android_hardware_SensorManager.cpp::nativeEnableSensor

static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
                               jint maxBatchReportLatency) {
    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
    return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
                                                         0);
}




6.\frameworks\native\libs\sensor\SensorEventQueue.cpp SensorEventQueue::enableSensor

status_t SensorEventQueue::enableSensor(Sensor const* sensor, int32_t samplingPeriodUs) const {
    return mSensorEventConnection->enableDisable(sensor->getHandle(), true,
                                                 us2ns(samplingPeriodUs), 0, 0);
}

7.frameworks\native\services\sensorservice\SensorEventConnection.cpp SensorService::SensorEventConnection::enableDisable

status_t SensorService::SensorEventConnection::enableDisable(
        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
        int reservedFlags)
{
    if (mDestroyed) {
        android_errorWriteLog(0x534e4554, "168211968");
        return DEAD_OBJECT;
    }

    status_t err;
    if (enabled) {
        nsecs_t requestedSamplingPeriodNs = samplingPeriodNs;
        bool isSensorCapped = false;
        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
        if (si != nullptr) {
            const Sensor& s = si->getSensor();
            if (mService->isSensorInCappedSet(s.getType())) {
                isSensorCapped = true;
            }
        }
        if (isSensorCapped) {
            err = mService->adjustSamplingPeriodBasedOnMicAndPermission(&samplingPeriodNs,
                                String16(mOpPackageName));
            if (err != OK) {
                return err;
            }
        }
        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
                               reservedFlags, mOpPackageName);
        if (err == OK && isSensorCapped) {
            if ((requestedSamplingPeriodNs >= SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) ||
                !isRateCappedBasedOnPermission()) {
                mMicSamplingPeriodBackup[handle] = requestedSamplingPeriodNs;
            } else {
                mMicSamplingPeriodBackup[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS;
            }
        }

    } else {
        err = mService->disable(this, handle);
        mMicSamplingPeriodBackup.erase(handle);
    }
    return err;
}

8.\frameworks\native\services\sensorservice\SensorService.cpp SensorService::enable

status_t SensorService::enable(const sp<SensorEventConnection>& connection,
        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
        const String16& opPackageName) {
    if (mInitCheck != NO_ERROR)
        return mInitCheck;

    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
    if (sensor == nullptr ||
        !canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
        return BAD_VALUE;
    }

    ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
    if (mCurrentOperatingMode != NORMAL
           && !isWhiteListedPackage(connection->getPackageName())) {
        return INVALID_OPERATION;
    }

    SensorRecord* rec = mActiveSensors.valueFor(handle);
    if (rec == nullptr) {
        rec = new SensorRecord(connection);
        mActiveSensors.add(handle, rec);
        if (sensor->isVirtual()) {
            mActiveVirtualSensors.emplace(handle);
        }

        // There was no SensorRecord for this sensor which means it was previously disabled. Mark
        // the recent event as stale to ensure that the previous event is not sent to a client. This
        // ensures on-change events that were generated during a previous sensor activation are not
        // erroneously sent to newly connected clients, especially if a second client registers for
        // an on-change sensor before the first client receives the updated event. Once an updated
        // event is received, the recent events will be marked as current, and any new clients will
        // immediately receive the most recent event.
        if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
            auto logger = mRecentEvent.find(handle);
            if (logger != mRecentEvent.end()) {
                logger->second->setLastEventStale();
            }
        }
    } else {
        if (rec->addConnection(connection)) {
            // this sensor is already activated, but we are adding a connection that uses it.
            // Immediately send down the last known value of the requested sensor if it's not a
            // "continuous" sensor.
            if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
                // NOTE: The wake_up flag of this event may get set to
                // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.

                auto logger = mRecentEvent.find(handle);
                if (logger != mRecentEvent.end()) {
                    sensors_event_t event;
                    // Verify that the last sensor event was generated from the current activation
                    // of the sensor. If not, it is possible for an on-change sensor to receive a
                    // sensor event that is stale if two clients re-activate the sensor
                    // simultaneously.
                    if(logger->second->populateLastEventIfCurrent(&event)) {
                        event.sensor = handle;
                        if (event.version == sizeof(sensors_event_t)) {
                            if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
                                setWakeLockAcquiredLocked(true);
                            }
                            connection->sendEvents(&event, 1, nullptr);
                            if (!connection->needsWakeLock() && mWakeLockAcquired) {
                                checkWakeLockStateLocked(&connLock);
                            }
                        }
                    }
                }
            }
        }
    }

    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
        mConnectionHolder.addEventConnectionIfNotPresent(connection);
    } else {
        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
            handle, connection.get());
    }

    // Check maximum delay for the sensor.
    nsecs_t maxDelayNs = sensor->getSensor().getMaxDelay() * 1000LL;
    if (maxDelayNs > 0 && (samplingPeriodNs > maxDelayNs)) {
        samplingPeriodNs = maxDelayNs;
    }

    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
    if (samplingPeriodNs < minDelayNs) {
        samplingPeriodNs = minDelayNs;
    }

    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%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 a first
    // flush complete event before sending events on this connection. Ignore
    // one-shot sensors which don't support flush(). Ignore on-change sensors
    // to maintain the on-change logic (any on-change events except the initial
    // one should be trigger by a change in value). Also if this sensor isn't
    // already active, don't call flush().
    if (err == NO_ERROR &&
            sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS &&
            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 older HAL.
        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);

        if (sensor->getSensor().getRequiredPermission().size() > 0 &&
                sensor->getSensor().getRequiredAppOp() >= 0) {
            connection->mHandleToAppOp[handle] = sensor->getSensor().getRequiredAppOp();
        }

        mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) =
                SensorRegistrationInfo(handle, connection->getPackageName(),
                                       samplingPeriodNs, maxBatchReportLatencyNs, true);
        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
    }

    if (err != NO_ERROR) {
        // batch/activate has failed, reset our state.
        cleanupWithoutDisableLocked(connection, handle);
    }
    return err;
}

9.frameworks\native\services\sensorservice\SensorInterface.cpp HardwareSensor::activate

status_t HardwareSensor::activate(void* ident, bool enabled) {
    return mSensorDevice.activate(ident, mSensor.getHandle(), enabled);
}

10.\frameworks\native\services\sensorservice\SensorDevice.cpp SensorDevice::activate

status_t SensorDevice::activate(void* ident, int handle, int enabled) {
    if (mHalWrapper == nullptr) return NO_INIT;

    Mutex::Autolock _l(mLock);
    return activateLocked(ident, handle, enabled);
}

status_t SensorDevice::activateLocked(void* ident, int handle, int enabled) {
    bool activateHardware = false;

    status_t err(NO_ERROR);

    ssize_t activationIndex = mActivationCount.indexOfKey(handle);
    if (activationIndex < 0) {
        ALOGW("Handle %d cannot be found in activation record", handle);
        return BAD_VALUE;
    }
    Info& info(mActivationCount.editValueAt(activationIndex));

    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)) {
            ALOGW("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d", ident,
                  handle);
            return NO_ERROR;
        }

        if (info.batchParams.indexOfKey(ident) >= 0) {
            if (info.numActiveClients() > 0 && !info.isActive) {
                activateHardware = 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 a connected dynamic sensor is deactivated, remove it from the
        // dictionary.
        auto it = mConnectedDynamicSensors.find(handle);
        if (it != mConnectedDynamicSensors.end()) {
            mConnectedDynamicSensors.erase(it);
        }

        if (info.removeBatchParamsForIdent(ident) >= 0) {
            if (info.numActiveClients() == 0) {
                // This is the last connection, we need to de-activate the underlying h/w sensor.
                activateHardware = true;
            } else {
                // Call batch for this sensor with the previously calculated best effort
                // batch_rate and timeout. One of the apps has unregistered for sensor
                // events, and the best effort batch parameters might have changed.
                ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64,
                         handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
                mHalWrapper->batch(handle, info.bestBatchParams.mTSample,
                                   info.bestBatchParams.mTBatch);
            }
        } else {
            // sensor wasn't enabled for this ident
        }

        if (isClientDisabledLocked(ident)) {
            return NO_ERROR;
        }
    }

    if (activateHardware) {
        err = doActivateHardwareLocked(handle, enabled);

        if (err != NO_ERROR && enabled) {
            // Failure when enabling the sensor. Clean up on failure.
            info.removeBatchParamsForIdent(ident);
        } else {
            // Update the isActive flag if there is no error. If there is an error when disabling a
            // sensor, still set the flag to false since the batch parameters have already been
            // removed. This ensures that everything remains in-sync.
            info.isActive = enabled;
        }
    }

    return err;
}

status_t SensorDevice::doActivateHardwareLocked(int handle, bool enabled) {
    ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
             enabled);
    status_t err = mHalWrapper->activate(handle, enabled);
    ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
             strerror(-err));
    return err;
}

11.以上是native层,之后是硬件抽象层(hal)
/hardware/libhardware/modules/sensors/dynamic_sensor/sensors.cpp

int SensorContext::activate(int handle, int enabled) {
    return mDynamicSensorManager->activate(handle, enabled);
}

12
/hardware/libhardware/modules/sensors/multihal.cpp

static int device__activate(struct sensors_poll_device_t *dev, int handle,
        int enabled) {
    sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    return ctx->activate(handle, enabled);
}

你可能感兴趣的:(android)