1 /*
2  * Copyright (C) 2022 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 CHRE_CORE_SYSTEM_HEALTH_MONITOR_H_
18 #define CHRE_CORE_SYSTEM_HEALTH_MONITOR_H_
19 
20 #include <cstdint>
21 
22 #include "chre/platform/assert.h"
23 #include "chre/platform/log.h"
24 #include "chre/util/enum.h"
25 #include "chre/util/non_copyable.h"
26 
27 namespace chre {
28 
29 /**
30  * Types of different health check id
31  * User should consider adding a new check id if current id does not describe
32  * the case accurately
33  *
34  * The goal of this enum class is to be granular enough to produce useful debug
35  * information and metric report
36  */
37 enum class HealthCheckId : uint16_t {
38   WifiScanResponseTimeout = 0,
39   WifiConfigureScanMonitorTimeout = 1,
40   WifiRequestRangingTimeout = 2,
41   UnexpectedWifiPalCallback = 3,
42 
43   //! Must be last
44   NumCheckIds
45 };
46 
47 class SystemHealthMonitor : public NonCopyable {
48  public:
49   /**
50    * Configures if onCheckFailureImpl() should crash
51    *
52    * @param enable true if onCheckFailureImpl() should log the error and crash,
53    * false if onCheckFailureImpl() should only log the error
54    */
setFatalErrorOnCheckFailure(bool enable)55   inline void setFatalErrorOnCheckFailure(bool enable) {
56     mShouldCheckCrash = enable;
57   }
58 
59   /**
60    * Provides a runtime configurable way to call/skip FATAL_ERROR
61    * to prevent crashing on programming errors that are low visibility
62    * to users
63    *
64    * Also provides a counter to log the occurrence of each type of defined
65    * HealthCheckId
66    *
67    * @param condition Boolean expression which evaluates to false in the failure
68    *        case
69    * @param id predefined HealthCheckId used to record occurrence of each
70    * failure
71    */
check(bool condition,HealthCheckId id)72   static inline void check(bool condition, HealthCheckId id) {
73     if (!condition) {
74       SystemHealthMonitor::onFailure(id);
75     }
76   }
77 
78   /**
79    * Similar to check() but should be called when HealthCheck has already failed
80    *
81    * @param id predefined HealthCheckId used to record occurrence of each
82    * failure
83    */
84   static void onFailure(HealthCheckId id);
85 
86  private:
87   bool mShouldCheckCrash = false;
88 
89   /**
90    * Records how many times a check failed on a HealthCheckId
91    */
92   uint16_t mCheckIdOccurrenceCounter[asBaseType(HealthCheckId::NumCheckIds)];
93 
94   /**
95    * Implements the logic once check encountered a false condition
96    * This is needed to prevent the runtime overhead when calling a function
97    * when it is not necessary while also have the ability to modify object
98    * member
99    *
100    *  @param id which HealthCheckId that matches this failure
101    */
102   void onCheckFailureImpl(HealthCheckId id);
103 };
104 
105 }  // namespace chre
106 
107 #endif  // CHRE_CORE_SYSTEM_HEALTH_MONITOR_H_
108