android开发分享SensorService数据传递给APK

SensorService数据传递给APKAPK调用SensorServiceAS下载Source for Android 29,创建APP导入Android.jar,直接查看可调用的API网址查看:https://developer.android.google.cn/reference/android/hardware/SensorManager * public class SensorActivity extends Activity implements SensorEventL


SensorService数据传递给APK

APK调用SensorService

AS下载Source for Android 29,创建APP导入Android.jar,直接查看可调用的API
网址查看:https://developer.android.google.cn/reference/android/hardware/SensorManager

SensorService数据传递给APK SensorService数据传递给APK

 * 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) {  *     }  * } 
  1. 获取对应Sensor
  2. 注册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

(0)
上一篇 2021年10月21日
下一篇 2021年10月21日

精彩推荐