audio: Fix remote submix module device ports handling

 - remove the default address "0" for IN_SUBMIX and OUT_SUBMIX;
 - remove the profiles in the device port and assign profiles when
   connecting;
 - make remote submix input to use "virtual" connection type,
   same as the output;
 - fix ModuleConfig in VTS to avoid returning devices with virtual
   connections as "external devices" because they can actually
   be connected even when connection simulation is disabled;
 - fix TryConnectMissingDevice VTS test to disconnect the device
   if the operation has unexpectedly succeeded.

Bug: 286914845
Bug: 294976817
Test: atest VtsHalAudioCoreTargetTest
Change-Id: Ife11c9c356d1b5dc587d08cef47294e3b29f65c5
diff --git a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
index 9be7837..adea877 100644
--- a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
@@ -19,8 +19,8 @@
 #include <vector>
 
 #include <android-base/logging.h>
+#include <error/expected_utils.h>
 
-#include "RemoteSubmixUtils.h"
 #include "core-impl/ModuleRemoteSubmix.h"
 #include "core-impl/StreamRemoteSubmix.h"
 
@@ -33,18 +33,6 @@
 
 namespace aidl::android::hardware::audio::core {
 
-ndk::ScopedAStatus ModuleRemoteSubmix::getTelephony(std::shared_ptr<ITelephony>* _aidl_return) {
-    *_aidl_return = nullptr;
-    LOG(DEBUG) << __func__ << ": returning null";
-    return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus ModuleRemoteSubmix::getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) {
-    *_aidl_return = nullptr;
-    LOG(DEBUG) << __func__ << ": returning null";
-    return ndk::ScopedAStatus::ok();
-}
-
 ndk::ScopedAStatus ModuleRemoteSubmix::getMicMute(bool* _aidl_return __unused) {
     LOG(DEBUG) << __func__ << ": is not supported";
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -70,23 +58,26 @@
 }
 
 ndk::ScopedAStatus ModuleRemoteSubmix::populateConnectedDevicePort(AudioPort* audioPort) {
-    LOG(VERBOSE) << __func__ << ": Profiles already populated by Configuration";
-    for (auto profile : audioPort->profiles) {
-        for (auto channelMask : profile.channelMasks) {
-            if (!r_submix::isChannelMaskSupported(channelMask)) {
-                LOG(ERROR) << __func__ << ": the profile " << profile.name
-                           << " has unsupported channel mask : " << channelMask.toString();
-                return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
-            }
-        }
-        for (auto sampleRate : profile.sampleRates) {
-            if (!r_submix::isSampleRateSupported(sampleRate)) {
-                LOG(ERROR) << __func__ << ": the profile " << profile.name
-                           << " has unsupported sample rate : " << sampleRate;
-                return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
-            }
-        }
+    // Find the corresponding mix port and copy its profiles.
+    std::vector<AudioRoute> routes;
+    // At this moment, the port has the same ID as the template port, see connectExternalDevice.
+    RETURN_STATUS_IF_ERROR(getAudioRoutesForAudioPort(audioPort->id, &routes));
+    if (routes.empty()) {
+        LOG(ERROR) << __func__ << ": no routes found for the port " << audioPort->toString();
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
+    const auto& route = *routes.begin();
+    AudioPort mixPort;
+    if (route.sinkPortId == audioPort->id) {
+        if (route.sourcePortIds.empty()) {
+            LOG(ERROR) << __func__ << ": invalid route " << route.toString();
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+        RETURN_STATUS_IF_ERROR(getAudioPort(*route.sourcePortIds.begin(), &mixPort));
+    } else {
+        RETURN_STATUS_IF_ERROR(getAudioPort(route.sinkPortId, &mixPort));
+    }
+    audioPort->profiles = mixPort.profiles;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -106,12 +97,6 @@
     return ndk::ScopedAStatus::ok();
 }
 
-void ModuleRemoteSubmix::onExternalDeviceConnectionChanged(
-        const ::aidl::android::media::audio::common::AudioPort& audioPort __unused,
-        bool connected __unused) {
-    LOG(DEBUG) << __func__ << ": do nothing and return";
-}
-
 ndk::ScopedAStatus ModuleRemoteSubmix::onMasterMuteChanged(bool __unused) {
     LOG(DEBUG) << __func__ << ": is not supported";
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
diff --git a/audio/aidl/default/r_submix/RemoteSubmixUtils.cpp b/audio/aidl/default/r_submix/RemoteSubmixUtils.cpp
deleted file mode 100644
index 2f5d17d..0000000
--- a/audio/aidl/default/r_submix/RemoteSubmixUtils.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vector>
-
-#include "RemoteSubmixUtils.h"
-
-namespace aidl::android::hardware::audio::core::r_submix {
-
-bool isChannelMaskSupported(const AudioChannelLayout& channelMask) {
-    const static std::vector<AudioChannelLayout> kSupportedChannelMask = {
-            AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
-                    AudioChannelLayout::LAYOUT_MONO),
-            AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
-                    AudioChannelLayout::LAYOUT_STEREO)};
-
-    if (std::find(kSupportedChannelMask.begin(), kSupportedChannelMask.end(), channelMask) !=
-        kSupportedChannelMask.end()) {
-        return true;
-    }
-    return false;
-}
-
-bool isSampleRateSupported(int sampleRate) {
-    const static std::vector<int> kSupportedSampleRates = {8000,  11025, 12000, 16000, 22050,
-                                                           24000, 32000, 44100, 48000};
-
-    if (std::find(kSupportedSampleRates.begin(), kSupportedSampleRates.end(), sampleRate) !=
-        kSupportedSampleRates.end()) {
-        return true;
-    }
-    return false;
-}
-
-}  // namespace aidl::android::hardware::audio::core::r_submix
diff --git a/audio/aidl/default/r_submix/RemoteSubmixUtils.h b/audio/aidl/default/r_submix/RemoteSubmixUtils.h
deleted file mode 100644
index 952a992..0000000
--- a/audio/aidl/default/r_submix/RemoteSubmixUtils.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <aidl/android/media/audio/common/AudioChannelLayout.h>
-#include <aidl/android/media/audio/common/AudioFormatDescription.h>
-
-using aidl::android::media::audio::common::AudioChannelLayout;
-
-namespace aidl::android::hardware::audio::core::r_submix {
-
-bool isChannelMaskSupported(const AudioChannelLayout& channelMask);
-
-bool isSampleRateSupported(int sampleRate);
-
-}  // namespace aidl::android::hardware::audio::core::r_submix