sensors open流程

描述:
enable sensor 的时候, sensor 的大概的调用流程是怎样的? 数据流是怎样的。
先插个眼,看懂了在来补充…

// --------------------------------------------------------------------------
2023年07月07日11:09:16 更新

HalProxy.cpp
这是 hardware 层的 active

Return<Result> HalProxy::activate(int32_t sensorHandle, bool enabled) {

    if (!isSubHalIndexValid(sensorHandle)) {
        return Result::BAD_VALUE;
    }
    return getSubHalForSensorHandle(sensorHandle)
            ->activate(clearSubHalIndex(sensorHandle), enabled);
}
std::shared_ptr<ISubHalWrapperBase> HalProxy::getSubHalForSensorHandle(int32_t sensorHandle) {
    return mSubHalList[extractSubHalIndex(sensorHandle)];
}

这两句可以理解为 进入 sensors-hal 的 activate 的函数
最后进入到
sensors_hw_module.cpp
Return sensors_hw_module::activate(int32_t handle, bool en)
{

return ResultFromStatus(_hal->activate((int)handle,(int)en));

}

调用到 sensors_hal.cpp 的 activate 的函数

int sensors_hal::activate(int handle, int enable)
{

    auto& sensor = it->second;
    try {
       
        if (enable) {
            sensor->activate();
        } else {
            sensor->deactivate();
        }
    } 
    return 0;
}

主要就是根据 handle 找出对应的 sensor , 然后调用 ssc_sensor::activate

void ssc_sensor::activate()
{
// sensor 是否是 activate 
 if (!is_active()) { 
      // 没看明白 这是什么场景下的 case ...
    if (_reset_requested) {
      ...
    }

/* establish a new connection to ssc */
//  ssc connection  应该是与 adsp 建立联系的,可以看到注册了一个 回调函数 ssc_conn_event_cb 
        _ssc_conn = make_unique<ssc_connection>(
        [this](const uint8_t *data, size_t size, uint64_t ts)
        {
            ssc_conn_event_cb(data, size, ts);
        });
   //  ssc_connection  的一些设置,暂时没有看懂这个设置有什么用。跳过
   ......................
   .....................
   
try {
            send_sensor_config_request();
            _set_thread_name = true;
 }                
}
}

void ssc_sensor::send_sensor_config_request()

{
    string pb_req_msg_encoded;
    sns_client_request_msg pb_req_msg;
// sensor 的一些设置,为发送做准备.比如: 采样率,msg_id 的设置
    if (_resampling == true) {
        pb_req_msg = create_resampler_config_request();
        pb_req_msg.mutable_suid()->set_suid_high(_resampler_suid.high);
        pb_req_msg.mutable_suid()->set_suid_low(_resampler_suid.low);
    } else {
        pb_req_msg = create_sensor_config_request();
        pb_req_msg.mutable_suid()->set_suid_high(_suid.high);
        pb_req_msg.mutable_suid()->set_suid_low(_suid.low);
    }

    uint32_t batch_period_us = get_params().max_latency_ns / NSEC_PER_USEC;
    uint32_t flush_period_us = 0;

    /* To support Android Hi-Fi requirements for non-wakeup sensors, if
       batch period is less than the time required to buffer
       fifoReservedEventCount number of events, we need to set flush period
       according to the fifoReservedEventCount. For streaming sensors,
       this will be derived from the sample_period and for non-streaming
       sensors, flush period will be set to a max value */
 //  好像是对 sample rate 的一些处理,没有完全看懂...  
    if (_wakeup_type == SENSOR_NO_WAKEUP) {
 
    } else {
        /*after fifoMaxEventCount need to wake up Apps and send the samples
        set batch period corresponding to that as you need to wakeup the App*/
    }
//  设置  batch的速率吧,不是很懂??
    if (_is_on_change_sp_enabled && get_reporting_mode() == SENSOR_FLAG_ON_CHANGE_MODE) {
        uint64_t sample_period_us = get_params().sample_period_ns/NSEC_PER_USEC;
        if (sample_period_us > UINT32_MAX) {
            sns_logi("sample_period_us is larger than acceptable value");
            batch_period_us = UINT32_MAX;
        } else {
            batch_period_us = sample_period_us;
        }
    }
    //  是否是同步 ??
    if (_is_sync_request_enabled) {
        send_sync_sensor_request(pb_req_msg_encoded);
    } else {
       
        if (is_active()) {
            _ssc_conn->send_request(pb_req_msg_encoded, false);
        } 
    }
}

可以看到 上面的函数就是 设置一些 参数,然后发给 adsp 那一侧( sample/batch 还是没太看懂)

ssc_conn_event_cb: ssc_connection 返回的数据,我们在上面注册的回调函数。 是 adsp 那一侧返回来的

void ssc_sensor::ssc_conn_event_cb(const uint8_t *data, size_t size, uint64_t sample_received_ts)
{
    

    sns_client_event_msg pb_event_msg;
    pb_event_msg.ParseFromArray(data, size);
    for (sample_count=0; sample_count < pb_event_msg.events_size(); sample_count++) {
        auto&& pb_event = pb_event_msg.events(sample_count);
       // flush_event 的处理 ...  不是很懂什么时候才会 flush ,有什么意义??
        if (pb_event.msg_id() == SNS_STD_MSGID_SNS_STD_FLUSH_EVENT && _donot_honor_flushevent == false) {
            handle_sns_std_flush_event(pb_event.timestamp());
            flush_req = true;
        } else {
           //a: 先看下这个处理 
            handle_sns_client_event(pb_event);
        }
    }
// for 循环之后 ,sensor 发过来的数据,就到了 event 利去了
    if (events.size()) {
        _event_count = events.size();
      //  b:   提交到哪里去?? 
      // 看下面的分析是:发送到 hardware 那边去了... 
        submit_sensors_hal_event();
    }

    if (flush_req) {
        on_flush_complete();
    }
    if(SENSOR_WAKEUP == _wakeup_type && nullptr !=_wakelock_inst)
      _wakelock_inst->put_n_locks(1);
    SNS_TRACE_END();
}
void ssc_sensor::handle_sns_client_event(
        const sns_client_event_msg_sns_client_event& pb_event)
{
    switch(pb_event.msg_id()) {
      case SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT:
          handle_sns_std_sensor_event(pb_event);
          break;
      default:
          break;
    }
}
这个 SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT 是 adsp 侧发过来的 sensor 获取到了数据,然后就发送

void ssc_sensor::handle_sns_std_sensor_event(
    const sns_client_event_msg_sns_client_event& pb_event)
    {
	
	 sns_std_sensor_event pb_stream_event;
    pb_stream_event.ParseFromString(pb_event.payload());
    // 构造一个 hal_event 的结构体,符合 sensors-hal 的数据要求.
    Event hal_event = create_sensor_hal_event(pb_event.timestamp());
// adsp 那边发过来的 sensor 的数据存储到  hal_event.u.data 数组中,这个数组的长度是  16
     for (int i = 0; i < num_items; i++) {
        hal_event.u.data[i] = pb_stream_event.data(i);
    }
    // 没太看懂是干啥的???
    cal_sample_inerval(pb_event.timestamp());
    calculate_latency(hal_event.timestamp);
    ...
    // 放入 events 里面去了 
     if(true == can_submit_sample(hal_event))
      events.push_back(hal_event);
}

hal_evnet 的结构要求:

Event ssc_sensor::create_sensor_hal_event(uint64_t ssc_timestamp)
{
    Event hal_event;
    //Fix for static analysis error - uninitialized variable
    memset(&hal_event, 0x00, sizeof(Event));
    hal_event.sensorHandle = get_sensor_info().handle;
    hal_event.sensorType = (SensorType)get_sensor_info().type;
    hal_event.timestamp = sensors_timeutil::get_instance().
        qtimer_ticks_to_elapsedRealtimeNano(ssc_timestamp);

    sns_logv("ssc_ts = %llu tk, hal_ts = %lld ns, %lf",
             (unsigned long long)ssc_timestamp,
             (long long)hal_event.timestamp, hal_event.timestamp / 1000000000.0 );
    return hal_event;
}

// b:

/* function to submit a new event to sensor HAL clients */
void sensor::submit_sensors_hal_event()
{
  if (events.size()) {
    submit();
  } 
}
void sensor::submit()
{
    sns_logd("post events , %s %zu, %d", get_sensor_info().stringType, events.size(), _bwakeup);
    if (_event_cb == nullptr) {
        sns_loge("_event_cb is null");
        return;
    }
    try {
        //TODO: make sure we really don't need to control wake-lock here
        //  发送到  HalProxy 那边去..
        _event_cb(events,  _bwakeup);
        events.clear();
    } 

我们看下 这个 _event_cb(events, _bwakeup);
我们在 void sensors_hal::init_sensors() 的时候

auto event_cb = [this](const std::vector& events, bool wakeup) {
_event_callback->post_events(events, wakeup); };
for (unique_ptr& s : sensors) {
s->register_event_callback(event_cb);
}
从这个可以看出 _event_cb 其实就是 event_cb 匿名函数

可以看到 class sensors_hal_event_callback {
public:
virtual ~sensors_hal_event_callback(){};
virtual void post_events(const std::vector& events, bool wakeup) = 0;
};
sensors_hal.h 文件中 是个存虚函数,没有实现

sensors_hw_module.h在看到有对这个函数重写
这个函数 有段注释.
/**

  • Thread-safe callback used to post events to the HalProxy. Sub-HALs should invoke this
  • whenever new sensor events need to be delivered to the sensors framework. Once invoked, the
  • HalProxy will attempt to send events to the sensors framework using a blocking write with a
  • 5 second timeout. This write may be done asynchronously if the queue used to communicate
  • with the framework is full to avoid blocking sub-HALs for the length of the timeout. If the
  • write fails, the events will be dropped and any wake locks held will be released.
  • The provided ScopedWakelock must be locked if the events are from wakeup sensors. If it’s
  • not locked accordingly, the HalProxy will crash as this indicates the sub-HAL isn’t compliant
  • with the sensors HAL 2.0 specification. Additionally, since ScopedWakelock isn’t copyable,
  • the HalProxy will take ownership of the wake lock given when this method is invoked. Once the
  • method returns, the HalProxy will handle holding the wake lock, if necessary, until the
  • framework has successfully processed any wakeup events.
  • No return type is used for this callback to avoid sub-HALs trying to resend events when
  • writes fail. Writes should only fail when the framework is under inordinate stress which will
  • likely result in a framework restart so retrying will likely only result in overloading the
  • HalProxy. Sub-HALs should always assume that the write was a success and perform any
  • necessary cleanup. Additionally, the HalProxy will ensure it logs any errors (through ADB and
  • bug reports) it encounters during delivery to ensure it’s obvious that a failure occurred.
  • @param events the events that should be sent to the sensors framework
  • @param wakelock ScopedWakelock that should be locked to send events from wake sensors and
  • unlocked otherwise.
    

*/
void post_events(const std::vector& events, bool wakeup) override;
看样子 像是向 发送到 HalProxy 那边去了…

目前看 sensor open 的大致流程算是看完了(当然除了那些 sample rate/batch 那些确实是没太看懂),但是 sensor open 之后,数据是一直开的,这样的话,sensor 数据就开始传输了。

题外话:
如果不是很确定调用关系的话,可以打印堆栈,从这 打印log 也能看的出来,这个调用关系

06-17 01:50:47.904  1022  1022 D : #00 pc 000000000004825c  /vendor/lib64/sensors.ssc.so (sensors_hal::activate(int, int)+80)
06-17 01:50:47.904  1022  1022 D : #01 pc 0000000000054e94  /vendor/lib64/sensors.ssc.so (android::hardware::sensors::V2_0::subhal::implementation::sensors_hw_module::activate(int, bool)+100)
06-17 01:50:47.904  1022  1022 D : #02 pc 0000000000013074  /vendor/bin/hw/android.hardware.sensors@2.0-service.multihal (android::hardware::sensors::V2_1::implementation::HalProxy::activate(int, bool)+264)
06-17 01:50:47.904  1022  1022 D : #03 pc 0000000000014708  /apex/com.android.vndk.v30/lib64/android.hardware.sensors@2.0.so (android::hardware::sensors::V2_0::BnHwSensors::_hidl_activate(android::hidl::base::V1_0::BnHwBase*, android::hardware::Parcel const&, android::hardware::Parcel*, std::__1::function<void (android::hardware::Parcel&)>)+184)
06-17 01:50:47.904  1022  1022 D : #04 pc 0000000000015b00  /apex/com.android.vndk.v30/lib64/android.hardware.sensors@2.0.so (android::hardware::sensors::V2_0::BnHwSensors::onTransact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+792)
06-17 01:50:47.904  1022  1022 D : #05 pc 00000000000826d0  /apex/com.android.vndk.v30/lib64/libhidlbase.so (android::hardware::BHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+68)
06-17 01:50:47.904  1022  1022 D : #06 pc 0000000000086668  /apex/com.android.vndk.v30/lib64/libhidlbase.so (android::hardware::IPCThreadState::getAndExecuteCommand()+1076)
06-17 01:50:47.904  1022  1022 D : #07 pc 00000000000878b0  /apex/com.android.vndk.v30/lib64/libhidlbase.so (android::hardware::IPCThreadState::joinThreadPool(bool)+96)
06-17 01:50:47.904  1022  1022 D : #08 pc 00000000000086bc  /vendor/bin/hw/android.hardware.sensors@2.0-service.multihal (main.cfi+1616)
06-17 01:50:47.904  1022  1022 D : #09 pc 000000000004a9f0  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+100)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值