1 /* 2 * Copyright (C) 2017 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 STATS_SERVICE_H 18 #define STATS_SERVICE_H 19 20 #include <aidl/android/os/BnStatsd.h> 21 #include <aidl/android/os/IPendingIntentRef.h> 22 #include <aidl/android/os/IPullAtomCallback.h> 23 #include <gtest/gtest_prod.h> 24 #include <utils/Looper.h> 25 26 #include <mutex> 27 28 #include "StatsLogProcessor.h" 29 #include "anomaly/AlarmMonitor.h" 30 #include "config/ConfigManager.h" 31 #include "external/StatsPullerManager.h" 32 #include "logd/LogEventQueue.h" 33 #include "packages/UidMap.h" 34 #include "shell/ShellSubscriber.h" 35 #include "statscompanion_util.h" 36 #include "utils/MultiConditionTrigger.h" 37 38 using namespace android; 39 using namespace android::os; 40 using namespace std; 41 42 using Status = ::ndk::ScopedAStatus; 43 using aidl::android::os::BnStatsd; 44 using aidl::android::os::IPendingIntentRef; 45 using aidl::android::os::IPullAtomCallback; 46 using ::ndk::ScopedAIBinder_DeathRecipient; 47 using ::ndk::ScopedFileDescriptor; 48 using std::shared_ptr; 49 50 namespace android { 51 namespace os { 52 namespace statsd { 53 54 class StatsService : public BnStatsd { 55 public: 56 StatsService(const sp<Looper>& handlerLooper, std::shared_ptr<LogEventQueue> queue); 57 virtual ~StatsService(); 58 59 /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */ 60 const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5; 61 62 virtual status_t dump(int fd, const char** args, uint32_t numArgs) override; 63 virtual status_t handleShellCommand(int in, int out, int err, const char** argv, 64 uint32_t argc) override; 65 66 virtual Status systemRunning(); 67 virtual Status statsCompanionReady(); 68 virtual Status bootCompleted(); 69 virtual Status informAnomalyAlarmFired(); 70 virtual Status informPollAlarmFired(); 71 virtual Status informAlarmForSubscriberTriggeringFired(); 72 73 virtual Status informAllUidData(const ScopedFileDescriptor& fd); 74 virtual Status informOnePackage(const string& app, int32_t uid, int64_t version, 75 const string& versionString, const string& installer); 76 virtual Status informOnePackageRemoved(const string& app, int32_t uid); 77 virtual Status informDeviceShutdown(); 78 79 /** 80 * Called right before we start processing events. 81 */ 82 void Startup(); 83 84 /** 85 * Called when terminiation signal received. 86 */ 87 void Terminate(); 88 89 /** 90 * Test ONLY interface. In real world, StatsService reads from LogEventQueue. 91 */ 92 virtual void OnLogEvent(LogEvent* event); 93 94 /** 95 * Binder call for clients to request data for this configuration key. 96 */ 97 virtual Status getData(int64_t key, 98 const int32_t callingUid, 99 vector<int8_t>* output) override; 100 101 102 /** 103 * Binder call for clients to get metadata across all configs in statsd. 104 */ 105 virtual Status getMetadata(vector<int8_t>* output) override; 106 107 108 /** 109 * Binder call to let clients send a configuration and indicate they're interested when they 110 * should requestData for this configuration. 111 */ 112 virtual Status addConfiguration(int64_t key, 113 const vector<int8_t>& config, 114 const int32_t callingUid) override; 115 116 /** 117 * Binder call to let clients register the data fetch operation for a configuration. 118 */ 119 virtual Status setDataFetchOperation(int64_t key, 120 const shared_ptr<IPendingIntentRef>& pir, 121 const int32_t callingUid) override; 122 123 /** 124 * Binder call to remove the data fetch operation for the specified config key. 125 */ 126 virtual Status removeDataFetchOperation(int64_t key, 127 const int32_t callingUid) override; 128 129 /** 130 * Binder call to let clients register the active configs changed operation. 131 */ 132 virtual Status setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir, 133 const int32_t callingUid, 134 vector<int64_t>* output) override; 135 136 /** 137 * Binder call to remove the active configs changed operation for the specified package.. 138 */ 139 virtual Status removeActiveConfigsChangedOperation(const int32_t callingUid) override; 140 /** 141 * Binder call to allow clients to remove the specified configuration. 142 */ 143 virtual Status removeConfiguration(int64_t key, 144 const int32_t callingUid) override; 145 146 /** 147 * Binder call to associate the given config's subscriberId with the given pendingIntentRef. 148 */ 149 virtual Status setBroadcastSubscriber(int64_t configId, 150 int64_t subscriberId, 151 const shared_ptr<IPendingIntentRef>& pir, 152 const int32_t callingUid) override; 153 154 /** 155 * Binder call to unassociate the given config's subscriberId with any pendingIntentRef. 156 */ 157 virtual Status unsetBroadcastSubscriber(int64_t configId, 158 int64_t subscriberId, 159 const int32_t callingUid) override; 160 161 /** Inform statsCompanion that statsd is ready. */ 162 virtual void sayHiToStatsCompanion(); 163 164 /** 165 * Binder call to notify statsd that all pullers from boot have been registered. 166 */ 167 virtual Status allPullersFromBootRegistered(); 168 169 /** 170 * Binder call to register a callback function for a pulled atom. 171 */ 172 virtual Status registerPullAtomCallback( 173 int32_t uid, int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis, 174 const std::vector<int32_t>& additiveFields, 175 const shared_ptr<IPullAtomCallback>& pullerCallback) override; 176 177 /** 178 * Binder call to register a callback function for a pulled atom. 179 */ 180 virtual Status registerNativePullAtomCallback( 181 int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis, 182 const std::vector<int32_t>& additiveFields, 183 const shared_ptr<IPullAtomCallback>& pullerCallback) override; 184 185 /** 186 * Binder call to unregister any existing callback for the given uid and atom. 187 */ 188 virtual Status unregisterPullAtomCallback(int32_t uid, int32_t atomTag) override; 189 190 /** 191 * Binder call to unregister any existing callback for the given atom and calling uid. 192 */ 193 virtual Status unregisterNativePullAtomCallback(int32_t atomTag) override; 194 195 /** 196 * Binder call to get registered experiment IDs. 197 */ 198 virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut); 199 200 private: 201 /** 202 * Load system properties at init. 203 */ 204 void init_system_properties(); 205 206 /** 207 * Helper for loading system properties. 208 */ 209 static void init_build_type_callback(void* cookie, const char* name, const char* value, 210 uint32_t serial); 211 212 /** 213 * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto. 214 */ 215 void dumpIncidentSection(int outFd); 216 217 /** 218 * Text or proto output of statsdStats dumpsys. 219 */ 220 void dumpStatsdStats(int outFd, bool verbose, bool proto); 221 222 /** 223 * Print usage information for the commands 224 */ 225 void print_cmd_help(int out); 226 227 /* Runs on its dedicated thread to process pushed stats event from socket. */ 228 void readLogs(); 229 230 /** 231 * Trigger a broadcast. 232 */ 233 status_t cmd_trigger_broadcast(int outFd, Vector<String8>& args); 234 235 236 /** 237 * Trigger an active configs changed broadcast. 238 */ 239 status_t cmd_trigger_active_config_broadcast(int outFd, Vector<String8>& args); 240 241 /** 242 * Handle the config sub-command. 243 */ 244 status_t cmd_config(int inFd, int outFd, int err, Vector<String8>& args); 245 246 /** 247 * Prints some basic stats to std out. 248 */ 249 status_t cmd_print_stats(int outFd, const Vector<String8>& args); 250 251 /** 252 * Print the event log. 253 */ 254 status_t cmd_dump_report(int outFd, const Vector<String8>& args); 255 256 /** 257 * Print the mapping of uids to package names. 258 */ 259 status_t cmd_print_uid_map(int outFd, const Vector<String8>& args); 260 261 /** 262 * Flush the data to disk. 263 */ 264 status_t cmd_write_data_to_disk(int outFd); 265 266 /** 267 * Write an AppBreadcrumbReported event to the StatsLog buffer, as if calling 268 * StatsLog.write(APP_BREADCRUMB_REPORTED). 269 */ 270 status_t cmd_log_app_breadcrumb(int outFd, const Vector<String8>& args); 271 272 /** 273 * Write an BinaryPushStateChanged event, as if calling StatsLog.logBinaryPushStateChanged(). 274 */ 275 status_t cmd_log_binary_push(int outFd, const Vector<String8>& args); 276 277 /** 278 * Print contents of a pulled metrics source. 279 */ 280 status_t cmd_print_pulled_metrics(int outFd, const Vector<String8>& args); 281 282 /** 283 * Removes all configs stored on disk and on memory. 284 */ 285 status_t cmd_remove_all_configs(int outFd); 286 287 /* 288 * Dump memory usage by statsd. 289 */ 290 status_t cmd_dump_memory_info(int outFd); 291 292 /* 293 * Clear all puller cached data 294 */ 295 status_t cmd_clear_puller_cache(int outFd); 296 297 /** 298 * Print all stats logs received to logcat. 299 */ 300 status_t cmd_print_logs(int outFd, const Vector<String8>& args); 301 302 /** 303 * Writes the value of args[uidArgIndex] into uid. 304 * Returns whether the uid is reasonable (type uid_t) and whether 305 * 1. it is equal to the calling uid, or 306 * 2. the device is mEngBuild, or 307 * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL). 308 */ 309 bool getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid); 310 311 /** 312 * Writes the value of uidSting into uid. 313 * Returns whether the uid is reasonable (type uid_t) and whether 314 * 1. it is equal to the calling uid, or 315 * 2. the device is mEngBuild, or 316 * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL). 317 */ 318 bool getUidFromString(const char* uidString, int32_t& uid); 319 320 /** 321 * Adds a configuration after checking permissions and obtaining UID from binder call. 322 */ 323 bool addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config); 324 325 /** 326 * Update a configuration. 327 */ 328 void set_config(int uid, const string& name, const StatsdConfig& config); 329 330 /** 331 * Death recipient callback that is called when StatsCompanionService dies. 332 * The cookie is a pointer to a StatsService object. 333 */ 334 static void statsCompanionServiceDied(void* cookie); 335 336 /** 337 * Implementation of statsCompanionServiceDied. 338 */ 339 void statsCompanionServiceDiedImpl(); 340 341 /** 342 * Tracks the uid <--> package name mapping. 343 */ 344 sp<UidMap> mUidMap; 345 346 /** 347 * Fetches external metrics 348 */ 349 sp<StatsPullerManager> mPullerManager; 350 351 /** 352 * Tracks the configurations that have been passed to statsd. 353 */ 354 sp<ConfigManager> mConfigManager; 355 356 /** 357 * The metrics recorder. 358 */ 359 sp<StatsLogProcessor> mProcessor; 360 361 /** 362 * The alarm monitor for anomaly detection. 363 */ 364 const sp<AlarmMonitor> mAnomalyAlarmMonitor; 365 366 /** 367 * The alarm monitor for alarms to directly trigger subscriber. 368 */ 369 const sp<AlarmMonitor> mPeriodicAlarmMonitor; 370 371 /** 372 * Whether this is an eng build. 373 */ 374 bool mEngBuild; 375 376 sp<ShellSubscriber> mShellSubscriber; 377 378 /** 379 * Mutex for setting the shell subscriber 380 */ 381 mutable mutex mShellSubscriberMutex; 382 std::shared_ptr<LogEventQueue> mEventQueue; 383 384 MultiConditionTrigger mBootCompleteTrigger; 385 static const inline string kBootCompleteTag = "BOOT_COMPLETE"; 386 static const inline string kUidMapReceivedTag = "UID_MAP"; 387 static const inline string kAllPullersRegisteredTag = "PULLERS_REGISTERED"; 388 389 ScopedAIBinder_DeathRecipient mStatsCompanionServiceDeathRecipient; 390 391 FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart); 392 FRIEND_TEST(StatsServiceTest, TestAddConfig_simple); 393 FRIEND_TEST(StatsServiceTest, TestAddConfig_empty); 394 FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid); 395 FRIEND_TEST(StatsServiceTest, TestGetUidFromArgs); 396 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp); 397 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot); 398 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade); 399 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval); 400 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit); 401 FRIEND_TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket); 402 FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket); 403 FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket); 404 FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket); 405 FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket); 406 FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket); 407 }; 408 409 } // namespace statsd 410 } // namespace os 411 } // namespace android 412 413 #endif // STATS_SERVICE_H 414