Support query direct playback support.
Support query direct playback support. Direct playback can be compressed
offload playback or compressed passthrough playback. This interface can
help developers to discover device's capabilities.
Bug: 197838445
Test: atest AudioManagerTest
Test: audiopolicy_fuzzer
Change-Id: I4066f53f5021b30e1fcf66de162c766326ee56cc
diff --git a/media/libaudioclient/AidlConversion.cpp b/media/libaudioclient/AidlConversion.cpp
index 4c83406..c202fea66 100644
--- a/media/libaudioclient/AidlConversion.cpp
+++ b/media/libaudioclient/AidlConversion.cpp
@@ -3314,4 +3314,53 @@
return trackSecondaryOutputInfo;
}
+ConversionResult<audio_direct_mode_t>
+aidl2legacy_AudioDirectMode_audio_direct_mode_t(media::AudioDirectMode aidl) {
+ switch (aidl) {
+ case media::AudioDirectMode::NONE:
+ return AUDIO_DIRECT_NOT_SUPPORTED;
+ case media::AudioDirectMode::OFFLOAD:
+ return AUDIO_DIRECT_OFFLOAD_SUPPORTED;
+ case media::AudioDirectMode::OFFLOAD_GAPLESS:
+ return AUDIO_DIRECT_OFFLOAD_GAPLESS_SUPPORTED;
+ case media::AudioDirectMode::BITSTREAM:
+ return AUDIO_DIRECT_BITSTREAM_SUPPORTED;
+ }
+ return unexpected(BAD_VALUE);
+}
+ConversionResult<media::AudioDirectMode>
+legacy2aidl_audio_direct_mode_t_AudioDirectMode(audio_direct_mode_t legacy) {
+ switch (legacy) {
+ case AUDIO_DIRECT_NOT_SUPPORTED:
+ return media::AudioDirectMode::NONE;
+ case AUDIO_DIRECT_OFFLOAD_SUPPORTED:
+ return media::AudioDirectMode::OFFLOAD;
+ case AUDIO_DIRECT_OFFLOAD_GAPLESS_SUPPORTED:
+ return media::AudioDirectMode::OFFLOAD_GAPLESS;
+ case AUDIO_DIRECT_BITSTREAM_SUPPORTED:
+ return media::AudioDirectMode::BITSTREAM;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_direct_mode_t> aidl2legacy_int32_t_audio_direct_mode_t_mask(int32_t aidl) {
+ using LegacyMask = std::underlying_type_t<audio_direct_mode_t>;
+
+ LegacyMask converted = VALUE_OR_RETURN(
+ (convertBitmask<LegacyMask, int32_t, audio_direct_mode_t, media::AudioDirectMode>(
+ aidl, aidl2legacy_AudioDirectMode_audio_direct_mode_t,
+ indexToEnum_index<media::AudioDirectMode>,
+ enumToMask_bitmask<LegacyMask, audio_direct_mode_t>)));
+ return static_cast<audio_direct_mode_t>(converted);
+}
+ConversionResult<int32_t> legacy2aidl_audio_direct_mode_t_int32_t_mask(audio_direct_mode_t legacy) {
+ using LegacyMask = std::underlying_type_t<audio_direct_mode_t>;
+
+ LegacyMask legacyMask = static_cast<LegacyMask>(legacy);
+ return convertBitmask<int32_t, LegacyMask, media::AudioDirectMode, audio_direct_mode_t>(
+ legacyMask, legacy2aidl_audio_direct_mode_t_AudioDirectMode,
+ indexToEnum_bitmask<audio_direct_mode_t>,
+ enumToMask_index<int32_t, media::AudioDirectMode>);
+}
+
} // namespace android
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 7e180a2..11c28f3 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -314,6 +314,7 @@
srcs: [
"aidl/android/media/AudioAttributesInternal.aidl",
"aidl/android/media/AudioClient.aidl",
+ "aidl/android/media/AudioDirectMode.aidl",
"aidl/android/media/AudioDualMonoMode.aidl",
"aidl/android/media/AudioFlag.aidl",
"aidl/android/media/AudioGainSys.aidl",
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 07ef246..b3c82787 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -2289,6 +2289,31 @@
return OK;
}
+status_t AudioSystem::getDirectPlaybackSupport(const audio_attributes_t *attr,
+ const audio_config_t *config,
+ audio_direct_mode_t* directMode) {
+ if (attr == nullptr || config == nullptr || directMode == nullptr) {
+ return BAD_VALUE;
+ }
+
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) {
+ return PERMISSION_DENIED;
+ }
+
+ media::AudioAttributesInternal attrAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributesInternal(*attr));
+ AudioConfig configAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_config_t_AudioConfig(*config, false /*isInput*/));
+
+ media::AudioDirectMode retAidl;
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ aps->getDirectPlaybackSupport(attrAidl, configAidl, &retAidl)));
+ *directMode = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_direct_mode_t_mask(
+ static_cast<int32_t>(retAidl)));
+ return NO_ERROR;
+}
+
class CaptureStateListenerImpl : public media::BnCaptureStateListener,
public IBinder::DeathRecipient {
diff --git a/media/libaudioclient/aidl/android/media/AudioDirectMode.aidl b/media/libaudioclient/aidl/android/media/AudioDirectMode.aidl
new file mode 100644
index 0000000..0da4721
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioDirectMode.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+package android.media;
+
+@Backing(type="int")
+enum AudioDirectMode {
+ NONE = 0,
+ OFFLOAD = 1,
+ OFFLOAD_GAPLESS = 2,
+ BITSTREAM = 4,
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 8e9ff86..7895ae3 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -20,6 +20,7 @@
import android.media.AudioAttributesEx;
import android.media.AudioAttributesInternal;
+import android.media.AudioDirectMode;
import android.media.AudioMix;
import android.media.AudioOffloadMode;
import android.media.AudioPatch;
@@ -376,4 +377,10 @@
boolean canBeSpatialized(in @nullable AudioAttributesInternal attr,
in @nullable AudioConfig config,
in AudioDevice[] devices);
+
+ /**
+ * Query how the direct playback is currently supported on the device.
+ */
+ AudioDirectMode getDirectPlaybackSupport(in AudioAttributesInternal attr,
+ in AudioConfig config);
}
diff --git a/media/libaudioclient/include/media/AidlConversion.h b/media/libaudioclient/include/media/AidlConversion.h
index a6c93cf..e769303 100644
--- a/media/libaudioclient/include/media/AidlConversion.h
+++ b/media/libaudioclient/include/media/AidlConversion.h
@@ -23,6 +23,7 @@
#include <android/media/AudioAttributesInternal.h>
#include <android/media/AudioClient.h>
+#include <android/media/AudioDirectMode.h>
#include <android/media/AudioDualMonoMode.h>
#include <android/media/AudioFlag.h>
#include <android/media/AudioIoConfigEvent.h>
@@ -445,5 +446,13 @@
legacy2aidl_TrackSecondaryOutputInfoPair_TrackSecondaryOutputInfo(
const TrackSecondaryOutputInfoPair& legacy);
+ConversionResult<audio_direct_mode_t>
+aidl2legacy_AudioDirectMode_audio_direct_mode_t(media::AudioDirectMode aidl);
+ConversionResult<media::AudioDirectMode>
+legacy2aidl_audio_direct_mode_t_AudioDirectMode(audio_direct_mode_t legacy);
+
+ConversionResult<audio_direct_mode_t> aidl2legacy_int32_t_audio_direct_mode_t_mask(int32_t aidl);
+ConversionResult<int32_t> legacy2aidl_audio_direct_mode_t_int32_t_mask(audio_direct_mode_t legacy);
+
} // namespace android
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 0e9d48c..11eb070 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -536,6 +536,19 @@
const AudioDeviceTypeAddrVector &devices,
bool *canBeSpatialized);
+ /**
+ * Query how the direct playback is currently supported on the device.
+ * @param attr audio attributes describing the playback use case
+ * @param config audio configuration for the playback
+ * @param directMode out: a set of flags describing how the direct playback is currently
+ * supported on the device
+ * @return NO_ERROR in case of success, DEAD_OBJECT, NO_INIT, BAD_VALUE, PERMISSION_DENIED
+ * in case of error.
+ */
+ static status_t getDirectPlaybackSupport(const audio_attributes_t *attr,
+ const audio_config_t *config,
+ audio_direct_mode_t *directMode);
+
// A listener for capture state changes.
class CaptureStateListener : public virtual RefBase {