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 <android_media_audiopolicy.h>
22 
23 namespace android::media::audiopolicy {
24 namespace audiopolicy_flags = android::media::audiopolicy;
25 using android::AudioPolicyService;
26 
27 namespace {
isAppOpSource(audio_source_t source)28 bool isAppOpSource(audio_source_t source)
29 {
30     switch (source) {
31         case AUDIO_SOURCE_FM_TUNER:
32         case AUDIO_SOURCE_ECHO_REFERENCE:
33         case AUDIO_SOURCE_REMOTE_SUBMIX:
34             return false;
35         default:
36             break;
37     }
38     return true;
39 }
40 
getTargetSdkForPackageName(std::string_view packageName)41 int getTargetSdkForPackageName(std::string_view packageName) {
42     const auto binder = defaultServiceManager()->checkService(String16{"package_native"});
43     int targetSdk = -1;
44     if (binder != nullptr) {
45         const auto pm = interface_cast<content::pm::IPackageManagerNative>(binder);
46         if (pm != nullptr) {
47             const auto status = pm->getTargetSdkVersionForPackage(
48                     String16{packageName.data(), packageName.size()}, &targetSdk);
49             return status.isOk() ? targetSdk : -1;
50         }
51     }
52     return targetSdk;
53 }
54 
doesPackageTargetAtLeastU(std::string_view packageName)55 bool doesPackageTargetAtLeastU(std::string_view packageName) {
56     return getTargetSdkForPackageName(packageName) >= __ANDROID_API_U__;
57 }
58 }
59 
60 // static
61 sp<OpRecordAudioMonitor>
createIfNeeded(const AttributionSourceState & attributionSource,const uint32_t virtualDeviceId,const audio_attributes_t & attr,wp<AudioPolicyService::AudioCommandThread> commandThread)62 OpRecordAudioMonitor::createIfNeeded(
63         const AttributionSourceState &attributionSource,
64         const uint32_t virtualDeviceId,
65         const audio_attributes_t &attr,
66         wp<AudioPolicyService::AudioCommandThread> commandThread)
67 {
68     if (isAudioServerOrRootUid(attributionSource.uid)) {
69         ALOGV("not silencing record for audio or root source %s",
70                 attributionSource.toString().c_str());
71         return nullptr;
72     }
73 
74     if (!isAppOpSource(attr.source)) {
75         ALOGD("not monitoring app op for uid %d and source %d",
76                 attributionSource.uid, attr.source);
77         return nullptr;
78     }
79 
80     if (!attributionSource.packageName.has_value()
81             || attributionSource.packageName.value().size() == 0) {
82         return nullptr;
83     }
84 
85     return new OpRecordAudioMonitor(attributionSource, virtualDeviceId, attr,
86                                     getOpForSource(attr.source), commandThread);
87 }
88 
OpRecordAudioMonitor(const AttributionSourceState & attributionSource,const uint32_t virtualDeviceId,const audio_attributes_t & attr,int32_t appOp,wp<AudioPolicyService::AudioCommandThread> commandThread)89 OpRecordAudioMonitor::OpRecordAudioMonitor(
90         const AttributionSourceState &attributionSource,
91         const uint32_t virtualDeviceId, const audio_attributes_t &attr,
92         int32_t appOp,
93         wp<AudioPolicyService::AudioCommandThread> commandThread) :
94         mHasOp(true), mAttributionSource(attributionSource),
95         mVirtualDeviceId(virtualDeviceId), mAttr(attr), mAppOp(appOp),
96         mCommandThread(commandThread) {
97 }
98 
~OpRecordAudioMonitor()99 OpRecordAudioMonitor::~OpRecordAudioMonitor()
100 {
101     if (mOpCallback != 0) {
102         mAppOpsManager.stopWatchingMode(mOpCallback);
103     }
104     mOpCallback.clear();
105 }
106 
onFirstRef()107 void OpRecordAudioMonitor::onFirstRef()
108 {
109     checkOp();
110     mOpCallback = new RecordAudioOpCallback(this);
111     ALOGV("start watching op %d for %s", mAppOp, mAttributionSource.toString().c_str());
112 
113     int flags = doesPackageTargetAtLeastU(
114             mAttributionSource.packageName.value_or("")) ?
115             AppOpsManager::WATCH_FOREGROUND_CHANGES : 0;
116     // TODO: We need to always watch AppOpsManager::OP_RECORD_AUDIO too
117     // since it controls the mic permission for legacy apps.
118     mAppOpsManager.startWatchingMode(mAppOp, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
119         mAttributionSource.packageName.value_or(""))),
120         flags,
121         mOpCallback);
122 }
123 
hasOp() const124 bool OpRecordAudioMonitor::hasOp() const {
125     return mHasOp.load();
126 }
127 
128 // Called by RecordAudioOpCallback when the app op corresponding to this OpRecordAudioMonitor
129 // is updated in AppOp callback and in onFirstRef()
130 // Note this method is never called (and never to be) for audio server / root track
131 // due to the UID in createIfNeeded(). As a result for those record track, it's:
132 // - not called from constructor,
133 // - not called from RecordAudioOpCallback because the callback is not installed in this case
checkOp(bool updateUidStates)134 void OpRecordAudioMonitor::checkOp(bool updateUidStates)
135 {
136     // TODO: We need to always check AppOpsManager::OP_RECORD_AUDIO too
137     // since it controls the mic permission for legacy apps.
138     const int32_t mode = mAppOpsManager.checkOp(mAppOp,
139             mAttributionSource.uid, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
140                 mAttributionSource.packageName.value_or(""))));
141     bool hasIt = (mode == AppOpsManager::MODE_ALLOWED);
142 
143     if (audiopolicy_flags::record_audio_device_aware_permission()) {
144         const bool canRecord = recordingAllowed(mAttributionSource, mVirtualDeviceId, mAttr.source);
145         hasIt = hasIt && canRecord;
146     }
147     // verbose logging only log when appOp changed
148     ALOGI_IF(hasIt != mHasOp.load(),
149             "App op %d missing, %ssilencing record %s",
150             mAppOp, hasIt ? "un" : "", mAttributionSource.toString().c_str());
151     mHasOp.store(hasIt);
152 
153     if (updateUidStates) {
154           sp<AudioPolicyService::AudioCommandThread> commandThread = mCommandThread.promote();
155           if (commandThread != nullptr) {
156               commandThread->updateUidStatesCommand();
157           }
158     }
159 }
160 
RecordAudioOpCallback(const wp<OpRecordAudioMonitor> & monitor)161 OpRecordAudioMonitor::RecordAudioOpCallback::RecordAudioOpCallback(
162         const wp<OpRecordAudioMonitor>& monitor) : mMonitor(monitor)
163 { }
164 
opChanged(int32_t op,const String16 & packageName __unused)165 void OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op,
166             const String16& packageName __unused) {
167     sp<OpRecordAudioMonitor> monitor = mMonitor.promote();
168     if (monitor != NULL) {
169         if (op != monitor->getOp()) {
170             return;
171         }
172         monitor->checkOp(true);
173     }
174 }
175 
176 } // android::media::audiopolicy::internal
177