1 /** 2 * Copyright (c) 2020, 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_WATCHDOG_SERVER_SRC_WATCHDOGPROCESSSERVICE_H_ 18 #define CPP_WATCHDOG_SERVER_SRC_WATCHDOGPROCESSSERVICE_H_ 19 20 #include "AIBinderDeathRegistrationWrapper.h" 21 22 #include <aidl/android/automotive/watchdog/ICarWatchdogClient.h> 23 #include <aidl/android/automotive/watchdog/TimeoutLength.h> 24 #include <aidl/android/automotive/watchdog/internal/ICarWatchdogMonitor.h> 25 #include <aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.h> 26 #include <aidl/android/automotive/watchdog/internal/ProcessIdentifier.h> 27 #include <android-base/chrono_utils.h> 28 #include <android-base/result.h> 29 #include <android/binder_auto_utils.h> 30 #include <android/hidl/manager/1.0/IServiceManager.h> 31 #include <cutils/multiuser.h> 32 #include <utils/Looper.h> 33 #include <utils/Mutex.h> 34 #include <utils/RefBase.h> 35 #include <utils/String16.h> 36 #include <utils/StrongPointer.h> 37 #include <utils/Vector.h> 38 39 #include <IVhalClient.h> 40 #include <VehicleHalTypes.h> 41 42 #include <optional> 43 #include <unordered_map> 44 #include <unordered_set> 45 #include <vector> 46 47 namespace android { 48 namespace automotive { 49 namespace watchdog { 50 51 // Forward declaration for testing use only. 52 namespace internal { 53 54 class WatchdogProcessServicePeer; 55 56 } // namespace internal 57 58 class WatchdogServiceHelperInterface; 59 60 class WatchdogProcessServiceInterface : virtual public android::RefBase { 61 public: 62 virtual android::base::Result<void> start() = 0; 63 virtual void terminate() = 0; 64 virtual void onDump(int fd) = 0; 65 virtual void doHealthCheck(int what) = 0; 66 virtual void handleBinderDeath(void* cookie) = 0; 67 virtual ndk::ScopedAStatus registerClient( 68 const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client, 69 aidl::android::automotive::watchdog::TimeoutLength timeout) = 0; 70 virtual ndk::ScopedAStatus unregisterClient( 71 const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& 72 client) = 0; 73 virtual ndk::ScopedAStatus registerCarWatchdogService( 74 const ndk::SpAIBinder& binder, 75 const android::sp<WatchdogServiceHelperInterface>& helper) = 0; 76 virtual void unregisterCarWatchdogService(const ndk::SpAIBinder& binder) = 0; 77 virtual ndk::ScopedAStatus registerMonitor( 78 const std::shared_ptr< 79 aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& 80 monitor) = 0; 81 virtual ndk::ScopedAStatus unregisterMonitor( 82 const std::shared_ptr< 83 aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& 84 monitor) = 0; 85 virtual ndk::ScopedAStatus tellClientAlive( 86 const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client, 87 int32_t sessionId) = 0; 88 virtual ndk::ScopedAStatus tellCarWatchdogServiceAlive( 89 const std::shared_ptr< 90 aidl::android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>& 91 service, 92 const std::vector<aidl::android::automotive::watchdog::internal::ProcessIdentifier>& 93 clientsNotResponding, 94 int32_t sessionId) = 0; 95 virtual ndk::ScopedAStatus tellDumpFinished( 96 const std::shared_ptr< 97 aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor, 98 const aidl::android::automotive::watchdog::internal::ProcessIdentifier& 99 processIdentifier) = 0; 100 virtual void setEnabled(bool isEnabled) = 0; 101 virtual void onUserStateChange(userid_t userId, bool isStarted) = 0; 102 virtual void onAidlVhalPidFetched(int32_t) = 0; 103 }; 104 105 class WatchdogProcessService final : public WatchdogProcessServiceInterface { 106 public: 107 explicit WatchdogProcessService(const android::sp<Looper>& handlerLooper); 108 WatchdogProcessService( 109 const std::function<std::shared_ptr< 110 android::frameworks::automotive::vhal::IVhalClient>()>& tryCreateVhalClientFunc, 111 const std::function<android::sp<android::hidl::manager::V1_0::IServiceManager>()>& 112 tryGetHidlServiceManagerFunc, 113 const std::function<int64_t(pid_t)>& getStartTimeForPidFunc, 114 const std::chrono::nanoseconds& vhalPidCachingRetryDelayNs, 115 const sp<Looper>& handlerLooper, 116 const sp<AIBinderDeathRegistrationWrapperInterface>& deathRegistrationWrapper); ~WatchdogProcessService()117 ~WatchdogProcessService() { terminate(); } 118 119 android::base::Result<void> start() override; 120 void terminate() override; 121 void onDump(int fd) override; 122 void doHealthCheck(int what) override; 123 void handleBinderDeath(void* cookie) override; 124 ndk::ScopedAStatus registerClient( 125 const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client, 126 aidl::android::automotive::watchdog::TimeoutLength timeout) override; 127 ndk::ScopedAStatus unregisterClient( 128 const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client) 129 override; 130 ndk::ScopedAStatus registerCarWatchdogService( 131 const ndk::SpAIBinder& binder, 132 const android::sp<WatchdogServiceHelperInterface>& helper) override; 133 void unregisterCarWatchdogService(const ndk::SpAIBinder& binder) override; 134 ndk::ScopedAStatus registerMonitor( 135 const std::shared_ptr< 136 aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor) 137 override; 138 ndk::ScopedAStatus unregisterMonitor( 139 const std::shared_ptr< 140 aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor) 141 override; 142 ndk::ScopedAStatus tellClientAlive( 143 const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client, 144 int32_t sessionId) override; 145 ndk::ScopedAStatus tellCarWatchdogServiceAlive( 146 const std::shared_ptr< 147 aidl::android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>& 148 service, 149 const std::vector<aidl::android::automotive::watchdog::internal::ProcessIdentifier>& 150 clientsNotResponding, 151 int32_t sessionId) override; 152 ndk::ScopedAStatus tellDumpFinished( 153 const std::shared_ptr< 154 aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor, 155 const aidl::android::automotive::watchdog::internal::ProcessIdentifier& 156 processIdentifier) override; 157 void setEnabled(bool isEnabled) override; 158 void onUserStateChange(userid_t userId, bool isStarted) override; 159 void onAidlVhalPidFetched(int32_t) override; 160 161 private: 162 enum ClientType { 163 Regular, 164 Service, 165 }; 166 167 class ClientInfo { 168 public: ClientInfo(const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient> & client,pid_t pid,userid_t userId,uint64_t startTimeMillis,const WatchdogProcessService & service)169 ClientInfo(const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& 170 client, 171 pid_t pid, userid_t userId, uint64_t startTimeMillis, 172 const WatchdogProcessService& service) : 173 kPid(pid), 174 kUserId(userId), 175 kStartTimeMillis(startTimeMillis), 176 kType(ClientType::Regular), 177 kService(service), 178 kClient(client) {} ClientInfo(const android::sp<WatchdogServiceHelperInterface> & helper,const ndk::SpAIBinder & binder,pid_t pid,userid_t userId,uint64_t startTimeMillis,const WatchdogProcessService & service)179 ClientInfo(const android::sp<WatchdogServiceHelperInterface>& helper, 180 const ndk::SpAIBinder& binder, pid_t pid, userid_t userId, 181 uint64_t startTimeMillis, const WatchdogProcessService& service) : 182 kPid(pid), 183 kUserId(userId), 184 kStartTimeMillis(startTimeMillis), 185 kType(ClientType::Service), 186 kService(service), 187 kWatchdogServiceHelper(helper), 188 kWatchdogServiceBinder(binder) {} 189 190 std::string toString() const; 191 AIBinder* getAIBinder() const; 192 ndk::ScopedAStatus linkToDeath(AIBinder_DeathRecipient* recipient) const; 193 ndk::ScopedAStatus unlinkToDeath(AIBinder_DeathRecipient* recipient) const; 194 ndk::ScopedAStatus checkIfAlive( 195 aidl::android::automotive::watchdog::TimeoutLength timeout) const; 196 ndk::ScopedAStatus prepareProcessTermination() const; 197 198 const pid_t kPid; 199 const userid_t kUserId; 200 const int64_t kStartTimeMillis; 201 const ClientType kType; 202 const WatchdogProcessService& kService; 203 const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient> kClient; 204 const android::sp<WatchdogServiceHelperInterface> kWatchdogServiceHelper; 205 const ndk::SpAIBinder kWatchdogServiceBinder; 206 207 int sessionId; 208 }; 209 210 struct HeartBeat { 211 int64_t eventTime; 212 int64_t value; 213 }; 214 215 typedef std::unordered_map<int, ClientInfo> PingedClientMap; 216 217 class PropertyChangeListener final : 218 public android::frameworks::automotive::vhal::ISubscriptionCallback { 219 public: PropertyChangeListener(const android::sp<WatchdogProcessService> & service)220 explicit PropertyChangeListener(const android::sp<WatchdogProcessService>& service) : 221 kService(service) {} 222 223 void onPropertyEvent(const std::vector< 224 std::unique_ptr<android::frameworks::automotive::vhal::IHalPropValue>>& 225 values) override; 226 227 void onPropertySetError( 228 const std::vector<android::frameworks::automotive::vhal::HalPropError>& errors) 229 override; 230 231 private: 232 const android::sp<WatchdogProcessService> kService; 233 }; 234 235 class MessageHandlerImpl final : public MessageHandler { 236 public: MessageHandlerImpl(const android::sp<WatchdogProcessService> & service)237 explicit MessageHandlerImpl(const android::sp<WatchdogProcessService>& service) : 238 kService(service) {} 239 240 void handleMessage(const Message& message) override; 241 242 private: 243 const android::sp<WatchdogProcessService> kService; 244 }; 245 246 private: 247 android::base::Result<void> registerClient( 248 const ClientInfo& clientInfo, 249 aidl::android::automotive::watchdog::TimeoutLength timeout); 250 ndk::ScopedAStatus unregisterClientLocked( 251 const std::vector<aidl::android::automotive::watchdog::TimeoutLength>& timeouts, 252 const ndk::SpAIBinder& binder, ClientType clientType); 253 ndk::ScopedAStatus tellClientAliveLocked(const ndk::SpAIBinder& binder, int32_t sessionId); 254 android::base::Result<void> startHealthCheckingLocked( 255 aidl::android::automotive::watchdog::TimeoutLength timeout); 256 android::base::Result<void> dumpAndKillClientsIfNotResponding( 257 aidl::android::automotive::watchdog::TimeoutLength timeout); 258 android::base::Result<void> dumpAndKillAllProcesses( 259 const std::vector<aidl::android::automotive::watchdog::internal::ProcessIdentifier>& 260 processesNotResponding, 261 bool reportToVhal); 262 int32_t getNewSessionId(); 263 android::base::Result<void> updateVhal( 264 const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); 265 android::base::Result<void> connectToVhal(); 266 void subscribeToVhalHeartBeat(); 267 const sp<WatchdogServiceHelperInterface> getWatchdogServiceHelperLocked(); 268 void cacheVhalProcessIdentifier(); 269 void cacheVhalProcessIdentifierForPid(int32_t pid); 270 android::base::Result<void> requestAidlVhalPid(); 271 void reportWatchdogAliveToVhal(); 272 void reportTerminatedProcessToVhal( 273 const std::vector<aidl::android::automotive::watchdog::internal::ProcessIdentifier>& 274 processesNotResponding); 275 android::base::Result<std::string> readProcCmdLine(int32_t pid); 276 void handleVhalDeath(); 277 void queryVhalProperties(); 278 void updateVhalHeartBeat(int64_t value); 279 void checkVhalHealth(); 280 void resetVhalInfoLocked(); 281 void terminateVhal(); 282 283 using ClientInfoMap = std::unordered_map<uintptr_t, ClientInfo>; 284 using Processor = std::function<void(ClientInfoMap&, ClientInfoMap::const_iterator)>; 285 bool findClientAndProcessLocked( 286 const std::vector<aidl::android::automotive::watchdog::TimeoutLength>& timeouts, 287 AIBinder* binder, const Processor& processor); 288 bool findClientAndProcessLocked( 289 const std::vector<aidl::android::automotive::watchdog::TimeoutLength>& timeouts, 290 uintptr_t binderPtrId, const Processor& processor); 291 std::chrono::nanoseconds getTimeoutDurationNs( 292 const aidl::android::automotive::watchdog::TimeoutLength& timeout); 293 294 private: 295 const std::function<std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient>()> 296 kTryCreateVhalClientFunc; 297 const std::function<android::sp<android::hidl::manager::V1_0::IServiceManager>()> 298 kTryGetHidlServiceManagerFunc; 299 const std::function<int64_t(pid_t)> kGetStartTimeForPidFunc; 300 const std::chrono::nanoseconds kVhalPidCachingRetryDelayNs; 301 302 android::sp<Looper> mHandlerLooper; 303 android::sp<MessageHandlerImpl> mMessageHandler; 304 ndk::ScopedAIBinder_DeathRecipient mClientBinderDeathRecipient; 305 std::unordered_set<aidl::android::hardware::automotive::vehicle::VehicleProperty> 306 mNotSupportedVhalProperties; 307 std::shared_ptr<PropertyChangeListener> mPropertyChangeListener; 308 // mLastSessionId is accessed only within main thread. No need for mutual-exclusion. 309 int32_t mLastSessionId; 310 bool mServiceStarted; 311 std::chrono::milliseconds mVhalHealthCheckWindowMs; 312 std::optional<std::chrono::nanoseconds> mOverriddenClientHealthCheckWindowNs; 313 std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient::OnBinderDiedCallbackFunc> 314 mVhalBinderDiedCallback; 315 android::sp<AIBinderDeathRegistrationWrapperInterface> mDeathRegistrationWrapper; 316 317 android::Mutex mMutex; 318 319 std::unordered_map<aidl::android::automotive::watchdog::TimeoutLength, ClientInfoMap> 320 mClientsByTimeout GUARDED_BY(mMutex); 321 std::unordered_map<aidl::android::automotive::watchdog::TimeoutLength, PingedClientMap> 322 mPingedClients GUARDED_BY(mMutex); 323 std::unordered_set<userid_t> mStoppedUserIds GUARDED_BY(mMutex); 324 std::shared_ptr<aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor> mMonitor 325 GUARDED_BY(mMutex); 326 bool mIsEnabled GUARDED_BY(mMutex); 327 std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> mVhalService 328 GUARDED_BY(mMutex); 329 std::optional<aidl::android::automotive::watchdog::internal::ProcessIdentifier> 330 mVhalProcessIdentifier GUARDED_BY(mMutex); 331 int32_t mTotalVhalPidCachingAttempts GUARDED_BY(mMutex); 332 HeartBeat mVhalHeartBeat GUARDED_BY(mMutex); 333 334 // For unit tests. 335 friend class internal::WatchdogProcessServicePeer; 336 }; 337 338 } // namespace watchdog 339 } // namespace automotive 340 } // namespace android 341 342 #endif // CPP_WATCHDOG_SERVER_SRC_WATCHDOGPROCESSSERVICE_H_ 343