2024年Android最新Android Sensor Native 源码分析_aosp源码解读(1),秋招面试技巧

尾声

在我的博客上很多朋友都在给我留言,需要一些系统的面试高频题目。之前说过我的复习范围无非是个人技术博客还有整理的笔记,考虑到笔记是手写版不利于保存,所以打算重新整理并放到网上,时间原因这里先列出面试问题,题解详见:


展示学习笔记

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • JNI registration.
    /
    static const JNINativeMethod gMethods[] = {
    /
    name, signature, funcPtr /
    //这边先将该接口注册,后面给system_server调用
    { “startSensorService”, “()V”, (void
    ) android_server_SystemServer_startSensorService }
    { “startHidlServices”, “()V”, (void*) android_server_SystemServer_startHidlServices },
    };

//在这儿创建sensorservice
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实例是通过调用SensorService::instantiate()方法创建的,此方法来源于SensorService的父类BinderService,所以实质上是调用BinderService::instantiate()来创建实例,而BinderService::instantiate()方法内部仅仅调用了BinderService::publish(),相关方法源码如下:



//这边SERVICE为SensorService类型
template
class BinderService
{
//…
public:
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp sm(defaultServiceManager());
//创建SensorService实例并且添加到ServiceManage
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);
}

static void instantiate() { publish(); }

//…
};


看SensorService的构造函数,主要是创建了UidPolicy对象,此对象功能是管理待机sensor的行为:



SensorService::SensorService()
mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
mWakeLockAcquired(false) {
mUidPolicy = new UidPolicy(this);
}

在BinderService::publish()函数中创建SensorService实例时,会调用onFirstRef()方法,这个方法里,首先创建并获取SensorDevice实例,获取vendor层注册的sensor数据,然后遍历每个sensor并将它们注册到SensorList里边,创建并运行一个SensorEventAckReceiver线程,再创建一个线程运行SensorService::threadLoop(),其代码如下:



void SensorService::onFirstRef() {
SensorDevice& dev(SensorDevice::getInstance());//创建并获取SensorDevice实例

sHmacGlobalKeyIsValid = initializeHmacKey();

if (dev.initCheck() == NO_ERROR) {
    sensor_t const* list;
    ssize_t count = dev.getSensorList(&list);//获取vendor层注册的sensor 数目
    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);
		//遍历每个sensor并将其注册到SensorList里边
        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) {
			//将HAL层的sensor_t类型结构体,存在HardwareSensor类里边,
			//进而在SensorList类里边通过map将handle和HardwareSensor一起存储起来,
                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();
		//融合虚拟sensor的一些逻辑处理,这些不是重点,可以先不管
		//所谓融合sensor,就是虚拟一个sensor,数据是拿一个或多个实际sensor的数据通过各种算法运算处理出来的,
		//比如手机里边的自动转屏功能,就是用加速度数据算出来的。
		//一般这些虚拟sensor需要一个算法一直在跑,若直接跑在AP端功耗很高,
		//手机厂家都是将其实现在协处理器里边,比如高通骁龙845、855的slpi,
		//而不是直接用google在framework实现的那套算法,
        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);
        }
        mWakeLockAcquired = false;
        mLooper = new Looper(false);
        const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
        mSensorEventBuffer = new sensors_event_t[minBufferSize];//创建存储sensor数据的buffer,可以存储256个数据
        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();//这个用来保存应用开关sensor的记录,后面 dumpsys sensorservice dump出来方便debug问题
        }
        mInitCheck = NO_ERROR;
		//创建并运行一个SensorEventAckReceiver 线程
		//这个loop线程用来不断检测是否需要持有wakelock
        mAckReceiver = new SensorEventAckReceiver(this);
        mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
        //在run里边调用SensorEventAckReceiver::threadLoop()方法,
		//通过创建一个线程运行SensorService::threadLoop(),
        run("SensorService", PRIORITY_URGENT_DISPLAY);
        // priority can only be changed after run
        enableSchedFifoMode();//降低主线程调度优先级
        // Start watching UID changes to apply policy.
        mUidPolicy->registerSelf();//这边mUidPolicy将自己注册到uid待机管理里边,后面应用待机行为发生变化时其接口会通过多态被回调
    }
}

}


下面来看SensorService::threadLoop()方法:



bool SensorService::threadLoop() {
ALOGD(“nuSensorService thread starting…”);

// each virtual sensor could generate an event per "real" event, that's why we need to size
// numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.  in practice, this is too
// aggressive, but guaranteed to be enough.
const size_t vcount = mSensors.getVirtualSensors().size();
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
const size_t numEventMax = minBufferSize / (1 + vcount);
//比如这边有vcount个虚拟的 sensor跑在framework,
//那么比较极端的情况下每从HAL取numEventMax个数据,这边vcount个sensor会各生成numEventMax个数据,
//而mSensorEventBuffer 最多只能容纳 MAX_RECEIVE_BUFFER_EVENT_COUNT个数据,
//所以 numEventMax = minBufferSize / (1 + vcount);

SensorDevice& device(SensorDevice::getInstance());

const int halVersion = device.getHalDeviceVersion();
do {
    //通过SensorDevice往HAL层取数据, 若没有数据的时候就一直阻塞(这个由前面说的第三方SO库实现)
    //一般在该so库的poll里边,可以采用c++标准实现的queue::pop(),来获取数据,没数据时就一直阻塞,
    //当驱动有数据上来时,另外一个线程将sensor数据往这个队列里边queue::pop就行了
    ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
    if (count < 0) {
        ALOGE("sensor poll failed (%s)", strerror(-count));
        break;

    }

    // Reset sensors_event_t.flags to zero for all events in the buffer.
    for (int i = 0; i < count; i++) {
         mSensorEventBuffer[i].flags = 0;
    }

    // Make a copy of the connection vector as some connections may be removed during the course
    // of this loop (especially when one-shot sensor events are present in the sensor_event
    // buffer). Promote all connections to StrongPointers before the lock is acquired. If the
    // destructor of the sp gets called when the lock is acquired, it may result in a deadlock
    // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
    // strongPointers to a vector before the lock is acquired.
    SortedVector< sp<SensorEventConnection> > activeConnections;
    populateActiveConnections(&activeConnections);

    Mutex::Autolock _l(mLock);
    // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
    // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
    // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
    // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
    // releasing the wakelock.
    bool bufferHasWakeUpEvent = false;
    for (int i = 0; i < count; i++) {
        if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
            bufferHasWakeUpEvent = true;
            break;
        }
    }
	//若有wakeup 类型sensor上报的数据就持有wakelock
    if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
        setWakeLockAcquiredLocked(true);
    }
    recordLastValueLocked(mSensorEventBuffer, count);//将事件保存下来,后面可以用dumpsys sensorservice dump出来方便分析问题

    // 暂时先忽略handle virtual sensor,dynamic sensor部分
	
	
    // 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;
    size_t numConnections = activeConnections.size();
    for (size_t i=0 ; i < numConnections; ++i) {
        if (activeConnections[i] != 0) {
			//通过SensorEventConnection 将数据通过socket发送给应用
            activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
                    mMapFlushEventsToConnections);
            needsWakeLock |= activeConnections[i]->needsWakeLock();
            // If the connection has one-shot sensors, it may be cleaned up after first trigger.
            // Early check for one-shot sensors.
            if (activeConnections[i]->hasOneShotSensors()) {
                cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
                        count);
            }
        }
    }
	
	//若还有wake up 类型的sensor报上来的数据的话,需要继续持有wakelock
    if (mWakeLockAcquired && !needsWakeLock) {
        setWakeLockAcquiredLocked(false);
    }
} while (!Thread::exitPending());

ALOGW("Exiting SensorService::threadLoop => aborting...");
abort();
return false;

}


该方法就是用SensorDevice循环去HAL层取数据,若无数据则阻塞当前线程,若有数据,则封装SensorEventConnection发送出去。至此SensorService已经启动了。


##### 3.2.2 SensorManager的启动流程


从前一篇分析安卓Sensor 框架 Java API层的源码中我们知道,SystemSensorManager继承并实现SensorManager的虚方法,应用通过调用SensorManger的方法来达到其监听sensor数据的需求,而实际功能的实现者是SystemSensorManager,且SystemSensorManager中负责和Native层的SensorManager交互。安卓系统开机时在  
 frameworks/base/core/java/android/app/SystemServiceRegistry.java中创建SystemSensorManger实例:



registerService(Context.SENSOR_SERVICE, SensorManager.class,
new CachedServiceFetcher() {
@Override
public SensorManager createService(ContextImpl ctx) {
return new SystemSensorManager(ctx.getOuterContext(),
ctx.mMainThread.getHandler().getLooper());
}});
然后跳转到SystemSensorManager的构造方法中:
public SystemSensorManager(Context context, Looper mainLooper) {
synchronized (sLock) {
if (!sNativeClassInited) {
sNativeClassInited = true;
nativeClassInit();//native层offset初始化,没做什么其他事情
}
}
Log.e(“======>lkh”, Log.getStackTraceString(new Throwable()));

mMainLooper = mainLooper;
mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
mContext = context;
mNativeInstance = nativeCreate(context.getOpPackageName());
//mNativeInstance 保存native创建的 c++对象 SensorManager的引用,
//该对象通过getOpPackageName()返回的结果作为参数创建,并且2者保存在一个map里边,
//注意,此SensorManager为native层c++实现的,非面向应用用Java实现的SensorManager

// initialize the sensor list
for (int index = 0;; ++index) {
    Sensor sensor = new Sensor();
    if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
    mFullSensorsList.add(sensor);
    mHandleToSensor.put(sensor.getHandle(), sensor);
}
//获取SesorService的sensor list里边的所有sensor,每个sensor创建一个对应的java层的Sensor对象,
//并保存到链表里边,并将sensor handle和sensor一并保存到map里边

}
在加锁的情况下,如果没有初始化过Native层的类,则调用nativeClassInit() JNI方法初始化,调用nativeCreate()方法初始化SensorManager.cpp的实例,再调用nativeGetSensorAtIndex() jni方法初始化sensor列表,以上分析可知,当SystemSensorManager初始化时,SensorManager.cpp同时也初始化了。
static jlong
nativeCreate
(JNIEnv *env, jclass clazz, jstring opPackageName)
{
ScopedUtfChars opPackageNameUtf(env, opPackageName);
return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
}
接下来跳入Native SensorManager的构造函数中:
SensorManager::SensorManager(const String16& opPackageName)
: mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) {
// okay we’re not locked here, but it’s not needed during construction
assertStateLocked();
}

status_t SensorManager::assertStateLocked() {
bool initSensorManager = false;
if (mSensorServer == NULL) {
initSensorManager = true;
} else {
// Ping binder to check if sensorservice is alive.
status_t err = IInterface::asBinder(mSensorServer)->pingBinder();
if (err != NO_ERROR) {
initSensorManager = true;
}
}
if (initSensorManager) {
waitForSensorService(&mSensorServer);
LOG_ALWAYS_FATAL_IF(mSensorServer == nullptr, “getService(SensorService) NULL”);

    class DeathObserver : public IBinder::DeathRecipient {
        SensorManager& mSensorManager;
        virtual void binderDied(const wp<IBinder>& who) {
            ALOGW("sensorservice died [%p]", who.unsafe_get());
            mSensorManager.sensorManagerDied();
        }
    public:
        explicit DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
    };

    mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
    IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);

    mSensors = mSensorServer->getSensorList(mOpPackageName);
    size_t count = mSensors.size();
    mSensorList =
            static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
    LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL");

    for (size_t i=0 ; i<count ; i++) {
        mSensorList[i] = mSensors.array() + i;
    }
}

return NO_ERROR;

}


上面代码主要做了3件事情:


1. 等待SensorService起来,获取到其指针
2. 注册一个DeathObserver,当sensorManagerDied()时,做一些清理操作
3. 获取sensorList里面的每一个sensor对象的地址


### 3.3 Sensor数据的分发


接下来分析SensorService如何将sensor数据分发到应用,上面SensorService启动时,我们知道SensorService启动了一个线程去执行threadLoop方法,这个方法首先调用SensorDevice::getInstance()方法,获取其实例引用,接下来就进入了一个调用SensorDevice::poll()方法的do while循环中,SensorDevice在其中扮演了十分重要的角色,主要通过该类从HAL层取数据,下面是SensorDevice的部分源码:



SensorDevice::SensorDevice()
mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {
//通过hidl与HAL层建立连接
if (!connectHidlService()) {
    return;
}

//获取开机时前面所说的第三方SO库注册的sensor,这个SO库一般就是直接与驱动进行通信对实际sensor进行开关和数据获取了,
//比如高通骁龙855的sensors.ssc.so通过qmi与slpi进行通信。
//这些sensor_t 类型的结构体,需要第三方的so库里边自己实现,每个结构体对象存储一个sensor的信息
checkReturn(mSensors->getSensorsList(
        [&](const auto &list) {
            const size_t count = list.size();

            mActivationCount.setCapacity(count);
            Info model;
            for (size_t i=0 ; i < count; i++) {
                sensor_t sensor;
                convertToSensor(list[i], &sensor);
                // Sanity check and clamp power if it is 0 (or close)
                if (sensor.power < minPowerMa) {
                    ALOGE("Reported power %f not deemed sane, clamping to %f",
                          sensor.power, minPowerMa);
                    sensor.power = minPowerMa;
                }
                mSensorList.push_back(sensor);//将HAL层注册的sensor保存起来,具体如何注册的,后面分析sensor HAL层部分再分析
				
				//保存该sensor的handle,具体数值是在前面所说的第三方SO库决定的,一般是从1开启按顺序叠加
                mActivationCount.add(list[i].sensorHandle, model);

                checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* disable */));//关闭该sensor,以防开着没用漏电
            }
        }));

}

bool SensorDevice::connectHidlService() {
// SensorDevice will wait for HAL service to start if HAL is declared in device manifest.
size_t retry = 10;

while (retry-- > 0) {
	//......
	
    //通过hidl获取 android.hardware.sensors@1.0-service
    mSensors = ISensors::getService();
    if (mSensors == nullptr) {
        // no sensor hidl service found
        break;
    }
	
	//.......
}
return (mSensors != nullptr);

}


与HAL层如何交互的分析已经远远超出我负责的范畴了,这里不做深入分析。我们只需知道Native层的Sensor数据是通过SensorDevice去HAL取得的就行了。当数据上来后,通过做一些判断和处理然后再分发给应用,其中判断处理包括:是否应该丢弃数据,是否是flush数据,是否需要将数据给融合sensor,应用是否已经关闭该sensor等,处理后,通过SensorService::SensorEventConnection::sendEvents将数据发出,senEvent()函数代码如下:



status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch,
wp const * mapFlushEventsToConnections) {
// filter out events not for this connection

sensors_event_t* sanitizedBuffer = nullptr;

int count = 0;
Mutex::Autolock _l(mConnectionLock); 
if (scratch) {
    size_t i=0;
    while (i<numEvents) {
        //每个数据琢一处理
        int32_t sensor_handle = buffer[i].sensor;
        if (buffer[i].type == SENSOR_TYPE_META_DATA) {
            ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
                    buffer[i].meta_data.sensor);
            // Setting sensor_handle to the correct sensor to ensure the sensor events per
            // connection are filtered correctly.  buffer[i].sensor is zero for meta_data
            // events.
            sensor_handle = buffer[i].meta_data.sensor;
        }

        ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
        //enable 一个sensor时,会保存该sensor的handle
        //确认一下若该sensor已经被disable了,那么就没有必要将该sensor的数据给到应用了
        //或者该应用没有注册该sensor的话,也是直接过滤掉
        // Check if this connection has registered for this sensor. If not continue to the
        // next sensor_event.
        if (index < 0) {
            ++i;
            continue;
        }

        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
        // Check if there is a pending flush_complete event for this sensor on this connection.
        if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
                mapFlushEventsToConnections[i] == this) {
            flushInfo.mFirstFlushPending = false;
            ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
                    buffer[i].meta_data.sensor);
            ++i;
            continue;
        }

        // If there is a pending flush complete event for this sensor on this connection,
        // ignore the event and proceed to the next.
        if (flushInfo.mFirstFlushPending) {
            ++i;
            continue;
        }

        //过滤掉flush的数据后,将要给到应用的数据拷到scratch
        do {
            // Keep copying events into the scratch buffer as long as they are regular
            // sensor_events are from the same sensor_handle OR they are flush_complete_events
            // from the same sensor_handle AND the current connection is mapped to the
            // corresponding flush_complete_event.
            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
                if (mapFlushEventsToConnections[i] == this) {
                    scratch[count++] = buffer[i];
                }
            } else {
                // Regular sensor event, just copy it to the scratch buffer.
				//若为false,即应用进入idle,那么就不将数据装进scratch在通过scratch给到应用,
                //否则就装进去
                if (mHasSensorAccess) {
                    scratch[count++] = buffer[i];
                }
            }
            i++;
        } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
                                    buffer[i].type != SENSOR_TYPE_META_DATA) ||
                                   (buffer[i].type == SENSOR_TYPE_META_DATA  &&
                                    buffer[i].meta_data.sensor == sensor_handle)));
    }
} else {
    //这边不会走到不用管,感觉google这段代码有点多余哈哈
    if (mHasSensorAccess) {
        scratch = const_cast<sensors_event_t *>(buffer);
        count = numEvents;
    } else {
        scratch = sanitizedBuffer = new sensors_event_t[numEvents];
        for (size_t i = 0; i < numEvents; i++) {
            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
                scratch[count++] = buffer[i++];
            }
        }
    }
}

sendPendingFlushEventsLocked();
// Early return if there are no events for this connection.
if (count == 0) {
    delete sanitizedBuffer;//可能遇到空指针?  free 已经做了判断了
    return status_t(NO_ERROR);
}

#if DEBUG_CONNECTIONS
mEventsReceived += count;
#endif
//将最新的数据缓存到mEventCache,后面可以dump出来debug
if (mCacheSize != 0) {
// There are some events in the cache which need to be sent first. Copy this buffer to
// the end of cache.
if (mCacheSize + count <= mMaxCacheSize) {
memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
mCacheSize += count;
} else {
// Check if any new sensors have registered on this connection which may have increased
// the max cache size that is desired.
if (mCacheSize + count < computeMaxCacheSizeLocked()) {
reAllocateCacheLocked(scratch, count);
delete sanitizedBuffer;
return status_t(NO_ERROR);
}
// Some events need to be dropped.
int remaningCacheSize = mMaxCacheSize - mCacheSize;
if (remaningCacheSize != 0) {
memcpy(&mEventCache[mCacheSize], scratch,
remaningCacheSize * sizeof(sensors_event_t));
}
int numEventsDropped = count - remaningCacheSize;
countFlushCompleteEventsLocked(mEventCache, numEventsDropped);
// Drop the first “numEventsDropped” in the cache.
memmove(mEventCache, &mEventCache[numEventsDropped],
(mCacheSize - numEventsDropped) * sizeof(sensors_event_t));

        // Copy the remainingEvents in scratch buffer to the end of cache.
        memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
                                        numEventsDropped * sizeof(sensors_event_t));
    }
    delete sanitizedBuffer;
    return status_t(NO_ERROR);
}

int index_wake_up_event = -1;
if (mHasSensorAccess) {
    index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
    if (index_wake_up_event >= 0) {
        scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
        ++mWakeLockRefCount;

#if DEBUG_CONNECTIONS
++mTotalAcksNeeded;
#endif
}
}

// NOTE: ASensorEvent and sensors_event_t are the same type.


//重点在这边,把scratch里边的数据发出去,
ssize_t size = SensorEventQueue::write(mChannel,
                                reinterpret_cast<ASensorEvent const*>(scratch), count);
if (size < 0) {
    // Write error, copy events to local cache.
    if (index_wake_up_event >= 0) {
        // If there was a wake_up sensor_event, reset the flag.
        scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
        if (mWakeLockRefCount > 0) {
            --mWakeLockRefCount;
        }

#if DEBUG_CONNECTIONS
–mTotalAcksNeeded;
#endif
}
if (mEventCache == NULL) {
mMaxCacheSize = computeMaxCacheSizeLocked();
mEventCache = new sensors_event_t[mMaxCacheSize];
mCacheSize = 0;
}
memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
mCacheSize += count;

    // Add this file descriptor to the looper to get a callback when this fd is available for
    // writing.
    updateLooperRegistrationLocked(mService->getLooper());
    delete sanitizedBuffer;

Android高级架构师

由于篇幅问题,我呢也将自己当前所在技术领域的各项知识点、工具、框架等汇总成一份技术路线图,还有一些架构进阶视频、全套学习PDF文件、面试文档、源码笔记。

  • 330页PDF Android学习核心笔记(内含上面8大板块)

  • Android学习的系统对应视频

  • Android进阶的系统对应学习资料

  • Android BAT部分大厂面试题(有解析)

好了,以上便是今天的分享,希望为各位朋友后续的学习提供方便。觉得内容不错,也欢迎多多分享给身边的朋友哈。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

ndroid高级架构师

由于篇幅问题,我呢也将自己当前所在技术领域的各项知识点、工具、框架等汇总成一份技术路线图,还有一些架构进阶视频、全套学习PDF文件、面试文档、源码笔记。

  • 330页PDF Android学习核心笔记(内含上面8大板块)

[外链图片转存中…(img-dqhLmpwf-1714959714506)]

[外链图片转存中…(img-LLP9T5Jh-1714959714507)]

  • Android学习的系统对应视频

  • Android进阶的系统对应学习资料

[外链图片转存中…(img-kG0oVyfl-1714959714507)]

  • Android BAT部分大厂面试题(有解析)

[外链图片转存中…(img-Y4rAybN3-1714959714507)]

好了,以上便是今天的分享,希望为各位朋友后续的学习提供方便。觉得内容不错,也欢迎多多分享给身边的朋友哈。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 26
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值