尾声
在我的博客上很多朋友都在给我留言,需要一些系统的面试高频题目。之前说过我的复习范围无非是个人技术博客还有整理的笔记,考虑到笔记是手写版不利于保存,所以打算重新整理并放到网上,时间原因这里先列出面试问题,题解详见:
展示学习笔记
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事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行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!