Android sensor睡眠唤醒相关

it2023-04-08  73

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

最新回复(0)