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 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 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, wp<PullUidProvider> provider); 83 84 // Unregister a pull uid provider. 85 virtual void UnregisterPullUidProvider(const ConfigKey& configKey, 86 wp<PullUidProvider> provider); 87 88 // Verify if we know how to pull for this matcher 89 bool PullerForMatcherExists(int tagId) const; 90 91 void OnAlarmFired(int64_t elapsedTimeNs); 92 93 // Pulls the most recent data. 94 // The data may be served from cache if consecutive pulls come within 95 // mCoolDownNs. 96 // Returns true if the pull was successful. 97 // Returns false when 98 // 1) the pull fails 99 // 2) pull takes longer than mPullTimeoutNs (intrinsic to puller) 100 // 3) Either a PullUidProvider was not registered for the config, or the there was no puller 101 // registered for any of the uids for this atom. 102 // If the metric wants to make any change to the data, like timestamps, they 103 // should make a copy as this data may be shared with multiple metrics. 104 virtual bool Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs, 105 vector<std::shared_ptr<LogEvent>>* data); 106 107 // Same as above, but directly specify the allowed uids to pull from. 108 virtual bool Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs, 109 vector<std::shared_ptr<LogEvent>>* data); 110 111 // Clear pull data cache immediately. 112 int ForceClearPullerCache(); 113 114 // Clear pull data cache if it is beyond respective cool down time. 115 int ClearPullerCacheIfNecessary(int64_t timestampNs); 116 117 void SetStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService); 118 119 void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs, 120 const int64_t timeoutNs, const vector<int32_t>& additiveFields, 121 const shared_ptr<IPullAtomCallback>& callback); 122 123 void UnregisterPullAtomCallback(const int uid, const int32_t atomTag); 124 125 std::map<const PullerKey, sp<StatsPuller>> kAllPullAtomInfo; 126 127 private: 128 const static int64_t kMinCoolDownNs = NS_PER_SEC; 129 const static int64_t kMaxTimeoutNs = 10 * NS_PER_SEC; 130 shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr; 131 132 // A struct containing an atom id and a Config Key 133 typedef struct ReceiverKey { 134 const int atomTag; 135 const ConfigKey configKey; 136 137 inline bool operator<(const ReceiverKey& that) const { 138 return atomTag == that.atomTag ? configKey < that.configKey : atomTag < that.atomTag; 139 } 140 } ReceiverKey; 141 142 typedef struct { 143 int64_t nextPullTimeNs; 144 int64_t intervalNs; 145 wp<PullDataReceiver> receiver; 146 } ReceiverInfo; 147 148 // mapping from Receiver Key to receivers 149 std::map<ReceiverKey, std::list<ReceiverInfo>> mReceivers; 150 151 // mapping from Config Key to the PullUidProvider for that config 152 std::map<ConfigKey, wp<PullUidProvider>> mPullUidProviders; 153 154 bool PullLocked(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs, 155 vector<std::shared_ptr<LogEvent>>* data); 156 157 bool PullLocked(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs, 158 vector<std::shared_ptr<LogEvent>>* data); 159 160 // locks for data receiver and StatsCompanionService changes 161 std::mutex mLock; 162 163 void updateAlarmLocked(); 164 165 int64_t mNextPullTimeNs; 166 167 // Death recipient that is triggered when the process holding the IPullAtomCallback has died. 168 ::ndk::ScopedAIBinder_DeathRecipient mPullAtomCallbackDeathRecipient; 169 170 /** 171 * Death recipient callback that is called when a pull atom callback dies. 172 * The cookie is a pointer to a PullAtomCallbackDeathCookie. 173 */ 174 static void pullAtomCallbackDied(void* cookie); 175 176 FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents); 177 FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm); 178 FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation); 179 FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition); 180 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); 181 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); 182 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); 183 184 FRIEND_TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate); 185 186 FRIEND_TEST(ConfigUpdateE2eTest, TestGaugeMetric); 187 FRIEND_TEST(ConfigUpdateE2eTest, TestValueMetric); 188 }; 189 190 } // namespace statsd 191 } // namespace os 192 } // namespace android 193