• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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