SensorService数据传递给APK
SensorService数据传递给APK
APK调用SensorService
AS下载Source for Android 29,创建APP导入Android.jar,直接查看可调用的API
网址查看:https://developer.android.google.cn/reference/android/hardware/SensorManager
* 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) {
* }
* }
- 获取对应Sensor
- 注册SensorEventListener监听,回调onSensorChanged方法
getSystemService(SENSOR_SERVICE)
获取的SensorManager是SystemServiceRegistry.java注册SystemSensorManager
frameworks/base/core/java/android/app/SystemServiceRegistry.java
static {
//......
registerService(Context.SENSOR_SERVICE, SensorManager.class,
new CachedServiceFetcher<SensorManager>() {
@Override
public SensorManager createService(ContextImpl ctx) {
return new SystemSensorManager(ctx.getOuterContext(),
ctx.mMainThread.getHandler().getLooper());
}});
//......
}
注册SensorEventListener
SensorEventListener是通过SystemSensorManager注册/注销
frameworks/base/core/java/android/hardware/SystemSensorManager.java
/** @hide */
@Override
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
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) {
// 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();
}
}
}
}
注释很清楚了
- - one Looper per SensorEventListener
- - one Looper per SensorEventQueue
- We map SensorEventListener to a SensorEventQueue, which holds the looper
SensorEventQueue 调用 dispatchSensorEvent
问题来了,这个 dispatchSensorEvent 是谁触发的???
1、不管其他看 dispatchSensorEvent 中调用 mListener.onSensorChanged(t); 传递给了APP监听SensorEventListener
2、SensorEventQueue 继承 BaseEventQueue
frameworks/base/core/java/android/hardware/SystemSensorManager.java
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
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);
}
// ... ...
}
BaseEventQueue
1、JNI调用初始化nativeInitBaseEventQueue
2、dispatchSensorEvent子类SensorEventQueue 实现
frameworks/base/core/java/android/hardware/SystemSensorManager.java
private abstract static class BaseEventQueue {
// ... ...
BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
if (packageName == null) packageName = "";
mNativeSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
new WeakReference<>(this), looper.getQueue(),
packageName, mode, manager.mContext.getOpPackageName());
mCloseGuard.open("dispose");
mManager = manager;
}
// ... ...
@UnsupportedAppUsage
protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
long timestamp);
// ... ...
}
android_hardware_SensorManager.cpp 创建 SensorEventQueue.cpp
1、nativeInitSensorEventQueue 实际是底层 SensorEventQueue.cpp 创建
2、SensorEventQueue作为参数,创建接收器 Receiver
frameworks/base/core/jni/android_hardware_SensorManager.cpp
static const JNINativeMethod gBaseEventQueueMethods[] = {
{"nativeInitBaseEventQueue",
"(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J",
(void*)nativeInitSensorEventQueue },
// ... ...
};
static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
ScopedUtfChars packageUtf(env, packageName);
String8 clientName(packageUtf.c_str());
sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));
if (queue == NULL) {
jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue.");
return 0;
}
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);
receiver->incStrong((void*)nativeInitSensorEventQueue);
return jlong(receiver.get());
}
SensorManager.cpp 创建 SensorEventQueue.cpp
1、创建 SensorEventConnection
2、SensorEventConnection 作为参数创建 SensorEventQueue
frameworks/native/services/sensorservice/hidl/SensorManager.cpp
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
sp<SensorEventQueue> queue;
Mutex::Autolock _l(mLock);
while (assertStateLocked() == NO_ERROR) {
sp<ISensorEventConnection> connection =
mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
if (connection == nullptr) {
// SensorService just died or the app doesn't have required permissions.
ALOGE("createEventQueue: connection is NULL.");
return nullptr;
}
queue = new SensorEventQueue(connection);
break;
}
return queue;
}
SensorEventQueue 实际是通过 SensorEventConnection 通信
SensorEventQueue.cpp 代码也可看出实际是SensorEventConnection通信
1、通过 SensorEventConnection 调用通信,实际是基于 BitTube 通信
2、write/read 通过 BitTube::sendObjects/BitTube::recvObjects
frameworks/native/libs/sensor/SensorEventQueue.cpp
// ... ...
void SensorEventQueue::onFirstRef()
{
mSensorChannel = mSensorEventConnection->getSensorChannel();
}
int SensorEventQueue::getFd() const
{
return mSensorChannel->getFd();
}
ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
ASensorEvent const* events, size_t numEvents) {
return BitTube::sendObjects(tube, events, numEvents);
}
// ... ...
Receiver 通过 AndroidRuntime::getJNIEnv() 执行 dispatchSensorEvent
问题又来了,哪这个 handleEvent 又是谁触发的??? 目前看是BitTube socket 通信触发
1、JNI gBaseEventQueueClassInfo.dispatchSensorEventgBaseEventQueueClassInfo.dispatchSensorEvent到SensorEventQueue.dispatchSensorEvent
2、mSensorQueue->getFd() 实际获通过 SensorEventConnection 获取 BitTube的mReceiveFd = sockets[0]
3、handler/Looper 轮询回调 LooperCallback,POLL_CALLBACK某个被监听fd被触发回调response.request.callback->handleEvent(fd, events, data);
class Receiver : public LooperCallback {
// ... ...
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();
// ... ...
// ... ...
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
buffer[i].meta_data.sensor);
}
// ... ...
if (receiverObj.get()) {
int type = buffer[i].additional_info.type;
int serial = buffer[i].additional_info.serial;
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent,
buffer[i].sensor,
type, serial,
mFloatScratch,
mIntScratch,
buffer[i].timestamp);
}
// ... ...
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchSensorEvent,
buffer[i].sensor,
mFloatScratch,
status,
buffer[i].timestamp);
}
// ... ...
};
SensorEventConnection / BitTube
1、mChannel = new BitTube基于BitTube实现通信
2、SensorService::threadLoop()中connection->sendEvent触发经过SensorEventConnection::sendEvents方法
3、SensorEventQueue::write 实际触发 BitTube::sendObjects(tube, events, numEvents);
SensorService::SensorEventConnection::SensorEventConnection(
const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
const String16& opPackageName, bool hasSensorAccess)
: mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(nullptr),
mCacheSize(0), mMaxCacheSize(0), mTimeOfLastEventDrop(0), mEventsDropped(0),
mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false),
mHasSensorAccess(hasSensorAccess) {
mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
mTotalAcksNeeded = mTotalAcksReceived = 0;
#endif
}
// ... ...
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch,
wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
// filter out events not for this connection
// ... ...
if (scratch) {
// ... ...
} else {
if (hasSensorAccess()) {
scratch = const_cast<sensors_event_t *>(buffer);
count = numEvents;
} else {
sanitizedBuffer.reset(new sensors_event_t[numEvents]);
scratch = sanitizedBuffer.get();
for (size_t i = 0; i < numEvents; i++) {
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
scratch[count++] = buffer[i++];
}
}
}
}
// ... ...
if (mCacheSize != 0) {
// There are some events in the cache which need to be sent first. Copy this buffer to
// the end of cache.
appendEventsToCacheLocked(scratch, count);
return status_t(NO_ERROR);
}
int index_wake_up_event = -1;
if (hasSensorAccess()) {
index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
if (index_wake_up_event >= 0) {
scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
++mWakeLockRefCount;
#if DEBUG_CONNECTIONS
++mTotalAcksNeeded;
#endif
}
}
// NOTE: ASensorEvent and sensors_event_t are the same type.
// 3、SensorEventQueue::write 实际触发 BitTube::sendObjects(tube, events, numEvents);
ssize_t size = SensorEventQueue::write(mChannel,
reinterpret_cast<ASensorEvent const*>(scratch), count);
// ... ...
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
// ... ...
BitTube 通过socket 通信Fd触发 LooperCallback类
1、BitTube::sendObjects/BitTube::recvObjects 通过socket 通信Fd触发 handler/Looper LooperCallback类回调Receiver::handleEvent
namespace android {
// ... ...
void BitTube::init(size_t rcvbuf, size_t sndbuf) {
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
// sine we don't use the "return channel", we keep it small...
setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
fcntl(sockets[0], F_SETFL, O_NONBLOCK);
fcntl(sockets[1], F_SETFL, O_NONBLOCK);
mReceiveFd = sockets[0];
mSendFd = sockets[1];
} else {
mReceiveFd = -errno;
ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
}
}
// ... ...
ssize_t BitTube::write(void const* vaddr, size_t size)
{
ssize_t err, len;
do {
len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
// cannot return less than size, since we're using SOCK_SEQPACKET
err = len < 0 ? errno : 0;
} while (err == EINTR);
return err == 0 ? len : -err;
}
ssize_t BitTube::read(void* vaddr, size_t size)
{
ssize_t err, len;
do {
len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);
err = len < 0 ? errno : 0;
} while (err == EINTR);
if (err == EAGAIN || err == EWOULDBLOCK) {
// EAGAIN means that we have non-blocking I/O but there was
// no data to be read. Nothing the client should care about.
return 0;
}
return err == 0 ? len : -err;
}
// ... ...
ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
void const* events, size_t count, size_t objSize)
{
const char* vaddr = reinterpret_cast<const char*>(events);
ssize_t size = tube->write(vaddr, count*objSize);
// should never happen because of SOCK_SEQPACKET
LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
"BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
count, objSize, size);
//ALOGE_IF(size<0, "error %d sending %d events", size, count);
return size < 0 ? size : size / static_cast<ssize_t>(objSize);
}
ssize_t BitTube::recvObjects(const sp<BitTube>& tube,
void* events, size_t count, size_t objSize)
{
char* vaddr = reinterpret_cast<char*>(events);
ssize_t size = tube->read(vaddr, count*objSize);
// should never happen because of SOCK_SEQPACKET
LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
"BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were received!)",
count, objSize, size);
//ALOGE_IF(size<0, "error %d receiving %d events", size, count);
return size < 0 ? size : size / static_cast<ssize_t>(objSize);
}
// ... ...
}; // namespace android
问题又又来了,哪这个 SensorService::threadLoop() 又是谁触发的???
SensorService::threadLoop()中connection->sendEvent 触发经过SensorEventConnection::sendEvents方法,再调用SensorEventQueue::write,实际触发 BitTube::sendObjects(tube, events, numEvents);
请查看**SensorService启动**:device.poll 通过poll往hal层取sensor数据, 若没有数据的时候就一直阻塞(该阻塞功能由SensorHAL层实现),当有数据时该函数就会返回
本文地址:https://blog.csdn.net/qq_23452385/article/details/107888880
上一篇: 单文件水的浓度驱动扰动