xref: /aosp_15_r20/frameworks/av/services/audiopolicy/service/AudioRecordClient.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2023 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 #include <android/content/pm/IPackageManagerNative.h>
18 
19 #include "AudioRecordClient.h"
20 #include "AudioPolicyService.h"
21 #include "binder/AppOpsManager.h"
22 #include "mediautils/ServiceUtilities.h"
23 #include <android_media_audiopolicy.h>
24 #include <media/AttrSourceIter.h>
25 
26 #include <algorithm>
27 
28 namespace android::media::audiopolicy {
29 namespace audiopolicy_flags = android::media::audiopolicy;
30 using android::AudioPolicyService;
31 
32 namespace {
isAppOpSource(audio_source_t source)33 bool isAppOpSource(audio_source_t source) {
34     switch (source) {
35         case AUDIO_SOURCE_FM_TUNER:
36         case AUDIO_SOURCE_ECHO_REFERENCE:
37         case AUDIO_SOURCE_REMOTE_SUBMIX:
38             return false;
39         default:
40             break;
41     }
42     return true;
43 }
44 
getTargetSdkForPackageName(std::string_view packageName)45 int getTargetSdkForPackageName(std::string_view packageName) {
46     const auto binder = defaultServiceManager()->checkService(String16{"package_native"});
47     int targetSdk = -1;
48     if (binder != nullptr) {
49         const auto pm = interface_cast<content::pm::IPackageManagerNative>(binder);
50         if (pm != nullptr) {
51             const auto status = pm->getTargetSdkVersionForPackage(
52                     String16{packageName.data(), packageName.size()}, &targetSdk);
53             return status.isOk() ? targetSdk : -1;
54         }
55     }
56     return targetSdk;
57 }
58 
doesPackageTargetAtLeastU(std::string_view packageName)59 bool doesPackageTargetAtLeastU(std::string_view packageName) {
60     return getTargetSdkForPackageName(packageName) >= __ANDROID_API_U__;
61 }
62 } // anonymous
63 
64 // static
65 sp<OpRecordAudioMonitor>
createIfNeeded(const AttributionSourceState & attributionSource,const uint32_t virtualDeviceId,const audio_attributes_t & attr,wp<AudioPolicyService::AudioCommandThread> commandThread)66 OpRecordAudioMonitor::createIfNeeded(
67         const AttributionSourceState &attributionSource,
68         const uint32_t virtualDeviceId,
69         const audio_attributes_t &attr,
70         wp<AudioPolicyService::AudioCommandThread> commandThread)
71 {
72     if (isAudioServerOrRootUid(attributionSource.uid)) {
73         ALOGV("not silencing record for audio or root source %s",
74                 attributionSource.toString().c_str());
75         return nullptr;
76     }
77 
78     if (!isAppOpSource(attr.source)) {
79         ALOGD("not monitoring app op for uid %d and source %d",
80                 attributionSource.uid, attr.source);
81         return nullptr;
82     }
83 
84     if (!attributionSource.packageName.has_value()
85             || attributionSource.packageName.value().size() == 0) {
86         return nullptr;
87     }
88 
89     return new OpRecordAudioMonitor(attributionSource, virtualDeviceId, attr,
90                                     getOpForSource(attr.source),
91                                     isRecordOpRequired(attr.source),
92                                     commandThread);
93 }
94 
95 // The vdi is carried in the attribution source for appops perm checks.
96 // Overwrite the entire chain with the vdi associated with the mix this client is attached to
97 // This ensures the checkOps triggered by the listener are correct.
98 // Note: we still only register for events by package name, so we assume that we get events
99 // independent of vdi.
overwriteVdi(AttributionSourceState & chain,int vdi)100 static AttributionSourceState& overwriteVdi(AttributionSourceState& chain, int vdi) {
101     using permission::AttrSourceIter::begin;
102     using permission::AttrSourceIter::end;
103     if (vdi != 0 /* default vdi */) {
104         std::for_each(begin(chain), end(), [vdi](auto& attr) { attr.deviceId = vdi; });
105     }
106     return chain;
107 }
108 
OpRecordAudioMonitor(AttributionSourceState attributionSource,const uint32_t virtualDeviceId,const audio_attributes_t & attr,int32_t appOp,bool shouldMonitorRecord,wp<AudioPolicyService::AudioCommandThread> commandThread)109 OpRecordAudioMonitor::OpRecordAudioMonitor(
110         AttributionSourceState attributionSource,
111         const uint32_t virtualDeviceId, const audio_attributes_t &attr,
112         int32_t appOp,
113         bool shouldMonitorRecord,
114         wp<AudioPolicyService::AudioCommandThread> commandThread) :
115         mHasOp(true),
116         mAttributionSource(overwriteVdi(attributionSource, virtualDeviceId)),
117         mVirtualDeviceId(virtualDeviceId), mAttr(attr),
118         mAppOp(appOp),
119         mShouldMonitorRecord(shouldMonitorRecord),
120         mCommandThread(commandThread) {}
121 
~OpRecordAudioMonitor()122 OpRecordAudioMonitor::~OpRecordAudioMonitor()
123 {
124     if (mOpCallback != 0) {
125         mAppOpsManager.stopWatchingMode(mOpCallback);
126     }
127     mOpCallback.clear();
128 }
129 
onFirstRef()130 void OpRecordAudioMonitor::onFirstRef()
131 {
132     using permission::AttrSourceIter::cbegin;
133     using permission::AttrSourceIter::cend;
134 
135     checkOp();
136     mOpCallback = new RecordAudioOpCallback(this);
137     ALOGV("start watching op %d for %s", mAppOp, mAttributionSource.toString().c_str());
138 
139     int flags = doesPackageTargetAtLeastU(mAttributionSource.packageName.value_or(""))
140                         ? AppOpsManager::WATCH_FOREGROUND_CHANGES
141                         : 0;
142 
143     const auto reg = [&](int32_t op) {
144         std::for_each(cbegin(mAttributionSource), cend(),
145                       [&](const auto& attr) {
146                           mAppOpsManager.startWatchingMode(
147                                   op,
148                                   VALUE_OR_FATAL(aidl2legacy_string_view_String16(
149                                           attr.packageName.value_or(""))),
150                                   flags, mOpCallback);
151                       });
152     };
153     reg(mAppOp);
154     if (mAppOp != AppOpsManager::OP_RECORD_AUDIO && mShouldMonitorRecord) {
155         reg(AppOpsManager::OP_RECORD_AUDIO);
156     }
157 }
158 
hasOp() const159 bool OpRecordAudioMonitor::hasOp() const {
160     return mHasOp.load();
161 }
162 
163 // Called by RecordAudioOpCallback when the app op corresponding to this OpRecordAudioMonitor
164 // is updated in AppOp callback and in onFirstRef()
165 // Note this method is never called (and never to be) for audio server / root track
166 // due to the UID in createIfNeeded(). As a result for those record track, it's:
167 // - not called from constructor,
168 // - not called from RecordAudioOpCallback because the callback is not installed in this case
checkOp(bool updateUidStates)169 void OpRecordAudioMonitor::checkOp(bool updateUidStates) {
170     using permission::AttrSourceIter::cbegin;
171     using permission::AttrSourceIter::cend;
172 
173     const auto check = [&](int32_t op) -> bool {
174         return std::all_of(cbegin(mAttributionSource), cend(), [&](const auto& x) {
175                     return mAppOpsManager.checkOp(op, x.uid,
176                                                   VALUE_OR_FATAL(aidl2legacy_string_view_String16(
177                                                           x.packageName.value_or("")))) ==
178                            AppOpsManager::MODE_ALLOWED;
179                 });
180     };
181     bool hasIt = check(mAppOp);
182     if (mAppOp != AppOpsManager::OP_RECORD_AUDIO && mShouldMonitorRecord) {
183         hasIt = hasIt && check(AppOpsManager::OP_RECORD_AUDIO);
184     }
185 
186     if (audiopolicy_flags::record_audio_device_aware_permission()) {
187         const bool canRecord = recordingAllowed(mAttributionSource, mVirtualDeviceId, mAttr.source);
188         hasIt = hasIt && canRecord;
189     }
190     // verbose logging only log when appOp changed
191     ALOGI_IF(hasIt != mHasOp.load(),
192             "App op %d missing, %ssilencing record %s",
193             mAppOp, hasIt ? "un" : "", mAttributionSource.toString().c_str());
194     mHasOp.store(hasIt);
195 
196     if (updateUidStates) {
197           sp<AudioPolicyService::AudioCommandThread> commandThread = mCommandThread.promote();
198           if (commandThread != nullptr) {
199               commandThread->updateUidStatesCommand();
200           }
201     }
202 }
203 
RecordAudioOpCallback(const wp<OpRecordAudioMonitor> & monitor)204 OpRecordAudioMonitor::RecordAudioOpCallback::RecordAudioOpCallback(
205         const wp<OpRecordAudioMonitor>& monitor) : mMonitor(monitor)
206 { }
207 
opChanged(int32_t op,const String16 & packageName __unused)208 void OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op,
209             const String16& packageName __unused) {
210     sp<OpRecordAudioMonitor> monitor = mMonitor.promote();
211     if (monitor != NULL) {
212         if (op != monitor->getOp()) {
213             return;
214         }
215         monitor->checkOp(true);
216     }
217 }
218 
219 }  // namespace android::media::audiopolicy
220