Android Senor Framework (五) SensorManager

SensorManager

通过前面的博客介绍可知在Java application中, 由SystemSensorManage对象管理每一个sensor;

在msm8909平台的HAL sensor实现中,有native SensorManager 管理HAL sensor 与Sensor driver交互,同时与Freamwork交互;

在它们中间即Native C/C++ Libraries中,同样也是由相应的SensorManager管理; 以下是SensorManager class定义:

class SensorManager : public ASensorManager
{
public:
    static SensorManager& getInstanceForPackage(const String16& packageName);
    ~SensorManager();
    ssize_t getSensorList(Sensor const* const** list);
    ssize_t getDynamicSensorList(Vector<Sensor>& list);
    Sensor const* getDefaultSensor(int type);
    sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0);
    bool isDataInjectionEnabled();
private:
    // DeathRecipient interface
    void sensorManagerDied();
    SensorManager(const String16& opPackageName);
    status_t assertStateLocked();
private:
    static Mutex sLock;
    static std::map<String16, SensorManager*> sPackageInstances;
    Mutex mLock;
    sp<ISensorServer> mSensorServer;
    Sensor const** mSensorList;
    Vector<Sensor> mSensors;
    sp<IBinder::DeathRecipient> mDeathObserver;
    const String16 mOpPackageName;
};

其构造器内容:

SensorManager::SensorManager(const String16& opPackageName)
    : mSensorList(0), mOpPackageName(opPackageName) {
    // okay we're not locked here, but it's not needed during construction
    assertStateLocked();
}

调用了 SensorManager的 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) {
        // try for 300 seconds (60*5(getService() tries for 5 seconds)) before giving up ...
        const String16 name("sensorservice");
        for (int i = 0; i < 60; i++) {
            status_t err = getService(name, &mSensorServer);
            if (err == NAME_NOT_FOUND) {
                sleep(1);
                continue;
            }
//......
        }
        class DeathObserver : public IBinder::DeathRecipient {
            SensorManager& mSensorManager;
            virtual void binderDied(const wp<IBinder>& who) {
                ALOGW("sensorservice died [%p]", who.unsafe_get());
                mSensorManager.sensorManagerDied();
            }
        public:
            DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
        };
        LOG_ALWAYS_FATAL_IF(mSensorServer.get() == NULL, "getService(SensorService) NULL");
        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;
}

初始化过程,获取Service:getService(name, &mSensorServer); 它的定义是 sp mSensorServer;

ISensorServer
frameworks\native\include\gui\ISensorServer.h
class ISensorServer : public IInterface
{
public:
    DECLARE_META_INTERFACE(SensorServer);
    virtual Vector<Sensor> getSensorList(const String16& opPackageName) = 0;
    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName) = 0;
    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
             int mode, const String16& opPackageName) = 0;
    virtual int32_t isDataInjectionEnabled() = 0;
};

frameworks\native\libs\gui\ISensorServer.cpp
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
             int mode, const String16& opPackageName)
    {
        Parcel data, reply;
        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
        data.writeString8(packageName);
        data.writeInt32(mode);
        data.writeString16(opPackageName);
        remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
        return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
    }

Sensor JNI

在分析Java application过程中,在SystemSensorManager 使用了 大量的native 方法; 在android的层次架构中,想要清楚的梳理代码逻辑关系,首先还是需要

把java 和 c++ 直接的映射关系,需要分析其中jni 实现;

系统启动过程中,AndroidRuntime会注册所需要的JNI接口;在AndroidRuntime.cpp中:

代码路径:/frameworks/base/core/jni/AndroidRuntime.cpp

/*
 * Register android native functions with the VM.
 */
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{  
   ATRACE_NAME("RegisterAndroidNatives");
   androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

   ALOGV("--- registering native functions ---\n");
   env->PushLocalFrame(200);
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
    //......
}
static const RegJNIRec gRegJNI[] = {
//......
  REG_JNI(register_android_hardware_SensorManager),
//......
}

register_android_hardware_SensorManager 实现的内容:

代码路径:/frameworks/base/core/jni/android_hardware_SensorManager.cpp

int register_android_hardware_SensorManager(JNIEnv *env)
{
    RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager",
            gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));
    RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager$BaseEventQueue",
            gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));
    gBaseEventQueueClassInfo.clazz = FindClassOrDie(env,
            "android/hardware/SystemSensorManager$BaseEventQueue");
//......
    return 0;
}

这里只关注 RegisterMethodsOrDie 注册的gSystemSensorManagerMethods,gBaseEventQueueMethods; 如其名称,前者是sensormange相关,后者是sensor event相关; 主要内容如下:

static const JNINativeMethod gSystemSensorManagerMethods[] = {
    {"nativeClassInit",
            "()V",
            (void*)nativeClassInit },
    {"nativeCreate",
             "(Ljava/lang/String;)J",
             (void*)nativeCreate },

    {"nativeGetSensorAtIndex",
            "(JLandroid/hardware/Sensor;I)Z",
            (void*)nativeGetSensorAtIndex },

    {"nativeGetDynamicSensors",
            "(JLjava/util/List;)V",
            (void*)nativeGetDynamicSensors },

    {"nativeIsDataInjectionEnabled",
            "(J)Z",
            (void*)nativeIsDataInjectionEnabled},
};
static const JNINativeMethod gBaseEventQueueMethods[] = {
    {"nativeInitBaseEventQueue",
             "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J",
             (void*)nativeInitSensorEventQueue },

    {"nativeEnableSensor",
            "(JIII)I",
            (void*)nativeEnableSensor },

    {"nativeDisableSensor",
            "(JI)I",
            (void*)nativeDisableSensor },

    {"nativeDestroySensorEventQueue",
            "(J)V",
            (void*)nativeDestroySensorEventQueue },

    {"nativeFlushSensor",
            "(J)I",
            (void*)nativeFlushSensor },

    {"nativeInjectSensorData",
            "(JI[FIJ)I",
            (void*)nativeInjectSensorData },
};

SystemManager.java 访问JNI

在SystemSensorManager.java中,其构造器函数会调用nativeClassInit() 用于初始化;nativeCreate用于创建SensorManager实例;调用nativeGetSensorAtIndex 循环初始化在java中的 sensor list;

代码实现如下:

    public SystemSensorManager(Context context, Looper mainLooper) {
        synchronized(sLock) {
            if (!sNativeClassInited) {
                sNativeClassInited = true;
                nativeClassInit();
            }
        }
        mMainLooper = mainLooper;
        mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
        mContext = context;
        mNativeInstance = nativeCreate(context.getOpPackageName());
 
        // 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);
        }
    }

它们在android_hardware_SensorManager.cpp 中的实现如下:

nativeClassInit
static void
nativeClassInit (JNIEnv *_env, jclass _this)
{
    //android.hardware.Sensor
    SensorOffsets& sensorOffsets = gSensorOffsets;
    jclass sensorClass = (jclass) _env->NewGlobalRef(_env->FindClass("android/hardware/Sensor"));
    sensorOffsets.clazz       = sensorClass;
    sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");
    sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");
    sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");
    sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");
    sensorOffsets.range       = _env->GetFieldID(sensorClass, "mMaxRange",  "F");
    sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
    sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
    sensorOffsets.minDelay    = _env->GetFieldID(sensorClass, "mMinDelay",  "I");
    sensorOffsets.fifoReservedEventCount =
            _env->GetFieldID(sensorClass, "mFifoReservedEventCount",  "I");
    sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount",  "I");
    sensorOffsets.stringType = _env->GetFieldID(sensorClass, "mStringType", "Ljava/lang/String;");
    sensorOffsets.requiredPermission = _env->GetFieldID(sensorClass, "mRequiredPermission",
                                                        "Ljava/lang/String;");
    sensorOffsets.maxDelay    = _env->GetFieldID(sensorClass, "mMaxDelay",  "I");
    sensorOffsets.flags = _env->GetFieldID(sensorClass, "mFlags",  "I");

    sensorOffsets.setType = _env->GetMethodID(sensorClass, "setType", "(I)Z");
    sensorOffsets.setUuid = _env->GetMethodID(sensorClass, "setUuid", "(JJ)V");
    sensorOffsets.init = _env->GetMethodID(sensorClass, "<init>", "()V");

    // java.util.List;
    ListOffsets& listOffsets = gListOffsets;
    jclass listClass = (jclass) _env->NewGlobalRef(_env->FindClass("java/util/List"));
    listOffsets.clazz = listClass;
    listOffsets.add = _env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
}
nativeCreate
static jlong nativeCreate
(JNIEnv *env, jclass clazz, jstring opPackageName)
{
    ScopedUtfChars opPackageNameUtf(env, opPackageName);
    return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
}

在JNI绑定的 nativeCreate中,调用了 用于创建SensorManager的实例化接口;

nativeGetSensorAtIndex
static jboolean
nativeGetSensorAtIndex(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensor, jint index)
{
    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);

    Sensor const* const* sensorList;
    ssize_t count = mgr->getSensorList(&sensorList);
    if (ssize_t(index) >= count) {
        return false;
    }

    return translateNativeSensorToJavaSensor(env, sensor, *sensorList[index]) != NULL;
}

在函数的最后 调用了translateNativeSensorToJavaSensor, 这正是前面提到的 把C++ 中的sensor 结构转化为java中的Sensor结构,它的实现如下:

translateNativeSensorToJavaSensor
translateNativeSensorToJavaSensor(JNIEnv *env, jobject sensor, const Sensor& nativeSensor) {
    const SensorOffsets& sensorOffsets(gSensorOffsets);

    if (sensor == NULL) {
        // Sensor sensor = new Sensor();
        sensor = env->NewObject(sensorOffsets.clazz, sensorOffsets.init, "");
    }

    if (sensor != NULL) {
        jstring name = env->NewStringUTF(nativeSensor.getName().string());
        jstring vendor = env->NewStringUTF(nativeSensor.getVendor().string());
        jstring requiredPermission =
                env->NewStringUTF(nativeSensor.getRequiredPermission().string());

        env->SetObjectField(sensor, sensorOffsets.name,      name);
        env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
        env->SetIntField(sensor, sensorOffsets.version,      nativeSensor.getVersion());
        env->SetIntField(sensor, sensorOffsets.handle,       nativeSensor.getHandle());
        env->SetFloatField(sensor, sensorOffsets.range,      nativeSensor.getMaxValue());
        env->SetFloatField(sensor, sensorOffsets.resolution, nativeSensor.getResolution());
        env->SetFloatField(sensor, sensorOffsets.power,      nativeSensor.getPowerUsage());
        env->SetIntField(sensor, sensorOffsets.minDelay,     nativeSensor.getMinDelay());
        env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount,
                         nativeSensor.getFifoReservedEventCount());
        env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount,
                         nativeSensor.getFifoMaxEventCount());
        env->SetObjectField(sensor, sensorOffsets.requiredPermission,
                            requiredPermission);
        env->SetIntField(sensor, sensorOffsets.maxDelay, nativeSensor.getMaxDelay());
        env->SetIntField(sensor, sensorOffsets.flags, nativeSensor.getFlags());

        if (env->CallBooleanMethod(sensor, sensorOffsets.setType, nativeSensor.getType())
                == JNI_FALSE) {
            jstring stringType = getInternedString(env, &nativeSensor.getStringType());
            env->SetObjectField(sensor, sensorOffsets.stringType, stringType);
        }

        // TODO(b/29547335): Rename "setUuid" method to "setId".
        int64_t id = nativeSensor.getId();
        env->CallVoidMethod(sensor, sensorOffsets.setUuid, id, 0);
    }
    return sensor;
}

SensorManager实例化

通过上面内容可知,systemSensosrManager.java中调用了nativeCreate,会调用到 JNI中绑定的nativeCreate, 进而调用SensorManager 实例化的api:

(jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));

它的实例化过程如下:

getInstanceForPackage
SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) {
    Mutex::Autolock _l(sLock);
    SensorManager* sensorManager;
    std::map<String16, SensorManager*>::iterator iterator =
        sPackageInstances.find(packageName);
    if (iterator != sPackageInstances.end()) {
        sensorManager = iterator->second;
    } else {
        String16 opPackageName = packageName;
        if (opPackageName.size() <= 0) {
            sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
            if (binder != 0) {
                const uid_t uid = IPCThreadState::self()->getCallingUid();
                Vector<String16> packages;
                interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages);
                if (!packages.isEmpty()) {
                    opPackageName = packages[0];
                } else {
                    ALOGE("No packages for calling UID");
                }
            } else {
                ALOGE("Cannot get permission service");
            }
        }
        sensorManager = new SensorManager(opPackageName);
        if (packageName.size() <= 0) {
            sPackageInstances.insert(std::make_pair(String16(), sensorManager));
        }
        // Stash the per package sensor manager.
        sPackageInstances.insert(std::make_pair(opPackageName, sensorManager));
    }
    return *sensorManager;
}

SensorEvent

整理中......

时序图

在app启动加载之前,启动初始化时已经创建了SensorMangager; 通过JNI绑定了 SensorManager的相应native方法,以下是其简要步骤;

  • a: AndroidRuntime::start() ->REG_JNI(register_android_hardware_SensorManager)
    ./base/core/jni/AndroidRuntime.cpp中调用注册了本地C++ 方法,库文件是libandroid_runtime.so;
    详细过程参考:Android系统启动流程

  • b: android_hardware_SensorManager.cpp中完成native C++函数与java方法的绑定,RegisterMethods;

  • c: 上面过程中已经完成了加载,Java代码中SystemSensorManager可以直接调用Sensor相关的native方法;

  • A: 系统服务注册时会创建SensorManager;
    代码路径:./core/java/android/app/SystemServiceRegistry.java
    registerService(Context.SENSOR_SERVICE, SensorManager.class,
    new CachedServiceFetcher() {
    @Override
    public SensorManager createService(ContextImpl ctx) {
    return new SystemSensorManager(ctx.getOuterContext(),
    ctx.mMainThread.getHandler().getLooper());
    }});
    参考:android笔记之SystemServiceRegistry

  • B: 创建一个SystemSensorManger实例;其构造函数会调用本地方法: nativeClassInit();

  • C: 构造函数会调用本地方法: nativeCreate(context.getOpPackageName());

  • D: 调用:nativeGetSensorAtIndex 循环添加sensor;

  1. App中,MainActivity中获取SensorManager;
  2. 通过SensorManager 获取类型为Acc的sensor对象;
  3. 通过SensorManager.registerListener注册SensorEventListener监听器,监听传感器
  4. registerListener调用到registerListenerImpl会创建SensorEventQueue,继承自BaseEventQueue ;
  5. 通过JNI调用本地方法nativeInitBaseEventQueue;
  6. C++中绑定的nativeInitSensorEventQueue函数被调用;创建event队列createEventQueue
  7. 添加Receiver;
  8. addSensor将sensor添加到queue,addSensorEvent(sensor);;
  9. addSensor使能sensor,通过JNI调用到本地方法:nativeEnableSensor;
  10. 调用enable
posted @ 2021-07-18 18:00  yujixuan  阅读(495)  评论(0编辑  收藏  举报