xref: /aosp_15_r20/frameworks/av/media/psh_utils/AudioPowerManager.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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 "AudioToken.h"
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AudioPowerManager"
19*ec779b8eSAndroid Build Coastguard Worker #include <com_android_media_audioserver.h>
20*ec779b8eSAndroid Build Coastguard Worker #include <cutils/properties.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <psh_utils/AudioPowerManager.h>
23*ec779b8eSAndroid Build Coastguard Worker 
24*ec779b8eSAndroid Build Coastguard Worker namespace android::media::psh_utils {
25*ec779b8eSAndroid Build Coastguard Worker 
26*ec779b8eSAndroid Build Coastguard Worker /* static */
getAudioPowerManager()27*ec779b8eSAndroid Build Coastguard Worker AudioPowerManager& AudioPowerManager::getAudioPowerManager() {
28*ec779b8eSAndroid Build Coastguard Worker     [[clang::no_destroy]] static AudioPowerManager apm;
29*ec779b8eSAndroid Build Coastguard Worker     return apm;
30*ec779b8eSAndroid Build Coastguard Worker }
31*ec779b8eSAndroid Build Coastguard Worker 
startClient(pid_t pid,uid_t uid,const std::string & additional)32*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<Token> AudioPowerManager::startClient(pid_t pid, uid_t uid,
33*ec779b8eSAndroid Build Coastguard Worker         const std::string& additional) {
34*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<PowerClientStats> powerClientStats;
35*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mMutex);
36*ec779b8eSAndroid Build Coastguard Worker     if (mPowerClientStats.count(uid) == 0) {
37*ec779b8eSAndroid Build Coastguard Worker         const auto it = mHistoricalClients.find(uid);
38*ec779b8eSAndroid Build Coastguard Worker         if (it == mHistoricalClients.end()) {
39*ec779b8eSAndroid Build Coastguard Worker             powerClientStats = std::make_shared<PowerClientStats>(uid, additional);
40*ec779b8eSAndroid Build Coastguard Worker         } else {
41*ec779b8eSAndroid Build Coastguard Worker             powerClientStats = it->second;
42*ec779b8eSAndroid Build Coastguard Worker             mHistoricalClients.erase(it);
43*ec779b8eSAndroid Build Coastguard Worker         }
44*ec779b8eSAndroid Build Coastguard Worker         mPowerClientStats[uid] = powerClientStats;
45*ec779b8eSAndroid Build Coastguard Worker     } else {
46*ec779b8eSAndroid Build Coastguard Worker         powerClientStats = mPowerClientStats[uid];
47*ec779b8eSAndroid Build Coastguard Worker     }
48*ec779b8eSAndroid Build Coastguard Worker     powerClientStats->addPid(pid);
49*ec779b8eSAndroid Build Coastguard Worker     mPidToUid[pid] = uid;
50*ec779b8eSAndroid Build Coastguard Worker     std::unique_ptr<Token> token =
51*ec779b8eSAndroid Build Coastguard Worker             std::make_unique<AudioClientToken>(powerClientStats, pid, uid, additional);
52*ec779b8eSAndroid Build Coastguard Worker     mOutstandingTokens.emplace(token.get());
53*ec779b8eSAndroid Build Coastguard Worker     return token;
54*ec779b8eSAndroid Build Coastguard Worker }
55*ec779b8eSAndroid Build Coastguard Worker 
startTrack(uid_t uid,const std::string & additional)56*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<Token> AudioPowerManager::startTrack(uid_t uid, const std::string& additional) {
57*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mMutex);
58*ec779b8eSAndroid Build Coastguard Worker     if (mPowerClientStats.count(uid) == 0) {
59*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: Cannot find uid: %d", __func__, uid);
60*ec779b8eSAndroid Build Coastguard Worker         return {};
61*ec779b8eSAndroid Build Coastguard Worker     }
62*ec779b8eSAndroid Build Coastguard Worker     auto powerClientStats = mPowerClientStats[uid];
63*ec779b8eSAndroid Build Coastguard Worker     std::unique_ptr<Token> token =
64*ec779b8eSAndroid Build Coastguard Worker             std::make_unique<AudioTrackToken>(powerClientStats, additional);
65*ec779b8eSAndroid Build Coastguard Worker     mOutstandingTokens.emplace(token.get());
66*ec779b8eSAndroid Build Coastguard Worker     return token;
67*ec779b8eSAndroid Build Coastguard Worker }
68*ec779b8eSAndroid Build Coastguard Worker 
startThread(pid_t pid,const std::string & wakeLockName,WakeFlag wakeFlag,const std::string & additional)69*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<Token> AudioPowerManager::startThread(
70*ec779b8eSAndroid Build Coastguard Worker         pid_t pid, const std::string& wakeLockName,
71*ec779b8eSAndroid Build Coastguard Worker         WakeFlag wakeFlag, const std::string& additional) {
72*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mMutex);
73*ec779b8eSAndroid Build Coastguard Worker     std::unique_ptr<Token> token =
74*ec779b8eSAndroid Build Coastguard Worker             std::make_unique<AudioThreadToken>(pid, wakeLockName, wakeFlag, additional);
75*ec779b8eSAndroid Build Coastguard Worker     mOutstandingTokens.emplace(token.get());
76*ec779b8eSAndroid Build Coastguard Worker     return token;
77*ec779b8eSAndroid Build Coastguard Worker }
78*ec779b8eSAndroid Build Coastguard Worker 
toString() const79*ec779b8eSAndroid Build Coastguard Worker std::string AudioPowerManager::toString() const {
80*ec779b8eSAndroid Build Coastguard Worker     const std::string prefix("  ");
81*ec779b8eSAndroid Build Coastguard Worker     std::string result;
82*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mMutex);
83*ec779b8eSAndroid Build Coastguard Worker     result.append("Power Tokens:\n");
84*ec779b8eSAndroid Build Coastguard Worker     std::vector<std::string> tokenInfo;
85*ec779b8eSAndroid Build Coastguard Worker     for (const auto& token: mOutstandingTokens) {
86*ec779b8eSAndroid Build Coastguard Worker         tokenInfo.emplace_back(token->toString());
87*ec779b8eSAndroid Build Coastguard Worker     }
88*ec779b8eSAndroid Build Coastguard Worker     std::sort(tokenInfo.begin(), tokenInfo.end());
89*ec779b8eSAndroid Build Coastguard Worker     for (const auto& info: tokenInfo) {
90*ec779b8eSAndroid Build Coastguard Worker         result.append(prefix).append(info).append("\n");
91*ec779b8eSAndroid Build Coastguard Worker     }
92*ec779b8eSAndroid Build Coastguard Worker     result.append("Power Clients:\n");
93*ec779b8eSAndroid Build Coastguard Worker     for (const auto& [uid, powerClientStats]: mPowerClientStats) {
94*ec779b8eSAndroid Build Coastguard Worker         result.append(powerClientStats->toString(true, prefix));
95*ec779b8eSAndroid Build Coastguard Worker     }
96*ec779b8eSAndroid Build Coastguard Worker     result.append("Power Client History:\n");
97*ec779b8eSAndroid Build Coastguard Worker     for (const auto& [power, powerClientStats]: mHistoricalClients) {
98*ec779b8eSAndroid Build Coastguard Worker         result.append(powerClientStats->toString(true, prefix));
99*ec779b8eSAndroid Build Coastguard Worker     }
100*ec779b8eSAndroid Build Coastguard Worker     return result;
101*ec779b8eSAndroid Build Coastguard Worker }
102*ec779b8eSAndroid Build Coastguard Worker 
stopClient(pid_t pid)103*ec779b8eSAndroid Build Coastguard Worker void AudioPowerManager::stopClient(pid_t pid) {
104*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mMutex);
105*ec779b8eSAndroid Build Coastguard Worker     const auto pidit = mPidToUid.find(pid);
106*ec779b8eSAndroid Build Coastguard Worker     if (pidit == mPidToUid.end()) return;
107*ec779b8eSAndroid Build Coastguard Worker     const uid_t uid = pidit->second;
108*ec779b8eSAndroid Build Coastguard Worker     const auto it = mPowerClientStats.find(uid);
109*ec779b8eSAndroid Build Coastguard Worker     if (it == mPowerClientStats.end()) return;
110*ec779b8eSAndroid Build Coastguard Worker 
111*ec779b8eSAndroid Build Coastguard Worker     auto powerClientStats = it->second;
112*ec779b8eSAndroid Build Coastguard Worker     size_t count = powerClientStats->removePid(pid);
113*ec779b8eSAndroid Build Coastguard Worker     if (count == 0) {
114*ec779b8eSAndroid Build Coastguard Worker         mHistoricalClients[uid] = powerClientStats;
115*ec779b8eSAndroid Build Coastguard Worker         mPowerClientStats.erase(it);
116*ec779b8eSAndroid Build Coastguard Worker         if (mHistoricalClients.size() > kHistory) {
117*ec779b8eSAndroid Build Coastguard Worker             mHistoricalClients.erase(mHistoricalClients.begin()); // remove oldest.
118*ec779b8eSAndroid Build Coastguard Worker         }
119*ec779b8eSAndroid Build Coastguard Worker     }
120*ec779b8eSAndroid Build Coastguard Worker     mPidToUid.erase(pid);
121*ec779b8eSAndroid Build Coastguard Worker }
122*ec779b8eSAndroid Build Coastguard Worker 
clear_token_ptr(Token * token)123*ec779b8eSAndroid Build Coastguard Worker void AudioPowerManager::clear_token_ptr(Token* token) {
124*ec779b8eSAndroid Build Coastguard Worker     if (token != nullptr) {
125*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mMutex);
126*ec779b8eSAndroid Build Coastguard Worker         (void)mOutstandingTokens.erase(token);
127*ec779b8eSAndroid Build Coastguard Worker     }
128*ec779b8eSAndroid Build Coastguard Worker }
129*ec779b8eSAndroid Build Coastguard Worker 
130*ec779b8eSAndroid Build Coastguard Worker /* static */
enabled()131*ec779b8eSAndroid Build Coastguard Worker bool AudioPowerManager::enabled() {
132*ec779b8eSAndroid Build Coastguard Worker     static const bool enabled = com::android::media::audioserver::power_stats()
133*ec779b8eSAndroid Build Coastguard Worker             && property_get_bool("persist.audio.power_stats.enabled", false);
134*ec779b8eSAndroid Build Coastguard Worker     return enabled;
135*ec779b8eSAndroid Build Coastguard Worker }
136*ec779b8eSAndroid Build Coastguard Worker 
137*ec779b8eSAndroid Build Coastguard Worker } // namespace android::media::psh_utils
138