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