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 <aidl/android/os/IStatsSubscriptionCallback.h> 24 #include <aidl/android/util/PropertyParcel.h> 25 #include <gtest/gtest_prod.h> 26 #include <utils/Looper.h> 27 28 #include <mutex> 29 30 #include "StatsLogProcessor.h" 31 #include "anomaly/AlarmMonitor.h" 32 #include "config/ConfigManager.h" 33 #include "external/StatsPullerManager.h" 34 #include "logd/LogEventQueue.h" 35 #include "packages/UidMap.h" 36 #include "shell/ShellSubscriber.h" 37 #include "statscompanion_util.h" 38 #include "utils/MultiConditionTrigger.h" 39 40 using namespace android; 41 using namespace android::os; 42 using namespace std; 43 44 using ::ndk::SpAIBinder; 45 using Status = ::ndk::ScopedAStatus; 46 using aidl::android::os::BnStatsd; 47 using aidl::android::os::IPendingIntentRef; 48 using aidl::android::os::IPullAtomCallback; 49 using aidl::android::os::IStatsQueryCallback; 50 using aidl::android::os::IStatsSubscriptionCallback; 51 using aidl::android::util::PropertyParcel; 52 using ::ndk::ScopedAIBinder_DeathRecipient; 53 using ::ndk::ScopedFileDescriptor; 54 55 namespace android { 56 namespace os { 57 namespace statsd { 58 59 class StatsService : public BnStatsd { 60 public: 61 StatsService(const sp<UidMap>& uidMap, shared_ptr<LogEventQueue> queue, 62 const std::shared_ptr<LogEventFilter>& logEventFilter); 63 virtual ~StatsService(); 64 65 /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */ 66 const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5; 67 68 virtual status_t dump(int fd, const char** args, uint32_t numArgs) override; 69 virtual status_t handleShellCommand(int in, int out, int err, const char** argv, 70 uint32_t argc) override; 71 72 virtual Status systemRunning(); 73 virtual Status statsCompanionReady(); 74 virtual Status bootCompleted(); 75 virtual Status informAnomalyAlarmFired(); 76 virtual Status informPollAlarmFired(); 77 virtual Status informAlarmForSubscriberTriggeringFired(); 78 79 virtual Status informAllUidData(const ScopedFileDescriptor& fd); 80 virtual Status informOnePackage(const string& app, int32_t uid, int64_t version, 81 const string& versionString, const string& installer, 82 const vector<uint8_t>& certificateHash); 83 virtual Status informOnePackageRemoved(const string& app, int32_t uid); 84 virtual Status informDeviceShutdown(); 85 86 /** 87 * Called right before we start processing events. 88 */ 89 void Startup(); 90 91 /** 92 * Called when terminiation signal received. 93 */ 94 void Terminate(); 95 96 /** 97 * Test ONLY interface. In real world, StatsService reads from LogEventQueue. 98 */ 99 virtual void OnLogEvent(LogEvent* event); 100 101 /** 102 * Binder call for clients to request data for this configuration key. 103 */ 104 virtual Status getData(int64_t key, 105 const int32_t callingUid, 106 vector<uint8_t>* output) override; 107 108 virtual Status getDataFd(int64_t key, const int32_t callingUid, 109 const ScopedFileDescriptor& fd) override; 110 111 /** 112 * Binder call for clients to get metadata across all configs in statsd. 113 */ 114 virtual Status getMetadata(vector<uint8_t>* output) override; 115 116 117 /** 118 * Binder call to let clients send a configuration and indicate they're interested when they 119 * should requestData for this configuration. 120 */ 121 virtual Status addConfiguration(int64_t key, 122 const vector<uint8_t>& config, 123 const int32_t callingUid) override; 124 125 /** 126 * Binder call to let clients register the data fetch operation for a configuration. 127 */ 128 virtual Status setDataFetchOperation(int64_t key, 129 const shared_ptr<IPendingIntentRef>& pir, 130 const int32_t callingUid) override; 131 132 /** 133 * Binder call to remove the data fetch operation for the specified config key. 134 */ 135 virtual Status removeDataFetchOperation(int64_t key, 136 const int32_t callingUid) override; 137 138 /** 139 * Binder call to let clients register the active configs changed operation. 140 */ 141 virtual Status setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir, 142 const int32_t callingUid, 143 vector<int64_t>* output) override; 144 145 /** 146 * Binder call to remove the active configs changed operation for the specified package.. 147 */ 148 virtual Status removeActiveConfigsChangedOperation(int32_t callingUid) override; 149 /** 150 * Binder call to allow clients to remove the specified configuration. 151 */ 152 virtual Status removeConfiguration(int64_t key, 153 const int32_t callingUid) override; 154 155 /** 156 * Binder call to associate the given config's subscriberId with the given pendingIntentRef. 157 */ 158 virtual Status setBroadcastSubscriber(int64_t configId, 159 int64_t subscriberId, 160 const shared_ptr<IPendingIntentRef>& pir, 161 const int32_t callingUid) override; 162 163 /** 164 * Binder call to unassociate the given config's subscriberId with any pendingIntentRef. 165 */ 166 virtual Status unsetBroadcastSubscriber(int64_t configId, 167 int64_t subscriberId, 168 const int32_t callingUid) override; 169 170 /** Inform statsCompanion that statsd is ready. */ 171 virtual void sayHiToStatsCompanion(); 172 173 /** 174 * Binder call to notify statsd that all pullers from boot have been registered. 175 */ 176 virtual Status allPullersFromBootRegistered(); 177 178 /** 179 * Binder call to register a callback function for a pulled atom. 180 */ 181 virtual Status registerPullAtomCallback( 182 int32_t uid, int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis, 183 const vector<int32_t>& additiveFields, 184 const shared_ptr<IPullAtomCallback>& pullerCallback) override; 185 186 /** 187 * Binder call to register a callback function for a pulled atom. 188 */ 189 virtual Status registerNativePullAtomCallback( 190 int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis, 191 const vector<int32_t>& additiveFields, 192 const shared_ptr<IPullAtomCallback>& pullerCallback) override; 193 194 /** 195 * Binder call to unregister any existing callback for the given uid and atom. 196 */ 197 virtual Status unregisterPullAtomCallback(int32_t uid, int32_t atomTag) override; 198 199 /** 200 * Binder call to unregister any existing callback for the given atom and calling uid. 201 */ 202 virtual Status unregisterNativePullAtomCallback(int32_t atomTag) override; 203 204 /** 205 * Binder call to get registered experiment IDs. 206 */ 207 virtual Status getRegisteredExperimentIds(vector<int64_t>* expIdsOut); 208 209 /** 210 * Binder call to update properties in statsd_java namespace. 211 */ 212 virtual Status updateProperties(const vector<PropertyParcel>& properties); 213 214 /** 215 * Binder call to let clients register the restricted metrics changed operation for the given 216 * config and calling uid. 217 */ 218 virtual Status setRestrictedMetricsChangedOperation(const int64_t configKey, 219 const string& configPackage, 220 const shared_ptr<IPendingIntentRef>& pir, 221 const int32_t callingUid, 222 vector<int64_t>* output); 223 224 /** 225 * Binder call to remove the restricted metrics changed operation for the specified config 226 * and calling uid. 227 */ 228 virtual Status removeRestrictedMetricsChangedOperation(const int64_t configKey, 229 const string& configPackage, 230 const int32_t callingUid); 231 232 /** 233 * Binder call to query data in statsd sql store. 234 */ 235 virtual Status querySql(const string& sqlQuery, const int32_t minSqlClientVersion, 236 const optional<vector<uint8_t>>& policyConfig, 237 const shared_ptr<IStatsQueryCallback>& callback, 238 const int64_t configKey, const string& configPackage, 239 const int32_t callingUid); 240 241 /** 242 * Binder call to add a subscription. 243 */ 244 virtual Status addSubscription(const vector<uint8_t>& subscriptionConfig, 245 const shared_ptr<IStatsSubscriptionCallback>& callback) override; 246 247 /** 248 * Binder call to remove a subscription. 249 */ 250 virtual Status removeSubscription( 251 const shared_ptr<IStatsSubscriptionCallback>& callback) override; 252 253 /** 254 * Binder call to flush atom events for a subscription. 255 */ 256 virtual Status flushSubscription( 257 const shared_ptr<IStatsSubscriptionCallback>& callback) override; 258 259 const static int kStatsdInitDelaySecs = 90; 260 261 private: 262 /** 263 * Load system properties at init. 264 */ 265 void init_system_properties(); 266 267 /** 268 * Helper for loading system properties. 269 */ 270 static void init_build_type_callback(void* cookie, const char* name, const char* value, 271 uint32_t serial); 272 273 /** 274 * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto. 275 */ 276 void dumpIncidentSection(int outFd); 277 278 /** 279 * Text or proto output of statsdStats dumpsys. 280 */ 281 void dumpStatsdStats(int outFd, bool verbose, bool proto); 282 283 /** 284 * Print usage information for the commands 285 */ 286 void print_cmd_help(int out); 287 288 /* Runs on its dedicated thread to process pushed stats event from socket. */ 289 void readLogs(); 290 291 /** 292 * Trigger a broadcast. 293 */ 294 status_t cmd_trigger_broadcast(int outFd, Vector<String8>& args); 295 296 297 /** 298 * Trigger an active configs changed broadcast. 299 */ 300 status_t cmd_trigger_active_config_broadcast(int outFd, Vector<String8>& args); 301 302 /** 303 * Handle the config sub-command. 304 */ 305 status_t cmd_config(int inFd, int outFd, int err, Vector<String8>& args); 306 307 /** 308 * Prints some basic stats to std out. 309 */ 310 status_t cmd_print_stats(int outFd, const Vector<String8>& args); 311 312 /** 313 * Print the event log. 314 */ 315 status_t cmd_dump_report(int outFd, const Vector<String8>& args); 316 317 /** 318 * Print the mapping of uids to package names. 319 */ 320 status_t cmd_print_uid_map(int outFd, const Vector<String8>& args); 321 322 /** 323 * Flush the data to disk. 324 */ 325 status_t cmd_write_data_to_disk(int outFd); 326 327 /** 328 * Write an AppBreadcrumbReported event to the StatsLog buffer, as if calling 329 * StatsLog.write(APP_BREADCRUMB_REPORTED). 330 */ 331 status_t cmd_log_app_breadcrumb(int outFd, const Vector<String8>& args); 332 333 /** 334 * Write an BinaryPushStateChanged event, as if calling StatsLog.logBinaryPushStateChanged(). 335 */ 336 status_t cmd_log_binary_push(int outFd, const Vector<String8>& args); 337 338 /** 339 * Print contents of a pulled metrics source. 340 */ 341 status_t cmd_print_pulled_metrics(int outFd, const Vector<String8>& args); 342 343 /** 344 * Removes all configs stored on disk and on memory. 345 */ 346 status_t cmd_remove_all_configs(int outFd); 347 348 /* 349 * Dump memory usage by statsd. 350 */ 351 status_t cmd_dump_memory_info(int outFd); 352 353 /* 354 * Clear all puller cached data 355 */ 356 status_t cmd_clear_puller_cache(int outFd); 357 358 /** 359 * Print all stats logs received to logcat. 360 */ 361 status_t cmd_print_logs(int outFd, const Vector<String8>& args); 362 363 /** 364 * Implementation for request data for the configuration key. 365 */ 366 void getDataChecked(int64_t key, const int32_t callingUid, vector<uint8_t>* output); 367 368 /** 369 * Writes the value of args[uidArgIndex] into uid. 370 * Returns whether the uid is reasonable (type uid_t) and whether 371 * 1. it is equal to the calling uid, or 372 * 2. the device is mEngBuild, or 373 * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL). 374 */ 375 bool getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid); 376 377 /** 378 * Writes the value of uidSting into uid. 379 * Returns whether the uid is reasonable (type uid_t) and whether 380 * 1. it is equal to the calling uid, or 381 * 2. the device is mEngBuild, or 382 * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL). 383 */ 384 bool getUidFromString(const char* uidString, int32_t& uid); 385 386 /** 387 * Adds a configuration after checking permissions and obtaining UID from binder call. 388 */ 389 bool addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config); 390 391 /** 392 * Update a configuration. 393 */ 394 void set_config(int uid, const string& name, const StatsdConfig& config); 395 396 /** 397 * Death recipient callback that is called when StatsCompanionService dies. 398 * The cookie is a pointer to a StatsService object. 399 */ 400 static void statsCompanionServiceDied(void* cookie); 401 402 /** 403 * Implementation of statsCompanionServiceDied. 404 */ 405 void statsCompanionServiceDiedImpl(); 406 407 /** 408 * Initialize ShellSubscriber 409 */ 410 void initShellSubscriber(); 411 412 /* 413 * Notify StatsLogProcessor of boot completed 414 */ 415 void onStatsdInitCompleted(int initEventDelaySecs); 416 417 /* 418 * This method is used to stop log reader thread. 419 */ 420 void stopReadingLogs(); 421 422 /* 423 * Notify async StatsdInitCompleted handler about termination event 424 */ 425 void onStatsdInitCompletedHandlerTermination(); 426 427 std::atomic<bool> mIsStopRequested = false; 428 429 /** 430 * Tracks the uid <--> package name mapping. 431 */ 432 const sp<UidMap> mUidMap; 433 434 /** 435 * Fetches external metrics 436 */ 437 sp<StatsPullerManager> mPullerManager; 438 439 /** 440 * Tracks the configurations that have been passed to statsd. 441 */ 442 sp<ConfigManager> mConfigManager; 443 444 /** 445 * The metrics recorder. 446 */ 447 sp<StatsLogProcessor> mProcessor; 448 449 /** 450 * The alarm monitor for anomaly detection. 451 */ 452 const sp<AlarmMonitor> mAnomalyAlarmMonitor; 453 454 /** 455 * The alarm monitor for alarms to directly trigger subscriber. 456 */ 457 const sp<AlarmMonitor> mPeriodicAlarmMonitor; 458 459 /** 460 * Whether this is an eng build. 461 */ 462 bool mEngBuild; 463 464 sp<ShellSubscriber> mShellSubscriber; 465 466 /** 467 * Mutex for setting the shell subscriber 468 */ 469 mutable mutex mShellSubscriberMutex; 470 shared_ptr<LogEventQueue> mEventQueue; 471 std::shared_ptr<LogEventFilter> mLogEventFilter; 472 473 std::unique_ptr<std::thread> mLogsReaderThread; 474 475 std::condition_variable mStatsdInitCompletedHandlerTerminationFlag; 476 std::mutex mStatsdInitCompletedHandlerTerminationFlagMutex; 477 /** 478 * @brief Used to communicated early termination request to onStatsdInitCompleted Handler 479 * @see onStatsdInitCompleted 480 */ 481 bool mStatsdInitCompletedHandlerTerminationRequested = false; 482 483 MultiConditionTrigger mBootCompleteTrigger; 484 static const inline string kBootCompleteTag = "BOOT_COMPLETE"; 485 static const inline string kUidMapReceivedTag = "UID_MAP"; 486 static const inline string kAllPullersRegisteredTag = "PULLERS_REGISTERED"; 487 488 ScopedAIBinder_DeathRecipient mStatsCompanionServiceDeathRecipient; 489 490 friend class StatsServiceConfigTest; 491 friend class RestrictedConfigE2ETest; 492 493 FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart); 494 FRIEND_TEST(StatsServiceTest, TestAddConfig_simple); 495 FRIEND_TEST(StatsServiceTest, TestAddConfig_empty); 496 FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid); 497 FRIEND_TEST(StatsServiceTest, TestGetUidFromArgs); 498 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp); 499 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot); 500 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade); 501 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval); 502 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit); 503 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnUpgradeWhenDisabled); 504 FRIEND_TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket); 505 FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket); 506 FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket); 507 FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket); 508 FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket); 509 FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket); 510 FRIEND_TEST(PartialBucketE2eTest, TestCountMetricNoSplitByDefault); 511 FRIEND_TEST(RestrictedConfigE2ETest, NonRestrictedConfigGetReport); 512 FRIEND_TEST(RestrictedConfigE2ETest, RestrictedConfigNoReport); 513 FRIEND_TEST(RestrictedConfigE2ETest, 514 TestSendRestrictedMetricsChangedBroadcastMultipleMatchedConfigs); 515 FRIEND_TEST(ConfigUpdateE2eTest, TestAnomalyDurationMetric); 516 517 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_single_bucket); 518 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_partial_bucket); 519 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets); 520 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period); 521 522 FRIEND_TEST(StatsServiceConfigTest, StatsServiceStatsdInitTest); 523 }; 524 525 } // namespace statsd 526 } // namespace os 527 } // namespace android 528 529 #endif // STATS_SERVICE_H 530