在SensorManager.java文件的开头,有一段sensor应用的示例。应用层获取sensor的数据主要是通过SensorManager的onAccuracyChanged和onSensorChanged两个监听接口。
public class SensorActivity extends Activity, implements SensorEventListener {
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
public SensorActivity() {
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
}
}
代码路径:frameworks/base/core/java/android/hardware/SensorManager.java,SensorManager类主要是对外提供sensor的调用接口:getDefaultSensor,registerListener,unregisterListener。从下面的代码里可以看到,这三个接口会调用getFullSensorList,registerListenerImpl,unregisterListenerImpl。实际实现的代码在SystemSensorManager.java里。
public Sensor getDefaultSensor(int type) {
// TODO: need to be smarter, for now, just return the 1st sensor
// 这里是从所有的sensor中获得对应type的sensor list.
List<Sensor> l = getSensorList(type);
boolean wakeUpSensor = false;
// For the following sensor types, return a wake-up sensor. These types are by default
// defined as wake-up sensors. For the rest of the SDK defined sensor types return a
// non_wake-up version.
// 如果获取的tyep是以下类型,则返回一个wake-up sensor,否则返回non_wake-up sensor。
if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION
|| type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE
|| type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE
|| type == Sensor.TYPE_WRIST_TILT_GESTURE
|| type == Sensor.TYPE_DYNAMIC_SENSOR_META || type == Sensor.TYPE_HINGE_ANGLE) {
wakeUpSensor = true;
}
for (Sensor sensor : l) {
if (sensor.isWakeUpSensor() == wakeUpSensor) return sensor;
}
return null;
}
public List<Sensor> getSensorList(int type) {
// cache the returned lists the first time
List<Sensor> list;
// 获取所有sensor
final List<Sensor> fullList = getFullSensorList();
synchronized (mSensorListByType) {
// 查看mSensorListByType缓存里有没有要组成的sensor,如果有的话直接返回
list = mSensorListByType.get(type);
if (list == null) {
if (type == Sensor.TYPE_ALL) {
list = fullList;
} else {
list = new ArrayList<Sensor>();
for (Sensor i : fullList) {
// 遍历所有sensor,找到对应type的sensor
if (i.getType() == type) {
list.add(i);
}
}
}
// Collections.unmodifiableList用于构造一个不能修改的List
list = Collections.unmodifiableList(list);
// 存入mSensorListByType缓存
mSensorListByType.append(type, list);
}
}
return list;
}
public boolean registerListener(SensorEventListener listener, Sensor sensor,
int samplingPeriodUs) {
return registerListener(listener, sensor, samplingPeriodUs, null);
}
public boolean registerListener(SensorEventListener listener, Sensor sensor,
int samplingPeriodUs, Handler handler) {
int delay = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
}
private static int getDelay(int rate) {
int delay = -1;
switch (rate) {
case SENSOR_DELAY_FASTEST:
delay = 0;
break;
case SENSOR_DELAY_GAME:
delay = 20000;
break;
case SENSOR_DELAY_UI:
delay = 66667;
break;
case SENSOR_DELAY_NORMAL:
delay = 200000;
break;
default:
delay = rate;
break;
}
return delay;
}
public void unregisterListener(SensorEventListener listener) {
if (listener == null) {
return;
}
unregisterListenerImpl(listener, null);
}
代码路径:frameworks/base/core/java/android/hardware/SystemSensorManager.java,SystemSensorManager继承SensorManager,完成getFullSensorList,registerListenerImpl,unregisterListenerImpl接口。
private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners =
new HashMap<SensorEventListener, SensorEventQueue>();
protected List<Sensor> getFullSensorList() {
return mFullSensorsList;
}
public SystemSensorManager(Context context, Looper mainLooper) {
synchronized (sLock) {
if (!sNativeClassInited) {
sNativeClassInited = true;
nativeClassInit();
}
}
mMainLooper = mainLooper;
mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
mContext = context;
mNativeInstance = nativeCreate(context.getOpPackageName());
// initialize the sensor list
for (int index = 0;; ++index) {
Sensor sensor = new Sensor();
if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
mFullSensorsList.add(sensor);
mHandleToSensor.put(sensor.getHandle(), sensor);
}
}
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) {
// 从缓存mSensorListeners里获取listener
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
queue = new SensorEventQueue(listener, looper, this, fullClassName);
// 添加sensor
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
// 将listener和queue存到缓存mSensorListeners中
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();
}
}
}
}
在registerListenerImpl函数里面,若之前该SensorEventListener(由应用自己创建)没有创建过SensorEventQueue,那么创建一个,并和SensorEventListener一起添加到mSensorListeners,当创建SensorEventQueue时,会同时构造一个其父类对象BaseEventQueue
static final class SensorEventQueue extends BaseEventQueue {
private final SensorEventListener mListener;
private final SparseArray mSensorsEvents = new SparseArray();
public SensorEventQueue(SensorEventListener listener, Looper looper,
SystemSensorManager manager, String packageName) {
// 调用父类方法
super(looper, manager, OPERATING_MODE_NORMAL, packageName);
mListener = listener;
}
......
// Called from native code.
@SuppressWarnings("unused")
@Override
// 数据分发,调用onAccuracyChanged,onSensorChanged
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);
// 回调应用重写的onAccuracyChanged
mListener.onAccuracyChanged(t.sensor, t.accuracy);
}
// 回调应用重写的onSensorChanged
mListener.onSensorChanged(t);
}
接着在其nativeInitBaseEventQueue()方法里边,通过jni调用android/frameworks/base/core/jni/android_hardware_SensorManager.cpp nativeInitSensorEventQueue()中创建一个接收数据的Receiver对象,这个之后分析数据如何给上来再详细分析。
接着看注册流程,然后,通过BaseEventQueue::addSensor()将注册一个sensor的流程继续往下走,
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;
}
通过BaseEventQueue::enableSensor()继续往下走,
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);
}
通过jni调用C++的接口,android/frameworks/base/core/jni/android_hardware_SensorManager.cpp
static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
jint maxBatchReportLatency) {
sp receiver(reinterpret_cast(eventQ));
return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
0);
}
接下来到了 android/frameworks/native/libs/sensor/SensorEventQueue.cpp
status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
int64_t maxBatchReportLatencyUs, int reservedFlags) const {
return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
us2ns(maxBatchReportLatencyUs), reservedFlags);
}
接着就到了 android/frameworks/native/services/sensorservice/SensorEventConnection.cpp
status_t SensorService::SensorEventConnection::enableDisable(
int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
int reservedFlags)
{
status_t err;
if (enabled) {
err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
reservedFlags, mOpPackageName);
} else {
err = mService->disable(this, handle);
}
return err;
}
接下去就是android/frameworks/native/services/sensorservice/SensorService.cpp SensorService::enable()
status_t SensorService::enable(const sp& connection,
int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
const String16& opPackageName) {
if (mInitCheck != NO_ERROR)
return mInitCheck;
sp 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;
}
接下来看android/frameworks/native/services/sensorservice/SensorInterface.cpp
status_t HardwareSensor::activate(void* ident, bool enabled) {
return mSensorDevice.activate(ident, mSensor.getHandle(), enabled);
}
接下来看android/frameworks/native/services/sensorservice/SensorDevice.cpp
status_t SensorDevice::activate(void* ident, int handle, int enabled) {
if (mSensors == 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)) {
ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
ident, handle);
return INVALID_OPERATION;
}
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()) {
delete it->second;
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);
checkReturn(mSensors->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 = checkReturnAndGetStatus(mSensors->activate(handle, enabled));
ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
strerror(-err));
return err;
}
接下来通过hidl,到了HAL,先到android 自己实现的hal层,就称它为android sensor hal吧,后面再往下手机厂家自己实现的hal层称为oem sensor hal 咯,
这边也是直接往下看流程,后面会再分析一下android sensor hal的启动,android/hardware/interfaces/sensors/1.0/default/Sensors.cpp
Return Sensors::activate(
int32_t sensor_handle, bool enabled) {
return ResultFromStatus(
mSensorDevice->activate(
reinterpret_cast(mSensorDevice),
sensor_handle,
enabled));
}
接着到了android/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);
}
int sensors_poll_context_t::activate(int handle, int enabled) {
int retval = -EINVAL;
ALOGV("activate");
int local_handle = get_local_handle(handle);
sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
retval = v0->activate(v0, local_handle, enabled);
} else {
ALOGE("IGNORING activate(enable %d) call to non-API-compliant sensor handle=%d !",
enabled, handle);
}
ALOGV("retval %d", retval);
return retval;
}
这边再下去就是厂家自己实现的接口了,android的部分到此为止
1 . Android calls sensors_open()
2 . A sensors hal obiect is created
a.The sensors hal sends lookup requests to the SSC about all known data types.
b.The sensor object is created when an SUID is available for a data type.
i.Sensor attributes are queried and stored in sensor object
ii.A sensor t object is populated using the attributesc . A list of available sensors is populated in sensors hal
3 . Android calls get_sensors_list().
a . A list of available sensors is returned
4 . Android calls batch ()
a . The sensors hal finds a sensor corresponding to the handleb . This sensor is configured with new parameterssensor is active . a new config request is sent
5 . Android calls activatea .
a.The sensors hal finds a sensor corresponding to the handle.
b . If this sensor is activated , a new ssc_connection ( ) is made and config request is sent.
c . If this sensor is deactivated . a ssc_connection is closed
6 . Android calls poll
a. A sensors hal returns available events
7.Android calls flush ()
a.A sensors hal finds a sensor corresponding to the handle
b . Calls sensor.flush ()
i.The sensor sends a flush request to the SSC