Merge "Fix Heap use after free in clearkey getSecureStops"
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index e39f885..b159ec3 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -74,6 +74,7 @@
 using android::MediaMuxer;
 using android::Overlay;
 using android::PersistentSurface;
+using android::PhysicalDisplayId;
 using android::ProcessState;
 using android::Rect;
 using android::String8;
@@ -116,7 +117,7 @@
 static uint32_t gBitRate = 20000000;     // 20Mbps
 static uint32_t gTimeLimitSec = kMaxTimeLimitSec;
 static uint32_t gBframes = 0;
-
+static PhysicalDisplayId gPhysicalDisplayId;
 // Set by signal handler to stop recording.
 static volatile bool gStopRequested = false;
 
@@ -269,14 +270,14 @@
 static status_t setDisplayProjection(
         SurfaceComposerClient::Transaction& t,
         const sp<IBinder>& dpy,
-        const DisplayInfo& mainDpyInfo) {
+        const DisplayInfo& displayInfo) {
 
     // Set the region of the layer stack we're interested in, which in our
     // case is "all of it".
-    Rect layerStackRect(mainDpyInfo.viewportW, mainDpyInfo.viewportH);
+    Rect layerStackRect(displayInfo.viewportW, displayInfo.viewportH);
 
     // We need to preserve the aspect ratio of the display.
-    float displayAspect = (float) mainDpyInfo.viewportH / (float) mainDpyInfo.viewportW;
+    float displayAspect = (float) displayInfo.viewportH / (float) displayInfo.viewportW;
 
 
     // Set the way we map the output onto the display surface (which will
@@ -335,16 +336,15 @@
  * Configures the virtual display.  When this completes, virtual display
  * frames will start arriving from the buffer producer.
  */
-static status_t prepareVirtualDisplay(const DisplayInfo& mainDpyInfo,
+static status_t prepareVirtualDisplay(const DisplayInfo& displayInfo,
         const sp<IGraphicBufferProducer>& bufferProducer,
         sp<IBinder>* pDisplayHandle) {
     sp<IBinder> dpy = SurfaceComposerClient::createDisplay(
             String8("ScreenRecorder"), false /*secure*/);
-
     SurfaceComposerClient::Transaction t;
     t.setDisplaySurface(dpy, bufferProducer);
-    setDisplayProjection(t, dpy, mainDpyInfo);
-    t.setDisplayLayerStack(dpy, 0);    // default stack
+    setDisplayProjection(t, dpy, displayInfo);
+    t.setDisplayLayerStack(dpy, displayInfo.layerStack);
     t.apply();
 
     *pDisplayHandle = dpy;
@@ -406,7 +406,7 @@
  * The muxer must *not* have been started before calling.
  */
 static status_t runEncoder(const sp<MediaCodec>& encoder,
-        const sp<MediaMuxer>& muxer, FILE* rawFp, const sp<IBinder>& mainDpy,
+        const sp<MediaMuxer>& muxer, FILE* rawFp, const sp<IBinder>& display,
         const sp<IBinder>& virtualDpy, uint8_t orientation) {
     static int kTimeout = 250000;   // be responsive on signal
     status_t err;
@@ -415,7 +415,7 @@
     uint32_t debugNumFrames = 0;
     int64_t startWhenNsec = systemTime(CLOCK_MONOTONIC);
     int64_t endWhenNsec = startWhenNsec + seconds_to_nanoseconds(gTimeLimitSec);
-    DisplayInfo mainDpyInfo;
+    DisplayInfo displayInfo;
     Vector<int64_t> timestamps;
     bool firstFrame = true;
 
@@ -472,16 +472,16 @@
                     //
                     // Polling for changes is inefficient and wrong, but the
                     // useful stuff is hard to get at without a Dalvik VM.
-                    err = SurfaceComposerClient::getDisplayInfo(mainDpy,
-                            &mainDpyInfo);
+                    err = SurfaceComposerClient::getDisplayInfo(display,
+                            &displayInfo);
                     if (err != NO_ERROR) {
                         ALOGW("getDisplayInfo(main) failed: %d", err);
-                    } else if (orientation != mainDpyInfo.orientation) {
-                        ALOGD("orientation changed, now %d", mainDpyInfo.orientation);
+                    } else if (orientation != displayInfo.orientation) {
+                        ALOGD("orientation changed, now %d", displayInfo.orientation);
                         SurfaceComposerClient::Transaction t;
-                        setDisplayProjection(t, virtualDpy, mainDpyInfo);
+                        setDisplayProjection(t, virtualDpy, displayInfo);
                         t.apply();
-                        orientation = mainDpyInfo.orientation;
+                        orientation = displayInfo.orientation;
                     }
                 }
 
@@ -661,32 +661,33 @@
     self->startThreadPool();
 
     // Get main display parameters.
-    const sp<IBinder> mainDpy = SurfaceComposerClient::getInternalDisplayToken();
-    if (mainDpy == nullptr) {
+    sp<IBinder> display = SurfaceComposerClient::getPhysicalDisplayToken(
+            gPhysicalDisplayId);
+    if (display == nullptr) {
         fprintf(stderr, "ERROR: no display\n");
         return NAME_NOT_FOUND;
     }
 
-    DisplayInfo mainDpyInfo;
-    err = SurfaceComposerClient::getDisplayInfo(mainDpy, &mainDpyInfo);
+    DisplayInfo displayInfo;
+    err = SurfaceComposerClient::getDisplayInfo(display, &displayInfo);
     if (err != NO_ERROR) {
         fprintf(stderr, "ERROR: unable to get display characteristics\n");
         return err;
     }
 
     if (gVerbose) {
-        printf("Main display is %dx%d @%.2ffps (orientation=%u)\n",
-                mainDpyInfo.viewportW, mainDpyInfo.viewportH, mainDpyInfo.fps,
-                mainDpyInfo.orientation);
+        printf("Display is %dx%d @%.2ffps (orientation=%u), layerStack=%u\n",
+                displayInfo.viewportW, displayInfo.viewportH, displayInfo.fps,
+                displayInfo.orientation, displayInfo.layerStack);
         fflush(stdout);
     }
 
     // Encoder can't take odd number as config
     if (gVideoWidth == 0) {
-        gVideoWidth = floorToEven(mainDpyInfo.viewportW);
+        gVideoWidth = floorToEven(displayInfo.viewportW);
     }
     if (gVideoHeight == 0) {
-        gVideoHeight = floorToEven(mainDpyInfo.viewportH);
+        gVideoHeight = floorToEven(displayInfo.viewportH);
     }
 
     // Configure and start the encoder.
@@ -694,7 +695,7 @@
     sp<FrameOutput> frameOutput;
     sp<IGraphicBufferProducer> encoderInputSurface;
     if (gOutputFormat != FORMAT_FRAMES && gOutputFormat != FORMAT_RAW_FRAMES) {
-        err = prepareEncoder(mainDpyInfo.fps, &encoder, &encoderInputSurface);
+        err = prepareEncoder(displayInfo.fps, &encoder, &encoderInputSurface);
 
         if (err != NO_ERROR && !gSizeSpecified) {
             // fallback is defined for landscape; swap if we're in portrait
@@ -707,7 +708,7 @@
                         gVideoWidth, gVideoHeight, newWidth, newHeight);
                 gVideoWidth = newWidth;
                 gVideoHeight = newHeight;
-                err = prepareEncoder(mainDpyInfo.fps, &encoder,
+                err = prepareEncoder(displayInfo.fps, &encoder,
                         &encoderInputSurface);
             }
         }
@@ -755,7 +756,7 @@
 
     // Configure virtual display.
     sp<IBinder> dpy;
-    err = prepareVirtualDisplay(mainDpyInfo, bufferProducer, &dpy);
+    err = prepareVirtualDisplay(displayInfo, bufferProducer, &dpy);
     if (err != NO_ERROR) {
         if (encoder != NULL) encoder->release();
         return err;
@@ -838,8 +839,8 @@
         }
     } else {
         // Main encoder loop.
-        err = runEncoder(encoder, muxer, rawFp, mainDpy, dpy,
-                mainDpyInfo.orientation);
+        err = runEncoder(encoder, muxer, rawFp, display, dpy,
+                displayInfo.orientation);
         if (err != NO_ERROR) {
             fprintf(stderr, "Encoder failed (err=%d)\n", err);
             // fall through to cleanup
@@ -1005,6 +1006,9 @@
         "    in videos captured to illustrate bugs.\n"
         "--time-limit TIME\n"
         "    Set the maximum recording time, in seconds.  Default / maximum is %d.\n"
+        "--display-id ID\n"
+        "    specify the physical display ID to record. Default is the primary display.\n"
+        "    see \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n"
         "--verbose\n"
         "    Display interesting information on stdout.\n"
         "--help\n"
@@ -1036,9 +1040,18 @@
         { "monotonic-time",     no_argument,        NULL, 'm' },
         { "persistent-surface", no_argument,        NULL, 'p' },
         { "bframes",            required_argument,  NULL, 'B' },
+        { "display-id",         required_argument,  NULL, 'd' },
         { NULL,                 0,                  NULL, 0 }
     };
 
+    std::optional<PhysicalDisplayId> displayId = SurfaceComposerClient::getInternalDisplayId();
+    if (!displayId) {
+        fprintf(stderr, "Failed to get token for internal display\n");
+        return 1;
+    }
+
+    gPhysicalDisplayId = *displayId;
+
     while (true) {
         int optionIndex = 0;
         int ic = getopt_long(argc, argv, "", longOptions, &optionIndex);
@@ -1133,6 +1146,18 @@
                 return 2;
             }
             break;
+        case 'd':
+            gPhysicalDisplayId = atoll(optarg);
+            if (gPhysicalDisplayId == 0) {
+                fprintf(stderr, "Please specify a valid physical display id\n");
+                return 2;
+            } else if (SurfaceComposerClient::
+                    getPhysicalDisplayToken(gPhysicalDisplayId) == nullptr) {
+                fprintf(stderr, "Invalid physical display id: %"
+                        ANDROID_PHYSICAL_DISPLAY_ID_FORMAT "\n", gPhysicalDisplayId);
+                return 2;
+            }
+            break;
         default:
             if (ic != '?') {
                 fprintf(stderr, "getopt_long returned unexpected value 0x%x\n", ic);
diff --git a/cmds/screenrecord/screenrecord.h b/cmds/screenrecord/screenrecord.h
index 9b058c2..cec7c13 100644
--- a/cmds/screenrecord/screenrecord.h
+++ b/cmds/screenrecord/screenrecord.h
@@ -18,6 +18,6 @@
 #define SCREENRECORD_SCREENRECORD_H
 
 #define kVersionMajor 1
-#define kVersionMinor 2
+#define kVersionMinor 3
 
 #endif /*SCREENRECORD_SCREENRECORD_H*/
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 0f0c72c..f4c277c 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -16,6 +16,7 @@
         "android.hardware.cas.native@1.0",
         "android.hidl.token@1.0-utils",
         "android.hidl.allocator@1.0",
+        "libcrypto",
         "libhidlmemory",
         "libhidlbase",
         "liblog",
@@ -29,7 +30,6 @@
     ],
 
     static_libs: [
-        "libcrypto",
         "libstagefright_foundation_without_imemory",
         "libstagefright_mpeg2support",
         "libutils",
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index e041533..af21a99 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -250,8 +250,8 @@
                          ALOGE("CB_ERROR: err is expected.");
                          break;
                      }
-                     if (!msg->findInt32("action", &actionCode)) {
-                         ALOGE("CB_ERROR: action is expected.");
+                     if (!msg->findInt32("actionCode", &actionCode)) {
+                         ALOGE("CB_ERROR: actionCode is expected.");
                          break;
                      }
                      msg->findString("detail", &detail);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 27d7856..b01e485 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -19,6 +19,9 @@
 #define LOG_TAG "AudioFlinger"
 //#define LOG_NDEBUG 0
 
+// Define AUDIO_ARRAYS_STATIC_CHECK to check all audio arrays are correct
+#define AUDIO_ARRAYS_STATIC_CHECK 1
+
 #include "Configuration.h"
 #include <dirent.h>
 #include <math.h>
diff --git a/services/audiopolicy/TEST_MAPPING b/services/audiopolicy/TEST_MAPPING
index a94fd87..eb6c19e 100644
--- a/services/audiopolicy/TEST_MAPPING
+++ b/services/audiopolicy/TEST_MAPPING
@@ -2,9 +2,6 @@
   "presubmit": [
     {
        "name": "audiopolicy_tests"
-    },
-    {
-       "name": "systemaudio_tests"
     }
   ]
 }
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index df23410..6f627f0 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -38,29 +38,3 @@
     test_suites: ["device-tests"],
 
 }
-
-// system/audio.h utilities test
-
-cc_test {
-    name: "systemaudio_tests",
-
-    shared_libs: [
-        "libaudiofoundation",
-        "libbase",
-        "liblog",
-        "libmedia_helper",
-        "libutils",
-    ],
-
-    header_libs: ["libmedia_headers"],
-
-    srcs: ["systemaudio_tests.cpp"],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-
-    test_suites: ["device-tests"],
-
-}
diff --git a/services/audiopolicy/tests/systemaudio_tests.cpp b/services/audiopolicy/tests/systemaudio_tests.cpp
deleted file mode 100644
index 1e4d07f..0000000
--- a/services/audiopolicy/tests/systemaudio_tests.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2018 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 <unordered_set>
-
-#include <gtest/gtest.h>
-
-#define LOG_TAG "SysAudio_Test"
-#include <log/log.h>
-#include <media/PatchBuilder.h>
-#include <system/audio.h>
-
-using namespace android;
-
-TEST(SystemAudioTest, PatchInvalid) {
-    audio_patch patch{};
-    ASSERT_FALSE(audio_patch_is_valid(&patch));
-    patch.num_sources = AUDIO_PATCH_PORTS_MAX + 1;
-    patch.num_sinks = 1;
-    ASSERT_FALSE(audio_patch_is_valid(&patch));
-    patch.num_sources = 1;
-    patch.num_sinks = AUDIO_PATCH_PORTS_MAX + 1;
-    ASSERT_FALSE(audio_patch_is_valid(&patch));
-    patch.num_sources = 0;
-    patch.num_sinks = 1;
-    ASSERT_FALSE(audio_patch_is_valid(&patch));
-}
-
-TEST(SystemAudioTest, PatchValid) {
-    const audio_port_config src = {
-        .id = 1, .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE };
-    // It's OK not to have sinks.
-    ASSERT_TRUE(audio_patch_is_valid((PatchBuilder{}).addSource(src).patch()));
-    const audio_port_config sink = {
-        .id = 2, .role = AUDIO_PORT_ROLE_SINK, .type = AUDIO_PORT_TYPE_DEVICE };
-    ASSERT_TRUE(audio_patch_is_valid((PatchBuilder{}).addSource(src).addSink(sink).patch()));
-    ASSERT_TRUE(audio_patch_is_valid(
-                    (PatchBuilder{}).addSource(src).addSource(src).addSink(sink).patch()));
-    ASSERT_TRUE(audio_patch_is_valid(
-                    (PatchBuilder{}).addSource(src).addSink(sink).addSink(sink).patch()));
-    ASSERT_TRUE(audio_patch_is_valid(
-                    (PatchBuilder{}).addSource(src).addSource(src).
-                    addSink(sink).addSink(sink).patch()));
-}
-
-TEST(SystemAudioTest, PatchHwAvSync) {
-    audio_port_config device_src_cfg = {
-        .id = 1, .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE };
-    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&device_src_cfg));
-    device_src_cfg.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
-    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&device_src_cfg));
-    device_src_cfg.flags.input = AUDIO_INPUT_FLAG_HW_AV_SYNC;
-    ASSERT_TRUE(audio_port_config_has_hw_av_sync(&device_src_cfg));
-
-    audio_port_config device_sink_cfg = {
-        .id = 1, .role = AUDIO_PORT_ROLE_SINK, .type = AUDIO_PORT_TYPE_DEVICE };
-    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&device_sink_cfg));
-    device_sink_cfg.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
-    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&device_sink_cfg));
-    device_sink_cfg.flags.output = AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
-    ASSERT_TRUE(audio_port_config_has_hw_av_sync(&device_sink_cfg));
-
-    audio_port_config mix_sink_cfg = {
-        .id = 1, .role = AUDIO_PORT_ROLE_SINK, .type = AUDIO_PORT_TYPE_MIX };
-    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&mix_sink_cfg));
-    mix_sink_cfg.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
-    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&mix_sink_cfg));
-    mix_sink_cfg.flags.input = AUDIO_INPUT_FLAG_HW_AV_SYNC;
-    ASSERT_TRUE(audio_port_config_has_hw_av_sync(&mix_sink_cfg));
-
-    audio_port_config mix_src_cfg = {
-        .id = 1, .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_MIX };
-    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&mix_src_cfg));
-    mix_src_cfg.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
-    ASSERT_FALSE(audio_port_config_has_hw_av_sync(&mix_src_cfg));
-    mix_src_cfg.flags.output = AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
-    ASSERT_TRUE(audio_port_config_has_hw_av_sync(&mix_src_cfg));
-}
-
-TEST(SystemAudioTest, PatchEqual) {
-    const audio_patch patch1{}, patch2{};
-    // Invalid patches are not equal.
-    ASSERT_FALSE(audio_patches_are_equal(&patch1, &patch2));
-    const audio_port_config src = {
-        .id = 1, .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE };
-    const audio_port_config sink = {
-        .id = 2, .role = AUDIO_PORT_ROLE_SINK, .type = AUDIO_PORT_TYPE_DEVICE };
-    ASSERT_FALSE(audio_patches_are_equal(
-                    (PatchBuilder{}).addSource(src).patch(),
-                    (PatchBuilder{}).addSource(src).addSink(sink).patch()));
-    ASSERT_TRUE(audio_patches_are_equal(
-                    (PatchBuilder{}).addSource(src).addSink(sink).patch(),
-                    (PatchBuilder{}).addSource(src).addSink(sink).patch()));
-    ASSERT_FALSE(audio_patches_are_equal(
-                    (PatchBuilder{}).addSource(src).addSink(sink).patch(),
-                    (PatchBuilder{}).addSource(src).addSource(src).addSink(sink).patch()));
-    audio_port_config sink_hw_av_sync = sink;
-    sink_hw_av_sync.config_mask |= AUDIO_PORT_CONFIG_FLAGS;
-    sink_hw_av_sync.flags.output = AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
-    ASSERT_FALSE(audio_patches_are_equal(
-                    (PatchBuilder{}).addSource(src).addSink(sink).patch(),
-                    (PatchBuilder{}).addSource(src).addSink(sink_hw_av_sync).patch()));
-    ASSERT_TRUE(audio_patches_are_equal(
-                    (PatchBuilder{}).addSource(src).addSink(sink_hw_av_sync).patch(),
-                    (PatchBuilder{}).addSource(src).addSink(sink_hw_av_sync).patch()));
-}
-
-void runAudioDeviceTypeHelperFunction(const std::unordered_set<audio_devices_t>& allDevices,
-                                      const audio_devices_t targetDevices[],
-                                      unsigned int targetDeviceCount,
-                                      const std::string& deviceTag,
-                                      bool (*device_type_helper_function)(audio_devices_t))
-{
-    std::unordered_set<audio_devices_t> devices(targetDevices, targetDevices + targetDeviceCount);
-    for (auto device : allDevices) {
-        if (devices.find(device) == devices.end()) {
-            ASSERT_FALSE(device_type_helper_function(device))
-                    << std::hex << device << " should not be " << deviceTag << " device";
-        } else {
-            ASSERT_TRUE(device_type_helper_function(device))
-                    << std::hex << device << " should be " << deviceTag << " device";
-        }
-    }
-}
-
-TEST(SystemAudioTest, AudioDeviceTypeHelperFunction) {
-    std::unordered_set<audio_devices_t> allDeviceTypes;
-    allDeviceTypes.insert(std::begin(AUDIO_DEVICE_OUT_ALL_ARRAY),
-            std::end(AUDIO_DEVICE_OUT_ALL_ARRAY));
-    allDeviceTypes.insert(std::begin(AUDIO_DEVICE_IN_ALL_ARRAY),
-            std::end(AUDIO_DEVICE_IN_ALL_ARRAY));
-
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, AUDIO_DEVICE_OUT_ALL_ARRAY,
-            std::size(AUDIO_DEVICE_OUT_ALL_ARRAY), "output", audio_is_output_device);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, AUDIO_DEVICE_IN_ALL_ARRAY,
-            std::size(AUDIO_DEVICE_IN_ALL_ARRAY), "input", audio_is_input_device);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY,
-            std::size(AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY), "a2dp out", audio_is_a2dp_out_device);
-    const audio_devices_t bluetoothInA2dpDevices[] = { AUDIO_DEVICE_IN_BLUETOOTH_A2DP };
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, bluetoothInA2dpDevices,
-            std::size(bluetoothInA2dpDevices), "a2dp in", audio_is_a2dp_in_device);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, AUDIO_DEVICE_OUT_ALL_SCO_ARRAY,
-            std::size(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY), "bluetooth out sco",
-            audio_is_bluetooth_out_sco_device);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, AUDIO_DEVICE_IN_ALL_SCO_ARRAY,
-            std::size(AUDIO_DEVICE_IN_ALL_SCO_ARRAY), "bluetooth in sco",
-            audio_is_bluetooth_in_sco_device);
-    const unsigned int scoDeviceCount = AUDIO_DEVICE_OUT_SCO_CNT + AUDIO_DEVICE_IN_SCO_CNT;
-    audio_devices_t scoDevices[scoDeviceCount];
-    std::copy(std::begin(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY), std::end(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY),
-              std::begin(scoDevices));
-    std::copy(std::begin(AUDIO_DEVICE_IN_ALL_SCO_ARRAY), std::end(AUDIO_DEVICE_IN_ALL_SCO_ARRAY),
-              std::begin(scoDevices) + AUDIO_DEVICE_OUT_SCO_CNT);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, scoDevices,
-            std::size(scoDevices), "bluetooth sco", audio_is_bluetooth_sco_device);
-    const audio_devices_t hearingAidOutDevices[] = { AUDIO_DEVICE_OUT_HEARING_AID };
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, hearingAidOutDevices,
-            std::size(hearingAidOutDevices), "hearing aid out", audio_is_hearing_aid_out_device);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, AUDIO_DEVICE_OUT_ALL_USB_ARRAY,
-            std::size(AUDIO_DEVICE_OUT_ALL_USB_ARRAY), "usb out", audio_is_usb_out_device);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, AUDIO_DEVICE_IN_ALL_USB_ARRAY,
-            std::size(AUDIO_DEVICE_IN_ALL_USB_ARRAY), "usb in", audio_is_usb_in_device);
-    const audio_devices_t remoteSubmixDevices[] = {
-            AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_DEVICE_OUT_REMOTE_SUBMIX };
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, remoteSubmixDevices,
-            std::size(remoteSubmixDevices), "remote submix", audio_is_remote_submix_device);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, AUDIO_DEVICE_OUT_ALL_DIGITAL_ARRAY,
-            std::size(AUDIO_DEVICE_OUT_ALL_DIGITAL_ARRAY), "digital out",
-            audio_is_digital_out_device);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, AUDIO_DEVICE_IN_ALL_DIGITAL_ARRAY,
-            std::size(AUDIO_DEVICE_IN_ALL_DIGITAL_ARRAY), "digital in",
-            audio_is_digital_in_device);
-    const unsigned int digitalDeviceCount
-            = AUDIO_DEVICE_OUT_DIGITAL_CNT + AUDIO_DEVICE_IN_DIGITAL_CNT;
-    audio_devices_t digitalDevices[digitalDeviceCount];
-    std::copy(std::begin(AUDIO_DEVICE_OUT_ALL_DIGITAL_ARRAY),
-              std::end(AUDIO_DEVICE_OUT_ALL_DIGITAL_ARRAY),
-              std::begin(digitalDevices));
-    std::copy(std::begin(AUDIO_DEVICE_IN_ALL_DIGITAL_ARRAY),
-              std::end(AUDIO_DEVICE_IN_ALL_DIGITAL_ARRAY),
-              std::begin(digitalDevices) + AUDIO_DEVICE_OUT_DIGITAL_CNT);
-    runAudioDeviceTypeHelperFunction(allDeviceTypes, digitalDevices,
-              std::size(digitalDevices), "digital", audio_device_is_digital);
-}