• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
18 
19 #include <aidl/android/os/IPullAtomCallback.h>
20 #include <aidl/android/os/IStatsCompanionService.h>
21 #include <utils/RefBase.h>
22 
23 #include <list>
24 #include <vector>
25 
26 #include "PullDataReceiver.h"
27 #include "PullUidProvider.h"
28 #include "StatsPuller.h"
29 #include "ThreadSafeQueue.h"
30 #include "guardrail/StatsdStats.h"
31 #include "logd/LogEvent.h"
32 #include "packages/UidMap.h"
33 
34 using aidl::android::os::IPullAtomCallback;
35 using aidl::android::os::IStatsCompanionService;
36 using std::shared_ptr;
37 
38 namespace android {
39 namespace os {
40 namespace statsd {
41 
42 typedef struct PullerKey {
43     // The uid of the process that registers this puller.
44     int uid = -1;
45     // The atom that this puller is for.
46     int atomTag;
47 
48     bool operator<(const PullerKey& that) const {
49         if (uid < that.uid) {
50             return true;
51         }
52         if (uid > that.uid) {
53             return false;
54         }
55         return atomTag < that.atomTag;
56     };
57 
58     bool operator==(const PullerKey& that) const {
59         return uid == that.uid && atomTag == that.atomTag;
60     };
61 
62 } PullerKey;
63 
64 class StatsPullerManager : public virtual RefBase {
65 public:
66     StatsPullerManager();
67 
~StatsPullerManager()68     virtual ~StatsPullerManager() {
69     }
70 
71     // A struct containing an atom id and a Config Key
72     typedef struct ReceiverKey {
73         const int atomTag;
74         const ConfigKey configKey;
75 
76         inline bool operator<(const ReceiverKey& that) const {
77             return atomTag == that.atomTag ? configKey < that.configKey : atomTag < that.atomTag;
78         }
79     } ReceiverKey;
80 
81     typedef struct {
82         int64_t nextPullTimeNs;
83         int64_t intervalNs;
84         wp<PullDataReceiver> receiver;
85     } ReceiverInfo;
86 
87     typedef struct {
88         PullerKey key;
89         sp<StatsPuller> puller;
90         vector<ReceiverInfo*> receivers;
91     } PullerParams;
92 
93     typedef struct {
94         PullErrorCode pullErrorCode;
95         PullerKey pullerKey;
96         std::vector<ReceiverInfo*> receiverInfo;
97         std::vector<shared_ptr<LogEvent>> data;
98     } PulledInfo;
99 
100     // Registers a receiver for tagId. It will be pulled on the nextPullTimeNs
101     // and then every intervalNs thereafter.
102     virtual void RegisterReceiver(int tagId, const ConfigKey& configKey,
103                                   const wp<PullDataReceiver>& receiver, int64_t nextPullTimeNs,
104                                   int64_t intervalNs);
105 
106     // Stop listening on a tagId.
107     virtual void UnRegisterReceiver(int tagId, const ConfigKey& configKey,
108                                     const wp<PullDataReceiver>& receiver);
109 
110     // Registers a pull uid provider for the config key. When pulling atoms, it will be used to
111     // determine which uids to pull from.
112     virtual void RegisterPullUidProvider(const ConfigKey& configKey,
113                                          const wp<PullUidProvider>& provider);
114 
115     // Unregister a pull uid provider.
116     virtual void UnregisterPullUidProvider(const ConfigKey& configKey,
117                                            const wp<PullUidProvider>& provider);
118 
119     // Verify if we know how to pull for this matcher
120     bool PullerForMatcherExists(int tagId) const;
121 
122     void OnAlarmFired(int64_t elapsedTimeNs);
123 
124     // Pulls the most recent data.
125     // The data may be served from cache if consecutive pulls come within
126     // mCoolDownNs.
127     // Returns true if the pull was successful.
128     // Returns false when
129     //   1) the pull fails
130     //   2) pull takes longer than mPullTimeoutNs (intrinsic to puller)
131     //   3) Either a PullUidProvider was not registered for the config, or the there was no puller
132     //      registered for any of the uids for this atom.
133     // If the metric wants to make any change to the data, like timestamps, they
134     // should make a copy as this data may be shared with multiple metrics.
135     virtual bool Pull(int tagId, const ConfigKey& configKey, int64_t eventTimeNs,
136                       vector<std::shared_ptr<LogEvent>>* data);
137 
138     // Same as above, but directly specify the allowed uids to pull from.
139     virtual bool Pull(int tagId, const vector<int32_t>& uids, int64_t eventTimeNs,
140                       vector<std::shared_ptr<LogEvent>>* data);
141 
142     // Clear pull data cache immediately.
143     int ForceClearPullerCache();
144 
145     // Clear pull data cache if it is beyond respective cool down time.
146     int ClearPullerCacheIfNecessary(int64_t timestampNs);
147 
148     void SetStatsCompanionService(const shared_ptr<IStatsCompanionService>& statsCompanionService);
149 
150     void RegisterPullAtomCallback(const int uid, const int32_t atomTag, int64_t coolDownNs,
151                                   const int64_t timeoutNs, const vector<int32_t>& additiveFields,
152                                   const shared_ptr<IPullAtomCallback>& callback);
153 
154     void UnregisterPullAtomCallback(const int uid, const int32_t atomTag);
155 
156     std::map<const PullerKey, sp<StatsPuller>> mAllPullAtomInfo;
157 
158 private:
159     const static int64_t kMinCoolDownNs = NS_PER_SEC;
160     const static int64_t kMaxTimeoutNs = 10 * NS_PER_SEC;
161     shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr;
162 
163     // mapping from Receiver Key to receivers
164     std::map<ReceiverKey, std::list<ReceiverInfo>> mReceivers;
165 
166     // mapping from Config Key to the PullUidProvider for that config
167     std::map<ConfigKey, wp<PullUidProvider>> mPullUidProviders;
168 
169     bool PullLocked(int tagId, const ConfigKey& configKey, int64_t eventTimeNs,
170                     vector<std::shared_ptr<LogEvent>>* data);
171 
172     bool PullLocked(int tagId, const vector<int32_t>& uids, int64_t eventTimeNs,
173                     vector<std::shared_ptr<LogEvent>>* data);
174 
175     bool getPullerUidsLocked(const int tagId, const ConfigKey& configKey, vector<int32_t>& uids);
176 
177     void initPullerQueue(ThreadSafeQueue<PullerParams>& pullerQueue,
178                          std::queue<PulledInfo>& pulledData, int64_t elapsedTimeNs,
179                          int64_t& minNextPullTimeNs);
180 
181     void onAlarmFiredSynchronous(const int64_t elapsedTimeNs, const int64_t wallClockNs,
182                                  int64_t& minNextPullTimeNs);
183     // locks for data receiver and StatsCompanionService changes
184     std::mutex mLock;
185 
186     void updateAlarmLocked();
187 
188     int64_t mNextPullTimeNs;
189 
190     FRIEND_TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTrigger);
191     FRIEND_TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTriggerWithActivation);
192     FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvents);
193     FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvent_LateAlarm);
194     FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsWithActivation);
195     FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsNoCondition);
196     FRIEND_TEST(GaugeMetricE2ePulledTest, TestSliceByStates);
197     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
198     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
199     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
200 
201     FRIEND_TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate);
202 
203     FRIEND_TEST(ConfigUpdateE2eTest, TestGaugeMetric);
204     FRIEND_TEST(ConfigUpdateE2eTest, TestValueMetric);
205 
206     FRIEND_TEST(StatsPullerManagerTest, TestSameAtomIsPulledInABatch);
207 };
208 
209 }  // namespace statsd
210 }  // namespace os
211 }  // namespace android
212