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);
}