1 /* 2 * Copyright (C) 2015 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 METRICS_METRICS_LIBRARY_H_ 18 #define METRICS_METRICS_LIBRARY_H_ 19 20 #include <sys/types.h> 21 #include <string> 22 #include <unistd.h> 23 24 #include <base/compiler_specific.h> 25 #include <base/files/file_path.h> 26 #include <base/macros.h> 27 #include <binder/IServiceManager.h> 28 #include <gtest/gtest_prod.h> // for FRIEND_TEST 29 30 namespace android { 31 namespace brillo { 32 namespace metrics { 33 class IMetricsd; 34 } // namespace metrics 35 } // namespace brillo 36 } // namespace android 37 38 class MetricsLibraryInterface { 39 public: 40 virtual void Init() = 0; 41 virtual bool AreMetricsEnabled() = 0; 42 virtual bool SendToUMA(const std::string& name, int sample, 43 int min, int max, int nbuckets) = 0; 44 virtual bool SendEnumToUMA(const std::string& name, int sample, int max) = 0; 45 virtual bool SendBoolToUMA(const std::string& name, bool sample) = 0; 46 virtual bool SendSparseToUMA(const std::string& name, int sample) = 0; ~MetricsLibraryInterface()47 virtual ~MetricsLibraryInterface() {} 48 }; 49 50 // Library used to send metrics to Chrome/UMA. 51 class MetricsLibrary : public MetricsLibraryInterface { 52 public: 53 MetricsLibrary(); 54 virtual ~MetricsLibrary(); 55 56 // Initializes the library. 57 void Init() override; 58 59 // Initializes the library and disables the cache of whether or not the 60 // metrics collection is enabled. 61 // By disabling this, we may have to check for the metrics status more often 62 // but the result will never be stale. 63 void InitWithNoCaching(); 64 65 // Returns whether or not the machine is running in guest mode. 66 bool IsGuestMode(); 67 68 // Returns whether or not metrics collection is enabled. 69 bool AreMetricsEnabled() override; 70 71 // Sends histogram data to Chrome for transport to UMA and returns 72 // true on success. This method results in the equivalent of an 73 // asynchronous non-blocking RPC to UMA_HISTOGRAM_CUSTOM_COUNTS 74 // inside Chrome (see base/histogram.h). 75 // 76 // |sample| is the sample value to be recorded (|min| <= |sample| < |max|). 77 // |min| is the minimum value of the histogram samples (|min| > 0). 78 // |max| is the maximum value of the histogram samples. 79 // |nbuckets| is the number of histogram buckets. 80 // [0,min) is the implicit underflow bucket. 81 // [|max|,infinity) is the implicit overflow bucket. 82 // 83 // Note that the memory allocated in Chrome for each histogram is 84 // proportional to the number of buckets. Therefore, it is strongly 85 // recommended to keep this number low (e.g., 50 is normal, while 86 // 100 is high). 87 bool SendToUMA(const std::string& name, int sample, 88 int min, int max, int nbuckets) override; 89 90 // Sends linear histogram data to Chrome for transport to UMA and 91 // returns true on success. This method results in the equivalent of 92 // an asynchronous non-blocking RPC to UMA_HISTOGRAM_ENUMERATION 93 // inside Chrome (see base/histogram.h). 94 // 95 // |sample| is the sample value to be recorded (1 <= |sample| < |max|). 96 // |max| is the maximum value of the histogram samples. 97 // 0 is the implicit underflow bucket. 98 // [|max|,infinity) is the implicit overflow bucket. 99 // 100 // An enumeration histogram requires |max| + 1 number of 101 // buckets. Note that the memory allocated in Chrome for each 102 // histogram is proportional to the number of buckets. Therefore, it 103 // is strongly recommended to keep this number low (e.g., 50 is 104 // normal, while 100 is high). 105 bool SendEnumToUMA(const std::string& name, int sample, int max) override; 106 107 // Specialization of SendEnumToUMA for boolean values. 108 bool SendBoolToUMA(const std::string& name, bool sample) override; 109 110 // Sends sparse histogram sample to Chrome for transport to UMA. Returns 111 // true on success. 112 // 113 // |sample| is the 32-bit integer value to be recorded. 114 bool SendSparseToUMA(const std::string& name, int sample) override; 115 116 // Sends a signal to UMA that a crash of the given |crash_kind| 117 // has occurred. Used by UMA to generate stability statistics. 118 bool SendCrashToUMA(const char *crash_kind); 119 120 // Sends a "generic Chrome OS event" to UMA. This is an event name 121 // that is translated into an enumerated histogram entry. Event names 122 // are added to metrics_library.cc. Optionally, they can be added 123 // to histograms.xml---but part of the reason for this is to simplify 124 // the addition of events (at the cost of having to look them up by 125 // number in the histograms dashboard). 126 bool SendCrosEventToUMA(const std::string& event); 127 128 // Debugging only. 129 // Dumps the histograms aggregated since metricsd started into |dump|. 130 // Returns true iff the dump succeeds. 131 bool GetHistogramsDump(std::string* dump); 132 133 private: 134 friend class CMetricsLibraryTest; 135 friend class MetricsLibraryTest; 136 friend class UploadServiceTest; 137 FRIEND_TEST(MetricsLibraryTest, AreMetricsEnabled); 138 FRIEND_TEST(MetricsLibraryTest, AreMetricsEnabledNoCaching); 139 FRIEND_TEST(MetricsLibraryTest, FormatChromeMessage); 140 FRIEND_TEST(MetricsLibraryTest, FormatChromeMessageTooLong); 141 FRIEND_TEST(MetricsLibraryTest, IsDeviceMounted); 142 FRIEND_TEST(MetricsLibraryTest, SendMessageToChrome); 143 FRIEND_TEST(MetricsLibraryTest, SendMessageToChromeUMAEventsBadFileLocation); 144 145 void InitForTest(const base::FilePath& metrics_directory); 146 147 // Sets |*result| to whether or not the |mounts_file| indicates that 148 // the |device_name| is currently mounted. Uses |buffer| of 149 // |buffer_size| to read the file. Returns false if any error. 150 bool IsDeviceMounted(const char* device_name, 151 const char* mounts_file, 152 char* buffer, int buffer_size, 153 bool* result); 154 155 // Connects to IMetricsd if the proxy does not exist or is not alive. 156 // Don't block if we fail to get the proxy for any reason. 157 bool CheckService(); 158 159 // Time at which we last checked if metrics were enabled. 160 time_t cached_enabled_time_; 161 162 // Cached state of whether or not metrics were enabled. 163 bool cached_enabled_; 164 165 // True iff we should cache the enabled/disabled status. 166 bool use_caching_; 167 168 android::sp<android::IServiceManager> manager_; 169 android::sp<android::brillo::metrics::IMetricsd> metricsd_proxy_; 170 base::FilePath consent_file_; 171 172 DISALLOW_COPY_AND_ASSIGN(MetricsLibrary); 173 }; 174 175 #endif // METRICS_METRICS_LIBRARY_H_ 176