什么个逻辑可以动态控制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); }
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")); }
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; }
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发送什么。
发现一个诡异的现象,当android wear手表放在链接器上,不会上报重复的数据,而不连接链接器放置就会上报重复的数据。
首先,确定这个现象的本质是睡眠唤醒的问题,链接充电座时,手表没有睡眠,而不链时手表会睡眠,可以通过一个app是否持有wakelock验证
起初判断这个event是sensor service睡眠唤醒时发送的,看上面的代码onActive/Idle并没有相关代码。
另外和睡眠唤醒相关的还有一处 sensor DSP会知道AP的睡眠唤醒状态,当sensorDSP知道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; }
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); } } }
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); } } } }
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; }