我是靠谱客的博主 可爱橘子,最近开发中收集的这篇文章主要介绍Android 9.0 Framework系列--Sensor框架(一),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

研究代码永远是学习进入的最好方式,因为本人更多的工作内容还是在farmework层,这里把之前的一些研究也总结一下。所有的研究都是基于

Android 9.0。

一、Sensor框架概述

关于Sensor框架在网上描述的也挺多的,我也不做深入分析了,这里把自己的思考在这里做一下总结。

整个Android的思路都是server-client的思路,Sensor也不例外,Sensor框架也分为两部分,

1.1 client --SensorManager(frameworksbasecorejavaandroidhardware)SensorManager类,它提供给客户实际操作。围绕SystemSensorManager,还有一系列相关类

1.1.1 java层

➢SensorManager.java --虚类

➢LegacySensorManager--9.0已废除

➢SensorListener.java --监听类

➢Sensor.java ---单个sensor的抽象,用户通过该类对Sensor进行具体实现

➢SystemSensorManager--SensorManager的实现类,实际上上层对Sensor的控制都在SystemSensorManager

1.1.2 jni层 

android_hardware_SensorManager.cpp(frameworksbasecorejni)

1.2 server--SensorService(frameworksnativeservicessensorservice)

SensorService及其一系列代码的主要功能是实现对hal层的的访问,实现虚拟传感器的的相关算法SensorService.cpp --传感器服务

SensorDevice.cpp-管理传感器

RotationVectorSensor.cpp-虚拟传感器

1.3 Hal层

hal层是由厂家自己实现的,它对上提供给SensorService访问,对下直接访问驱动,每一款不同的SOC写法不一样,但都遵照了相Android的相关规则。这里后续描述。

1.4 驱动层

驱动实现了sensor的具体的功能,比如加速度传感器主要是获得xyz的加速度等等。

二、启动

2.1 SensorService的启动

Android启动过程中,先启动SensorService,然后调用hal层进行相关初始化,并进入相关轮询状态。

2.1.1 startBootstrapServices() frameworksbaseservicesjavacomandroidserverSystemServer.java


/**
  * Start the sensor service. This is a blocking call and can take time.
  */
private static native void startSensorService();
    
private void startBootstrapServices() {
        .............................

        // The sensor service needs access to package manager service, app ops
        // service, and permissions service, therefore we start it after them.
        // Start sensor service in a separate thread. Completion should be checked
        // before using it.
        mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
            TimingsTraceLog traceLog = new TimingsTraceLog(
                    SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
            traceLog.traceBegin(START_SENSOR_SERVICE);
            //启动sensor,在jni中实现
            startSensorService();
            traceLog.traceEnd();
        }, START_SENSOR_SERVICE);
    }

2.1.2 startSensorService()

frameworksbaseservicescorejnicom_android_server_SystemServer.cpp 

startSensorService直接在jni中实现

/*
 * JNI registration.
 */
static const JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    { "startSensorService", "()V", (void*) android_server_SystemServer_startSensorService },
    { "startHidlServices", "()V", (void*) android_server_SystemServer_startHidlServices },
};

static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsensorservice", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        //直接调用SensorService::instantiate()
        SensorService::instantiate();
    }

}

2.1.3 SensorService::instantiate()

SensorService继承自BinderService,SensorService::instantiate()会进一步执行BinderService::instantiate,在BinderService中会执行addService,然后将SensorService加入到ServiceManager中。

2.1.4 SensorService::onFirstRef()

SensorService还继承了RefBase,所以会在第一次调用时,调用onFirstRef,而SensorService的初始化就是在onFirstRef中完成。onFirstRef中,比较重要的初始化内容包括:

2.1.4.1.创建SensorDevice,SensorDevice是负责与Hal层连接的关键类

2.1.4.2.从SensorDevice获得当前的传感器列表,并判断当前系统存在哪些传感器,创建对应的相关类,

2.1.4.3 根据当前传感器,创建虚拟传感器类。

从代码上看,一些虚拟传感器的创建关系如下:

加速度/地磁/陀螺仪都有:

RotationVectorSensor

OrientationSensor

LinearAccelerationSensor

CorrectedGyroSensor

GyroDriftSensor

加速度/陀螺仪:

GameRotationVectorSensor

GravitySensor

加速度/地磁:

GeoMagRotationVectorSensor

void SensorService::onFirstRef() {
    ALOGD("nuSensorService starting...");
    //2.1.4.1===
    SensorDevice& dev(SensorDevice::getInstance());

    sHmacGlobalKeyIsValid = initializeHmacKey();

    if (dev.initCheck() == NO_ERROR) {
        sensor_t const* list;
       //2.1.4.2===传感器创建
        ssize_t count = dev.getSensorList(&list);
        if (count > 0) {
            ssize_t orientationIndex = -1;
            bool hasGyro = false, hasAccel = false, hasMag = false;
            uint32_t virtualSensorsNeeds =
                    (1<<SENSOR_TYPE_GRAVITY) |
                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
                    (1<<SENSOR_TYPE_ROTATION_VECTOR) |
                    (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) |
                    (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);

            for (ssize_t i=0 ; i<count ; i++) {
                bool useThisSensor=true;

                switch (list[i].type) {
                    case SENSOR_TYPE_ACCELEROMETER:
                        hasAccel = true;
                        break;
                    case SENSOR_TYPE_MAGNETIC_FIELD:
                        hasMag = true;
                        break;
                    case SENSOR_TYPE_ORIENTATION:
                        orientationIndex = i;
                        break;
                    case SENSOR_TYPE_GYROSCOPE:
                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
                        hasGyro = true;
                        break;
                    case SENSOR_TYPE_GRAVITY:
                    case SENSOR_TYPE_LINEAR_ACCELERATION:
                    case SENSOR_TYPE_ROTATION_VECTOR:
                    case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
                    case SENSOR_TYPE_GAME_ROTATION_VECTOR:
                        if (IGNORE_HARDWARE_FUSION) {
                            useThisSensor = false;
                        } else {
                            virtualSensorsNeeds &= ~(1<<list[i].type);
                        }
                        break;
                }
                if (useThisSensor) {
                    registerSensor( new HardwareSensor(list[i]) );
                }
            }

            // it's safe to instantiate the SensorFusion object here
            // (it wants to be instantiated after h/w sensors have been
            // registered)
            SensorFusion::getInstance();
                 //2.1.4.3===虚拟传感器创建
            if (hasGyro && hasAccel && hasMag) {
                // Add Android virtual sensors if they're not already
                // available in the HAL
                bool needRotationVector =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0;

                registerSensor(new RotationVectorSensor(), !needRotationVector, true);
                registerSensor(new OrientationSensor(), !needRotationVector, true);

                bool needLinearAcceleration =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0;

                registerSensor(new LinearAccelerationSensor(list, count),
                               !needLinearAcceleration, true);

                // virtual debugging sensors are not for user
                registerSensor( new CorrectedGyroSensor(list, count), true, true);
                registerSensor( new GyroDriftSensor(), true, true);
            }

            if (hasAccel && hasGyro) {
                bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
                registerSensor(new GravitySensor(list, count), !needGravitySensor, true);

                bool needGameRotationVector =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0;
                registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true);
            }

            if (hasAccel && hasMag) {
                bool needGeoMagRotationVector =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0;
                registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
            }

            // Check if the device really supports batching by looking at the FIFO event
            // counts for each sensor.
            bool batchingSupported = false;
            mSensors.forEachSensor(
                    [&batchingSupported] (const Sensor& s) -> bool {
                        if (s.getFifoMaxEventCount() > 0) {
                            batchingSupported = true;
                        }
                        return !batchingSupported;
                    });

            if (batchingSupported) {
                // Increase socket buffer size to a max of 100 KB for batching capabilities.
                mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
            } else {
                mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
            }

            // Compare the socketBufferSize value against the system limits and limit
            // it to maxSystemSocketBufferSize if necessary.
            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
            char line[128];
            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
                line[sizeof(line) - 1] = '';
                size_t maxSystemSocketBufferSize;
                sscanf(line, "%zu", &maxSystemSocketBufferSize);
                if (mSocketBufferSize > maxSystemSocketBufferSize) {
                    mSocketBufferSize = maxSystemSocketBufferSize;
                }
            }
            if (fp) {
                fclose(fp);
            }

            mWakeLockAcquired = false;
            mLooper = new Looper(false);
            const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
            mSensorEventBuffer = new sensors_event_t[minBufferSize];
            mSensorEventScratch = new sensors_event_t[minBufferSize];
            mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize];
            mCurrentOperatingMode = NORMAL;

            mNextSensorRegIndex = 0;
            for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
                mLastNSensorRegistrations.push();
            }
            
            //2.1.4.4===运行
            //会启动threadLoop
            mInitCheck = NO_ERROR;
            mAckReceiver = new SensorEventAckReceiver(this);
            mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
            run("SensorService", PRIORITY_URGENT_DISPLAY);

            // priority can only be changed after run
            enableSchedFifoMode();

            // Start watching UID changes to apply policy.
            mUidPolicy->registerSelf();
        }
    }
}

2.1.5 SensorService::threadLoop()

SensorService::threadLoop()主要实现对sensor的poll,轮询sensor上报的相关事件

2.2 SensorService传感器的激活

SensorService除了了启动,还需要将已有的传感器进行activate,通常再底层驱动的实现过程中,只有activate后的传感器才会向上上报数据。

从代码跟踪上看Android启动过程中会向SystemSensorManager.注册registerListener,并进一步调用registerListenerImpl。

registerListenerImpl会获得SensorEventQueue ,并调用SensorEventQueue 的addSensor。

 /** @hide */
    @Override
    protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
           ................

        // Invariants to preserve:
        // - one Looper per SensorEventListener
        // - one Looper per SensorEventQueue
        // We map SensorEventListener to a SensorEventQueue, which holds the looper
        synchronized (mSensorListeners) {
            //获得SensorEventQueue 
            SensorEventQueue queue = mSensorListeners.get(listener);
            if (queue == null) {
                Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
                final String fullClassName =
                        listener.getClass().getEnclosingClass() != null
                            ? listener.getClass().getEnclosingClass().getName()
                            : listener.getClass().getName();
                queue = new SensorEventQueue(listener, looper, this, fullClassName);
				//向queue 中添加要监听的传感器
                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
                    queue.dispose();
                    return false;
                }
                mSensorListeners.put(listener, queue);
                return true;
            } else {
								Log.e(TAG, "registerListenerImpl33333");
                return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
            }
        }
    }

   

SensorEventQueue是SystemSensorManager的内部类,具体实现类是InjectEventQueue。

SensorEventQueue中的addSensor,会将上层要监听的sensor加入到监听队列中,并调用enableSensor使能对应的传感器

        public boolean addSensor(
                Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
            // Check if already present.
            int handle = sensor.getHandle();
            if (mActiveSensors.get(handle)) return false;

            // Get ready to receive events before calling enable.
            mActiveSensors.put(handle, true);
            //添加监听队列
            addSensorEvent(sensor);
            //使能传感器
            if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
                // Try continuous mode if batching fails.
                if (maxBatchReportLatencyUs == 0
                        || maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
                    removeSensor(sensor, false);
                    return false;
                }
            }
            return true;
        }


        private int enableSensor(
                Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
            if (mNativeSensorEventQueue == 0) throw new NullPointerException();
            if (sensor == null) throw new NullPointerException();
            //调用android_hardware_SensorManager.cpp jni使能传感器
            return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
                    maxBatchReportLatencyUs);
        }

android_hardware_SensorManager.cpp jni使能传感器 开始调用SensorEventQueue

static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
                               jint maxBatchReportLatency) {
    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
	    ALOGI("nativeEnableSensor");
    return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
                                                         0);
}

SensorEventQueue会调用SensorEventConnection

status_t SensorEventQueue::enableSensor(Sensor const* sensor, int32_t samplingPeriodUs) const {
	    ALOGE("SensorEventQueue enableSensor");
    return mSensorEventConnection->enableDisable(sensor->getHandle(), true,
                                                 us2ns(samplingPeriodUs), 0, 0);
}

SensorEventConnection会调用SensorService进行传感器激活

status_t SensorService::SensorEventConnection::enableDisable(
        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
        int reservedFlags)
{
    status_t err;
    if (enabled) {
		  ALOGE("SensorEventConnection::enableDisabl");
        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
                               reservedFlags, mOpPackageName);

    } else {
        err = mService->disable(this, handle);
    }
    return err;
}

 

03-20 11:12:18.037  3509  3524 D SensorService: Calling batch handle==0 flags=0rate=66667000 timeout== 100000000
03-20 11:12:18.037  3509  3524 D SensorService: Calling batch handle==0 flags=0rate=66667000 timeout== 100000000
03-20 11:12:18.037  3509  3524 D SensorService: SensorDevice::batch: ident=0x9a4d1180, handle=0x00000000, flags=0, period_ns=66667000 timeout=100000000
03-20 11:12:18.037  3509  3524 D SensorService:         >>> curr_period=9223372036854775807 min_period=66667000 curr_timeout=9223372036854775807 min_timeout=100000000
03-20 11:12:18.037  3509  3524 D SensorService:         >>> actuating h/w BATCH 0x00000000 66667000 100000000
03-20 11:12:18.038  3509  3524 D SensorService: Calling activate on 0
03-20 11[   26.291237@2] sensors 2-006b: sensor on: starting poll sensor data 64ms
:12:18.038  3509  3524 D SensorService: SensorDevice::activate: ident=0x9a4d1180, handle=0x00000000, enabled=1, count=1
03-20 11:12:18.038  3509  3524 D SensorService: enable index=0
03-20 11:12:18.038  3509  3524 D SensorService:         >>> actuating h/w activate handle=0 enabled=1

最后

以上就是可爱橘子为你收集整理的Android 9.0 Framework系列--Sensor框架(一)的全部内容,希望文章能够帮你解决Android 9.0 Framework系列--Sensor框架(一)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部