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 WATCHDOG_SERVER_SRC_WATCHDOGPROCESSSERVICE_H_ 18 #define WATCHDOG_SERVER_SRC_WATCHDOGPROCESSSERVICE_H_ 19 20 #include <android-base/result.h> 21 #include <android/automotive/watchdog/BnCarWatchdog.h> 22 #include <android/automotive/watchdog/PowerCycle.h> 23 #include <android/automotive/watchdog/UserState.h> 24 #include <binder/IBinder.h> 25 #include <binder/Status.h> 26 #include <cutils/multiuser.h> 27 #include <utils/Looper.h> 28 #include <utils/Mutex.h> 29 #include <utils/String16.h> 30 #include <utils/StrongPointer.h> 31 #include <utils/Vector.h> 32 33 #include <unordered_map> 34 #include <unordered_set> 35 #include <vector> 36 37 namespace android { 38 namespace automotive { 39 namespace watchdog { 40 41 class WatchdogProcessService : public IBinder::DeathRecipient { 42 public: 43 explicit WatchdogProcessService(const android::sp<Looper>& handlerLooper); 44 45 virtual android::base::Result<void> dump(int fd, const Vector<String16>& args); 46 47 virtual binder::Status registerClient(const sp<ICarWatchdogClient>& client, 48 TimeoutLength timeout); 49 virtual binder::Status unregisterClient(const sp<ICarWatchdogClient>& client); 50 virtual binder::Status registerMediator(const sp<ICarWatchdogClient>& mediator); 51 virtual binder::Status unregisterMediator(const sp<ICarWatchdogClient>& mediator); 52 virtual binder::Status registerMonitor(const sp<ICarWatchdogMonitor>& monitor); 53 virtual binder::Status unregisterMonitor(const sp<ICarWatchdogMonitor>& monitor); 54 virtual binder::Status tellClientAlive(const sp<ICarWatchdogClient>& client, int32_t sessionId); 55 virtual binder::Status tellMediatorAlive(const sp<ICarWatchdogClient>& mediator, 56 const std::vector<int32_t>& clientsNotResponding, 57 int32_t sessionId); 58 virtual binder::Status tellDumpFinished(const android::sp<ICarWatchdogMonitor>& monitor, 59 int32_t pid); 60 virtual binder::Status notifyPowerCycleChange(PowerCycle cycle); 61 virtual binder::Status notifyUserStateChange(userid_t userId, UserState state); 62 virtual void binderDied(const android::wp<IBinder>& who); 63 64 void doHealthCheck(int what); 65 void terminate(); 66 67 private: 68 enum ClientType { 69 Regular, 70 Mediator, 71 }; 72 73 struct ClientInfo { ClientInfoClientInfo74 ClientInfo(const android::sp<ICarWatchdogClient>& client, pid_t pid, userid_t userId, 75 ClientType type) : 76 client(client), 77 pid(pid), 78 userId(userId), 79 type(type) {} 80 std::string toString(); 81 82 android::sp<ICarWatchdogClient> client; 83 pid_t pid; 84 userid_t userId; 85 int sessionId; 86 ClientType type; 87 }; 88 89 typedef std::unordered_map<int, ClientInfo> PingedClientMap; 90 91 class MessageHandlerImpl : public MessageHandler { 92 public: 93 explicit MessageHandlerImpl(const android::sp<WatchdogProcessService>& service); 94 95 void handleMessage(const Message& message) override; 96 97 private: 98 android::sp<WatchdogProcessService> mService; 99 }; 100 101 private: 102 binder::Status registerClientLocked(const android::sp<ICarWatchdogClient>& client, 103 TimeoutLength timeout, ClientType clientType); 104 binder::Status unregisterClientLocked(const std::vector<TimeoutLength>& timeouts, 105 android::sp<IBinder> binder, ClientType clientType); 106 bool isRegisteredLocked(const android::sp<ICarWatchdogClient>& client); 107 binder::Status tellClientAliveLocked(const android::sp<ICarWatchdogClient>& client, 108 int32_t sessionId); 109 base::Result<void> startHealthCheckingLocked(TimeoutLength timeout); 110 base::Result<void> dumpAndKillClientsIfNotResponding(TimeoutLength timeout); 111 base::Result<void> dumpAndKillAllProcesses(const std::vector<int32_t>& processesNotResponding); 112 int32_t getNewSessionId(); 113 bool isWatchdogEnabled(); 114 115 using Processor = 116 std::function<void(std::vector<ClientInfo>&, std::vector<ClientInfo>::const_iterator)>; 117 bool findClientAndProcessLocked(const std::vector<TimeoutLength> timeouts, 118 const android::sp<IBinder> binder, const Processor& processor); 119 120 private: 121 sp<Looper> mHandlerLooper; 122 android::sp<MessageHandlerImpl> mMessageHandler; 123 Mutex mMutex; 124 std::unordered_map<TimeoutLength, std::vector<ClientInfo>> mClients GUARDED_BY(mMutex); 125 std::unordered_map<TimeoutLength, PingedClientMap> mPingedClients GUARDED_BY(mMutex); 126 std::unordered_set<userid_t> mStoppedUserId GUARDED_BY(mMutex); 127 android::sp<ICarWatchdogMonitor> mMonitor GUARDED_BY(mMutex); 128 bool mWatchdogEnabled GUARDED_BY(mMutex); 129 // mLastSessionId is accessed only within main thread. No need for mutual-exclusion. 130 int32_t mLastSessionId; 131 }; 132 133 } // namespace watchdog 134 } // namespace automotive 135 } // namespace android 136 137 #endif // WATCHDOG_SERVER_SRC_WATCHDOGPROCESSSERVICE_H_ 138