iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 20
0
Mobile Development

Android Pie 底層開發學習心得系列 第 28

[Day-28] Android Pie Sensor (5) 服務 (2)

  • Guide:
    • 介紹 (Overview)
    • 架構 (Architecture)
    • 應用 (Application)
    • 服務 (Service)
    • 硬件抽象層 (HAL)

啟動服務

上一篇提到大致上 SystemServer 是透過 ZygoteInit.java 反射啟動的,
首先會進入 main() 方法,
main() 會建構一個新的 SystemServer
然後運行 run() 方法:

frameworks/base/services/java/com/android/server/SystemServer.java

 295     public static void main(String[] args) {
 296         new SystemServer().run();      
 297     }

frameworks/base/services/java/com/android/server/SystemServer.java

 309     private void run() {
 310         try {
 311             traceBeginAndSlog("InitBeforeStartServices");
... ...
 432         // Start services. 
 433         try {              
 434             traceBeginAndSlog("StartServices");
 435             **startBootstrapServices**();
 436             startCoreServices();
 437             startOtherServices();
 438             SystemServerInitThreadPool.shutdown();
 439         } catch (Throwable ex) {
 440             Slog.e("System", "******************************************");
 441             Slog.e("System", "************ Failure starting system services", ex);
 442             throw ex;      
 443         } finally {        
 444             traceEnd();    
 445         }

這裡是從 8.0 版本就開始改成下面的寫法,
好處是原本 7.1 版本的寫法是新增一個子程序來執行,
因為沒有 trace 回傳子程序結果的判斷,
所以你的母程序不會知道子程序執行結果如何。
若是子程序出現錯誤時,便會出現類似這樣的 log:
chatty : uid=1000(system) SensorService expire 1 line
我們可以看到這裡將 startSensorService() 包在 TimingTraceLog 裡面:

frameworks/base/services/java/com/android/server/SystemServer.java

 543     private void startBootstrapServices() {
 544         Slog.i(TAG, "Reading configuration...");
... ...
 692         // The sensor service needs access to package manager service, app ops
 693         // service, and permissions service, therefore we start it after them.
 694         // Start sensor service in a separate thread. Completion should be checked
 695         // before using it. 
 696         **mSensorServiceStart** = SystemServerInitThreadPool.get().submit(() -> {
 697             TimingsTraceLog traceLog = new TimingsTraceLog(
 698                     SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
 699             traceLog.traceBegin(START_SENSOR_SERVICE);
 700             **startSensorService();**
 701             traceLog.traceEnd();
 702         }, START_SENSOR_SERVICE);
 703     }

其實它真正實作的地方在 JNI 的位置:

frameworks/base/services/core/jni/com_android_server_SystemServer.cpp

 31 namespace android {
 32                
 33 static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
 34     char propBuf[PROPERTY_VALUE_MAX];
 35     property_get("system_init.startsensorservice", propBuf, "1");
 36     if (strcmp(propBuf, "1") == 0) {
 37         SensorService::instantiate();
 38     }          
 39                
 40 }

可以順便看到 HIDL 的相關啟動也包含在內:

frameworks/base/services/core/jni/com_android_server_SystemServer.cpp

 42 static void android_server_SystemServer_startHidlServices(JNIEnv* env, jobject /* clazz */) {
 43     using ::android::frameworks::schedulerservice::V1_0::ISchedulingPolicyService;
 44     using ::android::frameworks::schedulerservice::V1_0::implementation::SchedulingPolicyService;
 45     using ::android::frameworks::sensorservice::V1_0::ISensorManager;
 46     using ::android::frameworks::sensorservice::V1_0::implementation::SensorManager;
 47     using ::android::hardware::configureRpcThreadpool;
 48                        
 49     status_t err;      
 50                        
 51     configureRpcThreadpool(5, false /* callerWillJoin */);
 52                        
 53     JavaVM *vm;        
 54     LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Cannot get Java VM"); 
 55                        
 56     sp<ISensorManager> sensorService = new SensorManager(vm);
 57     err = sensorService->registerAsService();
 58     ALOGE_IF(err != OK, "Cannot register %s: %d", ISensorManager::descriptor, err);
 59                        
 60     sp<ISchedulingPolicyService> schedulingService = new SchedulingPolicyService();
 61     err = schedulingService->registerAsService();
 62     ALOGE_IF(err != OK, "Cannot register %s: %d", ISchedulingPolicyService::descriptor, err);
 63 }

我們可以看到在 android_server_SystemServer_startSensorService 中,
創建線程 start_sensor_service 來實例化 SensorService
然後將 SensorService 添加到 ServiceManager 當中。
(SensorManagerServiceManager 裡獲取 SensorService)
SensorService 被創建時,onFirstRef 被調用。
(為什麼會跳到 onFirstRef 這部份,我建議自行搜尋「智慧指標」參考)
這個初始化函數完成了一些重要的初始化過程,我們來看一下:

frameworks/native/services/sensorservice/SensorService.cpp

 138 void SensorService::onFirstRef() {
 139     ALOGD("nuSensorService starting...");
 140     **SensorDevice& dev(SensorDevice::getInstance());**
 141
... ...

這裡很有趣的是,
SensorDevice 是一個單例類 (Singleton Pattern),
這是一個高階語言和前後端開發的常見寫法,
它主要做了以下幾件事:

  • connectHidlService
    連接 HAL 層的 HIDL service,
    調用 getServicve 看看是否 sensor 的 HIDL service 運行中

frameworks/native/services/sensorservice/SensorDevice.cpp

 54 SensorDevice::SensorDevice()
 55         : mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {
 56     if (!**connectHidlService**()) {   
 57         return; 
 58     }                
... ...
 87 }

這裡也和 7.1 版本的不太一樣了,直接呼叫 HIDL :

frameworks/native/services/sensorservice/SensorDevice.cpp

 89 bool SensorDevice::connectHidlService() {
 90     // SensorDevice will wait for HAL service to start if HAL is declared in device manifest.                                                                                        
 91     size_t retry = 10;
 92                    
 93     while (retry-- > 0) {
 94         mSensors = ISensors::getService();
 95         if (mSensors == nullptr) {       
 96             // no sensor hidl service found  
 97             break; 
 98         }          
 99                    
100         mRestartWaiter->reset();
101         // Poke ISensor service. If it has lingering connection from previous generation of
102         // system server, it will kill itself. There is no intention to handle the poll result,
103         // which will be done since the size is 0.
104         if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
105             // ok to continue
106             break; 
107         }          
108                    
109         // hidl service is restarting, pointer is invalid.
110         mSensors = nullptr;
111         ALOGI("%s unsuccessful, remaining retry %zu.", __FUNCTION__, retry);
112         mRestartWaiter->wait();
113     }              
114     return (mSensors != nullptr);    
115 }
  • SensorDevice::SensorDevice()
    調用動態庫getSensorsList獲取所有 sensor 的列表
    將它們填充到 mActivationCount 中,
    並對通過 activate 接口,對每個 HAL 層的 sensor 執行一次關閉的動作

frameworks/native/services/sensorservice/SensorDevice.cpp

 54 SensorDevice::SensorDevice()
 55         : mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {
 56     if (!connectHidlService()) {
 57         return; 
 58     }           
 59                 
 60     float minPowerMa = 0.001; // 1 microAmp
 61                 
 62     checkReturn(mSensors->**getSensorsList**(
 63             [&](const auto &list) {
 64                 const size_t count = list.size();
 65                 
 66                 **mActivationCount.setCapacity**(count);
 67                 Info model;
 68                 for (size_t i=0 ; i < count; i++) {
 69                     sensor_t sensor;
 70                     convertToSensor(list[i], &sensor);
 71                     // Sanity check and clamp power if it is 0 (or close)
 72                     if (sensor.power < minPowerMa) {
 73                         ALOGE("Reported power %f not deemed sane, clamping to %f", 
 74                               sensor.power, minPowerMa);
 75                         sensor.power = minPowerMa;
 76                     }
 77                     mSensorList.push_back(sensor);
 78                   
 79                     **mActivationCount.add(list[i].sensorHandle, model)**;
 80                 
 81                     **checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */));**
 82                 } 
 83             }));  
 84                   
 85     mIsDirectReportSupported =      
 86            (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
 87 }

frameworks/native/services/sensorservice/SensorService.cpp

 138 void SensorService::onFirstRef() {
 139     ALOGD("nuSensorService starting...");
... ...
 157             for (ssize_t i=0 ; i<count ; i++) {
 158                 bool useThisSensor=true;
... ...
 186                 if (useThisSensor) {
**//此接口會將傳感器父類SensorInterface接口與handle以std::map的方式保存在mHandleMap中**
 187                     **registerSensor**( new HardwareSensor(list[i]) );
 188                 }
 189             }           
 190                         
 191             // it's safe to instantiate the SensorFusion object here
 192             // (it wants to be instantiated after h/w sensors have been
 193             // registered)
**//這就是之前提到的融合演算法初始化**
 194             SensorFusion::getInstance();
... ...
 265             mWakeLockAcquired = false;
**//創立一個Looper**
 266             mLooper = new Looper(false);
... ...
**//當SensorService處於wake_lock狀態,此線程會等待loop應答,
//超時時間5秒,超時後清0所有SensorEventConnection鎖的引用計數**
 279             mAckReceiver = new SensorEventAckReceiver(this);
 280             mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
**//執行threadLoop()方法,輪詢接收HAL層上報的數據**
 281             run("SensorService", PRIORITY_URGENT_DISPLAY);

這裡可以看到 SensorService::onFirstRef 接口,
通過 SensorDevice 獲取傳感器列表信息後,
調用 registerSensor 分別將傳感器添加到 mSensors 中:

frameworks/native/services/sensorservice/SensorService.cpp

 305 const Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual) {
 306     int handle = s->getSensor().getHandle(); 
 307     int type = s->getSensor().getType();
 308     if (mSensors.add(handle, s, isDebug, isVirtual)){
 309         mRecentEvent.emplace(handle, new RecentEventLogger(type));
 310         return s->getSensor();
 311     } else {
 312         return mSensors.getNonSensor();
 313     }
 314 }

上面看到 Looper 被創建接著調用 run 方法,
這是用來監聽傳感器數據的上報和分發,
啟動 threadLoop 輪詢 HAL 層傳感器數據的上報。
來看一下 SensorServicethreadLoop

frameworks/native/services/sensorservice/SensorService.cpp

 614 bool SensorService::threadLoop() {  
 615     ALOGD("nuSensorService thread starting...");
... ...              
 624     SensorDevice& device(SensorDevice::getInstance());
 625                                       
 626     const int halVersion = device.getHalDeviceVersion();
 627     do { 
**//調用HAL層poll方法,來獲取所有傳感器數據**
 628         ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
 629         if (count < 0) {              
 630             ALOGE("sensor poll failed (%s)", strerror(-count));
 631             break;                    
 632         }                             
 ... ...

結語

其實後面還有一大段細節,
但我覺得有點像是要把程式碼每一行都看懂一樣繁瑣,
我附連結在底下,就交給有興趣的人自行補完吧。
最後再來總結一下 SensorService 的 UML 圖如下:

https://ithelp.ithome.com.tw/upload/images/20191009/20120515nxZ1DPHvSI.png


Reference :

https://blog.csdn.net/dabenxiong666/article/details/80726022


上一篇
[Day-27] Android Pie Sensor (4) 服務 (1)
下一篇
[Day-29] Android Pie Sensor (6) 硬件抽象層 (1)
系列文
Android Pie 底層開發學習心得30

尚未有邦友留言

立即登入留言