sensor数据分发

一.概要

        数据分发的流程你就是注册时序的一个逆过程,上一篇文章中说到了注册,[email protected]进程最后会创建一个data_msg_reader_thread线程在不断的监听数据,当收到数据后,数据会逐步往APP传递,传递的进程是[email protected]>system_server->APP,看了这篇文章你会大概了解这个sensor数据分发的流程。
数据分发流程见图上紫蓝色部分:

[email protected]进程接收数据并向上传递:

 

         我们先看到qmi的data_msg_reader_thread线程,APP每注册一个新的sensor都会创建一个data_msg_reader_thread线程,一个sensor只有一个data_msg_reader_thread线程,我们在之前注册的文章中SensorDevice.cpp部分说过如果这个sensor是第一次注册,那么他会继续调用activate,否则不会继续调用activate了,说明不会在次初始化qmi 连接,当然也不会再次创建线程了。这个线程的作用是监听某个类型的sensor数据,如果我们注册了10个不同的sensor,那么就会有是个data_msg_reader_thread线程。它们在这里会分别会通过socket接收BP发送上来的sensor数据,然后往上分发

vendor/qcom/proprietary/commonsys-intf/qmi-framework/qcci/src/qmi_cci_xport_qrtr.c

static void *data_msg_reader_thread(void *arg)

{

  struct xport_handle *xp = (struct xport_handle *)arg;

  unsigned char ch, *buf;

  int i;

  ssize_t rx_len;

  struct pollfd pbits[2];

  struct xport_ipc_router_server_addr src_addr;

  struct sockaddr_qrtr addr;

 

  while(1)

  {

    pbits[0].fd = xp->rdr_tdata.wakeup_pipe[0];

    pbits[0].events = POLLIN;

    pbits[1].fd = xp->fd;

    pbits[1].events = POLLIN;

    // 等待数据

    i = poll(pbits, 2, -1);

    if(i < 0)

    {

      if (errno == EINTR)

        QMI_CCI_LOGD("%s: poll error (%d)\n", __func__, errno);

      else

        QMI_FW_LOGE("%s: poll error (%d)\n", __func__, errno);

      continue;

    }

 

    ......

if((pbits[1].revents & POLLIN))

    {

      socklen_t addr_size = sizeof(struct sockaddr_qrtr);

 

      buf = (unsigned char *)calloc(xp->max_rx_len, 1);

      if(!buf)

      {

        QMI_FW_LOGE("%s: Unable to allocate read buffer for %p of size %d\n",

                     __func__, xp, xp->max_rx_len);

        break;

      }

      addr_size = sizeof(struct sockaddr_qrtr);

      // 通过socket读取bp发送过来的数据

      rx_len = recvfrom(xp->fd, buf, xp->max_rx_len, MSG_DONTWAIT, (struct sockaddr *)&addr, &addr_size);

      if (rx_len < 0)

      {

        QMI_FW_LOGE("%s: Error recvfrom %p - rc : %d\n", __func__, xp, errno);

        free(buf);

        break;

      }

      else if (rx_len == 0)

      {

        if (addr_size == sizeof(struct sockaddr_qrtr))

        {

          QMI_CCI_LOGD("%s: QCCI Received Resume_Tx on FD %d from port %08x:%08x\n",

                        __func__, xp->fd, addr.sq_node, addr.sq_port);

          qmi_cci_xport_resume(xp->clnt);

        }

        else

        {

          QMI_FW_LOGE("%s: No data read from %d\n", __func__, xp->fd);

        }

        free(buf);

        continue;

      }

      else if (addr.sq_port == QRTR_PORT_CTRL)

      {

  /* NOT expected to receive data from control port */

        QMI_FW_LOGE("%s: DATA from control port len[%d]\n", __func__, rx_len);

        free(buf);

        continue;

      }

 

      QMI_CCI_LOGD("%s: Received %d bytes from %d\n", __func__, rx_len, xp->fd);

      src_addr.service = 0;

      src_addr.instance = 0;

      src_addr.node_id = addr.sq_node;

      src_addr.port_id = addr.sq_port;

      // NO.1 将buf往上分发

      qmi_cci_xport_recv(xp->clnt, (void *)&src_addr, buf, (uint32_t)rx_len);

      free(buf);

    }

  ......

  return NULL;

}

这里主要是poll等待bp数据到来,到来之后通过socket读取bp发送过来的数据存到buf中,然后再通过qmi_cci_xport_recv方法将buf继续向上传递

qmi_client_error_type qmi_cci_xport_recv

(

 qmi_cci_client_type *clnt,

 void *addr,

 uint8_t *buf,

 uint32_t len

 )

{

   ......

 

  /* process indication */

  if(cntl_flag == QMI_INDICATION_CONTROL_FLAG)

  {

    if(clnt->info.client.ind_cb)

    {

      clnt->info.client.ind_cb(CLIENT_HANDLE(clnt), msg_id, msg_len ? buf : NULL, msg_len,

          clnt->info.client.ind_cb_data);

    }

    return QMI_NO_ERR;

  }

 

  ......

 

  return QMI_NO_ERR;

}

我们跳过一些步骤直接看到init_sensors中,qmi的层层回调最终会回到在init_sensors中的:
auto cb = [this](const auto& event, auto wakeup) { _event_queue.push(event, wakeup); };
这里最后会向_event_queue中push event

 

vendor/qcom/proprietary/sensors-see/sensors-hal/framework/sensors_hal.cpp

void sensors_hal::init_sensors()

{

    auto sensors = sensor_factory::instance().get_all_available_sensors();

    auto cb  = [this](const auto& event, auto wakeup) { _event_queue.push(event, wakeup); };

 

    for (unique_ptr& s : sensors) {

        assert(s != nullptr);

        s->register_callback(cb);

        const sensor_t& sensor_info = s->get_sensor_info();

        sns_logd("%s: %s/%d wakeup=%d", sensor_info.name,

                 sensor_info.stringType, sensor_info.handle,

                 (sensor_info.flags & SENSOR_FLAG_WAKE_UP) != 0);

        _hal_sensors.push_back(sensor_info);

        _sensors[sensor_info.handle] = std::move(s);

    }

#ifdef SNS_DIRECT_REPORT_SUPPORT

    if (check_direct_channel_support()) {

        gralloc_device = nullptr;

    }

    /* write sensor list to file*/

#endif

}

这里把_event_queue.push后会激活writerTask线程,writerTask线程是在sensorservice初始化的时候在addSubHwDevice方法中创建的,这个线程专门用来等待qmi传递过来的数据,当有数据之后,会调用 pthread_cond_broadcast(&data_available_cond); 激活另外一个正在等待的线程关系图如下:

调用栈流程图:

我们先看writerTask线程

void *writerTask(void* ptr) {

    ALOGV("writerTask STARTS");

    TaskContext* ctx = (TaskContext*)ptr;

    sensors_poll_device_t* device = ctx->device;

    SensorEventQueue* queue = ctx->queue;

    sensors_event_t* buffer;

    int eventsPolled;

    while (1) {

        pthread_mutex_lock(&queue_mutex);

        if (queue->waitForSpace(&queue_mutex)) {

            ALOGV("writerTask waited for space");

        }

        // 将queue中mData的地址修改为buffer指向的地址,后边会通过queue中的mData来读数据

        int bufferSize = queue->getWritableRegion(SENSOR_EVENT_QUEUE_CAPACITY, &buffer);

        // Do blocking poll outside of lock

        pthread_mutex_unlock(&queue_mutex);

 

        ALOGV("writerTask before poll() - bufferSize = %d", bufferSize);

        // 将poll到的数据写入buffer,实际是写进了queue中的mData

        eventsPolled = device->poll(device, buffer, bufferSize);

        ALOGV("writerTask poll() got %d events.", eventsPolled);

        if (eventsPolled <= 0) {

            if (eventsPolled < 0) {

                ALOGV("writerTask ignored error %d from %s", eventsPolled, device->common.module->name);

                ALOGE("ERROR: Fix %s so it does not return error from poll()", device->common.module->name);

            }

            continue;

        }

        pthread_mutex_lock(&queue_mutex);

        queue->markAsWritten(eventsPolled);

        ALOGV("writerTask wrote %d events", eventsPolled);

        if (waiting_for_data) {

            ALOGV("writerTask - broadcast data_available_cond");

            // 激活等待线程

            pthread_cond_broadcast(&data_available_cond);

        }

        pthread_mutex_unlock(&queue_mutex);

    }

    // never actually returns

    return NULL;

}

hardware/libhardware/modules/sensors/SensorEventQueue.cpp

int SensorEventQueue::getWritableRegion(int requestedLength, sensors_event_t** out) {

    ......

    *out = &mData[firstWritable];

    return lastWritable - firstWritable + 1;

}

sensors_event_t* SensorEventQueue::peek() {

    if (mSize == 0return NULL;

    return &mData[mStart];

}

我们看到system_server 通过binder call过来的线程:

int sensors_poll_context_t::poll(sensors_event_t *data, int maxReads) {

    ALOGV("poll");

    int empties = 0;

    int queueCount = 0;

    int eventsRead = 0;

 

    pthread_mutex_lock(&queue_mutex);

    queueCount = (int)this->queues.size();

    while (eventsRead == 0) {

        while (empties < queueCount && eventsRead < maxReads) {

            SensorEventQueue* queue = this->queues.at(this->nextReadIndex);

            // 线程被唤醒后读取event数据

            sensors_event_t* event = queue->peek();

            if (event == NULL) {

                empties++;

            else {

                empties = 0;

                // 将数据拷贝到data中

                this->copy_event_remap_handle(&data[eventsRead], event, nextReadIndex);

                if (data[eventsRead].sensor == SENSORS_HANDLE_BASE - 1) {

                    // Bad handle, do not pass corrupted event upstream !

                    ALOGW("Dropping bad local handle event packet on the floor");

                else {

                    eventsRead++;

                }

                queue->dequeue();

            }

            this->nextReadIndex = (this->nextReadIndex + 1) % queueCount;

        }

        if (eventsRead == 0) {

            // The queues have been scanned and none contain data, so wait.

            ALOGV("poll stopping to wait for data");

            waiting_for_data = true;

            // 等待线程被唤醒

            pthread_cond_wait(&data_available_cond, &queue_mutex);

            waiting_for_data = false;

            empties = 0;

        }

    }

    pthread_mutex_unlock(&queue_mutex);

    ALOGV("poll returning %d events.", eventsRead);

 

    return eventsRead;

}


这里是等待线程被唤醒,然后读取之前记录在queue中的mData,然后返回到system_server进程。

 

三.system_server进程

我们看到system_server的sensor线程对应的代码:

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

bool SensorService::threadLoop() {

    ALOGD("nuSensorService thread starting...");

    do {

        // poll数据

        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);

        ......

        // 将之前注册的mActiveConnections放到activeConnections中,下边分发的时候会用到

        populateActiveConnections(&activeConnections);

 

        ......

        // Send our events to clients. Check the state of wake lock for each client and release the

        // lock if none of the clients need it.

        bool needsWakeLock = false;

        size_t numConnections = activeConnections.size();

        for (size_t i=0 ; i < numConnections; ++i) {

            if (activeConnections[i] != 0) {

                // 分发数据

                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,

                        mMapFlushEventsToConnections);

                needsWakeLock |= activeConnections[i]->needsWakeLock();

                // If the connection has one-shot sensors, it may be cleaned up after first trigger.

                // Early check for one-shot sensors.

                if (activeConnections[i]->hasOneShotSensors()) {

                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,

                            count);

                }

            }

        }

 

        ......

        if (mWakeLockAcquired && !needsWakeLock) {

            // 调用mLooper->wake();唤醒消息队列

            setWakeLockAcquiredLocked(false);

        }

    while (!Thread::exitPending());

 

    ALOGW("Exiting SensorService::threadLoop => aborting...");

    abort();

    return false;

}

 

四.APP进程


looper wake后会调用handleEvent:

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

    virtual int handleEvent(int fd, int events, void* data) {

        JNIEnv* env = AndroidRuntime::getJNIEnv();

        sp q = reinterpret_cast(data);

        ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));

        ......

                    if (receiverObj.get()) {

                        //回调java

                        env->CallVoidMethod(receiverObj.get(),

                                            gBaseEventQueueClassInfo.dispatchSensorEvent,

                                            buffer[i].sensor,

                                            mFloatScratch,

                                            status,

                                            buffer[i].timestamp);

                    }

                }

               ......

        return 1;

    }

};

frameworks/base/core/jni/android_hardware_SensorManager.cpp

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

        }


最终会回调onAccuracyChanged和onSensorChanged,整个分发流程到此就结束了

五.调试技巧及关键点


      看了这么多可能还是是懂非懂的话,可以亲自动手来调试一下,调试的关键点我都已经帮你准备好了,你只需要准备好gdb就可以动手调试了吗,如果gdb你不会用的话,后续我会给你更新一个gdb脚本,运行脚本就能直接attach上对应的进程了
[email protected]进程完整调用栈
①gdb断点system_server端:b vendor/qcom/proprietary/sensors-see/sensors-hal/framework/sensors_hal.cpp:190,并继续运行
②打开写好的sensor APP
③当gdb停下时,bt打印调用栈

[email protected]端push数据到event_queue中调用栈如下:

(gdb) bt

#0  std::__1::__function::__func, void (sensors_event_t, bool)>::operator()(sensors_event_t&&, bool&&) (

    this=0x77362c6f80,

    __arg=,

    __arg=) at external/libcxx/include/functional:1562

#1  0x00000077366e4458 in std::__1::function::operator()(sensors_event_t, bool) const (this=, __arg=false, __arg=false)

    at external/libcxx/include/functional:1916

#2  sensor::submit_sensors_hal_event (this=0x77362c6f00, event=...) at vendor/qcom/proprietary/sensors-see/sensors-hal/framework/sensor.cpp:103

#3  0x00000077366fa3fc in ssc_sensor::handle_sns_std_sensor_event (this=0x77362c6f00, pb_event=...) at vendor/qcom/proprietary/sensors-see/sensors-hal/framework/ssc_sensor.cpp:626

#4  0x00000077366f9588 in ssc_sensor::ssc_conn_event_cb (this=0x77362c6f00, data=, size=, sample_received_ts=)

    at vendor/qcom/proprietary/sensors-see/sensors-hal/framework/ssc_sensor.cpp:461

#5  0x0000007736b04f6c in std::__1::function::operator()(unsigned char const*, unsigned long, unsigned longconst (this=,

    __arg=72142085440877, __arg=72142085440877, __arg=72142085440877) at external/libcxx/include/functional:1916

#6  ssc_qmi_connection::report_indication (this=, msg_id=, ind_buf=, ind_buf_len=, ts=)

    at vendor/qcom/proprietary/commonsys-intf/sensors-see/ssc/ssc_connection.cpp:648

#7  0x0000007736589354 in qmi_cci_xport_recv (clnt=0x7737246600, addr=, buf=0x7736301907 "\001\b", len=71)

    at vendor/qcom/proprietary/commonsys-intf/qmi-framework/qcci/src/qmi_cci_common.c:1378

#8  0x000000773658fad8 in data_msg_reader_thread (arg=0x77372413c0) at vendor/qcom/proprietary/commonsys-intf/qmi-framework/qcci/src/qmi_cci_xport_qrtr.c:430

#9  0x00000077379f14bc in __pthread_start (arg=0x7735a0f4f0) at bionic/libc/bionic/pthread_create.cpp:254

#10 0x0000007737984c3c in __start_thread (fn=0x77379f1494 <__pthread_start(void*)>, arg=0x7735a0f4f0) at bionic/libc/bionic/clone.cpp:52

2.system_server进程完整调用栈

"SensorService" prio=10 tid=41 Native

  | group="main" sCount=1 dsCount=0 flags=1 obj=0x15483a40 self=0x76f1749800

  | sysTid=23193 nice=-8 cgrp=default sched=1073741825/10 handle=0x76eebfb4f0

  | state=S schedstat=( 40777289 1410627 79 ) utm=1 stm=2 core=1 HZ=100

  | stack=0x76eeb00000-0x76eeb02000 stackSize=1009KB

  | held mutexes=

  kernel: (couldn't read /proc/self/task/23193/stack)

  native: #00 pc 000000000007aec4  /system/lib64/libc.so (__ioctl+4)

  native: #01 pc 000000000002ad80  /system/lib64/libc.so (ioctl+132)

  native: #02 pc 000000000001e9cc  /system/lib64/libhwbinder.so (android::hardware::IPCThreadState::talkWithDriver(bool)+200)

  native: #03 pc 000000000001f5d0  /system/lib64/libhwbinder.so (android::hardware::IPCThreadState::waitForResponse(android::hardware::Parcel*, int*)+60)

  native: #04 pc 000000000001ba48  /system/lib64/libhwbinder.so (android::hardware::BpHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function)+132)

  native: #05 pc 000000000000e100  /system/lib64/android.hardware.sensors@1.0.so (android::hardware::sensors::V1_0::BpHwSensors::_hidl_poll(android::hardware::IInterface*, android::hardware::details::HidlInstrumentor*, int, std::__1::function const&, android::hardware::hidl_vec const&)>)+228)

  native: #06 pc 000000000000f644  /system/lib64/android.hardware.sensors@1.0.so (android::hardware::sensors::V1_0::BpHwSensors::poll(int, std::__1::function const&, android::hardware::hidl_vec const&)>)+140)

  native: #07 pc 0000000000017de0  /system/lib64/libsensorservice.so (android::SensorDevice::poll(sensors_event_t*, unsigned long)+164)

  native: #08 pc 0000000000029f34  /system/lib64/libsensorservice.so (android::SensorService::threadLoop()+292)

  native: #09 pc 000000000002abfc  /system/lib64/libsensorservice.so (non-virtual thunk to android::SensorService::threadLoop()+12)

  native: #10 pc 00000000000100dc  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+284)

  native: #11 pc 00000000000b6bbc  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140)

  native: #12 pc 00000000000904b8  /system/lib64/libc.so (__pthread_start(void*)+36)

  native: #13 pc 0000000000023c38  /system/lib64/libc.so (__start_thread+68)

 

你可能感兴趣的:(安卓系统)