Allow call audio access for default dialer application

The access to call audio (record and play) will be granted only to the app associated with Dialer role, who also includes a new system permission.

Test: Compilation and manual tests
Bug: 135197853

Change-Id: I65ca823c235d4d3420630837427103783ad1d1b0
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 152883b..2f67a18 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -879,6 +879,7 @@
                                         audio_stream_type_t *stream,
                                         pid_t pid,
                                         uid_t uid,
+                                        const String16& opPackageName,
                                         const audio_config_t *config,
                                         audio_output_flags_t flags,
                                         audio_port_handle_t *selectedDeviceId,
@@ -888,7 +889,7 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return NO_INIT;
     return aps->getOutputForAttr(attr, output, session, stream, pid, uid,
-                                 config,
+                                 opPackageName, config,
                                  flags, selectedDeviceId, portId, secondaryOutputs);
 }
 
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 5b3a057..cccb131 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -214,6 +214,7 @@
                               audio_stream_type_t *stream,
                               pid_t pid,
                               uid_t uid,
+                              const String16& opPackageName,
                               const audio_config_t *config,
                               audio_output_flags_t flags,
                               audio_port_handle_t *selectedDeviceId,
@@ -252,6 +253,7 @@
             }
             data.writeInt32(pid);
             data.writeInt32(uid);
+            data.writeString16(opPackageName);
             data.write(config, sizeof(audio_config_t));
             data.writeInt32(static_cast <uint32_t>(flags));
             data.writeInt32(*selectedDeviceId);
@@ -1645,6 +1647,11 @@
             }
             pid_t pid = (pid_t)data.readInt32();
             uid_t uid = (uid_t)data.readInt32();
+            String16 opPackageName;
+            status = data.readString16(&opPackageName);
+            if (status != NO_ERROR) {
+                return status;
+            }
             audio_config_t config;
             memset(&config, 0, sizeof(audio_config_t));
             data.read(&config, sizeof(audio_config_t));
@@ -1656,7 +1663,7 @@
             std::vector<audio_io_handle_t> secondaryOutputs;
             status = getOutputForAttr(&attr,
                     &output, session, &stream, pid, uid,
-                    &config,
+                    opPackageName, &config,
                     flags, &selectedDeviceId, &portId, &secondaryOutputs);
             reply->writeInt32(status);
             status = reply->write(&attr, sizeof(audio_attributes_t));
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index fe211e0..07a2292 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -240,6 +240,7 @@
                                      audio_stream_type_t *stream,
                                      pid_t pid,
                                      uid_t uid,
+                                     const String16& opPackageName,
                                      const audio_config_t *config,
                                      audio_output_flags_t flags,
                                      audio_port_handle_t *selectedDeviceId,
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 8bc1d83..8658cfa 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -70,6 +70,7 @@
             if (clientInfo.readFromParcel(parcel) != NO_ERROR) {
                 return DEAD_OBJECT;
             }
+            opPackageName = parcel->readString16();
             if (parcel->readInt32() != 0) {
                 // TODO: Using unsecurePointer() has some associated security
                 //       pitfalls (see declaration for details).
@@ -97,6 +98,7 @@
             (void)parcel->write(&attr, sizeof(audio_attributes_t));
             (void)parcel->write(&config, sizeof(audio_config_t));
             (void)clientInfo.writeToParcel(parcel);
+            (void)parcel->writeString16(opPackageName);
             if (sharedBuffer != 0) {
                 (void)parcel->writeInt32(1);
                 (void)parcel->writeStrongBinder(IInterface::asBinder(sharedBuffer));
@@ -119,6 +121,7 @@
         audio_attributes_t attr;
         audio_config_t config;
         AudioClient clientInfo;
+        String16 opPackageName;
         sp<IMemory> sharedBuffer;
         uint32_t notificationsPerBuffer;
         float speed;
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index fe54dc5..779ca43 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -64,6 +64,7 @@
                                       audio_stream_type_t *stream,
                                       pid_t pid,
                                       uid_t uid,
+                                      const String16& opPackageName,
                                       const audio_config_t *config,
                                       audio_output_flags_t flags,
                                       audio_port_handle_t *selectedDeviceId,
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 87ea084..7fd4d0a 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -223,6 +223,25 @@
     return ok;
 }
 
+bool accessCallAudioAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
+    static const String16 sAccessCallAudio("android.permission.ACCESS_CALL_AUDIO");
+    PermissionController permissionController;
+    const String16 resolvedOpPackageName = resolveCallingPackage(
+         permissionController, opPackageName, uid);
+    if (resolvedOpPackageName.size() == 0) {
+        ALOGE("accessCallAudioAllowed - FAIL - package not found.");
+        return false;
+    }
+    AppOpsManager appOps;
+    const int32_t op = appOps.permissionToOpCode(sAccessCallAudio);
+    const int32_t opResult = appOps.noteOp(op, uid, resolvedOpPackageName);
+    if (opResult == PermissionController::MODE_DEFAULT) {
+        // Only allow in case this is a system app with the proper privilege permission
+        return PermissionCache::checkPermission(sAccessCallAudio, pid, uid);
+    }
+    return opResult == PermissionController::MODE_ALLOWED;
+}
+
 // privileged behavior needed by Dialer, Settings, SetupWizard and CellBroadcastReceiver
 bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid) {
     static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS");
@@ -259,28 +278,29 @@
     return NO_ERROR;
 }
 
-sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() {
+void MediaPackageManager::loadPackageManager() {
+    if (mPackageManager != nullptr) {
+        return;
+    }
     const sp<IServiceManager> sm = defaultServiceManager();
     if (sm == nullptr) {
         ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
-        return nullptr;
+        return;
     }
     sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName));
     if (packageManager == nullptr) {
         ALOGW("%s: failed to retrieve native package manager", __func__);
-        return nullptr;
+        return;
     }
-    return interface_cast<content::pm::IPackageManagerNative>(packageManager);
+    mPackageManager = interface_cast<content::pm::IPackageManagerNative>(packageManager);
 }
 
 std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) {
+    /** Can not fetch package manager at construction it may not yet be registered. */
+    loadPackageManager();
     if (mPackageManager == nullptr) {
-        /** Can not fetch package manager at construction it may not yet be registered. */
-        mPackageManager = retreivePackageManager();
-        if (mPackageManager == nullptr) {
-            ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
-            return std::nullopt;
-        }
+        ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
+        return std::nullopt;
     }
 
     std::vector<std::string> packageNames;
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 212599a..060e849 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -93,6 +93,7 @@
 bool dumpAllowed();
 bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
 bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid);
+bool accessCallAudioAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
 
 status_t checkIMemory(const sp<IMemory>& iMemory);
 
@@ -110,7 +111,7 @@
 private:
     static constexpr const char* nativePackageManagerName = "package_native";
     std::optional<bool> doIsAllowed(uid_t uid);
-    sp<content::pm::IPackageManagerNative> retreivePackageManager();
+    void loadPackageManager();
     sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest
     uint_t mPackageManagerErrors = 0;
     struct Package {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 5c5c5bb..e5a6e27 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -326,7 +326,7 @@
         ret = AudioSystem::getOutputForAttr(&localAttr, &io,
                                             actualSessionId,
                                             &streamType, client.clientPid, client.clientUid,
-                                            &fullConfig,
+                                            client.packageName, &fullConfig,
                                             (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
                                                     AUDIO_OUTPUT_FLAG_DIRECT),
                                             deviceId, &portId, &secondaryOutputs);
@@ -766,8 +766,9 @@
     output.outputId = AUDIO_IO_HANDLE_NONE;
     output.selectedDeviceId = input.selectedDeviceId;
     lStatus = AudioSystem::getOutputForAttr(&localAttr, &output.outputId, sessionId, &streamType,
-                                            clientPid, clientUid, &input.config, input.flags,
-                                            &output.selectedDeviceId, &portId, &secondaryOutputs);
+                                            clientPid, clientUid, input.opPackageName,
+                                            &input.config, input.flags, &output.selectedDeviceId,
+                                            &portId, &secondaryOutputs);
 
     if (lStatus != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) {
         ALOGE("createTrack() getOutputForAttr() return error %d or invalid output handle", lStatus);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 6ef2035..2833525 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -8731,6 +8731,7 @@
                                             &stream,
                                             client.clientPid,
                                             client.clientUid,
+                                            client.packageName,
                                             &config,
                                             flags,
                                             &deviceId,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 4d071c8..38801ec 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -211,6 +211,7 @@
                                               audio_stream_type_t *stream,
                                               pid_t pid,
                                               uid_t uid,
+                                              const String16& opPackageName,
                                               const audio_config_t *config,
                                               audio_output_flags_t flags,
                                               audio_port_handle_t *selectedDeviceId,
@@ -257,7 +258,8 @@
         case AudioPolicyInterface::API_OUTPUT_LEGACY:
             break;
         case AudioPolicyInterface::API_OUTPUT_TELEPHONY_TX:
-            if (!modifyPhoneStateAllowed(pid, uid)) {
+          if (!modifyPhoneStateAllowed(pid, uid) &&
+              !accessCallAudioAllowed(opPackageName, pid, uid)) {
                 ALOGE("%s() permission denied: modify phone state not allowed for uid %d",
                     __func__, uid);
                 result = PERMISSION_DENIED;
@@ -454,15 +456,22 @@
     }
 
     bool canCaptureOutput = captureAudioOutputAllowed(pid, uid);
-    if ((inputSource == AUDIO_SOURCE_VOICE_UPLINK ||
-        inputSource == AUDIO_SOURCE_VOICE_DOWNLINK ||
-        inputSource == AUDIO_SOURCE_VOICE_CALL ||
-        inputSource == AUDIO_SOURCE_ECHO_REFERENCE||
-        inputSource == AUDIO_SOURCE_FM_TUNER) &&
+    bool canCaptureTelephonyOutput = canCaptureOutput
+        || accessCallAudioAllowed(opPackageName, pid, uid);
+
+    if ((attr->source == AUDIO_SOURCE_ECHO_REFERENCE ||
+         attr->source == AUDIO_SOURCE_FM_TUNER) &&
         !canCaptureOutput) {
         return PERMISSION_DENIED;
     }
 
+    if ((attr->source == AUDIO_SOURCE_VOICE_UPLINK ||
+        attr->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
+        attr->source == AUDIO_SOURCE_VOICE_CALL) &&
+        !canCaptureTelephonyOutput) {
+        return PERMISSION_DENIED;
+    }
+
     bool canCaptureHotword = captureHotwordAllowed(opPackageName, pid, uid);
     if ((inputSource == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) {
         return BAD_VALUE;
@@ -494,6 +503,11 @@
                 break;
             case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
                 // FIXME: use the same permission as for remote submix for now.
+                if (!canCaptureTelephonyOutput) {
+                    ALOGE("getInputForAttr() permission denied: call capture not allowed");
+                    status = PERMISSION_DENIED;
+                }
+                break;
             case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
                 if (!canCaptureOutput) {
                     ALOGE("getInputForAttr() permission denied: capture not allowed");
@@ -521,9 +535,13 @@
             return status;
         }
 
+        bool allowAudioCapture = canCaptureOutput ||
+            (inputType == AudioPolicyInterface::API_INPUT_TELEPHONY_RX &&
+             canCaptureTelephonyOutput);
+
         sp<AudioRecordClient> client = new AudioRecordClient(*attr, *input, uid, pid, session, *portId,
                                                              *selectedDeviceId, opPackageName,
-                                                             canCaptureOutput, canCaptureHotword);
+                                                             allowAudioCapture, canCaptureHotword);
         mAudioRecordClients.add(*portId, client);
     }
 
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index e5c36ea..99cec5a 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -534,8 +534,8 @@
         //             OR client has CAPTURE_AUDIO_OUTPUT privileged permission
         bool allowCapture = !isAssistantOnTop
                 && ((isTopOrLatestActive && !isLatestSensitive) || isLatestSensitive)
-                && !(isSensitiveActive && !(isLatestSensitive || current->canCaptureOutput))
-                && !(isInCall && !current->canCaptureOutput);
+                && !(isSensitiveActive && !(isLatestSensitive || current->canCaptureCallOrOutput))
+                && !(isInCall && !current->canCaptureCallOrOutput);
 
         if (isVirtualSource(source)) {
             // Allow capture for virtual (remote submix, call audio TX or RX...) sources
@@ -555,7 +555,7 @@
             } else {
                 if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
                         source == AUDIO_SOURCE_HOTWORD) &&
-                        (!(isSensitiveActive || isInCall) || current->canCaptureOutput)) {
+                        (!(isSensitiveActive || isInCall) || current->canCaptureCallOrOutput)) {
                     allowCapture = true;
                 }
             }
@@ -567,7 +567,7 @@
             //     OR
             //         Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
             if (!isAssistantOnTop
-                    && (!(isSensitiveActive || isInCall) || current->canCaptureOutput)) {
+                    && (!(isSensitiveActive || isInCall) || current->canCaptureCallOrOutput)) {
                 allowCapture = true;
             }
             if (isA11yOnTop) {
@@ -580,7 +580,7 @@
             //     All active clients are using HOTWORD source
             //     AND no call is active
             //         OR client has CAPTURE_AUDIO_OUTPUT privileged permission
-            if (onlyHotwordActive && !(isInCall && !current->canCaptureOutput)) {
+            if (onlyHotwordActive && !(isInCall && !current->canCaptureCallOrOutput)) {
                 allowCapture = true;
             }
         }
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 41a0d2b..c3c87f1 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -82,6 +82,7 @@
                               audio_stream_type_t *stream,
                               pid_t pid,
                               uid_t uid,
+                              const String16& opPackageName,
                               const audio_config_t *config,
                               audio_output_flags_t flags,
                               audio_port_handle_t *selectedDeviceId,
@@ -807,15 +808,16 @@
                           const audio_io_handle_t io, uid_t uid, pid_t pid,
                           const audio_session_t session, audio_port_handle_t portId,
                           const audio_port_handle_t deviceId, const String16& opPackageName,
-                          bool canCaptureOutput, bool canCaptureHotword) :
+                          bool canCaptureCallOrOutput, bool canCaptureHotword) :
                     AudioClient(attributes, io, uid, pid, session, portId, deviceId),
                     opPackageName(opPackageName), startTimeNs(0),
-                    canCaptureOutput(canCaptureOutput), canCaptureHotword(canCaptureHotword) {}
+                    canCaptureCallOrOutput(canCaptureCallOrOutput),
+                    canCaptureHotword(canCaptureHotword) {}
                 ~AudioRecordClient() override = default;
 
         const String16 opPackageName;        // client package name
         nsecs_t startTimeNs;
-        const bool canCaptureOutput;
+        const bool canCaptureCallOrOutput;
         const bool canCaptureHotword;
     };