1e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev/* 2e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * Copyright (C) 2016 The Android Open Source Project 3e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * 4e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * Licensed under the Apache License, Version 2.0 (the "License"); 5e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * you may not use this file except in compliance with the License. 6e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * You may obtain a copy of the License at 7e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * 8e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * http://www.apache.org/licenses/LICENSE-2.0 9e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * 10e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * Unless required by applicable law or agreed to in writing, software 11e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * distributed under the License is distributed on an "AS IS" BASIS, 12e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * See the License for the specific language governing permissions and 14e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev * limitations under the License. 15e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev */ 16e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 172579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev#define LOG_TAG "automotive.vehicle@2.0-impl" 18e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 190e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev#include "SubscriptionManager.h" 200e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev 21e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev#include <cmath> 228ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev#include <inttypes.h> 23e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 240e0a925aea98a63120e3ce81e6f9ca83441a7b1fPavel Maltsev#include <android/log.h> 25e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 26e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev#include "VehicleUtils.h" 27e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 28e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevnamespace android { 29e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevnamespace hardware { 302579fb792b4d47555515459f372f63c4305ee2caPavel Maltsevnamespace automotive { 31e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevnamespace vehicle { 32e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevnamespace V2_0 { 33e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 34e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevbool mergeSubscribeOptions(const SubscribeOptions &oldOpts, 35e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev const SubscribeOptions &newOpts, 36e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev SubscribeOptions *outResult) { 37e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev float updatedRate = std::max(oldOpts.sampleRate, newOpts.sampleRate); 38fbd346636fe1b61fce69b5a0d9ceb2ffe7d81939Scott Randolph SubscribeFlags updatedFlags = SubscribeFlags(oldOpts.flags | newOpts.flags); 39e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 401ae977d6e87a88e1689d406636982e8296d68175Steve Paik bool updated = (updatedRate > oldOpts.sampleRate) || (updatedFlags != oldOpts.flags); 41e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (updated) { 42e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev *outResult = oldOpts; 43e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev outResult->sampleRate = updatedRate; 44e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev outResult->flags = updatedFlags; 45e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 46e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 47e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev return updated; 48e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 49e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 50e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevvoid HalClient::addOrUpdateSubscription(const SubscribeOptions &opts) { 518ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev ALOGI("%s opts.propId: 0x%x", __func__, opts.propId); 528ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev 53e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev auto it = mSubscriptions.find(opts.propId); 54e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (it == mSubscriptions.end()) { 55e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev mSubscriptions.emplace(opts.propId, opts); 56e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } else { 57e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev const SubscribeOptions& oldOpts = it->second; 58e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev SubscribeOptions updatedOptions; 59e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (mergeSubscribeOptions(oldOpts, opts, &updatedOptions)) { 60e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev mSubscriptions.erase(it); 61e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev mSubscriptions.emplace(opts.propId, updatedOptions); 62e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 63e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 64e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 65e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 668e624b323c9808c6454cd2e76ffd3ca2ede5679cPavel Maltsevbool HalClient::isSubscribed(int32_t propId, 678e624b323c9808c6454cd2e76ffd3ca2ede5679cPavel Maltsev SubscribeFlags flags) { 68e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev auto it = mSubscriptions.find(propId); 69e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (it == mSubscriptions.end()) { 70e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev return false; 71e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 72e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev const SubscribeOptions& opts = it->second; 731ae977d6e87a88e1689d406636982e8296d68175Steve Paik bool res = (opts.flags & flags); 74e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev return res; 75e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 76e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 778ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsevstd::vector<int32_t> HalClient::getSubscribedProperties() const { 788ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev std::vector<int32_t> props; 798ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev for (const auto& subscription : mSubscriptions) { 808ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev ALOGI("%s propId: 0x%x, propId: 0x%x", __func__, subscription.first, subscription.second.propId); 818ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev props.push_back(subscription.first); 828ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev } 838ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev return props; 848ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev} 858ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev 868ab96e3874baa572f10e314ef6e0614042b8305fPavel MaltsevStatusCode SubscriptionManager::addOrUpdateSubscription( 8741a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev ClientId clientId, 88e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev const sp<IVehicleCallback> &callback, 898ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev const hidl_vec<SubscribeOptions> &optionList, 908ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev std::list<SubscribeOptions>* outUpdatedSubscriptions) { 918ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev outUpdatedSubscriptions->clear(); 92e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 93e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev MuxGuard g(mLock); 94e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 958ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev ALOGI("SubscriptionManager::addOrUpdateSubscription, callback: %p", callback.get()); 968ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev 9741a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev const sp<HalClient>& client = getOrCreateHalClientLocked(clientId, callback); 988ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev if (client.get() == nullptr) { 998ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev return StatusCode::INTERNAL_ERROR; 1008ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev } 101e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 102e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev for (size_t i = 0; i < optionList.size(); i++) { 103e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev const SubscribeOptions& opts = optionList[i]; 1048ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev ALOGI("SubscriptionManager::addOrUpdateSubscription, prop: 0x%x", opts.propId); 105e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev client->addOrUpdateSubscription(opts); 106e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 107e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev addClientToPropMapLocked(opts.propId, client); 108e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 10928b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik if (SubscribeFlags::EVENTS_FROM_CAR & opts.flags) { 110e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev SubscribeOptions updated; 111e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (updateHalEventSubscriptionLocked(opts, &updated)) { 1128ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev outUpdatedSubscriptions->push_back(updated); 113e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 114e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 115e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 116e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 1178ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev return StatusCode::OK; 118e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 119e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 120e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevstd::list<HalClientValues> SubscriptionManager::distributeValuesToClients( 121e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev const std::vector<recyclable_ptr<VehiclePropValue>>& propValues, 122e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev SubscribeFlags flags) const { 123e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev std::map<sp<HalClient>, std::list<VehiclePropValue*>> clientValuesMap; 124e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 125e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev { 126e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev MuxGuard g(mLock); 127e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev for (const auto& propValue: propValues) { 128e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev VehiclePropValue* v = propValue.get(); 1291ae977d6e87a88e1689d406636982e8296d68175Steve Paik auto clients = getSubscribedClientsLocked(v->prop, flags); 130e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev for (const auto& client : clients) { 131e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev clientValuesMap[client].push_back(v); 132e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 133e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 134e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 135e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 136e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev std::list<HalClientValues> clientValues; 137e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev for (const auto& entry : clientValuesMap) { 138e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev clientValues.push_back(HalClientValues { 139e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev .client = entry.first, 140e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev .values = entry.second 141e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev }); 142e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 143e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 144e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev return clientValues; 145e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 146e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 1471ae977d6e87a88e1689d406636982e8296d68175Steve Paikstd::list<sp<HalClient>> SubscriptionManager::getSubscribedClients(int32_t propId, 1481ae977d6e87a88e1689d406636982e8296d68175Steve Paik SubscribeFlags flags) const { 149e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev MuxGuard g(mLock); 1501ae977d6e87a88e1689d406636982e8296d68175Steve Paik return getSubscribedClientsLocked(propId, flags); 151e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 152e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 153e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevstd::list<sp<HalClient>> SubscriptionManager::getSubscribedClientsLocked( 1541ae977d6e87a88e1689d406636982e8296d68175Steve Paik int32_t propId, SubscribeFlags flags) const { 155e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev std::list<sp<HalClient>> subscribedClients; 156e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 157e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev sp<HalClientVector> propClients = getClientsForPropertyLocked(propId); 158e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (propClients.get() != nullptr) { 159e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev for (size_t i = 0; i < propClients->size(); i++) { 160e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev const auto& client = propClients->itemAt(i); 1611ae977d6e87a88e1689d406636982e8296d68175Steve Paik if (client->isSubscribed(propId, flags)) { 162e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev subscribedClients.push_back(client); 163e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 164e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 165e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 166e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 167e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev return subscribedClients; 168e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 169e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 170e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevbool SubscriptionManager::updateHalEventSubscriptionLocked( 171e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev const SubscribeOptions &opts, SubscribeOptions *outUpdated) { 172e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev bool updated = false; 173e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev auto it = mHalEventSubscribeOptions.find(opts.propId); 174e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (it == mHalEventSubscribeOptions.end()) { 175e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev *outUpdated = opts; 176e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev mHalEventSubscribeOptions.emplace(opts.propId, opts); 177e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev updated = true; 178e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } else { 179e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev const SubscribeOptions& oldOpts = it->second; 180e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 181e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (mergeSubscribeOptions(oldOpts, opts, outUpdated)) { 182e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev mHalEventSubscribeOptions.erase(opts.propId); 183e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev mHalEventSubscribeOptions.emplace(opts.propId, *outUpdated); 184e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev updated = true; 185e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 186e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 187e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 188e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev return updated; 189e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 190e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 191e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevvoid SubscriptionManager::addClientToPropMapLocked( 1928e624b323c9808c6454cd2e76ffd3ca2ede5679cPavel Maltsev int32_t propId, const sp<HalClient> &client) { 193e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev auto it = mPropToClients.find(propId); 194e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev sp<HalClientVector> propClients; 195e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (it == mPropToClients.end()) { 196e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev propClients = new HalClientVector(); 197e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev mPropToClients.insert(std::make_pair(propId, propClients)); 198e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } else { 199e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev propClients = it->second; 200e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 201e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev propClients->addOrUpdate(client); 202e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 203e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 204e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevsp<HalClientVector> SubscriptionManager::getClientsForPropertyLocked( 2058e624b323c9808c6454cd2e76ffd3ca2ede5679cPavel Maltsev int32_t propId) const { 206e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev auto it = mPropToClients.find(propId); 207e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev return it == mPropToClients.end() ? nullptr : it->second; 208e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 209e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 210e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsevsp<HalClient> SubscriptionManager::getOrCreateHalClientLocked( 21141a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev ClientId clientId, const sp<IVehicleCallback>& callback) { 21241a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev auto it = mClients.find(clientId); 21341a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev 214e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (it == mClients.end()) { 21541a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev uint64_t cookie = reinterpret_cast<uint64_t>(clientId); 2168ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev ALOGI("Creating new client and linking to death recipient, cookie: 0x%" PRIx64, cookie); 2178ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev auto res = callback->linkToDeath(mCallbackDeathRecipient, cookie); 2188ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev if (!res.isOk()) { // Client is already dead? 2198ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev ALOGW("%s failed to link to death, client %p, err: %s", 2208ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev __func__, callback.get(), res.description().c_str()); 2218ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev return nullptr; 2228ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev } 223270aeae9f4aa06389d0f752ba05c4325a8690cddPavel Maltsev 224270aeae9f4aa06389d0f752ba05c4325a8690cddPavel Maltsev sp<HalClient> client = new HalClient(callback); 22541a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev mClients.insert({clientId, client}); 226e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev return client; 227e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } else { 228e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev return it->second; 229e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 230e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 231e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 23241a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsevvoid SubscriptionManager::unsubscribe(ClientId clientId, 2338e624b323c9808c6454cd2e76ffd3ca2ede5679cPavel Maltsev int32_t propId) { 234e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev MuxGuard g(mLock); 235e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev auto propertyClients = getClientsForPropertyLocked(propId); 23641a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev auto clientIter = mClients.find(clientId); 237e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (clientIter == mClients.end()) { 238e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev ALOGW("Unable to unsubscribe: no callback found, propId: 0x%x", propId); 239e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } else { 240e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev auto client = clientIter->second; 241e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 242e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (propertyClients != nullptr) { 243e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev propertyClients->remove(client); 244e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 245e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (propertyClients->isEmpty()) { 246e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev mPropToClients.erase(propId); 247e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 248e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 249e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 250e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev bool isClientSubscribedToOtherProps = false; 251e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev for (const auto& propClient : mPropToClients) { 252e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (propClient.second->indexOf(client) >= 0) { 253e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev isClientSubscribedToOtherProps = true; 254e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev break; 255e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 256e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 257e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 258e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev if (!isClientSubscribedToOtherProps) { 2598ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev auto res = client->getCallback()->unlinkToDeath(mCallbackDeathRecipient); 2608ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev if (!res.isOk()) { 2618ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev ALOGW("%s failed to unlink to death, client: %p, err: %s", 2628ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev __func__, client->getCallback().get(), res.description().c_str()); 2638ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev } 264e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev mClients.erase(clientIter); 265e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 266e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev } 267e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 2688ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev if (propertyClients == nullptr || propertyClients->isEmpty()) { 2698ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev mHalEventSubscribeOptions.erase(propId); 2708ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev mOnPropertyUnsubscribed(propId); 2718ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev } 2728ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev} 2738ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev 2748ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsevvoid SubscriptionManager::onCallbackDead(uint64_t cookie) { 2758ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev ALOGI("%s, cookie: 0x%" PRIx64, __func__, cookie); 27641a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev ClientId clientId = cookie; 2778ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev 2788ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev std::vector<int32_t> props; 2798ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev { 2808ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev MuxGuard g(mLock); 28141a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev const auto& it = mClients.find(clientId); 2828ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev if (it == mClients.end()) { 2838ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev return; // Nothing to do here, client wasn't subscribed to any properties. 2848ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev } 2858ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev const auto& halClient = it->second; 2868ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev props = halClient->getSubscribedProperties(); 2878ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev } 2888ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev 2898ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev for (int32_t propId : props) { 29041a000da5862af5f2ca8d1bcc87a7a8937ad75b5Pavel Maltsev unsubscribe(clientId, propId); 2918ab96e3874baa572f10e314ef6e0614042b8305fPavel Maltsev } 292e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} 293e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 294e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev 295e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} // namespace V2_0 296e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} // namespace vehicle 2972579fb792b4d47555515459f372f63c4305ee2caPavel Maltsev} // namespace automotive 298e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} // namespace hardware 299e2603e3d52dbd505cdda20a8111f45bf833d674aPavel Maltsev} // namespace android 300