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 <gtest/gtest_prod.h>
21 #include "StatsLogProcessor.h"
22 #include "anomaly/AlarmMonitor.h"
23 #include "config/ConfigManager.h"
24 #include "external/StatsPullerManager.h"
25 #include "logd/LogEventQueue.h"
26 #include "packages/UidMap.h"
27 #include "shell/ShellSubscriber.h"
28 #include "statscompanion_util.h"
29 
30 #include <android/frameworks/stats/1.0/IStats.h>
31 #include <android/frameworks/stats/1.0/types.h>
32 #include <android/os/BnStatsManager.h>
33 #include <android/os/IStatsCompanionService.h>
34 #include <android/os/IStatsManager.h>
35 #include <binder/IResultReceiver.h>
36 #include <binder/ParcelFileDescriptor.h>
37 #include <utils/Looper.h>
38 
39 #include <mutex>
40 
41 using namespace android;
42 using namespace android::binder;
43 using namespace android::frameworks::stats::V1_0;
44 using namespace android::os;
45 using namespace std;
46 
47 namespace android {
48 namespace os {
49 namespace statsd {
50 
51 using android::hardware::Return;
52 
53 class StatsService : public BnStatsManager,
54                      public IBinder::DeathRecipient {
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 onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
63     virtual status_t dump(int fd, const Vector<String16>& args);
64     virtual status_t command(int inFd, int outFd, int err, Vector<String8>& args,
65                              sp<IResultReceiver> resultReceiver);
66 
67     virtual Status systemRunning();
68     virtual Status statsCompanionReady();
69     virtual Status informAnomalyAlarmFired();
70     virtual Status informPollAlarmFired();
71     virtual Status informAlarmForSubscriberTriggeringFired();
72 
73     virtual Status informAllUidData(const ParcelFileDescriptor& fd);
74     virtual Status informOnePackage(const String16& app, int32_t uid, int64_t version,
75                                     const String16& version_string, const String16& installer);
76     virtual Status informOnePackageRemoved(const String16& 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 String16& packageName,
99                            vector<uint8_t>* output) override;
100 
101 
102     /**
103      * Binder call for clients to get metadata across all configs in statsd.
104      */
105     virtual Status getMetadata(const String16& packageName,
106                                vector<uint8_t>* output) override;
107 
108 
109     /**
110      * Binder call to let clients send a configuration and indicate they're interested when they
111      * should requestData for this configuration.
112      */
113     virtual Status addConfiguration(int64_t key,
114                                     const vector<uint8_t>& config,
115                                     const String16& packageName) override;
116 
117     /**
118      * Binder call to let clients register the data fetch operation for a configuration.
119      */
120     virtual Status setDataFetchOperation(int64_t key,
121                                          const sp<android::IBinder>& intentSender,
122                                          const String16& packageName) override;
123 
124     /**
125      * Binder call to remove the data fetch operation for the specified config key.
126      */
127     virtual Status removeDataFetchOperation(int64_t key,
128                                             const String16& packageName) override;
129 
130     /**
131      * Binder call to let clients register the active configs changed operation.
132      */
133     virtual Status setActiveConfigsChangedOperation(const sp<android::IBinder>& intentSender,
134                                                     const String16& packageName,
135                                                     vector<int64_t>* output) override;
136 
137     /**
138      * Binder call to remove the active configs changed operation for the specified package..
139      */
140     virtual Status removeActiveConfigsChangedOperation(const String16& packageName) override;
141     /**
142      * Binder call to allow clients to remove the specified configuration.
143      */
144     virtual Status removeConfiguration(int64_t key,
145                                        const String16& packageName) override;
146 
147     /**
148      * Binder call to associate the given config's subscriberId with the given intentSender.
149      * intentSender must be convertible into an IntentSender (in Java) using IntentSender(IBinder).
150      */
151     virtual Status setBroadcastSubscriber(int64_t configId,
152                                           int64_t subscriberId,
153                                           const sp<android::IBinder>& intentSender,
154                                           const String16& packageName) override;
155 
156     /**
157      * Binder call to unassociate the given config's subscriberId with any intentSender.
158      */
159     virtual Status unsetBroadcastSubscriber(int64_t configId,
160                                             int64_t subscriberId,
161                                             const String16& packageName) override;
162 
163     /** Inform statsCompanion that statsd is ready. */
164     virtual void sayHiToStatsCompanion();
165 
166     /**
167      * Binder call to get AppBreadcrumbReported atom.
168      */
169     virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override;
170 
171     /**
172      * Binder call to register a callback function for a vendor pulled atom.
173      * Note: this atom must NOT have uid as a field.
174      */
175     virtual Status registerPullerCallback(int32_t atomTag,
176         const sp<android::os::IStatsPullerCallback>& pullerCallback,
177         const String16& packageName) override;
178 
179     /**
180      * Binder call to unregister any existing callback function for a vendor pulled atom.
181      */
182     virtual Status unregisterPullerCallback(int32_t atomTag, const String16& packageName) override;
183 
184     /**
185      * Binder call to log BinaryPushStateChanged atom.
186      */
187     virtual Status sendBinaryPushStateChangedAtom(
188             const android::String16& trainNameIn,
189             const int64_t trainVersionCodeIn,
190             const int options,
191             const int32_t state,
192             const std::vector<int64_t>& experimentIdsIn) override;
193 
194     /**
195      * Binder call to log WatchdogRollbackOccurred atom.
196      */
197     virtual Status sendWatchdogRollbackOccurredAtom(
198             const int32_t rollbackTypeIn,
199             const android::String16& packageNameIn,
200             const int64_t packageVersionCodeIn,
201             const int32_t rollbackReasonIn,
202             const android::String16& failingPackageNameIn) override;
203 
204     /**
205      * Binder call to get registered experiment IDs.
206      */
207     virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut);
208 
209     /** IBinder::DeathRecipient */
210     virtual void binderDied(const wp<IBinder>& who) override;
211 
212 private:
213     /**
214      * Load system properties at init.
215      */
216     void init_system_properties();
217 
218     /**
219      * Helper for loading system properties.
220      */
221     static void init_build_type_callback(void* cookie, const char* name, const char* value,
222                                          uint32_t serial);
223 
224     /**
225      * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto.
226      */
227     void dumpIncidentSection(int outFd);
228 
229     /**
230      * Text or proto output of statsdStats dumpsys.
231      */
232     void dumpStatsdStats(int outFd, bool verbose, bool proto);
233 
234     /**
235      * Print usage information for the commands
236      */
237     void print_cmd_help(int out);
238 
239     /* Runs on its dedicated thread to process pushed stats event from socket. */
240     void readLogs();
241 
242     /**
243      * Trigger a broadcast.
244      */
245     status_t cmd_trigger_broadcast(int outFd, Vector<String8>& args);
246 
247 
248     /**
249      * Trigger an active configs changed broadcast.
250      */
251     status_t cmd_trigger_active_config_broadcast(int outFd, Vector<String8>& args);
252 
253     /**
254      * Handle the config sub-command.
255      */
256     status_t cmd_config(int inFd, int outFd, int err, Vector<String8>& args);
257 
258     /**
259      * Prints some basic stats to std out.
260      */
261     status_t cmd_print_stats(int outFd, const Vector<String8>& args);
262 
263     /**
264      * Print the event log.
265      */
266     status_t cmd_dump_report(int outFd, const Vector<String8>& args);
267 
268     /**
269      * Print the mapping of uids to package names.
270      */
271     status_t cmd_print_uid_map(int outFd, const Vector<String8>& args);
272 
273     /**
274      * Flush the data to disk.
275      */
276     status_t cmd_write_data_to_disk(int outFd);
277 
278     /**
279      * Write an AppBreadcrumbReported event to the StatsLog buffer, as if calling
280      * StatsLog.write(APP_BREADCRUMB_REPORTED).
281      */
282     status_t cmd_log_app_breadcrumb(int outFd, const Vector<String8>& args);
283 
284     /**
285      * Write an BinaryPushStateChanged event, as if calling StatsLog.logBinaryPushStateChanged().
286      */
287     status_t cmd_log_binary_push(int outFd, const Vector<String8>& args);
288 
289     /**
290      * Print contents of a pulled metrics source.
291      */
292     status_t cmd_print_pulled_metrics(int outFd, const Vector<String8>& args);
293 
294     /**
295      * Removes all configs stored on disk and on memory.
296      */
297     status_t cmd_remove_all_configs(int outFd);
298 
299     /*
300      * Dump memory usage by statsd.
301      */
302     status_t cmd_dump_memory_info(int outFd);
303 
304     /*
305      * Clear all puller cached data
306      */
307     status_t cmd_clear_puller_cache(int outFd);
308 
309     /**
310      * Print all stats logs received to logcat.
311      */
312     status_t cmd_print_logs(int outFd, const Vector<String8>& args);
313 
314     /**
315      * Writes the value of args[uidArgIndex] into uid.
316      * Returns whether the uid is reasonable (type uid_t) and whether
317      * 1. it is equal to the calling uid, or
318      * 2. the device is mEngBuild, or
319      * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL).
320      */
321     bool getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid);
322 
323     /**
324      * Writes the value of uidSting into uid.
325      * Returns whether the uid is reasonable (type uid_t) and whether
326      * 1. it is equal to the calling uid, or
327      * 2. the device is mEngBuild, or
328      * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL).
329      */
330      bool getUidFromString(const char* uidString, int32_t& uid);
331 
332     /**
333      * Adds a configuration after checking permissions and obtaining UID from binder call.
334      */
335     bool addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config);
336 
337     /**
338      * Update a configuration.
339      */
340     void set_config(int uid, const string& name, const StatsdConfig& config);
341 
342     /**
343      * Tracks the uid <--> package name mapping.
344      */
345     sp<UidMap> mUidMap;
346 
347     /**
348      * Fetches external metrics
349      */
350     sp<StatsPullerManager> mPullerManager;
351 
352     /**
353      * Tracks the configurations that have been passed to statsd.
354      */
355     sp<ConfigManager> mConfigManager;
356 
357     /**
358      * The metrics recorder.
359      */
360     sp<StatsLogProcessor> mProcessor;
361 
362     /**
363      * The alarm monitor for anomaly detection.
364      */
365     const sp<AlarmMonitor> mAnomalyAlarmMonitor;
366 
367     /**
368      * The alarm monitor for alarms to directly trigger subscriber.
369      */
370     const sp<AlarmMonitor> mPeriodicAlarmMonitor;
371 
372     /**
373      * Whether this is an eng build.
374      */
375     bool mEngBuild;
376 
377     sp<ShellSubscriber> mShellSubscriber;
378 
379     /**
380      * Mutex for setting the shell subscriber
381      */
382     mutable mutex mShellSubscriberMutex;
383     std::shared_ptr<LogEventQueue> mEventQueue;
384 
385     FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
386     FRIEND_TEST(StatsServiceTest, TestAddConfig_simple);
387     FRIEND_TEST(StatsServiceTest, TestAddConfig_empty);
388     FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid);
389     FRIEND_TEST(StatsServiceTest, TestGetUidFromArgs);
390     FRIEND_TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp);
391     FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade);
392     FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval);
393     FRIEND_TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit);
394     FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket);
395     FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket);
396     FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket);
397     FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket);
398 };
399 
400 }  // namespace statsd
401 }  // namespace os
402 }  // namespace android
403 
404 #endif  // STATS_SERVICE_H
405