SensorService数据传递给APP-Android12

Posted xhBruce

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SensorService数据传递给APP-Android12相关的知识,希望对你有一定的参考价值。

SensorService数据传递给APP-android12

android12-release


SensorService启动

SensorService启动-Android12

  • SensorService::threadLoop do-while循环通过device.poll往HAL层取sensor数据,connection->sendEvents() 通过SensorEventConnection中socket发送给APP监听SensorEventListener

SensorService::threadLoop()获取

frameworks/native/services/sensorservice/SensorService.cpp

1. device.poll 获取HAL层数据

  • device.poll往HAL层取sensor数据
bool SensorService::threadLoop() 
    ALOGD("nuSensorService thread starting...");
    // ... ...
    do 
        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
        // ... ...
     while (!Thread::exitPending());
    // ... ...

frameworks/native/services/sensorservice/SensorDevice.cpp
hardware/interfaces/sensors/common/utils/ISensorsWrapper.h
hardware/interfaces/sensors/xxx/ISensors.hal
hardware/interfaces/sensors/2.1/default/SensorsV2_1.cpp

ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) 
    if (mSensors == nullptr) return NO_INIT;

    ssize_t eventsRead = 0;
    if (mSensors->supportsMessageQueues()) 
        eventsRead = pollFmq(buffer, count);
     else if (mSensors->supportsPolling()) 
        eventsRead = pollHal(buffer, count);
     else 
        ALOGE("Must support polling or FMQ");
        eventsRead = -1;
    
    return eventsRead;

2. si->process(&out, event[i]) 处理VirtualSensor数据

bool SensorService::threadLoop() 
    ALOGD("nuSensorService thread starting...");
    // ... ...
    do 
        // ... ...
        // handle virtual sensors
        if (count && vcount) 
            // ... ...
                        sensors_event_t out;
                        sp<SensorInterface> si = mSensors.getInterface(handle);
                        // ... ...
                        if (si->process(&out, event[i])) 
                            mSensorEventBuffer[count + k] = out;
                            k++;
                        
            // ... ...
        
        // ... ...
     while (!Thread::exitPending());
    // ... ...

如类型SENSOR_TYPE_ORIENTATION:frameworks/native/services/sensorservice/OrientationSensor.cpp

  • 继承VirtualSensor最终继承SensorInterface(frameworks/native/services/sensorservice/SensorInterface.h
bool OrientationSensor::process(sensors_event_t* outEvent,
        const sensors_event_t& event)

    if (event.type == SENSOR_TYPE_ACCELEROMETER) 
        if (mSensorFusion.hasEstimate()) 
            vec3_t g;
            const float rad2deg = 180 / M_PI;
            const mat33_t R(mSensorFusion.getRotationMatrix());
            g[0] = atan2f(-R[1][0], R[0][0])    * rad2deg;
            g[1] = atan2f(-R[2][1], R[2][2])    * rad2deg;
            g[2] = asinf ( R[2][0])             * rad2deg;
            if (g[0] < 0)
                g[0] += 360;

            *outEvent = event;
            outEvent->orientation.azimuth = g.x;
            outEvent->orientation.pitch   = g.y;
            outEvent->orientation.roll    = g.z;
            outEvent->orientation.status  = SENSOR_STATUS_ACCURACY_HIGH;
            outEvent->sensor = '_ypr';
            outEvent->type = SENSOR_TYPE_ORIENTATION;
            return true;
        
    
    return false;

3. connection->sendEvents() 通过BitTube中socket上报

  • SensorEventConnection APP注册registerListener监听SensorEventListener时初始化SensorEventQueue
  • connection->sendEvents socket方式发送
bool SensorService::threadLoop() 
    ALOGD("nuSensorService thread starting...");
    // ... ...
    do 
        // ... ...
        for (const sp<SensorEventConnection>& connection : activeConnections) 
            connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
                    mMapFlushEventsToConnections);
            // ... ...
        
        // ... ...
     while (!Thread::exitPending());
    // ... ...

  • SensorEventConnection 是基于 Bittube 实现的。

frameworks/native/services/sensorservice/SensorEventConnection.cpp

status_t SensorService::SensorEventConnection::sendEvents(
        sensors_event_t const* buffer, size_t numEvents,
        sensors_event_t* scratch,
        wp<const SensorEventConnection> const * mapFlushEventsToConnections) 
    // ... ...
    // NOTE: ASensorEvent and sensors_event_t are the same type.
    ssize_t size = SensorEventQueue::write(mChannel,
                                    reinterpret_cast<ASensorEvent const*>(scratch), count);
    // ... ...

frameworks/native/libs/sensor/SensorEventQueue.cpp

ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
        ASensorEvent const* events, size_t numEvents) 
    return BitTube::sendObjects(tube, events, numEvents);

frameworks/native/libs/sensor/BitTube.cpp

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);

BitTube中socket的接收器Receiver

  • nativeInitSensorEventQueue注册初始化Receiver
  • Receiver实例化后调用onFirstRef(),handler\\Looper 轮询LooperCallback监听回调Receiver::handleEvent()
  • mSensorQueue->getFd() 实际就是 SensorEventQueue > SensorEventConnection > BitTube::getFd() 里边mReceiveFd = sockets[0]
  • env->CallVoidMethod(...gBaseEventQueueClassInfo.dispatchSensorEvent...) JNI 调用Java层SensorEventQueue中dispatchSensorEvent方法

frameworks/base/core/jni/android_hardware_SensorManager.cpp

//----------------------------------------------------------------------------

class Receiver : public LooperCallback 
// ... ...
private:
    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) 
        // ... ...
                    if (receiverObj.get()) 
                        env->CallVoidMethod(receiverObj.get(),
                                            gBaseEventQueueClassInfo.dispatchSensorEvent,
                                            buffer[i].sensor,
                                            mFloatScratch,
                                            status,
                                            buffer[i].timestamp);
                    
        // ... ...
        return 1;
    
;

static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
                                        j
                                        object eventQWeak, jobject msgQ, jstring packageName,
                                        jint mode, jstring opPackageName, jstring attributionTag) 
    // ... ...
    sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode, attributionTagName));
    // ... ...
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
    // ... ...
    sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);
    receiver->incStrong((void*)nativeInitSensorEventQueue);
    return jlong(receiver.get());

SystemSensorManager传递给APP监听SensorEventListener

  • mListener.onSensorChanged(t) 传递给APP监听SensorEventListener

frameworks/base/core/java/android/hardware/SystemSensorManager.java

static final class SensorEventQueue extends BaseEventQueue 
    // ... ...
    // Called from native code.
    @SuppressWarnings("unused")
    @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);
    
    // ... ...

时序图

以上是关于SensorService数据传递给APP-Android12的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据传递给BottomSheetDialogFragment [重复]

将数据传递给 viewController

将数据传递给服务 - android?

vue js将数据传递给组件

如何在 Swift(Cocoa 应用程序)中将数据传递给以前的 ViewController

如何通过数组将数据传递给表格视图?