• 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/chrono_utils.h>
21 #include <android-base/result.h>
22 #include <android/automotive/watchdog/ICarWatchdogClient.h>
23 #include <android/automotive/watchdog/internal/ICarWatchdogMonitor.h>
24 #include <android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.h>
25 #include <android/automotive/watchdog/internal/PowerCycle.h>
26 #include <android/automotive/watchdog/internal/ProcessIdentifier.h>
27 #include <android/automotive/watchdog/internal/UserState.h>
28 #include <binder/IBinder.h>
29 #include <binder/Status.h>
30 #include <cutils/multiuser.h>
31 #include <utils/Looper.h>
32 #include <utils/Mutex.h>
33 #include <utils/String16.h>
34 #include <utils/StrongPointer.h>
35 #include <utils/Vector.h>
36 
37 #include <IVhalClient.h>
38 #include <VehicleHalTypes.h>
39 
40 #include <optional>
41 #include <unordered_map>
42 #include <unordered_set>
43 #include <vector>
44 
45 namespace android {
46 namespace automotive {
47 namespace watchdog {
48 
49 // Forward declaration for testing use only.
50 namespace internal {
51 
52 class WatchdogProcessServicePeer;
53 
54 }  // namespace internal
55 
56 class WatchdogServiceHelperInterface;
57 
58 class WatchdogProcessServiceInterface : public android::RefBase {
59 public:
60     virtual android::base::Result<void> start() = 0;
61     virtual void terminate() = 0;
62     virtual android::base::Result<void> dump(int fd,
63                                              const android::Vector<android::String16>& args) = 0;
64     virtual void doHealthCheck(int what) = 0;
65 
66     virtual android::base::Result<void> registerWatchdogServiceHelper(
67             const android::sp<WatchdogServiceHelperInterface>& helper) = 0;
68 
69     virtual android::binder::Status registerClient(const android::sp<ICarWatchdogClient>& client,
70                                                    TimeoutLength timeout) = 0;
71     virtual android::binder::Status unregisterClient(
72             const android::sp<ICarWatchdogClient>& client) = 0;
73     virtual android::binder::Status registerCarWatchdogService(
74             const android::sp<IBinder>& binder) = 0;
75     virtual void unregisterCarWatchdogService(const android::sp<IBinder>& binder) = 0;
76     virtual android::binder::Status registerMonitor(
77             const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&
78                     monitor) = 0;
79     virtual android::binder::Status unregisterMonitor(
80             const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&
81                     monitor) = 0;
82     virtual android::binder::Status tellClientAlive(const android::sp<ICarWatchdogClient>& client,
83                                                     int32_t sessionId) = 0;
84     virtual android::binder::Status tellCarWatchdogServiceAlive(
85             const android::sp<
86                     android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>& service,
87             const std::vector<android::automotive::watchdog::internal::ProcessIdentifier>&
88                     clientsNotResponding,
89             int32_t sessionId) = 0;
90     virtual android::binder::Status tellDumpFinished(
91             const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&
92                     monitor,
93             const android::automotive::watchdog::internal::ProcessIdentifier&
94                     processIdentifier) = 0;
95     virtual void setEnabled(bool isEnabled) = 0;
96     virtual void onUserStateChange(userid_t userId, bool isStarted) = 0;
97 };
98 
99 class WatchdogProcessService final : public WatchdogProcessServiceInterface {
100 public:
101     explicit WatchdogProcessService(const android::sp<Looper>& handlerLooper);
~WatchdogProcessService()102     ~WatchdogProcessService() { terminate(); }
103 
104     android::base::Result<void> start();
105     void terminate();
106     virtual android::base::Result<void> dump(int fd,
107                                              const android::Vector<android::String16>& args);
108     void doHealthCheck(int what);
109 
110     virtual android::base::Result<void> registerWatchdogServiceHelper(
111             const android::sp<WatchdogServiceHelperInterface>& helper);
112 
113     virtual android::binder::Status registerClient(const android::sp<ICarWatchdogClient>& client,
114                                                    TimeoutLength timeout);
115     virtual android::binder::Status unregisterClient(const android::sp<ICarWatchdogClient>& client);
116     virtual android::binder::Status registerCarWatchdogService(const android::sp<IBinder>& binder);
117     virtual void unregisterCarWatchdogService(const android::sp<IBinder>& binder);
118     virtual android::binder::Status registerMonitor(
119             const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&
120                     monitor);
121     virtual android::binder::Status unregisterMonitor(
122             const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&
123                     monitor);
124     virtual android::binder::Status tellClientAlive(const android::sp<ICarWatchdogClient>& client,
125                                                     int32_t sessionId);
126     virtual android::binder::Status tellCarWatchdogServiceAlive(
127             const android::sp<
128                     android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>& service,
129             const std::vector<android::automotive::watchdog::internal::ProcessIdentifier>&
130                     clientsNotResponding,
131             int32_t sessionId);
132     virtual android::binder::Status tellDumpFinished(
133             const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&
134                     monitor,
135             const android::automotive::watchdog::internal::ProcessIdentifier& processIdentifier);
136     virtual void setEnabled(bool isEnabled);
137     virtual void onUserStateChange(userid_t userId, bool isStarted);
138 
139 private:
140     enum ClientType {
141         Regular,
142         Service,
143     };
144 
145     class ClientInfo {
146     public:
ClientInfo(const android::sp<ICarWatchdogClient> & client,pid_t pid,userid_t userId,uint64_t startTimeMillis)147         ClientInfo(const android::sp<ICarWatchdogClient>& client, pid_t pid, userid_t userId,
148                    uint64_t startTimeMillis) :
149               pid(pid),
150               userId(userId),
151               startTimeMillis(startTimeMillis),
152               type(ClientType::Regular),
153               client(client) {}
ClientInfo(const android::sp<WatchdogServiceHelperInterface> & helper,const android::sp<android::IBinder> & binder,pid_t pid,userid_t userId,uint64_t startTimeMillis)154         ClientInfo(const android::sp<WatchdogServiceHelperInterface>& helper,
155                    const android::sp<android::IBinder>& binder, pid_t pid, userid_t userId,
156                    uint64_t startTimeMillis) :
157               pid(pid),
158               userId(userId),
159               startTimeMillis(startTimeMillis),
160               type(ClientType::Service),
161               watchdogServiceHelper(helper),
162               watchdogServiceBinder(binder) {}
163 
164         std::string toString() const;
165         status_t linkToDeath(const android::sp<android::IBinder::DeathRecipient>& recipient) const;
166         status_t unlinkToDeath(
167                 const android::wp<android::IBinder::DeathRecipient>& recipient) const;
168         android::binder::Status checkIfAlive(TimeoutLength timeout) const;
169         android::binder::Status prepareProcessTermination() const;
170         bool operator!=(const ClientInfo& clientInfo) const {
171             return getBinder() != clientInfo.getBinder() || type != clientInfo.type;
172         }
matchesBinder(const android::sp<android::IBinder> & binder)173         bool matchesBinder(const android::sp<android::IBinder>& binder) const {
174             return binder == getBinder();
175         }
176 
177         pid_t pid;
178         userid_t userId;
179         int64_t startTimeMillis;
180         int sessionId;
181 
182     private:
183         android::sp<android::IBinder> getBinder() const;
184 
185         ClientType type;
186         android::sp<ICarWatchdogClient> client = nullptr;
187         android::sp<WatchdogServiceHelperInterface> watchdogServiceHelper = nullptr;
188         android::sp<IBinder> watchdogServiceBinder = nullptr;
189     };
190 
191     struct HeartBeat {
192         int64_t eventTime;
193         int64_t value;
194     };
195 
196     typedef std::unordered_map<int, ClientInfo> PingedClientMap;
197 
198     class BinderDeathRecipient final : public android::IBinder::DeathRecipient {
199     public:
200         explicit BinderDeathRecipient(const android::sp<WatchdogProcessService>& service);
201 
202         void binderDied(const android::wp<android::IBinder>& who) override;
203 
204     private:
205         android::sp<WatchdogProcessService> mService;
206     };
207 
208     class PropertyChangeListener final :
209           public android::frameworks::automotive::vhal::ISubscriptionCallback {
210     public:
211         explicit PropertyChangeListener(const android::sp<WatchdogProcessService>& service);
212 
213         void onPropertyEvent(const std::vector<
214                              std::unique_ptr<android::frameworks::automotive::vhal::IHalPropValue>>&
215                                      values) override;
216 
217         void onPropertySetError(
218                 const std::vector<android::frameworks::automotive::vhal::HalPropError>& errors)
219                 override;
220 
221     private:
222         android::sp<WatchdogProcessService> mService;
223     };
224 
225     class MessageHandlerImpl final : public MessageHandler {
226     public:
227         explicit MessageHandlerImpl(const android::sp<WatchdogProcessService>& service);
228 
229         void handleMessage(const Message& message) override;
230 
231     private:
232         android::sp<WatchdogProcessService> mService;
233     };
234 
235 private:
236     android::binder::Status registerClient(const ClientInfo& clientInfo, TimeoutLength timeout);
237     android::binder::Status unregisterClientLocked(const std::vector<TimeoutLength>& timeouts,
238                                                    android::sp<IBinder> binder,
239                                                    ClientType clientType);
240     android::binder::Status tellClientAliveLocked(const android::sp<android::IBinder>& binder,
241                                                   int32_t sessionId);
242     android::base::Result<void> startHealthCheckingLocked(TimeoutLength timeout);
243     android::base::Result<void> dumpAndKillClientsIfNotResponding(TimeoutLength timeout);
244     android::base::Result<void> dumpAndKillAllProcesses(
245             const std::vector<android::automotive::watchdog::internal::ProcessIdentifier>&
246                     processesNotResponding,
247             bool reportToVhal);
248     int32_t getNewSessionId();
249     android::base::Result<void> updateVhal(
250             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
251     android::base::Result<void> connectToVhalLocked();
252     void subscribeToVhalHeartBeatLocked();
253     bool cacheVhalProcessIdentifier();
254     void reportWatchdogAliveToVhal();
255     void reportTerminatedProcessToVhal(
256             const std::vector<android::automotive::watchdog::internal::ProcessIdentifier>&
257                     processesNotResponding);
258     android::base::Result<std::string> readProcCmdLine(int32_t pid);
259     void handleBinderDeath(const android::wp<android::IBinder>& who);
260     void handleVhalDeath();
261     void queryVhalPropertiesLocked();
262     bool isVhalPropertySupportedLocked(
263             aidl::android::hardware::automotive::vehicle::VehicleProperty propId);
264     void updateVhalHeartBeat(int64_t value);
265     void checkVhalHealth();
266     void terminateVhal();
267 
268     using Processor =
269             std::function<void(std::vector<ClientInfo>&, std::vector<ClientInfo>::const_iterator)>;
270     bool findClientAndProcessLocked(const std::vector<TimeoutLength> timeouts,
271                                     const ClientInfo& clientInfo, const Processor& processor);
272     bool findClientAndProcessLocked(const std::vector<TimeoutLength> timeouts,
273                                     const android::sp<android::IBinder> binder,
274                                     const Processor& processor);
275     std::chrono::nanoseconds getTimeoutDurationNs(const TimeoutLength& timeout);
276 
277 private:
278     android::sp<Looper> mHandlerLooper;
279     android::sp<MessageHandlerImpl> mMessageHandler;
280     std::unordered_set<aidl::android::hardware::automotive::vehicle::VehicleProperty>
281             mNotSupportedVhalProperties;
282     std::shared_ptr<PropertyChangeListener> mPropertyChangeListener;
283     // mLastSessionId is accessed only within main thread. No need for mutual-exclusion.
284     int32_t mLastSessionId;
285     bool mServiceStarted;
286     std::chrono::milliseconds mVhalHealthCheckWindowMs;
287     std::optional<std::chrono::nanoseconds> mOverriddenClientHealthCheckWindowNs;
288     std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient::OnBinderDiedCallbackFunc>
289             mOnBinderDiedCallback;
290     std::function<int64_t(pid_t)> mGetStartTimeForPidFunc;
291 
292     android::Mutex mMutex;
293     std::unordered_map<TimeoutLength, std::vector<ClientInfo>> mClients GUARDED_BY(mMutex);
294     std::unordered_map<TimeoutLength, PingedClientMap> mPingedClients GUARDED_BY(mMutex);
295     std::unordered_set<userid_t> mStoppedUserIds GUARDED_BY(mMutex);
296     android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor> mMonitor
297             GUARDED_BY(mMutex);
298     bool mIsEnabled GUARDED_BY(mMutex);
299     std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> mVhalService
300             GUARDED_BY(mMutex);
301     std::optional<android::automotive::watchdog::internal::ProcessIdentifier> mVhalProcessIdentifier
302             GUARDED_BY(mMutex);
303     HeartBeat mVhalHeartBeat GUARDED_BY(mMutex);
304     android::sp<WatchdogServiceHelperInterface> mWatchdogServiceHelper GUARDED_BY(mMutex);
305     android::sp<BinderDeathRecipient> mBinderDeathRecipient GUARDED_BY(mMutex);
306 
307     // For unit tests.
308     friend class internal::WatchdogProcessServicePeer;
309 };
310 
311 }  // namespace watchdog
312 }  // namespace automotive
313 }  // namespace android
314 
315 #endif  // CPP_WATCHDOG_SERVER_SRC_WATCHDOGPROCESSSERVICE_H_
316