Allow DEFAULT_INPUT_METHOD to capture audio during RTT call

The UID of the current InputMethodService (DEFAULT_INPUT_METHOD) is
pushed from AudioService to AudioPolicyService via AudioSystem.
Allow capture audio if:
- the UID is the current InputMethodService's UID,
- AND a RTT call is active,
- AND the source is AUDIO_SOURCE_VOICE_RECOGNITION.

Bug: 147037345
Test: use voice input with Gboard 9.1.4 during a simulated RTT call.
Change-Id: Ib32ec25e962833eddd0320742e177e3c1e0e5c05
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index b961209..ff2608c 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1479,6 +1479,14 @@
     return aps->setA11yServicesUids(uids);
 }
 
+status_t AudioSystem::setCurrentImeUid(uid_t uid)
+{
+    const sp <IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+
+    return aps->setCurrentImeUid(uid);
+}
+
 bool AudioSystem::isHapticPlaybackSupported()
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 4d2e369..1fd17fd 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -114,6 +114,7 @@
     GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY,
     GET_DEVICES_FOR_ATTRIBUTES,
     AUDIO_MODULES_UPDATED,  // oneway
+    SET_CURRENT_IME_UID,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -1145,6 +1146,18 @@
         return static_cast <status_t> (reply.readInt32());
     }
 
+    virtual status_t setCurrentImeUid(uid_t uid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        status_t status = remote()->transact(SET_CURRENT_IME_UID, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        return static_cast <status_t> (reply.readInt32());
+    }
+
     virtual bool isHapticPlaybackSupported()
     {
         Parcel data, reply;
@@ -1529,7 +1542,8 @@
         case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY:
         case GET_DEVICES_FOR_ATTRIBUTES:
         case SET_ALLOWED_CAPTURE_POLICY:
-        case AUDIO_MODULES_UPDATED: {
+        case AUDIO_MODULES_UPDATED:
+        case SET_CURRENT_IME_UID: {
             if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                       __func__, code, IPCThreadState::self()->getCallingPid(),
@@ -2680,6 +2694,18 @@
             return NO_ERROR;
         } break;
 
+        case SET_CURRENT_IME_UID: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            int32_t uid;
+            status_t status = data.readInt32(&uid);
+            if (status != NO_ERROR) {
+                return status;
+            }
+            status = setCurrentImeUid(uid);
+            reply->writeInt32(static_cast <int32_t>(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 6e395e0..575c910 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -399,6 +399,7 @@
 
     static status_t setAssistantUid(uid_t uid);
     static status_t setA11yServicesUids(const std::vector<uid_t>& uids);
+    static status_t setCurrentImeUid(uid_t uid);
 
     static bool     isHapticPlaybackSupported();
 
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 0ceca85..62066bf 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -221,6 +221,7 @@
 
     virtual status_t setAssistantUid(uid_t uid) = 0;
     virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids) = 0;
+    virtual status_t setCurrentImeUid(uid_t uid) = 0;
 
     virtual bool     isHapticPlaybackSupported() = 0;
     virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 57b23b7..6d79c94 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1420,6 +1420,13 @@
     return NO_ERROR;
 }
 
+status_t AudioPolicyService::setCurrentImeUid(uid_t uid)
+{
+    Mutex::Autolock _l(mLock);
+    mUidPolicy->setCurrentImeUid(uid);
+    return NO_ERROR;
+}
+
 bool AudioPolicyService::isHapticPlaybackSupported()
 {
     if (mAudioPolicyManager == NULL) {
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index dd46ffb..cbe6eb9 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -437,6 +437,8 @@
 //            OR all active clients are using HOTWORD source
 //        AND no call is active
 //            OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+//    OR the client is the current InputMethodService
+//        AND a RTT call is active AND the source is VOICE_RECOGNITION
 //    OR Any client
 //        AND The assistant is not on TOP
 //        AND is on TOP or latest started
@@ -627,6 +629,12 @@
                     && canCaptureIfInCallOrCommunication(current)) {
                 allowCapture = true;
             }
+        } else if (mUidPolicy->isCurrentImeUid(current->uid)) {
+            // For current InputMethodService allow capture if:
+            //     A RTT call is active AND the source is VOICE_RECOGNITION
+            if (rttCallActive && source == AUDIO_SOURCE_VOICE_RECOGNITION) {
+                allowCapture = true;
+            }
         }
         setAppState_l(current->portId,
                       allowCapture ? apmStatFromAmState(mUidPolicy->getUidState(current->uid)) :
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 9a619dd..3f24276 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -261,6 +261,7 @@
 
     virtual status_t setAssistantUid(uid_t uid);
     virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids);
+    virtual status_t setCurrentImeUid(uid_t uid);
 
     virtual bool     isHapticPlaybackSupported();
 
@@ -371,7 +372,7 @@
     public:
         explicit UidPolicy(wp<AudioPolicyService> service)
                 : mService(service), mObserverRegistered(false),
-                  mAssistantUid(0), mRttEnabled(false) {}
+                  mAssistantUid(0), mCurrentImeUid(0), mRttEnabled(false) {}
 
         void registerSelf();
         void unregisterSelf();
@@ -386,6 +387,8 @@
         void setA11yUids(const std::vector<uid_t>& uids) { mA11yUids.clear(); mA11yUids = uids; }
         bool isA11yUid(uid_t uid);
         bool isA11yOnTop();
+        void setCurrentImeUid(uid_t uid) { mCurrentImeUid = uid; }
+        bool isCurrentImeUid(uid_t uid) { return uid == mCurrentImeUid; }
         void setRttEnabled(bool enabled) { mRttEnabled = enabled; }
         bool isRttEnabled() { return mRttEnabled; }
 
@@ -417,6 +420,7 @@
         std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
         uid_t mAssistantUid;
         std::vector<uid_t> mA11yUids;
+        uid_t mCurrentImeUid;
         bool mRttEnabled;
     };