Merge "Add audio eraser effect filter in libaudiohal" into main
diff --git a/apex/Android.bp b/apex/Android.bp
index b0d7c02..356bf03 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -173,6 +173,7 @@
"mediaswcodec",
],
native_shared_libs: [
+ "libapexcodecs",
"libcodec2_hidl@1.0",
"libcodec2_hidl@1.1",
"libcodec2_hidl@1.2",
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index a03ccf5..78b793d 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -175,16 +175,10 @@
flag {
namespace: "camera_platform"
- name: "use_context_attribution_source"
- description: "Use the context-provided AttributionSource when checking for client permissions"
+ name: "data_delivery_permission_checks"
+ description: "Pass the full AttributionSource chain to PermissionChecker for data delivery"
bug: "190657833"
-}
-
-flag {
- namespace: "camera_platform"
- name: "check_full_attribution_source_chain"
- description: "Pass the full AttributionSource chain to PermissionChecker"
- bug: "190657833"
+ is_fixed_read_only: true
}
flag {
@@ -218,3 +212,20 @@
description: "Indicates when to activate Night Mode Camera Extension"
bug: "335902696"
}
+
+flag {
+ namespace: "camera_platform"
+ name: "zoom_method"
+ is_exported: true
+ description: "Gives apps explicit control on reflects zoom via ZOOM_RATIO capture result"
+ bug: "298899993"
+}
+
+flag {
+ namespace: "camera_platform"
+ is_exported: true
+ name: "ae_priority"
+ description: "Add AE priority modes"
+ bug: "359944765"
+}
+
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index fef6443..32e2f3d 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -562,6 +562,8 @@
case ACAMERA_CONTROL_ZOOM_RATIO:
case ACAMERA_CONTROL_SETTINGS_OVERRIDE:
case ACAMERA_CONTROL_AUTOFRAMING:
+ case ACAMERA_CONTROL_ZOOM_METHOD:
+ case ACAMERA_CONTROL_AE_PRIORITY_MODE:
case ACAMERA_EDGE_MODE:
case ACAMERA_FLASH_MODE:
case ACAMERA_FLASH_STRENGTH_LEVEL:
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 6c88288..b792de0 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -563,7 +563,9 @@
* application's selected exposure time, sensor sensitivity,
* and frame duration (ACAMERA_SENSOR_EXPOSURE_TIME,
* ACAMERA_SENSOR_SENSITIVITY, and
- * ACAMERA_SENSOR_FRAME_DURATION). If one of the FLASH modes
+ * ACAMERA_SENSOR_FRAME_DURATION). If ACAMERA_CONTROL_AE_PRIORITY_MODE is
+ * enabled, the relevant priority CaptureRequest settings will not be overridden.
+ * See ACAMERA_CONTROL_AE_PRIORITY_MODE for more details. If one of the FLASH modes
* is selected, the camera device's flash unit controls are
* also overridden.</p>
* <p>The FLASH modes are only available if the camera device
@@ -583,6 +585,7 @@
* different ACAMERA_FLASH_STRENGTH_LEVEL.</p>
*
* @see ACAMERA_CONTROL_AE_MODE
+ * @see ACAMERA_CONTROL_AE_PRIORITY_MODE
* @see ACAMERA_CONTROL_MODE
* @see ACAMERA_FLASH_INFO_AVAILABLE
* @see ACAMERA_FLASH_MODE
@@ -2401,6 +2404,95 @@
*/
ACAMERA_CONTROL_LOW_LIGHT_BOOST_STATE = // byte (acamera_metadata_enum_android_control_low_light_boost_state_t)
ACAMERA_CONTROL_START + 59,
+ /**
+ * <p>Whether the application uses ACAMERA_SCALER_CROP_REGION or ACAMERA_CONTROL_ZOOM_RATIO
+ * to control zoom levels.</p>
+ *
+ * @see ACAMERA_CONTROL_ZOOM_RATIO
+ * @see ACAMERA_SCALER_CROP_REGION
+ *
+ * <p>Type: byte (acamera_metadata_enum_android_control_zoom_method_t)</p>
+ *
+ * <p>This tag may appear in:
+ * <ul>
+ * <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+ * <li>ACaptureRequest</li>
+ * </ul></p>
+ *
+ * <p>If set to AUTO, the camera device detects which capture request key the application uses
+ * to do zoom, ACAMERA_SCALER_CROP_REGION or ACAMERA_CONTROL_ZOOM_RATIO. If
+ * the application doesn't set android.scaler.zoomRatio or sets it to 1.0 in the capture
+ * request, the effective zoom level is reflected in ACAMERA_SCALER_CROP_REGION in capture
+ * results. If ACAMERA_CONTROL_ZOOM_RATIO is set to values other than 1.0, the effective
+ * zoom level is reflected in ACAMERA_CONTROL_ZOOM_RATIO. AUTO is the default value
+ * for this control, and also the behavior of the OS before Android version
+ * <a href="https://developer.android.com/reference/android/os/Build.VERSION_CODES.html#BAKLAVA">BAKLAVA</a>.</p>
+ * <p>If set to ZOOM_RATIO, the application explicitly specifies zoom level be controlled
+ * by ACAMERA_CONTROL_ZOOM_RATIO, and the effective zoom level is reflected in
+ * ACAMERA_CONTROL_ZOOM_RATIO in capture results. This addresses an ambiguity with AUTO,
+ * with which the camera device cannot know if the application is using cropRegion or
+ * zoomRatio at 1.0x.</p>
+ *
+ * @see ACAMERA_CONTROL_ZOOM_RATIO
+ * @see ACAMERA_SCALER_CROP_REGION
+ */
+ ACAMERA_CONTROL_ZOOM_METHOD = // byte (acamera_metadata_enum_android_control_zoom_method_t)
+ ACAMERA_CONTROL_START + 60,
+ /**
+ * <p>Turn on AE priority mode.</p>
+ *
+ * <p>Type: byte (acamera_metadata_enum_android_control_ae_priority_mode_t)</p>
+ *
+ * <p>This tag may appear in:
+ * <ul>
+ * <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+ * <li>ACaptureRequest</li>
+ * </ul></p>
+ *
+ * <p>This control is only effective if ACAMERA_CONTROL_MODE is
+ * AUTO and ACAMERA_CONTROL_AE_MODE is set to one of its
+ * ON modes, with the exception of ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY.</p>
+ * <p>When a priority mode is enabled, the camera device's
+ * auto-exposure routine will maintain the application's
+ * selected parameters relevant to the priority mode while overriding
+ * the remaining exposure parameters
+ * (ACAMERA_SENSOR_EXPOSURE_TIME, ACAMERA_SENSOR_SENSITIVITY, and
+ * ACAMERA_SENSOR_FRAME_DURATION). For example, if
+ * SENSOR_SENSITIVITY_PRIORITY mode is enabled, the camera device will
+ * maintain the application-selected ACAMERA_SENSOR_SENSITIVITY
+ * while adjusting ACAMERA_SENSOR_EXPOSURE_TIME
+ * and ACAMERA_SENSOR_FRAME_DURATION. The overridden fields for a
+ * given capture will be available in its CaptureResult.</p>
+ *
+ * @see ACAMERA_CONTROL_AE_MODE
+ * @see ACAMERA_CONTROL_MODE
+ * @see ACAMERA_SENSOR_EXPOSURE_TIME
+ * @see ACAMERA_SENSOR_FRAME_DURATION
+ * @see ACAMERA_SENSOR_SENSITIVITY
+ */
+ ACAMERA_CONTROL_AE_PRIORITY_MODE = // byte (acamera_metadata_enum_android_control_ae_priority_mode_t)
+ ACAMERA_CONTROL_START + 61,
+ /**
+ * <p>List of auto-exposure priority modes for ACAMERA_CONTROL_AE_PRIORITY_MODE
+ * that are supported by this camera device.</p>
+ *
+ * @see ACAMERA_CONTROL_AE_PRIORITY_MODE
+ *
+ * <p>Type: byte[n]</p>
+ *
+ * <p>This tag may appear in:
+ * <ul>
+ * <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+ * </ul></p>
+ *
+ * <p>This entry lists the valid modes for
+ * ACAMERA_CONTROL_AE_PRIORITY_MODE for this camera device.
+ * If no AE priority modes are available for a device, this will only list OFF.</p>
+ *
+ * @see ACAMERA_CONTROL_AE_PRIORITY_MODE
+ */
+ ACAMERA_CONTROL_AE_AVAILABLE_PRIORITY_MODES = // byte[n]
+ ACAMERA_CONTROL_START + 62,
ACAMERA_CONTROL_END,
/**
@@ -4887,9 +4979,12 @@
* duration exposed to the nearest possible value (rather than expose longer).
* The final exposure time used will be available in the output capture result.</p>
* <p>This control is only effective if ACAMERA_CONTROL_AE_MODE or ACAMERA_CONTROL_MODE is set to
- * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+ * OFF; otherwise the auto-exposure algorithm will override this value. However, in the
+ * case that ACAMERA_CONTROL_AE_PRIORITY_MODE is set to SENSOR_EXPOSURE_TIME_PRIORITY, this
+ * control will be effective and not controlled by the auto-exposure algorithm.</p>
*
* @see ACAMERA_CONTROL_AE_MODE
+ * @see ACAMERA_CONTROL_AE_PRIORITY_MODE
* @see ACAMERA_CONTROL_MODE
*/
ACAMERA_SENSOR_EXPOSURE_TIME = // int64
@@ -4998,7 +5093,9 @@
* value. The final sensitivity used will be available in the
* output capture result.</p>
* <p>This control is only effective if ACAMERA_CONTROL_AE_MODE or ACAMERA_CONTROL_MODE is set to
- * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+ * OFF; otherwise the auto-exposure algorithm will override this value. However, in the
+ * case that ACAMERA_CONTROL_AE_PRIORITY_MODE is set to SENSOR_SENSITIVITY_PRIORITY, this
+ * control will be effective and not controlled by the auto-exposure algorithm.</p>
* <p>Note that for devices supporting postRawSensitivityBoost, the total sensitivity applied
* to the final processed image is the combination of ACAMERA_SENSOR_SENSITIVITY and
* ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST. In case the application uses the sensor
@@ -5007,6 +5104,7 @@
* set postRawSensitivityBoost.</p>
*
* @see ACAMERA_CONTROL_AE_MODE
+ * @see ACAMERA_CONTROL_AE_PRIORITY_MODE
* @see ACAMERA_CONTROL_MODE
* @see ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST
* @see ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE
@@ -9652,6 +9750,42 @@
} acamera_metadata_enum_android_control_low_light_boost_state_t;
+// ACAMERA_CONTROL_AE_PRIORITY_MODE
+typedef enum acamera_metadata_enum_acamera_control_ae_priority_mode {
+ /**
+ * <p>Disable AE priority mode. This is the default value.</p>
+ */
+ ACAMERA_CONTROL_AE_PRIORITY_MODE_OFF = 0,
+
+ /**
+ * <p>The camera device's auto-exposure routine is active and
+ * prioritizes the application-selected ISO (ACAMERA_SENSOR_SENSITIVITY).</p>
+ * <p>The application has control over ACAMERA_SENSOR_SENSITIVITY while
+ * the application's values for ACAMERA_SENSOR_EXPOSURE_TIME and
+ * ACAMERA_SENSOR_FRAME_DURATION are ignored.</p>
+ *
+ * @see ACAMERA_SENSOR_EXPOSURE_TIME
+ * @see ACAMERA_SENSOR_FRAME_DURATION
+ * @see ACAMERA_SENSOR_SENSITIVITY
+ */
+ ACAMERA_CONTROL_AE_PRIORITY_MODE_SENSOR_SENSITIVITY_PRIORITY = 1,
+
+ /**
+ * <p>The camera device's auto-exposure routine is active and
+ * prioritizes the application-selected exposure time
+ * (ACAMERA_SENSOR_EXPOSURE_TIME).</p>
+ * <p>The application has control over ACAMERA_SENSOR_EXPOSURE_TIME while
+ * the application's values for ACAMERA_SENSOR_SENSITIVITY and
+ * ACAMERA_SENSOR_FRAME_DURATION are ignored.</p>
+ *
+ * @see ACAMERA_SENSOR_EXPOSURE_TIME
+ * @see ACAMERA_SENSOR_FRAME_DURATION
+ * @see ACAMERA_SENSOR_SENSITIVITY
+ */
+ ACAMERA_CONTROL_AE_PRIORITY_MODE_SENSOR_EXPOSURE_TIME_PRIORITY = 2,
+
+} acamera_metadata_enum_android_control_ae_priority_mode_t;
+
// ACAMERA_EDGE_MODE
diff --git a/media/aconfig/codec_fwk.aconfig b/media/aconfig/codec_fwk.aconfig
index ee697ee..c820a2c 100644
--- a/media/aconfig/codec_fwk.aconfig
+++ b/media/aconfig/codec_fwk.aconfig
@@ -21,6 +21,13 @@
}
flag {
+ name: "codec_availability"
+ namespace: "codec_fwk"
+ description: "Feature flag for codec availability HAL API support"
+ bug: "363282971"
+}
+
+flag {
name: "codec_buffer_state_cleanup"
namespace: "codec_fwk"
description: "Bugfix flag for more buffer state cleanup in MediaCodec"
diff --git a/media/audio/aconfig/audio_framework.aconfig b/media/audio/aconfig/audio_framework.aconfig
index 7ee1360..ae7eb36 100644
--- a/media/audio/aconfig/audio_framework.aconfig
+++ b/media/audio/aconfig/audio_framework.aconfig
@@ -199,6 +199,13 @@
}
flag {
+ name: "spatial_audio_settings_versioning"
+ namespace: "media_audio"
+ description: "introduce versioning of spatial audio settings"
+ bug: "377977731"
+}
+
+flag {
name: "spatializer_capabilities"
namespace: "media_audio"
description: "spatializer reports effective channel masks"
diff --git a/media/codec2/components/apv/C2SoftApvDec.cpp b/media/codec2/components/apv/C2SoftApvDec.cpp
index 0617d06..0064cec 100644
--- a/media/codec2/components/apv/C2SoftApvDec.cpp
+++ b/media/codec2/components/apv/C2SoftApvDec.cpp
@@ -493,10 +493,13 @@
mOutBufferFlush(nullptr),
mIvColorformat(IV_YUV_420P),
mOutputDelay(kDefaultOutputDelay),
+ mHeaderDecoded(false),
+ mOutIndex(0u),
+ mHalPixelFormat(HAL_PIXEL_FORMAT_YV12),
mWidth(320),
mHeight(240),
- mHeaderDecoded(false),
- mOutIndex(0u) {
+ mSignalledOutputEos(false),
+ mSignalledError(false) {
oapvdHandle = NULL;
oapvmHandle = NULL;
outputCsp = OUTPUT_CSP_NATIVE;
diff --git a/media/codec2/components/apv/C2SoftApvDec.h b/media/codec2/components/apv/C2SoftApvDec.h
index 22bfcff..f5beb8f 100644
--- a/media/codec2/components/apv/C2SoftApvDec.h
+++ b/media/codec2/components/apv/C2SoftApvDec.h
@@ -66,7 +66,7 @@
namespace android {
-struct C2SoftApvDec : public SimpleC2Component {
+struct C2SoftApvDec final : public SimpleC2Component {
class IntfImpl;
C2SoftApvDec(const char* name, c2_node_id_t id, const std::shared_ptr<IntfImpl>& intfImpl);
diff --git a/media/codec2/components/apv/C2SoftApvEnc.cpp b/media/codec2/components/apv/C2SoftApvEnc.cpp
index 999c08d..a61cfd6 100644
--- a/media/codec2/components/apv/C2SoftApvEnc.cpp
+++ b/media/codec2/components/apv/C2SoftApvEnc.cpp
@@ -505,6 +505,8 @@
mReceivedFrames = 0;
mReceivedFirstFrame = false;
mColorFormat = OAPV_CF_PLANAR2;
+ memset(&mInputFrames, 0, sizeof(mInputFrames));
+ memset(&mReconFrames, 0, sizeof(mReconFrames));
return C2_OK;
}
@@ -512,6 +514,7 @@
for (int32_t i = 0; i < MAX_NUM_FRMS; i++) {
if (mInputFrames.frm[i].imgb != nullptr) {
imgb_release(mInputFrames.frm[i].imgb);
+ mInputFrames.frm[i].imgb = nullptr;
}
}
diff --git a/media/codec2/components/apv/C2SoftApvEnc.h b/media/codec2/components/apv/C2SoftApvEnc.h
index 445b042..441c663 100644
--- a/media/codec2/components/apv/C2SoftApvEnc.h
+++ b/media/codec2/components/apv/C2SoftApvEnc.h
@@ -31,11 +31,11 @@
#define APV_QP_MIN 1
#define APV_QP_MAX 51
-struct C2SoftApvEnc : public SimpleC2Component {
+struct C2SoftApvEnc final : public SimpleC2Component {
class IntfImpl;
C2SoftApvEnc(const char* name, c2_node_id_t id, const std::shared_ptr<IntfImpl>& intfImpl);
- ~C2SoftApvEnc();
+ virtual ~C2SoftApvEnc();
// From SimpleC2Component
c2_status_t onInit() override;
diff --git a/media/libaaudio/fuzzer/libaaudio_fuzzer.cpp b/media/libaaudio/fuzzer/libaaudio_fuzzer.cpp
index 1b06ea7..c3b43ab 100644
--- a/media/libaaudio/fuzzer/libaaudio_fuzzer.cpp
+++ b/media/libaaudio/fuzzer/libaaudio_fuzzer.cpp
@@ -17,6 +17,7 @@
#include "aaudio/AAudio.h"
#include "aaudio/AAudioTesting.h"
+#include "system/aaudio/AAudio.h"
#include <fuzzer/FuzzedDataProvider.h>
#include <functional>
@@ -183,6 +184,12 @@
fdp.PickValueInArray({AAUDIO_UNSPECIFIED, fdp.ConsumeIntegral<int32_t>()});
AAudioStreamBuilder_setFramesPerDataCallback(mAaudioBuilder, framesPerDataCallback);
+ const size_t tagsNumBytes = fdp.ConsumeIntegralInRange<size_t>(
+ 0, AAUDIO_ATTRIBUTES_TAGS_MAX_SIZE + 10);
+ AAudioStreamBuilder_setTags(mAaudioBuilder,
+ (tagsNumBytes == 0 ? nullptr
+ : fdp.ConsumeBytesAsString(tagsNumBytes).c_str()));
+
aaudio_policy_t policy =
fdp.PickValueInArray({fdp.PickValueInArray(kPolicies), fdp.ConsumeIntegral<int32_t>()});
AAudio_setMMapPolicy(policy);
@@ -193,6 +200,7 @@
int32_t maxFrames = 0;
int32_t count = 0;
aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
+ char tags[AAUDIO_ATTRIBUTES_TAGS_MAX_SIZE + 1];
invokeAAudioSetAPIs(fdp);
@@ -312,6 +320,9 @@
(void)AAudioStream_getBufferSizeInFrames(mAaudioStream);
},
[&]() {
+ (void)AAudioStream_getTags(mAaudioStream, tags);
+ },
+ [&]() {
(void)AAudioStream_isMMapUsed(mAaudioStream);
},
});
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 9abe037..a544066 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2463,12 +2463,8 @@
mediametrics_setInt32(nextMetricsHandle, kCodecCrypto, 1);
}
} else if (mFlags & kFlagIsSecure) {
- if (android::media::codec::provider_->secure_codecs_require_crypto()) {
- mErrorLog.log(LOG_TAG, "Crypto or descrambler must be given for secure codec");
- return INVALID_OPERATION;
- } else {
- ALOGW("Crypto or descrambler should be given for secure codec");
- }
+ // We'll catch this later when we process the buffers.
+ ALOGW("Crypto or descrambler should be given for secure codec");
}
if (mConfigureMsg != nullptr) {
@@ -6213,6 +6209,12 @@
CryptoPlugin::SubSample ss;
CryptoPlugin::Pattern pattern;
+ if (android::media::codec::provider_->secure_codecs_require_crypto()
+ && (mFlags & kFlagIsSecure) && !hasCryptoOrDescrambler()) {
+ mErrorLog.log(LOG_TAG, "Crypto or descrambler must be given for secure codec");
+ return INVALID_OPERATION;
+ }
+
if (msg->findSize("size", &size)) {
if (hasCryptoOrDescrambler()) {
ss.mNumBytesOfClearData = size;
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 7169b1e..b4794f1 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -123,6 +123,13 @@
CB_RESOURCE_RECLAIMED = 5,
CB_CRYPTO_ERROR = 6,
CB_LARGE_FRAME_OUTPUT_AVAILABLE = 7,
+
+ /** Callback ID for when the metrics for this codec have been flushed
+ * due to the start of a new subsession. The associated AMessage will
+ * contain an sp<WrapperObject<std::unique_ptr<mediametrics::Item>>>
+ * Object at the "metrics" key.
+ */
+ CB_METRICS_FLUSHED = 8,
};
static const pid_t kNoPid = -1;
diff --git a/media/module/libapexcodecs/Android.bp b/media/module/libapexcodecs/Android.bp
new file mode 100644
index 0000000..790b749
--- /dev/null
+++ b/media/module/libapexcodecs/Android.bp
@@ -0,0 +1,71 @@
+//
+// Copyright (C) 2024 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 {
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_defaults {
+ name: "libapexcodecs-defaults",
+ header_libs: [
+ "libbase_headers",
+ ],
+
+ srcs: ["ApexCodecs.cpp"],
+
+ shared_libs: [
+ "libbase",
+ "libnativewindow",
+ ],
+
+ export_include_dirs: ["include"],
+
+ export_shared_lib_headers: [
+ "libbase",
+ "libnativewindow",
+ ],
+
+}
+
+cc_library {
+ name: "libapexcodecs-testing",
+ defaults: ["libapexcodecs-defaults"],
+
+ visibility: [
+ ":__subpackages__",
+ ],
+}
+
+cc_library {
+ name: "libapexcodecs",
+ defaults: ["libapexcodecs-defaults"],
+
+ visibility: [
+ "//frameworks/av/apex:__subpackages__",
+ "//frameworks/av/media/codec2/hal/client",
+ ],
+
+ min_sdk_version: "apex_inherit",
+ version_script: "libapexcodecs.map.txt",
+ stubs: {
+ symbol_file: "libapexcodecs.map.txt",
+ versions: ["36"],
+ },
+
+ apex_available: [
+ "com.android.media.swcodec",
+ ],
+}
diff --git a/media/module/libapexcodecs/ApexCodecs.cpp b/media/module/libapexcodecs/ApexCodecs.cpp
new file mode 100644
index 0000000..7101677
--- /dev/null
+++ b/media/module/libapexcodecs/ApexCodecs.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <new>
+
+#include <android-base/no_destructor.h>
+#include <apex/ApexCodecs.h>
+
+// TODO: remove when we have real implementations
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+
+struct ApexCodec_ComponentStore {
+ ApexCodec_ComponentStore() = default;
+};
+
+ApexCodec_ComponentStore *ApexCodec_GetComponentStore() {
+ ::android::base::NoDestructor<ApexCodec_ComponentStore> store;
+ return store.get();
+}
+
+ApexCodec_ComponentTraits *ApexCodec_Traits_get(
+ ApexCodec_ComponentStore *store, size_t index) {
+ return nullptr;
+}
+
+ApexCodec_Status ApexCodec_Component_create(
+ ApexCodec_ComponentStore *store, const char *name, ApexCodec_Component **comp) {
+ *comp = nullptr;
+ return APEXCODEC_STATUS_NOT_FOUND;
+}
+
+void ApexCodec_Component_destroy(ApexCodec_Component *comp) {}
+
+ApexCodec_Status ApexCodec_Component_start(ApexCodec_Component *comp) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Status ApexCodec_Component_flush(ApexCodec_Component *comp) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Status ApexCodec_Component_reset(ApexCodec_Component *comp) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Configurable *ApexCodec_Component_getConfigurable(
+ ApexCodec_Component *comp) {
+ return nullptr;
+}
+
+ApexCodec_Status ApexCodec_SupportedValues_getTypeAndValues(
+ ApexCodec_SupportedValues *supportedValues,
+ ApexCodec_SupportedValuesType *type,
+ ApexCodec_SupportedValuesNumberType *numberType,
+ ApexCodec_Value **values,
+ uint32_t *numValues) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+void ApexCodec_SupportedValues_release(ApexCodec_SupportedValues *values) {}
+
+ApexCodec_Status ApexCodec_SettingResults_getResultAtIndex(
+ ApexCodec_SettingResults *results,
+ size_t index,
+ ApexCodec_SettingResultFailure *failure,
+ ApexCodec_ParamFieldValues *field,
+ ApexCodec_ParamFieldValues **conflicts,
+ size_t *numConflicts) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+void ApexCodec_SettingResults_release(ApexCodec_SettingResults *results) {}
+
+ApexCodec_Status ApexCodec_Component_process(
+ ApexCodec_Component *comp,
+ const ApexCodec_Buffer *input,
+ ApexCodec_Buffer *output,
+ size_t *consumed,
+ size_t *produced) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Status ApexCodec_Configurable_config(
+ ApexCodec_Configurable *comp,
+ ApexCodec_LinearBuffer *config,
+ ApexCodec_SettingResults **results) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Status ApexCodec_Configurable_query(
+ ApexCodec_Configurable *comp,
+ uint32_t indices[],
+ size_t numIndices,
+ ApexCodec_LinearBuffer *config,
+ size_t *written) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Status ApexCodec_ParamDescriptors_getIndices(
+ ApexCodec_ParamDescriptors *descriptors,
+ uint32_t **indices,
+ size_t *numIndices) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Status ApexCodec_ParamDescriptors_getDescriptor(
+ ApexCodec_ParamDescriptors *descriptors,
+ uint32_t index,
+ ApexCodec_ParamAttribute *attr,
+ const char **name,
+ uint32_t **dependencies,
+ size_t *numDependencies) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Status ApexCodec_ParamDescriptors_release(
+ ApexCodec_ParamDescriptors *descriptors) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Status ApexCodec_Configurable_querySupportedParams(
+ ApexCodec_Configurable *comp,
+ ApexCodec_ParamDescriptors **descriptors) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+ApexCodec_Status ApexCodec_Configurable_querySupportedValues(
+ ApexCodec_Configurable *comp,
+ ApexCodec_SupportedValuesQuery *queries,
+ size_t numQueries) {
+ return APEXCODEC_STATUS_OMITTED;
+}
+
+#pragma clang diagnostic pop
\ No newline at end of file
diff --git a/media/module/libapexcodecs/include/apex/ApexCodecs.h b/media/module/libapexcodecs/include/apex/ApexCodecs.h
new file mode 100644
index 0000000..b9f2e83
--- /dev/null
+++ b/media/module/libapexcodecs/include/apex/ApexCodecs.h
@@ -0,0 +1,768 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <sys/cdefs.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <android/api-level.h>
+#include <android/hardware_buffer.h>
+#include <android/versioning.h>
+
+__BEGIN_DECLS
+
+/**
+ * An API to access and operate codecs implemented within an APEX module,
+ * used only by the OS when using the codecs within a client process
+ * (instead of via a HAL).
+ *
+ * NOTE: Many of the constants and types mirror the ones in the Codec 2.0 API.
+ */
+
+/**
+ * Error code for ApexCodec APIs.
+ *
+ * Introduced in API 36.
+ */
+typedef enum ApexCodec_Status : int32_t {
+ APEXCODEC_STATUS_OK = 0,
+
+ /* bad input */
+ APEXCODEC_STATUS_BAD_VALUE = EINVAL,
+ APEXCODEC_STATUS_BAD_INDEX = ENXIO,
+ APEXCODEC_STATUS_CANNOT_DO = ENOTSUP,
+
+ /* bad sequencing of events */
+ APEXCODEC_STATUS_DUPLICATE = EEXIST,
+ APEXCODEC_STATUS_NOT_FOUND = ENOENT,
+ APEXCODEC_STATUS_BAD_STATE = EPERM,
+ APEXCODEC_STATUS_BLOCKING = EWOULDBLOCK,
+ APEXCODEC_STATUS_CANCELED = EINTR,
+
+ /* bad environment */
+ APEXCODEC_STATUS_NO_MEMORY = ENOMEM,
+ APEXCODEC_STATUS_REFUSED = EACCES,
+
+ APEXCODEC_STATUS_TIMED_OUT = ETIMEDOUT,
+
+ /* bad versioning */
+ APEXCODEC_STATUS_OMITTED = ENOSYS,
+
+ /* unknown fatal */
+ APEXCODEC_STATUS_CORRUPTED = EFAULT,
+ APEXCODEC_STATUS_NO_INIT = ENODEV,
+} ApexCodec_Status;
+
+/**
+ * Enum that represents the kind of component
+ *
+ * Introduced in API 36.
+ */
+typedef enum ApexCodec_Kind : uint32_t {
+ /**
+ * The component is of a kind that is not listed below.
+ */
+ APEXCODEC_KIND_OTHER = 0x0,
+ /**
+ * The component is a decoder, which decodes coded bitstream
+ * into raw buffers.
+ *
+ * Introduced in API 36.
+ */
+ APEXCODEC_KIND_DECODER = 0x1,
+ /**
+ * The component is an encoder, which encodes raw buffers
+ * into coded bitstream.
+ *
+ * Introduced in API 36.
+ */
+ APEXCODEC_KIND_ENCODER = 0x2,
+} ApexCodec_Kind;
+
+typedef enum ApexCodec_Domain : uint32_t {
+ /**
+ * A component domain that is not listed below.
+ *
+ * Introduced in API 36.
+ */
+ APEXCODEC_DOMAIN_OTHER = 0x0,
+ /**
+ * A component domain that operates on video.
+ *
+ * Introduced in API 36.
+ */
+ APEXCODEC_DOMAIN_VIDEO = 0x1,
+ /**
+ * A component domain that operates on audio.
+ *
+ * Introduced in API 36.
+ */
+ APEXCODEC_DOMAIN_AUDIO = 0x2,
+ /**
+ * A component domain that operates on image.
+ *
+ * Introduced in API 36.
+ */
+ APEXCODEC_DOMAIN_IMAGE = 0x3,
+} ApexCodec_Domain;
+
+/**
+ * Handle for component traits such as name, media type, kind (decoder/encoder),
+ * domain (audio/video/image), etc.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_ComponentTraits {
+ /**
+ * The name of the component.
+ */
+ const char *name;
+ /**
+ * The supported media type of the component.
+ */
+ const char *mediaType;
+ /**
+ * The kind of the component.
+ */
+ ApexCodec_Kind kind;
+ /**
+ * The domain on which the component operates.
+ */
+ ApexCodec_Domain domain;
+} ApexCodec_ComponentTraits;
+
+/**
+ * An opaque struct that represents a component store.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_ComponentStore ApexCodec_ComponentStore;
+
+/**
+ * Get the component store object. This function never fails.
+ *
+ * \return component store object.
+ */
+ApexCodec_ComponentStore *ApexCodec_GetComponentStore()
+ __INTRODUCED_IN(36);
+
+/**
+ * Get the traits object of a component at given index. ApexCodecs_Traits_*
+ * functions are used to extract information from the traits object.
+ *
+ * Returns nullptr if index is out of bounds. The returned object is owned by
+ * ApexCodec_ComponentStore object and the client should not delete it.
+ *
+ * The client can iterate through the traits objects by calling this function
+ * with an index incrementing from 0 until it gets a nullptr.
+ *
+ * \param index index of the traits object to query
+ * \return traits object at the index, or nullptr if the index is out of bounds.
+ */
+ApexCodec_ComponentTraits *ApexCodec_Traits_get(
+ ApexCodec_ComponentStore *store, size_t index) __INTRODUCED_IN(36);
+
+/**
+ * An opaque struct that represents a codec.
+ */
+typedef struct ApexCodec_Component ApexCodec_Component;
+
+/**
+ * Create a component by the name.
+ *
+ * \param store the component store
+ * \param name the name of the component
+ * \param component out-param to be filled with the component; must not be null
+ * \return APEXCODEC_STATUS_OK if successful
+ * APEXCODEC_STATUS_NOT_FOUND if the name is not found
+ */
+ApexCodec_Status ApexCodec_Component_create(
+ ApexCodec_ComponentStore *store, const char *name, ApexCodec_Component **comp)
+ __INTRODUCED_IN(36);
+
+/**
+ * Destroy the component by the handle. It is invalid to call component methods on the handle
+ * after calling this method. It is no-op to call this method with |comp| == nullptr.
+ *
+ * \param comp the handle for the component
+ */
+void ApexCodec_Component_destroy(ApexCodec_Component *comp) __INTRODUCED_IN(36);
+
+/**
+ * Start the component. The component is ready to process buffers after this call.
+ *
+ * \param comp the handle for the component
+ */
+ApexCodec_Status ApexCodec_Component_start(
+ ApexCodec_Component *comp) __INTRODUCED_IN(36);
+
+/**
+ * Flush the component's internal states. This operation preserves the existing configurations.
+ *
+ * \param comp the handle for the component
+ */
+ApexCodec_Status ApexCodec_Component_flush(
+ ApexCodec_Component *comp) __INTRODUCED_IN(36);
+
+/**
+ * Resets the component to the initial state, right after creation. Note that the configuration
+ * will also revert to the initial state, so if there are configurations required those should be
+ * set again to use the component.
+ *
+ * \param comp the handle for the component
+ */
+ApexCodec_Status ApexCodec_Component_reset(
+ ApexCodec_Component *comp) __INTRODUCED_IN(36);
+
+/**
+ * An opaque struct that represents a configurable part of the component.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_Configurable ApexCodec_Configurable;
+
+/**
+ * Return the configurable object for the given ApexCodec_Component.
+ * The returned object has the same lifecycle as |comp|.
+ *
+ * \param comp the handle for the component
+ * \return the configurable object handle
+ */
+ApexCodec_Configurable *ApexCodec_Component_getConfigurable(
+ ApexCodec_Component *comp) __INTRODUCED_IN(36);
+
+/**
+ * Enum that represents the flags for ApexCodec_Buffer.
+ *
+ * Introduced in API 36.
+ */
+typedef enum ApexCodec_BufferFlags : uint32_t {
+ APEXCODEC_FLAG_DROP_FRAME = (1 << 0),
+ APEXCODEC_FLAG_END_OF_STREAM = (1 << 1),
+ APEXCODEC_FLAG_DISCARD_FRAME = (1 << 2),
+ APEXCODEC_FLAG_INCOMPLETE = (1 << 3),
+ APEXCODEC_FLAG_CORRECTED = (1 << 4),
+ APEXCODEC_FLAG_CORRUPT = (1 << 5),
+ APEXCODEC_FLAG_CODEC_CONFIG = (1u << 31),
+} ApexCodec_BufferFlags;
+
+/**
+ * Enum that represents the type of buffer.
+ *
+ * Introduced in API 36.
+ */
+typedef enum ApexCodec_BufferType : uint32_t {
+ APEXCODEC_BUFFER_TYPE_INVALID,
+ APEXCODEC_BUFFER_TYPE_LINEAR,
+ APEXCODEC_BUFFER_TYPE_LINEAR_CHUNKS,
+ APEXCODEC_BUFFER_TYPE_GRAPHIC,
+ APEXCODEC_BUFFER_TYPE_GRAPHIC_CHUNKS,
+} ApexCodec_BufferType;
+
+/**
+ * Struct that represents the memory for ApexCodec_Buffer.
+ *
+ * All memory regions have the simple 1D representation.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_LinearBuffer {
+ /**
+ * A pointer to the start of the buffer. This is not aligned.
+ */
+ uint8_t *data;
+ /**
+ * Size of the buffer. The memory region between |data| (inclusive) and
+ * |data + size| (exclusive) is assumed to be valid for read/write.
+ */
+ size_t size;
+} ApexCodec_LinearBuffer;
+
+/**
+ * Struct that represents a buffer for ApexCodec_Component.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_Buffer {
+ /**
+ * Flags associated with the buffer.
+ */
+ ApexCodec_BufferFlags flags;
+ /**
+ * For input buffers client assign a unique sequential index for each buffer. For output buffers
+ * it is the same as the associated input buffer's frame index.
+ */
+ uint64_t frameIndex;
+ /**
+ * A timestamp associated with the buffer in microseconds.
+ */
+ uint64_t timestampUs;
+ /**
+ * The type of the buffer. The component may reject request to process a buffer with the wrong
+ * type. For example, a video decoder will reject an input buffer with type BUFFER_TYPE_GRAPHIC,
+ * or an output buffer with type BUFFER_TYPE_LINEAR.
+ */
+ ApexCodec_BufferType type;
+ /**
+ * The actual memory for the buffer.
+ */
+ union {
+ ApexCodec_LinearBuffer linear;
+ AHardwareBuffer *graphic;
+ } memory;
+ /**
+ * Config updates associated with the buffer. For input buffers these are sent to the component
+ * at the specific input frame. For output buffers these are config updates as a result of
+ * processing the buffer.
+ */
+ ApexCodec_LinearBuffer configUpdates;
+} ApexCodec_Buffer;
+
+/**
+ * Enum that represents the query type for the supported values.
+ *
+ * Introduced in API 36.
+ */
+typedef enum ApexCodec_SupportedValuesQueryType : uint32_t {
+ /** Query all possible supported values regardless of current configuration */
+ APEXCODEC_SUPPORTED_VALUES_QUERY_POSSIBLE,
+ /** Query supported values at current configuration */
+ APEXCODEC_SUPPORTED_VALUES_QUERY_CURRENT,
+} ApexCodec_SupportedValuesQueryType;
+
+/**
+ * Enum that represents the type of the supported values.
+ *
+ * Introduced in API 36.
+ */
+typedef enum ApexCodec_SupportedValuesType : uint32_t {
+ /** The supported values are empty. */
+ APEXCODEC_SUPPORTED_VALUES_EMPTY,
+ /**
+ * The supported values are represented by a range defined with {min, max, step, num, den}.
+ *
+ * If step is 0 and num and denom are both 1, the supported values are any value, for which
+ * min <= value <= max.
+ *
+ * Otherwise, the range represents a geometric/arithmetic/multiply-accumulate series, where
+ * successive supported values can be derived from previous values (starting at min), using the
+ * following formula:
+ * v[0] = min
+ * v[i] = v[i-1] * num / denom + step for i >= 1, while min < v[i] <= max.
+ */
+ APEXCODEC_SUPPORTED_VALUES_RANGE,
+ /** The supported values are represented by a list of values. */
+ APEXCODEC_SUPPORTED_VALUES_VALUES,
+ /** The supported values are represented by a list of flags. */
+ APEXCODEC_SUPPORTED_VALUES_FLAGS,
+} ApexCodec_SupportedValuesType;
+
+/**
+ * Enum that represents numeric types of the supported values.
+ *
+ * Introduced in API 36.
+ */
+typedef enum ApexCodec_SupportedValuesNumberType : uint32_t {
+ APEXCODEC_SUPPORTED_VALUES_TYPE_NONE = 0,
+ APEXCODEC_SUPPORTED_VALUES_TYPE_INT32 = 1,
+ APEXCODEC_SUPPORTED_VALUES_TYPE_UINT32 = 2,
+ // RESERVED = 3,
+ APEXCODEC_SUPPORTED_VALUES_TYPE_INT64 = 4,
+ APEXCODEC_SUPPORTED_VALUES_TYPE_UINT64 = 5,
+ // RESERVED = 6,
+ APEXCODEC_SUPPORTED_VALUES_TYPE_FLOAT = 7,
+} ApexCodec_SupportedValuesNumberType;
+
+/**
+ * Union of primitive types.
+ *
+ * Introduced in API 36.
+ */
+typedef union {
+ int32_t i32;
+ uint32_t u32;
+ int64_t i64;
+ uint64_t u64;
+ float f;
+} ApexCodec_Value;
+
+/**
+ * An opaque struct that represents the supported values of a parameter.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_SupportedValues ApexCodec_SupportedValues;
+
+/**
+ * Extract information from ApexCodec_SupportedValues object.
+ *
+ * \param [in] supportedValues the supported values object
+ * \param [out] type pointer to be filled with the type of the supported values
+ * \param [out] numberType pointer to be filled with the numeric type of the supported values
+ * \param [out] values pointer to be filled with the array of the actual supported values.
+ * if type == APEXCODEC_SUPPORTED_VALUES_EMPTY: nullptr
+ * if type == APEXCODEC_SUPPORTED_VALUES_RANGE: {min, max, step, num, den}
+ * if type == APEXCODEC_SUPPORTED_VALUES_VALUES/_FLAGS:
+ * the array of supported values/flags
+ * the array is owned by the |supportedValues| object and the client
+ * should not free it.
+ * \param [out] numValues pointer to be filled with the number of values.
+ * if type == APEXCODEC_SUPPORTED_VALUES_EMPTY: 0
+ * if type == APEXCODEC_SUPPORTED_VALUES_RANGE: 5
+ * if type == APEXCODEC_SUPPORTED_VALUES_VALUES/_FLAGS: varies
+ */
+ApexCodec_Status ApexCodec_SupportedValues_getTypeAndValues(
+ ApexCodec_SupportedValues *supportedValues,
+ ApexCodec_SupportedValuesType *type,
+ ApexCodec_SupportedValuesNumberType *numberType,
+ ApexCodec_Value **values,
+ uint32_t *numValues) __INTRODUCED_IN(36);
+
+/**
+ * Release the supported values object.
+ *
+ * \param values the supported values object
+ */
+void ApexCodec_SupportedValues_release(
+ ApexCodec_SupportedValues *values) __INTRODUCED_IN(36);
+
+/**
+ * Struct that represents the result of ApexCodec_Configurable_config.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_SettingResults ApexCodec_SettingResults;
+
+/**
+ * Enum that represents the failure code of ApexCodec_SettingResults.
+ *
+ * Introduced in API 36.
+ */
+typedef enum ApexCodec_SettingResultFailure : uint32_t {
+ /** parameter type is not supported */
+ APEXCODEC_SETTING_RESULT_BAD_TYPE,
+ /** parameter is not supported on the specific port */
+ APEXCODEC_SETTING_RESULT_BAD_PORT,
+ /** parameter is not supported on the specific stream */
+ APEXCODEC_SETTING_RESULT_BAD_INDEX,
+ /** parameter is read-only */
+ APEXCODEC_SETTING_RESULT_READ_ONLY,
+ /** parameter mismatches input data */
+ APEXCODEC_SETTING_RESULT_MISMATCH,
+ /** strict parameter does not accept value for the field at all */
+ APEXCODEC_SETTING_RESULT_BAD_VALUE,
+ /** strict parameter field value conflicts with another settings */
+ APEXCODEC_SETTING_RESULT_CONFLICT,
+ /** strict parameter field is out of range due to other settings */
+ APEXCODEC_SETTING_RESULT_UNSUPPORTED,
+ /**
+ * field does not accept the requested parameter value at all. It has been corrected to
+ * the closest supported value. This failure mode is provided to give guidance as to what
+ * are the currently supported values for this field (which may be a subset of the at-all-
+ * potential values)
+ */
+ APEXCODEC_SETTING_RESULT_INFO_BAD_VALUE,
+ /**
+ * requested parameter value is in conflict with an/other setting(s)
+ * and has been corrected to the closest supported value. This failure
+ * mode is given to provide guidance as to what are the currently supported values as well
+ * as to optionally provide suggestion to the client as to how to enable the requested
+ * parameter value.
+ */
+ APEXCODEC_SETTING_RESULT_INFO_CONFLICT,
+} ApexCodec_SettingResultFailure;
+
+/**
+ * Struct that represents a field and its supported values of a parameter.
+ *
+ * The offset and size of the field are where the field is located in the blob representation of
+ * the parameter, as used in the ApexCodec_Configurable_query() and ApexCodec_Configurable_config(),
+ * for example.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_ParamFieldValues {
+ /** index of the param */
+ uint32_t index;
+ /** offset of the param field */
+ uint32_t offset;
+ /** size of the param field */
+ uint32_t size;
+ /** currently supported values of the param field */
+ ApexCodec_SupportedValues *values;
+} ApexCodec_ParamFieldValues;
+
+/**
+ * Extract the result of ApexCodec_Configurable_config.
+ * The client can iterate through the results with index starting from 0 until this function returns
+ * APEXCODEC_STATUS_NOT_FOUND.
+ *
+ * \param [in] result the result object
+ * \param [in] index the index of the result to extract, starts from 0.
+ * \param [out] failure pointer to be filled with the failure code
+ * \param [out] field pointer to be filled with the field that failed.
+ * |field->value| is owned by the |result| object and the client should not
+ * free it.
+ * \param [out] conflicts pointer to be filled with the array of conflicts.
+ * nullptr if |numConflicts| is 0.
+ * the array and its content is owned by the |result| object and the client
+ * should not free it.
+ * \param [out] numConflicts pointer to be filled with the number of conflicts
+ * may be 0 if there are no conflicts
+ * \return APEXCODEC_STATUS_OK if successful
+ * \return APEXCODEC_STATUS_NOT_FOUND if index is out of range
+ */
+ApexCodec_Status ApexCodec_SettingResults_getResultAtIndex(
+ ApexCodec_SettingResults *results,
+ size_t index,
+ ApexCodec_SettingResultFailure *failure,
+ ApexCodec_ParamFieldValues *field,
+ ApexCodec_ParamFieldValues **conflicts,
+ size_t *numConflicts) __INTRODUCED_IN(36);
+
+/**
+ * Release the setting result object.
+ *
+ * \param result the setting result object
+ */
+void ApexCodec_SettingResults_release(
+ ApexCodec_SettingResults *results) __INTRODUCED_IN(36);
+
+/**
+ * Process one frame from |input|, and produce one frame to |output| if possible.
+ * When successfully filled, |output->memory.linear| has the size adjusted to the produced
+ * output size, in case of linear buffers. |input->configUpdates| is applied with the input
+ * buffer; |output->configUpdates| contains config updates as a result of processing the frame.
+ *
+ * \param comp the component to process the buffers
+ * \param input the input buffer; when nullptr, the component should fill |output| if there are
+ * any pending output buffers.
+ * \param output the output buffer, should not be nullptr.
+ * \param consumed the number of consumed bytes from the input buffer
+ * set to 0 if no input buffer has been consumed, including |input| is nullptr.
+ * for graphic buffers, any non-zero value means that the input buffer is consumed.
+ * \param produced the number of bytes produced on the output buffer
+ * set to 0 if no output buffer has been produced.
+ * for graphic buffers, any non-zero value means that the output buffer is filled.
+ * \return APEXCODEC_STATUS_OK if successful
+ * \return APEXCODEC_STATUS_NO_MEMORY if the output buffer is not suitable to hold the output frame
+ * the client should retry with a new output buffer;
+ * configUpdates should have the information to update
+ * the buffer size.
+ * \return APEXCODEC_STATUS_BAD_VALUE if the parameters are bad
+ * \return APEXCODEC_STATUS_BAD_STATE if the component is not in the right state
+ * to process the frame
+ * \return APEXCODEC_STATUS_CORRUPTED if unexpected error has occurred
+ */
+ApexCodec_Status ApexCodec_Component_process(
+ ApexCodec_Component *comp,
+ const ApexCodec_Buffer *input,
+ ApexCodec_Buffer *output,
+ size_t *consumed,
+ size_t *produced) __INTRODUCED_IN(36);
+
+/**
+ * Configure the component with the given config.
+ *
+ * Configurations are Codec 2.0 configs in binary blobs,
+ * concatenated if there are multiple configs.
+ *
+ * frameworks/av/media/codec2/core/include/C2Param.h contains more details about the configuration
+ * blob layout.
+ *
+ * The component may correct the configured parameters to the closest supported values, and could
+ * fail in case there are no values that the component can auto-correct to. |result| contains the
+ * information about the failures. See ApexCodec_SettingResultFailure and ApexCodec_SettingResults
+ * for more details.
+ *
+ * \param [in] comp the handle for the component
+ * \param [inout] config the config blob; after the call, the config blob is updated to the actual
+ * config by the component.
+ * \param [out] result the result of the configuration.
+ * the client should call ApexCodec_SettingResult_getResultAtIndex()
+ * to extract the result. The result object is owned by the client and should
+ * be released with ApexCodec_SettingResult_release().
+ * |result| may be nullptr if empty.
+ * \return APEXCODEC_STATUS_OK if successful
+ * \return APEXCODEC_STATUS_BAD_VALUE if the config is invalid
+ * \return APEXCODEC_STATUS_BAD_STATE if the component is not in the right state to be configured
+ * \return APEXCODEC_STATUS_CORRUPTED if unexpected error has occurred
+ */
+ApexCodec_Status ApexCodec_Configurable_config(
+ ApexCodec_Configurable *comp,
+ ApexCodec_LinearBuffer *config,
+ ApexCodec_SettingResults **results) __INTRODUCED_IN(36);
+
+/**
+ * Query the component for the given indices.
+ *
+ * Parameter indices are defined in frameworks/av/media/codec2/core/include/C2Config.h.
+ *
+ * \param [in] comp the handle for the component
+ * \param [in] indices the array of indices to query
+ * \param [in] numIndices the size of the indices array
+ * \param [inout] config the output buffer for the config blob, allocated by the client.
+ * if the |config->size| was insufficient, it is set to the required size
+ * and |config->data| remains unchanged.
+ * \param [out] written the number of bytes written to |config|.
+ * \return APEXCODEC_STATUS_OK if successful
+ * \return APEXCODEC_STATUS_NO_MEMORY if |config.size| is too small; |config.size| is updated to the
+ * requested buffer size.
+ * \return APEXCODEC_STATUS_BAD_VALUE if the parameters are bad. e.g. |indices|, |config|,
+ * |config->data| or |written| is nullptr.
+ */
+ApexCodec_Status ApexCodec_Configurable_query(
+ ApexCodec_Configurable *comp,
+ uint32_t indices[],
+ size_t numIndices,
+ ApexCodec_LinearBuffer *config,
+ size_t *written) __INTRODUCED_IN(36);
+
+/**
+ * Struct that represents a parameter descriptor.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_ParamDescriptors ApexCodec_ParamDescriptors;
+
+/**
+ * Enum that represents the attributes of a parameter.
+ *
+ * Introduced in API 36.
+ */
+typedef enum ApexCodec_ParamAttribute : uint32_t {
+ /** parameter is required to be specified */
+ APEXCODEC_PARAM_IS_REQUIRED = 1u << 0,
+ /** parameter retains its value */
+ APEXCODEC_PARAM_IS_PERSISTENT = 1u << 1,
+ /** parameter is strict */
+ APEXCODEC_PARAM_IS_STRICT = 1u << 2,
+ /** parameter is read-only */
+ APEXCODEC_PARAM_IS_READ_ONLY = 1u << 3,
+ /** parameter shall not be visible to clients */
+ APEXCODEC_PARAM_IS_HIDDEN = 1u << 4,
+ /** parameter shall not be used by framework (other than testing) */
+ APEXCODEC_PARAM_IS_INTERNAL = 1u << 5,
+ /** parameter is publicly const (hence read-only) */
+ APEXCODEC_PARAM_IS_CONST = 1u << 6 | APEXCODEC_PARAM_IS_READ_ONLY,
+} ApexCodec_ParamAttribute;
+
+/**
+ * Get the parameter indices of the param descriptors.
+ *
+ * \param [in] descriptors the param descriptors object
+ * \param [out] indices the pointer to be filled with the array of the indices;
+ * the array is owned by |descriptors| and should not be freed by the client.
+ * \param [out] numIndices the size of the indices array
+ * \return APEXCODEC_STATUS_OK if successful
+ * \return APEXCODEC_STATUS_BAD_VALUE if parameters are bad. e.g. |descriptors|, |indices| or
+ * |numIndices| is nullptr.
+ */
+ApexCodec_Status ApexCodec_ParamDescriptors_getIndices(
+ ApexCodec_ParamDescriptors *descriptors,
+ uint32_t **indices,
+ size_t *numIndices) __INTRODUCED_IN(36);
+
+/**
+ * Get the descriptor of the param.
+ *
+ * \param [in] descriptors the param descriptors object
+ * \param [in] index the index of the param
+ * \param [out] attr the attribute of the param
+ * \param [out] name the pointer to be filled with the name of the param
+ * the string is owned by |descriptors| and should not be freed by the client.
+ * \param [out] dependencies the pointer to be filled with an array of the parameter indices
+ * that the parameter with |index| depends on.
+ * may be null if empty.
+ * the array is owned by |descriptors| and should not be freed by the client.
+ * \param [out] numDependencies the number of dependencies
+ * \return APEXCODEC_STATUS_OK if successful
+ * \return APEXCODEC_STATUS_BAD_VALUE if parameters are bad. e.g. |descriptors|, |attr|, |name|,
+ * |dependencies| or |numDependencies| is nullptr.
+ * \return APEXCODEC_STATUS_BAD_INDEX if the index is not included in the param descriptors.
+ */
+ApexCodec_Status ApexCodec_ParamDescriptors_getDescriptor(
+ ApexCodec_ParamDescriptors *descriptors,
+ uint32_t index,
+ ApexCodec_ParamAttribute *attr,
+ const char **name,
+ uint32_t **dependencies,
+ size_t *numDependencies) __INTRODUCED_IN(36);
+
+/**
+ * Release the param descriptors object.
+ *
+ * \param descriptors the param descriptors object
+ */
+ApexCodec_Status ApexCodec_ParamDescriptors_release(
+ ApexCodec_ParamDescriptors *descriptors) __INTRODUCED_IN(36);
+
+/**
+ * Query the component for the supported parameters.
+ *
+ * \param comp the handle for the component
+ * \param descriptors the pointer to be filled with the param descriptors object
+ * the object should be released with ApexCodec_ParamDescriptors_release().
+ * \return APEXCODEC_STATUS_OK if successful
+ * \return APEXCODEC_STATUS_BAD_VALUE if parameters are bad. e.g. |descriptors| is nullptr.
+ */
+ApexCodec_Status ApexCodec_Configurable_querySupportedParams(
+ ApexCodec_Configurable *comp,
+ ApexCodec_ParamDescriptors **descriptors) __INTRODUCED_IN(36);
+
+/**
+ * Struct that represents the query for the supported values of a parameter.
+ *
+ * The offset of the field can be found in the layout of the parameter blob.
+ *
+ * Introduced in API 36.
+ */
+typedef struct ApexCodec_SupportedValuesQuery {
+ /* in-params */
+
+ /** index of the param */
+ uint32_t index;
+ /** offset to the param field */
+ size_t offset;
+ /** query type */
+ ApexCodec_SupportedValuesQueryType type;
+
+ /* out-params */
+
+ /** status of the query */
+ ApexCodec_Status status;
+
+ /** supported values. must be released with ApexCodec_SupportedValues_release(). */
+ ApexCodec_SupportedValues *values;
+} ApexCodec_SupportedValuesQuery;
+
+/**
+ * Query the component for the supported values of the given indices.
+ *
+ * \param comp the handle for the component
+ * \param queries the array of queries
+ * \param numQueries the size of the queries array
+ * \return APEXCODEC_STATUS_OK if successful
+ * APEXCODEC_STATUS_CORRUPTED if unexpected error has occurred
+ */
+ApexCodec_Status ApexCodec_Configurable_querySupportedValues(
+ ApexCodec_Configurable *comp,
+ ApexCodec_SupportedValuesQuery *queries,
+ size_t numQueries) __INTRODUCED_IN(36);
+
+__END_DECLS
\ No newline at end of file
diff --git a/media/module/libapexcodecs/libapexcodecs.map.txt b/media/module/libapexcodecs/libapexcodecs.map.txt
new file mode 100644
index 0000000..672cf89
--- /dev/null
+++ b/media/module/libapexcodecs/libapexcodecs.map.txt
@@ -0,0 +1,26 @@
+LIBAPEXCODECS_36 { # introduced=36
+ global:
+ ApexCodec_Component_create; # apex
+ ApexCodec_Component_destroy; # apex
+ ApexCodec_Component_flush; # apex
+ ApexCodec_Component_getConfigurable; # apex
+ ApexCodec_Component_process; # apex
+ ApexCodec_Component_start; # apex
+ ApexCodec_Component_reset; # apex
+ ApexCodec_Configurable_config; # apex
+ ApexCodec_Configurable_query; # apex
+ ApexCodec_Configurable_querySupportedParams; # apex
+ ApexCodec_Configurable_querySupportedValues; # apex
+ ApexCodec_GetComponentStore; # apex
+ ApexCodec_ParamDescriptors_getDescriptor; # apex
+ ApexCodec_ParamDescriptors_getIndices; # apex
+ ApexCodec_ParamDescriptors_release; # apex
+ ApexCodec_SettingResults_getResultAtIndex; # apex
+ ApexCodec_SettingResults_release; # apex
+ ApexCodec_SupportedValues_getTypeAndValues; # apex
+ ApexCodec_SupportedValues_release; # apex
+ ApexCodec_Traits_get; # apex
+
+ local:
+ *;
+};
\ No newline at end of file
diff --git a/media/module/libapexcodecs/tests/Android.bp b/media/module/libapexcodecs/tests/Android.bp
new file mode 100644
index 0000000..162d12c
--- /dev/null
+++ b/media/module/libapexcodecs/tests/Android.bp
@@ -0,0 +1,30 @@
+//
+// Copyright (C) 2024 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 {
+ default_team: "trendy_team_android_media_codec_framework",
+ default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_test {
+ name: "libapexcodecs_tests",
+ shared_libs: [
+ "libapexcodecs-testing",
+ "libcodec2",
+ ],
+
+ srcs: ["ApexCodecsTest.cpp"],
+}
diff --git a/media/module/libapexcodecs/tests/ApexCodecsTest.cpp b/media/module/libapexcodecs/tests/ApexCodecsTest.cpp
new file mode 100644
index 0000000..cd5ebba
--- /dev/null
+++ b/media/module/libapexcodecs/tests/ApexCodecsTest.cpp
@@ -0,0 +1,100 @@
+#include <C2.h>
+#include <C2Component.h>
+
+#include <apex/ApexCodecs.h>
+
+// static_asserts for enum values match
+static_assert((uint32_t)APEXCODEC_STATUS_OK == (uint32_t)C2_OK);
+static_assert((uint32_t)APEXCODEC_STATUS_BAD_VALUE == (uint32_t)C2_BAD_VALUE);
+static_assert((uint32_t)APEXCODEC_STATUS_BAD_INDEX == (uint32_t)C2_BAD_INDEX);
+static_assert((uint32_t)APEXCODEC_STATUS_CANNOT_DO == (uint32_t)C2_CANNOT_DO);
+static_assert((uint32_t)APEXCODEC_STATUS_DUPLICATE == (uint32_t)C2_DUPLICATE);
+static_assert((uint32_t)APEXCODEC_STATUS_NOT_FOUND == (uint32_t)C2_NOT_FOUND);
+static_assert((uint32_t)APEXCODEC_STATUS_BAD_STATE == (uint32_t)C2_BAD_STATE);
+static_assert((uint32_t)APEXCODEC_STATUS_BLOCKING == (uint32_t)C2_BLOCKING);
+static_assert((uint32_t)APEXCODEC_STATUS_CANCELED == (uint32_t)C2_CANCELED);
+static_assert((uint32_t)APEXCODEC_STATUS_NO_MEMORY == (uint32_t)C2_NO_MEMORY);
+static_assert((uint32_t)APEXCODEC_STATUS_REFUSED == (uint32_t)C2_REFUSED);
+static_assert((uint32_t)APEXCODEC_STATUS_TIMED_OUT == (uint32_t)C2_TIMED_OUT);
+static_assert((uint32_t)APEXCODEC_STATUS_OMITTED == (uint32_t)C2_OMITTED);
+static_assert((uint32_t)APEXCODEC_STATUS_CORRUPTED == (uint32_t)C2_CORRUPTED);
+static_assert((uint32_t)APEXCODEC_STATUS_NO_INIT == (uint32_t)C2_NO_INIT);
+
+static_assert((uint32_t)APEXCODEC_KIND_OTHER == (uint32_t)C2Component::KIND_OTHER);
+static_assert((uint32_t)APEXCODEC_KIND_DECODER == (uint32_t)C2Component::KIND_DECODER);
+static_assert((uint32_t)APEXCODEC_KIND_ENCODER == (uint32_t)C2Component::KIND_ENCODER);
+
+static_assert((uint32_t)APEXCODEC_DOMAIN_OTHER == (uint32_t)C2Component::DOMAIN_OTHER);
+static_assert((uint32_t)APEXCODEC_DOMAIN_VIDEO == (uint32_t)C2Component::DOMAIN_VIDEO);
+static_assert((uint32_t)APEXCODEC_DOMAIN_AUDIO == (uint32_t)C2Component::DOMAIN_AUDIO);
+static_assert((uint32_t)APEXCODEC_DOMAIN_IMAGE == (uint32_t)C2Component::DOMAIN_IMAGE);
+
+static_assert((uint32_t)APEXCODEC_FLAG_DROP_FRAME == (uint32_t)C2FrameData::FLAG_DROP_FRAME);
+static_assert((uint32_t)APEXCODEC_FLAG_END_OF_STREAM == (uint32_t)C2FrameData::FLAG_END_OF_STREAM);
+static_assert((uint32_t)APEXCODEC_FLAG_DISCARD_FRAME == (uint32_t)C2FrameData::FLAG_DISCARD_FRAME);
+static_assert((uint32_t)APEXCODEC_FLAG_INCOMPLETE == (uint32_t)C2FrameData::FLAG_INCOMPLETE);
+static_assert((uint32_t)APEXCODEC_FLAG_CORRECTED == (uint32_t)C2FrameData::FLAG_CORRECTED);
+static_assert((uint32_t)APEXCODEC_FLAG_CORRUPT == (uint32_t)C2FrameData::FLAG_CORRUPT);
+static_assert((uint32_t)APEXCODEC_FLAG_CODEC_CONFIG == (uint32_t)C2FrameData::FLAG_CODEC_CONFIG);
+
+static_assert((uint32_t)APEXCODEC_BUFFER_TYPE_INVALID ==
+ (uint32_t)C2BufferData::INVALID);
+static_assert((uint32_t)APEXCODEC_BUFFER_TYPE_LINEAR ==
+ (uint32_t)C2BufferData::LINEAR);
+static_assert((uint32_t)APEXCODEC_BUFFER_TYPE_LINEAR_CHUNKS ==
+ (uint32_t)C2BufferData::LINEAR_CHUNKS);
+static_assert((uint32_t)APEXCODEC_BUFFER_TYPE_GRAPHIC ==
+ (uint32_t)C2BufferData::GRAPHIC);
+static_assert((uint32_t)APEXCODEC_BUFFER_TYPE_GRAPHIC_CHUNKS ==
+ (uint32_t)C2BufferData::GRAPHIC_CHUNKS);
+
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_QUERY_CURRENT ==
+ (uint32_t)C2FieldSupportedValuesQuery::CURRENT);
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_QUERY_POSSIBLE ==
+ (uint32_t)C2FieldSupportedValuesQuery::POSSIBLE);
+
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_EMPTY ==
+ (uint32_t)C2FieldSupportedValues::EMPTY);
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_RANGE ==
+ (uint32_t)C2FieldSupportedValues::RANGE);
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_VALUES ==
+ (uint32_t)C2FieldSupportedValues::VALUES);
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_FLAGS ==
+ (uint32_t)C2FieldSupportedValues::FLAGS);
+
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_TYPE_NONE == (uint32_t)C2Value::NO_INIT);
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_TYPE_INT32 == (uint32_t)C2Value::INT32);
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_TYPE_UINT32 == (uint32_t)C2Value::UINT32);
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_TYPE_INT64 == (uint32_t)C2Value::INT64);
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_TYPE_UINT64 == (uint32_t)C2Value::UINT64);
+static_assert((uint32_t)APEXCODEC_SUPPORTED_VALUES_TYPE_FLOAT == (uint32_t)C2Value::FLOAT);
+
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_BAD_TYPE ==
+ (uint32_t)C2SettingResult::BAD_TYPE);
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_BAD_PORT ==
+ (uint32_t)C2SettingResult::BAD_PORT);
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_BAD_INDEX ==
+ (uint32_t)C2SettingResult::BAD_INDEX);
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_READ_ONLY ==
+ (uint32_t)C2SettingResult::READ_ONLY);
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_MISMATCH ==
+ (uint32_t)C2SettingResult::MISMATCH);
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_BAD_VALUE ==
+ (uint32_t)C2SettingResult::BAD_VALUE);
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_CONFLICT ==
+ (uint32_t)C2SettingResult::CONFLICT);
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_UNSUPPORTED ==
+ (uint32_t)C2SettingResult::UNSUPPORTED);
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_INFO_BAD_VALUE ==
+ (uint32_t)C2SettingResult::INFO_BAD_VALUE);
+static_assert((uint32_t)APEXCODEC_SETTING_RESULT_INFO_CONFLICT ==
+ (uint32_t)C2SettingResult::INFO_CONFLICT);
+
+static_assert((uint32_t)APEXCODEC_PARAM_IS_REQUIRED == (uint32_t)C2ParamDescriptor::IS_REQUIRED);
+static_assert((uint32_t)APEXCODEC_PARAM_IS_PERSISTENT ==
+ (uint32_t)C2ParamDescriptor::IS_PERSISTENT);
+static_assert((uint32_t)APEXCODEC_PARAM_IS_STRICT == (uint32_t)C2ParamDescriptor::IS_STRICT);
+static_assert((uint32_t)APEXCODEC_PARAM_IS_READ_ONLY == (uint32_t)C2ParamDescriptor::IS_READ_ONLY);
+static_assert((uint32_t)APEXCODEC_PARAM_IS_HIDDEN == (uint32_t)C2ParamDescriptor::IS_HIDDEN);
+static_assert((uint32_t)APEXCODEC_PARAM_IS_INTERNAL == (uint32_t)C2ParamDescriptor::IS_INTERNAL);
+static_assert((uint32_t)APEXCODEC_PARAM_IS_CONST == (uint32_t)C2ParamDescriptor::IS_CONST);
\ No newline at end of file
diff --git a/services/audiopolicy/OWNERS b/services/audiopolicy/OWNERS
index 50ceadf..4a65069 100644
--- a/services/audiopolicy/OWNERS
+++ b/services/audiopolicy/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 48436
+atneya@google.com
elaurent@google.com
jiabin@google.com
jmtrivi@google.com
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index f59ad18..8d44e06 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2275,7 +2275,7 @@
bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
- if (!flags::use_context_attribution_source()) {
+ if (!flags::data_delivery_permission_checks()) {
resolvedClientAttribution.pid = USE_CALLING_PID;
}
@@ -4111,7 +4111,7 @@
mAppOpsManager = std::make_unique<AppOpsManager>();
}
- mUidIsTrusted = isTrustedCallingUid(getClientUid());
+ mUidIsTrusted = isTrustedCallingUid(mClientAttribution.uid);
}
CameraService::BasicClient::~BasicClient() {
@@ -4281,7 +4281,7 @@
ATRACE_CALL();
// Don't start watching until we're streaming when using permissionChecker for data delivery
- if (!flags::check_full_attribution_source_chain()) {
+ if (!flags::data_delivery_permission_checks()) {
ALOGD("%s: Start camera ops, package name = %s, client UID = %d", __FUNCTION__,
getPackageName().c_str(), getClientUid());
@@ -4303,7 +4303,7 @@
}
}
} else {
- // TODO: Remove when removing the check_full_attribution_source_chain flag
+ // TODO: Remove when removing the data_delivery_permission_checks flag
ALOGD("%s: Bypassing checkOp for uid %d", __FUNCTION__, getClientUid());
}
@@ -4337,7 +4337,7 @@
getPackageName().c_str(), getClientUid());
if (mAppOpsManager != nullptr) {
- if (flags::check_full_attribution_source_chain()) {
+ if (flags::data_delivery_permission_checks()) {
ALOGD("%s: Start data delivery for uid %d", __FUNCTION__, getClientUid());
const PermissionChecker::PermissionResult result =
@@ -4381,7 +4381,7 @@
// noteAppOp is only used for when camera mute is not supported, in order
// to trigger the sensor privacy "Unblock" dialog
- if (flags::check_full_attribution_source_chain()) {
+ if (flags::data_delivery_permission_checks()) {
// Ignore the result, since we're only triggering the dialog
ALOGD("%s: Check data delivery permissions for uid %d", __FUNCTION__, getClientUid());
hasPermissionsForCameraForDataDelivery(std::string(), mClientAttribution);
@@ -4413,7 +4413,7 @@
}
if (mAppOpsManager != nullptr) {
- if (flags::check_full_attribution_source_chain()) {
+ if (flags::data_delivery_permission_checks()) {
ALOGD("%s: finishDataDelivery for uid %d", __FUNCTION__, getClientUid());
finishDataDelivery(mClientAttribution);
@@ -4458,7 +4458,7 @@
}
// When using the data delivery permission checks, the open state does not involve AppOps
- if (!flags::check_full_attribution_source_chain()) {
+ if (!flags::data_delivery_permission_checks()) {
// Always stop watching, even if no camera op is active
if (mOpsCallback != nullptr && mAppOpsManager != nullptr) {
mAppOpsManager->stopWatchingMode(mOpsCallback);
@@ -4486,7 +4486,7 @@
}
PermissionChecker::PermissionResult res;
- if (flags::check_full_attribution_source_chain()) {
+ if (flags::data_delivery_permission_checks()) {
int32_t appOpMode = AppOpsManager::MODE_ALLOWED;
std::for_each(AttrSourceItr{mClientAttribution}, AttrSourceItr::end(),
[&](const auto& attr) {
@@ -4522,7 +4522,7 @@
// Uid may be active, but not visible to the user (e.g. PROCESS_STATE_FOREGROUND_SERVICE).
// If not visible, but still active, then we want to block instead of muting the camera.
int32_t procState = ActivityManager::PROCESS_STATE_NONEXISTENT;
- if (flags::check_full_attribution_source_chain()) {
+ if (flags::data_delivery_permission_checks()) {
// Use the proc state of the last uid in the chain (ultimately receiving the data)
// when determining whether to mute or block
int32_t uid = -1;
diff --git a/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h b/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h
index 24473f7..1835f2f 100644
--- a/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h
+++ b/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h
@@ -96,6 +96,7 @@
{36, {
ANDROID_COLOR_CORRECTION_AVAILABLE_MODES,
ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE,
+ ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES,
ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS,
ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS,
@@ -138,6 +139,8 @@
{36, {
ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE,
ANDROID_COLOR_CORRECTION_COLOR_TINT,
+ ANDROID_CONTROL_AE_PRIORITY_MODE,
+ ANDROID_CONTROL_ZOOM_METHOD,
ANDROID_EXTENSION_NIGHT_MODE_INDICATOR,
} },
};
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 2d58652..c1f9204 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -1311,11 +1311,15 @@
int32_t height = std::get<1>(it);
int32_t gainmapWidth = std::get<0>(it) / HeicCompositeStream::kGainmapScale;
int32_t gainmapHeight = std::get<1>(it) / HeicCompositeStream::kGainmapScale;
- if (camera3::HeicCompositeStream::isSizeSupportedByHeifEncoder(width, height,
- &useHeic, &useGrid, &stall, nullptr /*hevcName*/, kFrameworkHeicAllowSWCodecs) &&
- camera3::HeicCompositeStream::isSizeSupportedByHeifEncoder(gainmapWidth,
- gainmapHeight, &useHeic, &useGrid, &stall, nullptr /*hevcName*/,
- kFrameworkHeicAllowSWCodecs) ) {
+ // Support gainmap sizes that are sufficiently aligned so CPU specific copy
+ // optimizations can be utilized without side effects.
+ if (((gainmapWidth % 64) == 0) && ((gainmapHeight % 2) == 0) &&
+ camera3::HeicCompositeStream::isSizeSupportedByHeifEncoder(width, height,
+ &useHeic, &useGrid, &stall, nullptr /*hevcName*/,
+ kFrameworkHeicAllowSWCodecs) &&
+ camera3::HeicCompositeStream::isSizeSupportedByHeifEncoder(gainmapWidth,
+ gainmapHeight, &useHeic, &useGrid, &stall, nullptr /*hevcName*/,
+ kFrameworkHeicAllowSWCodecs)) {
int32_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(it)),
static_cast<int32_t> (std::get<1>(it)),
ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_OUTPUT };
@@ -1894,6 +1898,36 @@
return res;
}
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addAePriorityModeTags() {
+ status_t res = OK;
+ auto& c = mCameraCharacteristics;
+
+ auto entry = c.find(ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES);
+ if (entry.count != 0) {
+ return res;
+ }
+
+ std::vector<int32_t> supportedChTags;
+ auto chTags = c.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
+ if (chTags.count == 0) {
+ ALOGE("%s: No supported camera characteristics keys!", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ std::vector<uint8_t> aePriorityAvailableModes = {
+ ANDROID_CONTROL_AE_PRIORITY_MODE_OFF };
+ supportedChTags.reserve(chTags.count + 1);
+ supportedChTags.insert(supportedChTags.end(), chTags.data.i32,
+ chTags.data.i32 + chTags.count);
+ supportedChTags.push_back(ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES);
+ c.update(ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES,
+ aePriorityAvailableModes.data(), aePriorityAvailableModes.size());
+ c.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, supportedChTags.data(),
+ supportedChTags.size());
+
+ return res;
+}
+
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addPreCorrectionActiveArraySize() {
status_t res = OK;
auto& c = mCameraCharacteristics;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index e629218..3bad975 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -779,6 +779,7 @@
status_t addPreCorrectionActiveArraySize();
status_t addReadoutTimestampTag(bool readoutTimestampSupported = true);
status_t addColorCorrectionAvailableModesTag(CameraMetadata& ch);
+ status_t addAePriorityModeTags();
status_t addSessionConfigQueryVersionTag();
static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag,
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index 3d6a23f..3a0cfa1 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -618,6 +618,14 @@
}
}
+ if (flags::ae_priority()) {
+ res = addAePriorityModeTags();
+ if (OK != res) {
+ ALOGE("%s: Unable to add CONTROL_AE_AVAILABLE_PRIORITY_MODES tag: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+ }
+
camera_metadata_entry flashAvailable =
mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
if (flashAvailable.count == 1 &&
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index edaee6e..756c255 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -683,6 +683,14 @@
}
}
+ if (flags::ae_priority()) {
+ res = addAePriorityModeTags();
+ if (OK != res) {
+ ALOGE("%s: Unable to add CONTROL_AE_AVAILABLE_PRIORITY_MODES tag: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+ }
+
camera_metadata_entry flashAvailable =
mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
if (flashAvailable.count == 1 &&
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 5295442..35a192f 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2885,7 +2885,7 @@
bool hasAppCallback, nsecs_t minExpectedDuration, nsecs_t maxExpectedDuration,
bool isFixedFps, const std::set<std::set<std::string>>& physicalCameraIds,
bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto, bool autoframingAuto,
- const std::set<std::string>& cameraIdsWithZoom,
+ const std::set<std::string>& cameraIdsWithZoom, bool useZoomRatio,
const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs) {
ATRACE_CALL();
std::lock_guard<std::mutex> l(mInFlightLock);
@@ -2894,7 +2894,7 @@
res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
hasAppCallback, minExpectedDuration, maxExpectedDuration, isFixedFps, physicalCameraIds,
isStillCapture, isZslCapture, rotateAndCropAuto, autoframingAuto, cameraIdsWithZoom,
- requestTimeNs, outputSurfaces));
+ requestTimeNs, useZoomRatio, outputSurfaces));
if (res < 0) return res;
if (mInFlightMap.size() == 1) {
@@ -4182,6 +4182,7 @@
}
bool isStillCapture = false;
bool isZslCapture = false;
+ bool useZoomRatio = false;
const camera_metadata_t* settings = halRequest->settings;
bool shouldUnlockSettings = false;
if (settings == nullptr) {
@@ -4201,6 +4202,14 @@
if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_ENABLE_ZSL_TRUE)) {
isZslCapture = true;
}
+
+ if (flags::zoom_method()) {
+ e = camera_metadata_ro_entry_t();
+ find_camera_metadata_ro_entry(settings, ANDROID_CONTROL_ZOOM_METHOD, &e);
+ if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_ZOOM_METHOD_ZOOM_RATIO)) {
+ useZoomRatio = true;
+ }
+ }
}
bool passSurfaceMap =
mUseHalBufManager || containsHalBufferManagedStream;
@@ -4214,7 +4223,7 @@
expectedDurationInfo.isFixedFps,
requestedPhysicalCameras, isStillCapture, isZslCapture,
captureRequest->mRotateAndCropAuto, captureRequest->mAutoframingAuto,
- mPrevCameraIdsWithZoom,
+ mPrevCameraIdsWithZoom, useZoomRatio,
passSurfaceMap ? uniqueSurfaceIdMap :
SurfaceMap{}, captureRequest->mRequestTimeNs);
ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 397ec5c..f1e088e 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -1275,8 +1275,8 @@
bool callback, nsecs_t minExpectedDuration, nsecs_t maxExpectedDuration,
bool isFixedFps, const std::set<std::set<std::string>>& physicalCameraIds,
bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto, bool autoframingAuto,
- const std::set<std::string>& cameraIdsWithZoom, const SurfaceMap& outputSurfaces,
- nsecs_t requestTimeNs);
+ const std::set<std::string>& cameraIdsWithZoom, bool useZoomRatio,
+ const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs);
/**
* Tracking for idle detection
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index 62226e1..66ffc98 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -304,7 +304,7 @@
CameraMetadata &collectedPartialResult,
uint32_t frameNumber,
bool reprocess, bool zslStillCapture, bool rotateAndCropAuto,
- const std::set<std::string>& cameraIdsWithZoom,
+ const std::set<std::string>& cameraIdsWithZoom, bool useZoomRatio,
const std::vector<PhysicalCaptureResultInfo>& physicalMetadatas) {
ATRACE_CALL();
if (pendingMetadata.isEmpty())
@@ -385,8 +385,9 @@
// Fix up result metadata to account for zoom ratio availabilities between
// HAL and app.
bool zoomRatioIs1 = cameraIdsWithZoom.find(states.cameraId) == cameraIdsWithZoom.end();
+ bool appUsesZoomRatio = !zoomRatioIs1 || useZoomRatio;
res = states.zoomRatioMappers[states.cameraId].updateCaptureResult(
- &captureResult.mMetadata, zoomRatioIs1);
+ &captureResult.mMetadata, appUsesZoomRatio);
if (res != OK) {
SET_ERR("Failed to update capture result zoom ratio metadata for frame %d: %s (%d)",
frameNumber, strerror(-res), res);
@@ -452,9 +453,10 @@
}
}
- zoomRatioIs1 = cameraIdsWithZoom.find(cameraId) == cameraIdsWithZoom.end();
+ // Note: Physical camera continues to use SCALER_CROP_REGION to reflect
+ // zoom levels.
res = states.zoomRatioMappers[cameraId].updateCaptureResult(
- &physicalMetadata.mPhysicalCameraMetadata, zoomRatioIs1);
+ &physicalMetadata.mPhysicalCameraMetadata, /*appUsesZoomRatio*/ false);
if (res != OK) {
SET_ERR("Failed to update camera %s's physical zoom ratio metadata for "
"frame %d: %s(%d)", cameraId.c_str(), frameNumber, strerror(-res), res);
@@ -828,7 +830,7 @@
sendCaptureResult(states, metadata, request.resultExtras,
collectedPartialResult, frameNumber,
hasInputBufferInRequest, request.zslCapture && request.stillCapture,
- request.rotateAndCropAuto, cameraIdsWithZoom,
+ request.rotateAndCropAuto, cameraIdsWithZoom, request.useZoomRatio,
request.physicalMetadatas);
}
}
@@ -1097,7 +1099,8 @@
r.pendingMetadata, r.resultExtras,
r.collectedPartialResult, msg.frame_number,
r.hasInputBuffer, r.zslCapture && r.stillCapture,
- r.rotateAndCropAuto, cameraIdsWithZoom, r.physicalMetadatas);
+ r.rotateAndCropAuto, cameraIdsWithZoom, r.useZoomRatio,
+ r.physicalMetadatas);
}
collectAndRemovePendingOutputBuffers(
states.useHalBufManager, states.halBufManagedStreamIds,
diff --git a/services/camera/libcameraservice/device3/InFlightRequest.h b/services/camera/libcameraservice/device3/InFlightRequest.h
index 3626f20..62980c5 100644
--- a/services/camera/libcameraservice/device3/InFlightRequest.h
+++ b/services/camera/libcameraservice/device3/InFlightRequest.h
@@ -198,6 +198,9 @@
// Current output transformation
int32_t transform;
+ // Whether the app explicitly uses ZOOM_RATIO
+ bool useZoomRatio;
+
static const nsecs_t kDefaultMinExpectedDuration = 33333333; // 33 ms
static const nsecs_t kDefaultMaxExpectedDuration = 100000000; // 100 ms
@@ -220,14 +223,15 @@
rotateAndCropAuto(false),
autoframingAuto(false),
requestTimeNs(0),
- transform(-1) {
+ transform(-1),
+ useZoomRatio(false) {
}
InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
bool hasAppCallback, nsecs_t minDuration, nsecs_t maxDuration, bool fixedFps,
const std::set<std::set<std::string>>& physicalCameraIdSet, bool isStillCapture,
bool isZslCapture, bool rotateAndCropAuto, bool autoframingAuto,
- const std::set<std::string>& idsWithZoom, nsecs_t requestNs,
+ const std::set<std::string>& idsWithZoom, nsecs_t requestNs, bool useZoomRatio,
const SurfaceMap& outSurfaces = SurfaceMap{}) :
shutterTimestamp(0),
sensorTimestamp(0),
@@ -250,7 +254,8 @@
cameraIdsWithZoom(idsWithZoom),
requestTimeNs(requestNs),
outputSurfaces(outSurfaces),
- transform(-1) {
+ transform(-1),
+ useZoomRatio(useZoomRatio) {
}
};
diff --git a/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp b/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp
index 2016284..5260ad3 100644
--- a/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp
+++ b/services/camera/libcameraservice/device3/ZoomRatioMapper.cpp
@@ -19,6 +19,8 @@
#include <algorithm>
+#include <com_android_internal_camera_flags.h>
+
#include "device3/ZoomRatioMapper.h"
#include "utils/SessionConfigurationUtilsHost.h"
@@ -42,13 +44,25 @@
}
status_t ZoomRatioMapper::initZoomRatioInTemplate(CameraMetadata *request) {
+ status_t res = OK;
+
+ if (flags::zoom_method()) {
+ uint8_t zoomMethod = ANDROID_CONTROL_ZOOM_METHOD_AUTO;
+ res = request->update(ANDROID_CONTROL_ZOOM_METHOD, &zoomMethod, 1);
+ if (res != OK) {
+ ALOGE("%s: Failed to update CONTROL_ZOOM_METHOD key: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+ }
+
camera_metadata_entry_t entry;
entry = request->find(ANDROID_CONTROL_ZOOM_RATIO);
float defaultZoomRatio = 1.0f;
if (entry.count == 0) {
- return request->update(ANDROID_CONTROL_ZOOM_RATIO, &defaultZoomRatio, 1);
+ res = request->update(ANDROID_CONTROL_ZOOM_RATIO, &defaultZoomRatio, 1);
}
- return OK;
+ return res;
}
status_t ZoomRatioMapper::overrideZoomRatioTags(
@@ -57,40 +71,69 @@
return BAD_VALUE;
}
+ bool halSupportZoomRatio = false;
camera_metadata_entry_t entry;
entry = deviceInfo->find(ANDROID_CONTROL_ZOOM_RATIO_RANGE);
if (entry.count != 2 && entry.count != 0) return BAD_VALUE;
-
// Hal has zoom ratio support
if (entry.count == 2) {
- *supportNativeZoomRatio = true;
- return OK;
+ halSupportZoomRatio = true;
}
- // Hal has no zoom ratio support
- *supportNativeZoomRatio = false;
-
- entry = deviceInfo->find(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
- if (entry.count != 1) {
- ALOGI("%s: Camera device doesn't support SCALER_AVAILABLE_MAX_DIGITAL_ZOOM key!",
- __FUNCTION__);
- return OK;
- }
-
- float zoomRange[] = {1.0f, entry.data.f[0]};
- status_t res = deviceInfo->update(ANDROID_CONTROL_ZOOM_RATIO_RANGE, zoomRange, 2);
- if (res != OK) {
- ALOGE("%s: Failed to update CONTROL_ZOOM_RATIO_RANGE key: %s (%d)",
- __FUNCTION__, strerror(-res), res);
- return res;
- }
-
+ // Add ZOOM_METHOD request and result keys
std::vector<int32_t> requestKeys;
entry = deviceInfo->find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
if (entry.count > 0) {
requestKeys.insert(requestKeys.end(), entry.data.i32, entry.data.i32 + entry.count);
}
- requestKeys.push_back(ANDROID_CONTROL_ZOOM_RATIO);
+ if (flags::zoom_method()) {
+ requestKeys.push_back(ANDROID_CONTROL_ZOOM_METHOD);
+ }
+ std::vector<int32_t> resultKeys;
+ entry = deviceInfo->find(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
+ if (entry.count > 0) {
+ resultKeys.insert(resultKeys.end(), entry.data.i32, entry.data.i32 + entry.count);
+ }
+ if (flags::zoom_method()) {
+ resultKeys.push_back(ANDROID_CONTROL_ZOOM_METHOD);
+ }
+
+ // Add additional keys if the HAL doesn't support ZOOM_RATIO
+ status_t res = OK;
+ if (!halSupportZoomRatio) {
+ entry = deviceInfo->find(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
+ if (entry.count != 1) {
+ ALOGI("%s: Camera device doesn't support SCALER_AVAILABLE_MAX_DIGITAL_ZOOM key!",
+ __FUNCTION__);
+ return OK;
+ }
+ float zoomRange[] = {1.0f, entry.data.f[0]};
+ res = deviceInfo->update(ANDROID_CONTROL_ZOOM_RATIO_RANGE, zoomRange, 2);
+ if (res != OK) {
+ ALOGE("%s: Failed to update CONTROL_ZOOM_RATIO_RANGE key: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+
+ requestKeys.push_back(ANDROID_CONTROL_ZOOM_RATIO);
+ resultKeys.push_back(ANDROID_CONTROL_ZOOM_RATIO);
+
+ std::vector<int32_t> charKeys;
+ entry = deviceInfo->find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
+ if (entry.count > 0) {
+ charKeys.insert(charKeys.end(), entry.data.i32, entry.data.i32 + entry.count);
+ }
+ charKeys.push_back(ANDROID_CONTROL_ZOOM_RATIO_RANGE);
+ res = deviceInfo->update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
+ charKeys.data(), charKeys.size());
+ if (res != OK) {
+ ALOGE("%s: Failed to update REQUEST_AVAILABLE_CHARACTERISTICS_KEYS: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+ }
+
+ // Update available request and result keys
res = deviceInfo->update(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
requestKeys.data(), requestKeys.size());
if (res != OK) {
@@ -98,13 +141,6 @@
__FUNCTION__, strerror(-res), res);
return res;
}
-
- std::vector<int32_t> resultKeys;
- entry = deviceInfo->find(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
- if (entry.count > 0) {
- resultKeys.insert(resultKeys.end(), entry.data.i32, entry.data.i32 + entry.count);
- }
- resultKeys.push_back(ANDROID_CONTROL_ZOOM_RATIO);
res = deviceInfo->update(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
resultKeys.data(), resultKeys.size());
if (res != OK) {
@@ -113,20 +149,7 @@
return res;
}
- std::vector<int32_t> charKeys;
- entry = deviceInfo->find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
- if (entry.count > 0) {
- charKeys.insert(charKeys.end(), entry.data.i32, entry.data.i32 + entry.count);
- }
- charKeys.push_back(ANDROID_CONTROL_ZOOM_RATIO_RANGE);
- res = deviceInfo->update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
- charKeys.data(), charKeys.size());
- if (res != OK) {
- ALOGE("%s: Failed to update REQUEST_AVAILABLE_CHARACTERISTICS_KEYS: %s (%d)",
- __FUNCTION__, strerror(-res), res);
- return res;
- }
-
+ *supportNativeZoomRatio = halSupportZoomRatio;
return OK;
}
@@ -223,7 +246,6 @@
if (!mIsValid) return INVALID_OPERATION;
status_t res = OK;
- bool zoomRatioIs1 = true;
camera_metadata_entry_t entry;
int arrayHeight, arrayWidth = 0;
res = getArrayDimensionsToBeUsed(request, &arrayWidth, &arrayHeight);
@@ -231,9 +253,14 @@
return res;
}
entry = request->find(ANDROID_CONTROL_ZOOM_RATIO);
- if (entry.count == 1 && entry.data.f[0] != 1.0f) {
- zoomRatioIs1 = false;
-
+ bool zoomRatioIs1 = (entry.count == 0 || entry.data.f[0] == 1.0f);
+ bool useZoomRatio = !zoomRatioIs1;
+ if (flags::zoom_method()) {
+ entry = request->find(ANDROID_CONTROL_ZOOM_METHOD);
+ useZoomRatio |= (entry.count == 1
+ && entry.data.u8[0] == ANDROID_CONTROL_ZOOM_METHOD_ZOOM_RATIO);
+ }
+ if (useZoomRatio) {
// If cropRegion is windowboxing, override it with activeArray
camera_metadata_entry_t cropRegionEntry = request->find(ANDROID_SCALER_CROP_REGION);
if (cropRegionEntry.count == 4) {
@@ -248,9 +275,9 @@
}
}
- if (mHalSupportsZoomRatio && zoomRatioIs1) {
+ if (mHalSupportsZoomRatio && !useZoomRatio) {
res = separateZoomFromCropLocked(request, false/*isResult*/, arrayWidth, arrayHeight);
- } else if (!mHalSupportsZoomRatio && !zoomRatioIs1) {
+ } else if (!mHalSupportsZoomRatio && useZoomRatio) {
res = combineZoomAndCropLocked(request, false/*isResult*/, arrayWidth, arrayHeight);
}
@@ -263,7 +290,7 @@
return res;
}
-status_t ZoomRatioMapper::updateCaptureResult(CameraMetadata* result, bool requestedZoomRatioIs1) {
+status_t ZoomRatioMapper::updateCaptureResult(CameraMetadata* result, bool useZoomRatio) {
if (!mIsValid) return INVALID_OPERATION;
status_t res = OK;
@@ -273,9 +300,9 @@
if (res != OK) {
return res;
}
- if (mHalSupportsZoomRatio && requestedZoomRatioIs1) {
+ if (mHalSupportsZoomRatio && !useZoomRatio) {
res = combineZoomAndCropLocked(result, true/*isResult*/, arrayWidth, arrayHeight);
- } else if (!mHalSupportsZoomRatio && !requestedZoomRatioIs1) {
+ } else if (!mHalSupportsZoomRatio && useZoomRatio) {
res = separateZoomFromCropLocked(result, true/*isResult*/, arrayWidth, arrayHeight);
} else {
camera_metadata_entry_t entry = result->find(ANDROID_CONTROL_ZOOM_RATIO);
diff --git a/services/camera/libcameraservice/device3/ZoomRatioMapper.h b/services/camera/libcameraservice/device3/ZoomRatioMapper.h
index 1aa8e78..0ac2e09 100644
--- a/services/camera/libcameraservice/device3/ZoomRatioMapper.h
+++ b/services/camera/libcameraservice/device3/ZoomRatioMapper.h
@@ -64,7 +64,7 @@
/**
* Update capture result to handle both cropRegion and zoomRatio.
*/
- status_t updateCaptureResult(CameraMetadata *request, bool requestedZoomRatioIs1);
+ status_t updateCaptureResult(CameraMetadata *request, bool useZoomRatio);
public: // Visible for testing. Do not use concurently.
void scaleCoordinates(int32_t* coordPairs, int coordCount,
diff --git a/services/camera/libcameraservice/tests/ZoomRatioTest.cpp b/services/camera/libcameraservice/tests/ZoomRatioTest.cpp
index badd47a..a531e10 100644
--- a/services/camera/libcameraservice/tests/ZoomRatioTest.cpp
+++ b/services/camera/libcameraservice/tests/ZoomRatioTest.cpp
@@ -296,7 +296,7 @@
}
metadata.update(ANDROID_SCALER_CROP_REGION, test2xCropRegion[index], 4);
- res = mapper.updateCaptureResult(&metadata, true/*requestedZoomRatioIs1*/);
+ res = mapper.updateCaptureResult(&metadata, false/*useZoomRatio*/);
ASSERT_EQ(res, OK);
entry = metadata.find(ANDROID_SCALER_CROP_REGION);
ASSERT_EQ(entry.count, 4U);
@@ -340,7 +340,7 @@
entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
EXPECT_NEAR(entry.data.f[0], 2.0f, kMaxAllowedRatioError);
- res = mapper.updateCaptureResult(&metadata, true/*requestedZoomRatioIs1*/);
+ res = mapper.updateCaptureResult(&metadata, false/*useZoomRatio*/);
ASSERT_EQ(res, OK);
entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
@@ -364,7 +364,7 @@
entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
EXPECT_NEAR(entry.data.f[0], 1.0f, kMaxAllowedRatioError);
- res = mapper.updateCaptureResult(&metadata, true/*requestedZoomRatioIs1*/);
+ res = mapper.updateCaptureResult(&metadata, false/*useZoomRatio*/);
ASSERT_EQ(res, OK);
entry = metadata.find(ANDROID_SCALER_CROP_REGION);
ASSERT_EQ(entry.count, 4U);
@@ -452,7 +452,7 @@
entry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
ASSERT_EQ(entry.data.f[0], zoomRatio);
- res = mapper.updateCaptureResult(&metadata, false/*requestedZoomRatioIs1*/);
+ res = mapper.updateCaptureResult(&metadata, true/*useZoomRatio*/);
ASSERT_EQ(res, OK);
entry = metadata.find(ANDROID_SCALER_CROP_REGION);
ASSERT_EQ(entry.count, 4U);
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
index 4b63704..80af140 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
@@ -138,7 +138,7 @@
int32_t attributedOpCode, bool forDataDelivery, bool startDataDelivery,
bool checkAutomotive) {
AttributionSourceState clientAttribution = attributionSource;
- if (!flags::check_full_attribution_source_chain() && !clientAttribution.next.empty()) {
+ if (!flags::data_delivery_permission_checks() && !clientAttribution.next.empty()) {
clientAttribution.next.clear();
}
@@ -408,7 +408,7 @@
clientUid = callingUid;
} else {
validUid = isTrustedCallingUid(callingUid);
- if (flags::use_context_attribution_source()) {
+ if (flags::data_delivery_permission_checks()) {
validUid = validUid || (clientUid == callingUid);
}
}
@@ -426,7 +426,7 @@
clientPid = callingPid;
} else {
validPid = isTrustedCallingUid(callingUid);
- if (flags::use_context_attribution_source()) {
+ if (flags::data_delivery_permission_checks()) {
validPid = validPid || (clientPid == callingPid);
}
}
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
index 8b2804d..1c5d6da 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
@@ -92,8 +92,8 @@
virtual void restoreCallingIdentity(int64_t token);
/**
- * If flag::use_context_attribution_source() is enabled, check the calling attribution source
- * and resolve its package name, or fill in the pid/uid/package name if necessary.
+ * If flags::data_delivery_permission_checks() is enabled, check the calling attribution
+ * source and resolve its package name, or fill in the pid/uid/package name if necessary.
*
* @param resolvedAttributionSource The resolved attribution source.
* @param methodName The name of the method calling this function (for logging only).
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index 08f6314..ee4df4e 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -41,6 +41,7 @@
namespace android {
namespace camera3 {
+namespace flags = com::android::internal::camera::flags;
void StreamConfiguration::getStreamConfigurations(
const CameraMetadata &staticInfo, int configuration,
@@ -1252,6 +1253,14 @@
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;
}