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/result.h> 21 #include <android/automotive/watchdog/ICarWatchdogClient.h> 22 #include <android/automotive/watchdog/internal/ICarWatchdogMonitor.h> 23 #include <android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.h> 24 #include <android/automotive/watchdog/internal/PowerCycle.h> 25 #include <android/automotive/watchdog/internal/UserState.h> 26 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h> 27 #include <binder/IBinder.h> 28 #include <binder/Status.h> 29 #include <cutils/multiuser.h> 30 #include <utils/Looper.h> 31 #include <utils/Mutex.h> 32 #include <utils/String16.h> 33 #include <utils/StrongPointer.h> 34 #include <utils/Vector.h> 35 36 #include <unordered_map> 37 #include <unordered_set> 38 #include <vector> 39 40 namespace android { 41 namespace automotive { 42 namespace watchdog { 43 44 class IWatchdogServiceHelper; 45 46 class WatchdogProcessService : public android::RefBase { 47 public: 48 explicit WatchdogProcessService(const android::sp<Looper>& handlerLooper); ~WatchdogProcessService()49 ~WatchdogProcessService() { terminate(); } 50 51 android::base::Result<void> start(); 52 void terminate(); 53 virtual android::base::Result<void> dump(int fd, 54 const android::Vector<android::String16>& args); 55 void doHealthCheck(int what); 56 57 virtual android::base::Result<void> registerWatchdogServiceHelper( 58 const android::sp<IWatchdogServiceHelper>& helper); 59 60 virtual android::binder::Status registerClient(const android::sp<ICarWatchdogClient>& client, 61 TimeoutLength timeout); 62 virtual android::binder::Status unregisterClient(const android::sp<ICarWatchdogClient>& client); 63 virtual android::binder::Status registerCarWatchdogService(const android::sp<IBinder>& binder); 64 virtual void unregisterCarWatchdogService(const android::sp<IBinder>& binder); 65 virtual android::binder::Status registerMonitor( 66 const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>& 67 monitor); 68 virtual android::binder::Status unregisterMonitor( 69 const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>& 70 monitor); 71 virtual android::binder::Status tellClientAlive(const android::sp<ICarWatchdogClient>& client, 72 int32_t sessionId); 73 virtual android::binder::Status tellCarWatchdogServiceAlive( 74 const android::sp< 75 android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>& service, 76 const std::vector<int32_t>& clientsNotResponding, int32_t sessionId); 77 virtual android::binder::Status tellDumpFinished( 78 const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>& 79 monitor, 80 int32_t pid); 81 virtual void setEnabled(bool isEnabled); 82 virtual android::binder::Status notifyUserStateChange( 83 userid_t userId, android::automotive::watchdog::internal::UserState state); 84 85 private: 86 enum ClientType { 87 Regular, 88 Service, 89 }; 90 91 struct ClientInfo { ClientInfoClientInfo92 ClientInfo(const android::sp<ICarWatchdogClient>& client, pid_t pid, userid_t userId) : 93 pid(pid), 94 userId(userId), 95 type(ClientType::Regular), 96 client(client) {} ClientInfoClientInfo97 ClientInfo(const android::sp<IWatchdogServiceHelper>& helper, 98 const android::sp<android::IBinder>& binder, pid_t pid, userid_t userId) : 99 pid(pid), 100 userId(userId), 101 type(ClientType::Service), 102 watchdogServiceHelper(helper), 103 watchdogServiceBinder(binder) {} 104 105 std::string toString() const; 106 status_t linkToDeath(const android::sp<android::IBinder::DeathRecipient>& recipient) const; 107 status_t unlinkToDeath( 108 const android::wp<android::IBinder::DeathRecipient>& recipient) const; 109 android::binder::Status checkIfAlive(TimeoutLength timeout) const; 110 android::binder::Status prepareProcessTermination() const; 111 bool operator!=(const ClientInfo& clientInfo) const { 112 return getBinder() != clientInfo.getBinder() || type != clientInfo.type; 113 } matchesBinderClientInfo114 bool matchesBinder(const android::sp<android::IBinder>& binder) const { 115 return binder == getBinder(); 116 } 117 118 pid_t pid; 119 userid_t userId; 120 int sessionId; 121 122 private: 123 android::sp<android::IBinder> getBinder() const; 124 125 ClientType type; 126 android::sp<ICarWatchdogClient> client = nullptr; 127 android::sp<IWatchdogServiceHelper> watchdogServiceHelper = nullptr; 128 android::sp<IBinder> watchdogServiceBinder = nullptr; 129 }; 130 131 struct HeartBeat { 132 int64_t eventTime; 133 int64_t value; 134 }; 135 136 typedef std::unordered_map<int, ClientInfo> PingedClientMap; 137 138 class BinderDeathRecipient : public android::IBinder::DeathRecipient { 139 public: 140 explicit BinderDeathRecipient(const android::sp<WatchdogProcessService>& service); 141 142 void binderDied(const android::wp<android::IBinder>& who) override; 143 144 private: 145 android::sp<WatchdogProcessService> mService; 146 }; 147 148 class HidlDeathRecipient : public android::hardware::hidl_death_recipient { 149 public: 150 explicit HidlDeathRecipient(const android::sp<WatchdogProcessService>& service); 151 152 void serviceDied(uint64_t cookie, 153 const android::wp<android::hidl::base::V1_0::IBase>& who) override; 154 155 private: 156 android::sp<WatchdogProcessService> mService; 157 }; 158 159 class PropertyChangeListener : 160 public android::hardware::automotive::vehicle::V2_0::IVehicleCallback { 161 public: 162 explicit PropertyChangeListener(const android::sp<WatchdogProcessService>& service); 163 164 android::hardware::Return<void> onPropertyEvent( 165 const android::hardware::hidl_vec< 166 android::hardware::automotive::vehicle::V2_0::VehiclePropValue>& propValues) 167 override; 168 android::hardware::Return<void> onPropertySet( 169 const android::hardware::automotive::vehicle::V2_0::VehiclePropValue& propValue) 170 override; 171 android::hardware::Return<void> onPropertySetError( 172 android::hardware::automotive::vehicle::V2_0::StatusCode errorCode, int32_t propId, 173 int32_t areaId) override; 174 175 private: 176 android::sp<WatchdogProcessService> mService; 177 }; 178 179 class MessageHandlerImpl : public MessageHandler { 180 public: 181 explicit MessageHandlerImpl(const android::sp<WatchdogProcessService>& service); 182 183 void handleMessage(const Message& message) override; 184 185 private: 186 android::sp<WatchdogProcessService> mService; 187 }; 188 189 private: 190 android::binder::Status registerClientLocked(const ClientInfo& clientInfo, 191 TimeoutLength timeout); 192 android::binder::Status unregisterClientLocked(const std::vector<TimeoutLength>& timeouts, 193 android::sp<IBinder> binder, 194 ClientType clientType); 195 android::binder::Status tellClientAliveLocked(const android::sp<android::IBinder>& binder, 196 int32_t sessionId); 197 android::base::Result<void> startHealthCheckingLocked(TimeoutLength timeout); 198 android::base::Result<void> dumpAndKillClientsIfNotResponding(TimeoutLength timeout); 199 android::base::Result<void> dumpAndKillAllProcesses( 200 const std::vector<int32_t>& processesNotResponding, bool reportToVhal); 201 int32_t getNewSessionId(); 202 android::base::Result<void> updateVhal( 203 const android::hardware::automotive::vehicle::V2_0::VehiclePropValue& value); 204 android::base::Result<void> connectToVhalLocked(); 205 void subscribeToVhalHeartBeatLocked(); 206 void reportWatchdogAliveToVhal(); 207 void reportTerminatedProcessToVhal(const std::vector<int32_t>& processesNotResponding); 208 android::base::Result<std::string> readProcCmdLine(int32_t pid); 209 void handleBinderDeath(const android::wp<android::IBinder>& who); 210 void handleHidlDeath(const android::wp<android::hidl::base::V1_0::IBase>& who); 211 void queryVhalPropertiesLocked(); 212 bool isVhalPropertySupportedLocked( 213 android::hardware::automotive::vehicle::V2_0::VehicleProperty propId); 214 void updateVhalHeartBeat(int64_t value); 215 void checkVhalHealth(); 216 void terminateVhal(); 217 218 using Processor = 219 std::function<void(std::vector<ClientInfo>&, std::vector<ClientInfo>::const_iterator)>; 220 bool findClientAndProcessLocked(const std::vector<TimeoutLength> timeouts, 221 const ClientInfo& clientInfo, const Processor& processor); 222 bool findClientAndProcessLocked(const std::vector<TimeoutLength> timeouts, 223 const android::sp<android::IBinder> binder, 224 const Processor& processor); 225 226 private: 227 android::sp<Looper> mHandlerLooper; 228 android::sp<MessageHandlerImpl> mMessageHandler; 229 android::Mutex mMutex; 230 std::unordered_map<TimeoutLength, std::vector<ClientInfo>> mClients GUARDED_BY(mMutex); 231 std::unordered_map<TimeoutLength, PingedClientMap> mPingedClients GUARDED_BY(mMutex); 232 std::unordered_set<userid_t> mStoppedUserIds GUARDED_BY(mMutex); 233 android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor> mMonitor 234 GUARDED_BY(mMutex); 235 bool mIsEnabled GUARDED_BY(mMutex); 236 // mLastSessionId is accessed only within main thread. No need for mutual-exclusion. 237 int32_t mLastSessionId; 238 bool mServiceStarted; 239 android::sp<android::hardware::automotive::vehicle::V2_0::IVehicle> mVhalService 240 GUARDED_BY(mMutex); 241 android::sp<BinderDeathRecipient> mBinderDeathRecipient; 242 android::sp<HidlDeathRecipient> mHidlDeathRecipient; 243 std::unordered_set<android::hardware::automotive::vehicle::V2_0::VehicleProperty> 244 mNotSupportedVhalProperties; 245 android::sp<PropertyChangeListener> mPropertyChangeListener; 246 HeartBeat mVhalHeartBeat GUARDED_BY(mMutex); 247 android::sp<IWatchdogServiceHelper> mWatchdogServiceHelper GUARDED_BY(mMutex); 248 }; 249 250 } // namespace watchdog 251 } // namespace automotive 252 } // namespace android 253 254 #endif // CPP_WATCHDOG_SERVER_SRC_WATCHDOGPROCESSSERVICE_H_ 255