1 /* 2 * Copyright (c) 2021, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CPP_TELEMETRY_CARTELEMETRYD_SRC_TELEMETRYSERVER_H_ 18 #define CPP_TELEMETRY_CARTELEMETRYD_SRC_TELEMETRYSERVER_H_ 19 20 #include "LooperWrapper.h" 21 #include "RingBuffer.h" 22 23 #include <aidl/android/automotive/telemetry/internal/ICarDataListener.h> 24 #include <aidl/android/frameworks/automotive/telemetry/CallbackConfig.h> 25 #include <aidl/android/frameworks/automotive/telemetry/CarData.h> 26 #include <aidl/android/frameworks/automotive/telemetry/ICarTelemetryCallback.h> 27 #include <android-base/chrono_utils.h> 28 #include <android-base/result.h> 29 #include <android-base/thread_annotations.h> 30 #include <gtest/gtest_prod.h> 31 #include <utils/Looper.h> 32 33 #include <cstdint> 34 #include <memory> 35 #include <unordered_map> 36 #include <unordered_set> 37 38 namespace android { 39 namespace automotive { 40 namespace telemetry { 41 42 using ::aidl::android::frameworks::automotive::telemetry::CallbackConfig; 43 using ::aidl::android::frameworks::automotive::telemetry::ICarTelemetryCallback; 44 45 struct TelemetryCallback { 46 CallbackConfig config; 47 std::shared_ptr<ICarTelemetryCallback> callback; 48 TelemetryCallbackTelemetryCallback49 TelemetryCallback() {} TelemetryCallbackTelemetryCallback50 explicit TelemetryCallback(const std::shared_ptr<ICarTelemetryCallback>& cb) : callback(cb) {} TelemetryCallbackTelemetryCallback51 explicit TelemetryCallback(const CallbackConfig& cfg, 52 const std::shared_ptr<ICarTelemetryCallback>& cb) : 53 config(cfg), callback(cb) {} 54 // Copy constructor & copy assignment 55 TelemetryCallback(const TelemetryCallback& other) = default; 56 TelemetryCallback& operator=(const TelemetryCallback& other) = default; 57 // Move constructor & move assignment 58 TelemetryCallback(TelemetryCallback&& other) = default; 59 TelemetryCallback& operator=(TelemetryCallback&& other) = default; 60 61 // Equal function 62 bool operator==(const TelemetryCallback& other) const { 63 return reinterpret_cast<uintptr_t>(callback->asBinder().get()) == 64 reinterpret_cast<uintptr_t>(other.callback->asBinder().get()); 65 } 66 67 struct HashFunction { operatorTelemetryCallback::HashFunction68 size_t operator()(const TelemetryCallback& tc) const { 69 return std::hash<uintptr_t>()( 70 reinterpret_cast<uintptr_t>(tc.callback->asBinder().get())); 71 } 72 }; 73 }; 74 75 // This class contains the main logic of cartelemetryd native service. 76 // 77 // [writer clients] -> ICarTelemetry -----------. 78 // [reader client] --> ICarTelemetryInternal -----`-> TelemetryServer 79 // 80 // TelemetryServer starts pushing CarData to ICarDataListener when there is a data available and 81 // the listener is set and alive. It uses `mLooper` for periodically pushing the data. 82 // 83 // This class is thread-safe. 84 class TelemetryServer { 85 public: 86 explicit TelemetryServer(LooperWrapper* looper, 87 const std::chrono::nanoseconds& pushCarDataDelayNs, int maxBufferSize); 88 89 /** 90 * Dumps the current state for dumpsys. 91 * 92 * <p>Expected to be called from a binder thread pool. 93 */ 94 void dump(int fd); 95 96 /** 97 * Writes incoming CarData to the RingBuffer. 98 * 99 * <p>Expected to be called from a binder thread pool. 100 */ 101 void writeCarData( 102 const std::vector<aidl::android::frameworks::automotive::telemetry::CarData>& dataList, 103 uid_t publisherUid); 104 105 /** 106 * Adds a ICarTelemtryCallback and associate it with the CallbackConfig. 107 * 108 * <p>Expected to be called from a binder thread pool. 109 110 * @return An empty okay result on success, or an error result if the callback already 111 * exists. 112 */ 113 android::base::Result<void> addCallback(const CallbackConfig& config, 114 const std::shared_ptr<ICarTelemetryCallback>& callback); 115 116 /** 117 * Removes a ICarTelemetryCallback. 118 * 119 * <p>Expected to be called from a binder thread pool. 120 * 121 * @return An empty okay result on success, or an error result if the callback is not found. 122 */ 123 android::base::Result<void> removeCallback( 124 const std::shared_ptr<ICarTelemetryCallback>& callback); 125 126 /** 127 * Sets the listener and overrides the previous listener if it exists. 128 * 129 * <p>Expected to be called from a binder thread pool. 130 */ 131 void setListener( 132 const std::shared_ptr<aidl::android::automotive::telemetry::internal::ICarDataListener>& 133 listener); 134 135 /** 136 * Clears the ICarDataListener. 137 * 138 * <p>Expected to be called from a binder thread pool. 139 */ 140 void clearListener(); 141 142 /** 143 * Adds active CarData IDs, called by CarTelemetrydPublisher when the IDs 144 * has active subscribers. 145 * 146 * <p>Expected to be called from a binder thread pool. 147 */ 148 void addCarDataIds(const std::vector<int32_t>& ids); 149 150 /** 151 * Removes CarData IDs, called by CarTelemetrydPublisher when the IDs 152 * no longer has subscribers. 153 * 154 * <p>Expected to be called from a binder thread pool. 155 */ 156 void removeCarDataIds(const std::vector<int32_t>& ids); 157 158 /** 159 * Expected to be called from a binder thread pool. 160 */ 161 std::shared_ptr<aidl::android::automotive::telemetry::internal::ICarDataListener> getListener(); 162 163 private: 164 class MessageHandlerImpl : public MessageHandler { 165 public: 166 explicit MessageHandlerImpl(TelemetryServer* server); 167 168 void handleMessage(const Message& message) override; 169 170 private: 171 TelemetryServer* mTelemetryServer; // not owned 172 }; 173 174 private: 175 // Find the common elements in mCarDataIds and the argument ids 176 std::vector<int32_t> findCarDataIdsIntersection(const std::vector<int32_t>& ids); 177 // Periodically called by mLooper if there is a "push car data" messages. 178 void pushCarDataToListeners(); 179 180 LooperWrapper* mLooper; // not owned 181 const std::chrono::nanoseconds mPushCarDataDelayNs; 182 183 // A single mutex for all the sensitive operations. Threads must not lock it for long time, 184 // as clients will be writing CarData to the ring buffer under this mutex. 185 std::mutex mMutex; 186 187 // Buffers vendor written CarData. 188 RingBuffer mRingBuffer GUARDED_BY(mMutex); 189 190 // Notifies listener when CarData is written. 191 std::shared_ptr<aidl::android::automotive::telemetry::internal::ICarDataListener> 192 mCarDataListener GUARDED_BY(mMutex); 193 194 // Stores a set of CarData IDs that have subscribers in CarTelemetryService. 195 // Used for filtering data. 196 std::unordered_set<int32_t> mCarDataIds GUARDED_BY(mMutex); 197 198 // A hashset of TelemetryCallbacks to keep track of which callbacks have been added. 199 std::unordered_set<TelemetryCallback, TelemetryCallback::HashFunction> mCallbacks 200 GUARDED_BY(mMutex); 201 202 // Maps CarData ID to a set of callbacks that are associated with this ID. 203 // Used for invoking the callback when this ID has been added or removed. 204 std::unordered_map<int32_t, 205 std::unordered_set<TelemetryCallback, TelemetryCallback::HashFunction>> 206 mIdToCallbacksMap GUARDED_BY(mMutex); 207 208 // Handler for mLooper. 209 android::sp<MessageHandlerImpl> mMessageHandler; 210 211 // Friends are simplest way of testing if `pushCarDataToListeners()` can handle edge cases. 212 friend class TelemetryServerTest; 213 FRIEND_TEST(TelemetryServerTest, NoListenerButMultiplePushes); 214 FRIEND_TEST(TelemetryServerTest, NoDataButMultiplePushes); 215 // The following test accesses member variables such as `mCarDataIds` and `mCallbacks` 216 // to check its contents. 217 FRIEND_TEST(TelemetryServerTest, RemoveCarDataIdsReturnsOk); 218 FRIEND_TEST(TelemetryServerTest, RemoveCallbackReturnsOk); 219 }; 220 221 } // namespace telemetry 222 } // namespace automotive 223 } // namespace android 224 225 #endif // CPP_TELEMETRY_CARTELEMETRYD_SRC_TELEMETRYSERVER_H_ 226