Vehicle HAL(3)--VehicleHalManager 分析
目录
1. VehicleHalManager 结构图(1)--VehicleHalManager
2. VehicleHalManager 结构图(2)--EmulatedVehicleHal
3. VehicleHalManager::onHalEvent() – 处理vhal层事件
3.1 VehicleHalManager::onBatchHalEvent()消费hal层事件
3.2 vhal 与 car service 通信举例:VehicleHalServer::createApPowerStateReq()
struct VehiclePropValue
4. VehicleHalManager::subscribe(xxx)--实现属性订阅功能
5. VehicleHalManager-BatchingConsumer 处理属性变化事件
6. VehicleHalManager的dump()
VehicleHalManager实现了IVehicle接口,是hidl服务载体。同时顾名思义,这个类是用来管理VehicleHal的。在vhal中,VehicleHal是一个抽象类,必须要有具体的实现,目前google给了一个模拟EmulatedVehicleHal(VehicleHal的具体实现类)。car service可以连接到这个VehicleHalManager。
1. VehicleHalManager 结构图(1)--VehicleHalManager
VehicleHalManager还实现IVehicle接口,处理event消息,管理订阅者。
2. VehicleHalManager 结构图(2)--EmulatedVehicleHal
google给了一个默认的EmulatedVehicleHal。
3. VehicleHalManager::onHalEvent() – 处理vhal层事件
将消息放入mEventQueue,里面有专门的线程处理。
EmulatedVehicleHal::onPropertyValue() >doHalEvent() > mOnHalEvent() 实际为 EmulatedVehicleHal::onPropertyValue() >doHalEvent() > VehicleHalManager::onHalEvent()
android11/hardware/interfaces/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHal.h
108 /* Propagates property change events to vehicle HAL clients. */
109 void doHalEvent(VehiclePropValuePtr v) {
110 mOnHalEvent(std::move(v));//mOnHalEvent为一个绑定函数,类似于一个回调
111 }
112
实际为:
467 void VehicleHalManager::onHalEvent(VehiclePropValuePtr v) {
468 mEventQueue.push(std::move(v));
469 }
BatchingConsumer消耗mEventQueue
hardware/interfaces/automotive/vehicle/2.0/default/common/include/vhal_v2_0/ConcurrentQueue.h
87 template<typename T>
88 class BatchingConsumer {
89 private:
90 enum class State {
91 INIT = 0,
92 RUNNING = 1,
93 STOP_REQUESTED = 2,
94 STOPPED = 3,
95 };
96
97 public:
98 BatchingConsumer() : mState(State::INIT) {}
99
100 BatchingConsumer(const BatchingConsumer &) = delete;
101 BatchingConsumer &operator=(const BatchingConsumer &) = delete;
102
103 using OnBatchReceivedFunc = std::function<void(const std::vector<T>& vec)>;
104
105 void run(ConcurrentQueue<T>* queue,
106 std::chrono::nanoseconds batchInterval,
107 const OnBatchReceivedFunc& func) {
108 mQueue = queue;
109 mBatchInterval = batchInterval;
110
111 mWorkerThread = std::thread(
112 &BatchingConsumer<T>::runInternal, this, func);//传入了func
113 }
114
115 void requestStop() {
116 mState = State::STOP_REQUESTED;
117 }
118
119 void waitStopped() {
120 if (mWorkerThread.joinable()) {
121 mWorkerThread.join();
122 }
123 }
124
125 private:
126 void runInternal(const OnBatchReceivedFunc& onBatchReceived) {//onBatchReceived为func
127 if (mState.exchange(State::RUNNING) == State::INIT) {
128 while (State::RUNNING == mState) {
129 mQueue->waitForItems();
130 if (State::STOP_REQUESTED == mState) break;
131
132 std::this_thread::sleep_for(mBatchInterval);
133 if (State::STOP_REQUESTED == mState) break;
134
135 std::vector<T> items = mQueue->flush();
136
137 if (items.size() > 0) {
138 onBatchReceived(items);//关键方法
139 }
140 }
141 }
142
143 mState = State::STOPPED;
144 }
145
146 private:
147 std::thread mWorkerThread;
148
149 std::atomic<State> mState;
150 std::chrono::nanoseconds mBatchInterval;
151 ConcurrentQueue<T>* mQueue;
152 };
func引用的来源在VehicleHalManager::init() > mBatchingConsumer.run。
431 void VehicleHalManager::init() {
432 ALOGI("VehicleHalManager::init");
433
434 mHidlVecOfVehiclePropValuePool.resize(kMaxHidlVecOfVehiclPropValuePoolSize);
435
436
437 mBatchingConsumer.run(&mEventQueue,
438 kHalEventBatchingTimeWindow,
439 std::bind(&VehicleHalManager::onBatchHalEvent,
440 this, _1));//关键方法
441
442 mHal->init(&mValueObjectPool,
443 std::bind(&VehicleHalManager::onHalEvent, this, _1),
444 std::bind(&VehicleHalManager::onHalPropertySetError, this,
445 _1, _2, _3));
446
447 // Initialize index with vehicle configurations received from VehicleHal.
448 auto supportedPropConfigs = mHal->listProperties();
449 mConfigIndex.reset(new VehiclePropConfigIndex(supportedPropConfigs));
450
451 std::vector<int32_t> supportedProperties(
452 supportedPropConfigs.size());
453 for (const auto& config : supportedPropConfigs) {
454 supportedProperties.push_back(config.prop);
455 }
456 }
3.1 VehicleHalManager::onBatchHalEvent()消费hal层事件
482 void VehicleHalManager::onBatchHalEvent(const std::vector<VehiclePropValuePtr>& values) {
483 const auto& clientValues =
484 mSubscriptionManager.distributeValuesToClients(values, SubscribeFlags::EVENTS_FROM_CAR);//通过mSubscriptionManager找到client。
485
486 for (const HalClientValues& cv : clientValues) {
487 auto vecSize = cv.values.size();
488 hidl_vec<VehiclePropValue> vec;
489 if (vecSize < kMaxHidlVecOfVehiclPropValuePoolSize) {
490 vec.setToExternal(&mHidlVecOfVehiclePropValuePool[0], vecSize);
491 } else {
492 vec.resize(vecSize);
493 }
494
495 int i = 0;
496 for (VehiclePropValue* pValue : cv.values) {
497 shallowCopy(&(vec)[i++], *pValue);
498 }
499 auto status = cv.client->getCallback()->onPropertyEvent(vec);//向上传递
500 if (!status.isOk()) {
501 ALOGE("Failed to notify client %s, err: %s",
502 toString(cv.client->getCallback()).c_str(),
503 status.description().c_str());
504 }
505 }
506 }
上层通过HalClient.Java向下订阅:
3.2 vhal 与 car service 通信举例:VehicleHalServer::createApPowerStateReq()
hal层创建的请求,发送给car framework java层
hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
158 VehicleHalServer::VehiclePropValuePtr VehicleHalServer::createApPowerStateReq(
159 VehicleApPowerStateReq state, int32_t param) {//传入state
160 auto req = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 2);//新建消息
161 req->prop = toInt(VehicleProperty::AP_POWER_STATE_REQ);//赋值消息码
162 req->areaId = 0;
163 req->timestamp = elapsedRealtimeNano();
164 req->status = VehiclePropertyStatus::AVAILABLE;
165 req->value.int32Values[0] = toInt(state);//power state
166 req->value.int32Values[1] = param;//second param
167 return req;
168 }
struct VehiclePropValue
hardware/interfaces/automotive/vehicle/2.0/types.hal
using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
3553 /**
3554 * Encapsulates the property name and the associated value. It
3555 * is used across various API calls to set values, get values or to register for
3556 * events.
3557 */
3558 struct VehiclePropValue {
3559 /** Time is elapsed nanoseconds since boot */
3560 int64_t timestamp;
3561
3562 /**
3563 * Area type(s) for non-global property it must be one of the value from
3564 * VehicleArea* enums or 0 for global properties.
3565 */
3566 int32_t areaId;
3567
3568 /** Property identifier */
3569 int32_t prop;
3570
3571 /** Status of the property */
3572 VehiclePropertyStatus status;
3573
3574 /**
3575 * Contains value for a single property. Depending on property data type of
3576 * this property (VehiclePropetyType) one field of this structure must be filled in.
3577 */
3578 struct RawValue {
3579 /**
3580 * This is used for properties of types VehiclePropertyType#INT
3581 * and VehiclePropertyType#INT_VEC
3582 */
3583 vec<int32_t> int32Values;
3584
3585 /**
3586 * This is used for properties of types VehiclePropertyType#FLOAT
3587 * and VehiclePropertyType#FLOAT_VEC
3588 */
3589 vec<float> floatValues;
3590
3591 /** This is used for properties of type VehiclePropertyType#INT64 */
3592 vec<int64_t> int64Values;
3593
3594 /** This is used for properties of type VehiclePropertyType#BYTES */
3595 vec<uint8_t> bytes;
3596
3597 /** This is used for properties of type VehiclePropertyType#STRING */
3598 string stringValue;
3599 };
3600
3601 RawValue value;
3602 };
AP_POWER_STATE_REPORT
hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
36 constexpr int AP_POWER_STATE_REPORT = (int)VehicleProperty::AP_POWER_STATE_REPORT;
VehicleProperty为int32_t类型
enum class VehicleProperty : int32_t
AP_POWER_STATE_REPORT的值
android11/packages/services/Car/car-lib/src/android/car/VehiclePropertyIds.java
1178 /**
1179 * Property to report power state of application processor
1180 *
1181 * It is assumed that AP's power state is controller by separate power
1182 * controller.
1183 *
1184 * int32Values[0] : VehicleApPowerStateReport enum value
1185 * int32Values[1] : Time in ms to wake up, if necessary. Otherwise 0.
1186 *
1187 *
1188 * @change_mode VehiclePropertyChangeMode:ON_CHANGE
1189 * @access VehiclePropertyAccess:READ_WRITE
1190 */
1191 AP_POWER_STATE_REPORT = 289475073 /* (0x0A01 | VehiclePropertyGroup:SYSTEM | VehiclePropertyType:INT32_VEC | VehicleArea:GLOBAL) */,
4. VehicleHalManager::subscribe(xxx)--实现属性订阅功能
管理属性消息的订阅。
hardware/interfaces/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
131 Return<StatusCode> VehicleHalManager::subscribe(const sp<IVehicleCallback> &callback,
132 const hidl_vec<SubscribeOptions> &options) {
133 hidl_vec<SubscribeOptions> verifiedOptions(options);
134 for (size_t i = 0; i < verifiedOptions.size(); i++) {
135 SubscribeOptions& ops = verifiedOptions[i];
136 auto prop = ops.propId;
137
138 const auto* config = getPropConfigOrNull(prop);
139 if (config == nullptr) {
140 ALOGE("Failed to subscribe: config not found, property: 0x%x",
141 prop);
142 return StatusCode::INVALID_ARG;
143 }
144
145 if (ops.flags == SubscribeFlags::UNDEFINED) {
146 ALOGE("Failed to subscribe: undefined flag in options provided");
147 return StatusCode::INVALID_ARG;
148 }
149
150 if (!isSubscribable(*config, ops.flags)) {
151 ALOGE("Failed to subscribe: property 0x%x is not subscribable",
152 prop);
153 return StatusCode::INVALID_ARG;
154 }
155
156 ops.sampleRate = checkSampleRate(*config, ops.sampleRate);
157 }
158
159 std::list<SubscribeOptions> updatedOptions;
160 auto res = mSubscriptionManager.addOrUpdateSubscription(getClientId(callback),//(1)关键代码
161 callback, verifiedOptions,
162 &updatedOptions);
163 if (StatusCode::OK != res) {
164 ALOGW("%s failed to subscribe, error code: %d", __func__, res);
165 return res;
166 }
167
168 for (auto opt : updatedOptions) {
169 mHal->subscribe(opt.propId, opt.sampleRate);//(2)转由vhal处理
170 }
171
172 return StatusCode::OK;
173 }
(1)SubscriptionManager::addOrUpdateSubscription增加订阅者
hardware/interfaces/automotive/vehicle/2.0/default/common/src/SubscriptionManager.cpp
86 StatusCode SubscriptionManager::addOrUpdateSubscription(
87 ClientId clientId,
88 const sp<IVehicleCallback> &callback,
89 const hidl_vec<SubscribeOptions> &optionList,
90 std::list<SubscribeOptions>* outUpdatedSubscriptions) {
91 outUpdatedSubscriptions->clear();
92
93 MuxGuard g(mLock);
94
95 ALOGI("SubscriptionManager::addOrUpdateSubscription, callback: %p", callback.get());
96
97 const sp<HalClient>& client = getOrCreateHalClientLocked(clientId, callback);
98 if (client.get() == nullptr) {
99 return StatusCode::INTERNAL_ERROR;
100 }
101
102 for (size_t i = 0; i < optionList.size(); i++) {
103 const SubscribeOptions& opts = optionList[i];
104 ALOGI("SubscriptionManager::addOrUpdateSubscription, prop: 0x%x", opts.propId);
105 client->addOrUpdateSubscription(opts);
106
107 addClientToPropMapLocked(opts.propId, client);
108
109 if (SubscribeFlags::EVENTS_FROM_CAR & opts.flags) {
110 SubscribeOptions updated;
111 if (updateHalEventSubscriptionLocked(opts, &updated)) {
112 outUpdatedSubscriptions->push_back(updated);
113 }
114 }
115 }
116
117 return StatusCode::OK;
118 }
(2)EmulatedVehicleHal::subscribe(xxx)
hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
316 StatusCode EmulatedVehicleHal::subscribe(int32_t property, float sampleRate) {
317 ALOGI("%s propId: 0x%x, sampleRate: %f", __func__, property, sampleRate);
318
319 if (isContinuousProperty(property)) {
320 mRecurrentTimer.registerRecurrentEvent(hertzToNanoseconds(sampleRate), property);
321 }
322 return StatusCode::OK;
323 }
(3)订阅后的转发
VehicleHalManager::onBatchHalEvent()消费hal层事件,开始便使用此函数获取client。
120 std::list<HalClientValues> SubscriptionManager::distributeValuesToClients(
121 const std::vector<recyclable_ptr<VehiclePropValue>>& propValues,
122 SubscribeFlags flags) const {
123 std::map<sp<HalClient>, std::list<VehiclePropValue*>> clientValuesMap;
124
125 {
126 MuxGuard g(mLock);
127 for (const auto& propValue: propValues) {
128 VehiclePropValue* v = propValue.get();
129 auto clients = getSubscribedClientsLocked(v->prop, flags);
130 for (const auto& client : clients) {
131 clientValuesMap[client].push_back(v);
132 }
133 }
134 }
135
136 std::list<HalClientValues> clientValues;
137 for (const auto& entry : clientValuesMap) {
138 clientValues.push_back(HalClientValues {
139 .client = entry.first,
140 .values = entry.second
141 });
142 }
143
144 return clientValues;
145 }
hardware/interfaces/automotive/vehicle/2.0/default/common/include/vhal_v2_0/SubscriptionManager.h
40 class HalClient : public android::RefBase {
41 public:
42 HalClient(const sp<IVehicleCallback> &callback)
43 : mCallback(callback) {}
44
45 virtual ~HalClient() {}
46 public:
47 sp<IVehicleCallback> getCallback() const {
48 return mCallback;
49 }
50
51 void addOrUpdateSubscription(const SubscribeOptions &opts);
52 bool isSubscribed(int32_t propId, SubscribeFlags flags);
53 std::vector<int32_t> getSubscribedProperties() const;
54
55 private:
56 const sp<IVehicleCallback> mCallback;
57
58 std::map<int32_t, SubscribeOptions> mSubscriptions;
59 };
5. VehicleHalManager-BatchingConsumer 处理属性变化事件
hardware/interfaces/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
87 template<typename T>
88 class BatchingConsumer {
89 private:
90 enum class State {
91 INIT = 0,
92 RUNNING = 1,
93 STOP_REQUESTED = 2,
94 STOPPED = 3,
95 };
96
97 public:
98 BatchingConsumer() : mState(State::INIT) {}
99
100 BatchingConsumer(const BatchingConsumer &) = delete;
101 BatchingConsumer &operator=(const BatchingConsumer &) = delete;
102
103 using OnBatchReceivedFunc = std::function<void(const std::vector<T>& vec)>;
104
105 void run(ConcurrentQueue<T>* queue,
106 std::chrono::nanoseconds batchInterval,
107 const OnBatchReceivedFunc& func) {
108 mQueue = queue;
109 mBatchInterval = batchInterval;
110
111 mWorkerThread = std::thread(
112 &BatchingConsumer<T>::runInternal, this, func);
113 }
114
115 void requestStop() {
116 mState = State::STOP_REQUESTED;
117 }
118
119 void waitStopped() {
120 if (mWorkerThread.joinable()) {
121 mWorkerThread.join();
122 }
123 }
124
125 private:
126 void runInternal(const OnBatchReceivedFunc& onBatchReceived) {
127 if (mState.exchange(State::RUNNING) == State::INIT) {
128 while (State::RUNNING == mState) {
129 mQueue->waitForItems();
130 if (State::STOP_REQUESTED == mState) break;
131
132 std::this_thread::sleep_for(mBatchInterval);
133 if (State::STOP_REQUESTED == mState) break;
134
135 std::vector<T> items = mQueue->flush();
136
137 if (items.size() > 0) {
138 onBatchReceived(items);
139 }
140 }
141 }
142
143 mState = State::STOPPED;
144 }
145
146 private:
147 std::thread mWorkerThread;
148
149 std::atomic<State> mState;
150 std::chrono::nanoseconds mBatchInterval;
151 ConcurrentQueue<T>* mQueue;
152 };
467 void VehicleHalManager::onHalEvent(VehiclePropValuePtr v) {
468 mEventQueue.push(std::move(v));
469 }
mEventQueue是什么?
hardware/interfaces/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h
130 ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
6. VehicleHalManager的dump()
主体为:cmdDumpAllProperties(xxx)。
先看VehicleHalManager init,VehicleHalManager init初始化是就把属性支持的属性写入了mConfigIndex。
void VehicleHalManager::init() {ALOGI("VehicleHalManager::init");mHidlVecOfVehiclePropValuePool.resize(kMaxHidlVecOfVehiclPropValuePoolSize);mBatchingConsumer.run(&mEventQueue,kHalEventBatchingTimeWindow,std::bind(&VehicleHalManager::onBatchHalEvent,this, _1));mHal->init(&mValueObjectPool,std::bind(&VehicleHalManager::onHalEvent, this, _1),std::bind(&VehicleHalManager::onHalPropertySetError, this,_1, _2, _3));// Initialize index with vehicle configurations received from VehicleHal.auto supportedPropConfigs = mHal->listProperties();mConfigIndex.reset(new VehiclePropConfigIndex(supportedPropConfigs));//放入mConfigIndexstd::vector<int32_t> supportedProperties(supportedPropConfigs.size());for (const auto& config : supportedPropConfigs) {supportedProperties.push_back(config.prop);}
}
6.1 cmdDumpAllProperties(xxx)
279 void VehicleHalManager::cmdDumpAllProperties(int fd) {
280 auto& halConfig = mConfigIndex->getAllConfigs();//初始化时,从store设置
281 size_t size = halConfig.size();
282 if (size == 0) {
283 dprintf(fd, "no properties to dump\n");
284 return;
285 }
286 int rowNumber = 0;
287 dprintf(fd, "dumping %zu properties\n", size);
288 for (auto& config : halConfig) {
289 cmdDumpOneProperty(fd, ++rowNumber, config);
290 }
291 }