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 #define DEBUG false  // STOPSHIP if true
18 #include "Log.h"
19 
20 #include "StatsPuller.h"
21 #include "guardrail/StatsdStats.h"
22 #include "puller_util.h"
23 #include "stats_log_util.h"
24 #include "StatsPullerManagerImpl.h"
25 
26 namespace android {
27 namespace os {
28 namespace statsd {
29 
30 using std::lock_guard;
31 
32 sp<UidMap> StatsPuller::mUidMap = nullptr;
SetUidMap(const sp<UidMap> & uidMap)33 void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; }
34 
35 // ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently
StatsPuller(const int tagId)36 StatsPuller::StatsPuller(const int tagId)
37     : mTagId(tagId) {
38     mCoolDownNs = StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)->second.coolDownNs;
39     VLOG("Puller for tag %d created. Cooldown set to %lld", mTagId, (long long)mCoolDownNs);
40 }
41 
Pull(const int64_t elapsedTimeNs,std::vector<std::shared_ptr<LogEvent>> * data)42 bool StatsPuller::Pull(const int64_t elapsedTimeNs, std::vector<std::shared_ptr<LogEvent>>* data) {
43     lock_guard<std::mutex> lock(mLock);
44     int64_t wallClockTimeNs = getWallClockNs();
45     StatsdStats::getInstance().notePull(mTagId);
46     if (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs) {
47         (*data) = mCachedData;
48         StatsdStats::getInstance().notePullFromCache(mTagId);
49         return true;
50     }
51     if (mMinPullIntervalNs > elapsedTimeNs - mLastPullTimeNs) {
52         mMinPullIntervalNs = elapsedTimeNs - mLastPullTimeNs;
53         StatsdStats::getInstance().updateMinPullIntervalSec(mTagId,
54                                                             mMinPullIntervalNs / NS_PER_SEC);
55     }
56     mCachedData.clear();
57     mLastPullTimeNs = elapsedTimeNs;
58     bool ret = PullInternal(&mCachedData);
59     for (const shared_ptr<LogEvent>& data : mCachedData) {
60         data->setElapsedTimestampNs(elapsedTimeNs);
61         data->setLogdWallClockTimestampNs(wallClockTimeNs);
62     }
63     if (ret && mCachedData.size() > 0) {
64       mergeIsolatedUidsToHostUid(mCachedData, mUidMap, mTagId);
65       (*data) = mCachedData;
66     }
67     return ret;
68 }
69 
ForceClearCache()70 int StatsPuller::ForceClearCache() {
71     return clearCache();
72 }
73 
clearCache()74 int StatsPuller::clearCache() {
75     lock_guard<std::mutex> lock(mLock);
76     int ret = mCachedData.size();
77     mCachedData.clear();
78     mLastPullTimeNs = 0;
79     return ret;
80 }
81 
ClearCacheIfNecessary(int64_t timestampNs)82 int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) {
83     if (timestampNs - mLastPullTimeNs > mCoolDownNs) {
84         return clearCache();
85     } else {
86         return 0;
87     }
88 }
89 
90 }  // namespace statsd
91 }  // namespace os
92 }  // namespace android
93