Android SensorManager学习

SensorManager

在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<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();

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

接下来看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<Result> Sensors::activate(
		int32_t sensor_handle, bool enabled) {
	return ResultFromStatus(
			mSensorDevice->activate(
				reinterpret_cast<sensors_poll_device_t *>(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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值