Merge "Camera: Populate ZOOM_METHOD in CaptureResult" into main
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index 2feebb4..3b199b3 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -183,6 +183,13 @@
flag {
namespace: "camera_platform"
+ name: "depth_jpeg_extensions"
+ description: "Add Depth Jpeg extension output support"
+ bug: "362788689"
+}
+
+flag {
+ namespace: "camera_platform"
name: "mirror_mode_shared_surfaces"
is_exported: true
description: "Support setting and getting mirror mode for shared surfaces"
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 754f066..eaa5bd5 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -288,10 +288,10 @@
}
DrmStatus DrmHal::getSupportedSchemes(std::vector<uint8_t>& schemes) const {
- status_t statusResult;
- statusResult = mDrmHalAidl->getSupportedSchemes(schemes);
- if (statusResult == OK) return statusResult;
- return mDrmHalHidl->getSupportedSchemes(schemes);
+ const DrmStatus statusResultAidl = mDrmHalAidl->getSupportedSchemes(schemes);
+ const DrmStatus statusResultHidl = mDrmHalHidl->getSupportedSchemes(schemes);
+ if (statusResultHidl == OK || statusResultAidl == OK) return OK;
+ return statusResultAidl;
}
} // namespace android
diff --git a/media/OWNERS b/media/OWNERS
index b926075..5e32047 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -1,6 +1,7 @@
# Bug component: 1344
elaurent@google.com
essick@google.com
+atneya@google.com
hunga@google.com
jiabin@google.com
jmtrivi@google.com
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 95a8a69..f739f3c 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -76,8 +76,6 @@
using media::audio::common::AudioOffloadInfo;
using media::audio::common::AudioOutputFlags;
using media::audio::common::AudioPlaybackRate;
-using media::audio::common::AudioPolicyForcedConfig;
-using media::audio::common::AudioPolicyForceUse;
using media::audio::common::AudioPort;
using media::audio::common::AudioPortConfig;
using media::audio::common::AudioPortDeviceExt;
@@ -3359,138 +3357,6 @@
return OK;
}
-ConversionResult<audio_policy_force_use_t>
-aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(AudioPolicyForceUse aidl) {
- switch (aidl) {
- case AudioPolicyForceUse::COMMUNICATION:
- return AUDIO_POLICY_FORCE_FOR_COMMUNICATION;
- case AudioPolicyForceUse::MEDIA:
- return AUDIO_POLICY_FORCE_FOR_MEDIA;
- case AudioPolicyForceUse::RECORD:
- return AUDIO_POLICY_FORCE_FOR_RECORD;
- case AudioPolicyForceUse::DOCK:
- return AUDIO_POLICY_FORCE_FOR_DOCK;
- case AudioPolicyForceUse::SYSTEM:
- return AUDIO_POLICY_FORCE_FOR_SYSTEM;
- case AudioPolicyForceUse::HDMI_SYSTEM_AUDIO:
- return AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO;
- case AudioPolicyForceUse::ENCODED_SURROUND:
- return AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND;
- case AudioPolicyForceUse::VIBRATE_RINGING:
- return AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioPolicyForceUse>
-legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(audio_policy_force_use_t legacy) {
- switch (legacy) {
- case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
- return AudioPolicyForceUse::COMMUNICATION;
- case AUDIO_POLICY_FORCE_FOR_MEDIA:
- return AudioPolicyForceUse::MEDIA;
- case AUDIO_POLICY_FORCE_FOR_RECORD:
- return AudioPolicyForceUse::RECORD;
- case AUDIO_POLICY_FORCE_FOR_DOCK:
- return AudioPolicyForceUse::DOCK;
- case AUDIO_POLICY_FORCE_FOR_SYSTEM:
- return AudioPolicyForceUse::SYSTEM;
- case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
- return AudioPolicyForceUse::HDMI_SYSTEM_AUDIO;
- case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
- return AudioPolicyForceUse::ENCODED_SURROUND;
- case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
- return AudioPolicyForceUse::VIBRATE_RINGING;
- case AUDIO_POLICY_FORCE_USE_CNT:
- break;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<audio_policy_forced_cfg_t>
-aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(AudioPolicyForcedConfig aidl) {
- switch (aidl) {
- case AudioPolicyForcedConfig::NONE:
- return AUDIO_POLICY_FORCE_NONE;
- case AudioPolicyForcedConfig::SPEAKER:
- return AUDIO_POLICY_FORCE_SPEAKER;
- case AudioPolicyForcedConfig::HEADPHONES:
- return AUDIO_POLICY_FORCE_HEADPHONES;
- case AudioPolicyForcedConfig::BT_SCO:
- return AUDIO_POLICY_FORCE_BT_SCO;
- case AudioPolicyForcedConfig::BT_A2DP:
- return AUDIO_POLICY_FORCE_BT_A2DP;
- case AudioPolicyForcedConfig::WIRED_ACCESSORY:
- return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
- case AudioPolicyForcedConfig::BT_CAR_DOCK:
- return AUDIO_POLICY_FORCE_BT_CAR_DOCK;
- case AudioPolicyForcedConfig::BT_DESK_DOCK:
- return AUDIO_POLICY_FORCE_BT_DESK_DOCK;
- case AudioPolicyForcedConfig::ANALOG_DOCK:
- return AUDIO_POLICY_FORCE_ANALOG_DOCK;
- case AudioPolicyForcedConfig::DIGITAL_DOCK:
- return AUDIO_POLICY_FORCE_DIGITAL_DOCK;
- case AudioPolicyForcedConfig::NO_BT_A2DP:
- return AUDIO_POLICY_FORCE_NO_BT_A2DP;
- case AudioPolicyForcedConfig::SYSTEM_ENFORCED:
- return AUDIO_POLICY_FORCE_SYSTEM_ENFORCED;
- case AudioPolicyForcedConfig::HDMI_SYSTEM_AUDIO_ENFORCED:
- return AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED;
- case AudioPolicyForcedConfig::ENCODED_SURROUND_NEVER:
- return AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER;
- case AudioPolicyForcedConfig::ENCODED_SURROUND_ALWAYS:
- return AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS;
- case AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL:
- return AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL;
- case AudioPolicyForcedConfig::BT_BLE:
- return AUDIO_POLICY_FORCE_BT_BLE;
- }
- return unexpected(BAD_VALUE);
-}
-
-ConversionResult<AudioPolicyForcedConfig>
-legacy2aidl_audio_policy_forced_cfg_t_AudioPolicyForcedConfig(audio_policy_forced_cfg_t legacy) {
- switch (legacy) {
- case AUDIO_POLICY_FORCE_NONE:
- return AudioPolicyForcedConfig::NONE;
- case AUDIO_POLICY_FORCE_SPEAKER:
- return AudioPolicyForcedConfig::SPEAKER;
- case AUDIO_POLICY_FORCE_HEADPHONES:
- return AudioPolicyForcedConfig::HEADPHONES;
- case AUDIO_POLICY_FORCE_BT_SCO:
- return AudioPolicyForcedConfig::BT_SCO;
- case AUDIO_POLICY_FORCE_BT_A2DP:
- return AudioPolicyForcedConfig::BT_A2DP;
- case AUDIO_POLICY_FORCE_WIRED_ACCESSORY:
- return AudioPolicyForcedConfig::WIRED_ACCESSORY;
- case AUDIO_POLICY_FORCE_BT_CAR_DOCK:
- return AudioPolicyForcedConfig::BT_CAR_DOCK;
- case AUDIO_POLICY_FORCE_BT_DESK_DOCK:
- return AudioPolicyForcedConfig::BT_DESK_DOCK;
- case AUDIO_POLICY_FORCE_ANALOG_DOCK:
- return AudioPolicyForcedConfig::ANALOG_DOCK;
- case AUDIO_POLICY_FORCE_DIGITAL_DOCK:
- return AudioPolicyForcedConfig::DIGITAL_DOCK;
- case AUDIO_POLICY_FORCE_NO_BT_A2DP:
- return AudioPolicyForcedConfig::NO_BT_A2DP;
- case AUDIO_POLICY_FORCE_SYSTEM_ENFORCED:
- return AudioPolicyForcedConfig::SYSTEM_ENFORCED;
- case AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED:
- return AudioPolicyForcedConfig::HDMI_SYSTEM_AUDIO_ENFORCED;
- case AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER:
- return AudioPolicyForcedConfig::ENCODED_SURROUND_NEVER;
- case AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS:
- return AudioPolicyForcedConfig::ENCODED_SURROUND_ALWAYS;
- case AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL:
- return AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL;
- case AUDIO_POLICY_FORCE_BT_BLE:
- return AudioPolicyForcedConfig::BT_BLE;
- case AUDIO_POLICY_FORCE_CFG_CNT:
- break;
- }
- return unexpected(BAD_VALUE);
-}
-
} // namespace android
#undef GET_DEVICE_DESC_CONNECTION
diff --git a/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h b/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h
index 9dfb7e7..7268464 100644
--- a/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h
+++ b/media/audioaidlconversion/include/media/AidlConversionCppNdk-impl.h
@@ -58,8 +58,6 @@
#include PREFIX(android/media/audio/common/AudioMode.h)
#include PREFIX(android/media/audio/common/AudioOffloadInfo.h)
#include PREFIX(android/media/audio/common/AudioOutputFlags.h)
-#include PREFIX(android/media/audio/common/AudioPolicyForceUse.h)
-#include PREFIX(android/media/audio/common/AudioPolicyForcedConfig.h)
#include PREFIX(android/media/audio/common/AudioPort.h)
#include PREFIX(android/media/audio/common/AudioPortConfig.h)
#include PREFIX(android/media/audio/common/AudioPortExt.h)
@@ -78,7 +76,6 @@
#include <system/audio.h>
#include <system/audio_effect.h>
-#include <system/audio_policy.h>
#if defined(BACKEND_NDK_IMPL)
namespace aidl {
@@ -457,18 +454,6 @@
media::audio::common::MicrophoneInfo* aidlInfo,
media::audio::common::MicrophoneDynamicInfo* aidlDynamic);
-ConversionResult<audio_policy_forced_cfg_t>
-aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(
- media::audio::common::AudioPolicyForcedConfig aidl);
-ConversionResult<media::audio::common::AudioPolicyForcedConfig>
-legacy2aidl_audio_policy_forced_cfg_t_AudioPolicyForcedConfig(audio_policy_forced_cfg_t legacy);
-
-ConversionResult<audio_policy_force_use_t>
-aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(
- media::audio::common::AudioPolicyForceUse aidl);
-ConversionResult<media::audio::common::AudioPolicyForceUse>
-legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(audio_policy_force_use_t legacy);
-
} // namespace android
#if defined(BACKEND_NDK_IMPL)
diff --git a/media/codec2/components/apv/C2SoftApvEnc.cpp b/media/codec2/components/apv/C2SoftApvEnc.cpp
index d6a9597..9c5e0b2 100644
--- a/media/codec2/components/apv/C2SoftApvEnc.cpp
+++ b/media/codec2/components/apv/C2SoftApvEnc.cpp
@@ -958,108 +958,98 @@
finish(workIndex, fillWork);
}
}
-void C2SoftApvEnc::createCsdData(const std::unique_ptr<C2Work>& work, oapv_bitb_t* bitb,
- uint32_t encodedSize) {
- uint32_t csdStart = 0, csdEnd = 0;
- uint32_t bitOffset = 0;
- uint8_t* buf = (uint8_t*)bitb->addr + csdStart;
- if (encodedSize == 0) {
- ALOGE("the first frame size is zero, so no csd data will be created.");
+void C2SoftApvEnc::createCsdData(const std::unique_ptr<C2Work>& work,
+ oapv_bitb_t* bitb,
+ uint32_t encodedSize) {
+ if (encodedSize < 31) {
+ ALOGE("the first frame size is too small, so no csd data will be created.");
return;
}
- ABitReader reader(buf, encodedSize);
+ ABitReader reader((uint8_t*)bitb->addr, encodedSize);
+
+ uint8_t number_of_configuration_entry = 0;
+ uint8_t pbu_type = 0;
+ uint8_t number_of_frame_info = 0;
+ bool color_description_present_flag = false;
+ bool capture_time_distance_ignored = false;
+ uint8_t profile_idc = 0;
+ uint8_t level_idc = 0;
+ uint8_t band_idc = 0;
+ uint32_t frame_width_minus1 = 0;
+ uint32_t frame_height_minus1 = 0;
+ uint8_t chroma_format_idc = 0;
+ uint8_t bit_depth_minus8 = 0;
+ uint8_t capture_time_distance = 0;
+ uint8_t color_primaries = 0;
+ uint8_t transfer_characteristics = 0;
+ uint8_t matrix_coefficients = 0;
/* pbu_header() */
- reader.skipBits(32);
- bitOffset += 32; // pbu_size
- reader.skipBits(32);
- bitOffset += 32; // currReadSize
- csdStart = bitOffset / 8;
-
- int32_t pbu_type = reader.getBits(8);
- bitOffset += 8; // pbu_type
- reader.skipBits(16);
- bitOffset += 16; // group_id
- reader.skipBits(8);
- bitOffset += 8; // reserved_zero_8bits
+ reader.skipBits(32); // pbu_size
+ reader.skipBits(32); // currReadSize
+ pbu_type = reader.getBits(8); // pbu_type
+ reader.skipBits(16); // group_id
+ reader.skipBits(8); // reserved_zero_8bits
/* frame info() */
- int32_t profile_idc = reader.getBits(8);
- bitOffset += 8; // profile_idc
- int32_t level_idc = reader.getBits(8);
- bitOffset += 8; // level_idc
- int32_t band_idc = reader.getBits(3);
- bitOffset += 3; // band_idc
- reader.skipBits(5);
- bitOffset += 5; // reserved_zero_5bits
- int32_t width = reader.getBits(32);
- bitOffset += 32; // width
- int32_t height = reader.getBits(32);
- bitOffset += 32; // height
- int32_t chroma_idc = reader.getBits(4);
- bitOffset += 4; // chroma_format_idc
- reader.skipBits(4);
- bitOffset += 4; // bit_depth
- reader.skipBits(8);
- bitOffset += 8; // capture_time_distance
- reader.skipBits(8);
- bitOffset += 8; // reserved_zero_8bits
+ profile_idc = reader.getBits(8); // profile_idc
+ level_idc = reader.getBits(8); // level_idc
+ band_idc = reader.getBits(3); // band_idc
+ reader.skipBits(5); // reserved_zero_5bits
+ frame_width_minus1 = reader.getBits(32); // width
+ frame_height_minus1 = reader.getBits(32); // height
+ chroma_format_idc = reader.getBits(4); // chroma_format_idc
+ bit_depth_minus8 = reader.getBits(4); // bit_depth
+ capture_time_distance = reader.getBits(8); // capture_time_distance
+ reader.skipBits(8); // reserved_zero_8bits
/* frame header() */
- reader.skipBits(8);
- bitOffset += 8; // reserved_zero_8bit
- bool color_description_present_flag = reader.getBits(1);
- bitOffset += 1; // color_description_present_flag
+ reader.skipBits(8); // reserved_zero_8bit
+ color_description_present_flag = reader.getBits(1); // color_description_present_flag
if (color_description_present_flag) {
- reader.skipBits(8);
- bitOffset += 8; // color_primaries
- reader.skipBits(8);
- bitOffset += 8; // transfer_characteristics
- reader.skipBits(8);
- bitOffset += 8; // matrix_coefficients
- }
- bool use_q_matrix = reader.getBits(1);
- bitOffset += 1; // use_q_matrix
- if (use_q_matrix) {
- /* quantization_matrix() */
- int32_t numComp = chroma_idc == 0 ? 1
- : chroma_idc == 2 ? 3
- : chroma_idc == 3 ? 3
- : chroma_idc == 4 ? 4
- : -1;
- int32_t needBitsForQ = 64 * 8 * numComp;
- reader.skipBits(needBitsForQ);
- bitOffset += needBitsForQ;
+ color_primaries = reader.getBits(8); // color_primaries
+ transfer_characteristics = reader.getBits(8); // transfer_characteristics
+ matrix_coefficients = reader.getBits(8); // matrix_coefficients
}
- /* tile_info() */
- int32_t tile_width_in_mbs_minus1 = reader.getBits(28);
- bitOffset += 28;
- int32_t tile_height_in_mbs_minus1 = reader.getBits(28);
- bitOffset += 28;
- bool tile_size_present_in_fh_flag = reader.getBits(1);
- bitOffset += 1;
- if (tile_size_present_in_fh_flag) {
- int32_t numTiles = ceil((double)width / (double)tile_width_in_mbs_minus1) *
- ceil((double)height / (double)tile_height_in_mbs_minus1);
- reader.skipBits(32 * numTiles);
- bitOffset += (32 * numTiles);
- }
+ number_of_configuration_entry = 1; // The real-time encoding on the device is assumed to be 1.
+ number_of_frame_info = 1; // The real-time encoding on the device is assumed to be 1.
- reader.skipBits(8);
- bitOffset += 8; // reserved_zero_8bits
+ std::vector<uint8_t> csdData;
+ csdData.push_back((uint8_t)0x1);
+ csdData.push_back(number_of_configuration_entry);
- /* byte_alignmenet() */
- while (bitOffset % 8) {
- reader.skipBits(1);
- bitOffset += 1;
+ for (uint8_t i = 0; i < number_of_configuration_entry; i++) {
+ csdData.push_back(pbu_type);
+ csdData.push_back(number_of_frame_info);
+ for (uint8_t j = 0; j < number_of_frame_info; j++) {
+ csdData.push_back((uint8_t)((color_description_present_flag << 1) |
+ capture_time_distance_ignored));
+ csdData.push_back(profile_idc);
+ csdData.push_back(level_idc);
+ csdData.push_back(band_idc);
+ csdData.push_back((uint8_t)((frame_width_minus1 >> 24) & 0xff));
+ csdData.push_back((uint8_t)((frame_width_minus1 >> 16) & 0xff));
+ csdData.push_back((uint8_t)((frame_width_minus1 >> 8) & 0xff));
+ csdData.push_back((uint8_t)(frame_width_minus1 & 0xff));
+ csdData.push_back((uint8_t)((frame_height_minus1 >> 24) & 0xff));
+ csdData.push_back((uint8_t)((frame_height_minus1 >> 16) & 0xff));
+ csdData.push_back((uint8_t)((frame_height_minus1 >> 8) & 0xff));
+ csdData.push_back((uint8_t)(frame_height_minus1 & 0xff));
+ csdData.push_back((uint8_t)(((chroma_format_idc << 4) & 0xf0) |
+ (bit_depth_minus8 & 0xf)));
+ csdData.push_back((uint8_t)(capture_time_distance));
+ if (color_description_present_flag) {
+ csdData.push_back(color_primaries);
+ csdData.push_back(transfer_characteristics);
+ csdData.push_back(matrix_coefficients);
+ }
+ }
}
- csdEnd = bitOffset / 8;
- int32_t csdSize = csdEnd - csdStart + 1;
std::unique_ptr<C2StreamInitDataInfo::output> csd =
- C2StreamInitDataInfo::output::AllocUnique(csdSize, 0u);
+ C2StreamInitDataInfo::output::AllocUnique(csdData.size(), 0u);
if (!csd) {
ALOGE("CSD allocation failed");
mSignalledError = true;
@@ -1068,10 +1058,10 @@
return;
}
- buf = buf + csdStart;
- memcpy(csd->m.value, buf, csdSize);
+ memcpy(csd->m.value, csdData.data(), csdData.size());
work->worklets.front()->output.configUpdate.push_back(std::move(csd));
}
+
c2_status_t C2SoftApvEnc::drainInternal(uint32_t drainMode,
const std::shared_ptr<C2BlockPool>& pool,
const std::unique_ptr<C2Work>& work) {
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 069d6ad..fa5ce77 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -70,6 +70,7 @@
enum platform_level_t : uint32_t; ///< platform level
enum prepend_header_mode_t : uint32_t; ///< prepend header operational modes
enum profile_t : uint32_t; ///< coding profile
+ enum resource_kind_t : uint32_t; ///< resource kinds
enum scaling_method_t : uint32_t; ///< scaling methods
enum scan_order_t : uint32_t; ///< scan orders
enum secure_mode_t : uint32_t; ///< secure/protected modes
@@ -101,6 +102,7 @@
kParamIndexMasteringDisplayColorVolume,
kParamIndexChromaOffset,
kParamIndexGopLayer,
+ kParamIndexSystemResource,
/* =================================== parameter indices =================================== */
@@ -167,6 +169,10 @@
/* Region of Interest Encoding parameters */
kParamIndexQpOffsetMapBuffer, // info-buffer, used to signal qp-offset map for a frame
+ /* resource capacity and resources excluded */
+ kParamIndexResourcesCapacity,
+ kParamIndexResourcesExcluded,
+
// deprecated
kParamIndexDelayRequest = kParamIndexDelay | C2Param::CoreIndex::IS_REQUEST_FLAG,
@@ -1257,21 +1263,114 @@
/* ----------------------------------------- resources ----------------------------------------- */
/**
- * Resources needed and resources reserved for current configuration.
- *
- * Resources are tracked as a vector of positive numbers. Available resources are defined by
- * the vendor.
- *
- * By default, no resources are reserved for a component. If resource reservation is successful,
- * the component shall be able to use those resources exclusively. If however, the component is
- * not using all of the reserved resources, those may be shared with other components.
- *
- * TODO: define some of the resources.
+ * Resource kind.
*/
-typedef C2GlobalParam<C2Tuning, C2Uint64Array, kParamIndexResourcesNeeded> C2ResourcesNeededTuning;
-typedef C2GlobalParam<C2Tuning, C2Uint64Array, kParamIndexResourcesReserved>
- C2ResourcesReservedTuning;
+C2ENUM(C2Config::resource_kind_t, uint32_t,
+ CONST,
+ PER_FRAME,
+ PER_INPUT_BLOCK,
+ PER_OUTPUT_BLOCK
+)
+
+/**
+ * Definition of a system resource use.
+ *
+ * [PROPOSED]
+ *
+ * System resources are defined by the default component store.
+ * They represent any physical or abstract entities of limited availability
+ * that is required for a component instance to execute and process work.
+ *
+ * Each defined resource has an id.
+ * The use of a resource is specified by the amount and the kind (e.g. whether the amount
+ * of resources is required for each frame processed, or whether they are required
+ * regardless of the processing rate (const amount)).
+ *
+ * Note: implementations can shadow this structure with their own custom resource
+ * structure where a uint32_t based enum is used for id.
+ * This can be used to provide a name for each resource, via parameter descriptors.
+ */
+
+struct C2SystemResourceStruct {
+ C2SystemResourceStruct(uint32_t id_,
+ C2Config::resource_kind_t kind_,
+ uint64_t amount_)
+ : id(id_), kind(kind_), amount(amount_) { }
+ uint32_t id;
+ C2Config::resource_kind_t kind;
+ uint64_t amount;
+
+ DEFINE_AND_DESCRIBE_C2STRUCT(SystemResource)
+ C2FIELD(id, "id")
+ C2FIELD(kind, "kind")
+ C2FIELD(amount, "amount")
+};
+
+/**
+ * Total system resource capacity.
+ *
+ * [PROPOSED]
+ *
+ * This setting is implemented by the default component store.
+ * The total resource capacity is specified as the maximum amount for each resource ID
+ * that is supported by the device hardware or firmware.
+ * As such, the kind must be CONST for each element.
+ */
+typedef C2GlobalParam<C2Tuning,
+ C2SimpleArrayStruct<C2SystemResourceStruct>,
+ kParamIndexResourcesCapacity> C2ResourcesCapacityTuning;
+constexpr char C2_PARAMKEY_RESOURCES_CAPACITY[] = "resources.capacity";
+
+/**
+ * Excluded system resources.
+ *
+ * [PROPOSED]
+ *
+ * This setting is implemented by the default component store.
+ * Some system resources may be used by components and not tracked by the Codec 2.0 API.
+ * This is communicated by this tuning.
+ * Excluded resources are the total resources that are used by non-Codec 2.0 components.
+ * It is specified as the excluded amount for each resource ID that is used by
+ * a non-Codec 2.0 component. As such, the kind must be CONST for each element.
+ *
+ * The platform can calculate the available resources as total capacity minus
+ * excluded resource minus sum of needed resources for each component.
+ */
+typedef C2GlobalParam<C2Tuning,
+ C2SimpleArrayStruct<C2SystemResourceStruct>,
+ kParamIndexResourcesExcluded> C2ResourcesExcludedTuning;
+constexpr char C2_PARAMKEY_RESOURCES_EXCLUDED[] = "resources.excluded";
+
+/**
+ * System resources needed for the current configuration.
+ *
+ * [PROPOSED]
+ *
+ * Resources are tracked as a list of individual resource use specifications.
+ * The resource kind can be CONST, PER_FRAME, PER_INPUT_BLODCK or PER_OUTPUT_BLOCK.
+ */
+typedef C2GlobalParam<C2Tuning,
+ C2SimpleArrayStruct<C2SystemResourceStruct>,
+ kParamIndexResourcesNeeded> C2ResourcesNeededTuning;
constexpr char C2_PARAMKEY_RESOURCES_NEEDED[] = "resources.needed";
+
+/**
+ * System resources reserved for this component
+ *
+ * [FUTURE]
+ *
+ * This allows the platform to set aside system resources for the component.
+ * Since this is a static resource reservation, kind must be CONST for each element.
+ * This resource reservation only considers CONST and PER_FRAME use.
+ *
+ * By default, no resources are reserved for a component.
+ * If resource reservation is successful, the component shall be able to use those
+ * resources exclusively. If however, the component is not using all of the
+ * reserved resources, those may be shared with other components.
+ */
+typedef C2GlobalParam<C2Tuning,
+ C2SimpleArrayStruct<C2SystemResourceStruct>,
+ kParamIndexResourcesReserved> C2ResourcesReservedTuning;
constexpr char C2_PARAMKEY_RESOURCES_RESERVED[] = "resources.reserved";
/**
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
index fd242a1..0f5cdd6 100644
--- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -16,6 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Codec2InfoBuilder"
+
+#include <cstdlib>
+
#include <log/log.h>
#include <strings.h>
@@ -508,6 +511,10 @@
&& !hasPrefix(v.first, "domain-")
&& !hasPrefix(v.first, "variant-")) {
writer->addGlobalSetting(v.first.c_str(), v.second.c_str());
+ if (v.first == "max-concurrent-instances") {
+ MediaCodecInfoWriter::SetMaxSupportedInstances(
+ (int32_t)strtol(v.second.c_str(), NULL, 10));
+ }
}
}
@@ -797,6 +804,7 @@
}
}
}
+ codecInfo->createCodecCaps();
}
}
return OK;
diff --git a/media/janitors/better_together_OWNERS b/media/janitors/better_together_OWNERS
new file mode 100644
index 0000000..70723cb
--- /dev/null
+++ b/media/janitors/better_together_OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 137631
+
+aquilescanta@google.com
+asapperstein@google.com
+halliwell@google.com
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 136edcc..6c41198 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -119,8 +119,42 @@
*
* Available since API level 34.
*/
- AAUDIO_FORMAT_IEC61937
+ AAUDIO_FORMAT_IEC61937,
+ /**
+ * This format is used for audio compressed in MP3 format.
+ */
+ AAUDIO_FORMAT_MP3,
+
+ /**
+ * This format is used for audio compressed in AAC LC format.
+ */
+ AAUDIO_FORMAT_AAC_LC,
+
+ /**
+ * This format is used for audio compressed in AAC HE V1 format.
+ */
+ AAUDIO_FORMAT_AAC_HE_V1,
+
+ /**
+ * This format is used for audio compressed in AAC HE V2 format.
+ */
+ AAUDIO_FORMAT_AAC_HE_V2,
+
+ /**
+ * This format is used for audio compressed in AAC ELD format.
+ */
+ AAUDIO_FORMAT_AAC_ELD,
+
+ /**
+ * This format is used for audio compressed in AAC XHE format.
+ */
+ AAUDIO_FORMAT_AAC_XHE,
+
+ /**
+ * This format is used for audio compressed in OPUS.
+ */
+ AAUDIO_FORMAT_OPUS
};
typedef int32_t aaudio_format_t;
@@ -335,7 +369,23 @@
/**
* Reducing latency is more important than battery life.
*/
- AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
+ AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+
+ /**
+ * Extending battery life is more important than low latency.
+ *
+ * This mode is not supported in input streams.
+ * This mode will play through the offloaded audio path to save battery life.
+ *
+ * Comparing to mode {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING}, the stream at
+ * this mode will be able to write a large amount(several seconds) of data within a
+ * short time. The written data will be queued in a hardware buffer. After that, the
+ * app can suspend its thread/process that playing audio, the audio framework's data
+ * pipe will be suspended automatically and the CPU will be allowed to sleep for
+ * power saving. When all queued data are played, the apps will be able to get callback
+ * to feed more data.
+ */
+ AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED
};
typedef int32_t aaudio_performance_mode_t;
@@ -1090,7 +1140,8 @@
* Set the requested performance mode.
*
* Supported modes are {@link #AAUDIO_PERFORMANCE_MODE_NONE},
- * {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING} * and {@link #AAUDIO_PERFORMANCE_MODE_LOW_LATENCY}.
+ * {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING}, {@link #AAUDIO_PERFORMANCE_MODE_LOW_LATENCY} and
+ * {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED}.
*
* The default, if you do not call this function, is {@link #AAUDIO_PERFORMANCE_MODE_NONE}.
*
@@ -1475,6 +1526,44 @@
__INTRODUCED_IN(26);
/**
+ * Prototype for the callback function that is passed to
+ * AAudioStreamBuilder_setPresentationEndCallback().
+ *
+ * This will be called when all the buffers of an offloaded stream that were queued in the audio
+ * system (e.g. the combination of the Android audio framework and the device's audio hardware)
+ * have been played after AudioStream_requestStop() has been called.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream(), which must be an
+ * output stream as the offloaded mode is only supported for output stream
+ * @param userData the same address that was passed to
+ * AAudioStreamBuilder_setPresentationEndCallback().
+ */
+typedef void (*AAudioStream_presentationEndCallback)(AAudioStream* _Nonnull stream,
+ void* _Null_unspecified userData);
+
+/**
+ * Request that AAudio call this function when all the buffers of an offloaded stream that were
+ * queued in the audio system (e.g. the combination of the Android audio framework and the device's
+ * audio hardware) have been played.
+ *
+ * The presentation end callback must be used together with the data callback.
+ * The presentation edn callback won't be called if the stream is closed before all the data
+ * is played.
+ *
+ * Available since API level 36.
+ *
+ * @param builder reference provided by AAudio_createStreamBuilder()
+ * @param callback pointer to a function that will be called when all the buffers of an offloaded
+ * stream that were queued have been played.
+ * @param userData pointer to an application data structure that will be passed
+ * to the callback functions.
+ */
+AAUDIO_API void AAudioStreamBuilder_setPresentationEndCallback(
+ AAudioStreamBuilder* _Nonnull builder,
+ AAudioStream_presentationEndCallback _Nonnull callback,
+ void* _Nullable userData) __INTRODUCED_IN(36);
+
+/**
* Open a stream based on the options in the StreamBuilder.
*
* AAudioStream_close() must be called when finished with the stream to recover
@@ -2188,6 +2277,72 @@
AAUDIO_API aaudio_channel_mask_t AAudioStream_getChannelMask(AAudioStream* _Nonnull stream)
__INTRODUCED_IN(32);
+/**
+ * Configures the delay and padding values for the current stream playing in offload mode.
+ * This should only be used on a stream whose performance mode is
+ * {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED} and the format is compressed format.
+ * The unit is frames, where a frame includes samples for all audio channels, e.g. 100 frames
+ * for a stereo stream corresponds to 200 interleaved PCM samples.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream()
+ * @param delayInFrames number of frames to be ignored at the beginning of the stream. A value
+ * of 0 indicates no delay is to be applied.
+ * @param paddingInFrames number of frames to be ignored at the end of the stream. A value of 0
+ * of 0 indicates no padding is to be applied.
+ * @return {@link #AAUDIO_OK} if the delay and padding values are set successfully,
+ * or {@link #AAUDIO_ERROR_ILLEGAL_ARGUMENT} if delayInFrames or paddingInFrames
+ * is less than 0,
+ * or {@link #AAUDIO_ERROR_UNIMPLEMENTED} if the stream is not an output stream whose
+ * performance mode is {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED},
+ * or {@link #AAUDIO_ERROR_INVALID_STATE} if the stream is not yet initialized.
+ */
+AAUDIO_API aaudio_result_t AAudioStream_setOffloadDelayPadding(
+ AAudioStream* _Nonnull stream, int32_t delayInFrames, int32_t paddingInFrames)
+ __INTRODUCED_IN(36);
+
+/**
+ * Return the decoder delay of an offloaded stream in frames.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream()
+ * @return the offload delay in frames that previously set with
+ * {@link #AAudioStream_setOffloadDelayPadding},
+ * or 0 if it was never modified,
+ * or {@link #AAUDIO_ERROR_UNIMPLEMENTED} if the stream is not an output stream whose
+ * performance mode is {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED},
+ * or {@link #AAUDIO_ERROR_INVALID_STATE} if the stream is not yet initialized.
+ */
+AAUDIO_API int32_t AAudioStream_getOffloadDelay(AAudioStream* _Nonnull stream) __INTRODUCED_IN(36);
+
+/**
+ * Return the decoder padding of an offloaded stream in frames.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream()
+ * @return the offload padding in frames that previously set with
+ * {@link #AAudioStream_setOffloadDelayPadding},
+ * or 0 if it was never modified,
+ * or {@link #AAUDIO_ERROR_UNIMPLEMENTED} if the stream is not an output stream whose
+ * performance mode is {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED},
+ * or {@link #AAUDIO_ERROR_INVALID_STATE} if the stream is not yet initialized.
+ */
+AAUDIO_API int32_t AAudioStream_getOffloadPadding(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(36);
+
+/**
+ * Declares that the last data writing operation on this stream provided the last buffer of this
+ * stream.
+ * After the end of stream, previously set padding and delay values are ignored. That indicates
+ * all written data will be played.
+ * Use this method in the same thread as any data writing operation.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream()
+ * @return {@link #AAUDIO_OK} on success,
+ * or {@link #AAUDIO_ERROR_UNIMPLEMENTED} if the stream is not an output stream whose
+ * performance mode is {@link #AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED},
+ * or {@link #AAUDIO_ERROR_INVALID_STATE} if the stream is not yet initialized.
+ */
+AAUDIO_API aaudio_result_t AAudioStream_setOffloadEndOfStream(AAudioStream* _Nonnull stream)
+ __INTRODUCED_IN(36);
+
#ifdef __cplusplus
}
#endif
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 64152f0..de82471 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -255,6 +255,16 @@
streamBuilder->setErrorCallbackUserData(userData);
}
+AAUDIO_API void AAudioStreamBuilder_setPresentationEndCallback(AAudioStreamBuilder* builder,
+ AAudioStream_presentationEndCallback callback, void* userData) {
+ AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+ if (streamBuilder == nullptr) {
+ return;
+ }
+ streamBuilder->setPresentationEndCallbackProc(callback)
+ ->setPresentationEndCallbackUserData(userData);
+}
+
AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder,
int32_t frames)
{
@@ -693,3 +703,27 @@
// Do not return channel index masks as they are not public.
return AAudio_isChannelIndexMask(channelMask) ? AAUDIO_UNSPECIFIED : channelMask;
}
+
+AAUDIO_API aaudio_result_t AAudioStream_setOffloadDelayPadding(
+ AAudioStream* stream, int32_t delayInFrames, int32_t paddingInFrames) {
+ if (delayInFrames < 0 || paddingInFrames < 0) {
+ return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ }
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->setOffloadDelayPadding(delayInFrames, paddingInFrames);
+}
+
+AAUDIO_API int32_t AAudioStream_getOffloadDelay(AAudioStream* stream) {
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->getOffloadDelay();
+}
+
+AAUDIO_API int32_t AAudioStream_getOffloadPadding(AAudioStream* stream) {
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->getOffloadPadding();
+}
+
+AAUDIO_API aaudio_result_t AAudioStream_setOffloadEndOfStream(AAudioStream* stream) {
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->setOffloadEndOfStream();
+}
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index f504fa9..ed20d12 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -58,6 +58,13 @@
case AUDIO_FORMAT_PCM_24_BIT_PACKED:
case AUDIO_FORMAT_PCM_8_24_BIT:
case AUDIO_FORMAT_IEC61937:
+ case AUDIO_FORMAT_MP3:
+ case AUDIO_FORMAT_AAC_LC:
+ case AUDIO_FORMAT_AAC_HE_V1:
+ case AUDIO_FORMAT_AAC_HE_V2:
+ case AUDIO_FORMAT_AAC_ELD:
+ case AUDIO_FORMAT_AAC_XHE:
+ case AUDIO_FORMAT_OPUS:
break; // valid
default:
ALOGD("audioFormat not valid, audio_format_t = 0x%08x", format);
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 8e3bcf7..468bcfa 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -116,6 +116,8 @@
mErrorCallbackProc = builder.getErrorCallbackProc();
mDataCallbackUserData = builder.getDataCallbackUserData();
mErrorCallbackUserData = builder.getErrorCallbackUserData();
+ setPresentationEndCallbackUserData(builder.getPresentationEndCallbackUserData());
+ setPresentationEndCallbackProc(builder.getPresentationEndCallbackProc());
return AAUDIO_OK;
}
@@ -285,6 +287,10 @@
aaudio_result_t AudioStream::systemStopInternal() {
std::lock_guard<std::mutex> lock(mStreamLock);
+ return systemStopInternal_l();
+}
+
+aaudio_result_t AudioStream::systemStopInternal_l() {
aaudio_result_t result = safeStop_l();
if (result == AAUDIO_OK) {
// We only call this for logging in "dumpsys audio". So ignore return code.
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 3354adf..0ddc8ed 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -332,7 +332,7 @@
* have been called.
*/
int32_t getBytesPerFrame() const {
- return mSamplesPerFrame * getBytesPerSample();
+ return audio_bytes_per_frame(mSamplesPerFrame, mFormat);
}
/**
@@ -346,7 +346,7 @@
* This is only valid after setDeviceSamplesPerFrame() and setDeviceFormat() have been called.
*/
int32_t getBytesPerDeviceFrame() const {
- return getDeviceSamplesPerFrame() * audio_bytes_per_sample(getDeviceFormat());
+ return audio_bytes_per_frame(getDeviceSamplesPerFrame(), getDeviceFormat());
}
virtual int64_t getFramesWritten() = 0;
@@ -390,6 +390,24 @@
mDeviceSamplesPerFrame = deviceSamplesPerFrame;
}
+ virtual aaudio_result_t setOffloadDelayPadding(int32_t delayInFrames, int32_t paddingInFrames) {
+ return AAUDIO_ERROR_UNIMPLEMENTED;
+ }
+
+ virtual int32_t getOffloadDelay() {
+ return AAUDIO_ERROR_UNIMPLEMENTED;
+ }
+
+ virtual int32_t getOffloadPadding() {
+ return AAUDIO_ERROR_UNIMPLEMENTED;
+ }
+
+ virtual aaudio_result_t setOffloadEndOfStream() EXCLUDES(mStreamLock) {
+ return AAUDIO_ERROR_UNIMPLEMENTED;
+ }
+
+ virtual void setPresentationEndCallbackProc(AAudioStream_presentationEndCallback proc) { }
+ virtual void setPresentationEndCallbackUserData(void* userData) { }
/**
* @return true if data callback has been specified
@@ -408,7 +426,7 @@
/**
* @return true if called from the same thread as the callback
*/
- bool collidesWithCallback() const;
+ virtual bool collidesWithCallback() const;
// Implement AudioDeviceCallback
void onAudioDeviceUpdate(audio_io_handle_t audioIo,
@@ -649,6 +667,8 @@
aaudio_result_t joinThread_l(void **returnArg) REQUIRES(mStreamLock);
+ virtual aaudio_result_t systemStopInternal_l() REQUIRES(mStreamLock);
+
std::atomic<bool> mCallbackEnabled{false};
float mDuckAndMuteVolume = 1.0f;
@@ -742,6 +762,8 @@
mAudioBalance = audioBalance;
}
+ aaudio_result_t safeStop_l() REQUIRES(mStreamLock);
+
std::string mMetricsId; // set once during open()
std::mutex mStreamLock;
@@ -750,8 +772,6 @@
private:
- aaudio_result_t safeStop_l() REQUIRES(mStreamLock);
-
/**
* Release then close the stream.
*/
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 73bd69f..61881cb 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -174,6 +174,11 @@
__func__);
allowMMap = false;
}
+ if (!audio_is_linear_pcm(getFormat())) {
+ ALOGD("%s() MMAP not used because the requested format(%#x) is not pcm",
+ __func__, getFormat());
+ allowMMap = false;
+ }
// SessionID and Effects are only supported in Legacy mode.
if (getSessionId() != AAUDIO_SESSION_ID_NONE) {
@@ -261,6 +266,14 @@
case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
break;
+ case AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED:
+ if (getDirection() != AAUDIO_DIRECTION_OUTPUT ||
+ getFormat() == AUDIO_FORMAT_DEFAULT ||
+ getSampleRate() == 0 ||
+ getChannelMask() == AAUDIO_UNSPECIFIED) {
+ return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ }
+ break;
default:
ALOGE("illegal performanceMode = %d", mPerformanceMode);
return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.h b/media/libaaudio/src/core/AudioStreamBuilder.h
index f91c25a..d0678ae 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.h
+++ b/media/libaaudio/src/core/AudioStreamBuilder.h
@@ -89,6 +89,24 @@
return mErrorCallbackUserData;
}
+ AudioStreamBuilder* setPresentationEndCallbackProc(AAudioStream_presentationEndCallback proc) {
+ mPresentationEndCallbackProc = proc;
+ return this;
+ }
+
+ AAudioStream_presentationEndCallback getPresentationEndCallbackProc() const {
+ return mPresentationEndCallbackProc;
+ }
+
+ AudioStreamBuilder* setPresentationEndCallbackUserData(void *userData) {
+ mPresentationEndCallbackUserData = userData;
+ return this;
+ }
+
+ void *getPresentationEndCallbackUserData() const {
+ return mPresentationEndCallbackUserData;
+ }
+
int32_t getFramesPerDataCallback() const {
return mFramesPerDataCallback;
}
@@ -128,6 +146,9 @@
AAudioStream_errorCallback mErrorCallbackProc = nullptr;
void *mErrorCallbackUserData = nullptr;
+ AAudioStream_presentationEndCallback mPresentationEndCallbackProc = nullptr;
+ void *mPresentationEndCallbackUserData = nullptr;
+
enum {
PRIVACY_SENSITIVE_DEFAULT = -1,
PRIVACY_SENSITIVE_DISABLED = 0,
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 2e57f0d..da15563 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -22,6 +22,7 @@
#include <media/AudioTrack.h>
#include <aaudio/AAudio.h>
+#include <com_android_media_aaudio.h>
#include <system/audio.h>
#include "core/AudioGlobal.h"
@@ -56,6 +57,10 @@
aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder)
{
+ if (!com::android::media::aaudio::offload_support() &&
+ builder.getPerformanceMode() == AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
+ return AAUDIO_ERROR_UNIMPLEMENTED;
+ }
aaudio_result_t result = AAUDIO_OK;
result = AudioStream::open(builder);
@@ -152,6 +157,34 @@
if (tags.has_value() && !tags.value().empty()) {
strcpy(attributes.tags, tags.value().c_str());
}
+
+ audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
+ if (getPerformanceMode() == AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.format = format;
+ config.channel_mask = channelMask;
+ config.sample_rate = getSampleRate();
+ audio_direct_mode_t directMode = AUDIO_DIRECT_NOT_SUPPORTED;
+ if (status_t status = AudioSystem::getDirectPlaybackSupport(
+ &attributes, &config, &directMode);
+ status != NO_ERROR) {
+ ALOGE("%s, failed to query direct support, error=%d", __func__, status);
+ return status;
+ }
+ static const audio_direct_mode_t offloadMode = static_cast<audio_direct_mode_t>(
+ AUDIO_DIRECT_OFFLOAD_SUPPORTED | AUDIO_DIRECT_OFFLOAD_GAPLESS_SUPPORTED);
+ if ((directMode & offloadMode) == AUDIO_DIRECT_NOT_SUPPORTED) {
+ return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ }
+ flags = AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+ frameCount = 0;
+ offloadInfo.format = format;
+ offloadInfo.sample_rate = getSampleRate();
+ offloadInfo.channel_mask = channelMask;
+ offloadInfo.has_video = false;
+ offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
+ }
+
mAudioTrack = new AudioTrack();
// TODO b/182392769: use attribution source util
mAudioTrack->set(
@@ -167,7 +200,8 @@
false, // DEFAULT threadCanCallJava
sessionId,
streamTransferType,
- nullptr, // DEFAULT audio_offload_info_t
+ getPerformanceMode() == AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED
+ ? &offloadInfo : nullptr,
AttributionSourceState(), // DEFAULT uid and pid
&attributes,
// WARNING - If doNotReconnect set true then audio stops after plugging and unplugging
@@ -247,7 +281,9 @@
audio_output_flags_t actualFlags = mAudioTrack->getFlags();
aaudio_performance_mode_t actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
// We may not get the RAW flag. But as long as we get the FAST flag we can call it LOW_LATENCY.
- if ((actualFlags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
+ if ((actualFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != AUDIO_OUTPUT_FLAG_NONE) {
+ actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED;
+ } else if ((actualFlags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
} else if ((actualFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
actualPerformanceMode = AAUDIO_PERFORMANCE_MODE_POWER_SAVING;
@@ -347,6 +383,7 @@
setState(originalState);
return AAudioConvert_androidToAAudioResult(err);
}
+ mOffloadEosPending = false;
return AAUDIO_OK;
}
@@ -430,6 +467,12 @@
break;
case AAUDIO_STREAM_STATE_STOPPING:
if (mAudioTrack->stopped()) {
+ if (getPerformanceMode() == AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
+ std::lock_guard<std::mutex> lock(mStreamLock);
+ if (!mOffloadEosPending) {
+ break;
+ }
+ }
setState(AAUDIO_STREAM_STATE_STOPPED);
}
break;
@@ -579,6 +622,104 @@
mAudioTrack->setPlayerIId(mPlayerBase->getPlayerIId());
}
+aaudio_result_t AudioStreamTrack::systemStopInternal_l() {
+ if (aaudio_result_t result = AudioStream::systemStopInternal_l(); result != AAUDIO_OK) {
+ return result;
+ }
+ mOffloadEosPending = false;
+ return AAUDIO_OK;
+}
+
+aaudio_result_t AudioStreamTrack::setOffloadDelayPadding(
+ int32_t delayInFrames, int32_t paddingInFrames) {
+ if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED ||
+ audio_is_linear_pcm(getFormat())) {
+ return AAUDIO_ERROR_UNIMPLEMENTED;
+ }
+ if (mAudioTrack == nullptr) {
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ AudioParameter param = AudioParameter();
+ param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delayInFrames);
+ param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingInFrames);
+ mAudioTrack->setParameters(param.toString());
+ mOffloadDelayFrames.store(delayInFrames);
+ mOffloadPaddingFrames.store(paddingInFrames);
+ return AAUDIO_OK;
+}
+
+int32_t AudioStreamTrack::getOffloadDelay() {
+ if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED ||
+ audio_is_linear_pcm(getFormat())) {
+ return AAUDIO_ERROR_UNIMPLEMENTED;
+ }
+ if (mAudioTrack == nullptr) {
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ return mOffloadDelayFrames.load();
+}
+
+int32_t AudioStreamTrack::getOffloadPadding() {
+ if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED ||
+ audio_is_linear_pcm(getFormat())) {
+ return AAUDIO_ERROR_UNIMPLEMENTED;
+ }
+ if (mAudioTrack == nullptr) {
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ return mOffloadPaddingFrames.load();
+}
+
+aaudio_result_t AudioStreamTrack::setOffloadEndOfStream() {
+ if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
+ return AAUDIO_ERROR_UNIMPLEMENTED;
+ }
+ if (mAudioTrack == nullptr) {
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ std::lock_guard<std::mutex> lock(mStreamLock);
+ if (aaudio_result_t result = safeStop_l(); result != AAUDIO_OK) {
+ return result;
+ }
+ mOffloadEosPending = true;
+ return AAUDIO_OK;
+}
+
+bool AudioStreamTrack::collidesWithCallback() const {
+ if (AudioStream::collidesWithCallback()) {
+ return true;
+ }
+ pid_t thisThread = gettid();
+ return mPresentationEndCallbackThread.load() == thisThread;
+}
+
+void AudioStreamTrack::onStreamEnd() {
+ if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_POWER_SAVING_OFFLOADED) {
+ return;
+ }
+ if (getState() == AAUDIO_STREAM_STATE_STOPPING) {
+ std::lock_guard<std::mutex> lock(mStreamLock);
+ if (mOffloadEosPending) {
+ requestStart_l();
+ }
+ mOffloadEosPending = false;
+ }
+ maybeCallPresentationEndCallback();
+}
+
+void AudioStreamTrack::maybeCallPresentationEndCallback() {
+ if (mPresentationEndCallbackProc != nullptr) {
+ pid_t expected = CALLBACK_THREAD_NONE;
+ if (mPresentationEndCallbackThread.compare_exchange_strong(expected, gettid())) {
+ (*mPresentationEndCallbackProc)(
+ (AAudioStream *) this, mPresentationEndCallbackUserData);
+ mPresentationEndCallbackThread.store(CALLBACK_THREAD_NONE);
+ } else {
+ ALOGW("%s() error callback already running!", __func__);
+ }
+ }
+}
+
#if AAUDIO_USE_VOLUME_SHAPER
using namespace android::media::VolumeShaper;
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.h b/media/libaaudio/src/legacy/AudioStreamTrack.h
index 05609c4..82ba772 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.h
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.h
@@ -49,6 +49,11 @@
aaudio_result_t requestPause_l() REQUIRES(mStreamLock) override;
aaudio_result_t requestFlush_l() REQUIRES(mStreamLock) override;
aaudio_result_t requestStop_l() REQUIRES(mStreamLock) override;
+ aaudio_result_t systemStopInternal_l() REQUIRES(mStreamLock) final;
+
+ bool collidesWithCallback() const final;
+
+ void onStreamEnd() final;
public:
bool isFlushSupported() const override {
@@ -89,6 +94,26 @@
void registerPlayerBase() override;
+ // Offload begin --------------------------------------
+ aaudio_result_t setOffloadDelayPadding(int32_t delayInFrames, int32_t paddingInFrames) final;
+
+ int32_t getOffloadDelay() final;
+
+ int32_t getOffloadPadding() final;
+
+ aaudio_result_t setOffloadEndOfStream() EXCLUDES(mStreamLock) final;
+
+ void setPresentationEndCallbackProc(AAudioStream_presentationEndCallback proc) final {
+ mPresentationEndCallbackProc = proc;
+ }
+
+ virtual void setPresentationEndCallbackUserData(void *userData) final {
+ mPresentationEndCallbackUserData = userData;
+ }
+
+ void maybeCallPresentationEndCallback();
+ // Offload end ----------------------------------------
+
#if AAUDIO_USE_VOLUME_SHAPER
virtual android::binder::Status applyVolumeShaper(
const android::media::VolumeShaper::Configuration& configuration,
@@ -110,6 +135,15 @@
// TODO add 64-bit position reporting to AudioTrack and use it.
aaudio_wrapping_frames_t mPositionWhenPausing = 0;
+
+ // Offload --------------------------------------------
+ std::atomic<int32_t> mOffloadDelayFrames = 0;
+ std::atomic<int32_t> mOffloadPaddingFrames = 0;
+ bool mOffloadEosPending GUARDED_BY(mStreamLock) = false;
+
+ AAudioStream_presentationEndCallback mPresentationEndCallbackProc = nullptr;
+ void *mPresentationEndCallbackUserData = nullptr;
+ std::atomic<pid_t> mPresentationEndCallbackThread{CALLBACK_THREAD_NONE};
};
} /* namespace aaudio */
diff --git a/media/libaaudio/src/libaaudio.map.txt b/media/libaaudio/src/libaaudio.map.txt
index 36d76aa..44bb4c6 100644
--- a/media/libaaudio/src/libaaudio.map.txt
+++ b/media/libaaudio/src/libaaudio.map.txt
@@ -28,6 +28,7 @@
AAudioStreamBuilder_setChannelMask; # introduced=32
AAudioStreamBuilder_setSpatializationBehavior; # introduced=32
AAudioStreamBuilder_setIsContentSpatialized; # introduced=32
+ AAudioStreamBuilder_setPresentationEndCallback; #introduced=36
AAudioStreamBuilder_openStream;
AAudioStreamBuilder_delete;
AAudioStream_close;
@@ -73,6 +74,10 @@
AAudio_getPlatformMMapPolicy; # introduced=36
AAudio_getPlatformMMapExclusivePolicy; #introduced=36
AAudioStream_getDeviceIds; # introduced=36
+ AAudioStream_setOffloadDelayPadding; #introduced=36
+ AAudioStream_getOffloadDelay; #introduced=36
+ AAudioStream_getOffloadPadding; #introduced=36
+ AAudioStream_setOffloadEndOfStream; #introduced=36
AAudioStreamBuilder_setTags; # systemapi
AAudioStream_getTags; # systemapi
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index c741946..873fcba 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -147,6 +147,27 @@
case AAUDIO_FORMAT_IEC61937:
androidFormat = AUDIO_FORMAT_IEC61937;
break;
+ case AAUDIO_FORMAT_MP3:
+ androidFormat = AUDIO_FORMAT_MP3;
+ break;
+ case AAUDIO_FORMAT_AAC_LC:
+ androidFormat = AUDIO_FORMAT_AAC_LC;
+ break;
+ case AAUDIO_FORMAT_AAC_HE_V1:
+ androidFormat = AUDIO_FORMAT_AAC_HE_V1;
+ break;
+ case AAUDIO_FORMAT_AAC_HE_V2:
+ androidFormat = AUDIO_FORMAT_AAC_HE_V2;
+ break;
+ case AAUDIO_FORMAT_AAC_ELD:
+ androidFormat = AUDIO_FORMAT_AAC_ELD;
+ break;
+ case AAUDIO_FORMAT_AAC_XHE:
+ androidFormat = AUDIO_FORMAT_AAC_XHE;
+ break;
+ case AAUDIO_FORMAT_OPUS:
+ androidFormat = AUDIO_FORMAT_OPUS;
+ break;
default:
androidFormat = AUDIO_FORMAT_INVALID;
ALOGE("%s() 0x%08X unrecognized", __func__, aaudioFormat);
@@ -176,6 +197,27 @@
case AUDIO_FORMAT_IEC61937:
aaudioFormat = AAUDIO_FORMAT_IEC61937;
break;
+ case AUDIO_FORMAT_MP3:
+ aaudioFormat = AAUDIO_FORMAT_MP3;
+ break;
+ case AUDIO_FORMAT_AAC_LC:
+ aaudioFormat = AAUDIO_FORMAT_AAC_LC;
+ break;
+ case AUDIO_FORMAT_AAC_HE_V1:
+ aaudioFormat = AAUDIO_FORMAT_AAC_HE_V1;
+ break;
+ case AUDIO_FORMAT_AAC_HE_V2:
+ aaudioFormat = AAUDIO_FORMAT_AAC_HE_V2;
+ break;
+ case AUDIO_FORMAT_AAC_ELD:
+ aaudioFormat = AAUDIO_FORMAT_AAC_ELD;
+ break;
+ case AUDIO_FORMAT_AAC_XHE:
+ aaudioFormat = AAUDIO_FORMAT_AAC_XHE;
+ break;
+ case AUDIO_FORMAT_OPUS:
+ aaudioFormat = AAUDIO_FORMAT_OPUS;
+ break;
default:
aaudioFormat = AAUDIO_FORMAT_INVALID;
ALOGE("%s() 0x%08X unrecognized", __func__, androidFormat);
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index d5069f5..940e4b5 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -373,4 +373,6 @@
aaudio_policy_t AAudioConvert_androidToAAudioMMapPolicy(
android::media::audio::common::AudioMMapPolicy policy);
+bool AAudio_isCompressedFormat(audio_format_t format);
+
#endif //UTILITY_AAUDIO_UTILITIES_H
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 61204ae..6dfb327 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -359,6 +359,8 @@
"aidl/android/media/AudioMixerBehavior.aidl",
"aidl/android/media/AudioOffloadMode.aidl",
"aidl/android/media/AudioPolicyDeviceState.aidl",
+ "aidl/android/media/AudioPolicyForceUse.aidl",
+ "aidl/android/media/AudioPolicyForcedConfig.aidl",
"aidl/android/media/AudioProductStrategy.aidl",
"aidl/android/media/AudioVolumeGroup.aidl",
"aidl/android/media/DeviceRole.aidl",
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index cfa3011..dcfef45 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -62,8 +62,6 @@
using media::audio::common::AudioMMapPolicyInfo;
using media::audio::common::AudioMMapPolicyType;
using media::audio::common::AudioOffloadInfo;
-using media::audio::common::AudioPolicyForceUse;
-using media::audio::common::AudioPolicyForcedConfig;
using media::audio::common::AudioSource;
using media::audio::common::AudioStreamType;
using media::audio::common::AudioUsage;
@@ -1193,9 +1191,9 @@
if (aps == nullptr) return AUDIO_POLICY_FORCE_NONE;
auto result = [&]() -> ConversionResult<audio_policy_forced_cfg_t> {
- AudioPolicyForceUse usageAidl = VALUE_OR_RETURN(
+ media::AudioPolicyForceUse usageAidl = VALUE_OR_RETURN(
legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(usage));
- AudioPolicyForcedConfig configAidl;
+ media::AudioPolicyForcedConfig configAidl;
RETURN_IF_ERROR(statusTFromBinderStatus(
aps->getForceUse(usageAidl, &configAidl)));
return aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(configAidl);
diff --git a/media/libaudioclient/PolicyAidlConversion.cpp b/media/libaudioclient/PolicyAidlConversion.cpp
index a414cb7..163a359 100644
--- a/media/libaudioclient/PolicyAidlConversion.cpp
+++ b/media/libaudioclient/PolicyAidlConversion.cpp
@@ -296,6 +296,138 @@
return unexpected(BAD_VALUE);
}
+ConversionResult<audio_policy_force_use_t>
+aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(media::AudioPolicyForceUse aidl) {
+ switch (aidl) {
+ case media::AudioPolicyForceUse::COMMUNICATION:
+ return AUDIO_POLICY_FORCE_FOR_COMMUNICATION;
+ case media::AudioPolicyForceUse::MEDIA:
+ return AUDIO_POLICY_FORCE_FOR_MEDIA;
+ case media::AudioPolicyForceUse::RECORD:
+ return AUDIO_POLICY_FORCE_FOR_RECORD;
+ case media::AudioPolicyForceUse::DOCK:
+ return AUDIO_POLICY_FORCE_FOR_DOCK;
+ case media::AudioPolicyForceUse::SYSTEM:
+ return AUDIO_POLICY_FORCE_FOR_SYSTEM;
+ case media::AudioPolicyForceUse::HDMI_SYSTEM_AUDIO:
+ return AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO;
+ case media::AudioPolicyForceUse::ENCODED_SURROUND:
+ return AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND;
+ case media::AudioPolicyForceUse::VIBRATE_RINGING:
+ return AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<media::AudioPolicyForceUse>
+legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(audio_policy_force_use_t legacy) {
+ switch (legacy) {
+ case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
+ return media::AudioPolicyForceUse::COMMUNICATION;
+ case AUDIO_POLICY_FORCE_FOR_MEDIA:
+ return media::AudioPolicyForceUse::MEDIA;
+ case AUDIO_POLICY_FORCE_FOR_RECORD:
+ return media::AudioPolicyForceUse::RECORD;
+ case AUDIO_POLICY_FORCE_FOR_DOCK:
+ return media::AudioPolicyForceUse::DOCK;
+ case AUDIO_POLICY_FORCE_FOR_SYSTEM:
+ return media::AudioPolicyForceUse::SYSTEM;
+ case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
+ return media::AudioPolicyForceUse::HDMI_SYSTEM_AUDIO;
+ case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
+ return media::AudioPolicyForceUse::ENCODED_SURROUND;
+ case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
+ return media::AudioPolicyForceUse::VIBRATE_RINGING;
+ case AUDIO_POLICY_FORCE_USE_CNT:
+ break;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_policy_forced_cfg_t>
+aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(media::AudioPolicyForcedConfig aidl) {
+ switch (aidl) {
+ case media::AudioPolicyForcedConfig::NONE:
+ return AUDIO_POLICY_FORCE_NONE;
+ case media::AudioPolicyForcedConfig::SPEAKER:
+ return AUDIO_POLICY_FORCE_SPEAKER;
+ case media::AudioPolicyForcedConfig::HEADPHONES:
+ return AUDIO_POLICY_FORCE_HEADPHONES;
+ case media::AudioPolicyForcedConfig::BT_SCO:
+ return AUDIO_POLICY_FORCE_BT_SCO;
+ case media::AudioPolicyForcedConfig::BT_A2DP:
+ return AUDIO_POLICY_FORCE_BT_A2DP;
+ case media::AudioPolicyForcedConfig::WIRED_ACCESSORY:
+ return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
+ case media::AudioPolicyForcedConfig::BT_CAR_DOCK:
+ return AUDIO_POLICY_FORCE_BT_CAR_DOCK;
+ case media::AudioPolicyForcedConfig::BT_DESK_DOCK:
+ return AUDIO_POLICY_FORCE_BT_DESK_DOCK;
+ case media::AudioPolicyForcedConfig::ANALOG_DOCK:
+ return AUDIO_POLICY_FORCE_ANALOG_DOCK;
+ case media::AudioPolicyForcedConfig::DIGITAL_DOCK:
+ return AUDIO_POLICY_FORCE_DIGITAL_DOCK;
+ case media::AudioPolicyForcedConfig::NO_BT_A2DP:
+ return AUDIO_POLICY_FORCE_NO_BT_A2DP;
+ case media::AudioPolicyForcedConfig::SYSTEM_ENFORCED:
+ return AUDIO_POLICY_FORCE_SYSTEM_ENFORCED;
+ case media::AudioPolicyForcedConfig::HDMI_SYSTEM_AUDIO_ENFORCED:
+ return AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED;
+ case media::AudioPolicyForcedConfig::ENCODED_SURROUND_NEVER:
+ return AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER;
+ case media::AudioPolicyForcedConfig::ENCODED_SURROUND_ALWAYS:
+ return AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS;
+ case media::AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL:
+ return AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL;
+ case media::AudioPolicyForcedConfig::BT_BLE:
+ return AUDIO_POLICY_FORCE_BT_BLE;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<media::AudioPolicyForcedConfig>
+legacy2aidl_audio_policy_forced_cfg_t_AudioPolicyForcedConfig(audio_policy_forced_cfg_t legacy) {
+ switch (legacy) {
+ case AUDIO_POLICY_FORCE_NONE:
+ return media::AudioPolicyForcedConfig::NONE;
+ case AUDIO_POLICY_FORCE_SPEAKER:
+ return media::AudioPolicyForcedConfig::SPEAKER;
+ case AUDIO_POLICY_FORCE_HEADPHONES:
+ return media::AudioPolicyForcedConfig::HEADPHONES;
+ case AUDIO_POLICY_FORCE_BT_SCO:
+ return media::AudioPolicyForcedConfig::BT_SCO;
+ case AUDIO_POLICY_FORCE_BT_A2DP:
+ return media::AudioPolicyForcedConfig::BT_A2DP;
+ case AUDIO_POLICY_FORCE_WIRED_ACCESSORY:
+ return media::AudioPolicyForcedConfig::WIRED_ACCESSORY;
+ case AUDIO_POLICY_FORCE_BT_CAR_DOCK:
+ return media::AudioPolicyForcedConfig::BT_CAR_DOCK;
+ case AUDIO_POLICY_FORCE_BT_DESK_DOCK:
+ return media::AudioPolicyForcedConfig::BT_DESK_DOCK;
+ case AUDIO_POLICY_FORCE_ANALOG_DOCK:
+ return media::AudioPolicyForcedConfig::ANALOG_DOCK;
+ case AUDIO_POLICY_FORCE_DIGITAL_DOCK:
+ return media::AudioPolicyForcedConfig::DIGITAL_DOCK;
+ case AUDIO_POLICY_FORCE_NO_BT_A2DP:
+ return media::AudioPolicyForcedConfig::NO_BT_A2DP;
+ case AUDIO_POLICY_FORCE_SYSTEM_ENFORCED:
+ return media::AudioPolicyForcedConfig::SYSTEM_ENFORCED;
+ case AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED:
+ return media::AudioPolicyForcedConfig::HDMI_SYSTEM_AUDIO_ENFORCED;
+ case AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER:
+ return media::AudioPolicyForcedConfig::ENCODED_SURROUND_NEVER;
+ case AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS:
+ return media::AudioPolicyForcedConfig::ENCODED_SURROUND_ALWAYS;
+ case AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL:
+ return media::AudioPolicyForcedConfig::ENCODED_SURROUND_MANUAL;
+ case AUDIO_POLICY_FORCE_BT_BLE:
+ return media::AudioPolicyForcedConfig::BT_BLE;
+ case AUDIO_POLICY_FORCE_CFG_CNT:
+ break;
+ }
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<device_role_t>
aidl2legacy_DeviceRole_device_role_t(media::DeviceRole aidl) {
switch (aidl) {
diff --git a/media/libaudioclient/aidl/android/media/AudioPolicyForceUse.aidl b/media/libaudioclient/aidl/android/media/AudioPolicyForceUse.aidl
new file mode 100644
index 0000000..9bb0605
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioPolicyForceUse.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum AudioPolicyForceUse {
+ COMMUNICATION = 0,
+ MEDIA = 1,
+ RECORD = 2,
+ DOCK = 3,
+ SYSTEM = 4,
+ HDMI_SYSTEM_AUDIO = 5,
+ ENCODED_SURROUND = 6,
+ VIBRATE_RINGING = 7,
+}
diff --git a/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl b/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl
new file mode 100644
index 0000000..111bb2f
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+/**
+ * {@hide}
+ */
+@Backing(type="int")
+enum AudioPolicyForcedConfig {
+ NONE = 0,
+ SPEAKER = 1,
+ HEADPHONES = 2,
+ BT_SCO = 3,
+ BT_A2DP = 4,
+ WIRED_ACCESSORY = 5,
+ BT_CAR_DOCK = 6,
+ BT_DESK_DOCK = 7,
+ ANALOG_DOCK = 8,
+ DIGITAL_DOCK = 9,
+ NO_BT_A2DP = 10, /* A2DP sink is not preferred to speaker or wired HS */
+ SYSTEM_ENFORCED = 11,
+ HDMI_SYSTEM_AUDIO_ENFORCED = 12,
+ ENCODED_SURROUND_NEVER = 13,
+ ENCODED_SURROUND_ALWAYS = 14,
+ ENCODED_SURROUND_MANUAL = 15,
+ BT_BLE = 16,
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 7f4a7dd..fab2d95 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -25,6 +25,8 @@
import android.media.AudioOffloadMode;
import android.media.AudioPatchFw;
import android.media.AudioPolicyDeviceState;
+import android.media.AudioPolicyForcedConfig;
+import android.media.AudioPolicyForceUse;
import android.media.AudioPortFw;
import android.media.AudioPortConfigFw;
import android.media.AudioPortRole;
@@ -49,8 +51,6 @@
import android.media.audio.common.AudioMMapPolicyInfo;
import android.media.audio.common.AudioMMapPolicyType;
import android.media.audio.common.AudioMode;
-import android.media.audio.common.AudioPolicyForcedConfig;
-import android.media.audio.common.AudioPolicyForceUse;
import android.media.audio.common.AudioProfile;
import android.media.audio.common.AudioOffloadInfo;
import android.media.audio.common.AudioPort;
diff --git a/media/libaudioclient/aidl/fuzzer/Android.bp b/media/libaudioclient/aidl/fuzzer/Android.bp
index 14e528f..05db9e5 100644
--- a/media/libaudioclient/aidl/fuzzer/Android.bp
+++ b/media/libaudioclient/aidl/fuzzer/Android.bp
@@ -22,7 +22,7 @@
name: "libaudioclient_aidl_fuzzer_defaults",
static_libs: [
"android.hardware.audio.common@7.0-enums",
- "audiopermissioncontroller",
+ "libaudiopermission",
"libaudiomockhal",
"libfakeservicemanager",
"libjsoncpp",
diff --git a/media/libaudioclient/include/media/PolicyAidlConversion.h b/media/libaudioclient/include/media/PolicyAidlConversion.h
index 1b90d6b..ed9ddd6 100644
--- a/media/libaudioclient/include/media/PolicyAidlConversion.h
+++ b/media/libaudioclient/include/media/PolicyAidlConversion.h
@@ -28,6 +28,8 @@
#include <android/media/AudioMixRouteFlag.h>
#include <android/media/AudioMixType.h>
#include <android/media/AudioOffloadMode.h>
+#include <android/media/AudioPolicyForceUse.h>
+#include <android/media/AudioPolicyForcedConfig.h>
#include <android/media/DeviceRole.h>
#include <media/AidlConversionUtil.h>
@@ -82,6 +84,16 @@
ConversionResult<media::AudioPolicyDeviceState>
legacy2aidl_audio_policy_dev_state_t_AudioPolicyDeviceState(audio_policy_dev_state_t legacy);
+ConversionResult<audio_policy_force_use_t>
+aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(media::AudioPolicyForceUse aidl);
+ConversionResult<media::AudioPolicyForceUse>
+legacy2aidl_audio_policy_force_use_t_AudioPolicyForceUse(audio_policy_force_use_t legacy);
+
+ConversionResult<audio_policy_forced_cfg_t>
+aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(media::AudioPolicyForcedConfig aidl);
+ConversionResult<media::AudioPolicyForcedConfig>
+legacy2aidl_audio_policy_forced_cfg_t_AudioPolicyForcedConfig(audio_policy_forced_cfg_t legacy);
+
ConversionResult<device_role_t>
aidl2legacy_DeviceRole_device_role_t(media::DeviceRole aidl);
ConversionResult<media::DeviceRole>
diff --git a/services/audiopolicy/permission/Android.bp b/media/libaudiopermission/Android.bp
similarity index 92%
rename from services/audiopolicy/permission/Android.bp
rename to media/libaudiopermission/Android.bp
index cfbeaae..7275fd7 100644
--- a/services/audiopolicy/permission/Android.bp
+++ b/media/libaudiopermission/Android.bp
@@ -4,13 +4,13 @@
}
cc_library_headers {
- name: "audiopermissioncontroller_headers",
+ name: "libaudiopermission_headers",
host_supported: true,
export_include_dirs: ["include"],
}
cc_library {
- name: "audiopermissioncontroller",
+ name: "libaudiopermission",
srcs: [
"NativePermissionController.cpp",
@@ -83,14 +83,14 @@
}
cc_test {
- name: "audiopermissioncontroller_test",
+ name: "libaudiopermission_test",
host_supported: true,
defaults: [
"libmediautils_tests_config",
],
static_libs: [
"audio-permission-aidl-cpp",
- "audiopermissioncontroller",
+ "libaudiopermission",
"framework-permission-aidl-cpp",
"libgmock",
],
diff --git a/services/audiopolicy/permission/NativePermissionController.cpp b/media/libaudiopermission/NativePermissionController.cpp
similarity index 100%
rename from services/audiopolicy/permission/NativePermissionController.cpp
rename to media/libaudiopermission/NativePermissionController.cpp
diff --git a/services/audiopolicy/permission/ValidatedAttributionSourceState.cpp b/media/libaudiopermission/ValidatedAttributionSourceState.cpp
similarity index 100%
rename from services/audiopolicy/permission/ValidatedAttributionSourceState.cpp
rename to media/libaudiopermission/ValidatedAttributionSourceState.cpp
diff --git a/services/audiopolicy/permission/include/media/IPermissionProvider.h b/media/libaudiopermission/include/media/IPermissionProvider.h
similarity index 100%
rename from services/audiopolicy/permission/include/media/IPermissionProvider.h
rename to media/libaudiopermission/include/media/IPermissionProvider.h
diff --git a/services/audiopolicy/permission/include/media/NativePermissionController.h b/media/libaudiopermission/include/media/NativePermissionController.h
similarity index 100%
rename from services/audiopolicy/permission/include/media/NativePermissionController.h
rename to media/libaudiopermission/include/media/NativePermissionController.h
diff --git a/services/audiopolicy/permission/include/media/ValidatedAttributionSourceState.h b/media/libaudiopermission/include/media/ValidatedAttributionSourceState.h
similarity index 100%
rename from services/audiopolicy/permission/include/media/ValidatedAttributionSourceState.h
rename to media/libaudiopermission/include/media/ValidatedAttributionSourceState.h
diff --git a/services/audiopolicy/permission/tests/NativePermissionControllerTest.cpp b/media/libaudiopermission/tests/NativePermissionControllerTest.cpp
similarity index 100%
rename from services/audiopolicy/permission/tests/NativePermissionControllerTest.cpp
rename to media/libaudiopermission/tests/NativePermissionControllerTest.cpp
diff --git a/services/audiopolicy/permission/tests/ValidatedAttributionSourceStateTest.cpp b/media/libaudiopermission/tests/ValidatedAttributionSourceStateTest.cpp
similarity index 100%
rename from services/audiopolicy/permission/tests/ValidatedAttributionSourceStateTest.cpp
rename to media/libaudiopermission/tests/ValidatedAttributionSourceStateTest.cpp
diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp
index d5d1a09..3834278 100644
--- a/media/libmedia/MediaCodecInfo.cpp
+++ b/media/libmedia/MediaCodecInfo.cpp
@@ -26,6 +26,9 @@
namespace android {
+// initialize max supported instances with default value.
+int32_t MediaCodecInfo::sMaxSupportedInstances = 0;
+
/** This redundant redeclaration is needed for C++ pre 14 */
constexpr char MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK[];
constexpr char MediaCodecInfo::Capabilities::FEATURE_DYNAMIC_TIMESTAMP[];
@@ -169,6 +172,15 @@
return NULL;
}
+const std::shared_ptr<CodecCapabilities> MediaCodecInfo::getCodecCapsFor(
+ const char *mediaType) const {
+ ssize_t ix = getCodecCapIndex(mediaType);
+ if (ix >= 0) {
+ return mCodecCaps.valueAt(ix);
+ }
+ return nullptr;
+}
+
const char *MediaCodecInfo::getCodecName() const {
return mName.c_str();
}
@@ -179,6 +191,7 @@
// static
sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
+ sMaxSupportedInstances = parcel.readInt32();
AString name = AString::FromParcel(parcel);
AString owner = AString::FromParcel(parcel);
Attributes attributes = static_cast<Attributes>(parcel.readInt32());
@@ -201,12 +214,17 @@
return NULL;
if (info != NULL) {
info->mCaps.add(mediaType, caps);
+ std::shared_ptr<CodecCapabilities> codecCaps
+ = MediaCodecInfoWriter::BuildCodecCapabilities(
+ mediaType.c_str(), caps, info->isEncoder());
+ info->mCodecCaps.add(mediaType, codecCaps);
}
}
return info;
}
status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
+ parcel->writeInt32(sMaxSupportedInstances);
mName.writeToParcel(parcel);
mOwner.writeToParcel(parcel);
parcel->writeInt32(mAttributes);
@@ -234,6 +252,25 @@
return -1;
}
+ssize_t MediaCodecInfo::getCodecCapIndex(const char *mediaType) const {
+ if (mediaType == nullptr) {
+ return -1;
+ }
+
+ if (mCodecCaps.size() != mCaps.size()) {
+ ALOGE("Size of mCodecCaps and mCaps do not match, which are %zu and %zu",
+ mCodecCaps.size(), mCaps.size());
+ }
+
+ for (size_t ix = 0; ix < mCodecCaps.size(); ix++) {
+ if (mCodecCaps.keyAt(ix).equalsIgnoreCase(mediaType)) {
+ return ix;
+ }
+ }
+
+ return -1;
+}
+
MediaCodecInfo::MediaCodecInfo()
: mAttributes((MediaCodecInfo::Attributes)0),
mRank(0x100) {
@@ -283,6 +320,52 @@
return false;
}
+void MediaCodecInfoWriter::createCodecCaps() {
+ mInfo->mCodecCaps.clear();
+ for (size_t ix = 0; ix < mInfo->mCaps.size(); ix++) {
+ AString mediaType = mInfo->mCaps.keyAt(ix);
+ sp<MediaCodecInfo::Capabilities> caps = mInfo->mCaps.valueAt(ix);
+ mInfo->mCodecCaps.add(mediaType,
+ BuildCodecCapabilities(mediaType.c_str(), caps, mInfo->isEncoder(),
+ MediaCodecInfo::sMaxSupportedInstances));
+ }
+}
+
+// static
+std::shared_ptr<CodecCapabilities> MediaCodecInfoWriter::BuildCodecCapabilities(
+ const char *mediaType, sp<MediaCodecInfo::Capabilities> caps, bool isEncoder,
+ int32_t maxSupportedInstances) {
+ Vector<ProfileLevel> profileLevels_;
+ Vector<uint32_t> colorFormats_;
+ caps->getSupportedProfileLevels(&profileLevels_);
+ caps->getSupportedColorFormats(&colorFormats_);
+
+ std::vector<ProfileLevel> profileLevels;
+ std::vector<uint32_t> colorFormats;
+ for (ProfileLevel pl : profileLevels_) {
+ profileLevels.push_back(pl);
+ }
+ for (uint32_t cf : colorFormats_) {
+ colorFormats.push_back(cf);
+ }
+
+ sp<AMessage> defaultFormat = new AMessage();
+ defaultFormat->setString("mime", mediaType);
+
+ sp<AMessage> capabilitiesInfo = caps->getDetails();
+
+ std::shared_ptr<CodecCapabilities> codecCaps = std::make_shared<CodecCapabilities>();
+ codecCaps->init(profileLevels, colorFormats, isEncoder, defaultFormat,
+ capabilitiesInfo, maxSupportedInstances);
+
+ return codecCaps;
+}
+
+// static
+void MediaCodecInfoWriter::SetMaxSupportedInstances(int32_t maxSupportedInstances) {
+ MediaCodecInfo::sMaxSupportedInstances = maxSupportedInstances;
+}
+
MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
mInfo(info) {
}
diff --git a/media/libmedia/include/media/MediaCodecInfo.h b/media/libmedia/include/media/MediaCodecInfo.h
index 72aca98..60e383a 100644
--- a/media/libmedia/include/media/MediaCodecInfo.h
+++ b/media/libmedia/include/media/MediaCodecInfo.h
@@ -192,6 +192,7 @@
Attributes getAttributes() const;
void getSupportedMediaTypes(Vector<AString> *mediaTypes) const;
const sp<Capabilities> getCapabilitiesFor(const char *mediaType) const;
+ const std::shared_ptr<CodecCapabilities> getCodecCapsFor(const char *mediaType) const;
const char *getCodecName() const;
/**
@@ -229,14 +230,21 @@
status_t writeToParcel(Parcel *parcel) const;
private:
+ /**
+ * Max supported instances setting from MediaCodecList global setting.
+ */
+ static int32_t sMaxSupportedInstances;
+
AString mName;
AString mOwner;
Attributes mAttributes;
KeyedVector<AString, sp<Capabilities> > mCaps;
+ KeyedVector<AString, std::shared_ptr<CodecCapabilities>> mCodecCaps;
Vector<AString> mAliases;
uint32_t mRank;
ssize_t getCapabilityIndex(const char *mediaType) const;
+ ssize_t getCodecCapIndex(const char *mediaType) const;
/**
* Construct an `MediaCodecInfo` object. After the construction, its
@@ -264,6 +272,15 @@
*/
struct MediaCodecInfoWriter {
/**
+ * Get CodecCapabilities from Capabilities.
+ */
+ static std::shared_ptr<CodecCapabilities> BuildCodecCapabilities(const char *mediaType,
+ sp<MediaCodecInfo::Capabilities> caps, bool isEncoder, int maxSupportedInstances = 0);
+ /**
+ * Set the max supported instances global setting from MediaCodecList.
+ */
+ static void SetMaxSupportedInstances(int32_t maxSupportedInstances);
+ /**
* Set the name of the codec.
*
* @param name The new name.
@@ -319,6 +336,10 @@
* @param rank The rank of the component.
*/
void setRank(uint32_t rank);
+ /**
+ * Create CodecCapabilities map from Capabilities.
+ */
+ void createCodecCaps();
private:
/**
* The associated `MediaCodecInfo`.
diff --git a/media/libstagefright/OmxInfoBuilder.cpp b/media/libstagefright/OmxInfoBuilder.cpp
index 79ffdeb..1cb8f14 100644
--- a/media/libstagefright/OmxInfoBuilder.cpp
+++ b/media/libstagefright/OmxInfoBuilder.cpp
@@ -21,6 +21,8 @@
#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
#endif
+#include <cstdlib>
+
#include <android-base/properties.h>
#include <utils/Log.h>
@@ -131,6 +133,10 @@
for (const auto& p : serviceAttributes) {
writer->addGlobalSetting(
p.key.c_str(), p.value.c_str());
+ if (p.key == "max-concurrent-instances") {
+ MediaCodecInfoWriter::SetMaxSupportedInstances(
+ (int32_t)strtol(p.value.c_str(), NULL, 10));
+ }
}
// Convert roles to lists of codecs
@@ -217,6 +223,8 @@
ALOGW("Fail to add media type %s to codec %s",
typeName.c_str(), nodeName.c_str());
info->removeMediaType(typeName.c_str());
+ } else {
+ info->createCodecCaps();
}
}
}
diff --git a/media/module/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/module/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
index d21908f..7905e4f 100644
--- a/media/module/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
+++ b/media/module/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
@@ -458,6 +458,12 @@
if (bufferInfo.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
LOG(DEBUG) << "EOS from decoder.";
+ // NOTE - b/360057459
+ // There is a synchronization problem between feeding the frame to the encoder input surface
+ // and signaling end of stream.
+ // Waiting before signaling end of stream so that input surface has time to feed remaining
+ // frames to the encoder.
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
media_status_t status = AMediaCodec_signalEndOfInputStream(mEncoder->getCodec());
if (status != AMEDIA_OK) {
LOG(ERROR) << "SignalEOS on encoder returned error: " << status;
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 01bde42..add8a43 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -149,7 +149,7 @@
"audio-permission-aidl-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
- "audiopermissioncontroller",
+ "libaudiopermission",
"av-types-aidl-cpp",
"com.android.media.audio-aconfig-cc",
"com.android.media.audioserver-aconfig-cc",
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 33194b7..e5bd121 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -24,6 +24,7 @@
#include <android/media/audio/common/AudioMMapPolicyType.h>
#include <android/media/GetInputForAttrResponse.h>
#include <android/content/AttributionSourceState.h>
+#include <error/BinderResult.h>
#include <media/AudioCommonTypes.h>
#include <media/AudioContainers.h>
#include <media/AudioDeviceTypeAddr.h>
@@ -182,8 +183,7 @@
audio_input_flags_t flags,
audio_unique_id_t riid,
audio_session_t session,
- const AttributionSourceState& attributionSource,
- input_type_t *inputType /* out param */) = 0;
+ const AttributionSourceState& attributionSource) = 0;
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_port_handle_t portId) = 0;
// indicates to the audio policy manager that the input stops being used.
@@ -636,6 +636,32 @@
virtual status_t getMmapPolicyInfos(
media::audio::common::AudioMMapPolicyType policyType,
std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) = 0;
+
+ enum class MixType {
+ // e.g. audio recording from a microphone
+ NONE = 0,
+ // used for "remote submix" legacy mode (no DAP), capture of the media to play it remotely
+ CAPTURE,
+ // used for platform audio rerouting, where mixes are handled by external and dynamically
+ // installed policies which reroute audio mixes
+ EXT_POLICY_REROUTE,
+ // used for playback capture with a MediaProjection
+ PUBLIC_CAPTURE_PLAYBACK,
+ // used for capture from telephony RX path
+ TELEPHONY_RX_CAPTURE,
+ };
+
+ struct PermissionReqs {
+ media::audio::common::AudioSource source;
+ MixType mixType;
+ uint32_t virtualDeviceId;
+ // Flag based validation
+ bool isHotword;
+ bool isCallRedir;
+ };
+
+ virtual error::BinderResult<bool> checkPermissionForInput(const AttributionSourceState& attr,
+ const PermissionReqs& req) = 0;
};
// These are the signatures of createAudioPolicyManager/destroyAudioPolicyManager
diff --git a/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types_aidl.xml.in b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types_aidl.xml.in
index dc2517b..424c983 100644
--- a/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types_aidl.xml.in
+++ b/services/audiopolicy/engineconfigurable/config/example/common/audio_policy_engine_criterion_types_aidl.xml.in
@@ -19,76 +19,77 @@
<criterion_type name="OutputDevicesAddressesType" type="inclusive">
<values>
<!-- legacy remote submix -->
- <value literal="0" numerical="1"/>
+ <value literal="0"/>
</values>
</criterion_type>
<criterion_type name="InputDevicesAddressesType" type="inclusive">
<values>
<!-- legacy remote submix -->
- <value literal="0" numerical="1"/>
+ <value literal="0"/>
</values>
</criterion_type>
<criterion_type name="AndroidModeType" type="exclusive"/>
<criterion_type name="ForceUseForCommunicationType" type="exclusive">
<values>
- <value literal="NONE" numerical="0"/>
- <value literal="SPEAKER" numerical="1"/>
- <value literal="BT_SCO" numerical="3"/>
+ <value literal="NONE"/>
+ <value literal="SPEAKER"/>
+ <value literal="BT_SCO"/>
</values>
</criterion_type>
<criterion_type name="ForceUseForMediaType" type="exclusive">
<values>
- <value literal="NONE" numerical="0"/>
- <value literal="SPEAKER" numerical="1"/>
- <value literal="HEADPHONES" numerical="2"/>
- <value literal="BT_A2DP" numerical="4"/>
- <value literal="WIRED_ACCESSORY" numerical="5"/>
- <value literal="ANALOG_DOCK" numerical="8"/>
- <value literal="DIGITAL_DOCK" numerical="9"/>
- <value literal="NO_BT_A2DP" numerical="10"/>
+ <value literal="NONE"/>
+ <value literal="SPEAKER"/>
+ <value literal="HEADPHONES"/>
+ <value literal="BT_A2DP"/>
+ <value literal="ANALOG_DOCK"/>
+ <value literal="DIGITAL_DOCK"/>
+ <value literal="WIRED_ACCESSORY"/>
+ <value literal="NO_BT_A2DP"/>
</values>
</criterion_type>
<criterion_type name="ForceUseForRecordType" type="exclusive">
<values>
- <value literal="NONE" numerical="0"/>
- <value literal="BT_SCO" numerical="3"/>
- <value literal="WIRED_ACCESSORY" numerical="5"/>
+ <value literal="NONE"/>
+ <value literal="BT_SCO"/>
+ <value literal="WIRED_ACCESSORY"/>
</values>
</criterion_type>
<criterion_type name="ForceUseForDockType" type="exclusive">
<values>
- <value literal="NONE" numerical="0"/>
- <value literal="WIRED_ACCESSORY" numerical="5"/>
- <value literal="BT_CAR_DOCK" numerical="6"/>
- <value literal="BT_DESK_DOCK" numerical="7"/>
- <value literal="ANALOG_DOCK" numerical="8"/>
- <value literal="DIGITAL_DOCK" numerical="9"/>
+ <value literal="NONE"/>
+ <value literal="BT_CAR_DOCK"/>
+ <value literal="BT_DESK_DOCK"/>
+ <value literal="ANALOG_DOCK"/>
+ <value literal="DIGITAL_DOCK"/>
+ <value literal="WIRED_ACCESSORY"/>
</values>
</criterion_type>
<criterion_type name="ForceUseForSystemType" type="exclusive" >
<values>
- <value literal="NONE" numerical="0"/>
- <value literal="SYSTEM_ENFORCED" numerical="11"/>
+ <value literal="NONE"/>
+ <value literal="SYSTEM_ENFORCED"/>
</values>
</criterion_type>
<criterion_type name="ForceUseForHdmiSystemAudioType" type="exclusive">
<values>
- <value literal="NONE" numerical="0"/>
- <value literal="HDMI_SYSTEM_AUDIO_ENFORCED" numerical="12"/>
+ <value literal="NONE"/>
+ <value literal="HDMI_SYSTEM_AUDIO_ENFORCED"/>
</values>
</criterion_type>
<criterion_type name="ForceUseForEncodedSurroundType" type="exclusive">
<values>
- <value literal="NONE" numerical="0"/>
- <value literal="ENCODED_SURROUND_NEVER" numerical="13"/>
- <value literal="ENCODED_SURROUND_ALWAYS" numerical="14"/>
- <value literal="ENCODED_SURROUND_MANUAL" numerical="15"/>
+ <value literal="UNSPECIFIED"/>
+ <value literal="NEVER"/>
+ <value literal="ALWAYS"/>
+ <value literal="MANUAL"/>
</values>
</criterion_type>
<criterion_type name="ForceUseForVibrateRingingType" type="exclusive">
<values>
- <value literal="NONE" numerical="0"/>
- <value literal="BT_SCO" numerical="3"/>
+ <value literal="NONE"/>
+ <value literal="BT_SCO"/>
+ <value literal="BT_BLE"/>
</values>
</criterion_type>
</criterion_types>
diff --git a/services/audiopolicy/engineconfigurable/config/src/CapEngineConfig.cpp b/services/audiopolicy/engineconfigurable/config/src/CapEngineConfig.cpp
index b72e517..b89fba0 100644
--- a/services/audiopolicy/engineconfigurable/config/src/CapEngineConfig.cpp
+++ b/services/audiopolicy/engineconfigurable/config/src/CapEngineConfig.cpp
@@ -41,21 +41,23 @@
namespace android {
-using utilities::convertTo;
+using base::unexpected;
using media::audio::common::AudioDeviceAddress;
using media::audio::common::AudioDeviceDescription;
using media::audio::common::AudioHalCapCriterion;
+using media::audio::common::AudioHalCapCriterionV2;
using media::audio::common::AudioHalCapParameter;
using media::audio::common::AudioHalCapRule;
+using media::audio::common::AudioPolicyForceUse;
using media::audio::common::AudioSource;
using media::audio::common::AudioStreamType;
-using media::audio::common::AudioHalCapCriterionV2;
-using ::android::base::unexpected;
+using utilities::convertTo;
namespace capEngineConfig {
static constexpr const char *gLegacyOutputDevicePrefix = "AUDIO_DEVICE_OUT_";
static constexpr const char *gLegacyInputDevicePrefix = "AUDIO_DEVICE_IN_";
+static constexpr const char *gLegacyForcePrefix = "AUDIO_POLICY_FORCE_";
static constexpr const char *gLegacyStreamPrefix = "AUDIO_STREAM_";
static constexpr const char *gLegacySourcePrefix = "AUDIO_SOURCE_";
static constexpr const char *gPolicyParamPrefix = "/Policy/policy/";
@@ -83,6 +85,134 @@
return capName;
}
+ConversionResult<audio_policy_forced_cfg_t>
+ aidl2legacy_AudioPolicyForceUseCommunicationDeviceCategory_audio_policy_forced_cfg_t(
+ const AudioPolicyForceUse::CommunicationDeviceCategory aidl) {
+ switch (aidl) {
+ case AudioPolicyForceUse::CommunicationDeviceCategory::NONE:
+ return AUDIO_POLICY_FORCE_NONE;
+ case AudioPolicyForceUse::CommunicationDeviceCategory::SPEAKER:
+ return AUDIO_POLICY_FORCE_SPEAKER;
+ case AudioPolicyForceUse::CommunicationDeviceCategory::BT_SCO:
+ return AUDIO_POLICY_FORCE_BT_SCO;
+ case AudioPolicyForceUse::CommunicationDeviceCategory::BT_BLE:
+ return AUDIO_POLICY_FORCE_BT_BLE;
+ case AudioPolicyForceUse::CommunicationDeviceCategory::WIRED_ACCESSORY:
+ return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_policy_forced_cfg_t>
+ aidl2legacy_AudioPolicyForceUseMediaDeviceCategory_audio_policy_forced_cfg_t(
+ const AudioPolicyForceUse::MediaDeviceCategory aidl) {
+ switch (aidl) {
+ case AudioPolicyForceUse::MediaDeviceCategory::NONE:
+ return AUDIO_POLICY_FORCE_NONE;
+ case AudioPolicyForceUse::MediaDeviceCategory::SPEAKER:
+ return AUDIO_POLICY_FORCE_SPEAKER;
+ case AudioPolicyForceUse::MediaDeviceCategory::HEADPHONES:
+ return AUDIO_POLICY_FORCE_HEADPHONES;
+ case AudioPolicyForceUse::MediaDeviceCategory::BT_A2DP:
+ return AUDIO_POLICY_FORCE_BT_A2DP;
+ case AudioPolicyForceUse::MediaDeviceCategory::ANALOG_DOCK:
+ return AUDIO_POLICY_FORCE_ANALOG_DOCK;
+ case AudioPolicyForceUse::MediaDeviceCategory::DIGITAL_DOCK:
+ return AUDIO_POLICY_FORCE_DIGITAL_DOCK;
+ case AudioPolicyForceUse::MediaDeviceCategory::WIRED_ACCESSORY:
+ return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
+ case AudioPolicyForceUse::MediaDeviceCategory::NO_BT_A2DP:
+ return AUDIO_POLICY_FORCE_NO_BT_A2DP;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_policy_forced_cfg_t>
+ aidl2legacy_AudioPolicyForceUseDockType_audio_policy_forced_cfg_t(
+ const AudioPolicyForceUse::DockType aidl) {
+ switch (aidl) {
+ case AudioPolicyForceUse::DockType::NONE:
+ return AUDIO_POLICY_FORCE_NONE;
+ case AudioPolicyForceUse::DockType::BT_CAR_DOCK:
+ return AUDIO_POLICY_FORCE_BT_CAR_DOCK;
+ case AudioPolicyForceUse::DockType::BT_DESK_DOCK:
+ return AUDIO_POLICY_FORCE_BT_DESK_DOCK;
+ case AudioPolicyForceUse::DockType::ANALOG_DOCK:
+ return AUDIO_POLICY_FORCE_ANALOG_DOCK;
+ case AudioPolicyForceUse::DockType::DIGITAL_DOCK:
+ return AUDIO_POLICY_FORCE_DIGITAL_DOCK;
+ case AudioPolicyForceUse::DockType::WIRED_ACCESSORY:
+ return AUDIO_POLICY_FORCE_WIRED_ACCESSORY;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<audio_policy_forced_cfg_t>
+ aidl2legacy_AudioPolicyForceUseEncodedSurroundConfig_audio_policy_forced_cfg_t(
+ const AudioPolicyForceUse::EncodedSurroundConfig aidl) {
+ switch (aidl) {
+ case AudioPolicyForceUse::EncodedSurroundConfig::UNSPECIFIED:
+ return AUDIO_POLICY_FORCE_NONE;
+ case AudioPolicyForceUse::EncodedSurroundConfig::NEVER:
+ return AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER;
+ case AudioPolicyForceUse::EncodedSurroundConfig::ALWAYS:
+ return AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS;
+ case AudioPolicyForceUse::EncodedSurroundConfig::MANUAL:
+ return AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL;
+ }
+ return unexpected(BAD_VALUE);
+}
+
+ConversionResult<std::pair<audio_policy_force_use_t, audio_policy_forced_cfg_t>>
+ aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t_audio_policy_forced_cfg_t(
+ const AudioPolicyForceUse& aidl) {
+ switch (aidl.getTag()) {
+ case AudioPolicyForceUse::forCommunication:
+ return std::make_pair(
+ AUDIO_POLICY_FORCE_FOR_COMMUNICATION,
+ VALUE_OR_RETURN(
+ aidl2legacy_AudioPolicyForceUseCommunicationDeviceCategory_audio_policy_forced_cfg_t(
+ aidl.get<AudioPolicyForceUse::forCommunication>())));
+ case AudioPolicyForceUse::forMedia:
+ return std::make_pair(
+ AUDIO_POLICY_FORCE_FOR_MEDIA,
+ VALUE_OR_RETURN(
+ aidl2legacy_AudioPolicyForceUseMediaDeviceCategory_audio_policy_forced_cfg_t(
+ aidl.get<AudioPolicyForceUse::forMedia>())));
+ case AudioPolicyForceUse::forRecord:
+ return std::make_pair(
+ AUDIO_POLICY_FORCE_FOR_RECORD,
+ VALUE_OR_RETURN(
+ aidl2legacy_AudioPolicyForceUseCommunicationDeviceCategory_audio_policy_forced_cfg_t(
+ aidl.get<AudioPolicyForceUse::forRecord>())));
+ case AudioPolicyForceUse::dock:
+ return std::make_pair(AUDIO_POLICY_FORCE_FOR_DOCK,
+ VALUE_OR_RETURN(
+ aidl2legacy_AudioPolicyForceUseDockType_audio_policy_forced_cfg_t(
+ aidl.get<AudioPolicyForceUse::dock>())));
+ case AudioPolicyForceUse::systemSounds:
+ return std::make_pair(AUDIO_POLICY_FORCE_FOR_SYSTEM,
+ aidl.get<AudioPolicyForceUse::systemSounds>() ?
+ AUDIO_POLICY_FORCE_SYSTEM_ENFORCED : AUDIO_POLICY_FORCE_NONE);
+ case AudioPolicyForceUse::hdmiSystemAudio:
+ return std::make_pair(
+ AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO,
+ aidl.get<AudioPolicyForceUse::hdmiSystemAudio>() ?
+ AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : AUDIO_POLICY_FORCE_NONE);
+ case AudioPolicyForceUse::encodedSurround:
+ return std::make_pair(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND, VALUE_OR_RETURN(
+ aidl2legacy_AudioPolicyForceUseEncodedSurroundConfig_audio_policy_forced_cfg_t(
+ aidl.get<AudioPolicyForceUse::encodedSurround>())));
+ case AudioPolicyForceUse::forVibrateRinging:
+ return std::make_pair(
+ AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING,
+ VALUE_OR_RETURN(
+ aidl2legacy_AudioPolicyForceUseCommunicationDeviceCategory_audio_policy_forced_cfg_t(
+ aidl.get<AudioPolicyForceUse::forVibrateRinging>())));
+ }
+ return unexpected(BAD_VALUE);
+}
+
ConversionResult<std::string> aidl2legacy_AudioHalCapCriterionV2_CapName(
const AudioHalCapCriterionV2& aidl) {
switch (aidl.getTag()) {
@@ -97,14 +227,14 @@
case AudioHalCapCriterionV2::telephonyMode:
return gPhoneStateCriterionName;
case AudioHalCapCriterionV2::forceConfigForUse: {
- auto aidlCriterion = aidl.get<AudioHalCapCriterionV2::forceConfigForUse>();
- return gForceUseCriterionTag[VALUE_OR_RETURN(
- aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(
- aidlCriterion.forceUse))];
+ auto aidlCriterion = aidl.get<AudioHalCapCriterionV2::forceConfigForUse>().values[0];
+ const auto [forceUse, _] = VALUE_OR_RETURN(
+ aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t_audio_policy_forced_cfg_t(
+ aidlCriterion));
+ return gForceUseCriterionTag[forceUse];
}
- default:
- return unexpected(BAD_VALUE);
}
+ return unexpected(BAD_VALUE);
}
ConversionResult<std::string> aidl2legacy_AudioHalCapCriterionV2TypeDevice_CapCriterionValue(
@@ -121,6 +251,32 @@
isOut ? gLegacyOutputDevicePrefix : gLegacyInputDevicePrefix);
}
+ConversionResult<audio_policy_forced_cfg_t>
+ aidl2legacy_AudioHalCapCriterionV2ForceUse_audio_policy_forced_cfg_t(
+ const AudioPolicyForceUse& aidl) {
+ const auto [_, legacyForcedCfg] = VALUE_OR_RETURN(
+ aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t_audio_policy_forced_cfg_t(
+ aidl));
+ return legacyForcedCfg;
+}
+
+ConversionResult<std::string> audio_policy_forced_cfg_t_CapCriterionValue(
+ audio_policy_forced_cfg_t legacyForcedCfg) {
+ std::string legacyForcedCfgLiteral = audio_policy_forced_cfg_to_string(legacyForcedCfg);
+ if (legacyForcedCfgLiteral.empty()) {
+ ALOGE("%s Invalid forced config value %d", __func__, legacyForcedCfg);
+ return unexpected(BAD_VALUE);
+ }
+ return truncatePrefix(legacyForcedCfgLiteral, gLegacyForcePrefix);
+}
+
+ConversionResult<std::string> aidl2legacy_AudioHalCapCriterionV2ForceUse_CapCriterionValue(
+ const AudioPolicyForceUse& aidl) {
+ const audio_policy_forced_cfg_t legacyForcedCfg = VALUE_OR_RETURN(
+ aidl2legacy_AudioHalCapCriterionV2ForceUse_audio_policy_forced_cfg_t(aidl));
+ return audio_policy_forced_cfg_t_CapCriterionValue(legacyForcedCfg);
+}
+
ConversionResult<std::string> aidl2legacy_AudioHalCapCriterionV2Type_CapCriterionValue(
const AudioHalCapCriterionV2& aidl) {
switch (aidl.getTag()) {
@@ -139,10 +295,10 @@
case AudioHalCapCriterionV2::telephonyMode:
return toString(aidl.get<AudioHalCapCriterionV2::telephonyMode>().values[0]);
case AudioHalCapCriterionV2::forceConfigForUse:
- return toString(aidl.get<AudioHalCapCriterionV2::forceConfigForUse>().values[0]);
- default:
- return unexpected(BAD_VALUE);
+ return aidl2legacy_AudioHalCapCriterionV2ForceUse_CapCriterionValue(
+ aidl.get<AudioHalCapCriterionV2::forceConfigForUse>().values[0]);
}
+ return unexpected(BAD_VALUE);
}
ConversionResult<std::string> aidl2legacy_AudioHalCapRule_CapRule(
@@ -331,24 +487,28 @@
engineConfig::Criterion& criterion = capCriterion.criterion;
engineConfig::CriterionType& criterionType = capCriterion.criterionType;
- auto loadForceUseCriterion = [](const auto &aidlCriterion, auto &criterion,
- auto &criterionType) -> status_t {
- uint32_t legacyForceUse = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(
- aidlCriterion.forceUse));
+ auto loadForceUseCriterion = [](const auto& aidlCriterion, auto& criterion,
+ auto& criterionType) -> status_t {
+ if (aidlCriterion.values.empty()) {
+ return BAD_VALUE;
+ }
+ const auto [legacyForceUse, _] = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t_audio_policy_forced_cfg_t(
+ aidlCriterion.values[0]));
criterion.typeName = criterionType.name;
criterionType.name = criterion.typeName + gCriterionTypeSuffix;
criterionType.isInclusive =
(aidlCriterion.logic == AudioHalCapCriterionV2::LogicalDisjunction::INCLUSIVE);
criterion.name = gForceUseCriterionTag[legacyForceUse];
- criterion.defaultLiteralValue = toString(aidlCriterion.defaultValue);
- if (aidlCriterion.values.empty()) {
- return BAD_VALUE;
- }
+ criterion.defaultLiteralValue = toString(
+ aidlCriterion.defaultValue.template get<AudioPolicyForceUse::forMedia>());
for (auto &value : aidlCriterion.values) {
- uint32_t legacyForcedConfig = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioPolicyForcedConfig_audio_policy_forced_cfg_t(value));
- criterionType.valuePairs.push_back({legacyForcedConfig, 0, toString(value)});
+ const audio_policy_forced_cfg_t legacyForcedCfg = VALUE_OR_RETURN_STATUS(
+ aidl2legacy_AudioHalCapCriterionV2ForceUse_audio_policy_forced_cfg_t(value));
+ const std::string legacyForcedCfgLiteral = VALUE_OR_RETURN_STATUS(
+ audio_policy_forced_cfg_t_CapCriterionValue(legacyForcedCfg));
+ criterionType.valuePairs.push_back(
+ {legacyForcedCfg, 0, legacyForcedCfgLiteral});
}
return NO_ERROR;
};
diff --git a/services/audiopolicy/engineconfigurable/tools/capBuildPolicyCriterionTypes.py b/services/audiopolicy/engineconfigurable/tools/capBuildPolicyCriterionTypes.py
index b873830..1adc602 100755
--- a/services/audiopolicy/engineconfigurable/tools/capBuildPolicyCriterionTypes.py
+++ b/services/audiopolicy/engineconfigurable/tools/capBuildPolicyCriterionTypes.py
@@ -102,7 +102,6 @@
ordered_values = OrderedDict(sorted(values_dict.items(), key=lambda x: x[1]))
for key, value in ordered_values.items():
value_node = ET.SubElement(values_node, "value")
- value_node.set('numerical', str(value))
value_node.set('literal', key)
if criterion_type.get('name') == "OutputDevicesMaskType":
@@ -114,20 +113,14 @@
for criterion_name, values_list in addressCriteria.items():
for criterion_type in criterion_types_root.findall('criterion_type'):
if criterion_type.get('name') == criterion_name:
- index = 0
existing_values_node = criterion_type.find("values")
if existing_values_node is not None:
- for existing_value in existing_values_node.findall('value'):
- if existing_value.get('numerical') == str(1 << index):
- index += 1
values_node = existing_values_node
else:
values_node = ET.SubElement(criterion_type, "values")
for value in values_list:
value_node = ET.SubElement(values_node, "value", literal=value)
- value_node.set('numerical', str(1 << index))
- index += 1
xmlstr = ET.tostring(criterion_types_root, encoding='utf8', method='xml')
reparsed = MINIDOM.parseString(xmlstr)
diff --git a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
index 84ad604..b17a248 100644
--- a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
+++ b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
@@ -295,14 +295,12 @@
audio_port_handle_t localPortId;
if (!portId) portId = &localPortId;
*portId = AUDIO_PORT_HANDLE_NONE;
- AudioPolicyInterface::input_type_t inputType;
AttributionSourceState attributionSource;
attributionSource.uid = 0;
attributionSource.token = sp<BBinder>::make();
- const auto inputRes =
- mManager->getInputForAttr(attr, input, *selectedDeviceId, config, flags, riid,
- AUDIO_SESSION_NONE, attributionSource, &inputType);
+ const auto inputRes = mManager->getInputForAttr(attr, input, *selectedDeviceId, config, flags,
+ riid, AUDIO_SESSION_NONE, attributionSource);
if (!inputRes.has_value()) return false;
if (inputRes->portId == AUDIO_PORT_HANDLE_NONE || inputRes->input == AUDIO_IO_HANDLE_NONE) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 465b0bf..18b5ea9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2935,8 +2935,7 @@
audio_input_flags_t flags,
audio_unique_id_t riid,
audio_session_t session,
- const AttributionSourceState& attributionSource,
- input_type_t *inputType)
+ const AttributionSourceState& attributionSource)
{
ALOGV("%s() source %d, sampling rate %d, format %#x, channel mask %#x, session %d, "
"flags %#x attributes=%s requested device ID %d",
@@ -2957,6 +2956,17 @@
attributes.source = AUDIO_SOURCE_MIC;
}
+ using PermissionReqs = AudioPolicyClientInterface::PermissionReqs;
+ using MixType = AudioPolicyClientInterface::MixType;
+ PermissionReqs permReq {
+ .source = legacy2aidl_audio_source_t_AudioSource(attributes.source).value(),
+ .mixType = MixType::NONE, // can be modified
+ .virtualDeviceId = 0, // can be modified
+ .isHotword = (flags & (AUDIO_INPUT_FLAG_HW_HOTWORD | AUDIO_INPUT_FLAG_HOTWORD_TAP |
+ AUDIO_INPUT_FLAG_HW_LOOKBACK)) != 0,
+ .isCallRedir = (attributes.flags & AUDIO_FLAG_CALL_REDIRECTION) != 0,
+ };
+
// Explicit routing?
sp<DeviceDescriptor> explicitRoutingDevice =
mAvailableInputDevices.getDeviceFromId(requestedDeviceId);
@@ -3000,13 +3010,9 @@
}
}
}
- *inputType = API_INPUT_LEGACY;
device = inputDesc->getDevice();
ALOGV("%s reusing MMAP input %d for session %d", __FUNCTION__, requestedInput, session);
- // TODO perm check
} else {
- *inputType = API_INPUT_INVALID;
-
if (attributes.source == AUDIO_SOURCE_REMOTE_SUBMIX &&
extractAddressFromAudioAttributes(attributes).has_value()) {
status_t status = mPolicyMixes.getInputMixForAttr(attributes, &policyMix);
@@ -3027,12 +3033,12 @@
}
if (is_mix_loopback_render(policyMix->mRouteFlags)) {
- *inputType = API_INPUT_MIX_PUBLIC_CAPTURE_PLAYBACK;
+ permReq.mixType = MixType::PUBLIC_CAPTURE_PLAYBACK;
} else {
- *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
+ permReq.mixType = MixType::EXT_POLICY_REROUTE;
}
// TODO is this correct?
- vdi = policyMix->mVirtualDeviceId;
+ permReq.virtualDeviceId = policyMix->mVirtualDeviceId;
} else {
if (explicitRoutingDevice != nullptr) {
device = explicitRoutingDevice;
@@ -3050,24 +3056,35 @@
attributes.source))};
}
if (device->type() == AUDIO_DEVICE_IN_ECHO_REFERENCE) {
- *inputType = API_INPUT_MIX_CAPTURE;
+ permReq.mixType = MixType::CAPTURE;
} else if (policyMix) {
ALOG_ASSERT(policyMix->mMixType == MIX_TYPE_RECORDERS, "Invalid Mix Type");
// there is an external policy, but this input is attached to a mix of recorders,
// meaning it receives audio injected into the framework, so the recorder doesn't
// know about it and is therefore considered "legacy"
- *inputType = API_INPUT_LEGACY;
- vdi = policyMix->mVirtualDeviceId;
+ permReq.mixType = MixType::NONE;
+ permReq.virtualDeviceId = policyMix->mVirtualDeviceId;
} else if (audio_is_remote_submix_device(device->type())) {
- *inputType = API_INPUT_MIX_CAPTURE;
+ permReq.mixType = MixType::CAPTURE;
} else if (device->type() == AUDIO_DEVICE_IN_TELEPHONY_RX) {
- *inputType = API_INPUT_TELEPHONY_RX;
+ permReq.mixType = MixType::TELEPHONY_RX_CAPTURE;
} else {
- *inputType = API_INPUT_LEGACY;
+ permReq.mixType = MixType::NONE;
}
}
- // TODO perm check
+ auto permRes = mpClientInterface->checkPermissionForInput(attributionSource, permReq);
+ if (!permRes.has_value()) return base::unexpected {permRes.error()};
+ if (!permRes.value()) {
+ return base::unexpected{Status::fromExceptionCode(
+ EX_SECURITY, String8::format("%s: %s missing perms for source %d mix %d vdi %d"
+ "hotword? %d callredir? %d", __func__, attributionSource.toString().c_str(),
+ static_cast<int>(permReq.source),
+ static_cast<int>(permReq.mixType),
+ permReq.virtualDeviceId,
+ permReq.isHotword,
+ permReq.isCallRedir))};
+ }
input = getInputForDevice(device, session, attributes, config, flags, policyMix);
if (input == AUDIO_IO_HANDLE_NONE) {
@@ -3108,14 +3125,14 @@
mEffects.moveEffectsForIo(session, input, &mInputs, mpClientInterface);
inputDesc->addClient(clientDesc);
- ALOGV("getInputForAttr() returns input %d type %d selectedDeviceId %d for port ID %d",
- input, *inputType, selectedDeviceId, allocatedPortId);
+ ALOGV("getInputForAttr() returns input %d selectedDeviceId %d vdi %d for port ID %d",
+ input, selectedDeviceId, permReq.virtualDeviceId, allocatedPortId);
auto ret = media::GetInputForAttrResponse {};
ret.input = input;
ret.selectedDeviceId = selectedDeviceId;
ret.portId = allocatedPortId;
- ret.virtualDeviceId = vdi;
+ ret.virtualDeviceId = permReq.virtualDeviceId;
ret.config = legacy2aidl_audio_config_base_t_AudioConfigBase(config, true /*isInput*/).value();
return ret;
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 28bf5cb..44863ee 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -144,8 +144,7 @@
audio_input_flags_t flags,
audio_unique_id_t riid,
audio_session_t session,
- const AttributionSourceState& attributionSource,
- input_type_t *inputType /* out param */) override;
+ const AttributionSourceState& attributionSource) override;
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_port_handle_t portId);
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index 79e328e..f415a41 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -25,7 +25,6 @@
"audio-permission-aidl-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
- "audiopermissioncontroller",
"audiopolicy-aidl-cpp",
"audiopolicy-types-aidl-cpp",
"capture_state_listener-aidl-cpp",
@@ -37,6 +36,7 @@
"libaudioclient_aidl_conversion",
"libaudiofoundation",
"libaudiohal",
+ "libaudiopermission",
"libaudiopolicy",
"libaudiopolicycomponents",
"libaudiopolicymanagerdefault",
@@ -118,6 +118,6 @@
name: "audiopolicyservicelocal_headers",
host_supported: true,
export_include_dirs: ["include"],
- header_libs: ["audiopermissioncontroller_headers"],
- export_header_lib_headers: ["audiopermissioncontroller_headers"],
+ header_libs: ["libaudiopermission_headers"],
+ export_header_lib_headers: ["libaudiopermission_headers"],
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 9d9836f..12320b7 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -87,8 +87,6 @@
using media::audio::common::AudioFormatDescription;
using media::audio::common::AudioMode;
using media::audio::common::AudioOffloadInfo;
-using media::audio::common::AudioPolicyForceUse;
-using media::audio::common::AudioPolicyForcedConfig;
using media::audio::common::AudioSource;
using media::audio::common::AudioStreamType;
using media::audio::common::AudioUsage;
@@ -298,8 +296,8 @@
return Status::ok();
}
-Status AudioPolicyService::setForceUse(AudioPolicyForceUse usageAidl,
- AudioPolicyForcedConfig configAidl)
+Status AudioPolicyService::setForceUse(media::AudioPolicyForceUse usageAidl,
+ media::AudioPolicyForcedConfig configAidl)
{
audio_policy_force_use_t usage = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(usageAidl));
@@ -330,8 +328,8 @@
return Status::ok();
}
-Status AudioPolicyService::getForceUse(AudioPolicyForceUse usageAidl,
- AudioPolicyForcedConfig* _aidl_return) {
+Status AudioPolicyService::getForceUse(media::AudioPolicyForceUse usageAidl,
+ media::AudioPolicyForcedConfig* _aidl_return) {
audio_policy_force_use_t usage = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioPolicyForceUse_audio_policy_force_use_t(usageAidl));
@@ -680,13 +678,14 @@
}
}
-error::BinderResult<bool> AudioPolicyService::evaluatePermsForSource(
- const AttributionSourceState& attrSource, AudioSource source, bool isHotword) {
+error::BinderResult<bool> AudioPolicyService::AudioPolicyClient::checkPermissionForInput(
+ const AttributionSourceState& attrSource, const PermissionReqs& req) {
+
error::BinderResult<bool> permRes = true;
const auto check_perm = [&](PermissionEnum perm, uid_t uid) {
- return getPermissionProvider().checkPermission(perm, uid);
+ return mAudioPolicyService->getPermissionProvider().checkPermission(perm, uid);
};
- switch (source) {
+ switch (req.source) {
case AudioSource::VOICE_UPLINK:
case AudioSource::VOICE_DOWNLINK:
case AudioSource::VOICE_CALL:
@@ -721,14 +720,13 @@
case AudioSource::VOICE_PERFORMANCE:
// No additional check intended
case AudioSource::REMOTE_SUBMIX:
- // special-case checked based on device (evaluatePermsForDevice)
+ // special-case checked based on mix type below
break;
}
- bool isAllowed = VALUE_OR_RETURN(permRes);
-
- if (!isAllowed) {
- if (isLegacyOutputSource(source)) {
+ if (!permRes.has_value()) return permRes;
+ if (!permRes.value()) {
+ if (isLegacyOutputSource(req.source)) {
permRes = audioserver_permissions() ? check_perm(CAPTURE_AUDIO_OUTPUT, attrSource.uid)
: captureAudioOutputAllowed(attrSource);
PROPAGATE_FALSEY(permRes);
@@ -737,70 +735,61 @@
}
}
- if (isHotword) {
+ if (req.isHotword) {
permRes = audioserver_permissions() ? check_perm(CAPTURE_AUDIO_HOTWORD, attrSource.uid)
: captureHotwordAllowed(attrSource);
PROPAGATE_FALSEY(permRes);
}
- // All sources which aren't output capture require RECORD as well,
- // as well as vdi policy mix
- const auto legacySource = aidl2legacy_AudioSource_audio_source_t(source).value();
- if (isRecordOpRequired(legacySource)) {
- permRes = audioserver_permissions() ? check_perm(RECORD_AUDIO, attrSource.uid)
- : recordingAllowed(attrSource, legacySource);
- PROPAGATE_FALSEY(permRes);
- }
- return true;
-}
-
-error::BinderResult<bool> AudioPolicyService::evaluatePermsForDevice(
- const AttributionSourceState& attrSource, AudioSource source,
- AudioPolicyInterface::input_type_t inputType, uint32_t vdi, bool isCallRedir) {
- // enforce permission (if any) required for each type of input
- error::BinderResult<bool> permRes = true;
- const auto check_perm = [&](PermissionEnum perm, uid_t uid) {
- return getPermissionProvider().checkPermission(perm, uid);
- };
+ // TODO evaluate whether we should be checking call redirection like this
bool isAllowedDueToCallPerm = false;
- if (isCallRedir) {
+ if (req.isCallRedir) {
const auto checkCall = audioserver_permissions()
- ? check_perm(CALL_AUDIO_INTERCEPTION, attrSource.uid)
- : callAudioInterceptionAllowed(attrSource);
+ ? check_perm(CALL_AUDIO_INTERCEPTION, attrSource.uid)
+ : callAudioInterceptionAllowed(attrSource);
isAllowedDueToCallPerm = VALUE_OR_RETURN(checkCall);
}
- switch (inputType) {
- case AudioPolicyInterface::API_INPUT_MIX_PUBLIC_CAPTURE_PLAYBACK:
+
+ switch (req.mixType) {
+ case MixType::NONE:
+ break;
+ case MixType::PUBLIC_CAPTURE_PLAYBACK:
// this use case has been validated in audio service with a MediaProjection token,
// and doesn't rely on regular permissions
- case AudioPolicyInterface::API_INPUT_LEGACY:
+ // TODO (b/378778313)
break;
- case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
+ case MixType::TELEPHONY_RX_CAPTURE:
if (isAllowedDueToCallPerm) break;
// FIXME: use the same permission as for remote submix for now.
FALLTHROUGH_INTENDED;
- case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
+ case MixType::CAPTURE:
permRes = audioserver_permissions() ? check_perm(CAPTURE_AUDIO_OUTPUT, attrSource.uid)
: captureAudioOutputAllowed(attrSource);
break;
- case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE: {
+ case MixType::EXT_POLICY_REROUTE:
// TODO intended?
if (isAllowedDueToCallPerm) break;
permRes = audioserver_permissions() ? check_perm(MODIFY_AUDIO_ROUTING, attrSource.uid)
: modifyAudioRoutingAllowed(attrSource);
break;
- }
- case AudioPolicyInterface::API_INPUT_INVALID:
- default:
- LOG_ALWAYS_FATAL("%s encountered an invalid input type %d", __func__, (int)inputType);
}
PROPAGATE_FALSEY(permRes);
- if (audiopolicy_flags::record_audio_device_aware_permission()) {
- // enforce device-aware RECORD_AUDIO permission
- const auto legacySource = aidl2legacy_AudioSource_audio_source_t(source).value();
- return vdi == kDefaultVirtualDeviceId || recordingAllowed(attrSource, vdi, legacySource);
+ // All sources which aren't output capture
+ // AND capture from vdi policy mix (the injected audio is mic data from another device)
+ // REQUIRE RECORD perms
+ const auto legacySource = aidl2legacy_AudioSource_audio_source_t(req.source).value();
+ if (req.virtualDeviceId != kDefaultVirtualDeviceId) {
+ // TODO assert that this is always a recordOpSource
+ // TODO upcall solution
+ return recordingAllowed(attrSource, req.virtualDeviceId, legacySource);
+ }
+
+ if (isRecordOpRequired(legacySource)) {
+ permRes = audioserver_permissions() ? check_perm(RECORD_AUDIO, attrSource.uid)
+ : recordingAllowed(attrSource, legacySource);
+ PROPAGATE_FALSEY(permRes);
}
return true;
}
@@ -847,19 +836,14 @@
inputSource = AudioSource::MIC;
}
- const bool isHotword = (flags & (AUDIO_INPUT_FLAG_HW_HOTWORD | AUDIO_INPUT_FLAG_HOTWORD_TAP |
- AUDIO_INPUT_FLAG_HW_LOOKBACK)) != 0;
-
const bool isCallRedir = (attr.flags & AUDIO_FLAG_CALL_REDIRECTION) != 0;
- const bool canCaptureOutput = audioserver_permissions()
- ? CHECK_PERM(CAPTURE_AUDIO_OUTPUT, attributionSource.uid)
- : captureAudioOutputAllowed(attributionSource);
-
//TODO(b/374751406): remove forcing canBypassConcurrentPolicy to canCaptureOutput
// once all system apps using CAPTURE_AUDIO_OUTPUT to capture during calls
// are updated to use the new CONCURRENT_AUDIO_RECORD_BYPASS permission.
- bool canBypassConcurrentPolicy = canCaptureOutput;
+ bool canBypassConcurrentPolicy = audioserver_permissions()
+ ? CHECK_PERM(CAPTURE_AUDIO_OUTPUT, attributionSource.uid)
+ : captureAudioOutputAllowed(attributionSource);
if (concurrent_audio_record_bypass_permission()) {
canBypassConcurrentPolicy = audioserver_permissions() ?
CHECK_PERM(BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION,
@@ -867,55 +851,16 @@
: bypassConcurrentPolicyAllowed(attributionSource);
}
- const bool hasPerm = VALUE_OR_RETURN_STATUS(evaluatePermsForSource(
- attributionSource,
- inputSource,
- isHotword));
-
- if (!hasPerm) {
- return Status::fromExceptionCode(
- EX_SECURITY, String8::format("%s: %s missing perms for source %s", __func__,
- attributionSource.toString().c_str(),
- toString(inputSource).c_str()));
- }
-
sp<AudioPolicyEffects> audioPolicyEffects;
base::expected<media::GetInputForAttrResponse, std::variant<binder::Status, AudioConfigBase>>
res;
{
- AudioPolicyInterface::input_type_t inputType;
-
audio_utils::lock_guard _l(mMutex);
- {
- AutoCallerClear acc;
- // the audio_in_acoustics_t parameter is ignored by get_input()
- res = mAudioPolicyManager->getInputForAttr(attr, requestedInput, requestedDeviceId,
- config, flags, riid, session, attributionSource, &inputType);
-
- }
- audioPolicyEffects = mAudioPolicyEffects;
-
- if (res.has_value()) {
- const auto permResult = evaluatePermsForDevice(attributionSource,
- inputSource, inputType, res->virtualDeviceId,
- isCallRedir);
-
- if (!permResult.has_value()) {
- AutoCallerClear acc;
- mAudioPolicyManager->releaseInput(res->portId);
- return permResult.error();
- } else if (!permResult.value()) {
- AutoCallerClear acc;
- mAudioPolicyManager->releaseInput(res->portId);
- return Status::fromExceptionCode(
- EX_SECURITY,
- String8::format(
- "%s: %s missing perms for input type %d, inputSource %d, vdi %d",
- __func__, attributionSource.toString().c_str(), inputType,
- inputSource, res->virtualDeviceId));
- }
- }
-
+ AutoCallerClear acc;
+ // the audio_in_acoustics_t parameter is ignored by get_input()
+ res = mAudioPolicyManager->getInputForAttr(attr, requestedInput, requestedDeviceId,
+ config, flags, riid, session,
+ attributionSource);
if (!res.has_value()) {
if (res.error().index() == 1) {
_aidl_return->config = std::get<1>(res.error());
@@ -925,16 +870,15 @@
}
}
- DeviceIdVector selectedDeviceIds = { res->selectedDeviceId };
- sp<AudioRecordClient> client = new AudioRecordClient(attr, res->input, session, res->portId,
- selectedDeviceIds, attributionSource,
- res->virtualDeviceId,
- canBypassConcurrentPolicy,
- mOutputCommandThread);
+ audioPolicyEffects = mAudioPolicyEffects;
+
+ sp<AudioRecordClient> client = new AudioRecordClient(
+ attr, res->input, session, res->portId, {res->selectedDeviceId}, attributionSource,
+ res->virtualDeviceId, canBypassConcurrentPolicy, mOutputCommandThread);
mAudioRecordClients.add(res->portId, client);
}
- if (audioPolicyEffects != 0) {
+ if (audioPolicyEffects != nullptr) {
// create audio pre processors according to input source
status_t status = audioPolicyEffects->addInputEffects(res->input,
aidl2legacy_AudioSource_audio_source_t(inputSource).value(), session);
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 5fe200c..acd9fe9 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -108,10 +108,10 @@
const std::string& deviceName,
const AudioFormatDescription& encodedFormat) override;
binder::Status setPhoneState(AudioMode state, int32_t uid) override;
- binder::Status setForceUse(android::media::audio::common::AudioPolicyForceUse usage,
- android::media::audio::common::AudioPolicyForcedConfig config) override;
- binder::Status getForceUse(android::media::audio::common::AudioPolicyForceUse usage,
- android::media::audio::common::AudioPolicyForcedConfig* _aidl_return) override;
+ binder::Status setForceUse(media::AudioPolicyForceUse usage,
+ media::AudioPolicyForcedConfig config) override;
+ binder::Status getForceUse(media::AudioPolicyForceUse usage,
+ media::AudioPolicyForcedConfig* _aidl_return) override;
binder::Status getOutput(AudioStreamType stream, int32_t* _aidl_return) override;
binder::Status getOutputForAttr(const media::audio::common::AudioAttributes& attr,
int32_t session,
@@ -504,14 +504,6 @@
const audio_output_flags_t flags);
status_t unregisterOutput(audio_io_handle_t output);
- error::BinderResult<bool> evaluatePermsForSource(const AttributionSourceState& attrSource,
- AudioSource source, bool isHotword);
-
- error::BinderResult<bool> evaluatePermsForDevice(const AttributionSourceState& attrSource,
- AudioSource source,
- AudioPolicyInterface::input_type_t inputType,
- uint32_t vdi, bool isCallRedir);
-
// If recording we need to make sure the UID is allowed to do that. If the UID is idle
// then it cannot record and gets buffers with zeros - silence. As soon as the UID
// transitions to an active state we will start reporting buffers with data. This approach
@@ -968,6 +960,9 @@
media::audio::common::AudioMMapPolicyType policyType,
std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) override;
+ error::BinderResult<bool> checkPermissionForInput(const AttributionSourceState& attr,
+ const PermissionReqs& req) override;
+
private:
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/audiopolicy/service/AudioRecordClient.cpp b/services/audiopolicy/service/AudioRecordClient.cpp
index fd344d9..01e557c 100644
--- a/services/audiopolicy/service/AudioRecordClient.cpp
+++ b/services/audiopolicy/service/AudioRecordClient.cpp
@@ -64,12 +64,12 @@
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = AttributionSourceState;
- using pointer = const value_type*;
- using reference = const value_type&;
+ using pointer = value_type*;
+ using reference = value_type&;
AttrSourceItr() : mAttr(nullptr) {}
- AttrSourceItr(const AttributionSourceState& attr) : mAttr(&attr) {}
+ AttrSourceItr(AttributionSourceState& attr) : mAttr(&attr) {}
reference operator*() const { return *mAttr; }
pointer operator->() const { return mAttr; }
@@ -89,7 +89,7 @@
static AttrSourceItr end() { return AttrSourceItr{}; }
private:
- const AttributionSourceState * mAttr;
+ AttributionSourceState * mAttr;
};
} // anonymous
@@ -134,6 +134,16 @@
mVirtualDeviceId(virtualDeviceId), mAttr(attr), mAppOp(appOp),
mShouldMonitorRecord(shouldMonitorRecord),
mCommandThread(commandThread) {
+ // The vdi is carried in the attribution source for appops perm checks.
+ // Overwrite the entire chain with the vdi associated with the mix this client is attached to
+ // This ensures the checkOps triggered by the listener are correct.
+ // Note: we still only register for events by package name, so we assume that we get events
+ // independent of vdi.
+ if (mVirtualDeviceId != 0 /* default vdi */) {
+ // TODO (atneya@) lift for const
+ std::for_each(AttrSourceItr{mAttributionSource}, AttrSourceItr::end(),
+ [&](auto& attr) { attr.deviceId = mVirtualDeviceId; });
+ }
}
OpRecordAudioMonitor::~OpRecordAudioMonitor()
diff --git a/services/audiopolicy/service/AudioRecordClient.h b/services/audiopolicy/service/AudioRecordClient.h
index f45b4de..3553f1d 100644
--- a/services/audiopolicy/service/AudioRecordClient.h
+++ b/services/audiopolicy/service/AudioRecordClient.h
@@ -71,7 +71,7 @@
void checkOp(bool updateUidStates = false);
std::atomic_bool mHasOp;
- const AttributionSourceState mAttributionSource;
+ AttributionSourceState mAttributionSource;
const uint32_t mVirtualDeviceId;
const audio_attributes_t mAttr;
const int32_t mAppOp;
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index 33dc5fe..8e5fb96 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -128,6 +128,10 @@
std::vector<media::audio::common::AudioMMapPolicyInfo>* /*policyInfos*/) override {
return INVALID_OPERATION;
}
+ error::BinderResult<bool> checkPermissionForInput(const AttributionSourceState& /* attr */,
+ const PermissionReqs& /* req */) {
+ return true;
+ }
};
} // namespace android
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 3cdf6a1..a8f79c3 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -334,10 +334,9 @@
if (!portId) portId = &localPortId;
*portId = AUDIO_PORT_HANDLE_NONE;
if (!virtualDeviceId) virtualDeviceId = 0;
- AudioPolicyInterface::input_type_t inputType;
AttributionSourceState attributionSource = createAttributionSourceState(/*uid=*/ 0);
auto inputRes = mManager->getInputForAttr(attr, *input, *selectedDeviceId,
- config, flags, riid, session, attributionSource, &inputType);
+ config, flags, riid, session, attributionSource);
ASSERT_TRUE(inputRes.has_value());
ASSERT_NE(inputRes->portId, AUDIO_PORT_HANDLE_NONE);
*input = inputRes->input;
@@ -1242,7 +1241,7 @@
};
auto inputRes = mManager->getInputForAttr(attr, requestedInput, requestedDeviceId,
requestedConfig, AUDIO_INPUT_FLAG_NONE, 1 /*riid*/,
- AUDIO_SESSION_NONE, attributionSource, &inputType);
+ AUDIO_SESSION_NONE, attributionSource);
ASSERT_TRUE(inputRes.has_value());
ASSERT_NE(inputRes->portId, AUDIO_PORT_HANDLE_NONE);
ASSERT_EQ(VALUE_OR_FATAL(legacy2aidl_audio_config_base_t_AudioConfigBase(
@@ -1255,7 +1254,7 @@
inputRes = mManager->getInputForAttr(attr, requestedInput, requestedDeviceId, requestedConfig,
AUDIO_INPUT_FLAG_NONE, 1 /*riid*/, AUDIO_SESSION_NONE,
- attributionSource, &inputType);
+ attributionSource);
ASSERT_TRUE(inputRes.has_value());
ASSERT_NE(inputRes->portId, AUDIO_PORT_HANDLE_NONE);
ASSERT_EQ(VALUE_OR_FATAL(legacy2aidl_audio_config_base_t_AudioConfigBase(requestedConfig,
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index df94478..31a45c3 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -3811,14 +3811,31 @@
const std::string& cameraId) {
// Remove from active clients list
std::vector<sp<CameraService::BasicClient>> clients;
- std::vector<CameraService::DescriptorPtr> clientDescriptors;
- clientDescriptors = mActiveClientManager.removeAll(cameraId);
- for (const auto& clientDescriptorPtr : clientDescriptors) {
+ if (flags::camera_multi_client()) {
+ std::vector<CameraService::DescriptorPtr> clientDescriptors;
+ clientDescriptors = mActiveClientManager.removeAll(cameraId);
+ for (const auto& clientDescriptorPtr : clientDescriptors) {
+ if (clientDescriptorPtr != nullptr) {
+ sp<BasicClient> client = clientDescriptorPtr->getValue();
+ if (client.get() != nullptr) {
+ cacheClientTagDumpIfNeeded(clientDescriptorPtr->getKey(), client.get());
+ clients.push_back(client);
+ }
+ }
+ }
+ } else {
+ auto clientDescriptorPtr = mActiveClientManager.remove(cameraId);
+ if (clientDescriptorPtr == nullptr) {
+ ALOGW("%s: Could not evict client, no client for camera ID %s", __FUNCTION__,
+ cameraId.c_str());
+ return clients;
+ }
+
sp<BasicClient> client = clientDescriptorPtr->getValue();
if (client.get() != nullptr) {
cacheClientTagDumpIfNeeded(clientDescriptorPtr->getKey(), client.get());
+ clients.push_back(client);
}
- clients.push_back(client);
}
return clients;
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 9c75ede..6f29ff4 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -631,6 +631,9 @@
CameraClientManager();
virtual ~CameraClientManager();
+ // Bring all remove() functions into scope
+ using ClientManager::remove;
+
virtual void remove(const DescriptorPtr& value) override;
/**
diff --git a/services/camera/libcameraservice/utils/ClientManager.h b/services/camera/libcameraservice/utils/ClientManager.h
index b2b8685..0f0dc4c 100644
--- a/services/camera/libcameraservice/utils/ClientManager.h
+++ b/services/camera/libcameraservice/utils/ClientManager.h
@@ -746,9 +746,9 @@
for (auto it = mClients.begin(); it != mClients.end();)
{
if ((*it)->getKey() == key) {
- it = mClients.erase(it);
if (mListener != nullptr) mListener->onClientRemoved(**it);
clients.push_back(*it);
+ it = mClients.erase(it);
} else {
++it;
}
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index ee4df4e..202ab96 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -1253,14 +1253,6 @@
request->update(ANDROID_CONTROL_AUTOFRAMING, &kDefaultAutoframingMode, 1);
}
- if (flags::ae_priority()) {
- // Fill in CONTROL_AE_PRIORITY_MODE if not available
- if (!request->exists(ANDROID_CONTROL_AE_PRIORITY_MODE)) {
- static const uint8_t kDefaultAePriorityMode = ANDROID_CONTROL_AE_PRIORITY_MODE_OFF;
- request->update(ANDROID_CONTROL_AE_PRIORITY_MODE, &kDefaultAePriorityMode, 1);
- }
- }
-
return OK;
}