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/IStatsCompanionService.h>
20 #include <utils/RefBase.h>
21 #include <mutex>
22 #include <vector>
23 #include "packages/UidMap.h"
24 
25 #include "guardrail/StatsdStats.h"
26 #include "logd/LogEvent.h"
27 #include "puller_util.h"
28 
29 using aidl::android::os::IStatsCompanionService;
30 using std::shared_ptr;
31 
32 namespace android {
33 namespace os {
34 namespace statsd {
35 
36 class StatsPuller : public virtual RefBase {
37 public:
38     explicit StatsPuller(const int tagId,
39                          const int64_t coolDownNs = NS_PER_SEC,
40                          const int64_t pullTimeoutNs = StatsdStats::kPullMaxDelayNs,
41                          const std::vector<int> additiveFields = std::vector<int>());
42 
~StatsPuller()43     virtual ~StatsPuller() {}
44 
45     // Pulls the most recent data.
46     // The data may be served from cache if consecutive pulls come within
47     // predefined cooldown time.
48     // Returns true if the pull was successful.
49     // Returns false when
50     //   1) the pull fails
51     //   2) pull takes longer than mPullTimeoutNs (intrinsic to puller)
52     // If a metric wants to make any change to the data, like timestamps, it
53     // should make a copy as this data may be shared with multiple metrics.
54     bool Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data);
55 
56     // Clear cache immediately
57     int ForceClearCache();
58 
59     // Clear cache if elapsed time is more than cooldown time
60     int ClearCacheIfNecessary(int64_t timestampNs);
61 
62     static void SetUidMap(const sp<UidMap>& uidMap);
63 
SetStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService)64     virtual void SetStatsCompanionService(
65             shared_ptr<IStatsCompanionService> statsCompanionService) {};
66 
67 protected:
68     const int mTagId;
69 
70     // Max time allowed to pull this atom.
71     // We cannot reliably kill a pull thread. So we don't terminate the puller.
72     // The data is discarded if the pull takes longer than this and mHasGoodData
73     // marked as false.
74     const int64_t mPullTimeoutNs = StatsdStats::kPullMaxDelayNs;
75 
76 private:
77     mutable std::mutex mLock;
78 
79     // Real puller impl.
80     virtual bool PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) = 0;
81 
82     bool mHasGoodData = false;
83 
84     // Minimum time before this puller does actual pull again.
85     // Pullers can cause significant impact to system health and battery.
86     // So that we don't pull too frequently.
87     // If a pull request comes before cooldown, a cached version from previous pull
88     // will be returned.
89     const int64_t mCoolDownNs = 1 * NS_PER_SEC;
90 
91     // The field numbers of the fields that need to be summed when merging
92     // isolated uid with host uid.
93     const std::vector<int> mAdditiveFields;
94 
95     int64_t mLastPullTimeNs;
96 
97     // All pulls happen due to an event (app upgrade, bucket boundary, condition change, etc).
98     // If multiple pulls need to be done at the same event time, we will always use the cache after
99     // the first pull.
100     int64_t mLastEventTimeNs;
101 
102     // Cache of data from last pull. If next request comes before cool down finishes,
103     // cached data will be returned.
104     // Cached data is cleared when
105     //   1) A pull fails
106     //   2) A new pull request comes after cooldown time.
107     //   3) clearCache is called.
108     std::vector<std::shared_ptr<LogEvent>> mCachedData;
109 
110     int clearCache();
111 
112     int clearCacheLocked();
113 
114     static sp<UidMap> mUidMap;
115 };
116 
117 }  // namespace statsd
118 }  // namespace os
119 }  // namespace android
120