/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_SubscriptionManager_H_ #define android_hardware_automotive_vehicle_aidl_impl_vhal_include_SubscriptionManager_H_ #include #include #include #include #include #include #include #include #include #include #include namespace android { namespace hardware { namespace automotive { namespace vehicle { // A class to represent all the subscription configs for a continuous [propId, areaId]. class ContSubConfigs final { public: using ClientIdType = const AIBinder*; void addClient(const ClientIdType& clientId, float sampleRate); void removeClient(const ClientIdType& clientId); float getMaxSampleRate(); private: float mMaxSampleRate = 0.; std::unordered_map mSampleRates; void refreshMaxSampleRate(); }; // A thread-safe subscription manager that manages all VHAL subscriptions. class SubscriptionManager final { public: using ClientIdType = const AIBinder*; using CallbackType = std::shared_ptr; explicit SubscriptionManager(IVehicleHardware* hardware); ~SubscriptionManager(); // Subscribes to properties according to {@code SubscribeOptions}. Note that all option must // contain non-empty areaIds field, which contains all area IDs to subscribe. As a result, // the options here is different from the options passed from VHAL client. // Returns error if any of the subscribe options is not valid or one of the properties failed // to subscribe. Part of the properties maybe be subscribed successfully if this function // returns error. Caller is safe to retry since subscribing to an already subscribed property // is okay. // Returns ok if all the options are parsed correctly and all the properties are subscribed. VhalResult subscribe( const CallbackType& callback, const std::vector& options, bool isContinuousProperty); // Unsubscribes from the properties for the client. // Returns error if the client was not subscribed before, or one of the given property was not // subscribed, or one of the property failed to unsubscribe. Caller is safe to retry since // unsubscribing to an already unsubscribed property is okay (it would be ignored). // Returns ok if all the requested properties for the client are unsubscribed. VhalResult unsubscribe(ClientIdType client, const std::vector& propIds); // Unsubscribes from all the properties for the client. // Returns error if the client was not subscribed before or one of the subscribed properties // for the client failed to unsubscribe. Caller is safe to retry. // Returns ok if all the properties for the client are unsubscribed. VhalResult unsubscribe(ClientIdType client); // For a list of updated properties, returns a map that maps clients subscribing to // the updated properties to a list of updated values. This would only return on-change property // clients that should be informed for the given updated values. std::unordered_map< CallbackType, std::vector> getSubscribedClients( const std::vector& updatedValues); // Gets the sample rate for the continuous property. Returns {@code std::nullopt} if the // property has not been subscribed before or is not a continuous property. std::optional getSampleRate(const ClientIdType& clientId, int32_t propId, int32_t areaId); // Checks whether the sample rate is valid. static bool checkSampleRate(float sampleRate); private: // Friend class for testing. friend class DefaultVehicleHalTest; IVehicleHardware* mVehicleHardware; mutable std::mutex mLock; std::unordered_map, PropIdAreaIdHash> mClientsByPropIdArea GUARDED_BY(mLock); std::unordered_map> mSubscribedPropsByClient GUARDED_BY(mLock); std::unordered_map mContSubConfigsByPropIdArea GUARDED_BY(mLock); VhalResult updateSampleRateLocked(const ClientIdType& clientId, const PropIdAreaId& propIdAreaId, float sampleRate) REQUIRES(mLock); VhalResult removeSampleRateLocked(const ClientIdType& clientId, const PropIdAreaId& propIdAreaId) REQUIRES(mLock); // Checks whether the manager is empty. For testing purpose. bool isEmpty(); // Get the interval in nanoseconds accroding to sample rate. static android::base::Result getInterval(float sampleRate); }; } // namespace vehicle } // namespace automotive } // namespace hardware } // namespace android #endif // android_hardware_automotive_vehicle_aidl_impl_vhal_include_SubscriptionManager_H_