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