Android sensor睡眠唤醒相关

编程入门 行业动态 更新时间:2024-10-10 02:15:54

Android sensor<a href=https://www.elefans.com/category/jswz/34/1754135.html style=睡眠唤醒相关"/>

Android sensor睡眠唤醒相关

sensor hal log等级的设置

什么个逻辑可以动态控制log等

const char SENSORS_HAL_PROP_DEBUG[] = "persist.vendor.debug.sensors.hal";
/* map debug property value to log_level */
static const unordered_map<char, sensors_log::log_level> log_level_map = {
    { '0', sensors_log::SILENT },
    { '1', sensors_log::INFO },
    { 'e', sensors_log::ERROR },
    { 'E', sensors_log::ERROR },
    { 'i', sensors_log::INFO },
    { 'I', sensors_log::INFO },
    { 'd', sensors_log::DEBUG },
    { 'D', sensors_log::DEBUG },
    { 'v', sensors_log::VERBOSE },
    { 'V', sensors_log::VERBOSE },
};

void sensors_hal::get_system_config()
{
    char debug_prop[PROPERTY_VALUE_MAX];
    int len;
    len = property_get(SENSORS_HAL_PROP_DEBUG, debug_prop, "i");
    if (len > 0) {
        if (log_level_map.find(debug_prop[0]) != log_level_map.end()) {
            _sysconfig.log_level = log_level_map.at(debug_prop[0]);
        }
    }
    sns_logi("log_level: %d", _sysconfig.log_level);
}

ActivityManager 监听UidObserver事件:gone/idle/active/unknow

void SensorService::onFirstRef() { 
    // Start watching UID changes to apply policy.
    mUidPolicy->registerSelf();
}

void SensorService::UidPolicy::registerSelf() {                                                                                               
      ActivityManager am;
      am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
              | ActivityManager::UID_OBSERVER_IDLE
              | ActivityManager::UID_OBSERVER_ACTIVE,
              ActivityManager::PROCESS_STATE_UNKNOWN,
              String16("android"));
}

UidActive/UidIdle对应的处理函数

native app是怎样使用java service的?

void SensorService::UidPolicy::onUidActive(uid_t uid) {
      {
          Mutex::Autolock _l(mUidLock);
          mActiveUids.insert(uid);
      }
      sp<SensorService> service = mService.promote();
      if (service != nullptr) {
          service->setSensorAccess(uid, true);
      }
}
  
void SensorService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
      bool deleted = false;
      {
          Mutex::Autolock _l(mUidLock);
          if (mActiveUids.erase(uid) > 0) {
              deleted = true;
          }
      }
      if (deleted) {
          sp<SensorService> service = mService.promote();
          if (service != nullptr) {
              service->setSensorAccess(uid, false);
          }
      }
}

最终调用函数 setSensorAccess:

void SensorService::setSensorAccess(uid_t uid, bool hasAccess) {
    ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
    for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) {
        if (conn->getUid() == uid) {
            conn->setSensorAccess(hasAccess);
        }
    }
}

void SensorService::SensorEventConnection::setSensorAccess(const bool hasAccess) {
    Mutex::Autolock _l(mConnectionLock);
    mHasSensorAccess = hasAccess;
}

来自sensor数据是否发往app的判断

UidActive/idle的代码影响了sensor data是否发往client.

        // 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;for (const sp<SensorEventConnection>& connection : activeConnections) {connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,mMapFlushEventsToConnections);needsWakeLock |= connection->needsWakeLock();// If the connection has one-shot sensors, it may be cleaned up after first trigger.// Early check for one-shot sensors.if (connection->hasOneShotSensors()) {cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count);}}

SensorService::SensorEventConnection::sendEvents (connection->sendEvents)
    hasSensorAccess()
        SensorEventQueue::write(mChannel,
            reinterpret_cast<ASensorEvent const*>(scratch), count); 

如果没有数据上传的app如睡眠唤醒后,就要查数据上报的流程,也就是UidActive/idle的代码。

睡眠唤醒相关的代码只是控制了数据上传的控制变量,并没有向sensor发送什么。

 

当睡眠唤醒时,SEE sensor会收到event?

发现一个诡异的现象,当android wear手表放在链接器上,不会上报重复的数据,而不连接链接器放置就会上报重复的数据。

首先,确定这个现象的本质是睡眠唤醒的问题,链接充电座时,手表没有睡眠,而不链时手表会睡眠,可以通过一个app是否持有wakelock验证

起初判断这个event是sensor service睡眠唤醒时发送的,看上面的代码onActive/Idle并没有相关代码。

另外和睡眠唤醒相关的还有一处 sensor DSP会知道AP的睡眠唤醒状态,当sensorDSP知道AP 睡眠唤醒时是否会做一些配置?

remote_proc_sate sensor获得AP状态

sns_rc sns_remote_proc_state_register(sns_register_cb const *register_api)
{
  return register_api->init_sensor(sizeof(sns_remote_proc_state_state),
                                   &remote_proc_state_sensor_api,
                                   &sns_remote_proc_state_sensor_instance_api);
}

typedef enum _sns_std_client_processor {
    SNS_STD_CLIENT_PROCESSOR_SSC = 0,
    SNS_STD_CLIENT_PROCESSOR_APSS = 1,
    SNS_STD_CLIENT_PROCESSOR_ADSP = 2,
    SNS_STD_CLIENT_PROCESSOR_MDSP = 3,
    SNS_STD_CLIENT_PROCESSOR_CDSP = 4,
    SNS_STD_CLIENT_PROCESSOR_COUNT = 5
} sns_std_client_processor;

/**
 * Main function for the SMP2P task. Function registers with the SMP2P service
 * and waits for SMP2P notifications. Signals an event when an SMP2P notification
 * is received.
 *
 * @param[i] args      signal thread pointer
 */
void
sns_remote_proc_state_task(void *args)
{
    sig_thread->cb(sig_thread->sensor, 0, &proc_type);
}

/**
 * Handles signal event from remote processor state task on
 * remote processor state change
 *
 * @param[i] this          remote processor state sensor
 * @param[i] args          remote processor type
 */
static void
sns_remote_proc_state_process_signal_events(sns_sensor *this, uint32_t signal, void const *args)
{
  UNUSED_VAR(signal);
  sns_std_client_processor *proc_type = (sns_std_client_processor *)args;
  sns_sensor_instance *inst = NULL;

  SNS_PROFILE(SNS_REMOTE_PROC_STATE_PROCESS_SIGNAL_EVENT, 1, *proc_type);
  SNS_PRINTF(LOW, this, "Received signal event");

  inst = sns_remote_proc_state_match_instance(this, *proc_type);

  if(NULL != inst)
  {
    sns_remote_proc_state_inst_generate_event(inst, this);
  }
}

/**
 * Find remote processor state instance that has the same processor type
 * as the provided processor type of the new request
 *
 * @param[i] sensor      remote processor state sensor
 * @param[i] proc_type   remote processor type
 */
static sns_sensor_instance*
sns_remote_proc_state_match_instance(sns_sensor *const sensor, sns_std_client_processor proc_type)
{
  sns_sensor_instance *instance;

  for(instance = sensor->cb->get_sensor_instance(sensor, true);
      NULL != instance;
      instance = sensor->cb->get_sensor_instance(sensor, false))
  {
    sns_remote_proc_state_inst_state *inst_state =
      (sns_remote_proc_state_inst_state *)instance->state->state;
    if(inst_state->inst_proc_type == proc_type)
    {
      return instance;
    }
  }
  return NULL;
}

/**
 * Generate event to notify the clients of a remote processor state change
 *
 * @param[i] instance      remote processor state sensor instance
 * @param[i] sensor        remote processor state sensor
 *
 * @return
 * SNS_RC_SUCCESS         if event sent successfully
 * SNS_RC_FAILED          otherwise
 */
static sns_rc
sns_remote_proc_state_inst_generate_event(sns_sensor_instance *const instance,
                                          sns_sensor *const sensor)
{
  sns_remote_proc_state_state *state = (sns_remote_proc_state_state *)sensor->state->state;
  sns_remote_proc_state_event remote_proc_state_event = sns_remote_proc_state_event_init_default;
  sns_remote_proc_state_inst_state *inst_state =
    (sns_remote_proc_state_inst_state *)instance->state->state;
  sns_rc rc = SNS_RC_SUCCESS;

  remote_proc_state_event.proc_type = inst_state->inst_proc_type;

  if(SNS_STD_CLIENT_PROCESSOR_APSS == remote_proc_state_event.proc_type)
  {
    remote_proc_state_event.event_type = state->ap_proc_state;
  }

  SNS_PROFILE(SNS_REMOTE_PROC_STATE_GENERATE_EVENT, 1, remote_proc_state_event.event_type);

  if(!pb_send_event(instance, sns_remote_proc_state_event_fields, &remote_proc_state_event,
                sns_get_system_time(), SNS_REMOTE_PROC_STATE_MSGID_SNS_REMOTE_PROC_STATE_EVENT,
                NULL))
  {
    SNS_PRINTF(ERROR, sensor, "Failed to send Remote Proc State event for instance %p", instance);
    rc = SNS_RC_FAILED;
  }
  return rc;
}

see client manager接收remote_proc_state sensor的数据

static void __attribute__ ((noinline))
cm_handle_single_remote_proc_event(sns_sensor *this, sns_sensor_event *event_in)
{
  sns_std_client_processor proc_type = SNS_STD_CLIENT_PROCESSOR_APSS;
  cm_proc_info *proc_info = NULL;

  if(SNS_REMOTE_PROC_STATE_MSGID_SNS_REMOTE_PROC_STATE_EVENT == event_in->message_id)
  {}

  cm_process_proc_transition(prev_proc_susp_state,
        proc_info->is_suspended,
        this, proc_type);
}

/**
 * Process APPS transition into and out of suspend state.
 * Also updates the processor suspend state for each request
 *
 * @param[i] prev_in_suspend The previous APPS state.
 * @param[i] curr_in_suspend The previous APPS state.
 * @param[i] this            The CM sensor pointer.
 */
SNS_SECTION(".text.island") static void __attribute__ ((noinline))
cm_process_proc_transition(bool prev_in_suspend, bool curr_in_suspend,
    sns_sensor *this, sns_std_client_processor proc_type)
{
  //Suspend -> Apps awake
  if(prev_in_suspend && !curr_in_suspend)
  {
    SNS_PRINTF(LOW, this, "Suspend to awake transition processing");

    //Decide Island State and set latency vote
    sns_cm_set_latency_vote(this, proc_type);
    sns_cm_send_all_data_for_proc((sns_fw_sensor *)this, proc_type, false);
    cm_req_max_batch(this,curr_in_suspend, false, proc_type);
  }
  //Awake->Suspend
  else if(!prev_in_suspend && curr_in_suspend)
  {
    //Decide Island State
    if(!sns_cm_is_island_blocked(this, proc_type))
    {
      /* Release the latency on apps suspend */
      sns_pwr_sleep_mgr_release_latency((void *)this);
    }
    cm_req_max_batch(this,curr_in_suspend,true, proc_type);
  }
  //1. Cancel current timer
  //2. clear timer event list
  //3. and re-register timers after evaluating.
}

/**
 * Changes the requests on all sensor streams for
 * max batching or end max batching.
 *
 * @param[i] this                The sensor pointer.
 * @param[i] proc_in_suspend     The current proccessor state.
 * @param[i] enable_max_batch    The max batch flag to set.
 * @param[i] proc_type           The client processor type.
 *
 */
static void
cm_req_max_batch(sns_sensor *this, bool proc_in_suspend,
    bool enable_max_batch, sns_std_client_processor proc_type)
{
  while(NULL != sns_isafe_list_iter_curr(&instance_iter))
  {
    cm_sensor_inst = (sns_sensor_instance*)sns_isafe_list_iter_get_curr_data(&instance_iter);
    if(NULL != cm_sensor_inst)
    {
      sns_cm_inst_state *cm_inst_state = (sns_cm_inst_state*)cm_sensor_inst->state->state;
      //Switch out of max batching
      sns_isafe_list_iter req_iter;

      for(sns_isafe_list_iter_init(&req_iter, &cm_inst_state->req_list, true);
          NULL!=sns_isafe_list_iter_curr(&req_iter);
          sns_isafe_list_iter_advance(&req_iter))
      {
        sns_cm_request *cm_request = (sns_cm_request*)sns_isafe_list_iter_get_curr_data(&req_iter);
        if(proc_type == cm_request->req_msg.susp_config.client_proc_type &&
           NULL != cm_request->data_stream)
        {
          //We always update the processor suspend state here.
          cm_request->proc_susp_state = proc_in_suspend;
          if(!(state->registry_config.max_batch_disabled))
          {
            cm_switch_non_wkup_req_max_batch_state(cm_request->data_stream,
                cm_request,enable_max_batch);
          }
        }
      }

      //Flush all the requests for the sensor instance
      //if APPS is awake and we have at least 1 non wakeup client
      if(!enable_max_batch && 0 < apss_proc_info->non_wk_cnt)
      {
        sns_cm_send_flush(cm_sensor_inst, SNS_STD_CLIENT_PROCESSOR_APSS);
      }
    }
}

non-wakeup sensor会睡眠唤醒时send non-wakeup request

static void
cm_switch_non_wkup_req_max_batch_state(sns_data_stream *data_stream,
    sns_cm_request *cm_req, bool enable_max_batch)
{
  //Change non-wakeup requests to max_batch requests.
  if(SNS_CLIENT_DELIVERY_WAKEUP != cm_req->req_msg.susp_config.delivery_type)
  {
    uint8_t buffer[200];

    sns_std_request decoded_req = cm_req->req_msg.request;

    decoded_req.has_batching = true;
    // Decide max batch based on the max batch flag
    decoded_req.batching.has_max_batch = true;
    decoded_req.batching.max_batch = enable_max_batch;

    pb_buffer_arg arg ;
    if(0 != cm_req->sensor_payload_len)
    {
      arg.buf = cm_req->sensor_payload;
      arg.buf_len =  cm_req->sensor_payload_len;
    }
    else
    {
      arg.buf = NULL;
      arg.buf_len =  0;
    }

    decoded_req.payload.funcs.encode = &pb_encode_string_cb;
    decoded_req.payload.arg = &arg;
    pb_ostream_t stream_o = pb_ostream_from_buffer((pb_byte_t *)buffer, sizeof(buffer));

    //If payload was empty then reset the payload encode to prevent encoding null bytes.
    if(0 == arg.buf_len)
    {
      arg.buf = NULL;
      arg.buf_len = 0;
    }
    if(!pb_encode(&stream_o, sns_std_request_fields, &decoded_req))
    {
      SNS_SPRINTF(ERROR, sns_fw_printf, "Error Encoding request: %s", PB_GET_ERROR(&stream_o));
    }
    else
    {
      size_t encoded_len = stream_o.bytes_written;
      if(0 < encoded_len)
      {
        sns_request request = (sns_request){
          .request_len = encoded_len,
            .request = buffer,
            .message_id = cm_req->req_msg.msg_id };
        data_stream->api->send_request(data_stream, &request);
      }
    }
  }
}
 

sns_pedometer_instance_set_client_config

xxx_set_client_config就会收到SNS_STD_SENSOR_MSGID_SNS_STD_ON_CHANGE_CONFIG message

在这里如果做上传数据到client的操作,client就会在睡眠唤醒时收到数据。

  sns_rc sns_pedometer_instance_set_client_config(
      sns_sensor_instance *const this, sns_request const *client_request) {
    sns_rc rc = SNS_RC_SUCCESS;
    sns_pedometer_instance_state *state =
        (sns_pedometer_instance_state *)this->state->state;
    SNS_INST_PRINTF(LOW, this, "client_request->message_id=%d",
                    client_request->message_id);
    if ( SNS_STD_SENSOR_MSGID_SNS_STD_ON_CHANGE_CONFIG ==
            client_request->message_id) {

      send_data_to_client(意图是调用的app得到初值,但这会导致多次上报和设想的不一样)
      // if based on amd to control resampler, not enable resampler here
      // if not using amd, enable resampler here
      if (state->sensor_configed == false) {
        // sns_pedo_enable_resampler(this);
        sns_pedo_enable_amd(this);
        state->sensor_configed = true;
      }
    }
    return rc; 
  }           

更多推荐

Android sensor睡眠唤醒相关

本文发布于:2024-02-28 01:12:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1767689.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:睡眠   Android   sensor

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!