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 "StatsPullerManager.h"
22 #include "guardrail/StatsdStats.h"
23 #include "puller_util.h"
24 #include "stats_log_util.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
StatsPuller(const int tagId)35 StatsPuller::StatsPuller(const int tagId)
36 : mTagId(tagId), mLastPullTimeNs(0) {
37 }
38
Pull(std::vector<std::shared_ptr<LogEvent>> * data)39 bool StatsPuller::Pull(std::vector<std::shared_ptr<LogEvent>>* data) {
40 lock_guard<std::mutex> lock(mLock);
41 int64_t elapsedTimeNs = getElapsedRealtimeNs();
42 StatsdStats::getInstance().notePull(mTagId);
43 const bool shouldUseCache = elapsedTimeNs - mLastPullTimeNs <
44 StatsPullerManager::kAllPullAtomInfo.at(mTagId).coolDownNs;
45 if (shouldUseCache) {
46 if (mHasGoodData) {
47 (*data) = mCachedData;
48 StatsdStats::getInstance().notePullFromCache(mTagId);
49 }
50 return mHasGoodData;
51 }
52
53 if (mLastPullTimeNs > 0) {
54 StatsdStats::getInstance().updateMinPullIntervalSec(
55 mTagId, (elapsedTimeNs - mLastPullTimeNs) / NS_PER_SEC);
56 }
57 mCachedData.clear();
58 mLastPullTimeNs = elapsedTimeNs;
59 mHasGoodData = PullInternal(&mCachedData);
60 if (!mHasGoodData) {
61 return mHasGoodData;
62 }
63 const int64_t pullDurationNs = getElapsedRealtimeNs() - elapsedTimeNs;
64 StatsdStats::getInstance().notePullTime(mTagId, pullDurationNs);
65 const bool pullTimeOut =
66 pullDurationNs > StatsPullerManager::kAllPullAtomInfo.at(mTagId).pullTimeoutNs;
67 if (pullTimeOut) {
68 // Something went wrong. Discard the data.
69 clearCacheLocked();
70 mHasGoodData = false;
71 StatsdStats::getInstance().notePullTimeout(mTagId);
72 ALOGW("Pull for atom %d exceeds timeout %lld nano seconds.", mTagId,
73 (long long)pullDurationNs);
74 return mHasGoodData;
75 }
76
77 if (mCachedData.size() > 0) {
78 mapAndMergeIsolatedUidsToHostUid(mCachedData, mUidMap, mTagId);
79 }
80
81 (*data) = mCachedData;
82 return mHasGoodData;
83 }
84
ForceClearCache()85 int StatsPuller::ForceClearCache() {
86 return clearCache();
87 }
88
clearCache()89 int StatsPuller::clearCache() {
90 lock_guard<std::mutex> lock(mLock);
91 return clearCacheLocked();
92 }
93
clearCacheLocked()94 int StatsPuller::clearCacheLocked() {
95 int ret = mCachedData.size();
96 mCachedData.clear();
97 mLastPullTimeNs = 0;
98 return ret;
99 }
100
ClearCacheIfNecessary(int64_t timestampNs)101 int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) {
102 if (timestampNs - mLastPullTimeNs >
103 StatsPullerManager::kAllPullAtomInfo.at(mTagId).coolDownNs) {
104 return clearCache();
105 } else {
106 return 0;
107 }
108 }
109
110 } // namespace statsd
111 } // namespace os
112 } // namespace android
113