1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2024 The Android Open Source Project 3*ec779b8eSAndroid Build Coastguard Worker * 4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*ec779b8eSAndroid Build Coastguard Worker * 8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*ec779b8eSAndroid Build Coastguard Worker * 10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License. 15*ec779b8eSAndroid Build Coastguard Worker */ 16*ec779b8eSAndroid Build Coastguard Worker 17*ec779b8eSAndroid Build Coastguard Worker #include <psh_utils/PowerClientStats.h> 18*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/ServiceUtilities.h> 19*ec779b8eSAndroid Build Coastguard Worker 20*ec779b8eSAndroid Build Coastguard Worker namespace android::media::psh_utils { 21*ec779b8eSAndroid Build Coastguard Worker 22*ec779b8eSAndroid Build Coastguard Worker /* static */ getCommandThread()23*ec779b8eSAndroid Build Coastguard Workeraudio_utils::CommandThread& PowerClientStats::getCommandThread() { 24*ec779b8eSAndroid Build Coastguard Worker [[clang::no_destroy]] static audio_utils::CommandThread ct; 25*ec779b8eSAndroid Build Coastguard Worker return ct; 26*ec779b8eSAndroid Build Coastguard Worker } 27*ec779b8eSAndroid Build Coastguard Worker PowerClientStats(uid_t uid,const std::string & additional)28*ec779b8eSAndroid Build Coastguard WorkerPowerClientStats::PowerClientStats(uid_t uid, const std::string& additional) 29*ec779b8eSAndroid Build Coastguard Worker : mUid(uid), mAdditional(additional) {} 30*ec779b8eSAndroid Build Coastguard Worker start(int64_t actualNs)31*ec779b8eSAndroid Build Coastguard Workervoid PowerClientStats::start(int64_t actualNs) { 32*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mMutex); 33*ec779b8eSAndroid Build Coastguard Worker ++mTokenCount; 34*ec779b8eSAndroid Build Coastguard Worker if (mStartNs == 0) mStartNs = actualNs; 35*ec779b8eSAndroid Build Coastguard Worker if (mStartStats) return; 36*ec779b8eSAndroid Build Coastguard Worker mStartStats = PowerStatsCollector::getCollector().getStats(kStatTimeToleranceNs); 37*ec779b8eSAndroid Build Coastguard Worker } 38*ec779b8eSAndroid Build Coastguard Worker stop(int64_t actualNs)39*ec779b8eSAndroid Build Coastguard Workervoid PowerClientStats::stop(int64_t actualNs) { 40*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mMutex); 41*ec779b8eSAndroid Build Coastguard Worker if (--mTokenCount > 0) return; 42*ec779b8eSAndroid Build Coastguard Worker if (mStartNs != 0) mCumulativeNs += actualNs - mStartNs; 43*ec779b8eSAndroid Build Coastguard Worker mStartNs = 0; 44*ec779b8eSAndroid Build Coastguard Worker if (!mStartStats) return; 45*ec779b8eSAndroid Build Coastguard Worker const auto stopStats = PowerStatsCollector::getCollector().getStats(kStatTimeToleranceNs); 46*ec779b8eSAndroid Build Coastguard Worker if (stopStats && stopStats != mStartStats) { 47*ec779b8eSAndroid Build Coastguard Worker *mCumulativeStats += *stopStats - *mStartStats; 48*ec779b8eSAndroid Build Coastguard Worker } 49*ec779b8eSAndroid Build Coastguard Worker mStartStats.reset(); 50*ec779b8eSAndroid Build Coastguard Worker } 51*ec779b8eSAndroid Build Coastguard Worker addPid(pid_t pid)52*ec779b8eSAndroid Build Coastguard Workervoid PowerClientStats::addPid(pid_t pid) { 53*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mMutex); 54*ec779b8eSAndroid Build Coastguard Worker mPids.emplace(pid); 55*ec779b8eSAndroid Build Coastguard Worker } 56*ec779b8eSAndroid Build Coastguard Worker removePid(pid_t pid)57*ec779b8eSAndroid Build Coastguard Workersize_t PowerClientStats::removePid(pid_t pid) { 58*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mMutex); 59*ec779b8eSAndroid Build Coastguard Worker mPids.erase(pid); 60*ec779b8eSAndroid Build Coastguard Worker return mPids.size(); 61*ec779b8eSAndroid Build Coastguard Worker } 62*ec779b8eSAndroid Build Coastguard Worker toString(bool stats,const std::string & prefix) const63*ec779b8eSAndroid Build Coastguard Workerstd::string PowerClientStats::toString(bool stats, const std::string& prefix) const { 64*ec779b8eSAndroid Build Coastguard Worker std::lock_guard l(mMutex); 65*ec779b8eSAndroid Build Coastguard Worker 66*ec779b8eSAndroid Build Coastguard Worker // Adjust delta time and stats if currently running. 67*ec779b8eSAndroid Build Coastguard Worker auto cumulativeStats = mCumulativeStats; 68*ec779b8eSAndroid Build Coastguard Worker auto cumulativeNs = mCumulativeNs; 69*ec779b8eSAndroid Build Coastguard Worker if (mStartNs) cumulativeNs += systemTime(SYSTEM_TIME_BOOTTIME) - mStartNs; 70*ec779b8eSAndroid Build Coastguard Worker if (mStartStats) { 71*ec779b8eSAndroid Build Coastguard Worker const auto stopStats = PowerStatsCollector::getCollector().getStats(kStatTimeToleranceNs); 72*ec779b8eSAndroid Build Coastguard Worker if (stopStats && stopStats != mStartStats) { 73*ec779b8eSAndroid Build Coastguard Worker auto newStats = std::make_shared<PowerStats>(*cumulativeStats); 74*ec779b8eSAndroid Build Coastguard Worker *newStats += *stopStats - *mStartStats; 75*ec779b8eSAndroid Build Coastguard Worker cumulativeStats = newStats; 76*ec779b8eSAndroid Build Coastguard Worker } 77*ec779b8eSAndroid Build Coastguard Worker } 78*ec779b8eSAndroid Build Coastguard Worker 79*ec779b8eSAndroid Build Coastguard Worker std::string result(prefix); 80*ec779b8eSAndroid Build Coastguard Worker result.append("uid: ") 81*ec779b8eSAndroid Build Coastguard Worker .append(std::to_string(mUid)) 82*ec779b8eSAndroid Build Coastguard Worker .append(" ").append(mediautils::UidInfo::getInfo(mUid)->package) 83*ec779b8eSAndroid Build Coastguard Worker .append(" streams: ").append(std::to_string(mTokenCount)) 84*ec779b8eSAndroid Build Coastguard Worker .append(" seconds: ").append(std::to_string(cumulativeNs * 1e-9)); 85*ec779b8eSAndroid Build Coastguard Worker result.append(" {"); 86*ec779b8eSAndroid Build Coastguard Worker for (auto pid : mPids) { 87*ec779b8eSAndroid Build Coastguard Worker result.append(" ").append(std::to_string(pid)); 88*ec779b8eSAndroid Build Coastguard Worker } 89*ec779b8eSAndroid Build Coastguard Worker result.append(" }"); 90*ec779b8eSAndroid Build Coastguard Worker if (!mAdditional.empty()) { 91*ec779b8eSAndroid Build Coastguard Worker result.append("\n").append(prefix).append(mAdditional); 92*ec779b8eSAndroid Build Coastguard Worker } 93*ec779b8eSAndroid Build Coastguard Worker if (stats) { 94*ec779b8eSAndroid Build Coastguard Worker std::string prefix2(prefix); 95*ec779b8eSAndroid Build Coastguard Worker prefix2.append(" "); 96*ec779b8eSAndroid Build Coastguard Worker result.append("\n").append(cumulativeStats->normalizedEnergy(prefix2)); 97*ec779b8eSAndroid Build Coastguard Worker } 98*ec779b8eSAndroid Build Coastguard Worker return result; 99*ec779b8eSAndroid Build Coastguard Worker } 100*ec779b8eSAndroid Build Coastguard Worker 101*ec779b8eSAndroid Build Coastguard Worker } // namespace android::media::psh_utils 102