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层实现),当有数据时该函数就会返回
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/addevelopment/894516.html