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 #pragma once
18 
19 #include "AIBinderDeathRegistrationWrapper.h"
20 
21 #include <aidl/android/automotive/watchdog/ICarWatchdogClient.h>
22 #include <aidl/android/automotive/watchdog/TimeoutLength.h>
23 #include <aidl/android/automotive/watchdog/internal/ICarWatchdogMonitor.h>
24 #include <aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.h>
25 #include <aidl/android/automotive/watchdog/internal/ProcessIdentifier.h>
26 #include <android-base/chrono_utils.h>
27 #include <android-base/result.h>
28 #include <android/binder_auto_utils.h>
29 #include <android/hidl/manager/1.0/IServiceManager.h>
30 #include <android/util/ProtoOutputStream.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 class PackageInfoResolverInterface;
60 
61 class WatchdogProcessServiceInterface : virtual public android::RefBase {
62 public:
63     virtual android::base::Result<void> start() = 0;
64     virtual void terminate() = 0;
65     virtual void onDump(int fd) = 0;
66     virtual void onDumpProto(android::util::ProtoOutputStream& outProto) = 0;
67     virtual void doHealthCheck(int what) = 0;
68     virtual void handleBinderDeath(void* cookie) = 0;
69     virtual ndk::ScopedAStatus registerClient(
70             const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client,
71             aidl::android::automotive::watchdog::TimeoutLength timeout) = 0;
72     virtual ndk::ScopedAStatus unregisterClient(
73             const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>&
74                     client) = 0;
75     virtual ndk::ScopedAStatus registerCarWatchdogService(
76             const ndk::SpAIBinder& binder,
77             const android::sp<WatchdogServiceHelperInterface>& helper) = 0;
78     virtual void unregisterCarWatchdogService(const ndk::SpAIBinder& binder) = 0;
79     virtual ndk::ScopedAStatus registerMonitor(
80             const std::shared_ptr<
81                     aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>&
82                     monitor) = 0;
83     virtual ndk::ScopedAStatus unregisterMonitor(
84             const std::shared_ptr<
85                     aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>&
86                     monitor) = 0;
87     virtual ndk::ScopedAStatus tellClientAlive(
88             const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client,
89             int32_t sessionId) = 0;
90     virtual ndk::ScopedAStatus tellCarWatchdogServiceAlive(
91             const std::shared_ptr<
92                     aidl::android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>&
93                     service,
94             const std::vector<aidl::android::automotive::watchdog::internal::ProcessIdentifier>&
95                     clientsNotResponding,
96             int32_t sessionId) = 0;
97     virtual ndk::ScopedAStatus tellDumpFinished(
98             const std::shared_ptr<
99                     aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor,
100             const aidl::android::automotive::watchdog::internal::ProcessIdentifier&
101                     processIdentifier) = 0;
102     virtual void setEnabled(bool isEnabled) = 0;
103     virtual void onUserStateChange(userid_t userId, bool isStarted) = 0;
104     virtual void onAidlVhalPidFetched(int32_t) = 0;
105 };
106 
107 class WatchdogProcessService final : public WatchdogProcessServiceInterface {
108 public:
109     explicit WatchdogProcessService(const android::sp<Looper>& handlerLooper);
110     WatchdogProcessService(
111             const std::function<std::shared_ptr<
112                     android::frameworks::automotive::vhal::IVhalClient>()>& tryCreateVhalClientFunc,
113             const std::function<android::sp<android::hidl::manager::V1_0::IServiceManager>()>&
114                     tryGetHidlServiceManagerFunc,
115             const std::function<int64_t(pid_t)>& getStartTimeForPidFunc,
116             const std::chrono::nanoseconds& vhalPidCachingRetryDelayNs,
117             const sp<Looper>& handlerLooper,
118             const sp<AIBinderDeathRegistrationWrapperInterface>& deathRegistrationWrapper);
119     ~WatchdogProcessService();
120 
121     android::base::Result<void> start() override;
122     void terminate() override;
123     void onDump(int fd) override;
124     void onDumpProto(util::ProtoOutputStream& outProto) override;
125     void doHealthCheck(int what) override;
126     void handleBinderDeath(void* cookie) override;
127     ndk::ScopedAStatus registerClient(
128             const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client,
129             aidl::android::automotive::watchdog::TimeoutLength timeout) override;
130     ndk::ScopedAStatus unregisterClient(
131             const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client)
132             override;
133     ndk::ScopedAStatus registerCarWatchdogService(
134             const ndk::SpAIBinder& binder,
135             const android::sp<WatchdogServiceHelperInterface>& helper) override;
136     void unregisterCarWatchdogService(const ndk::SpAIBinder& binder) override;
137     ndk::ScopedAStatus registerMonitor(
138             const std::shared_ptr<
139                     aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor)
140             override;
141     ndk::ScopedAStatus unregisterMonitor(
142             const std::shared_ptr<
143                     aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor)
144             override;
145     ndk::ScopedAStatus tellClientAlive(
146             const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>& client,
147             int32_t sessionId) override;
148     ndk::ScopedAStatus tellCarWatchdogServiceAlive(
149             const std::shared_ptr<
150                     aidl::android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>&
151                     service,
152             const std::vector<aidl::android::automotive::watchdog::internal::ProcessIdentifier>&
153                     clientsNotResponding,
154             int32_t sessionId) override;
155     ndk::ScopedAStatus tellDumpFinished(
156             const std::shared_ptr<
157                     aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor,
158             const aidl::android::automotive::watchdog::internal::ProcessIdentifier&
159                     processIdentifier) override;
160     void setEnabled(bool isEnabled) override;
161     void onUserStateChange(userid_t userId, bool isStarted) override;
162     void onAidlVhalPidFetched(int32_t) override;
163 
164 private:
165     enum ClientType {
166         Regular,
167         Service,
168     };
169 
170     class ClientInfo {
171     public:
ClientInfo(const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient> & client,pid_t pid,userid_t userId,uint64_t startTimeMillis,const WatchdogProcessService & service)172         ClientInfo(const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient>&
173                            client,
174                    pid_t pid, userid_t userId, uint64_t startTimeMillis,
175                    const WatchdogProcessService& service) :
176               kPid(pid),
177               kUserId(userId),
178               kStartTimeMillis(startTimeMillis),
179               kType(ClientType::Regular),
180               kService(service),
181               kClient(client) {}
ClientInfo(const android::sp<WatchdogServiceHelperInterface> & helper,const ndk::SpAIBinder & binder,pid_t pid,userid_t userId,uint64_t startTimeMillis,const WatchdogProcessService & service)182         ClientInfo(const android::sp<WatchdogServiceHelperInterface>& helper,
183                    const ndk::SpAIBinder& binder, pid_t pid, userid_t userId,
184                    uint64_t startTimeMillis, const WatchdogProcessService& service) :
185               kPid(pid),
186               kUserId(userId),
187               kStartTimeMillis(startTimeMillis),
188               kType(ClientType::Service),
189               kService(service),
190               kWatchdogServiceHelper(helper),
191               kWatchdogServiceBinder(binder) {}
192 
193         std::string toString() const;
194         AIBinder* getAIBinder() const;
195         ndk::ScopedAStatus linkToDeath(AIBinder_DeathRecipient* recipient) const;
196         ndk::ScopedAStatus unlinkToDeath(AIBinder_DeathRecipient* recipient) const;
197         ndk::ScopedAStatus checkIfAlive(
198                 aidl::android::automotive::watchdog::TimeoutLength timeout) const;
199         ndk::ScopedAStatus prepareProcessTermination() const;
200 
201         const pid_t kPid;
202         const userid_t kUserId;
203         const int64_t kStartTimeMillis;
204         const ClientType kType;
205         const WatchdogProcessService& kService;
206         const std::shared_ptr<aidl::android::automotive::watchdog::ICarWatchdogClient> kClient;
207         const android::sp<WatchdogServiceHelperInterface> kWatchdogServiceHelper;
208         const ndk::SpAIBinder kWatchdogServiceBinder;
209 
210         int sessionId;
211         std::string packageName;
212     };
213 
214     struct HeartBeat {
215         int64_t eventTime;
216         int64_t value;
217     };
218 
219     typedef std::unordered_map<int, ClientInfo> PingedClientMap;
220 
221     class PropertyChangeListener final :
222           public android::frameworks::automotive::vhal::ISubscriptionCallback {
223     public:
PropertyChangeListener(const android::sp<WatchdogProcessService> & service)224         explicit PropertyChangeListener(const android::sp<WatchdogProcessService>& service) :
225               kService(service) {}
226 
227         void onPropertyEvent(const std::vector<
228                              std::unique_ptr<android::frameworks::automotive::vhal::IHalPropValue>>&
229                                      values) override;
230 
231         void onPropertySetError(
232                 const std::vector<android::frameworks::automotive::vhal::HalPropError>& errors)
233                 override;
234 
235     private:
236         const android::sp<WatchdogProcessService> kService;
237     };
238 
239     class MessageHandlerImpl final : public MessageHandler {
240     public:
MessageHandlerImpl(const android::sp<WatchdogProcessService> & service)241         explicit MessageHandlerImpl(const android::sp<WatchdogProcessService>& service) :
242               kService(service) {}
243 
244         void handleMessage(const Message& message) override;
245 
246     private:
247         const android::sp<WatchdogProcessService> kService;
248     };
249 
250 private:
251     android::base::Result<void> registerClient(
252             const ClientInfo& clientInfo,
253             aidl::android::automotive::watchdog::TimeoutLength timeout);
254     ndk::ScopedAStatus unregisterClientLocked(
255             const std::vector<aidl::android::automotive::watchdog::TimeoutLength>& timeouts,
256             const ndk::SpAIBinder& binder, ClientType clientType);
257     ndk::ScopedAStatus tellClientAliveLocked(const ndk::SpAIBinder& binder, int32_t sessionId);
258     android::base::Result<void> startHealthCheckingLocked(
259             aidl::android::automotive::watchdog::TimeoutLength timeout);
260     android::base::Result<void> dumpAndKillClientsIfNotResponding(
261             aidl::android::automotive::watchdog::TimeoutLength timeout);
262     android::base::Result<void> dumpAndKillAllProcesses(
263             const std::vector<aidl::android::automotive::watchdog::internal::ProcessIdentifier>&
264                     processesNotResponding,
265             bool reportToVhal);
266     int32_t getNewSessionId();
267     android::base::Result<void> updateVhal(
268             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
269     android::base::Result<void> connectToVhal();
270     void subscribeToVhalHeartBeat();
271     const sp<WatchdogServiceHelperInterface> getWatchdogServiceHelperLocked();
272     void cacheVhalProcessIdentifier();
273     void cacheVhalProcessIdentifierForPid(int32_t pid);
274     android::base::Result<void> requestAidlVhalPid();
275     void reportWatchdogAliveToVhal();
276     void reportTerminatedProcessToVhal(
277             const std::vector<aidl::android::automotive::watchdog::internal::ProcessIdentifier>&
278                     processesNotResponding);
279     android::base::Result<std::string> readProcCmdLine(int32_t pid);
280     void handleVhalDeath();
281     void queryVhalProperties();
282     void updateVhalHeartBeat(int64_t value);
283     void checkVhalHealth();
284     void resetVhalInfoLocked();
285     void terminateVhal();
286 
287     using ClientInfoMap = std::unordered_map<uintptr_t, ClientInfo>;
288     using Processor = std::function<void(ClientInfoMap&, ClientInfoMap::const_iterator)>;
289     bool findClientAndProcessLocked(
290             const std::vector<aidl::android::automotive::watchdog::TimeoutLength>& timeouts,
291             AIBinder* binder, const Processor& processor);
292     bool findClientAndProcessLocked(
293             const std::vector<aidl::android::automotive::watchdog::TimeoutLength>& timeouts,
294             uintptr_t binderPtrId, const Processor& processor);
295     std::chrono::nanoseconds getTimeoutDurationNs(
296             const aidl::android::automotive::watchdog::TimeoutLength& timeout);
297     static int toProtoClientType(ClientType clientType);
298 
299 private:
300     const std::function<std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient>()>
301             kTryCreateVhalClientFunc;
302     const std::function<android::sp<android::hidl::manager::V1_0::IServiceManager>()>
303             kTryGetHidlServiceManagerFunc;
304     const std::function<int64_t(pid_t)> kGetStartTimeForPidFunc;
305     const std::chrono::nanoseconds kVhalPidCachingRetryDelayNs;
306 
307     android::sp<Looper> mHandlerLooper;
308     android::sp<MessageHandlerImpl> mMessageHandler;
309     ndk::ScopedAIBinder_DeathRecipient mClientBinderDeathRecipient;
310     std::unordered_set<aidl::android::hardware::automotive::vehicle::VehicleProperty>
311             mNotSupportedVhalProperties;
312     std::shared_ptr<PropertyChangeListener> mPropertyChangeListener;
313     // mLastSessionId is accessed only within main thread. No need for mutual-exclusion.
314     int32_t mLastSessionId;
315     bool mServiceStarted;
316     std::chrono::milliseconds mVhalHealthCheckWindowMillis;
317     std::optional<std::chrono::nanoseconds> mOverriddenClientHealthCheckWindowNs;
318     std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient::OnBinderDiedCallbackFunc>
319             mVhalBinderDiedCallback;
320     android::sp<AIBinderDeathRegistrationWrapperInterface> mDeathRegistrationWrapper;
321     std::shared_ptr<PackageInfoResolverInterface> mPackageInfoResolver;
322 
323     android::Mutex mMutex;
324 
325     std::unordered_map<aidl::android::automotive::watchdog::TimeoutLength, ClientInfoMap>
326             mClientsByTimeout GUARDED_BY(mMutex);
327     std::unordered_map<aidl::android::automotive::watchdog::TimeoutLength, PingedClientMap>
328             mPingedClients GUARDED_BY(mMutex);
329     std::unordered_set<userid_t> mStoppedUserIds GUARDED_BY(mMutex);
330     std::shared_ptr<aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor> mMonitor
331             GUARDED_BY(mMutex);
332     bool mIsEnabled GUARDED_BY(mMutex);
333     std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> mVhalService
334             GUARDED_BY(mMutex);
335     std::optional<aidl::android::automotive::watchdog::internal::ProcessIdentifier>
336             mVhalProcessIdentifier GUARDED_BY(mMutex);
337     int32_t mTotalVhalPidCachingAttempts GUARDED_BY(mMutex);
338     HeartBeat mVhalHeartBeat GUARDED_BY(mMutex);
339 
340     // For unit tests.
341     friend class internal::WatchdogProcessServicePeer;
342 };
343 
344 }  // namespace watchdog
345 }  // namespace automotive
346 }  // namespace android
347