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