Merge "audioservice: add RTT mode observer" into qt-dev
am: e81a326d90

Change-Id: Ib14ec53635da419711c3e084a3b76dbaf199eaa0
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 1e7f9fa..02dc516 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1512,6 +1512,13 @@
     return aps->getVolumeGroupFromAudioAttributes(aa, volumeGroup);
 }
 
+status_t AudioSystem::setRttEnabled(bool enabled)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->setRttEnabled(enabled);
+}
+
 // ---------------------------------------------------------------------------
 
 int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index c548457..64f0aca 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -104,6 +104,7 @@
     GET_VOLUME_GROUP_FOR_ATTRIBUTES,
     SET_ALLOWED_CAPTURE_POLICY,
     MOVE_EFFECTS_TO_IO,
+    SET_RTT_ENABLED
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -1271,6 +1272,18 @@
         volumeGroup = static_cast<volume_group_t>(reply.readInt32());
         return NO_ERROR;
     }
+
+    virtual status_t setRttEnabled(bool enabled)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(static_cast<int32_t>(enabled));
+        status_t status = remote()->transact(SET_RTT_ENABLED, data, &reply);
+        if (status != NO_ERROR) {
+           return status;
+        }
+        return static_cast<status_t>(reply.readInt32());
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1332,7 +1345,8 @@
         case REMOVE_UID_DEVICE_AFFINITY:
         case GET_OFFLOAD_FORMATS_A2DP:
         case LIST_AUDIO_VOLUME_GROUPS:
-        case GET_VOLUME_GROUP_FOR_ATTRIBUTES: {
+        case GET_VOLUME_GROUP_FOR_ATTRIBUTES:
+        case SET_RTT_ENABLED: {
             if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                       __func__, code, IPCThreadState::self()->getCallingPid(),
@@ -2347,6 +2361,14 @@
             return NO_ERROR;
         }
 
+        case SET_RTT_ENABLED: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            bool enabled = static_cast<bool>(data.readInt32());
+            status_t status = setRttEnabled(enabled);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 56c69f6..09e80b2 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -394,6 +394,8 @@
     static status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
                                                       volume_group_t &volumeGroup);
 
+    static status_t setRttEnabled(bool enabled);
+
     // ----------------------------------------------------------------------------
 
     class AudioVolumeGroupCallback : public RefBase
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 33ab1f9..32275cf 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -220,6 +220,8 @@
     virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) = 0;
     virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
                                                        volume_group_t &volumeGroup) = 0;
+
+    virtual status_t setRttEnabled(bool enabled) = 0;
 };
 
 
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 16fdeaf..b824212 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -128,7 +128,7 @@
     if (isAudioServerOrRootUid(uid)) return true;
     static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
     bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid);
-    if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
+    if (!ok) ALOGV("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
     return ok;
 }
 
@@ -149,7 +149,7 @@
         // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
         ok = PermissionCache::checkPermission(sCaptureHotwordAllowed, pid, uid);
     }
-    if (!ok) ALOGE("android.permission.CAPTURE_AUDIO_HOTWORD");
+    if (!ok) ALOGV("android.permission.CAPTURE_AUDIO_HOTWORD");
     return ok;
 }
 
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index b0a8541..fa8da89 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -193,7 +193,8 @@
     if (!mPackageManager.allowPlaybackCapture(uid)) {
         attr->flags |= AUDIO_FLAG_NO_MEDIA_PROJECTION;
     }
-    if (!bypassInterruptionPolicyAllowed(pid, uid)) {
+    if (((attr->flags & (AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE)) != 0)
+            && !bypassInterruptionPolicyAllowed(pid, uid)) {
         attr->flags &= ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE);
     }
     audio_output_flags_t originalFlags = flags;
@@ -1316,4 +1317,12 @@
     Mutex::Autolock _l(mLock);
     return mAudioPolicyManager->getVolumeGroupFromAudioAttributes(aa, volumeGroup);
 }
+
+status_t AudioPolicyService::setRttEnabled(bool enabled)
+{
+    Mutex::Autolock _l(mLock);
+    mUidPolicy->setRttEnabled(enabled);
+    return NO_ERROR;
+}
+
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index e3c72ae..77f7997 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -409,7 +409,7 @@
 //    following cases:
 //    Another client in the same UID has already been allowed to capture
 //    OR The client is the assistant
-//        AND an accessibility service is on TOP
+//        AND an accessibility service is on TOP or a RTT call is active
 //               AND the source is VOICE_RECOGNITION or HOTWORD
 //        OR uses VOICE_RECOGNITION AND is on TOP
 //               OR uses HOTWORD
@@ -436,6 +436,9 @@
     bool isAssistantOnTop = false;
     bool isSensitiveActive = false;
     bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL;
+    bool rttCallActive =
+            (mPhoneState == AUDIO_MODE_IN_CALL || mPhoneState == AUDIO_MODE_IN_COMMUNICATION)
+            && mUidPolicy->isRttEnabled();
 
     // if Sensor Privacy is enabled then all recordings should be silenced.
     if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
@@ -518,13 +521,13 @@
             allowCapture = true;
         } else if (mUidPolicy->isAssistantUid(current->uid)) {
             // For assistant allow capture if:
-            //     An accessibility service is on TOP
+            //     An accessibility service is on TOP or a RTT call is active
             //            AND the source is VOICE_RECOGNITION or HOTWORD
             //     OR is on TOP AND uses VOICE_RECOGNITION
             //            OR uses HOTWORD
             //         AND there is no active privacy sensitive capture or call
             //             OR client has CAPTURE_AUDIO_OUTPUT privileged permission
-            if (isA11yOnTop) {
+            if (isA11yOnTop || rttCallActive) {
                 if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
                     allowCapture = true;
                 }
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 8db63a5..e467f70 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -256,6 +256,8 @@
     virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
                                                        volume_group_t &volumeGroup);
 
+    virtual status_t setRttEnabled(bool enabled);
+
             status_t doStopOutput(audio_port_handle_t portId);
             void doReleaseOutput(audio_port_handle_t portId);
 
@@ -345,7 +347,8 @@
     class UidPolicy : public BnUidObserver, public virtual IBinder::DeathRecipient {
     public:
         explicit UidPolicy(wp<AudioPolicyService> service)
-                : mService(service), mObserverRegistered(false), mAssistantUid(0) {}
+                : mService(service), mObserverRegistered(false),
+                  mAssistantUid(0), mRttEnabled(false) {}
 
         void registerSelf();
         void unregisterSelf();
@@ -360,6 +363,8 @@
         void setA11yUids(const std::vector<uid_t>& uids) { mA11yUids.clear(); mA11yUids = uids; }
         bool isA11yUid(uid_t uid);
         bool isA11yOnTop();
+        void setRttEnabled(bool enabled) { mRttEnabled = enabled; }
+        bool isRttEnabled() { return mRttEnabled; }
 
         // BnUidObserver implementation
         void onUidActive(uid_t uid) override;
@@ -387,6 +392,7 @@
         std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
         uid_t mAssistantUid;
         std::vector<uid_t> mA11yUids;
+        bool mRttEnabled;
     };
 
     // If sensor privacy is enabled then all apps, including those that are active, should be