android sensor: registerListener

sensor Java層

private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners =
            new HashMap<SensorEventListener, SensorEventQueue>();
@Override
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
        // We map SensorEventListener to a SensorEventQueue, which holds the looper
        synchronized (mSensorListeners) {
            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: 使用user註冊的listener, looper,和listener的fullClassName
                queue = new SensorEventQueue(listener, looper, this, fullClassName);

                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
                    queue.dispose();
                    return false;
                }
                mSensorListeners.put(listener, queue);
                return true;
            } else {
                return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
            }
        }
}

下面詳細分析:SensorEventQueue

1. new SensorEventQueue(listener, looper, this, fullClassName);


public SensorEventQueue(SensorEventListener listener, Looper looper,
                SystemSensorManager manager, String packageName) {
            super(looper, manager, OPERATING_MODE_NORMAL, packageName);
            mListener = listener;
}


//看下基類的構建
BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
            if (packageName == null) packageName = "";
        // native層對應的SensorEventQueue
            mNativeSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
                    new WeakReference<>(this), looper.getQueue(),
                    packageName, mode, manager.mContext.getOpPackageName());

            mCloseGuard.open("dispose");
            mManager = manager;
}

static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
        jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
    //native層的SensorManager
    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
    ScopedUtfChars packageUtf(env, packageName);
    String8 clientName(packageUtf.c_str());
    // SensorManger->createEventQueue: SensorEventQueue?
    sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));

    //從java層message queue得到native層message queue
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);

    //native層receiver, 並返回到java層
    sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);
    receiver->incStrong((void*)nativeInitSensorEventQueue);
    return jlong(receiver.get());
}

1.1 sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));

sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
    sp<SensorEventQueue> queue;

    Mutex::Autolock _l(mLock);
    while (assertStateLocked() == NO_ERROR) {
    //創建ISensorEventConnection
        sp<ISensorEventConnection> connection =
                mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
    //由Connection創建SensorEventQueue
        queue = new SensorEventQueue(connection);
        break;
    }
    return queue;
}

1.1.1 createSensorEventConnection: client


    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());
    }

1.1.2 createSensorEventConnection: service


sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
        int requestedMode, const String16& opPackageName) {

    uid_t uid = IPCThreadState::self()->getCallingUid();
    pid_t pid = IPCThreadState::self()->getCallingPid();

    String8 connPackageName =
            (packageName == "") ? String8::format("unknown_package_pid_%d", pid) : packageName;

    String16 connOpPackageName =
            (opPackageName == String16("")) ? String16(connPackageName) : opPackageName;

    bool hasSensorAccess = mUidPolicy->isUidActive(uid);

    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName,
            requestedMode == DATA_INJECTION, connOpPackageName, hasSensorAccess));

    return result;
}

1.1.2.1 SensorEventConnection: 創BitTube


SensorService::SensorEventConnection::SensorEventConnection(
        const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
        const String16& opPackageName, bool hasSensorAccess)
    : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
      mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(nullptr),
      mCacheSize(0), mMaxCacheSize(0), mTimeOfLastEventDrop(0), mEventsDropped(0),
      mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false),
      mHasSensorAccess(hasSensorAccess) {
    //創建 通信channel: BitTube
    mChannel = new BitTube(mService->mSocketBufferSize);

    if  ( mService->isonwhitelist(packageName) )
    {
        ALOGI("SensorEventConnection, from packagename %s",packageName.c_str());
        mHasSensorAccess = true;
    }
}

1.1.2 由service創建的connection 創建client層的SensorEventQueue


//創建接收SensorEvent的buffer
SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
    : mSensorEventConnection(connection), mRecBuffer(nullptr), mAvailable(0), mConsumed(0),
      mNumAcksToSend(0) {
    mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
}
typedef struct ASensorEvent {
    int32_t version; /* sizeof(struct ASensorEvent) */
    int32_t sensor;
    int32_t type;
    int32_t reserved0;
    int64_t timestamp;
    union {
        union {
            float           data[16];
            ASensorVector   vector;
            ASensorVector   acceleration;
            ASensorVector   magnetic;
            float           temperature;
            float           distance;
            float           light;
            float           pressure;
            float           relative_humidity;
            AUncalibratedEvent uncalibrated_gyro;
            AUncalibratedEvent uncalibrated_magnetic;
            AMetaDataEvent meta_data;
            AHeartRateEvent heart_rate;
            ADynamicSensorEvent dynamic_sensor_meta;
            AAdditionalInfoEvent additional_info;
        };
        union {
            uint64_t        data[8];
            uint64_t        step_counter;
        } u64;
    };

    uint32_t flags;
    int32_t reserved1[3];
} ASensorEvent;

1.2 Receiver: jni層還創建了receiver


class Receiver : public LooperCallback {
    sp<SensorEventQueue> mSensorQueue;
    sp<MessageQueue> mMessageQueue;
    jobject mReceiverWeakGlobal;
    jfloatArray mFloatScratch;
    jintArray   mIntScratch;
public:
    Receiver(const sp<SensorEventQueue>& sensorQueue,
            const sp<MessageQueue>& messageQueue,
            jobject receiverWeak) {
        JNIEnv* env = AndroidRuntime::getJNIEnv();
        mSensorQueue = sensorQueue;
        mMessageQueue = messageQueue;
        mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak);

        mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16));
        mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16));
    }
private:
    virtual void onFirstRef() {
        LooperCallback::onFirstRef();
        mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
                ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
    }

    virtual int handleEvent(int fd, int events, void* data) {
        JNIEnv* env = AndroidRuntime::getJNIEnv();
        sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
        ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));

        ssize_t n;
        ASensorEvent buffer[16];
        while ((n = q->read(buffer, 16)) > 0) {
        //對收到數據的處理
        }
}

2 java 層addSensor(sensor, delayUs, maxBatchReportLatencyUs)


//這裏queue是java層queue
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();
            return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
                    maxBatchReportLatencyUs);
}

2.1 jni層nativeEnableSensor

private static native int nativeEnableSensor(long eventQ, int handle, int rateUs,
                int maxBatchReportLatencyUs);

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

status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
                                        int64_t maxBatchReportLatencyUs, int reservedFlags) const {
    return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
                                                 us2ns(maxBatchReportLatencyUs), reservedFlags);
}

2.2 enableDisable:client

virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,
                           nsecs_t maxBatchReportLatencyNs, int reservedFlags)
{
        Parcel data, reply;
        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
        data.writeInt32(handle);
        data.writeInt32(enabled);
        data.writeInt64(samplingPeriodNs);
        data.writeInt64(maxBatchReportLatencyNs);
        data.writeInt32(reservedFlags);
        remote()->transact(ENABLE_DISABLE, data, &reply);
        return reply.readInt32();
}

2.3 enableDisable: service

status_t BnSensorEventConnection::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case ENABLE_DISABLE: {
            CHECK_INTERFACE(ISensorEventConnection, data, reply);
            int handle = data.readInt32();
            int enabled = data.readInt32();
            nsecs_t samplingPeriodNs = data.readInt64();
            nsecs_t maxBatchReportLatencyNs = data.readInt64();
            int reservedFlags = data.readInt32();
            status_t result = enableDisable(handle, enabled, samplingPeriodNs,
                                            maxBatchReportLatencyNs, reservedFlags);
            reply->writeInt32(result);
            return NO_ERROR;
        }
}

2.4 connection service 調入sensor service

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

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

2.5 調入hidl client

status_t SensorService::enable(const sp<SensorEventConnection>& connection,
        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
        const String16& opPackageName) {
    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
    if (connection->addSensor(handle)) {}
    //調到hidl
    sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
                                 maxBatchReportLatencyNs);
}

hardware/interfaces/sensors/1.0/default/Sensors.cpp
Return<Result> Sensors::batch(
        int32_t sensor_handle,
        int64_t sampling_period_ns,
        int64_t max_report_latency_ns) {
    return ResultFromStatus(
            mSensorDevice->batch(
                mSensorDevice,
                sensor_handle,
                0, /*flags*/
                sampling_period_ns,
                max_report_latency_ns));
}

2.6 調入hidl service: SEE的具體實現batch

int sensors_hal::batch(int handle, int flags, int64_t sampling_period_ns,
                       int64_t max_report_latency_ns)
{
    auto it = _sensors.find(handle);

    auto& sensor = it->second;
    sensor_params params;
    params.max_latency_ns = max_report_latency_ns;
    params.sample_period_ns = sampling_period_ns;

    try {
        sensor->set_config(params);
    }
    return 0;
}

void sensor::set_config(sensor_params params)
{
    /* if new params are same as existing params, no update required. */
    if (!(params == _params)) {
        _params = params;
        /* if sensor is active, update configuration */
        if (is_active()) {
            update_config();
        }
    }
}


void ssc_sensor::update_config()
{
    lock_guard<mutex> lk(_mutex);
    send_sensor_config_request();
}

//和SEE的通信最終是_ssc_conn->send_request

void ssc_sensor::send_sensor_config_request()
{
    string pb_req_msg_encoded;
    //---
    sns_client_request_msg pb_req_msg;
    if(is_active())
      _ssc_conn->send_request(pb_req_msg_encoded);

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章