• 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 "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