Merge "Camera: Fix use-after-free issue with provider instance" into main
diff --git a/apex/ld.config.txt b/apex/ld.config.txt
index 4dc5fb1..c24d51f 100644
--- a/apex/ld.config.txt
+++ b/apex/ld.config.txt
@@ -33,7 +33,7 @@
# TODO: replace the following when apex has a way to auto-generate this list
# namespace.default.link.platform.shared_libs = %LLNDK_LIBRARIES%
# namespace.default.link.platform.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
-namespace.default.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libandroid_net.so:libc.so:libcgrouprc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libdl_android.so:libvulkan.so:libbinder_ndk.so
+namespace.default.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libandroid_net.so:libc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libdl_android.so:libvulkan.so:libbinder_ndk.so
###############################################################################
# "platform" namespace
@@ -138,7 +138,7 @@
# TODO: replace the following when apex has a way to auto-generate this list
# namespace.sphal.link.platform.shared_libs = %LLNDK_LIBRARIES%
# namespace.sphal.link.platform.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
-namespace.sphal.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libandroid_net.so:libc.so:libcgrouprc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libvulkan.so:libbinder_ndk.so
+namespace.sphal.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libandroid_net.so:libc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libvulkan.so:libbinder_ndk.so
# Add a link for libz.so which is llndk on devices where VNDK is not enforced.
namespace.sphal.link.platform.shared_libs += libz.so
diff --git a/camera/CameraUtils.cpp b/camera/CameraUtils.cpp
index 3473780..ebb3305 100644
--- a/camera/CameraUtils.cpp
+++ b/camera/CameraUtils.cpp
@@ -32,7 +32,7 @@
const char *kCameraServiceDisabledProperty = "config.disable_cameraservice";
status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
- int mirrorMode, /*out*/int32_t* transform) {
+ int mirrorMode, bool enableTransformInverseDisplay, /*out*/int32_t* transform) {
ALOGV("%s", __FUNCTION__);
if (transform == NULL) {
@@ -128,7 +128,9 @@
* aspect ratio, or the preview will end up looking non-uniformly
* stretched.
*/
- flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
+ if (enableTransformInverseDisplay) {
+ flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
+ }
ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index 55e5fc8..ebfd7d7 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 {
@@ -235,3 +229,9 @@
bug: "359944765"
}
+flag {
+ namespace: "camera_platform"
+ name: "feature_combination_baklava"
+ description: "Add new feature combination query version for Baklava"
+ bug: "370778206"
+}
diff --git a/camera/include/camera/CameraUtils.h b/camera/include/camera/CameraUtils.h
index d358407..766cac1 100644
--- a/camera/include/camera/CameraUtils.h
+++ b/camera/include/camera/CameraUtils.h
@@ -46,7 +46,7 @@
* Returns OK on success, or a negative error code.
*/
static status_t getRotationTransform(const CameraMetadata& staticInfo,
- int mirrorMode, /*out*/int32_t* transform);
+ int mirrorMode, bool enableTransformInverseDisplay, /*out*/int32_t* transform);
/**
* Check if the image data is VideoNativeHandleMetadata, that contains a native handle.
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index b792de0..704b46e 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -9750,6 +9750,28 @@
} acamera_metadata_enum_android_control_low_light_boost_state_t;
+// ACAMERA_CONTROL_ZOOM_METHOD
+typedef enum acamera_metadata_enum_acamera_control_zoom_method {
+ /**
+ * <p>The camera device automatically detects whether the application does zoom with
+ * ACAMERA_SCALER_CROP_REGION or ACAMERA_CONTROL_ZOOM_RATIO, and in turn decides which
+ * metadata tag reflects the effective zoom level.</p>
+ *
+ * @see ACAMERA_CONTROL_ZOOM_RATIO
+ * @see ACAMERA_SCALER_CROP_REGION
+ */
+ ACAMERA_CONTROL_ZOOM_METHOD_AUTO = 0,
+
+ /**
+ * <p>The application intends to control zoom via ACAMERA_CONTROL_ZOOM_RATIO, and
+ * the effective zoom level is reflected by ACAMERA_CONTROL_ZOOM_RATIO in capture results.</p>
+ *
+ * @see ACAMERA_CONTROL_ZOOM_RATIO
+ */
+ ACAMERA_CONTROL_ZOOM_METHOD_ZOOM_RATIO = 1,
+
+} acamera_metadata_enum_android_control_zoom_method_t;
+
// ACAMERA_CONTROL_AE_PRIORITY_MODE
typedef enum acamera_metadata_enum_acamera_control_ae_priority_mode {
/**
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index 3325da6..9ed8197 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -1684,8 +1684,9 @@
__FUNCTION__, burstId, cbh.mRequests.size());
dev->setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
}
+
sp<CaptureRequest> request = cbh.mRequests[burstId];
- ALOGE("%s: request = %p", __FUNCTION__, request.get());
+ ALOGV("%s: request = %p", __FUNCTION__, request.get());
sp<AMessage> msg = nullptr;
if (v2Callback) {
msg = new AMessage(kWhatCaptureStart2, dev->mHandler);
diff --git a/camera/tests/fuzzer/camera_utils_fuzzer.cpp b/camera/tests/fuzzer/camera_utils_fuzzer.cpp
index c816f82..ca0a06f 100644
--- a/camera/tests/fuzzer/camera_utils_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_utils_fuzzer.cpp
@@ -75,6 +75,7 @@
CameraUtils::getRotationTransform(
staticMetadata, mFDP->ConsumeIntegral<int32_t>() /* mirrorMode */,
+ true /*enableTransformInverseDisplay*/,
&transform /*out*/);
},
[&]() { CameraUtils::isCameraServiceDisabled(); },
diff --git a/media/audio/aconfig/Android.bp b/media/audio/aconfig/Android.bp
index 2da6758..cab126f 100644
--- a/media/audio/aconfig/Android.bp
+++ b/media/audio/aconfig/Android.bp
@@ -120,6 +120,7 @@
"//frameworks/base/api",
"//frameworks/base/core/res",
],
+ exportable: true,
}
aconfig_declarations {
@@ -152,6 +153,20 @@
}
java_aconfig_library {
+ name: "android.media.audio-aconfig-exported-java",
+ aconfig_declarations: "android.media.audio-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+ min_sdk_version: "Tiramisu",
+ mode: "exported",
+ apex_available: [
+ "com.android.btservices",
+ ],
+ visibility: [
+ "//packages/modules/Bluetooth:__subpackages__",
+ ],
+}
+
+java_aconfig_library {
name: "android.media.audiopolicy-aconfig-java",
aconfig_declarations: "android.media.audiopolicy-aconfig",
defaults: ["framework-minus-apex-aconfig-java-defaults"],
diff --git a/media/audio/aconfig/audio_framework.aconfig b/media/audio/aconfig/audio_framework.aconfig
index ae7eb36..1450417 100644
--- a/media/audio/aconfig/audio_framework.aconfig
+++ b/media/audio/aconfig/audio_framework.aconfig
@@ -120,6 +120,14 @@
}
flag {
+ name: "hardening_permission_spa"
+ is_exported: true
+ namespace: "media_audio"
+ description: "Flag for special app access impl for hardening."
+ bug: "376480814"
+}
+
+flag {
name: "iamf_definitions_api"
is_exported: true
namespace: "media_audio"
diff --git a/media/codec2/components/dav1d/C2SoftDav1dDec.cpp b/media/codec2/components/dav1d/C2SoftDav1dDec.cpp
index 4ec26d6..44a8dd1 100644
--- a/media/codec2/components/dav1d/C2SoftDav1dDec.cpp
+++ b/media/codec2/components/dav1d/C2SoftDav1dDec.cpp
@@ -139,8 +139,8 @@
addParameter(DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
.withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
.withFields({
- C2F(mSize, width).inRange(2, 2048, 2),
- C2F(mSize, height).inRange(2, 2048, 2),
+ C2F(mSize, width).inRange(2, 4096, 2),
+ C2F(mSize, height).inRange(2, 4096, 2),
})
.withSetter(MaxPictureSizeSetter, mSize)
.build());
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index 318f093..83cbe47 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -69,8 +69,8 @@
DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
.withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
.withFields({
- C2F(mSize, width).inRange(2, 2048),
- C2F(mSize, height).inRange(2, 2048),
+ C2F(mSize, width).inRange(2, 4096),
+ C2F(mSize, height).inRange(2, 4096),
})
.withSetter(SizeSetter)
.build());
@@ -167,8 +167,8 @@
DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
.withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
.withFields({
- C2F(mSize, width).inRange(2, 2048, 2),
- C2F(mSize, height).inRange(2, 2048, 2),
+ C2F(mSize, width).inRange(2, 4096, 2),
+ C2F(mSize, height).inRange(2, 4096, 2),
})
.withSetter(MaxPictureSizeSetter, mSize)
.build());
diff --git a/media/libaaudio/fuzzer/Android.bp b/media/libaaudio/fuzzer/Android.bp
index a1ed6a0..3b50744 100644
--- a/media/libaaudio/fuzzer/Android.bp
+++ b/media/libaaudio/fuzzer/Android.bp
@@ -62,8 +62,6 @@
"libaudioclient",
"libaudioutils",
"libbase_ndk",
- "libcgrouprc",
- "libcgrouprc_format",
"libcutils",
"libjsoncpp",
"liblog",
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/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index f68b506..bb0deb1 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -95,7 +95,7 @@
// ServiceSingleton to provide interaction with the service notifications and
// binder death notifications.
//
-// If the AF/AP service is unavailable for kServiceWaitMs from ServiceManager,
+// If the AF/AP service is unavailable for kServiceClientWaitMs from ServiceManager,
// ServiceSingleton will return a nullptr service handle resulting in the same dead object error
// as if the service died (which it did, otherwise we'd be returning the cached handle).
//
@@ -129,9 +129,10 @@
//
// TODO(b/375691003) We use 10s as a conservative timeout value, and will tune closer to 3s.
// Too small a value (i.e. less than 1s would churn repeated calls to get the service).
-static constexpr int32_t kServiceWaitMs = 10'000;
+// The value can be tuned by the property audio.service.client_wait_ms.
+static constexpr int32_t kServiceClientWaitMs = 10'000;
-static constexpr const char kServiceWaitProperty[] = "audio.service.wait_ms";
+static constexpr const char kServiceWaitProperty[] = "audio.service.client_wait_ms";
// AudioFlingerServiceTraits is a collection of methods that parameterize the
// ServiceSingleton handler for IAudioFlinger
@@ -172,7 +173,7 @@
}
mediautils::initService<media::IAudioFlingerService, AudioFlingerServiceTraits>();
mWaitMs = std::chrono::milliseconds(
- property_get_int32(kServiceWaitProperty, kServiceWaitMs));
+ property_get_int32(kServiceWaitProperty, kServiceClientWaitMs));
init = true;
}
if (mValid) return mService;
@@ -272,7 +273,8 @@
static inline constinit std::mutex mMutex;
static inline constinit sp<AudioSystem::AudioFlingerClient> mClient GUARDED_BY(mMutex);
static inline constinit sp<IAudioFlinger> mService GUARDED_BY(mMutex);
- static inline constinit std::chrono::milliseconds mWaitMs GUARDED_BY(mMutex) {kServiceWaitMs};
+ static inline constinit std::chrono::milliseconds mWaitMs
+ GUARDED_BY(mMutex) {kServiceClientWaitMs};
static inline constinit bool mValid GUARDED_BY(mMutex) = false;
static inline constinit std::atomic_bool mDisableThreadPoolStart = false;
};
@@ -1014,7 +1016,7 @@
}
mediautils::initService<IAudioPolicyService, AudioPolicyServiceTraits>();
mWaitMs = std::chrono::milliseconds(
- property_get_int32(kServiceWaitProperty, kServiceWaitMs));
+ property_get_int32(kServiceWaitProperty, kServiceClientWaitMs));
init = true;
}
if (mValid) return mService;
@@ -1071,7 +1073,8 @@
static inline constinit sp<AudioSystem::AudioPolicyServiceClient> mClient GUARDED_BY(mMutex);
static inline constinit sp<IAudioPolicyService> mService GUARDED_BY(mMutex);
static inline constinit bool mValid GUARDED_BY(mMutex) = false;
- static inline constinit std::chrono::milliseconds mWaitMs GUARDED_BY(mMutex) {kServiceWaitMs};
+ static inline constinit std::chrono::milliseconds mWaitMs
+ GUARDED_BY(mMutex) {kServiceClientWaitMs};
static inline constinit std::atomic_bool mDisableThreadPoolStart = false;
};
diff --git a/media/libaudioclient/aidl/fuzzer/Android.bp b/media/libaudioclient/aidl/fuzzer/Android.bp
index a215c0b..14e528f 100644
--- a/media/libaudioclient/aidl/fuzzer/Android.bp
+++ b/media/libaudioclient/aidl/fuzzer/Android.bp
@@ -24,8 +24,6 @@
"android.hardware.audio.common@7.0-enums",
"audiopermissioncontroller",
"libaudiomockhal",
- "libcgrouprc",
- "libcgrouprc_format",
"libfakeservicemanager",
"libjsoncpp",
"libmediametricsservice",
diff --git a/media/libaudioclient/fuzzer/Android.bp b/media/libaudioclient/fuzzer/Android.bp
index 8bca8df..65ada70 100644
--- a/media/libaudioclient/fuzzer/Android.bp
+++ b/media/libaudioclient/fuzzer/Android.bp
@@ -37,8 +37,6 @@
"effect-aidl-cpp",
"libaudioclient",
"libbase",
- "libcgrouprc",
- "libcgrouprc_format",
"libcutils",
"libjsoncpp",
"liblog",
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index ddf14a3..3941280 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -107,7 +107,6 @@
"framework-permission-aidl-cpp",
"libaudioutils",
"libbase",
- "libcgrouprc",
"libdl",
"libmedia",
"libmedia_helper",
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index f5dec56..ddef852 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -206,6 +206,7 @@
shared_libs: [
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
+ "com.android.media.audio-aconfig-cc",
"libaudio_aidl_conversion_common_cpp",
"libaudio_aidl_conversion_common_ndk",
"libaudio_aidl_conversion_common_ndk_cpp",
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
index 2753906..ac69b26 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.cpp
@@ -25,10 +25,12 @@
#include <error/expected_utils.h>
#include <aidl/android/media/audio/common/AudioStreamType.h>
#include <android/binder_manager.h>
+#include <com_android_media_audio.h>
#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionEffect.h>
#include <system/audio.h>
#include <system/audio_aidl_utils.h>
+#include <system/audio_effects/effect_uuid.h>
#include <utils/Log.h>
#include "AidlUtils.h"
@@ -68,6 +70,7 @@
std::vector<Descriptor> list;
if (mFactory) {
mFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &list).isOk();
+ filterHalDescriptors(list);
}
return list;
}()),
@@ -180,6 +183,11 @@
AudioUuid aidlUuid =
VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_uuid_t_AudioUuid(*uuid));
+ if (!com_android_media_audio_audio_eraser_effect() && isAudioEraser(aidlUuid)) {
+ ALOGE("%s Audio eraser effect not supported yet", __func__);
+ return BAD_VALUE;
+ }
+
std::shared_ptr<IEffect> aidlEffect;
// Use EffectProxy interface instead of IFactory to create
const bool isProxy = isProxyEffect(aidlUuid);
@@ -367,6 +375,23 @@
return 0;
}
+
+bool EffectsFactoryHalAidl::isAudioEraser(const AudioUuid& uuid) {
+ return uuid == getEffectTypeUuidEraser();
+}
+
+void EffectsFactoryHalAidl::filterHalDescriptors(std::vector<Descriptor>& descs) {
+ if (!com_android_media_audio_audio_eraser_effect()) {
+ descs.erase(std::remove_if(descs.begin(), descs.end(),
+ [](const Descriptor& desc) {
+ return isAudioEraser(desc.common.id.type);
+ }),
+ descs.end());
+ }
+
+ return;
+}
+
} // namespace effect
// When a shared library is built from a static library, even explicit
diff --git a/media/libaudiohal/impl/EffectsFactoryHalAidl.h b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
index 3b8628c..a3cd165 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalAidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalAidl.h
@@ -94,6 +94,11 @@
std::vector<effect_descriptor_t>* descriptors);
bool isProxyEffect(const aidl::android::media::audio::common::AudioUuid& uuid) const;
+
+ static bool isAudioEraser(const aidl::android::media::audio::common::AudioUuid& uuid);
+
+ // filter out descriptors which can not supported by the framework
+ static void filterHalDescriptors(std::vector<Descriptor>& descs);
};
} // namespace effect
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index a544066..efbd682 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1192,6 +1192,19 @@
return new PersistentSurface(bufferProducer, bufferSource);
}
+//static
+status_t MediaCodec::getGloballyAvailableResources(std::vector<GlobalResourceInfo>& resources) {
+ resources.clear();
+ // Make sure codec availability feature is on.
+ if (!android::media::codec::codec_availability()) {
+ return ERROR_UNSUPPORTED;
+ }
+ // TODO: For now this is just an empty function.
+ // The actual implementation should use component store to query the
+ // available resources from hal, and fill in resources with the same.
+ return ERROR_UNSUPPORTED;
+}
+
// GenerateCodecId generates a 64bit Random ID for each codec that is created.
// The Codec ID is generated as:
// - A process-unique random high 32bits
@@ -1298,7 +1311,12 @@
CHECK_EQ(mState, UNINITIALIZED);
mResourceManagerProxy->removeClient();
- flushMediametrics();
+ flushMediametrics(); // this deletes mMetricsHandle
+ // don't keep the last metrics handle around
+ if (mLastMetricsHandle != 0) {
+ mediametrics_delete(mLastMetricsHandle);
+ mLastMetricsHandle = 0;
+ }
// clean any saved metrics info we stored as part of configure()
if (mConfigureMsg != nullptr) {
@@ -1309,7 +1327,7 @@
}
}
-// except for in constructor, called from the looper thread (and therefore mutexed)
+// except for in constructor, called from the looper thread (and therefore not mutexed)
void MediaCodec::initMediametrics() {
if (mMetricsHandle == 0) {
mMetricsHandle = mediametrics_create(kCodecKeyName);
@@ -1335,6 +1353,7 @@
mInputBufferCounter = 0;
}
+ mSubsessionCount = 0;
mLifetimeStartNs = systemTime(SYSTEM_TIME_MONOTONIC);
resetMetricsFields();
}
@@ -1346,6 +1365,17 @@
mReliabilityContextMetrics = ReliabilityContextMetrics();
}
+// always called from the looper thread (and therefore not mutexed)
+void MediaCodec::resetSubsessionMetricsFields() {
+ mBytesEncoded = 0;
+ mFramesEncoded = 0;
+ mFramesInput = 0;
+ mBytesInput = 0;
+ mEarliestEncodedPtsUs = INT64_MAX;
+ mLatestEncodedPtsUs = INT64_MIN;
+}
+
+// always called from the looper thread
void MediaCodec::updateMediametrics() {
if (mMetricsHandle == 0) {
ALOGV("no metrics handle found");
@@ -1710,6 +1740,7 @@
}
}
+// except for in destructor, called from the looper thread
void MediaCodec::flushMediametrics() {
ALOGV("flushMediametrics");
@@ -1723,7 +1754,14 @@
if (mMetricsToUpload && mediametrics_count(mMetricsHandle) > 0) {
mediametrics_selfRecord(mMetricsHandle);
}
- mediametrics_delete(mMetricsHandle);
+ // keep previous metrics handle for subsequent getMetrics() calls.
+ // NOTE: There could be multiple error events, each flushing the metrics.
+ // We keep the last non-empty metrics handle, so getMetrics() in the
+ // next call will get the latest metrics prior to the errors.
+ if (mLastMetricsHandle != 0) {
+ mediametrics_delete(mLastMetricsHandle);
+ }
+ mLastMetricsHandle = mMetricsHandle;
mMetricsHandle = 0;
}
// we no longer have anything pending upload
@@ -1888,7 +1926,10 @@
});
}
- if (mDomain == DOMAIN_VIDEO && (mFlags & kFlagIsEncoder)) {
+ // NOTE: these were erroneously restricted to video encoders, but we want them for all
+ // codecs.
+ if (android::media::codec::provider_->subsession_metrics()
+ || (mDomain == DOMAIN_VIDEO && (mFlags & kFlagIsEncoder))) {
mBytesInput += buffer->size();
mFramesInput++;
}
@@ -1910,12 +1951,15 @@
++mInputBufferCounter;
}
-// when we get a buffer back from the codec
+// when we get a buffer back from the codec, always called from the looper thread
void MediaCodec::statsBufferReceived(int64_t presentationUs, const sp<MediaCodecBuffer> &buffer) {
CHECK_NE(mState, UNINITIALIZED);
- if (mDomain == DOMAIN_VIDEO && (mFlags & kFlagIsEncoder)) {
+ // NOTE: these were erroneously restricted to video encoders, but we want them for all
+ // codecs.
+ if (android::media::codec::provider_->subsession_metrics()
+ || (mDomain == DOMAIN_VIDEO && (mFlags & kFlagIsEncoder))) {
int32_t flags = 0;
(void) buffer->meta()->findInt32("flags", &flags);
@@ -2525,6 +2569,31 @@
return err;
}
+status_t MediaCodec::getRequiredResources(std::vector<InstanceResourceInfo>& resources) {
+ resources.clear();
+ // Make sure codec availability feature is on.
+ if (!android::media::codec::codec_availability()) {
+ return ERROR_UNSUPPORTED;
+ }
+ // Make sure that the codec was configured already.
+ if (mState != CONFIGURED && mState != STARTING && mState != STARTED &&
+ mState != FLUSHING && mState != FLUSHED) {
+ ALOGE("Codec wasn't configured yet!");
+ return INVALID_OPERATION;
+ }
+
+ if (!mRequiredResourceInfo.empty()) {
+ resources = mRequiredResourceInfo;
+ return OK;
+ }
+
+ // TODO: For now this is just an empty function.
+ // The actual implementation should use component interface
+ // (for example, through mCodec->getRequiredDeviceResources) to query the
+ // the required resources for this configuration, and fill in resources with the same.
+ return ERROR_UNSUPPORTED;
+}
+
// Media Format Shaping support
//
@@ -3613,6 +3682,10 @@
updateMediametrics();
results = mediametrics_dup(mMetricsHandle);
updateEphemeralMediametrics(results);
+ } else if (mLastMetricsHandle != 0) {
+ // After error, mMetricsHandle is cleared, but we keep the last
+ // metrics around so that it can be queried by getMetrics().
+ results = mediametrics_dup(mLastMetricsHandle);
} else {
results = mediametrics_dup(mMetricsHandle);
}
@@ -3882,6 +3955,7 @@
return true;
}
+// always called from the looper thread
MediaCodec::DequeueOutputResult MediaCodec::handleDequeueOutputBuffer(
const sp<AReplyToken> &replyID, bool newRequest) {
if (!isExecuting()) {
@@ -3937,6 +4011,9 @@
response->setInt32("flags", flags);
+ // NOTE: we must account the stats for an output buffer only after we
+ // already handled a potential output format change that could have
+ // started a new subsession.
statsBufferReceived(timeUs, buffer);
response->postReply(replyID);
@@ -5841,6 +5918,7 @@
}
}
+// always called from the looper thread
void MediaCodec::handleOutputFormatChangeIfNeeded(const sp<MediaCodecBuffer> &buffer) {
sp<AMessage> format = buffer->format();
if (mOutputFormat == format) {
@@ -5924,6 +6002,24 @@
}
}
}
+
+ // Update the width and the height.
+ int32_t left = 0, top = 0, right = 0, bottom = 0, width = 0, height = 0;
+ bool newSubsession = false;
+ if (android::media::codec::provider_->subsession_metrics()
+ && mOutputFormat->findInt32("width", &width)
+ && mOutputFormat->findInt32("height", &height)
+ && (width != mWidth || height != mHeight)) {
+ // consider a new subsession if the width or height changes.
+ newSubsession = true;
+ }
+ // TODO: properly detect new audio subsession
+
+ // Only consider a new subsession if we already have output (from a previous subsession).
+ if (newSubsession && mMetricsToUpload && mBytesEncoded > 0) {
+ handleStartingANewSubsession();
+ }
+
if (mFlags & kFlagIsAsync) {
onOutputFormatChanged();
} else {
@@ -5931,8 +6027,6 @@
postActivityNotificationIfPossible();
}
- // Update the width and the height.
- int32_t left = 0, top = 0, right = 0, bottom = 0, width = 0, height = 0;
bool resolutionChanged = false;
if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
mWidth = right - left + 1;
@@ -5959,6 +6053,35 @@
updateHdrMetrics(false /* isConfig */);
}
+// always called from the looper thread (and therefore not mutexed)
+void MediaCodec::handleStartingANewSubsession() {
+ // create a new metrics item for the subsession with the new resolution.
+ // TODO: properly account input counts for the previous and the new
+ // subsessions. We only find out that a new subsession started from the
+ // output format, but by that time we already accounted the input counts
+ // to the previous subsession.
+ flushMediametrics(); // this deletes mMetricsHandle, but stores it in mLastMetricsHandle
+
+ // hence mLastMetricsHandle has the metrics item for the previous subsession.
+ if ((mFlags & kFlagIsAsync) && mCallback != nullptr) {
+ sp<AMessage> msg = mCallback->dup();
+ msg->setInt32("callbackID", CB_METRICS_FLUSHED);
+ std::unique_ptr<mediametrics::Item> flushedMetrics(
+ mediametrics::Item::convert(mediametrics_dup(mLastMetricsHandle)));
+ msg->setObject("metrics", new WrapperObject<std::unique_ptr<mediametrics::Item>>(
+ std::move(flushedMetrics)));
+ msg->post();
+ }
+
+ // reuse/continue old metrics item for the new subsession.
+ mMetricsHandle = mediametrics_dup(mLastMetricsHandle);
+ mMetricsToUpload = true;
+ // TODO: configured width/height for the new subsession should be the
+ // previous width/height.
+ mSubsessionCount++;
+ resetSubsessionMetricsFields();
+}
+
void MediaCodec::extractCSD(const sp<AMessage> &format) {
mCSD.clear();
@@ -6959,6 +7082,18 @@
}
}
+void MediaCodec::onRequiredResourcesChanged(
+ const std::vector<InstanceResourceInfo>& resourceInfo) {
+ mRequiredResourceInfo = resourceInfo;
+ // Make sure codec availability feature is on.
+ if (mCallback != nullptr && android::media::codec::codec_availability()) {
+ // Post the callback
+ sp<AMessage> msg = mCallback->dup();
+ msg->setInt32("callbackID", CB_REQUIRED_RESOURCES_CHANGED);
+ msg->post();
+ }
+}
+
void MediaCodec::postActivityNotificationIfPossible() {
if (mActivityNotify == NULL) {
return;
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index b4794f1..df1ebd7 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -130,6 +130,11 @@
* Object at the "metrics" key.
*/
CB_METRICS_FLUSHED = 8,
+
+ /** Callback ID to notify the change in resource requirement
+ * for the codec component.
+ */
+ CB_REQUIRED_RESOURCES_CHANGED = 9,
};
static const pid_t kNoPid = -1;
@@ -149,6 +154,73 @@
static sp<PersistentSurface> CreatePersistentInputSurface();
+ /**
+ * Abstraction for the Global Codec resources.
+ * This encapsulates all the available codec resources on the device.
+ */
+ struct GlobalResourceInfo {
+ /**
+ * Name of the Resource type.
+ */
+ std::string mName;
+ /**
+ * Total count/capacity of resources of this type.
+ */
+ int mCapacity;
+ /**
+ * Available count of this resource type.
+ */
+ int mAvailable;
+
+ GlobalResourceInfo(const std::string& name, int capacity, int available) :
+ mName(name),
+ mCapacity(capacity),
+ mAvailable(available) {}
+
+ GlobalResourceInfo(const GlobalResourceInfo& info) :
+ mName(info.mName),
+ mCapacity(info.mCapacity),
+ mAvailable(info.mAvailable) {}
+ };
+
+ /**
+ * Abstraction for the resources associated with a codec instance.
+ * This encapsulates the required codec resources for a configured codec instance.
+ */
+ struct InstanceResourceInfo {
+ /**
+ * Name of the Resource type.
+ */
+ std::string mName;
+ /**
+ * Required resource count of this type.
+ */
+ int mStaticCount;
+ /**
+ * Per frame resource requirement of this resource type.
+ */
+ int mPerFrameCount;
+
+ InstanceResourceInfo(const std::string& name, int staticCount, int perFrameCount) :
+ mName(name),
+ mStaticCount(staticCount),
+ mPerFrameCount(perFrameCount) {}
+
+ InstanceResourceInfo(const InstanceResourceInfo& info) :
+ mName(info.mName),
+ mStaticCount(info.mStaticCount),
+ mPerFrameCount(info.mPerFrameCount) {}
+ };
+
+ /**
+ * Get a list of Globally available device codec resources.
+ *
+ * It will return INVALID_OPERATION if:
+ * - HAL does not implement codec availability API
+ * - codec_availability feature flag isn't defined.
+ */
+ static status_t getGloballyAvailableResources(std::vector<GlobalResourceInfo>& resources);
+
status_t configure(
const sp<AMessage> &format,
const sp<Surface> &nativeWindow,
@@ -162,6 +234,19 @@
const sp<IDescrambler> &descrambler,
uint32_t flags);
+ /**
+ * Get a list of required codec resources.
+ *
+ * This may only be called after configuring the codec.
+ *
+ * Calling this while the codec wasn't configured, will result in
+ * returning INVALID_OPERATION error code.
+ * It will also return INVALID_OPERATION if:
+ * - HAL does not implement codec availability API
+ * - codec_availability feature flag isn't defined.
+ */
+ status_t getRequiredResources(std::vector<InstanceResourceInfo>& resources);
+
status_t releaseCrypto();
status_t setCallback(const sp<AMessage> &callback);
@@ -491,12 +576,21 @@
Mutex mMetricsLock;
mediametrics_handle_t mMetricsHandle = 0;
+ mediametrics_handle_t mLastMetricsHandle = 0; // only accessed from the looper or destructor
bool mMetricsToUpload = false;
nsecs_t mLifetimeStartNs = 0;
void initMediametrics();
void updateMediametrics();
void flushMediametrics();
void resetMetricsFields();
+
+ // Reset the metrics fields for a new subsession.
+ void resetSubsessionMetricsFields();
+
+ // Start a new subsession (for metrics). This includes flushing the current
+ // metrics, notifying the client and resetting the session fields.
+ void handleStartingANewSubsession();
+
void updateEphemeralMediametrics(mediametrics_handle_t item);
void updateLowLatency(const sp<AMessage> &msg);
void updateCodecImportance(const sp<AMessage>& msg);
@@ -558,6 +652,7 @@
int32_t setOutputSurfaceCount;
int32_t resolutionChangeCount;
} mReliabilityContextMetrics;
+ int32_t mSubsessionCount;
// initial create parameters
AString mInitName;
@@ -678,6 +773,7 @@
void onCryptoError(const sp<AMessage> &msg);
void onError(status_t err, int32_t actionCode, const char *detail = NULL);
void onOutputFormatChanged();
+ void onRequiredResourcesChanged(const std::vector<InstanceResourceInfo>& resourceInfo);
status_t onSetParameters(const sp<AMessage> ¶ms);
@@ -777,6 +873,8 @@
friend class MediaTestHelper;
CodecErrorLog mErrorLog;
+ // Required resource info for this codec.
+ std::vector<InstanceResourceInfo> mRequiredResourceInfo;
DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
};
diff --git a/media/module/extractors/mpeg2/Android.bp b/media/module/extractors/mpeg2/Android.bp
index aa59a0c..63dbcda 100644
--- a/media/module/extractors/mpeg2/Android.bp
+++ b/media/module/extractors/mpeg2/Android.bp
@@ -44,7 +44,6 @@
shared_libs: [
"libbase",
- "libcgrouprc#29",
],
header_libs: [
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 867561a..5fbe48c 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1327,7 +1327,8 @@
// states to reset position info for pcm tracks
if (audio_is_linear_pcm(mFormat)
- && (state == IDLE || state == STOPPED || state == FLUSHED)) {
+ && (state == IDLE || state == STOPPED || state == FLUSHED
+ || state == PAUSED)) {
mFrameMap.reset();
if (!isFastTrack()) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index d22bf49..04ebb57 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -8350,7 +8350,9 @@
VolumeSource vsToDriveAbs = toVolumeSource(groupToDriveAbs);
if (vsToDriveAbs == volumeSource) {
// attenuation is applied by the abs volume controller
- return (index != 0) ? volumeDbMax : volumeDb;
+ // do not mute LE broadcast to allow the secondary device to continue playing
+ return (index != 0 || volumeDevice == AUDIO_DEVICE_OUT_BLE_BROADCAST) ? volumeDbMax
+ : volumeDb;
} else {
IVolumeCurves &curvesAbs = getVolumeCurves(vsToDriveAbs);
int indexAbs = curvesAbs.getVolumeIndex({volumeDevice});
@@ -8765,6 +8767,7 @@
case AUDIO_USAGE_SAFETY:
case AUDIO_USAGE_VEHICLE_STATUS:
case AUDIO_USAGE_ANNOUNCEMENT:
+ case AUDIO_USAGE_SPEAKER_CLEANUP:
break;
default:
return false;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index bdd7cbc..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;
}
@@ -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/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 45b7c3b..6bcc935 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -28,6 +28,7 @@
#include <camera/CameraUtils.h>
#include <camera/StringUtils.h>
#include <com_android_internal_camera_flags.h>
+#include <com_android_window_flags.h>
#include <cutils/properties.h>
#include <gui/Surface.h>
#include <gui/view/Surface.h>
@@ -53,6 +54,7 @@
using namespace camera2;
namespace flags = com::android::internal::camera::flags;
+namespace wm_flags = com::android::window::flags;
// Interface used by CameraService
@@ -134,8 +136,13 @@
// The 'mRotateAndCropMode' value only accounts for the necessary adjustment
// when the display rotates. The sensor orientation still needs to be calculated
// and applied similar to the Camera2 path.
+ using hardware::BnCameraService::ROTATION_OVERRIDE_ROTATION_ONLY;
+ bool enableTransformInverseDisplay = true;
+ if (wm_flags::enable_camera_compat_for_desktop_windowing()) {
+ enableTransformInverseDisplay = (mRotationOverride != ROTATION_OVERRIDE_ROTATION_ONLY);
+ }
CameraUtils::getRotationTransform(staticInfo, OutputConfiguration::MIRROR_MODE_AUTO,
- &mRotateAndCropPreviewTransform);
+ enableTransformInverseDisplay, &mRotateAndCropPreviewTransform);
mStreamingProcessor = new StreamingProcessor(this);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index c1f9204..48f43e6 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -2058,14 +2058,25 @@
int versionCode = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_UPSIDE_DOWN_CAKE;
IPCTransport ipcTransport = parentProvider->getIPCTransport();
- int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
- if (ipcTransport == IPCTransport::AIDL
- && deviceVersion >= CAMERA_DEVICE_API_VERSION_1_3) {
- versionCode = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_VANILLA_ICE_CREAM;
+ auto& c = mCameraCharacteristics;
+ status_t res = OK;
+ if (ipcTransport != IPCTransport::AIDL) {
+ res = c.update(ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION, &versionCode, 1);
+ mSessionConfigQueryVersion = versionCode;
+ return res;
}
- auto& c = mCameraCharacteristics;
- status_t res = c.update(ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION, &versionCode, 1);
+ int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
+ if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_3) {
+ versionCode = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_VANILLA_ICE_CREAM;
+ } else if (deviceVersion >= CAMERA_DEVICE_API_VERSION_1_4) {
+ if (flags::feature_combination_baklava()) {
+ versionCode = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_BAKLAVA;
+ } else {
+ versionCode = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_VANILLA_ICE_CREAM;
+ }
+ }
+ res = c.update(ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION, &versionCode, 1);
mSessionConfigQueryVersion = versionCode;
return res;
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 3bad975..803df40 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -88,6 +88,7 @@
#define CAMERA_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0)
#define CAMERA_DEVICE_API_VERSION_1_2 HARDWARE_DEVICE_API_VERSION(1, 2)
#define CAMERA_DEVICE_API_VERSION_1_3 HARDWARE_DEVICE_API_VERSION(1, 3)
+#define CAMERA_DEVICE_API_VERSION_1_4 HARDWARE_DEVICE_API_VERSION(1, 4)
#define CAMERA_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0)
#define CAMERA_DEVICE_API_VERSION_3_1 HARDWARE_DEVICE_API_VERSION(3, 1)
#define CAMERA_DEVICE_API_VERSION_3_2 HARDWARE_DEVICE_API_VERSION(3, 2)
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 6260b9b..c6434a5 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -58,6 +58,7 @@
#include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
#include <android/hardware/camera2/ICameraDeviceUser.h>
#include <com_android_internal_camera_flags.h>
+#include <com_android_window_flags.h>
#include "CameraService.h"
#include "aidl/android/hardware/graphics/common/Dataspace.h"
@@ -83,6 +84,8 @@
using namespace android::hardware::cameraservice::utils::conversion::aidl;
namespace flags = com::android::internal::camera::flags;
+namespace wm_flags = com::android::window::flags;
+
namespace android {
Camera3Device::Camera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
@@ -2894,7 +2897,7 @@
res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
hasAppCallback, minExpectedDuration, maxExpectedDuration, isFixedFps, physicalCameraIds,
isStillCapture, isZslCapture, rotateAndCropAuto, autoframingAuto, cameraIdsWithZoom,
- useZoomRatio, requestTimeNs, outputSurfaces));
+ requestTimeNs, useZoomRatio, outputSurfaces));
if (res < 0) return res;
if (mInFlightMap.size() == 1) {
@@ -5820,7 +5823,13 @@
status_t Camera3Device::deriveAndSetTransformLocked(
Camera3OutputStreamInterface& stream, int mirrorMode, int surfaceId) {
int transform = -1;
- int res = CameraUtils::getRotationTransform(mDeviceInfo, mirrorMode, &transform);
+ bool enableTransformInverseDisplay = true;
+ using hardware::ICameraService::ROTATION_OVERRIDE_ROTATION_ONLY;
+ if (wm_flags::enable_camera_compat_for_desktop_windowing()) {
+ enableTransformInverseDisplay = (mRotationOverride != ROTATION_OVERRIDE_ROTATION_ONLY);
+ }
+ int res = CameraUtils::getRotationTransform(mDeviceInfo, mirrorMode,
+ enableTransformInverseDisplay, &transform);
if (res != OK) {
return res;
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index 66ffc98..78f1698 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -687,7 +687,8 @@
if (orientation.count > 0) {
int32_t transform;
ret = CameraUtils::getRotationTransform(deviceInfo->second,
- OutputConfiguration::MIRROR_MODE_AUTO, &transform);
+ OutputConfiguration::MIRROR_MODE_AUTO,
+ /*transformInverseDisplay*/true, &transform);
if (ret == OK) {
// It is possible for camera providers to return the capture
// results after the processed frames. In such scenario, we will
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).