睡眠唤醒相关"/>
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睡眠唤醒相关
发布评论