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