Android SensorManager,SystemSensorManager,SensorService调用过程分析

本文主要分析android 在应用层register一个sensor后从应用层调用到framework SensorService的过程。

版本:android 8.0.0,abdroid 8.1.0

大致调用顺序为:appliction ===>SensorManager===>SystemSeneorManager===>Sensorservice

1,对于应用层,举个使用的小例子:

    private SensorManager mSensorManager;
    private Sensor mSensor;
               
    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    mSensorManager.registerListener(mSensorEventListener,mSensor,SensorManager.SENSOR_DELAY_NORMAL);

    final SensorEventListener mSensorEventListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent sensorEvent) {

            Log.i(TAG,"sensorEvent.sensor.getType():" + sensorEvent.sensor.getType());
            if(sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
                //add you code
            }

        }
        @Override
        public void onAccuracyChanged(Sensor sensor, int i) {
            //add your code

        }
    };
主要就是调用SensorManager的regisListener()方法,接下来就到了framework的SensorManager了

2,SensorManager

源码位置:android/frameworks/base/core/java/android/hardware/SensorManager.java

先看registerListener函数:


1.	public boolean registerListener(SensorEventListener listener, Sensor sensor,  
2.	        int samplingPeriodUs) {  
3.	    return registerListener(listener, sensor, samplingPeriodUs, null);  

对于其参数说明:

SensorEventListener:前面应用层需实现其onSensorChanged()接口,数据传上来时该接口被调用(callback);

Sensor:sensor对象,需说明其类型;

samplingPeriodUs:period,顾名思义为周期,接收数据的周期,

可以取以下几个值:

SENSOR_DELAY_NORMAL: rate (default)suitable for screen orientation changes//延迟200000ms

SENSOR_DELAY_UI: rate suitable for the userinterface(适合用户界面的速率)//延迟66667ms

SENSOR_DELAY_GAME: rate suitable for games(不知道是啥意思)//延迟20000ms

SENSOR_DELAY_FASTEST: get sensor data asfast as possible//没有延迟,

或自己期望的值,不过也得不高于采样率喔。

接着看,,,,,

1.	public boolean registerListener(SensorEventListener listener, Sensor sensor,  
2.	           int samplingPeriodUs, int maxReportLatencyUs) {  
3.	       int delay = getDelay(samplingPeriodUs);  
4.	       return registerListenerImpl(listener, sensor, delay, null, maxReportLatencyUs, 0);  
5.	}  

打个小插曲,先看一下getDelay()接口:

1.	private static int getDelay(int rate) {  
2.	    int delay = -1;  
3.	    switch (rate) {  
4.	        case SENSOR_DELAY_FASTEST:  
5.	            delay = 0;  
6.	            break;  
7.	        case SENSOR_DELAY_GAME:  
8.	            delay = 20000;  
9.	            break;  
10.	        case SENSOR_DELAY_UI:  
11.	            delay = 66667;  
12.	            break;  
13.	        case SENSOR_DELAY_NORMAL:  
14.	            delay = 200000;  
15.	            break;  
16.	        default:  
17.	            delay = rate;  
18.	            break;  
19.	    }  
20.	    return delay;  
21.	}  

就是对参数做了个转换,好了回到主分支继续,,,

1.	/** @hide */  
2.	protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,  
3.	        int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags);  

SystemSensorManager继承了SensorManager

registerListenerImpl()SystemSensorManager类里边实现,这样就到了SystemSensorManager

3,SystemSensorManager

registerListenerImpl()方法实现如下:

 
1.	/** @hide */  
2.	@Override  
3.	protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,  
4.	        int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {    
5.	    // Invariants to preserve:  
6.	    // - one Looper per SensorEventListener  
7.	    // - one Looper per SensorEventQueue  
8.	    // We map SensorEventListener to a SensorEventQueue, which holds the looper  
9.	    synchronized (mSensorListeners) {  
10.	        SensorEventQueue queue = mSensorListeners.get(listener);  
11.	        //由于mySensorListener首次注册,所以queue==null
12.	       //因此需要new一个SensorEventQueue
13.	     	 
14.	        if (queue == null) {  
15.	             //前面SensorManager里边handler == null
16.	             //所以looper = mMainLooper
17.	            Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;  
18.	            final String fullClassName = listener.getClass().getEnclosingClass() != null ?  
19.	                listener.getClass().getEnclosingClass().getName() :  
20.	                listener.getClass().getName();  
21.	            queue = new SensorEventQueue(listener, looper, this, fullClassName);  
22.	            if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {  
23.	                queue.dispose();  
24.	                return false;  
25.	            }  
26.	 			//将2者加入hashMap
27.	            mSensorListeners.put(listener, queue);  
28.	            return true;  
29.	        } else {  
30.	            return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);  
31.	        }  
32.	    }  
33.	}  

对于mSensorListeners.put(listener, queue);mSensorListeners类型为

1.	private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners =  new HashMap<SensorEventListener, SensorEventQueue>();  


主要为创建一个SensorEventQueue后将sensor添加进去,

该变量sensor为前面应用层注册的时候传进来的通过mSensorManager.getDefaultSensor(Sensor.TYPE_...)获取到的


看看SensorEventQueue是个什么东西,主要看构造方法和addSensor方法,

static final classSensorEventQueue extends BaseEventQueue

BaseEventQueue的构造函数

1.	     BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {  
2.	         if (packageName == null) packageName = "";  
3.	    //通过jni调用c++  
4.	         nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,  
5.	                 new WeakReference<>(this), looper.getQueue(),  
6.	                 packageName, mode, manager.mContext.getOpPackageName());  
7.	         mCloseGuard.open("dispose");  
8.	         mManager = manager;  
9.	     }  



nativeInitBaseEventQueue()函数在

android/frameworks/base/core/jni/android_hardware_SensorManager.cpp里边,

1.	static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,  
2.	        jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {  
3.	    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);  
4.	    ScopedUtfChars packageUtf(env, packageName);  
5.	    String8 clientName(packageUtf.c_str());  
6.	    sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));  
7.	  
8.	    if (queue == NULL) {  
9.	        jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue.");  
10.	        return 0;  
11.	    }  
12.	  
13.	    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);  
14.	    if (messageQueue == NULL) {  
15.	        jniThrowRuntimeException(env, "MessageQueue is not initialized.");  
16.	        return 0;  
17.	    }  
18.	  
19.	    sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);  
20.	    receiver->incStrong((void*)nativeInitSensorEventQueue);  
21.	    return jlong(receiver.get());  
22.	}  

在这里边new 了一个receiver对象,

返回该receiver对象,保存在类BaseEventQueue里边的nSensorEventQueue 属性里边,

这边的addSensor()还是调用父类BaseEventQuene的方法:

1.	public boolean addSensor(  
2.	        Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {  
3.	    // Check if already present.  
4.	    int handle = sensor.getHandle();  
5.	    if (mActiveSensors.get(handle)) return false;  
6.	  
7.	    // Get ready to receive events before calling enable.  
8.	    mActiveSensors.put(handle, true);  
9.	    addSensorEvent(sensor);  
10.	  
11.	    if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {  
12.	        // Try continuous mode if batching fails.  
13.	        if (maxBatchReportLatencyUs == 0 ||  
14.	            maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {  
15.	          removeSensor(sensor, false);  
16.	          return false;  
17.	        }  
18.	    }  
19.	    return true;  
20.	} 

addSensorEvent()方法,调用的为类SensorEventQueue自己的addSensorEvent()方法,


1.	public void addSensorEvent(Sensor sensor) {  
2.	    SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,  
3.	            mManager.mTargetSdkLevel));  
4.	    synchronized (mSensorsEvents) {  
5.	        mSensorsEvents.put(sensor.getHandle(), t);  
6.	    }  
7.	}  

new了一个SensorEvent对象后,将其与sensor里边的handle一起添加进mSensorsEvents

mSensorsEvents

1.	private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();  

再看enableSensor()方法,

1.	private int enableSensor(  
2.	        Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {  
3.	    if (nSensorEventQueue == 0) throw new NullPointerException();  
4.	    if (sensor == null) throw new NullPointerException();  
5.	//通过jni调用c++
6.	    return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs,  
7.	            maxBatchReportLatencyUs);  
8.	}  

接着看nativeEnableSensor()方法,同样在

android/frameworks/base/core/jni/android_hardware_SensorManager.cpp里边

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

这边有一个回调,即

nSensorEventQueue->getSensorEventQueue()->enableSensor,回过头去看nSensorEventQueue

在类BaseEventQueue构造函数里边被初始化,nSensorEventQueue 保存了一个在jni里边

New receiver对象。所以,

receiver->getSensorEventQueue()->enableSensor()

<==>

nSensorEventQueue->getSensorEventQueue()->enableSensor(),

nSensorEventQueue保存的又是一个在jni里边New receiver对象,

所以确实是receiver->getSensorEventQueue()->enableSensor()

其实就是一个指针类型强制转过来又转回去。

看看jni函数nativeInitSensorEventQueue()是如何搞的,

1.	static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,  
2.	        jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {  
3.	    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);  
4.	    ScopedUtfChars packageUtf(env, packageName);  
5.	    String8 clientName(packageUtf.c_str());  
6.	    sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));  
7.	  
8.	    if (queue == NULL) {  
9.	        jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue.");  
10.	        return 0;  
11.	    }  
12.	  
13.	    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);  
14.	    if (messageQueue == NULL) {  
15.	        jniThrowRuntimeException(env, "MessageQueue is not initialized.");  
16.	        return 0;  
17.	    }  
18.	    // eventQWeak为其调用对象BaseEventQueue的this指针                                            
19.	    sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);  
20.	    receiver->incStrong((void*)nativeInitSensorEventQueue);  
21.	    return jlong(receiver.get());  
22.	}  

将类BaseEventQueue构造函数传进来的。。。这边还通过回调createEventQueue()

android_os_MessageQueue_getMessageQueue()初始化了2个指针queuemessageQueue 

先看看到底receiver->getSensorEventQueue()->enableSensor()

getSensorEventQueue()到底返回的是个什么东西,再去看那个东西的enableSensor()方法,

看名字估计是返回个SensorEventQueue类型的指针吧,也就是上面初始化

sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode))queue指针,并且后来不是传进去给Receiver的构造函数了嘛。

接下来验证一下,Revceiver类:

1.	sp<SensorEventQueue> getSensorEventQueue() const {  
2.	    return mSensorQueue;  
3.	}  

mSensorQueue在构造函数里边初始化为:

1.	Receiver(const sp<SensorEventQueue>& sensorQueue,  
2.	        const sp<MessageQueue>& messageQueue,  
3.	        jobject receiverWeak) {  
4.	    JNIEnv* env = AndroidRuntime::getJNIEnv();  
5.	    mSensorQueue = sensorQueue;  
6.	    mMessageQueue = messageQueue;  
7.	    mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak);  
8.	  
9.	    mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16));  
10.	    mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16));  
11.	}  

也确实就是前边传进来的queue没错,

接下来就去搞懂queue->enableSensor()到底怎么搞的,

在类SensorEventQueue中,看其enableSensor()方法,

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

即调用了mSensorEventConnectionenableDisable()方法,去看看mSensorEventConnection是个什么东西,定义为,


1.	sp<ISensorEventConnection> mSensorEventConnection;  

使用,看看在哪儿被初始化的,在构造函数里边被初始化,

1.	SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)  
2.	    : mSensorEventConnection(connection), mRecBuffer(NULL), mAvailable(0), mConsumed(0),  
3.	      mNumAcksToSend(0) {  
4.	    mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];  
5.	}  

那么connection就是在前面nativeInitSensorEventQueue()函数里边初始化queue传进去的mgr->createEventQueue(clientName, mode)了,

也就是说,mgr->createEventQueue(clientName, mode)返回一个ISensorEventConnection类型指针,然后在nativeEnableSensor()函数里边会通过

receiver->getSensorEventQueue()->enableSensor()最终去调用它的enableDisable()方法,

接下来需要看2个东西,一个是mgrjava里边的SensorManager.Instance,

Instance其实是通过jni调用c++里边的SensorManager创建一个SensorManager对象后返回,如下,


1.	static jlong  
2.	nativeCreate  
3.	(JNIEnv *env, jclass clazz, jstring opPackageName)  
4.	{  
5.	    ScopedUtfChars opPackageNameUtf(env, opPackageName);  
6.	    return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));  
7.	}  

/android/frameworks/native/libs/sensor/SensorManager.cpp里边,如下,截取部分代码


1.	SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) {  
2.	    
3.	    SensorManager* sensorManager;  
4.	    a
5.	        sensorManager = new SensorManager(opPackageName);  
6.	  
7.	  
8.	    return *sensorManager;  
9.	}  

所以mgr->createEventQueue(clientName, mode)就是调用c++里边的SensorManager里边的createEventQueue()方法,看看该方法做了什么,其实顾名思义就是创建了一个EventQueue对象并返回嘛,代码如下:

位置为:android/frameworks/native/libs/sensor/SensorManager.cpp

1.	sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {  
2.	    sp<SensorEventQueue> queue;  
3.	  
4.	    Mutex::Autolock _l(mLock);  
5.	    while (assertStateLocked() == NO_ERROR) {  
6.	        sp<ISensorEventConnection> connection =  
7.	                mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);  
8.	        if (connection == NULL) {  
9.	            // SensorService just died or the app doesn't have required permissions.  
10.	            ALOGE("createEventQueue: connection is NULL.");  
11.	            return NULL;  
12.	        }  
13.	        queue = new SensorEventQueue(connection);  
14.	        break;  
15.	    }  
16.	    return queue;  
17.	}  

到了这边就有点清楚了,

一个·SensorEventQueue对象(queue),通过一个ISensorEventConnection对其进行初始化,然后将其(queue)返回给调用者,所以前边queue->enableSensor()

tatus_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,  
2.	                                        int64_t maxBatchReportLatencyUs, int reservedFlags) const {  
3.	    return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),  
4.	                                                 us2ns(maxBatchReportLatencyUs), reservedFlags);  
5.	}  

里边的

mSensorEventConnection->enableDisable()即为在

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

里边创建的一个ISensorEventConnection 指针指向的ISensorEventConnection子类对象的enableDisable()方法。

接下来先看该ISensorEventConnectionenableDisable方法,


1.	virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,  
2.	                               nsecs_t maxBatchReportLatencyNs, int reservedFlags) = 0;  



为纯虚函数,所以实现在其子类,所以需要搞清楚

1, 还有mSensorServer是个什么东西,

Ans:SensorService

2, mSensorServer->createSensorEventConnection()返回的是个什么对象,

 Ans:返回一个SensorEventConnection的对象

mSensorServer为
sp<ISensorServer> mSensorServer;

所以看类ISensorServer的createSensorEventConnection()方法,

在android/ frameworks\native\libs\sensor/ ISensorServer.cpp里边


1.	virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,  
2.	         int mode, const String16& opPackageName)  
3.	{  
4.	    Parcel data, reply;  
5.	    data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());  
6.	    data.writeString8(packageName);  
7.	    data.writeInt32(mode);  
8.	    data.writeString16(opPackageName);  
9.	    remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);  
10.	    return interface_cast<ISensorEventConnection>(reply.readStrongBinder());  
11.	}  

继续看:

1.	tatus_t BnSensorServer::onTransact(  
2.	    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
3.	{  
4.	    switch(code) {  
5.	     //省略其他无关代码
6.	        case CREATE_SENSOR_EVENT_CONNECTION: {  
7.	            CHECK_INTERFACE(ISensorServer, data, reply);  
8.	            String8 packageName = data.readString8();  
9.	            int32_t mode = data.readInt32();  
10.	            const String16& opPackageName = data.readString16();  
11.	            sp<ISensorEventConnection> connection(createSensorEventConnection(packageName, mode,  
12.	                    opPackageName));  
13.	            reply->writeStrongBinder(IInterface::asBinder(connection));  
14.	            return NO_ERROR;  
15.	        }  
16.	     //省略其他无关代码
17.	    }  
18.	    return BBinder::onTransact(code, data, reply, flags);  
19.	}  

此时就调用到SensorService里边了,

4,SensorService

位置为:android/frameworks/native/services/sensorservice/SensorService.cpp
摘取部分代码:
1.	p<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,  
2.	        int requestedMode, const String16& opPackageName) {  
3.	  
4.	 
5.	 
6.	    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,  
7.	            requestedMode == DATA_INJECTION, opPackageName));  
8.	    if (requestedMode == DATA_INJECTION) {  
9.	        if (mActiveConnections.indexOf(result) < 0) {  
10.	            mActiveConnections.add(result);  
11.	        }  
12.	        // Add the associated file descriptor to the Looper for polling whenever there is data to  
13.	        // be injected.  
14.	        result->updateLooperRegistration(mLooper);  
15.	    }  
16.	    return result;  
17.	} 

即new 一个SensorEventConnection对象存放在result指针里边并返回。

所以到这儿就有点清楚了,前边的 mSensorEventConnection->enableDisable()

其实就是调用类SensorEventConnectionenableDisable()方法,

位置为:android/ frameworks\native\services\sensorservice/ SensorEventConnection.cpp

如下:


1.	status_t SensorService::SensorEventConnection::enableDisable(  
2.	        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,  
3.	        int reservedFlags)  
4.	{  
5.	    status_t err;  
6.	    if (enabled) {  
7.	        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,  
8.	                               reservedFlags, mOpPackageName);  
9.	  
10.	    } else {  
11.	        err = mService->disable(this, handle);  
12.	    }  
13.	    return err;  
14.	}  

看一下mService是个啥东西,

sp<SensorService> const mService;

SensorEventConnection构造函数:

1.	SensorService::SensorEventConnection::SensorEventConnection(  
2.	        const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,  
3.	        const String16& opPackageName)  
4.	    : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),  
5.	      mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),  
6.	      mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName) {  
7.	    mChannel = new BitTube(mService->mSocketBufferSize);  
8.	#if DEBUG_CONNECTIONS  
9.	    mEventsReceived = mEventsSentFromCache = mEventsSent = 0;  
10.	    mTotalAcksNeeded = mTotalAcksReceived = 0;  
11.	#endif  
12.	}  

即创建SensorEventConnection时传进来的一个SensorService对象地址,、

所以也就是调用SensorService::enable(),

接下来看SensorService的enable()方法,如下截取片段:

status_t SensorService::enable(const sp<SensorEventConnection>& connection,
        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
        const String16& opPackageName) {
    /......
//获取各个类型的hal层的sensor实例,这边是在SensorService:onFirsRef()注册的
    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);

    if (err == NO_ERROR) {
        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
		//here active这边是调hal
        err = sensor->activate(connection.get(), true);
	   // 调用SensorDevice::activate

    }
//......
    return err;
}

这边获取到前面在SensorService::onFirsRef()注册的实例后,调用SensorDevice::activate(),

在这里边就会调用hal层的activate(),

sp<android::hardware::sensors::V1_0::ISensors> mSensors;

mSensors->activate(handle, enabled);

mSensors是在SensorDevice的构造函数里边通过hidl获取到hal层的一个android::hardware::sensors::V1_0::ISensors 类型的对象,该对象定义在hal层里边,之后就可以使用该对象通过hidl协议去调用hal层的服务了


接下去hal层怎么走,日后分析。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值