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; 33 void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; } 34 35 StatsPuller::StatsPuller(const int tagId) 36 : mTagId(tagId), mLastPullTimeNs(0) { 37 } 38 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 85 int StatsPuller::ForceClearCache() { 86 return clearCache(); 87 } 88 89 int StatsPuller::clearCache() { 90 lock_guard<std::mutex> lock(mLock); 91 return clearCacheLocked(); 92 } 93 94 int StatsPuller::clearCacheLocked() { 95 int ret = mCachedData.size(); 96 mCachedData.clear(); 97 mLastPullTimeNs = 0; 98 return ret; 99 } 100 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