Merge changes from topic "OfflineReproc-impl"
* changes:
Camera: Propagate all offline stream ids to clients
Camera: Add initial offline client listener logic
Camera: Initial support for composite streams in offline mode
Camera: Initial offline session client
Camera: fill in Camera3Device offline processing impl
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index d8220eb..56f209c 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -57,6 +57,9 @@
"libmediandk",
"libnativewindow",
],
+ header_libs: [
+ "jni_headers",
+ ],
cflags: [
"-fvisibility=hidden",
"-DEXPORT=__attribute__ ((visibility (\"default\")))",
@@ -121,7 +124,6 @@
"android.frameworks.cameraservice.common@2.0",
"android.frameworks.cameraservice.service@2.0",
],
-
static_libs: [
"android.hardware.camera.common@1.0-helper",
"libarect",
diff --git a/camera/ndk/NdkCameraMetadata.cpp b/camera/ndk/NdkCameraMetadata.cpp
index 9a39ed8..99691ed 100644
--- a/camera/ndk/NdkCameraMetadata.cpp
+++ b/camera/ndk/NdkCameraMetadata.cpp
@@ -26,6 +26,68 @@
using namespace android;
+#ifndef __ANDROID_VNDK__
+namespace {
+
+constexpr const char* android_hardware_camera2_CameraMetadata_jniClassName =
+ "android/hardware/camera2/CameraMetadata";
+constexpr const char* android_hardware_camera2_CameraCharacteristics_jniClassName =
+ "android/hardware/camera2/CameraCharacteristics";
+constexpr const char* android_hardware_camera2_CaptureResult_jniClassName =
+ "android/hardware/camera2/CaptureResult";
+
+jclass android_hardware_camera2_CameraCharacteristics_clazz = nullptr;
+jclass android_hardware_camera2_CaptureResult_clazz = nullptr;
+jmethodID android_hardware_camera2_CameraMetadata_getNativeMetadataPtr = nullptr;
+
+// Called at most once to initializes global variables used by JNI.
+bool InitJni(JNIEnv* env) {
+ // From C++11 onward, static initializers are guaranteed to be executed at most once,
+ // even if called from multiple threads.
+ static bool ok = [env]() -> bool {
+ const jclass cameraMetadataClazz = env->FindClass(
+ android_hardware_camera2_CameraMetadata_jniClassName);
+ if (cameraMetadataClazz == nullptr) {
+ return false;
+ }
+ android_hardware_camera2_CameraMetadata_getNativeMetadataPtr =
+ env->GetMethodID(cameraMetadataClazz, "getNativeMetadataPtr", "()J");
+ if (android_hardware_camera2_CameraMetadata_getNativeMetadataPtr == nullptr) {
+ return false;
+ }
+
+ android_hardware_camera2_CameraCharacteristics_clazz = env->FindClass(
+ android_hardware_camera2_CameraCharacteristics_jniClassName);
+ if (android_hardware_camera2_CameraCharacteristics_clazz == nullptr) {
+ return false;
+ }
+
+ android_hardware_camera2_CaptureResult_clazz = env->FindClass(
+ android_hardware_camera2_CaptureResult_jniClassName);
+ if (android_hardware_camera2_CaptureResult_clazz == nullptr) {
+ return false;
+ }
+
+ return true;
+ }();
+ return ok;
+}
+
+// Given cameraMetadata, an instance of android.hardware.camera2.CameraMetadata, invokes
+// cameraMetadata.getNativeMetadataPtr() and returns it as a CameraMetadata*.
+CameraMetadata* CameraMetadata_getNativeMetadataPtr(JNIEnv* env, jobject cameraMetadata) {
+ if (cameraMetadata == nullptr) {
+ ALOGE("%s: Invalid Java CameraMetadata object.", __FUNCTION__);
+ return nullptr;
+ }
+ jlong ret = env->CallLongMethod(cameraMetadata,
+ android_hardware_camera2_CameraMetadata_getNativeMetadataPtr);
+ return reinterpret_cast<CameraMetadata *>(ret);
+}
+
+} // namespace
+#endif /* __ANDROID_VNDK__ */
+
EXPORT
camera_status_t ACameraMetadata_getConstEntry(
const ACameraMetadata* acm, uint32_t tag, ACameraMetadata_const_entry* entry) {
@@ -58,7 +120,7 @@
return nullptr;
}
ACameraMetadata* copy = new ACameraMetadata(*src);
- copy->incStrong((void*) ACameraMetadata_copy);
+ copy->incStrong(/*id=*/(void*) ACameraMetadata_copy);
return copy;
}
@@ -86,3 +148,34 @@
return staticMetadata->isLogicalMultiCamera(numPhysicalCameras, physicalCameraIds);
}
+
+#ifndef __ANDROID_VNDK__
+EXPORT
+ACameraMetadata* ACameraMetadata_fromCameraMetadata(JNIEnv* env, jobject cameraMetadata) {
+ ATRACE_CALL();
+
+ const bool ok = InitJni(env);
+ LOG_ALWAYS_FATAL_IF(!ok, "Failed to find CameraMetadata Java classes.");
+
+ if (cameraMetadata == nullptr) {
+ return nullptr;
+ }
+
+ ACameraMetadata::ACAMERA_METADATA_TYPE type;
+ if (env->IsInstanceOf(cameraMetadata,
+ android_hardware_camera2_CameraCharacteristics_clazz)) {
+ type = ACameraMetadata::ACM_CHARACTERISTICS;
+ } else if (env->IsInstanceOf(cameraMetadata,
+ android_hardware_camera2_CaptureResult_clazz)) {
+ type = ACameraMetadata::ACM_RESULT;
+ } else {
+ return nullptr;
+ }
+
+ CameraMetadata* src = CameraMetadata_getNativeMetadataPtr(env,
+ cameraMetadata);
+ ACameraMetadata* output = new ACameraMetadata(src, type);
+ output->incStrong(/*id=*/(void*) ACameraMetadata_fromCameraMetadata);
+ return output;
+}
+#endif /* __ANDROID_VNDK__ */
\ No newline at end of file
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index e15e1a0..0ff78ab 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -28,7 +28,37 @@
* ACameraMetadata Implementation
*/
ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type) :
- mData(buffer), mType(type) {
+ mData(new CameraMetadata(buffer)),
+ mOwnsData(true),
+ mType(type) {
+ init();
+}
+
+ACameraMetadata::ACameraMetadata(CameraMetadata* cameraMetadata, ACAMERA_METADATA_TYPE type) :
+ mData(cameraMetadata),
+ mOwnsData(false),
+ mType(type) {
+ init();
+}
+
+ACameraMetadata::ACameraMetadata(const ACameraMetadata& other) :
+ mOwnsData(other.mOwnsData),
+ mType(other.mType) {
+ if (other.mOwnsData) {
+ mData = new CameraMetadata(*(other.mData));
+ } else {
+ mData = other.mData;
+ }
+}
+
+ACameraMetadata::~ACameraMetadata() {
+ if (mOwnsData) {
+ delete mData;
+ }
+}
+
+void
+ACameraMetadata::init() {
if (mType == ACM_CHARACTERISTICS) {
filterUnsupportedFeatures();
filterStreamConfigurations();
@@ -61,7 +91,7 @@
void
ACameraMetadata::filterUnsupportedFeatures() {
// Hide unsupported capabilities (reprocessing)
- camera_metadata_entry entry = mData.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ camera_metadata_entry entry = mData->find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
if (entry.count == 0 || entry.type != TYPE_BYTE) {
ALOGE("%s: malformed available capability key! count %zu, type %d",
__FUNCTION__, entry.count, entry.type);
@@ -80,7 +110,7 @@
}
}
}
- mData.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities);
+ mData->update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities);
}
void
@@ -118,7 +148,7 @@
const int STREAM_WIDTH_OFFSET = 1;
const int STREAM_HEIGHT_OFFSET = 2;
const int STREAM_DURATION_OFFSET = 3;
- camera_metadata_entry entry = mData.find(tag);
+ camera_metadata_entry entry = mData->find(tag);
if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) {
ALOGE("%s: malformed duration key %d! count %zu, type %d",
__FUNCTION__, tag, entry.count, entry.type);
@@ -194,7 +224,7 @@
}
}
- mData.update(tag, filteredDurations);
+ mData->update(tag, filteredDurations);
}
void
@@ -204,7 +234,7 @@
const int STREAM_WIDTH_OFFSET = 1;
const int STREAM_HEIGHT_OFFSET = 2;
const int STREAM_IS_INPUT_OFFSET = 3;
- camera_metadata_entry entry = mData.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
+ camera_metadata_entry entry = mData->find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
ALOGE("%s: malformed available stream configuration key! count %zu, type %d",
__FUNCTION__, entry.count, entry.type);
@@ -234,10 +264,10 @@
}
if (filteredStreamConfigs.size() > 0) {
- mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
+ mData->update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
}
- entry = mData.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
+ entry = mData->find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d",
__FUNCTION__, entry.count, entry.type);
@@ -270,11 +300,11 @@
}
if (filteredDepthStreamConfigs.size() > 0) {
- mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+ mData->update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
filteredDepthStreamConfigs);
}
- entry = mData.find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
+ entry = mData->find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
Vector<int32_t> filteredHeicStreamConfigs;
filteredHeicStreamConfigs.setCapacity(entry.count);
@@ -297,9 +327,9 @@
filteredHeicStreamConfigs.push_back(height);
filteredHeicStreamConfigs.push_back(isInput);
}
- mData.update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs);
+ mData->update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs);
- entry = mData.find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
+ entry = mData->find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
Vector<int32_t> filteredDynamicDepthStreamConfigs;
filteredDynamicDepthStreamConfigs.setCapacity(entry.count);
@@ -322,7 +352,7 @@
filteredDynamicDepthStreamConfigs.push_back(height);
filteredDynamicDepthStreamConfigs.push_back(isInput);
}
- mData.update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
+ mData->update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
filteredDynamicDepthStreamConfigs);
}
@@ -343,7 +373,7 @@
Mutex::Autolock _l(mLock);
- camera_metadata_ro_entry rawEntry = mData.find(tag);
+ camera_metadata_ro_entry rawEntry = static_cast<const CameraMetadata*>(mData)->find(tag);
if (rawEntry.count == 0) {
ALOGE("%s: cannot find metadata tag %d", __FUNCTION__, tag);
return ACAMERA_ERROR_METADATA_NOT_FOUND;
@@ -390,9 +420,9 @@
/*out*/const uint32_t** tags) const {
Mutex::Autolock _l(mLock);
if (mTags.size() == 0) {
- size_t entry_count = mData.entryCount();
+ size_t entry_count = mData->entryCount();
mTags.setCapacity(entry_count);
- const camera_metadata_t* rawMetadata = mData.getAndLock();
+ const camera_metadata_t* rawMetadata = mData->getAndLock();
for (size_t i = 0; i < entry_count; i++) {
camera_metadata_ro_entry_t entry;
int ret = get_camera_metadata_ro_entry(rawMetadata, i, &entry);
@@ -405,7 +435,7 @@
mTags.push_back(entry.tag);
}
}
- mData.unlock(rawMetadata);
+ mData->unlock(rawMetadata);
}
*numTags = mTags.size();
@@ -415,7 +445,7 @@
const CameraMetadata&
ACameraMetadata::getInternalData() const {
- return mData;
+ return (*mData);
}
bool
diff --git a/camera/ndk/impl/ACameraMetadata.h b/camera/ndk/impl/ACameraMetadata.h
index 97f7f48..a57b2ff 100644
--- a/camera/ndk/impl/ACameraMetadata.h
+++ b/camera/ndk/impl/ACameraMetadata.h
@@ -36,8 +36,8 @@
using namespace android;
/**
- * ACameraMetadata opaque struct definition
- * Leave outside of android namespace because it's NDK struct
+ * ACameraMetadata is an opaque struct definition.
+ * It is intentionally left outside of the android namespace because it's NDK struct.
*/
struct ACameraMetadata : public RefBase {
public:
@@ -47,11 +47,20 @@
ACM_RESULT, // Read only
} ACAMERA_METADATA_TYPE;
- // Takes ownership of pass-in buffer
- ACameraMetadata(camera_metadata_t *buffer, ACAMERA_METADATA_TYPE type);
- // Clone
- ACameraMetadata(const ACameraMetadata& other) :
- mData(other.mData), mType(other.mType) {};
+ // Constructs a ACameraMetadata that takes ownership of `buffer`.
+ ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type);
+
+ // Constructs a ACameraMetadata that is a view of `cameraMetadata`.
+ // `cameraMetadata` will not be deleted by ~ACameraMetadata().
+ ACameraMetadata(CameraMetadata* cameraMetadata, ACAMERA_METADATA_TYPE type);
+
+ // Copy constructor.
+ //
+ // If `other` owns its CameraMetadata, then makes a deep copy.
+ // Otherwise, the new instance is also a view of the same data.
+ ACameraMetadata(const ACameraMetadata& other);
+
+ ~ACameraMetadata();
camera_status_t getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const;
@@ -70,6 +79,9 @@
private:
+ // Common code called by constructors.
+ void init();
+
// This function does not check whether the capability passed to it is valid.
// The caller must make sure that it is.
bool isNdkSupportedCapability(const int32_t capability);
@@ -95,11 +107,11 @@
status_t ret = OK;
if (count == 0 && data == nullptr) {
- ret = mData.erase(tag);
+ ret = mData->erase(tag);
} else {
// Here we have to use reinterpret_cast because the NDK data type is
// exact copy of internal data type but they do not inherit from each other
- ret = mData.update(tag, reinterpret_cast<const INTERNAL_T*>(data), count);
+ ret = mData->update(tag, reinterpret_cast<const INTERNAL_T*>(data), count);
}
if (ret == OK) {
@@ -110,10 +122,14 @@
}
}
- // guard access of public APIs: get/update/getTags
- mutable Mutex mLock;
- CameraMetadata mData;
- mutable Vector<uint32_t> mTags; // updated in getTags, cleared by update
+ // Guard access of public APIs: get/update/getTags.
+ mutable Mutex mLock;
+
+ CameraMetadata* mData;
+ // If true, has ownership of mData. Otherwise, mData is a view of an external instance.
+ bool mOwnsData;
+
+ mutable Vector<uint32_t> mTags; // Updated by `getTags()`, cleared by `update()`.
const ACAMERA_METADATA_TYPE mType;
static std::unordered_set<uint32_t> sSystemTags;
diff --git a/camera/ndk/include/camera/NdkCameraMetadata.h b/camera/ndk/include/camera/NdkCameraMetadata.h
index 9bbfb83..ee75610 100644
--- a/camera/ndk/include/camera/NdkCameraMetadata.h
+++ b/camera/ndk/include/camera/NdkCameraMetadata.h
@@ -39,6 +39,12 @@
#include <stdint.h>
#include <sys/cdefs.h>
+#ifndef __ANDROID_VNDK__
+#if __ANDROID_API__ >= 30
+#include "jni.h"
+#endif /* __ANDROID_API__ >= 30 */
+#endif /* __ANDROID_VNDK__ */
+
#include "NdkCameraError.h"
#include "NdkCameraMetadataTags.h"
@@ -255,8 +261,40 @@
#endif /* __ANDROID_API__ >= 29 */
+#ifndef __ANDROID_VNDK__
+#if __ANDROID_API__ >= 30
+
+/**
+ * Return a {@link ACameraMetadata} that references the same data as
+ * {@link cameraMetadata}, which is an instance of
+ * {@link android.hardware.camera2.CameraMetadata} (e.g., a
+ * {@link android.hardware.camera2.CameraCharacteristics} or
+ * {@link android.hardware.camera2.CaptureResult}).
+ *
+ * <p>The returned ACameraMetadata must be freed by the application by {@link ACameraMetadata_free}
+ * after application is done using it.</p>
+ *
+ * <p>This function does not affect the lifetime of {@link cameraMetadata}. Attempting to use the
+ * returned ACameraMetadata object after {@link cameraMetadata} has been garbage collected is
+ * unsafe. To manage the lifetime beyond the current JNI function call, use
+ * {@code env->NewGlobalRef()} and {@code env->DeleteGlobalRef()}.
+ *
+ * @param env the JNI environment.
+ * @param cameraMetadata the source {@link android.hardware.camera2.CameraMetadata} from which the
+ * returned {@link ACameraMetadata} is a view.
+ *
+ * @return a valid ACameraMetadata pointer or NULL if {@link cameraMetadata} is null or not a valid
+ * instance of {@link android.hardware.camera2.CameraMetadata}.
+ *
+ */
+ACameraMetadata* ACameraMetadata_fromCameraMetadata(JNIEnv* env, jobject cameraMetadata)
+ __INTRODUCED_IN(30);
+
+#endif /* __ANDROID_API__ >= 30 */
+#endif /* __ANDROID_VNDK__ */
+
__END_DECLS
#endif /* _NDK_CAMERA_METADATA_H */
-/** @} */
+/** @} */
\ No newline at end of file
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 6fefa41..3ac3ded 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -2509,6 +2509,11 @@
* <p><code>p' = Rp</code></p>
* <p>where <code>p</code> is in the device sensor coordinate system, and
* <code>p'</code> is in the camera-oriented coordinate system.</p>
+ * <p>If ACAMERA_LENS_POSE_REFERENCE is UNDEFINED, the quaternion rotation cannot
+ * be accurately represented by the camera device, and will be represented by
+ * default values matching its default facing.</p>
+ *
+ * @see ACAMERA_LENS_POSE_REFERENCE
*/
ACAMERA_LENS_POSE_ROTATION = // float[4]
ACAMERA_LENS_START + 6,
@@ -2549,6 +2554,8 @@
* <p>When ACAMERA_LENS_POSE_REFERENCE is GYROSCOPE, then this position is relative to
* the center of the primary gyroscope on the device. The axis definitions are the same as
* with PRIMARY_CAMERA.</p>
+ * <p>When ACAMERA_LENS_POSE_REFERENCE is UNDEFINED, this position cannot be accurately
+ * represented by the camera device, and will be represented as <code>(0, 0, 0)</code>.</p>
*
* @see ACAMERA_LENS_DISTORTION
* @see ACAMERA_LENS_INTRINSIC_CALIBRATION
@@ -2691,8 +2698,10 @@
ACAMERA_LENS_RADIAL_DISTORTION = // Deprecated! DO NOT USE
ACAMERA_LENS_START + 11,
/**
- * <p>The origin for ACAMERA_LENS_POSE_TRANSLATION.</p>
+ * <p>The origin for ACAMERA_LENS_POSE_TRANSLATION, and the accuracy of
+ * ACAMERA_LENS_POSE_TRANSLATION and ACAMERA_LENS_POSE_ROTATION.</p>
*
+ * @see ACAMERA_LENS_POSE_ROTATION
* @see ACAMERA_LENS_POSE_TRANSLATION
*
* <p>Type: byte (acamera_metadata_enum_android_lens_pose_reference_t)</p>
@@ -7539,6 +7548,19 @@
*/
ACAMERA_LENS_POSE_REFERENCE_GYROSCOPE = 1,
+ /**
+ * <p>The camera device cannot represent the values of ACAMERA_LENS_POSE_TRANSLATION
+ * and ACAMERA_LENS_POSE_ROTATION accurately enough. One such example is a camera device
+ * on the cover of a foldable phone: in order to measure the pose translation and rotation,
+ * some kind of hinge position sensor would be needed.</p>
+ * <p>The value of ACAMERA_LENS_POSE_TRANSLATION must be all zeros, and
+ * ACAMERA_LENS_POSE_ROTATION must be values matching its default facing.</p>
+ *
+ * @see ACAMERA_LENS_POSE_ROTATION
+ * @see ACAMERA_LENS_POSE_TRANSLATION
+ */
+ ACAMERA_LENS_POSE_REFERENCE_UNDEFINED = 2,
+
} acamera_metadata_enum_android_lens_pose_reference_t;
diff --git a/camera/ndk/libcamera2ndk.map.txt b/camera/ndk/libcamera2ndk.map.txt
index b6f1553..2b630db 100644
--- a/camera/ndk/libcamera2ndk.map.txt
+++ b/camera/ndk/libcamera2ndk.map.txt
@@ -31,6 +31,7 @@
ACameraMetadata_getAllTags;
ACameraMetadata_getConstEntry;
ACameraMetadata_isLogicalMultiCamera; # introduced=29
+ ACameraMetadata_fromCameraMetadata; # introduced=30
ACameraOutputTarget_create;
ACameraOutputTarget_free;
ACaptureRequest_addTarget;
diff --git a/media/extractors/Android.bp b/media/extractors/Android.bp
index 06ef788..bb42580 100644
--- a/media/extractors/Android.bp
+++ b/media/extractors/Android.bp
@@ -13,7 +13,7 @@
// limitations under the License.
cc_defaults {
- name: "extractor-defaults_no-sanitizer",
+ name: "extractor-defaults",
include_dirs: [
"frameworks/av/media/libstagefright/include",
@@ -35,12 +35,6 @@
],
version_script: "exports.lds",
-}
-
-cc_defaults {
- name: "extractor-defaults",
-
- defaults: ["extractor-defaults_no-sanitizer"],
sanitize: {
cfi: true,
diff --git a/media/extractors/mp4/Android.bp b/media/extractors/mp4/Android.bp
index 3dc3fed..e48e1b7 100644
--- a/media/extractors/mp4/Android.bp
+++ b/media/extractors/mp4/Android.bp
@@ -1,6 +1,6 @@
-cc_defaults {
- name: "libmp4extractor_defaults",
- defaults: ["extractor-defaults_no-sanitizer"],
+cc_library {
+ name: "libmp4extractor",
+ defaults: ["extractor-defaults"],
srcs: [
"AC4Parser.cpp",
@@ -17,24 +17,3 @@
"libutils",
],
}
-
-cc_library {
-
- name: "libmp4extractor",
- defaults: ["libmp4extractor_defaults"],
-
- sanitize: {
- cfi: true,
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- },
-
-}
-
-cc_library_static {
- name: "libmp4extractor_fuzzing",
-
- defaults: ["libmp4extractor_defaults"],
-}
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index baada22..8753aa9 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -44,14 +44,6 @@
sanitize: {
integer_overflow: true,
misc_undefined: ["bounds"],
- diag: {
- integer_overflow: true,
- misc_undefined: ["bounds"],
- no_recover: [
- "bounds",
- "integer",
- ],
- },
},
stubs: {
@@ -137,14 +129,5 @@
sanitize: {
integer_overflow: true,
misc_undefined: ["bounds"],
- diag: {
- integer_overflow: true,
- misc_undefined: ["bounds"],
- no_recover: [
- "bounds",
- "integer",
- ],
- },
},
-
}
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index ef9d253..960120f 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1310,7 +1310,7 @@
OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
status_t err = configureOutputBuffersFromNativeWindow(
&bufferCount, &bufferSize, &minUndequeuedBuffers,
- false /* preregister */);
+ mFlags & kFlagPreregisterMetadataBuffers /* preregister */);
if (err != OK)
return err;
mNumUndequeuedBuffers = minUndequeuedBuffers;
@@ -1896,6 +1896,19 @@
setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer);
err = OK; // ignore error for now
}
+
+ OMX_INDEXTYPE index;
+ if (mOMXNode->getExtensionIndex(
+ "OMX.google.android.index.preregisterMetadataBuffers", &index) == OK) {
+ OMX_CONFIG_BOOLEANTYPE param;
+ InitOMXParams(¶m);
+ param.bEnabled = OMX_FALSE;
+ if (mOMXNode->getParameter(index, ¶m, sizeof(param)) == OK) {
+ if (param.bEnabled == OMX_TRUE) {
+ mFlags |= kFlagPreregisterMetadataBuffers;
+ }
+ }
+ }
}
if (haveNativeWindow) {
sp<ANativeWindow> nativeWindow =
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 7754de4..d56ec4f 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -158,6 +158,7 @@
kFlagIsSecure = 1,
kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
kFlagIsGrallocUsageProtected = 4,
+ kFlagPreregisterMetadataBuffers = 8,
};
enum {
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 6f48c5d..5418f10 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -105,7 +105,8 @@
ERROR_CAS_CARD_MUTE = CAS_ERROR_BASE - 15,
ERROR_CAS_CARD_INVALID = CAS_ERROR_BASE - 16,
ERROR_CAS_BLACKOUT = CAS_ERROR_BASE - 17,
- ERROR_CAS_LAST_USED_ERRORCODE = CAS_ERROR_BASE - 17,
+ ERROR_CAS_REBOOTING = CAS_ERROR_BASE - 18,
+ ERROR_CAS_LAST_USED_ERRORCODE = CAS_ERROR_BASE - 18,
ERROR_CAS_VENDOR_MAX = CAS_ERROR_BASE - 500,
ERROR_CAS_VENDOR_MIN = CAS_ERROR_BASE - 999,
diff --git a/media/libstagefright/tests/writer/README.md b/media/libstagefright/tests/writer/README.md
index 52db6f0..ae07917 100644
--- a/media/libstagefright/tests/writer/README.md
+++ b/media/libstagefright/tests/writer/README.md
@@ -19,12 +19,13 @@
adb push ${OUT}/data/nativetest/writerTest/writerTest /data/local/tmp/
-The resource file for the tests is taken from Codec2 VTS resource folder. Push these files into device for testing.
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/writerTestRes.zip).
+Download and extract the folder. Push all the files in this folder to /data/local/tmp/ on the device.
```
-adb push $ANDROID_BUILD_TOP/frameworks/av/media/codec2/hidl/1.0/vts/functional/res /sdcard/
+adb push writerTestRes /data/local/tmp/
```
usage: writerTest -P \<path_to_res_folder\>
```
-adb shell /data/local/tmp/writerTest -P /sdcard/res/
+adb shell /data/local/tmp/writerTest -P /data/local/tmp/
```
diff --git a/media/libstagefright/tests/writer/WriterTest.cpp b/media/libstagefright/tests/writer/WriterTest.cpp
index d68438c..409f141 100644
--- a/media/libstagefright/tests/writer/WriterTest.cpp
+++ b/media/libstagefright/tests/writer/WriterTest.cpp
@@ -29,9 +29,9 @@
#include <media/stagefright/AACWriter.h>
#include <media/stagefright/AMRWriter.h>
-#include <media/stagefright/OggWriter.h>
-#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MPEG2TSWriter.h>
+#include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/OggWriter.h>
#include <webm/WebmWriter.h>
#include "WriterTestEnvironment.h"
@@ -89,19 +89,36 @@
class WriterTest : public ::testing::TestWithParam<pair<string, int32_t>> {
public:
+ WriterTest() : mWriter(nullptr), mFileMeta(nullptr), mCurrentTrack(nullptr) {}
+
+ ~WriterTest() {
+ if (mWriter) {
+ mWriter.clear();
+ mWriter = nullptr;
+ }
+ if (mFileMeta) {
+ mFileMeta.clear();
+ mFileMeta = nullptr;
+ }
+ if (mCurrentTrack) {
+ mCurrentTrack.clear();
+ mCurrentTrack = nullptr;
+ }
+ }
+
virtual void SetUp() override {
mNumCsds = 0;
mInputFrameId = 0;
mWriterName = unknown_comp;
mDisableTest = false;
- std::map<std::string, standardWriters> mapWriter = {
+ static const std::map<std::string, standardWriters> mapWriter = {
{"ogg", OGG}, {"aac", AAC}, {"aac_adts", AAC_ADTS}, {"webm", WEBM},
{"mpeg4", MPEG4}, {"amrnb", AMR_NB}, {"amrwb", AMR_WB}, {"mpeg2Ts", MPEG2TS}};
// Find the component type
string writerFormat = GetParam().first;
if (mapWriter.find(writerFormat) != mapWriter.end()) {
- mWriterName = mapWriter[writerFormat];
+ mWriterName = mapWriter.at(writerFormat);
}
if (mWriterName == standardWriters::unknown_comp) {
cout << "[ WARN ] Test Skipped. No specific writer mentioned\n";
@@ -110,10 +127,8 @@
}
virtual void TearDown() override {
- mWriter.clear();
- mFileMeta.clear();
mBufferInfo.clear();
- if (mInputStream) mInputStream.close();
+ if (mInputStream.is_open()) mInputStream.close();
}
void getInputBufferInfo(string inputFileName, string inputInfo);
@@ -149,7 +164,7 @@
void WriterTest::getInputBufferInfo(string inputFileName, string inputInfo) {
std::ifstream eleInfo;
eleInfo.open(inputInfo.c_str());
- CHECK_EQ(eleInfo.is_open(), true);
+ ASSERT_EQ(eleInfo.is_open(), true);
int32_t bytesCount = 0;
uint32_t flags = 0;
int64_t timestamp = 0;
@@ -162,7 +177,7 @@
}
eleInfo.close();
mInputStream.open(inputFileName.c_str(), std::ifstream::binary);
- CHECK_EQ(mInputStream.is_open(), true);
+ ASSERT_EQ(mInputStream.is_open(), true);
}
int32_t WriterTest::createWriter(int32_t fd) {
@@ -258,14 +273,11 @@
string outputFile = OUTPUT_FILE_NAME;
int32_t fd =
open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
- if (fd < 0) return;
+ ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
// Creating writer within a test scope. Destructor should be called when the test ends
- int32_t status = createWriter(fd);
- if (status) {
- cout << "Failed to create writer for output format:" << GetParam().first << "\n";
- ASSERT_TRUE(false);
- }
+ ASSERT_EQ((status_t)OK, createWriter(fd))
+ << "Failed to create writer for output format:" << GetParam().first;
}
TEST_P(WriterTest, WriterTest) {
@@ -276,38 +288,32 @@
string outputFile = OUTPUT_FILE_NAME;
int32_t fd =
open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
- if (fd < 0) return;
+ ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
+
int32_t status = createWriter(fd);
- if (status) {
- cout << "Failed to create writer for output format:" << writerFormat << "\n";
- ASSERT_TRUE(false);
- }
+ ASSERT_EQ((status_t)OK, status) << "Failed to create writer for output format:" << writerFormat;
+
string inputFile = gEnv->getRes();
string inputInfo = gEnv->getRes();
configFormat param;
bool isAudio;
int32_t inputFileIdx = GetParam().second;
getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
- if (!inputFile.compare(gEnv->getRes())) {
- ALOGV("No input file specified");
- return;
- }
+ ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
getInputBufferInfo(inputFile, inputInfo);
status = addWriterSource(isAudio, param);
- if (status) {
- cout << "Failed to add source for " << writerFormat << "Writer \n";
- ASSERT_TRUE(false);
- }
- CHECK_EQ((status_t)OK, mWriter->start(mFileMeta.get()));
+ ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+
+ status = mWriter->start(mFileMeta.get());
+ ASSERT_EQ((status_t)OK, status);
status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
mBufferInfo.size());
+ ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
mCurrentTrack->stop();
- if (status) {
- cout << writerFormat << " writer failed \n";
- mWriter->stop();
- ASSERT_TRUE(false);
- }
- CHECK_EQ((status_t)OK, mWriter->stop());
+
+ status = mWriter->stop();
+ ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
close(fd);
}
@@ -319,59 +325,125 @@
string outputFile = OUTPUT_FILE_NAME;
int32_t fd =
open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
- if (fd < 0) return;
+ ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
+
int32_t status = createWriter(fd);
- if (status) {
- cout << "Failed to create writer for output format:" << writerFormat << "\n";
- ASSERT_TRUE(false);
- }
+ ASSERT_EQ((status_t)OK, status) << "Failed to create writer for output format:" << writerFormat;
+
string inputFile = gEnv->getRes();
string inputInfo = gEnv->getRes();
configFormat param;
bool isAudio;
int32_t inputFileIdx = GetParam().second;
getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
- if (!inputFile.compare(gEnv->getRes())) {
- ALOGV("No input file specified");
- return;
- }
+ ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
getInputBufferInfo(inputFile, inputInfo);
status = addWriterSource(isAudio, param);
- if (status) {
- cout << "Failed to add source for " << writerFormat << "Writer \n";
- ASSERT_TRUE(false);
- }
- CHECK_EQ((status_t)OK, mWriter->start(mFileMeta.get()));
+ ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+
+ status = mWriter->start(mFileMeta.get());
+ ASSERT_EQ((status_t)OK, status);
status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
mBufferInfo.size() / 4);
- if (status) {
- cout << writerFormat << " writer failed \n";
- mCurrentTrack->stop();
- mWriter->stop();
- ASSERT_TRUE(false);
- }
+ ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
bool isPaused = false;
if ((mWriterName != standardWriters::MPEG2TS) && (mWriterName != standardWriters::MPEG4)) {
- CHECK_EQ((status_t)OK, mWriter->pause());
+ status = mWriter->pause();
+ ASSERT_EQ((status_t)OK, status);
isPaused = true;
}
// In the pause state, writers shouldn't write anything. Testing the writers for the same
int32_t numFramesPaused = mBufferInfo.size() / 4;
- status |= sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+ status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
mInputFrameId, numFramesPaused, isPaused);
+ ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
if (isPaused) {
- CHECK_EQ((status_t)OK, mWriter->start(mFileMeta.get()));
+ status = mWriter->start(mFileMeta.get());
+ ASSERT_EQ((status_t)OK, status);
}
- status |= sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+ status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
mInputFrameId, mBufferInfo.size());
+ ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
mCurrentTrack->stop();
- if (status) {
- cout << writerFormat << " writer failed \n";
- mWriter->stop();
- ASSERT_TRUE(false);
+
+ status = mWriter->stop();
+ ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
+ close(fd);
+}
+
+TEST_P(WriterTest, MultiStartStopPauseTest) {
+ // TODO: (b/144821804)
+ // Enable the test for MPE2TS writer
+ if (mDisableTest || mWriterName == standardWriters::MPEG2TS) return;
+ ALOGV("Test writers for multiple start, stop and pause calls");
+
+ string outputFile = OUTPUT_FILE_NAME;
+ int32_t fd =
+ open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+ ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
+
+ string writerFormat = GetParam().first;
+ int32_t status = createWriter(fd);
+ ASSERT_EQ(status, (status_t)OK) << "Failed to create writer for output format:" << writerFormat;
+
+ string inputFile = gEnv->getRes();
+ string inputInfo = gEnv->getRes();
+ configFormat param;
+ bool isAudio;
+ int32_t inputFileIdx = GetParam().second;
+ getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
+ ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
+ getInputBufferInfo(inputFile, inputInfo);
+ status = addWriterSource(isAudio, param);
+ ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+
+ // first start should succeed.
+ status = mWriter->start(mFileMeta.get());
+ ASSERT_EQ((status_t)OK, status) << "Could not start the writer";
+
+ // Multiple start() may/may not succeed.
+ // Writers are expected to not crash on multiple start() calls.
+ for (int32_t count = 0; count < kMaxCount; count++) {
+ mWriter->start(mFileMeta.get());
}
- CHECK_EQ((status_t)OK, mWriter->stop());
+
+ status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
+ mBufferInfo.size() / 4);
+ ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
+ for (int32_t count = 0; count < kMaxCount; count++) {
+ mWriter->pause();
+ mWriter->start(mFileMeta.get());
+ }
+
+ mWriter->pause();
+ int32_t numFramesPaused = mBufferInfo.size() / 4;
+ status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+ mInputFrameId, numFramesPaused, true);
+ ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
+ for (int32_t count = 0; count < kMaxCount; count++) {
+ mWriter->start(mFileMeta.get());
+ }
+
+ status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+ mInputFrameId, mBufferInfo.size());
+ ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
+ mCurrentTrack->stop();
+
+ // first stop should succeed.
+ status = mWriter->stop();
+ ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
+ // Multiple stop() may/may not succeed.
+ // Writers are expected to not crash on multiple stop() calls.
+ for (int32_t count = 0; count < kMaxCount; count++) {
+ mWriter->stop();
+ }
close(fd);
}
diff --git a/media/libstagefright/tests/writer/WriterTestEnvironment.h b/media/libstagefright/tests/writer/WriterTestEnvironment.h
index 34c2baa..99e686f 100644
--- a/media/libstagefright/tests/writer/WriterTestEnvironment.h
+++ b/media/libstagefright/tests/writer/WriterTestEnvironment.h
@@ -25,7 +25,7 @@
class WriterTestEnvironment : public ::testing::Environment {
public:
- WriterTestEnvironment() : res("/sdcard/media/") {}
+ WriterTestEnvironment() : res("/data/local/tmp/") {}
// Parses the command line arguments
int initFromOptions(int argc, char **argv);
diff --git a/media/libstagefright/tests/writer/WriterUtility.cpp b/media/libstagefright/tests/writer/WriterUtility.cpp
index 2ba90a0..f24ccb6 100644
--- a/media/libstagefright/tests/writer/WriterUtility.cpp
+++ b/media/libstagefright/tests/writer/WriterUtility.cpp
@@ -26,7 +26,7 @@
int32_t &inputFrameId, sp<MediaAdapter> ¤tTrack, int32_t offset,
int32_t range, bool isPaused) {
while (1) {
- if (inputFrameId == (int)bufferInfo.size() || inputFrameId >= (offset + range)) break;
+ if (inputFrameId >= (int)bufferInfo.size() || inputFrameId >= (offset + range)) break;
int32_t size = bufferInfo[inputFrameId].size;
char *data = (char *)malloc(size);
if (!data) {
diff --git a/media/libstagefright/tests/writer/WriterUtility.h b/media/libstagefright/tests/writer/WriterUtility.h
index d402798..cdd6246 100644
--- a/media/libstagefright/tests/writer/WriterUtility.h
+++ b/media/libstagefright/tests/writer/WriterUtility.h
@@ -33,6 +33,7 @@
#define CODEC_CONFIG_FLAG 32
constexpr uint32_t kMaxCSDStrlen = 16;
+constexpr uint32_t kMaxCount = 20;
struct BufferInfo {
int32_t size;
diff --git a/media/mediaserver/manifest_media_c2_software.xml b/media/mediaserver/manifest_media_c2_software.xml
index 5196336..f23ed44 100644
--- a/media/mediaserver/manifest_media_c2_software.xml
+++ b/media/mediaserver/manifest_media_c2_software.xml
@@ -2,7 +2,7 @@
<hal>
<name>android.hardware.media.c2</name>
<transport>hwbinder</transport>
- <version>1.0</version>
+ <version>1.1</version>
<interface>
<name>IComponentStore</name>
<instance>software</instance>
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 4376802..1b2f7c7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -200,6 +200,7 @@
{
static constexpr const char *speakerDrcEnabled = "speaker_drc_enabled";
static constexpr const char *callScreenModeSupported= "call_screen_mode_supported";
+ static constexpr const char *engineLibrarySuffix = "engine_library";
};
static status_t deserialize(const xmlNode *root, AudioPolicyConfig *config);
@@ -692,6 +693,11 @@
convertTo<std::string, bool>(attr, value)) {
config->setCallScreenModeSupported(value);
}
+ std::string engineLibrarySuffix = getXmlAttribute(cur, Attributes::engineLibrarySuffix);
+ if (!engineLibrarySuffix.empty()) {
+ config->setEngineLibraryNameSuffix(engineLibrarySuffix);
+ }
+ return NO_ERROR;
}
}
return NO_ERROR;
diff --git a/services/audiopolicy/config/Android.bp b/services/audiopolicy/config/Android.bp
index 4b5e788..f4610bb 100644
--- a/services/audiopolicy/config/Android.bp
+++ b/services/audiopolicy/config/Android.bp
@@ -92,6 +92,10 @@
srcs: ["audio_policy_configuration_generic.xml"],
}
filegroup {
+ name: "audio_policy_configuration_generic_configurable",
+ srcs: ["audio_policy_configuration_generic_configurable.xml"],
+}
+filegroup {
name: "usb_audio_policy_configuration",
srcs: ["usb_audio_policy_configuration.xml"],
}
diff --git a/services/audiopolicy/config/audio_policy_configuration_generic_configurable.xml b/services/audiopolicy/config/audio_policy_configuration_generic_configurable.xml
new file mode 100644
index 0000000..fbe4f7f
--- /dev/null
+++ b/services/audiopolicy/config/audio_policy_configuration_generic_configurable.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
+
+ <!-- Global configuration Decalaration -->
+ <globalConfiguration speaker_drc_enabled="false" engine_library="configurable"/>
+
+ <modules>
+ <!-- Primary Audio HAL -->
+ <xi:include href="primary_audio_policy_configuration.xml"/>
+
+ <!-- Remote Submix Audio HAL -->
+ <xi:include href="r_submix_audio_policy_configuration.xml"/>
+
+ </modules>
+ <!-- End of Modules section -->
+
+ <!-- Volume section:
+ IMPORTANT NOTE: Volume tables have been moved to engine configuration.
+ Keep it here for legacy.
+ Engine will fallback on these files if none are provided by engine.
+ -->
+
+ <xi:include href="audio_policy_volumes.xml"/>
+ <xi:include href="default_volume_tables.xml"/>
+
+ <!-- End of Volume section -->
+
+ <!-- Surround Sound configuration -->
+
+ <xi:include href="surround_sound_configuration_5_0.xml"/>
+
+ <!-- End of Surround Sound configuration -->
+
+</audioPolicyConfiguration>
diff --git a/services/audiopolicy/engine/config/Android.bp b/services/audiopolicy/engine/config/Android.bp
index 885b5fa..ff840f9 100644
--- a/services/audiopolicy/engine/config/Android.bp
+++ b/services/audiopolicy/engine/config/Android.bp
@@ -1,4 +1,4 @@
-cc_library_static {
+cc_library {
name: "libaudiopolicyengine_config",
export_include_dirs: ["include"],
include_dirs: [
@@ -14,17 +14,14 @@
],
shared_libs: [
"libmedia_helper",
- "libandroidicu",
"libxml2",
"libutils",
"liblog",
"libcutils",
],
- static_libs: [
- "libaudiopolicycomponents",
- ],
header_libs: [
"libaudio_system_headers",
- "libaudiopolicycommon",
+ "libmedia_headers",
+ "libaudioclient_headers",
],
}
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index d47fbd2..7f8cdd9 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -18,7 +18,6 @@
//#define LOG_NDEBUG 0
#include "EngineConfig.h"
-#include <policy.h>
#include <cutils/properties.h>
#include <media/TypeConverter.h>
#include <media/convert.h>
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 752ba92..7e5c5e3 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -80,8 +80,9 @@
status_t Engine::initCheck()
{
- if (mPolicyParameterMgr == nullptr || mPolicyParameterMgr->start() != NO_ERROR) {
- ALOGE("%s: could not start Policy PFW", __FUNCTION__);
+ std::string error;
+ if (mPolicyParameterMgr == nullptr || mPolicyParameterMgr->start(error) != NO_ERROR) {
+ ALOGE("%s: could not start Policy PFW: %s", __FUNCTION__, error.c_str());
return NO_INIT;
}
return EngineBase::initCheck();
@@ -162,21 +163,21 @@
return mPolicyParameterMgr->getForceUse(usage);
}
-status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> device,
audio_policy_dev_state_t state)
{
- mPolicyParameterMgr->setDeviceConnectionState(devDesc, state);
-
- if (audio_is_output_device(devDesc->type())) {
+ mPolicyParameterMgr->setDeviceConnectionState(
+ device->type(), device->address().c_str(), state);
+ if (audio_is_output_device(device->type())) {
// FIXME: Use DeviceTypeSet when the interface is ready
return mPolicyParameterMgr->setAvailableOutputDevices(
deviceTypesToBitMask(getApmObserver()->getAvailableOutputDevices().types()));
- } else if (audio_is_input_device(devDesc->type())) {
+ } else if (audio_is_input_device(device->type())) {
// FIXME: Use DeviceTypeSet when the interface is ready
return mPolicyParameterMgr->setAvailableInputDevices(
deviceTypesToBitMask(getApmObserver()->getAvailableInputDevices().types()));
}
- return EngineBase::setDeviceConnectionState(devDesc, state);
+ return EngineBase::setDeviceConnectionState(device, state);
}
status_t Engine::loadAudioPolicyEngineConfig()
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.bp b/services/audiopolicy/engineconfigurable/wrapper/Android.bp
index 6f59487..301ecc0 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/Android.bp
+++ b/services/audiopolicy/engineconfigurable/wrapper/Android.bp
@@ -11,7 +11,6 @@
"libbase_headers",
"libaudiopolicycommon",
],
- static_libs: ["libaudiopolicycomponents"],
shared_libs: [
"liblog",
"libutils",
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index 465a6f9..1b3b9a0 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -92,7 +92,8 @@
template <>
struct ParameterManagerWrapper::parameterManagerElementSupported<ISelectionCriterionTypeInterface> {};
-ParameterManagerWrapper::ParameterManagerWrapper()
+ParameterManagerWrapper::ParameterManagerWrapper(bool enableSchemaVerification,
+ const std::string &schemaUri)
: mPfwConnectorLogger(new ParameterMgrPlatformConnectorLogger)
{
// Connector
@@ -104,6 +105,15 @@
// Logger
mPfwConnector->setLogger(mPfwConnectorLogger);
+
+ // Schema validation
+ std::string error;
+ bool ret = mPfwConnector->setValidateSchemasOnStart(enableSchemaVerification, error);
+ ALOGE_IF(!ret, "Failed to activate schema validation: %s", error.c_str());
+ if (enableSchemaVerification && ret && !schemaUri.empty()) {
+ ALOGE("Schema verification activated with schema URI: %s", schemaUri.c_str());
+ mPfwConnector->setSchemaUri(schemaUri);
+ }
}
status_t ParameterManagerWrapper::addCriterion(const std::string &name, bool isInclusive,
@@ -145,11 +155,10 @@
delete mPfwConnector;
}
-status_t ParameterManagerWrapper::start()
+status_t ParameterManagerWrapper::start(std::string &error)
{
ALOGD("%s: in", __FUNCTION__);
/// Start PFW
- std::string error;
if (!mPfwConnector->start(error)) {
ALOGE("%s: Policy PFW start error: %s", __FUNCTION__, error.c_str());
return NO_INIT;
@@ -253,13 +262,13 @@
return interface->getLiteralValue(valueToCheck, literalValue);
}
-status_t ParameterManagerWrapper::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
- audio_policy_dev_state_t state)
+status_t ParameterManagerWrapper::setDeviceConnectionState(
+ audio_devices_t type, const std::string address, audio_policy_dev_state_t state)
{
- std::string criterionName = audio_is_output_device(devDesc->type()) ?
+ std::string criterionName = audio_is_output_device(type) ?
gOutputDeviceAddressCriterionName : gInputDeviceAddressCriterionName;
- ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->address().c_str(),
+ ALOGV("%s: device with address %s %s", __FUNCTION__, address.c_str(),
state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE? "disconnected" : "connected");
ISelectionCriterionInterface *criterion =
getElement<ISelectionCriterionInterface>(criterionName, mPolicyCriteria);
@@ -271,8 +280,8 @@
auto criterionType = criterion->getCriterionType();
int deviceAddressId;
- if (not criterionType->getNumericalValue(devDesc->address().c_str(), deviceAddressId)) {
- ALOGW("%s: unknown device address reported (%s)", __FUNCTION__, devDesc->address().c_str());
+ if (not criterionType->getNumericalValue(address.c_str(), deviceAddressId)) {
+ ALOGW("%s: unknown device address reported (%s)", __FUNCTION__, address.c_str());
return BAD_TYPE;
}
int currentValueMask = criterion->getCriterionState();
diff --git a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
index 8443008..62b129a 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
@@ -16,9 +16,6 @@
#pragma once
-#include <PolicyAudioPort.h>
-#include <HwModule.h>
-#include <DeviceDescriptor.h>
#include <system/audio.h>
#include <system/audio_policy.h>
#include <utils/Errors.h>
@@ -47,16 +44,18 @@
using Criteria = std::map<std::string, ISelectionCriterionInterface *>;
public:
- ParameterManagerWrapper();
+ ParameterManagerWrapper(bool enableSchemaVerification = false,
+ const std::string &schemaUri = {});
~ParameterManagerWrapper();
/**
* Starts the platform state service.
* It starts the parameter framework policy instance.
+ * @param[out] contains human readable error if starts failed
*
- * @return NO_ERROR if success, error code otherwise.
+ * @return NO_ERROR if success, error code otherwise, and error is set to human readable string.
*/
- status_t start();
+ status_t start(std::string &error);
/**
* The following API wrap policy action to criteria
@@ -117,7 +116,15 @@
*/
status_t setAvailableOutputDevices(audio_devices_t outputDevices);
- status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+ /**
+ * @brief setDeviceConnectionState propagates a state event on a given device(s)
+ * @param type bit mask of the device whose state has changed
+ * @param address of the device whose state has changed
+ * @param state new state of the given device
+ * @return NO_ERROR if new state corretly propagated to Engine Parameter-Framework, error
+ * code otherwise.
+ */
+ status_t setDeviceConnectionState(audio_devices_t type, const std::string address,
audio_policy_dev_state_t state);
/**
diff --git a/services/mediacodec/registrant/CodecServiceRegistrant.cpp b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
index 706ebee..58db801e 100644
--- a/services/mediacodec/registrant/CodecServiceRegistrant.cpp
+++ b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
@@ -20,11 +20,11 @@
#include <android-base/logging.h>
#include <C2PlatformSupport.h>
-#include <codec2/hidl/1.0/ComponentStore.h>
+#include <codec2/hidl/1.1/ComponentStore.h>
#include <media/CodecServiceRegistrant.h>
extern "C" void RegisterCodecServices() {
- using namespace ::android::hardware::media::c2::V1_0;
+ using namespace ::android::hardware::media::c2::V1_1;
LOG(INFO) << "Creating software Codec2 service...";
android::sp<IComponentStore> store =
new utils::ComponentStore(