Merge "Enforce CREATE_VIRTUAL_DEVICE permission for virtual camera service" into main
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index 409a930..8078cea 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -22,6 +22,7 @@
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraInjectionCallback;
import android.hardware.camera2.ICameraInjectionSession;
+import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.VendorTagDescriptor;
import android.hardware.camera2.params.VendorTagDescriptorCache;
import android.hardware.camera2.utils.ConcurrentCameraIdCombination;
@@ -261,4 +262,18 @@
const int DEVICE_STATE_FOLDED = 4;
const int DEVICE_STATE_LAST_FRAMEWORK_BIT = 0x80000000; // 1 << 31;
+ // Create a CaptureRequest metadata based on template id
+ CameraMetadataNative createDefaultRequest(@utf8InCpp String cameraId, int templateId);
+
+ /**
+ * Check whether a particular session configuration with optional session parameters
+ * has camera device support.
+ *
+ * @param cameraId The camera id to query session configuration on
+ * @param sessionConfiguration Specific session configuration to be verified.
+ * @return true - in case the stream combination is supported.
+ * false - in case there is no device support.
+ */
+ boolean isSessionConfigurationWithParametersSupported(@utf8InCpp String cameraId,
+ in SessionConfiguration sessionConfiguration);
}
diff --git a/camera/camera2/SessionConfiguration.cpp b/camera/camera2/SessionConfiguration.cpp
index 7cf6087..2f1f22d 100644
--- a/camera/camera2/SessionConfiguration.cpp
+++ b/camera/camera2/SessionConfiguration.cpp
@@ -22,10 +22,13 @@
#include <camera/camera2/SessionConfiguration.h>
#include <camera/camera2/OutputConfiguration.h>
+#include <com_android_internal_camera_flags.h>
#include <binder/Parcel.h>
namespace android {
+namespace flags = com::android::internal::camera::flags;
+
status_t SessionConfiguration::readFromParcel(const android::Parcel* parcel) {
status_t err = OK;
int operatingMode = 0;
@@ -67,6 +70,22 @@
return err;
}
+ bool hasSessionParameters = false;
+ CameraMetadata settings;
+ if (flags::feature_combination_query()) {
+ if ((err = parcel->readBool(&hasSessionParameters)) != OK) {
+ ALOGE("%s: Failed to read hasSessionParameters flag from parcel", __FUNCTION__);
+ return err;
+ }
+
+ if (hasSessionParameters) {
+ if ((err = settings.readFromParcel(parcel)) != OK) {
+ ALOGE("%s: Failed to read metadata flag from parcel", __FUNCTION__);
+ return err;
+ }
+ }
+ }
+
mOperatingMode = operatingMode;
mInputWidth = inputWidth;
mInputHeight = inputHeight;
@@ -75,7 +94,10 @@
for (auto& stream : outputStreams) {
mOutputStreams.push_back(stream);
}
-
+ if (flags::feature_combination_query()) {
+ mHasSessionParameters = hasSessionParameters;
+ mSessionParameters = std::move(settings);
+ }
return err;
}
@@ -103,6 +125,16 @@
err = parcel->writeParcelableVector(mOutputStreams);
if (err != OK) return err;
+ if (flags::feature_combination_query()) {
+ err = parcel->writeBool(mHasSessionParameters);
+ if (err != OK) return err;
+
+ if (mHasSessionParameters) {
+ err = mSessionParameters.writeToParcel(parcel);
+ if (err != OK) return err;
+ }
+ }
+
return OK;
}
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index 501b48b..f7deda1 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -13,6 +13,14 @@
description: "Introduces a new concert mode camera extension type"
bug: "297083874"
}
+
+flag {
+ namespace: "camera_platform"
+ name: "feature_combination_query"
+ description: "Query feature combination support and session specific characteristics"
+ bug: "309627704"
+}
+
flag {
namespace: "camera_platform"
name: "log_ultrawide_usage"
@@ -54,11 +62,3 @@
description: "Enable session parameter injection via reconfiguration"
bug: "308984721"
}
-
-flag {
- namespace: "camera_platform"
- name: "camera_ae_mode_low_light_boost"
- description: "An AE mode that enables increased brightening in low light scenes"
- bug: "312803148"
-}
-
diff --git a/camera/include/camera/camera2/SessionConfiguration.h b/camera/include/camera/camera2/SessionConfiguration.h
index 29913f6..120bf9e 100644
--- a/camera/include/camera/camera2/SessionConfiguration.h
+++ b/camera/include/camera/camera2/SessionConfiguration.h
@@ -18,6 +18,7 @@
#define ANDROID_HARDWARE_CAMERA2_SESSIONCONFIGURATION_H
#include <binder/Parcelable.h>
+#include <camera/CameraMetadata.h>
namespace android {
@@ -39,6 +40,8 @@
int getInputFormat() const { return mInputFormat; }
int getOperatingMode() const { return mOperatingMode; }
bool inputIsMultiResolution() const { return mInputIsMultiResolution; }
+ bool hasSessionParameters() const { return mHasSessionParameters; }
+ const CameraMetadata& getSessionParameters() const { return mSessionParameters; }
virtual status_t writeToParcel(android::Parcel* parcel) const override;
virtual status_t readFromParcel(const android::Parcel* parcel) override;
@@ -111,6 +114,8 @@
std::vector<OutputConfiguration> mOutputStreams;
int mInputWidth, mInputHeight, mInputFormat, mOperatingMode;
bool mInputIsMultiResolution = false;
+ bool mHasSessionParameters = false;
+ CameraMetadata mSessionParameters;
};
} // namespace params
} // namespace camera2
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 86b9e99..3a483cc 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -2244,39 +2244,6 @@
*/
ACAMERA_CONTROL_AUTOFRAMING_STATE = // byte (acamera_metadata_enum_android_control_autoframing_state_t)
ACAMERA_CONTROL_START + 54,
- /**
- * <p>The operating luminance range of low light boost measured in lux (lx).</p>
- *
- * <p>Type: float[2]</p>
- *
- * <p>This tag may appear in:
- * <ul>
- * <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
- * </ul></p>
- *
- */
- ACAMERA_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE = // float[2]
- ACAMERA_CONTROL_START + 55,
- /**
- * <p>Current state of the low light boost AE mode.</p>
- *
- * <p>Type: byte (acamera_metadata_enum_android_control_low_light_boost_state_t)</p>
- *
- * <p>This tag may appear in:
- * <ul>
- * <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
- * </ul></p>
- *
- * <p>When low light boost is enabled by setting the AE mode to
- * 'ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY', it can dynamically apply a low light
- * boost when the light level threshold is exceeded.</p>
- * <p>This state indicates when low light boost is 'ACTIVE' and applied. Similarly, it can
- * indicate when it is not being applied by returning 'INACTIVE'.</p>
- * <p>This key will be absent from the CaptureResult if AE mode is not set to
- * 'ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY.</p>
- */
- ACAMERA_CONTROL_LOW_LIGHT_BOOST_STATE = // byte (acamera_metadata_enum_android_control_low_light_boost_state_t)
- ACAMERA_CONTROL_START + 56,
ACAMERA_CONTROL_END,
/**
@@ -8247,44 +8214,6 @@
*/
ACAMERA_CONTROL_AE_MODE_ON_EXTERNAL_FLASH = 5,
- /**
- * <p>Like 'ON' but applies additional brightness boost in low light scenes.</p>
- * <p>When the scene lighting conditions are within the range defined by
- * ACAMERA_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE this mode will apply additional
- * brightness boost.</p>
- * <p>This mode will automatically adjust the intensity of low light boost applied
- * according to the scene lighting conditions. A darker scene will receive more boost
- * while a brighter scene will receive less boost.</p>
- * <p>This mode can ignore the set target frame rate to allow more light to be captured
- * which can result in choppier motion. The frame rate can extend to lower than the
- * ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES but will not go below 10 FPS. This mode
- * can also increase the sensor sensitivity gain which can result in increased luma
- * and chroma noise. The sensor sensitivity gain can extend to higher values beyond
- * ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE. This mode may also apply additional
- * processing to recover details in dark and bright areas of the image,and noise
- * reduction at high sensitivity gain settings to manage the trade-off between light
- * sensitivity and capture noise.</p>
- * <p>This mode is restricted to two output surfaces. One output surface type can either
- * be SurfaceView or TextureView. Another output surface type can either be MediaCodec
- * or MediaRecorder. This mode cannot be used with a target FPS range higher than 30
- * FPS.</p>
- * <p>If the session configuration is not supported, the AE mode reported in the
- * CaptureResult will be 'ON' instead of 'ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY'.</p>
- * <p>The application can observe the CapturerResult field
- * ACAMERA_CONTROL_LOW_LIGHT_BOOST_STATE to determine when low light boost is 'ACTIVE' or
- * 'INACTIVE'.</p>
- * <p>The low light boost is 'ACTIVE' once the scene lighting condition is less than the
- * upper bound lux value defined by ACAMERA_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE.
- * This mode will be 'INACTIVE' once the scene lighting condition is greater than the
- * upper bound lux value defined by ACAMERA_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE.</p>
- *
- * @see ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES
- * @see ACAMERA_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE
- * @see ACAMERA_CONTROL_LOW_LIGHT_BOOST_STATE
- * @see ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE
- */
- ACAMERA_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY = 6,
-
} acamera_metadata_enum_android_control_ae_mode_t;
// ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
@@ -9286,20 +9215,6 @@
} acamera_metadata_enum_android_control_autoframing_state_t;
-// ACAMERA_CONTROL_LOW_LIGHT_BOOST_STATE
-typedef enum acamera_metadata_enum_acamera_control_low_light_boost_state {
- /**
- * <p>The AE mode 'ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY' is enabled but not applied.</p>
- */
- ACAMERA_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE = 0,
-
- /**
- * <p>The AE mode 'ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY' is enabled and applied.</p>
- */
- ACAMERA_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE = 1,
-
-} acamera_metadata_enum_android_control_low_light_boost_state_t;
-
// ACAMERA_EDGE_MODE
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 30c385c..60b814e 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -562,7 +562,7 @@
GET_DEVICE_DESC_CONNECTION(IP_V4));
append_AudioDeviceDescription(pairs,
AUDIO_DEVICE_IN_BUS, AUDIO_DEVICE_OUT_BUS,
- AudioDeviceType::IN_DEVICE, AudioDeviceType::OUT_DEVICE);
+ AudioDeviceType::IN_BUS, AudioDeviceType::OUT_BUS);
append_AudioDeviceDescription(pairs,
AUDIO_DEVICE_IN_PROXY, AUDIO_DEVICE_OUT_PROXY,
AudioDeviceType::IN_AFE_PROXY, AudioDeviceType::OUT_AFE_PROXY,
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.h b/media/libaaudio/src/binding/AAudioBinderClient.h
index 8faf6e8..66d3295 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.h
+++ b/media/libaaudio/src/binding/AAudioBinderClient.h
@@ -203,12 +203,12 @@
private:
android::Mutex mServiceLock;
- std::shared_ptr<AAudioServiceInterface> mAdapter;
+ std::shared_ptr<AAudioServiceInterface> mAdapter PT_GUARDED_BY(mServiceLock);
android::sp<AAudioClient> mAAudioClient;
- std::shared_ptr<AAudioServiceInterface> getAAudioService();
+ std::shared_ptr<AAudioServiceInterface> getAAudioService() EXCLUDES(mServiceLock);
- void dropAAudioService();
+ void dropAAudioService() EXCLUDES(mServiceLock);
};
diff --git a/media/libaaudio/src/client/AudioEndpoint.h b/media/libaaudio/src/client/AudioEndpoint.h
index 01dd05a..2c23e1d 100644
--- a/media/libaaudio/src/client/AudioEndpoint.h
+++ b/media/libaaudio/src/client/AudioEndpoint.h
@@ -117,8 +117,6 @@
bool mFreeRunning{false};
android::fifo_counter_t mDataReadCounter{0}; // only used if free-running
android::fifo_counter_t mDataWriteCounter{0}; // only used if free-running
-
- std::mutex mDataQueueLock;
};
} // namespace aaudio
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index ca0db0d..f431da8 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -64,6 +64,9 @@
#define LOG_TIMESTAMPS 0
+// Minimum number of bursts to use when sample rate conversion is used.
+#define MIN_SAMPLE_RATE_CONVERSION_NUM_BURSTS 3
+
AudioStreamInternal::AudioStreamInternal(AAudioServiceInterface &serviceInterface, bool inService)
: AudioStream()
, mClockModel()
@@ -910,6 +913,12 @@
numBursts = 1;
}
+ // Set a minimum number of bursts if sample rate conversion is used.
+ if ((getSampleRate() != getDeviceSampleRate()) &&
+ (numBursts < MIN_SAMPLE_RATE_CONVERSION_NUM_BURSTS)) {
+ numBursts = MIN_SAMPLE_RATE_CONVERSION_NUM_BURSTS;
+ }
+
if (mAudioEndpoint) {
// Clip against the actual size from the endpoint.
int32_t actualFramesDevice = 0;
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index f2f5cac..49a63c4 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -172,7 +172,7 @@
return createThread_l(periodNanoseconds, threadProc, threadArg);
}
- aaudio_result_t joinThread(void **returnArg);
+ aaudio_result_t joinThread(void **returnArg) EXCLUDES(mStreamLock);
virtual aaudio_result_t registerThread() {
return AAUDIO_OK;
@@ -424,7 +424,7 @@
}
// This is used by the AudioManager to duck and mute the stream when changing audio focus.
- void setDuckAndMuteVolume(float duckAndMuteVolume);
+ void setDuckAndMuteVolume(float duckAndMuteVolume) EXCLUDES(mStreamLock);
float getDuckAndMuteVolume() const {
return mDuckAndMuteVolume;
@@ -459,11 +459,11 @@
mPlayerBase->unregisterWithAudioManager();
}
- aaudio_result_t systemStart();
+ aaudio_result_t systemStart() EXCLUDES(mStreamLock);
- aaudio_result_t systemPause();
+ aaudio_result_t systemPause() EXCLUDES(mStreamLock);
- aaudio_result_t safeFlush();
+ aaudio_result_t safeFlush() EXCLUDES(mStreamLock);
/**
* This is called when an app calls AAudioStream_requestStop();
@@ -474,14 +474,14 @@
/**
* This is called internally when an app callback returns AAUDIO_CALLBACK_RESULT_STOP.
*/
- aaudio_result_t systemStopInternal();
+ aaudio_result_t systemStopInternal() EXCLUDES(mStreamLock);
/**
* Safely RELEASE a stream after taking mStreamLock and checking
* to make sure we are not being called from a callback.
* @return AAUDIO_OK or a negative error
*/
- aaudio_result_t safeRelease();
+ aaudio_result_t safeRelease() EXCLUDES(mStreamLock);
/**
* Safely RELEASE and CLOSE a stream after taking mStreamLock and checking
@@ -490,7 +490,7 @@
*/
aaudio_result_t safeReleaseClose();
- aaudio_result_t safeReleaseCloseInternal();
+ aaudio_result_t safeReleaseCloseInternal() EXCLUDES(mStreamLock);
protected:
diff --git a/media/libaaudio/tests/test_various.cpp b/media/libaaudio/tests/test_various.cpp
index b68fc7b..eea8783 100644
--- a/media/libaaudio/tests/test_various.cpp
+++ b/media/libaaudio/tests/test_various.cpp
@@ -829,7 +829,7 @@
void waitForFinished() {
std::unique_lock <std::mutex> aLock(mutex);
- conditionVariable.wait(aLock, [=] { return finished; });
+ conditionVariable.wait(aLock, [this] { return finished; });
}
// For signalling foreground test when callback finished
diff --git a/media/libaudiofoundation/include/media/AudioPort.h b/media/libaudiofoundation/include/media/AudioPort.h
index 77e58ed..5786f7f 100644
--- a/media/libaudiofoundation/include/media/AudioPort.h
+++ b/media/libaudiofoundation/include/media/AudioPort.h
@@ -48,7 +48,10 @@
audio_port_role_t getRole() const { return mRole; }
virtual void setFlags(uint32_t flags);
- uint32_t getFlags() const { return useInputChannelMask() ? mFlags.input : mFlags.output; }
+ uint32_t getFlags() const {
+ return useInputChannelMask() ? static_cast<uint32_t>(mFlags.input)
+ : static_cast<uint32_t>(mFlags.output);
+ }
void setGains(const AudioGains &gains) { mGains = gains; }
const AudioGains &getGains() const { return mGains; }
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 2c8e50b..cb45f54 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -361,7 +361,7 @@
DeviceVector moduleDevices = hwModule->getAllDevices();
auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress, encodedFormat);
- // Prevent overwritting moduleDevice address if connected device does not have the same
+ // Prevent overwriting moduleDevice address if connected device does not have the same
// address (since getDevice with empty address ignores match on address), use dynamic device
if (moduleDevice && allowToCreate &&
(!moduleDevice->address().empty() &&
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index f25bca3..4883a09 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -106,7 +106,7 @@
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
"android.hardware.camera.provider@2.7",
- "android.hardware.camera.provider-V2-ndk",
+ "android.hardware.camera.provider-V3-ndk",
"libaidlcommonsupport",
"libbinderthreadstateutils",
"libcameraservice_device_independent",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 8add05e..feb9c75 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -84,6 +84,7 @@
#include "utils/TagMonitor.h"
#include "utils/CameraThreadState.h"
#include "utils/CameraServiceProxyWrapper.h"
+#include "utils/SessionConfigurationUtils.h"
namespace {
const char* kPermissionServiceName = "permission";
@@ -95,8 +96,10 @@
namespace android {
-using binder::Status;
using namespace camera3;
+using namespace camera3::SessionConfigurationUtils;
+
+using binder::Status;
using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
using frameworks::cameraservice::service::implementation::AidlCameraService;
using hardware::ICamera;
@@ -861,6 +864,136 @@
return Status::ok();
}
+Status CameraService::createDefaultRequest(const std::string& unresolvedCameraId, int templateId,
+ /* out */
+ hardware::camera2::impl::CameraMetadataNative* request) {
+ ATRACE_CALL();
+
+ if (!flags::feature_combination_query()) {
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
+ "Camera subsystem doesn't support this method!");
+ }
+ if (!mInitialized) {
+ ALOGE("%s: Camera subsystem is not available", __FUNCTION__);
+ logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
+ return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available");
+ }
+
+ const std::string cameraId = resolveCameraId(unresolvedCameraId,
+ CameraThreadState::getCallingUid());
+
+ binder::Status res;
+ if (request == nullptr) {
+ res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
+ "Camera %s: Error creating default request", cameraId.c_str());
+ return res;
+ }
+ camera_request_template_t tempId = camera_request_template_t::CAMERA_TEMPLATE_COUNT;
+ res = SessionConfigurationUtils::mapRequestTemplateFromClient(
+ cameraId, templateId, &tempId);
+ if (!res.isOk()) {
+ ALOGE("%s: Camera %s: failed to map request Template %d",
+ __FUNCTION__, cameraId.c_str(), templateId);
+ return res;
+ }
+
+ if (shouldRejectSystemCameraConnection(cameraId)) {
+ return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to create default"
+ "request for system only device %s: ", cameraId.c_str());
+ }
+
+ // Check for camera permissions
+ if (!hasCameraPermissions()) {
+ return STATUS_ERROR(ERROR_PERMISSION_DENIED,
+ "android.permission.CAMERA needed to call"
+ "createDefaultRequest");
+ }
+
+ CameraMetadata metadata;
+ status_t err = mCameraProviderManager->createDefaultRequest(cameraId, tempId, &metadata);
+ if (err == OK) {
+ request->swap(metadata);
+ } else if (err == BAD_VALUE) {
+ res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ "Camera %s: Template ID %d is invalid or not supported: %s (%d)",
+ cameraId.c_str(), templateId, strerror(-err), err);
+ } else {
+ res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
+ "Camera %s: Error creating default request for template %d: %s (%d)",
+ cameraId.c_str(), templateId, strerror(-err), err);
+ }
+ return res;
+}
+
+Status CameraService::isSessionConfigurationWithParametersSupported(
+ const std::string& unresolvedCameraId,
+ const SessionConfiguration& sessionConfiguration,
+ /*out*/
+ bool* supported) {
+ ATRACE_CALL();
+
+ if (!flags::feature_combination_query()) {
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
+ "Camera subsystem doesn't support this method!");
+ }
+ if (!mInitialized) {
+ ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
+ logServiceError("Camera subsystem is not available", ERROR_DISCONNECTED);
+ return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available");
+ }
+
+ const std::string cameraId = resolveCameraId(unresolvedCameraId,
+ CameraThreadState::getCallingUid());
+ if (supported == nullptr) {
+ std::string msg = fmt::sprintf("Camera %s: Invalid 'support' input!",
+ unresolvedCameraId.c_str());
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
+ }
+
+ if (shouldRejectSystemCameraConnection(cameraId)) {
+ return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to query "
+ "session configuration with parameters support for system only device %s: ",
+ cameraId.c_str());
+ }
+
+ // Check for camera permissions
+ if (!hasCameraPermissions()) {
+ return STATUS_ERROR(ERROR_PERMISSION_DENIED,
+ "android.permission.CAMERA needed to call"
+ "isSessionConfigurationWithParametersSupported");
+ }
+
+ *supported = false;
+ status_t ret = mCameraProviderManager->isSessionConfigurationSupported(cameraId.c_str(),
+ sessionConfiguration, /*mOverrideForPerfClass*/false, /*checkSessionParams*/true,
+ supported);
+ binder::Status res;
+ switch (ret) {
+ case OK:
+ // Expected, do nothing.
+ break;
+ case INVALID_OPERATION: {
+ std::string msg = fmt::sprintf(
+ "Camera %s: Session configuration query not supported!",
+ cameraId.c_str());
+ ALOGD("%s: %s", __FUNCTION__, msg.c_str());
+ res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
+ }
+
+ break;
+ default: {
+ std::string msg = fmt::sprintf( "Camera %s: Error: %s (%d)", cameraId.c_str(),
+ strerror(-ret), ret);
+ ALOGE("%s: %s", __FUNCTION__, msg.c_str());
+ res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ msg.c_str());
+ }
+ }
+
+ return res;
+}
+
Status CameraService::parseCameraIdRemapping(
const hardware::CameraIdRemapping& cameraIdRemapping,
/* out */ TCameraIdRemapping* cameraIdRemappingMap) {
@@ -3042,6 +3175,22 @@
return Status::ok();
}
+bool CameraService::hasCameraPermissions() const {
+ int callingPid = CameraThreadState::getCallingPid();
+ int callingUid = CameraThreadState::getCallingUid();
+ AttributionSourceState attributionSource{};
+ attributionSource.pid = callingPid;
+ attributionSource.uid = callingUid;
+ bool res = checkPermission(std::string(), sCameraPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+
+ bool hasPermission = ((callingPid == getpid()) || res);
+ if (!hasPermission) {
+ ALOGE("%s: pid %d doesn't have camera permissions", __FUNCTION__, callingPid);
+ }
+ return hasPermission;
+}
+
Status CameraService::isConcurrentSessionConfigurationSupported(
const std::vector<CameraIdAndSessionConfiguration>& cameraIdsAndSessionConfigurations,
int targetSdkVersion, /*out*/bool* isSupported) {
@@ -3057,15 +3206,7 @@
}
// Check for camera permissions
- int callingPid = CameraThreadState::getCallingPid();
- int callingUid = CameraThreadState::getCallingUid();
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- bool checkPermissionForCamera = checkPermission(std::string(),
- sCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
- if ((callingPid != getpid()) && !checkPermissionForCamera) {
- ALOGE("%s: pid %d doesn't have camera permissions", __FUNCTION__, callingPid);
+ if (!hasCameraPermissions()) {
return STATUS_ERROR(ERROR_PERMISSION_DENIED,
"android.permission.CAMERA needed to call"
"isConcurrentSessionConfigurationSupported");
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 6819136..cabac17 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -234,6 +234,16 @@
virtual binder::Status remapCameraIds(const hardware::CameraIdRemapping&
cameraIdRemapping);
+ virtual binder::Status createDefaultRequest(const std::string& cameraId, int templateId,
+ /*out*/
+ hardware::camera2::impl::CameraMetadataNative* request);
+
+ virtual binder::Status isSessionConfigurationWithParametersSupported(
+ const std::string& cameraId,
+ const SessionConfiguration& sessionConfiguration,
+ /*out*/
+ bool* supported);
+
// Extra permissions checks
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags);
@@ -662,6 +672,7 @@
bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId, int callingPid,
int callingUid) const;
+ bool hasCameraPermissions() const;
/**
* Typesafe version of device status, containing both the HAL-layer and the service interface-
* layer values.
diff --git a/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h b/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h
index e403b97..b193be2 100644
--- a/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h
+++ b/services/camera/libcameraservice/aidl/VndkVersionMetadataTags.h
@@ -77,7 +77,6 @@
{34, {
ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
- ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE,
ANDROID_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL,
ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL,
ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL,
@@ -109,7 +108,6 @@
{34, {
ANDROID_CONTROL_AUTOFRAMING,
ANDROID_CONTROL_AUTOFRAMING_STATE,
- ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
ANDROID_CONTROL_SETTINGS_OVERRIDE,
ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
ANDROID_EXTENSION_CURRENT_TYPE,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 28f7054..095d425 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -742,13 +742,6 @@
return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
}
- auto operatingMode = sessionConfiguration.getOperatingMode();
- res = SessionConfigurationUtils::checkOperatingMode(operatingMode, mDevice->info(),
- mCameraIdStr);
- if (!res.isOk()) {
- return res;
- }
-
if (status == nullptr) {
std::string msg = fmt::sprintf( "Camera %s: Invalid status!", mCameraIdStr.c_str());
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
@@ -756,11 +749,9 @@
}
*status = false;
- camera3::metadataGetter getMetadata = [this](const std::string &id,
- bool /*overrideForPerfClass*/) {
- return mDevice->infoPhysical(id);};
ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.c_str(),
- sessionConfiguration, mOverrideForPerfClass, getMetadata, status);
+ sessionConfiguration, mOverrideForPerfClass, /*checkSessionParams*/false,
+ status);
switch (ret) {
case OK:
// Expected, do nothing.
@@ -1396,7 +1387,9 @@
status_t err;
camera_request_template_t tempId = camera_request_template_t::CAMERA_TEMPLATE_COUNT;
- if (!(res = mapRequestTemplate(templateId, &tempId)).isOk()) return res;
+ res = SessionConfigurationUtils::mapRequestTemplateFromClient(
+ mCameraIdStr, templateId, &tempId);
+ if (!res.isOk()) return res;
CameraMetadata metadata;
if ( (err = mDevice->createDefaultRequest(tempId, &metadata) ) == OK &&
@@ -2245,44 +2238,6 @@
return CameraUtils::getRotationTransform(staticInfo, mirrorMode, transform);
}
-binder::Status CameraDeviceClient::mapRequestTemplate(int templateId,
- camera_request_template_t* tempId /*out*/) {
- binder::Status ret = binder::Status::ok();
-
- if (tempId == nullptr) {
- ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
- "Camera %s: Invalid template argument", mCameraIdStr.c_str());
- return ret;
- }
- switch(templateId) {
- case ICameraDeviceUser::TEMPLATE_PREVIEW:
- *tempId = camera_request_template_t::CAMERA_TEMPLATE_PREVIEW;
- break;
- case ICameraDeviceUser::TEMPLATE_RECORD:
- *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_RECORD;
- break;
- case ICameraDeviceUser::TEMPLATE_STILL_CAPTURE:
- *tempId = camera_request_template_t::CAMERA_TEMPLATE_STILL_CAPTURE;
- break;
- case ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT:
- *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_SNAPSHOT;
- break;
- case ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG:
- *tempId = camera_request_template_t::CAMERA_TEMPLATE_ZERO_SHUTTER_LAG;
- break;
- case ICameraDeviceUser::TEMPLATE_MANUAL:
- *tempId = camera_request_template_t::CAMERA_TEMPLATE_MANUAL;
- break;
- default:
- ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
- "Camera %s: Template ID %d is invalid or not supported",
- mCameraIdStr.c_str(), templateId);
- return ret;
- }
-
- return ret;
-}
-
const CameraMetadata &CameraDeviceClient::getStaticInfo(const std::string &cameraId) {
if (mDevice->getId() == cameraId) {
return mDevice->info();
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 5dea3aa..b2c9626 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -312,10 +312,6 @@
/*out*/SurfaceMap* surfaceMap, /*out*/Vector<int32_t>* streamIds,
/*out*/int32_t* currentStreamId);
- // Utility method that maps AIDL request templates.
- binder::Status mapRequestTemplate(int templateId,
- camera_request_template_t* tempId /*out*/);
-
// IGraphicsBufferProducer binder -> Stream ID + Surface ID for output streams
KeyedVector<sp<IBinder>, StreamSurfaceId> mStreamMap;
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 01199af..983b2c1 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -35,6 +35,7 @@
#include "binder/Status.h"
#include "FrameProducer.h"
#include "utils/IPCTransport.h"
+#include "utils/SessionConfigurationUtils.h"
#include "CameraOfflineSessionBase.h"
@@ -42,17 +43,6 @@
namespace camera3 {
-typedef enum camera_request_template {
- CAMERA_TEMPLATE_PREVIEW = 1,
- CAMERA_TEMPLATE_STILL_CAPTURE = 2,
- CAMERA_TEMPLATE_VIDEO_RECORD = 3,
- CAMERA_TEMPLATE_VIDEO_SNAPSHOT = 4,
- CAMERA_TEMPLATE_ZERO_SHUTTER_LAG = 5,
- CAMERA_TEMPLATE_MANUAL = 6,
- CAMERA_TEMPLATE_COUNT,
- CAMERA_VENDOR_TEMPLATE_START = 0x40000000
-} camera_request_template_t;
-
typedef enum camera_stream_configuration_mode {
CAMERA_STREAM_CONFIGURATION_NORMAL_MODE = 0,
CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE = 1,
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index adcb523..fbb5e1b 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -397,7 +397,7 @@
status_t CameraProviderManager::isSessionConfigurationSupported(const std::string& id,
const SessionConfiguration &configuration, bool overrideForPerfClass,
- metadataGetter getMetadata, bool *status /*out*/) const {
+ bool checkSessionParams, bool *status /*out*/) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo == nullptr) {
@@ -405,7 +405,41 @@
}
return deviceInfo->isSessionConfigurationSupported(configuration,
- overrideForPerfClass, getMetadata, status);
+ overrideForPerfClass, checkSessionParams, status);
+}
+
+status_t CameraProviderManager::createDefaultRequest(const std::string& cameraId,
+ camera_request_template_t templateId,
+ CameraMetadata* metadata) const {
+ ATRACE_CALL();
+ if (templateId <= 0 || templateId >= CAMERA_TEMPLATE_COUNT) {
+ return BAD_VALUE;
+ }
+
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+ auto deviceInfo = findDeviceInfoLocked(cameraId);
+ if (deviceInfo == nullptr) {
+ return NAME_NOT_FOUND;
+ }
+
+ camera_metadata_t *rawRequest;
+ status_t res = deviceInfo->createDefaultRequest(templateId,
+ &rawRequest);
+
+ if (res == BAD_VALUE) {
+ ALOGI("%s: template %d is not supported on this camera device",
+ __FUNCTION__, templateId);
+ return res;
+ } else if (res != OK) {
+ ALOGE("Unable to construct request template %d: %s (%d)",
+ templateId, strerror(-res), res);
+ return res;
+ }
+
+ set_camera_metadata_vendor_id(rawRequest, deviceInfo->mProviderTagid);
+ metadata->acquire(rawRequest);
+
+ return OK;
}
status_t CameraProviderManager::getCameraIdIPCTransport(const std::string &id,
@@ -1011,6 +1045,20 @@
}
}
+CameraMetadata CameraProviderManager::ProviderInfo::DeviceInfo3::deviceInfo(
+ const std::string &id) {
+ if (id.empty()) {
+ return mCameraCharacteristics;
+ } else {
+ if (mPhysicalCameraCharacteristics.find(id) != mPhysicalCameraCharacteristics.end()) {
+ return mPhysicalCameraCharacteristics.at(id);
+ } else {
+ ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, id.c_str());
+ return mCameraCharacteristics;
+ }
+ }
+}
+
SystemCameraKind CameraProviderManager::ProviderInfo::DeviceInfo3::getSystemCameraKind() {
camera_metadata_entry_t entryCap;
entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
@@ -1757,6 +1805,26 @@
return res;
}
+status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addSessionConfigQueryVersionTag() {
+ sp<ProviderInfo> parentProvider = mParentProvider.promote();
+ if (parentProvider == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ 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 = c.update(ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION, &versionCode, 1);
+
+ return res;
+}
+
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::removeAvailableKeys(
CameraMetadata& c, const std::vector<uint32_t>& keys, uint32_t keyTag) {
status_t res = OK;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index fd04854..6142a71 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -87,6 +87,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_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)
@@ -299,12 +300,20 @@
int targetSdkVersion, bool *isSupported);
std::vector<std::unordered_set<std::string>> getConcurrentCameraIds() const;
+
+ /**
+ * Create a default capture request metadata for a camera and a specific
+ * template.
+ */
+ status_t createDefaultRequest(const std::string& id,
+ camera3::camera_request_template_t templateId,
+ hardware::camera2::impl::CameraMetadataNative* request) const;
/**
* Check for device support of specific stream combination.
*/
status_t isSessionConfigurationSupported(const std::string& id,
const SessionConfiguration &configuration,
- bool overrideForPerfClass, camera3::metadataGetter getMetadata,
+ bool overrideForPerfClass, bool checkSessionParams,
bool *status /*out*/) const;
/**
@@ -619,12 +628,17 @@
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &/*configuration*/,
bool /*overrideForPerfClass*/,
- camera3::metadataGetter /*getMetadata*/,
+ bool /*checkSessionParams*/,
bool * /*status*/) {
return INVALID_OPERATION;
}
virtual status_t filterSmallJpegSizes() = 0;
virtual void notifyDeviceStateChange(int64_t /*newState*/) {}
+ virtual status_t createDefaultRequest(
+ camera3::camera_request_template_t /*templateId*/,
+ camera_metadata_t** /*metadata*/) {
+ return INVALID_OPERATION;
+ }
DeviceInfo(const std::string& name, const metadata_vendor_id_t tagId,
const std::string &id, const hardware::hidl_version& version,
@@ -675,10 +689,6 @@
bool overrideToPortrait) override;
virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
CameraMetadata *characteristics) const override;
- virtual status_t isSessionConfigurationSupported(
- const SessionConfiguration &configuration, bool /*overrideForPerfClass*/,
- camera3::metadataGetter /*getMetadata*/,
- bool *status /*out*/) = 0;
virtual status_t filterSmallJpegSizes() override;
virtual void notifyDeviceStateChange(
int64_t newState) override;
@@ -712,6 +722,7 @@
status_t addAutoframingTags();
status_t addPreCorrectionActiveArraySize();
status_t addReadoutTimestampTag(bool readoutTimestampSupported = true);
+ status_t addSessionConfigQueryVersionTag();
static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag,
android_pixel_format_t format,
@@ -736,6 +747,8 @@
std::vector<int64_t>* stallDurations,
const camera_metadata_entry& halStreamConfigs,
const camera_metadata_entry& halStreamDurations);
+
+ CameraMetadata deviceInfo(const std::string &id);
};
protected:
std::string mType;
@@ -887,8 +900,6 @@
std::vector<std::string>& systemCameraDeviceIds) const;
status_t usbDeviceDetached(const std::string &usbDeviceId);
- ndk::ScopedAStatus onAidlRegistration(const std::string& in_name,
- const ::ndk::SpAIBinder& in_binder);
static bool isVirtualCameraHalEnabled();
};
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index c2b8bf4..a64c9d7 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -386,7 +386,7 @@
std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
AidlProviderInfo::initializeDeviceInfo(
const std::string &name, const metadata_vendor_id_t tagId,
- const std::string &id, uint16_t minorVersion) {
+ const std::string &id, uint16_t /*minorVersion*/) {
::ndk::ScopedAStatus status;
auto cameraInterface = startDeviceInterface(name);
@@ -411,9 +411,18 @@
conflictName = id;
}
+ int32_t interfaceVersion = 0;
+ status = cameraInterface->getInterfaceVersion(&interfaceVersion);
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to obtain interface version for camera device %s: %s", __FUNCTION__,
+ id.c_str(), status.getMessage());
+ return nullptr;
+ }
+
return std::unique_ptr<DeviceInfo3>(
- new AidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
- this, mProviderPublicCameraIds, cameraInterface));
+ new AidlDeviceInfo3(name, tagId, id, static_cast<uint16_t>(interfaceVersion),
+ HalToFrameworkResourceCost(resourceCost), this,
+ mProviderPublicCameraIds, cameraInterface));
}
status_t AidlProviderInfo::reCacheConcurrentStreamingCameraIdsLocked() {
@@ -604,6 +613,14 @@
mHasFlashUnit = false;
}
+ if (flags::feature_combination_query()) {
+ res = addSessionConfigQueryVersionTag();
+ if (OK != res) {
+ ALOGE("%s: Unable to add sessionConfigurationQueryVersion tag: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ }
+ }
+
camera_metadata_entry entry =
mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
if (entry.count == 1) {
@@ -766,13 +783,24 @@
status_t AidlProviderInfo::AidlDeviceInfo3::isSessionConfigurationSupported(
const SessionConfiguration &configuration, bool overrideForPerfClass,
- camera3::metadataGetter getMetadata, bool *status) {
+ bool checkSessionParams, bool *status) {
+
+ auto operatingMode = configuration.getOperatingMode();
+
+ auto res = SessionConfigurationUtils::checkOperatingMode(operatingMode,
+ mCameraCharacteristics, mId);
+ if (!res.isOk()) {
+ return UNKNOWN_ERROR;
+ }
camera::device::StreamConfiguration streamConfiguration;
bool earlyExit = false;
+ camera3::metadataGetter getMetadata = [this](const std::string &id,
+ bool /*overrideForPerfClass*/) {return this->deviceInfo(id);};
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
mId, mCameraCharacteristics, mCompositeJpegRDisabled, getMetadata,
- mPhysicalIds, streamConfiguration, overrideForPerfClass, &earlyExit);
+ mPhysicalIds, streamConfiguration, overrideForPerfClass, mProviderTagid,
+ checkSessionParams, &earlyExit);
if (!bRes.isOk()) {
return UNKNOWN_ERROR;
@@ -790,8 +818,25 @@
return DEAD_OBJECT;
}
- ::ndk::ScopedAStatus ret =
- interface->isStreamCombinationSupported(streamConfiguration, status);
+ ::ndk::ScopedAStatus ret;
+ if (checkSessionParams) {
+ // Only interface version 1_3 or greater supports
+ // isStreamCombinationWIthSettingsSupported.
+ int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_1_3) {
+ ALOGI("%s: Camera device version (major %d, minor %d) doesn't support querying of "
+ "session configuration!", __FUNCTION__, mVersion.get_major(),
+ mVersion.get_minor());
+ return INVALID_OPERATION;
+ }
+ if (flags::feature_combination_query()) {
+ ret = interface->isStreamCombinationWithSettingsSupported(streamConfiguration, status);
+ } else {
+ return INVALID_OPERATION;
+ }
+ } else {
+ ret = interface->isStreamCombinationSupported(streamConfiguration, status);
+ }
if (!ret.isOk()) {
*status = false;
ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.getMessage());
@@ -801,6 +846,60 @@
}
+status_t AidlProviderInfo::AidlDeviceInfo3::createDefaultRequest(
+ camera3::camera_request_template_t templateId, camera_metadata_t** metadata) {
+ const std::shared_ptr<camera::device::ICameraDevice> interface =
+ startDeviceInterface();
+
+ if (interface == nullptr) {
+ return DEAD_OBJECT;
+ }
+
+ int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_1_3) {
+ ALOGI("%s: Camera device minor version 0x%x doesn't support creating "
+ " default request!", __FUNCTION__, mVersion.get_minor());
+ return INVALID_OPERATION;
+ }
+
+ aidl::android::hardware::camera::device::CameraMetadata request;
+
+ using aidl::android::hardware::camera::device::RequestTemplate;
+ RequestTemplate id;
+ status_t res = SessionConfigurationUtils::mapRequestTemplateToAidl(
+ templateId, &id);
+ if (res != OK) {
+ return res;
+ }
+
+ if (!flags::feature_combination_query()) {
+ return INVALID_OPERATION;
+ }
+
+ auto err = interface->constructDefaultRequestSettings(id, &request);
+ if (!err.isOk()) {
+ ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
+ return AidlProviderInfo::mapToStatusT(err);
+ }
+ const camera_metadata *r =
+ reinterpret_cast<const camera_metadata_t*>(request.metadata.data());
+ size_t expectedSize = request.metadata.size();
+ int ret = validate_camera_metadata_structure(r, &expectedSize);
+ if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
+ *metadata = clone_camera_metadata(r);
+ if (*metadata == nullptr) {
+ ALOGE("%s: Unable to clone camera metadata received from HAL",
+ __FUNCTION__);
+ res = UNKNOWN_ERROR;
+ }
+ } else {
+ ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+ res = UNKNOWN_ERROR;
+ }
+
+ return res;
+}
+
status_t AidlProviderInfo::convertToAidlHALStreamCombinationAndCameraIdsLocked(
const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
const std::set<std::string>& perfClassPrimaryCameraIds,
@@ -840,7 +939,8 @@
cameraId, deviceInfo,
mManager->isCompositeJpegRDisabledLocked(cameraId), getMetadata,
physicalCameraIds, streamConfiguration,
- overrideForPerfClass, &shouldExit);
+ overrideForPerfClass, mProviderTagid,
+ /*checkSessionParams*/false, &shouldExit);
if (!bStatus.isOk()) {
ALOGE("%s: convertToHALStreamCombination failed", __FUNCTION__);
return INVALID_OPERATION;
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
index 90bc627..cc5101a 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
@@ -107,8 +107,6 @@
struct AidlDeviceInfo3 : public CameraProviderManager::ProviderInfo::DeviceInfo3 {
- //TODO: fix init
- const hardware::hidl_version mVersion = hardware::hidl_version{3, 2};
std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
mSavedInterface = nullptr;
@@ -129,9 +127,13 @@
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &/*configuration*/,
- bool overrideForPerfClass, camera3::metadataGetter /*getMetadata*/,
+ bool overrideForPerfClass, bool checkSessionParams,
bool *status/*status*/);
+ virtual status_t createDefaultRequest(
+ camera3::camera_request_template_t templateId,
+ camera_metadata_t** metadata) override;
+
std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
startDeviceInterface();
};
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index e4bd503..d2643c1 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -853,13 +853,21 @@
status_t HidlProviderInfo::HidlDeviceInfo3::isSessionConfigurationSupported(
const SessionConfiguration &configuration, bool overrideForPerfClass,
- metadataGetter getMetadata, bool *status) {
+ bool checkSessionParams, bool *status) {
+
+ if (checkSessionParams) {
+ // HIDL device doesn't support checking session parameters
+ return INVALID_OPERATION;
+ }
hardware::camera::device::V3_7::StreamConfiguration configuration_3_7;
bool earlyExit = false;
+ camera3::metadataGetter getMetadata = [this](const std::string &id,
+ bool /*overrideForPerfClass*/) {return this->deviceInfo(id);};
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
mId, mCameraCharacteristics, getMetadata, mPhysicalIds,
- configuration_3_7, overrideForPerfClass, &earlyExit);
+ configuration_3_7, overrideForPerfClass, mProviderTagid,
+ &earlyExit);
if (!bRes.isOk()) {
return UNKNOWN_ERROR;
@@ -961,7 +969,7 @@
cameraIdAndSessionConfig.mSessionConfiguration,
cameraId, deviceInfo, getMetadata,
physicalCameraIds, streamConfiguration,
- overrideForPerfClass, &shouldExit);
+ overrideForPerfClass, mProviderTagid, &shouldExit);
if (!bStatus.isOk()) {
ALOGE("%s: convertToHALStreamCombination failed", __FUNCTION__);
return INVALID_OPERATION;
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
index fa6f4d4..f53db7f 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
@@ -105,7 +105,7 @@
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &/*configuration*/,
- bool overrideForPerfClass, camera3::metadataGetter getMetadata,
+ bool overrideForPerfClass, bool checkSessionParams,
bool *status/*status*/);
sp<hardware::camera::device::V3_2::ICameraDevice> startDeviceInterface();
};
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 8006ee1..0a5b0c4 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -75,6 +75,7 @@
#include <tuple>
using namespace android::camera3;
+using namespace android::camera3::SessionConfigurationUtils;
using namespace android::hardware::camera;
namespace flags = com::android::internal::camera::flags;
@@ -1365,62 +1366,52 @@
return filterParamsAndConfigureLocked(sessionParams, operatingMode);
}
-status_t Camera3Device::filterParamsAndConfigureLocked(const CameraMetadata& sessionParams,
+status_t Camera3Device::filterParamsAndConfigureLocked(const CameraMetadata& params,
int operatingMode) {
- //Filter out any incoming session parameters
- const CameraMetadata params(sessionParams);
+ CameraMetadata filteredParams;
+ SessionConfigurationUtils::filterParameters(params, mDeviceInfo, mVendorTagId, filteredParams);
+
camera_metadata_entry_t availableSessionKeys = mDeviceInfo.find(
ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
- CameraMetadata filteredParams(availableSessionKeys.count);
- camera_metadata_t *meta = const_cast<camera_metadata_t *>(
- filteredParams.getAndLock());
- set_camera_metadata_vendor_id(meta, mVendorTagId);
- filteredParams.unlock(meta);
- if (availableSessionKeys.count > 0) {
- bool rotateAndCropSessionKey = false;
- bool autoframingSessionKey = false;
- for (size_t i = 0; i < availableSessionKeys.count; i++) {
- camera_metadata_ro_entry entry = params.find(
- availableSessionKeys.data.i32[i]);
- if (entry.count > 0) {
- filteredParams.update(entry);
+
+ bool rotateAndCropSessionKey = false;
+ bool autoframingSessionKey = false;
+ for (size_t i = 0; i < availableSessionKeys.count; i++) {
+ if (ANDROID_SCALER_ROTATE_AND_CROP == availableSessionKeys.data.i32[i]) {
+ rotateAndCropSessionKey = true;
+ }
+ if (ANDROID_CONTROL_AUTOFRAMING == availableSessionKeys.data.i32[i]) {
+ autoframingSessionKey = true;
+ }
+ }
+
+ if (rotateAndCropSessionKey || autoframingSessionKey) {
+ sp<CaptureRequest> request = new CaptureRequest();
+ PhysicalCameraSettings settingsList;
+ settingsList.metadata = filteredParams;
+ request->mSettingsList.push_back(settingsList);
+
+ if (rotateAndCropSessionKey) {
+ auto rotateAndCropEntry = filteredParams.find(ANDROID_SCALER_ROTATE_AND_CROP);
+ if (rotateAndCropEntry.count > 0 &&
+ rotateAndCropEntry.data.u8[0] == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
+ request->mRotateAndCropAuto = true;
+ } else {
+ request->mRotateAndCropAuto = false;
}
- if (ANDROID_SCALER_ROTATE_AND_CROP == availableSessionKeys.data.i32[i]) {
- rotateAndCropSessionKey = true;
- }
- if (ANDROID_CONTROL_AUTOFRAMING == availableSessionKeys.data.i32[i]) {
- autoframingSessionKey = true;
+
+ overrideAutoRotateAndCrop(request, mOverrideToPortrait, mRotateAndCropOverride);
+ }
+
+ if (autoframingSessionKey) {
+ auto autoframingEntry = filteredParams.find(ANDROID_CONTROL_AUTOFRAMING);
+ if (autoframingEntry.count > 0 &&
+ autoframingEntry.data.u8[0] == ANDROID_CONTROL_AUTOFRAMING_AUTO) {
+ overrideAutoframing(request, mAutoframingOverride);
}
}
- if (rotateAndCropSessionKey || autoframingSessionKey) {
- sp<CaptureRequest> request = new CaptureRequest();
- PhysicalCameraSettings settingsList;
- settingsList.metadata = filteredParams;
- request->mSettingsList.push_back(settingsList);
-
- if (rotateAndCropSessionKey) {
- auto rotateAndCropEntry = filteredParams.find(ANDROID_SCALER_ROTATE_AND_CROP);
- if (rotateAndCropEntry.count > 0 &&
- rotateAndCropEntry.data.u8[0] == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
- request->mRotateAndCropAuto = true;
- } else {
- request->mRotateAndCropAuto = false;
- }
-
- overrideAutoRotateAndCrop(request, mOverrideToPortrait, mRotateAndCropOverride);
- }
-
- if (autoframingSessionKey) {
- auto autoframingEntry = filteredParams.find(ANDROID_CONTROL_AUTOFRAMING);
- if (autoframingEntry.count > 0 &&
- autoframingEntry.data.u8[0] == ANDROID_CONTROL_AUTOFRAMING_AUTO) {
- overrideAutoframing(request, mAutoframingOverride);
- }
- }
-
- filteredParams = request->mSettingsList.begin()->metadata;
- }
+ filteredParams = request->mSettingsList.begin()->metadata;
}
return configureStreamsLocked(operatingMode, filteredParams);
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
index c90fad2..97475f0 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -851,33 +851,15 @@
ATRACE_NAME("CameraAidlHal::constructDefaultRequestSettings");
using aidl::android::hardware::camera::device::RequestTemplate;
if (!valid()) return INVALID_OPERATION;
- status_t res = OK;
RequestTemplate id;
- aidl::android::hardware::camera::device::CameraMetadata request;
- switch (templateId) {
- case CAMERA_TEMPLATE_PREVIEW:
- id = RequestTemplate::PREVIEW;
- break;
- case CAMERA_TEMPLATE_STILL_CAPTURE:
- id = RequestTemplate::STILL_CAPTURE;
- break;
- case CAMERA_TEMPLATE_VIDEO_RECORD:
- id = RequestTemplate::VIDEO_RECORD;
- break;
- case CAMERA_TEMPLATE_VIDEO_SNAPSHOT:
- id = RequestTemplate::VIDEO_SNAPSHOT;
- break;
- case CAMERA_TEMPLATE_ZERO_SHUTTER_LAG:
- id = RequestTemplate::ZERO_SHUTTER_LAG;
- break;
- case CAMERA_TEMPLATE_MANUAL:
- id = RequestTemplate::MANUAL;
- break;
- default:
- // Unknown template ID, or this HAL is too old to support it
- return BAD_VALUE;
+ status_t res = SessionConfigurationUtils::mapRequestTemplateToAidl(
+ templateId, &id);
+ if (res != OK) {
+ return res;
}
+
+ aidl::android::hardware::camera::device::CameraMetadata request;
auto err = mAidlSession->constructDefaultRequestSettings(id, &request);
if (!err.isOk()) {
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
index efc58b4..9dd657c 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
@@ -49,7 +49,7 @@
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
"android.hardware.camera.provider@2.7",
- "android.hardware.camera.provider-V2-ndk",
+ "android.hardware.camera.provider-V3-ndk",
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.3",
diff --git a/services/camera/libcameraservice/tests/Android.bp b/services/camera/libcameraservice/tests/Android.bp
index e9ecc86..5072edd 100644
--- a/services/camera/libcameraservice/tests/Android.bp
+++ b/services/camera/libcameraservice/tests/Android.bp
@@ -62,7 +62,7 @@
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
"android.hardware.camera.provider@2.7",
- "android.hardware.camera.provider-V2-ndk",
+ "android.hardware.camera.provider-V3-ndk",
"libcameraservice",
"libgmock",
"libflagtest",
diff --git a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
index afc8b94..467707e 100644
--- a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
@@ -299,6 +299,16 @@
::ndk::ScopedAStatus getTorchStrengthLevel(int32_t*) override {
return ndk::ScopedAStatus::ok();
}
+ ::ndk::ScopedAStatus constructDefaultRequestSettings(
+ ::aidl::android::hardware::camera::device::RequestTemplate,
+ ::aidl::android::hardware::camera::device::CameraMetadata*) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus isStreamCombinationWithSettingsSupported(
+ const ::aidl::android::hardware::camera::device::StreamConfiguration&,
+ bool*) override {
+ return ndk::ScopedAStatus::ok();
+ }
};
/**
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index f7257e3..3be8e15 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -34,6 +34,7 @@
using android::camera3::OutputStreamInfo;
using android::camera3::OutputStreamInfo;
using android::hardware::camera2::ICameraDeviceUser;
+using aidl::android::hardware::camera::device::RequestTemplate;
namespace android {
namespace camera3 {
@@ -682,7 +683,8 @@
bool isCompositeJpegRDisabled,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
- bool overrideForPerfClass, bool *earlyExit) {
+ bool overrideForPerfClass, metadata_vendor_id_t vendorTagId,
+ bool checkSessionParams, bool *earlyExit) {
using SensorPixelMode = aidl::android::hardware::camera::metadata::SensorPixelMode;
auto operatingMode = sessionConfiguration.getOperatingMode();
binder::Status res = checkOperatingMode(operatingMode, deviceInfo,
@@ -875,6 +877,21 @@
}
}
}
+
+ if (checkSessionParams) {
+ const CameraMetadata &deviceInfo = getMetadata(logicalCameraId,
+ /*overrideForPerfClass*/false);
+ CameraMetadata filteredParams;
+
+ filterParameters(sessionConfiguration.getSessionParameters(), deviceInfo,
+ vendorTagId, filteredParams);
+
+ camera_metadata_t* metadata = const_cast<camera_metadata_t*>(filteredParams.getAndLock());
+ uint8_t *metadataP = reinterpret_cast<uint8_t*>(metadata);
+ streamConfiguration.sessionParams.metadata.assign(metadataP,
+ metadataP + get_camera_metadata_size(metadata));
+ }
+
return binder::Status::ok();
}
@@ -1049,6 +1066,92 @@
return targetSdkVersion >= SDK_VERSION_S && isPerfClassPrimaryCamera;
}
+binder::Status mapRequestTemplateFromClient(const std::string& cameraId, int templateId,
+ camera_request_template_t* tempId /*out*/) {
+ binder::Status ret = binder::Status::ok();
+
+ if (tempId == nullptr) {
+ ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ "Camera %s: Invalid template argument", cameraId.c_str());
+ return ret;
+ }
+ switch(templateId) {
+ case ICameraDeviceUser::TEMPLATE_PREVIEW:
+ *tempId = camera_request_template_t::CAMERA_TEMPLATE_PREVIEW;
+ break;
+ case ICameraDeviceUser::TEMPLATE_RECORD:
+ *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_RECORD;
+ break;
+ case ICameraDeviceUser::TEMPLATE_STILL_CAPTURE:
+ *tempId = camera_request_template_t::CAMERA_TEMPLATE_STILL_CAPTURE;
+ break;
+ case ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT:
+ *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_SNAPSHOT;
+ break;
+ case ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG:
+ *tempId = camera_request_template_t::CAMERA_TEMPLATE_ZERO_SHUTTER_LAG;
+ break;
+ case ICameraDeviceUser::TEMPLATE_MANUAL:
+ *tempId = camera_request_template_t::CAMERA_TEMPLATE_MANUAL;
+ break;
+ default:
+ ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
+ "Camera %s: Template ID %d is invalid or not supported",
+ cameraId.c_str(), templateId);
+ return ret;
+ }
+
+ return ret;
+}
+
+status_t mapRequestTemplateToAidl(camera_request_template_t templateId,
+ RequestTemplate* id /*out*/) {
+ switch (templateId) {
+ case CAMERA_TEMPLATE_PREVIEW:
+ *id = RequestTemplate::PREVIEW;
+ break;
+ case CAMERA_TEMPLATE_STILL_CAPTURE:
+ *id = RequestTemplate::STILL_CAPTURE;
+ break;
+ case CAMERA_TEMPLATE_VIDEO_RECORD:
+ *id = RequestTemplate::VIDEO_RECORD;
+ break;
+ case CAMERA_TEMPLATE_VIDEO_SNAPSHOT:
+ *id = RequestTemplate::VIDEO_SNAPSHOT;
+ break;
+ case CAMERA_TEMPLATE_ZERO_SHUTTER_LAG:
+ *id = RequestTemplate::ZERO_SHUTTER_LAG;
+ break;
+ case CAMERA_TEMPLATE_MANUAL:
+ *id = RequestTemplate::MANUAL;
+ break;
+ default:
+ // Unknown template ID, or this HAL is too old to support it
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
+void filterParameters(const CameraMetadata& src, const CameraMetadata& deviceInfo,
+ int vendorTagId, CameraMetadata& dst) {
+ const CameraMetadata params(src);
+ camera_metadata_ro_entry_t availableSessionKeys = deviceInfo.find(
+ ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
+ CameraMetadata filteredParams(availableSessionKeys.count);
+ camera_metadata_t *meta = const_cast<camera_metadata_t *>(
+ filteredParams.getAndLock());
+ set_camera_metadata_vendor_id(meta, vendorTagId);
+ filteredParams.unlock(meta);
+ for (size_t i = 0; i < availableSessionKeys.count; i++) {
+ camera_metadata_ro_entry entry = params.find(
+ availableSessionKeys.data.i32[i]);
+ if (entry.count > 0) {
+ filteredParams.update(entry);
+ }
+ }
+ dst = std::move(filteredParams);
+}
+
} // namespace SessionConfigurationUtils
} // namespace camera3
} // namespace android
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 79d80ea..29e3eca 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -48,6 +48,17 @@
namespace android {
namespace camera3 {
+typedef enum camera_request_template {
+ CAMERA_TEMPLATE_PREVIEW = 1,
+ CAMERA_TEMPLATE_STILL_CAPTURE = 2,
+ CAMERA_TEMPLATE_VIDEO_RECORD = 3,
+ CAMERA_TEMPLATE_VIDEO_SNAPSHOT = 4,
+ CAMERA_TEMPLATE_ZERO_SHUTTER_LAG = 5,
+ CAMERA_TEMPLATE_MANUAL = 6,
+ CAMERA_TEMPLATE_COUNT,
+ CAMERA_VENDOR_TEMPLATE_START = 0x40000000
+} camera_request_template_t;
+
typedef std::function<CameraMetadata (const std::string &, bool overrideForPerfClass)>
metadataGetter;
@@ -144,7 +155,8 @@
bool isCompositeJpegRDisabled, metadataGetter getMetadata,
const std::vector<std::string> &physicalCameraIds,
aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
- bool overrideForPerfClass, bool *earlyExit);
+ bool overrideForPerfClass, metadata_vendor_id_t vendorTagId,
+ bool checkSessionParams, bool *earlyExit);
StreamConfigurationPair getStreamConfigurationPair(const CameraMetadata &metadata);
@@ -157,6 +169,16 @@
const std::set<std::string>& perfClassPrimaryCameraIds, const std::string& cameraId,
int32_t targetSdkVersion);
+// Utility method that maps AIDL request templates.
+binder::Status mapRequestTemplateFromClient(const std::string& cameraId, int templateId,
+ camera_request_template_t* tempId /*out*/);
+
+status_t mapRequestTemplateToAidl(camera_request_template_t templateId,
+ aidl::android::hardware::camera::device::RequestTemplate* tempId /*out*/);
+
+void filterParameters(const CameraMetadata& src, const CameraMetadata& deviceInfo,
+ int vendorTagId, CameraMetadata& dst);
+
constexpr int32_t MAX_SURFACES_PER_STREAM = 4;
constexpr int32_t ROUNDING_WIDTH_CAP = 1920;
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
index cf93d3b..bf8ea84 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
@@ -108,11 +108,12 @@
const std::string &logicalCameraId, const CameraMetadata &deviceInfo,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
- bool overrideForPerfClass, bool *earlyExit) {
+ bool overrideForPerfClass, metadata_vendor_id_t vendorTagId, bool *earlyExit) {
aidl::android::hardware::camera::device::StreamConfiguration aidlStreamConfiguration;
auto ret = convertToHALStreamCombination(sessionConfiguration, logicalCameraId, deviceInfo,
false /*isCompositeJpegRDisabled*/, getMetadata, physicalCameraIds,
- aidlStreamConfiguration, overrideForPerfClass, earlyExit);
+ aidlStreamConfiguration, overrideForPerfClass, vendorTagId,
+ /*checkSessionParams*/false, earlyExit);
if (!ret.isOk()) {
return ret;
}
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
index eae2e30..bc37470 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
@@ -37,7 +37,8 @@
const std::string &cameraId, const CameraMetadata &deviceInfo,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
- bool overrideForPerfClass, bool *earlyExit);
+ bool overrideForPerfClass, metadata_vendor_id_t vendorTagId,
+ bool *earlyExit);
// Utility function to convert a V3_7::StreamConfiguration to
// V3_4::StreamConfiguration. Return false if the original V3_7 configuration cannot
diff --git a/services/camera/virtualcamera/Android.bp b/services/camera/virtualcamera/Android.bp
index 8d4a476..cb4e10f 100644
--- a/services/camera/virtualcamera/Android.bp
+++ b/services/camera/virtualcamera/Android.bp
@@ -27,7 +27,7 @@
static_libs: [
"android.hardware.camera.common@1.0-helper",
"android.hardware.camera.common-V1-ndk",
- "android.hardware.camera.device-V3-ndk",
+ "android.hardware.camera.device-V2-ndk",
"android.hardware.camera.metadata-V2-ndk",
"android.hardware.camera.provider-V2-ndk",
"libaidlcommonsupport",
diff --git a/services/camera/virtualcamera/VirtualCameraDevice.cc b/services/camera/virtualcamera/VirtualCameraDevice.cc
index f5fa16e..ec72ee3 100644
--- a/services/camera/virtualcamera/VirtualCameraDevice.cc
+++ b/services/camera/virtualcamera/VirtualCameraDevice.cc
@@ -143,6 +143,7 @@
.setControlAwbRegions({kDefaultEmptyControlRegion})
.setControlAeCompensationRange(0, 1)
.setControlAeCompensationStep(camera_metadata_rational_t{0, 1})
+ .setControlZoomRatioRange(/*min=*/1.0, /*max=*/1.0)
.setMaxJpegSize(kMaxJpegSize)
.setAvailableRequestKeys({ANDROID_CONTROL_AF_MODE})
.setAvailableResultKeys({ANDROID_CONTROL_AF_MODE})
diff --git a/services/camera/virtualcamera/VirtualCameraRenderThread.cc b/services/camera/virtualcamera/VirtualCameraRenderThread.cc
index 8a2db1c..8621160 100644
--- a/services/camera/virtualcamera/VirtualCameraRenderThread.cc
+++ b/services/camera/virtualcamera/VirtualCameraRenderThread.cc
@@ -24,6 +24,7 @@
#include <mutex>
#include <thread>
+#include "GLES/gl.h"
#include "VirtualCameraSessionContext.h"
#include "aidl/android/hardware/camera/common/Status.h"
#include "aidl/android/hardware/camera/device/BufferStatus.h"
@@ -271,9 +272,9 @@
}
auto status = streamConfig->format == PixelFormat::BLOB
- ? renderIntoBlobStreamBuffer(
- reqBuffer.getStreamId(), reqBuffer.getBufferId(),
- streamConfig->bufferSize, reqBuffer.getFence())
+ ? renderIntoBlobStreamBuffer(reqBuffer.getStreamId(),
+ reqBuffer.getBufferId(),
+ reqBuffer.getFence())
: renderIntoImageStreamBuffer(reqBuffer.getStreamId(),
reqBuffer.getBufferId(),
reqBuffer.getFence());
@@ -354,17 +355,21 @@
}
ndk::ScopedAStatus VirtualCameraRenderThread::renderIntoBlobStreamBuffer(
- const int streamId, const int bufferId, const size_t bufferSize,
- sp<Fence> fence) {
+ const int streamId, const int bufferId, sp<Fence> fence) {
ALOGV("%s", __func__);
- sp<GraphicBuffer> gBuffer = mEglSurfaceTexture->getCurrentBuffer();
- if (gBuffer == nullptr) {
- // Most probably nothing was yet written to input surface if we reached this.
- ALOGE("%s: Cannot fetch most recent buffer from SurfaceTexture", __func__);
- return cameraStatus(Status::INTERNAL_ERROR);
- }
std::shared_ptr<AHardwareBuffer> hwBuffer =
mSessionContext.fetchHardwareBuffer(streamId, bufferId);
+ if (hwBuffer == nullptr) {
+ ALOGE("%s: Failed to fetch hardware buffer %d for streamId %d", __func__,
+ bufferId, streamId);
+ return cameraStatus(Status::INTERNAL_ERROR);
+ }
+
+ std::optional<Stream> stream = mSessionContext.getStreamConfig(streamId);
+ if (!stream.has_value()) {
+ ALOGE("%s, failed to fetch information about stream %d", __func__, streamId);
+ return cameraStatus(Status::INTERNAL_ERROR);
+ }
AHardwareBuffer_Planes planes_info;
@@ -377,27 +382,36 @@
return cameraStatus(Status::INTERNAL_ERROR);
}
- android_ycbcr ycbcr;
- status_t status =
- gBuffer->lockYCbCr(AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, &ycbcr);
- ALOGV("Locked buffers");
- if (status != NO_ERROR) {
- AHardwareBuffer_unlock(hwBuffer.get(), nullptr);
- ALOGE("%s: Failed to lock graphic buffer: %d", __func__, status);
- return cameraStatus(Status::INTERNAL_ERROR);
- }
+ sp<GraphicBuffer> gBuffer = mEglSurfaceTexture->getCurrentBuffer();
+ bool compressionSuccess = true;
+ if (gBuffer != nullptr) {
+ android_ycbcr ycbcr;
+ status_t status =
+ gBuffer->lockYCbCr(AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, &ycbcr);
+ ALOGV("Locked buffers");
+ if (status != NO_ERROR) {
+ AHardwareBuffer_unlock(hwBuffer.get(), nullptr);
+ ALOGE("%s: Failed to lock graphic buffer: %d", __func__, status);
+ return cameraStatus(Status::INTERNAL_ERROR);
+ }
- bool success = compressJpeg(gBuffer->getWidth(), gBuffer->getHeight(), ycbcr,
- bufferSize, planes_info.planes[0].data);
+ compressionSuccess =
+ compressJpeg(gBuffer->getWidth(), gBuffer->getHeight(), ycbcr,
+ stream->bufferSize, planes_info.planes[0].data);
- status_t res = gBuffer->unlock();
- if (res != NO_ERROR) {
- ALOGE("Failed to unlock graphic buffer: %d", res);
+ status_t res = gBuffer->unlock();
+ if (res != NO_ERROR) {
+ ALOGE("Failed to unlock graphic buffer: %d", res);
+ }
+ } else {
+ compressionSuccess =
+ compressBlackJpeg(stream->width, stream->height, stream->bufferSize,
+ planes_info.planes[0].data);
}
AHardwareBuffer_unlock(hwBuffer.get(), nullptr);
ALOGV("Unlocked buffers");
- return success ? ndk::ScopedAStatus::ok()
- : cameraStatus(Status::INTERNAL_ERROR);
+ return compressionSuccess ? ndk::ScopedAStatus::ok()
+ : cameraStatus(Status::INTERNAL_ERROR);
}
ndk::ScopedAStatus VirtualCameraRenderThread::renderIntoImageStreamBuffer(
@@ -435,7 +449,15 @@
mEglDisplayContext->makeCurrent();
framebuffer->beforeDraw();
- mEglTextureProgram->draw(mEglSurfaceTexture->updateTexture());
+ if (mEglSurfaceTexture->getCurrentBuffer() == nullptr) {
+ // If there's no current buffer, nothing was written to the surface and
+ // texture is not initialized yet. Let's render the framebuffer black
+ // instead of rendering the texture.
+ glClearColor(0.0f, 0.5f, 0.5f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ } else {
+ mEglTextureProgram->draw(mEglSurfaceTexture->updateTexture());
+ }
framebuffer->afterDraw();
const std::chrono::nanoseconds after =
diff --git a/services/camera/virtualcamera/VirtualCameraRenderThread.h b/services/camera/virtualcamera/VirtualCameraRenderThread.h
index 30de7c2..a4374e6 100644
--- a/services/camera/virtualcamera/VirtualCameraRenderThread.h
+++ b/services/camera/virtualcamera/VirtualCameraRenderThread.h
@@ -126,7 +126,6 @@
// Always called on render thread.
ndk::ScopedAStatus renderIntoBlobStreamBuffer(const int streamId,
const int bufferId,
- const size_t bufferSize,
sp<Fence> fence = nullptr);
// Render current image to the YCbCr buffer.
diff --git a/services/camera/virtualcamera/VirtualCameraSession.h b/services/camera/virtualcamera/VirtualCameraSession.h
index 8bf66bc..50962e5 100644
--- a/services/camera/virtualcamera/VirtualCameraSession.h
+++ b/services/camera/virtualcamera/VirtualCameraSession.h
@@ -64,12 +64,6 @@
std::vector<::aidl::android::hardware::camera::device::HalStream>*
_aidl_return) override EXCLUDES(mLock);
- ndk::ScopedAStatus configureStreamsV2(
- const ::aidl::android::hardware::camera::device::StreamConfiguration&,
- ::aidl::android::hardware::camera::device::ConfigureStreamsRet*) override {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- };
-
ndk::ScopedAStatus constructDefaultRequestSettings(
::aidl::android::hardware::camera::device::RequestTemplate in_type,
::aidl::android::hardware::camera::device::CameraMetadata* _aidl_return)
diff --git a/services/camera/virtualcamera/tests/EglUtilTest.cc b/services/camera/virtualcamera/tests/EglUtilTest.cc
index d387ebf..d0b7218 100644
--- a/services/camera/virtualcamera/tests/EglUtilTest.cc
+++ b/services/camera/virtualcamera/tests/EglUtilTest.cc
@@ -31,28 +31,12 @@
namespace virtualcamera {
namespace {
-using ::testing::Eq;
-using ::testing::NotNull;
+using ::testing::IsNull;
constexpr int kWidth = 64;
constexpr int kHeight = 64;
constexpr char kGlExtYuvTarget[] = "GL_EXT_YUV_target";
-uint8_t getY(const android_ycbcr& ycbcr, const int x, const int y) {
- uint8_t* yPtr = reinterpret_cast<uint8_t*>(ycbcr.y);
- return *(yPtr + ycbcr.ystride * y + x);
-}
-
-uint8_t getCb(const android_ycbcr& ycbcr, const int x, const int y) {
- uint8_t* cbPtr = reinterpret_cast<uint8_t*>(ycbcr.cb);
- return *(cbPtr + ycbcr.cstride * (y / 2) + (x / 2) * ycbcr.chroma_step);
-}
-
-uint8_t getCr(const android_ycbcr& ycbcr, const int x, const int y) {
- uint8_t* crPtr = reinterpret_cast<uint8_t*>(ycbcr.cr);
- return *(crPtr + ycbcr.cstride * (y / 2) + (x / 2) * ycbcr.chroma_step);
-}
-
TEST(EglDisplayContextTest, SuccessfulInitialization) {
EglDisplayContext displayContext;
@@ -88,7 +72,7 @@
EXPECT_TRUE(eglTextureProgram.isInitialized());
}
-TEST_F(EglTest, EglSurfaceTextureBlackAfterInit) {
+TEST_F(EglTest, EglSurfaceCurrentBufferNullAfterInit) {
if (!isGlExtensionSupported(kGlExtYuvTarget)) {
GTEST_SKIP() << "Skipping test because of missing required GL extension " << kGlExtYuvTarget;
}
@@ -97,24 +81,7 @@
surfaceTexture.updateTexture();
sp<GraphicBuffer> buffer = surfaceTexture.getCurrentBuffer();
- ASSERT_THAT(buffer, NotNull());
- const int width = buffer->getWidth();
- const int height = buffer->getHeight();
- ASSERT_THAT(width, Eq(kWidth));
- ASSERT_THAT(height, Eq(kHeight));
-
- android_ycbcr ycbcr;
- status_t ret = buffer->lockYCbCr(AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, &ycbcr);
- ASSERT_THAT(ret, Eq(NO_ERROR));
- for (int i = 0; i < width; ++i) {
- for (int j = 0; j < height; ++j) {
- EXPECT_THAT(getY(ycbcr, i, j), Eq(0x00));
- EXPECT_THAT(getCb(ycbcr, i, j), Eq(0x7f));
- EXPECT_THAT(getCr(ycbcr, i, j), Eq(0x7f));
- }
- }
-
- buffer->unlock();
+ EXPECT_THAT(buffer, IsNull());
}
} // namespace
diff --git a/services/camera/virtualcamera/util/EglSurfaceTexture.cc b/services/camera/virtualcamera/util/EglSurfaceTexture.cc
index 266d65a..5b479c0 100644
--- a/services/camera/virtualcamera/util/EglSurfaceTexture.cc
+++ b/services/camera/virtualcamera/util/EglSurfaceTexture.cc
@@ -31,26 +31,6 @@
namespace companion {
namespace virtualcamera {
-namespace {
-
-void submitBlackBufferYCbCr420(Surface& surface) {
- ANativeWindow_Buffer buffer;
-
- int ret = surface.lock(&buffer, nullptr);
- if (ret != NO_ERROR) {
- ALOGE("%s: Cannot lock output surface: %d", __func__, ret);
- return;
- }
- uint8_t* data = reinterpret_cast<uint8_t*>(buffer.bits);
- const int yPixNr = buffer.width * buffer.height;
- const int uvPixNr = (buffer.width / 2) * (buffer.height / 2);
- memset(data, 0x00, yPixNr);
- memset(data + yPixNr, 0x7f, 2 * uvPixNr);
- surface.unlockAndPost();
-}
-
-} // namespace
-
EglSurfaceTexture::EglSurfaceTexture(const uint32_t width, const uint32_t height)
: mWidth(width), mHeight(height) {
glGenTextures(1, &mTextureId);
@@ -67,14 +47,6 @@
mGlConsumer->setDefaultBufferFormat(AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420);
mSurface = sp<Surface>::make(mBufferProducer);
- // Submit black buffer to the surface to make sure there's input buffer
- // to process in case capture request comes before client writes something
- // to the surface.
- //
- // Note that if the client does write something before capture request is
- // processed (& updateTexture is called), this black buffer will be
- // skipped (and recycled).
- submitBlackBufferYCbCr420(*mSurface);
}
EglSurfaceTexture::~EglSurfaceTexture() {
diff --git a/services/camera/virtualcamera/util/JpegUtil.cc b/services/camera/virtualcamera/util/JpegUtil.cc
index 6f10376..2b19c13 100644
--- a/services/camera/virtualcamera/util/JpegUtil.cc
+++ b/services/camera/virtualcamera/util/JpegUtil.cc
@@ -20,6 +20,7 @@
#include <cstddef>
#include <cstdint>
#include <memory>
+#include <vector>
#include "android/hardware_buffer.h"
#include "jpeglib.h"
@@ -37,10 +38,9 @@
class LibJpegContext {
public:
- LibJpegContext(int width, int height, const android_ycbcr& ycbcr,
- const size_t outBufferSize, void* outBuffer)
- : mYCbCr(ycbcr),
- mWidth(width),
+ LibJpegContext(int width, int height, const size_t outBufferSize,
+ void* outBuffer)
+ : mWidth(width),
mHeight(height),
mDstBufferSize(outBufferSize),
mDstBuffer(outBuffer) {
@@ -94,15 +94,15 @@
mCompressStruct.comp_info[2].v_samp_factor = 1;
}
- bool compress() {
+ bool compress(const android_ycbcr& ycbr) {
// Prepare arrays of pointers to scanlines of each plane.
std::vector<JSAMPROW> yLines(mHeight);
std::vector<JSAMPROW> cbLines(mHeight / 2);
std::vector<JSAMPROW> crLines(mHeight / 2);
- uint8_t* y = static_cast<uint8_t*>(mYCbCr.y);
- uint8_t* cb = static_cast<uint8_t*>(mYCbCr.cb);
- uint8_t* cr = static_cast<uint8_t*>(mYCbCr.cr);
+ uint8_t* y = static_cast<uint8_t*>(ycbr.y);
+ uint8_t* cb = static_cast<uint8_t*>(ycbr.cb);
+ uint8_t* cr = static_cast<uint8_t*>(ycbr.cr);
// Since UV samples might be interleaved (semiplanar) we need to copy
// them to separate planes, since libjpeg doesn't directly
@@ -115,20 +115,59 @@
for (int i = 0; i < c_samples; ++i) {
cb_plane[i] = *cb;
cr_plane[i] = *cr;
- cb += mYCbCr.chroma_step;
- cr += mYCbCr.chroma_step;
+ cb += ycbr.chroma_step;
+ cr += ycbr.chroma_step;
}
// Collect pointers to individual scanline of each plane.
for (int i = 0; i < mHeight; ++i) {
- yLines[i] = y + i * mYCbCr.ystride;
+ yLines[i] = y + i * ycbr.ystride;
}
for (int i = 0; i < (mHeight / 2); ++i) {
cbLines[i] = cb_plane.data() + i * (mWidth / 2);
crLines[i] = cr_plane.data() + i * (mWidth / 2);
}
- // Perform actual compression.
+ return compress(yLines, cbLines, crLines);
+ }
+
+ bool compressBlackImage() {
+ // We only really need to prepare one scanline for Y and one shared scanline
+ // for Cb & Cr.
+ std::vector<uint8_t> yLine(mWidth, 0);
+ std::vector<uint8_t> chromaLine(mWidth / 2, 0xff / 2);
+
+ std::vector<JSAMPROW> yLines(mHeight, yLine.data());
+ std::vector<JSAMPROW> cLines(mHeight / 2, chromaLine.data());
+
+ return compress(yLines, cLines, cLines);
+ }
+
+ private:
+ void setSuccess(const boolean success) {
+ mSuccess = success;
+ }
+
+ void initDestination() {
+ mDestinationMgr.next_output_byte = reinterpret_cast<JOCTET*>(mDstBuffer);
+ mDestinationMgr.free_in_buffer = mDstBufferSize;
+ ALOGV("%s:%d jpeg start: %p [%zu]", __FUNCTION__, __LINE__, mDstBuffer,
+ mDstBufferSize);
+ }
+
+ void termDestination() {
+ mEncodedSize = mDstBufferSize - mDestinationMgr.free_in_buffer;
+ ALOGV("%s:%d Done with jpeg: %zu", __FUNCTION__, __LINE__, mEncodedSize);
+ }
+
+ // Perform actual compression.
+ //
+ // Takes vector of pointers to Y / Cb / Cr scanlines as an input. Length of
+ // each vector needs to correspond to height of corresponding plane.
+ //
+ // Returns true if compression is successful, false otherwise.
+ bool compress(std::vector<JSAMPROW>& yLines, std::vector<JSAMPROW>& cbLines,
+ std::vector<JSAMPROW>& crLines) {
jpeg_start_compress(&mCompressStruct, TRUE);
while (mCompressStruct.next_scanline < mCompressStruct.image_height) {
@@ -149,23 +188,6 @@
return mSuccess;
}
- private:
- void setSuccess(const boolean success) {
- mSuccess = success;
- }
-
- void initDestination() {
- mDestinationMgr.next_output_byte = reinterpret_cast<JOCTET*>(mDstBuffer);
- mDestinationMgr.free_in_buffer = mDstBufferSize;
- ALOGV("%s:%d jpeg start: %p [%zu]", __FUNCTION__, __LINE__, mDstBuffer,
- mDstBufferSize);
- }
-
- void termDestination() {
- mEncodedSize = mDstBufferSize - mDestinationMgr.free_in_buffer;
- ALOGV("%s:%d Done with jpeg: %zu", __FUNCTION__, __LINE__, mEncodedSize);
- }
-
// === libjpeg callbacks below ===
static void onOutputError(j_common_ptr cinfo) {
@@ -195,9 +217,6 @@
jpeg_error_mgr mErrorMgr;
jpeg_destination_mgr mDestinationMgr;
- // Layout of the input image.
- android_ycbcr mYCbCr;
-
// Dimensions of the input image.
int mWidth;
int mHeight;
@@ -216,11 +235,15 @@
} // namespace
-// Returns true if the EGL is in an error state and logs the error.
bool compressJpeg(int width, int height, const android_ycbcr& ycbcr,
size_t outBufferSize, void* outBuffer) {
- return LibJpegContext(width, height, ycbcr, outBufferSize, outBuffer)
- .compress();
+ return LibJpegContext(width, height, outBufferSize, outBuffer).compress(ycbcr);
+}
+
+bool compressBlackJpeg(int width, int height, size_t outBufferSize,
+ void* outBuffer) {
+ return LibJpegContext(width, height, outBufferSize, outBuffer)
+ .compressBlackImage();
}
} // namespace virtualcamera
diff --git a/services/camera/virtualcamera/util/JpegUtil.h b/services/camera/virtualcamera/util/JpegUtil.h
index 8bff008..c44d0a8 100644
--- a/services/camera/virtualcamera/util/JpegUtil.h
+++ b/services/camera/virtualcamera/util/JpegUtil.h
@@ -27,9 +27,15 @@
namespace virtualcamera {
// Jpeg-compress image into the output buffer.
+// Returns true if the compression was successful, false otherwise.
bool compressJpeg(int width, int height, const android_ycbcr& ycbcr,
size_t outBufferSize, void* outBuffer);
+// Jpeg-compress all-black image into the output buffer.
+// Returns true if the compression was successful, false otherwise.
+bool compressBlackJpeg(int width, int height, size_t outBufferSize,
+ void* outBuffer);
+
} // namespace virtualcamera
} // namespace companion
} // namespace android
diff --git a/services/camera/virtualcamera/util/MetadataBuilder.cc b/services/camera/virtualcamera/util/MetadataBuilder.cc
index b3b1a26..92a48b9 100644
--- a/services/camera/virtualcamera/util/MetadataBuilder.cc
+++ b/services/camera/virtualcamera/util/MetadataBuilder.cc
@@ -233,6 +233,12 @@
return *this;
}
+MetadataBuilder& MetadataBuilder::setControlZoomRatioRange(const float min,
+ const float max) {
+ mEntryMap[ANDROID_CONTROL_ZOOM_RATIO_RANGE] = std::vector<float>({min, max});
+ return *this;
+}
+
MetadataBuilder& MetadataBuilder::setSensorActiveArraySize(int x0, int y0,
int x1, int y1) {
mEntryMap[ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE] =
diff --git a/services/camera/virtualcamera/util/MetadataBuilder.h b/services/camera/virtualcamera/util/MetadataBuilder.h
index 2124398..d992d31 100644
--- a/services/camera/virtualcamera/util/MetadataBuilder.h
+++ b/services/camera/virtualcamera/util/MetadataBuilder.h
@@ -151,6 +151,9 @@
// See ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM in CameraMetadataTag.aidl.
MetadataBuilder& setAvailableMaxDigitalZoom(const float maxZoom);
+ // See ANDROID_CONTROL_ZOOM_RATIO_RANGE in CameraMetadataTag.aidl.
+ MetadataBuilder& setControlZoomRatioRange(float min, float max);
+
// A list of all keys that the camera device has available to use with
// CaptureRequest.
//
diff --git a/services/oboeservice/AAudioClientTracker.h b/services/oboeservice/AAudioClientTracker.h
index cd3b75a..3d4ab34 100644
--- a/services/oboeservice/AAudioClientTracker.h
+++ b/services/oboeservice/AAudioClientTracker.h
@@ -110,7 +110,7 @@
private:
mutable std::mutex mLock;
const pid_t mProcessId;
- std::set<android::sp<AAudioServiceStreamBase>> mStreams;
+ std::set<android::sp<AAudioServiceStreamBase>> mStreams GUARDED_BY(mLock);
// hold onto binder to receive death notifications
android::sp<IBinder> mBinder;
bool mExclusiveEnabled = true;
diff --git a/services/oboeservice/AAudioEndpointManager.h b/services/oboeservice/AAudioEndpointManager.h
index 1d38d26..cddc261 100644
--- a/services/oboeservice/AAudioEndpointManager.h
+++ b/services/oboeservice/AAudioEndpointManager.h
@@ -58,18 +58,25 @@
* @param sharingMode
* @return endpoint or null
*/
- android::sp<AAudioServiceEndpoint> openEndpoint(android::AAudioService &audioService,
- const aaudio::AAudioStreamRequest &request);
+ android::sp<AAudioServiceEndpoint> openEndpoint(
+ android::AAudioService &audioService,
+ const aaudio::AAudioStreamRequest &request)
+ EXCLUDES(mExclusiveLock, mSharedLock);
- void closeEndpoint(const android::sp<AAudioServiceEndpoint>& serviceEndpoint);
+ void closeEndpoint(const android::sp<AAudioServiceEndpoint>& serviceEndpoint)
+ EXCLUDES(mExclusiveLock, mSharedLock);;
private:
- android::sp<AAudioServiceEndpoint> openExclusiveEndpoint(android::AAudioService &aaudioService,
- const aaudio::AAudioStreamRequest &request,
- sp<AAudioServiceEndpoint> &endpointToSteal);
+ android::sp<AAudioServiceEndpoint> openExclusiveEndpoint(
+ android::AAudioService &aaudioService,
+ const aaudio::AAudioStreamRequest &request,
+ sp<AAudioServiceEndpoint> &endpointToSteal)
+ EXCLUDES(mExclusiveLock);
- android::sp<AAudioServiceEndpoint> openSharedEndpoint(android::AAudioService &aaudioService,
- const aaudio::AAudioStreamRequest &request);
+ android::sp<AAudioServiceEndpoint> openSharedEndpoint(
+ android::AAudioService &aaudioService,
+ const aaudio::AAudioStreamRequest &request)
+ EXCLUDES(mSharedLock);
android::sp<AAudioServiceEndpoint> findExclusiveEndpoint_l(
const AAudioStreamConfiguration& configuration)
@@ -77,7 +84,8 @@
android::sp<AAudioServiceEndpointShared> findSharedEndpoint_l(
const AAudioStreamConfiguration& configuration)
- REQUIRES(mSharedLock);
+ REQUIRES(mSharedLock)
+ EXCLUDES(mExclusiveLock);
void closeExclusiveEndpoint(const android::sp<AAudioServiceEndpoint>& serviceEndpoint);
void closeSharedEndpoint(const android::sp<AAudioServiceEndpoint>& serviceEndpoint);
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index dff571b..6de95e0 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -55,9 +55,11 @@
*/
virtual void close() = 0;
- aaudio_result_t registerStream(const android::sp<AAudioServiceStreamBase>& stream);
+ aaudio_result_t registerStream(const android::sp<AAudioServiceStreamBase>& stream)
+ EXCLUDES(mLockStreams);
- aaudio_result_t unregisterStream(const android::sp<AAudioServiceStreamBase>& stream);
+ aaudio_result_t unregisterStream(const android::sp<AAudioServiceStreamBase>& stream)
+ EXCLUDES(mLockStreams);
virtual aaudio_result_t startStream(android::sp<AAudioServiceStreamBase> stream,
audio_port_handle_t *clientHandle) = 0;
@@ -148,9 +150,11 @@
* @param portHandle
* @return return true if a stream with the given portHandle is registered
*/
- bool isStreamRegistered(audio_port_handle_t portHandle);
+ bool isStreamRegistered(audio_port_handle_t portHandle)
+ EXCLUDES(mLockStreams);
- std::vector<android::sp<AAudioServiceStreamBase>> disconnectRegisteredStreams();
+ std::vector<android::sp<AAudioServiceStreamBase>> disconnectRegisteredStreams()
+ EXCLUDES(mLockStreams);
mutable std::mutex mLockStreams;
std::vector<android::sp<AAudioServiceStreamBase>> mRegisteredStreams
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index f19005c..eaa578c 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -19,7 +19,6 @@
#include <atomic>
#include <functional>
-#include <mutex>
#include <vector>
#include "client/AudioStreamInternal.h"
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.h b/services/oboeservice/AAudioServiceEndpointPlay.h
index 160a1de..704502e 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.h
+++ b/services/oboeservice/AAudioServiceEndpointPlay.h
@@ -19,7 +19,6 @@
#include <atomic>
#include <functional>
-#include <mutex>
#include <vector>
#include "client/AudioStreamInternal.h"
diff --git a/services/oboeservice/AAudioServiceEndpointShared.h b/services/oboeservice/AAudioServiceEndpointShared.h
index 0efb227..2c73953 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.h
+++ b/services/oboeservice/AAudioServiceEndpointShared.h
@@ -18,7 +18,6 @@
#define AAUDIO_SERVICE_ENDPOINT_SHARED_H
#include <atomic>
-#include <mutex>
#include <android-base/thread_annotations.h>
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index 8f51ce4..d5061b3 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -76,7 +76,8 @@
/**
* Open the device.
*/
- virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request) = 0;
+ virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request)
+ EXCLUDES(mUpMessageQueueLock);
// We log the CLOSE from the close() method. We needed this separate method to log the OPEN
// because we had to wait until we generated the handle.
@@ -269,7 +270,8 @@
AudioEndpointParcelable* mParcelable;
};
- aaudio_result_t getDescription_l(AudioEndpointParcelable* parcelable) REQUIRES(mLock);
+ aaudio_result_t getDescription_l(AudioEndpointParcelable* parcelable)
+ REQUIRES(mLock) EXCLUDES(mUpMessageQueueLock);
void setState(aaudio_stream_state_t state);
@@ -279,7 +281,8 @@
*/
virtual aaudio_result_t startDevice();
- aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command);
+ aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command)
+ EXCLUDES(mUpMessageQueueLock);
aaudio_result_t sendCurrentTimestamp_l() REQUIRES(mLock);
@@ -342,7 +345,7 @@
pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID;
std::mutex mUpMessageQueueLock;
- std::shared_ptr<SharedRingBuffer> mUpMessageQueue;
+ std::shared_ptr<SharedRingBuffer> mUpMessageQueue PT_GUARDED_BY(mUpMessageQueueLock);
enum : int32_t {
START,
@@ -402,7 +405,7 @@
/**
* @return true if the queue is getting full.
*/
- bool isUpMessageQueueBusy();
+ bool isUpMessageQueueBusy() EXCLUDES(mUpMessageQueueLock);
aaudio_handle_t mHandle = -1;
bool mFlowing = false;
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h
index db3c8d0..42032d7 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.h
+++ b/services/oboeservice/AAudioServiceStreamMMAP.h
@@ -49,7 +49,8 @@
bool inService);
~AAudioServiceStreamMMAP() override = default;
- aaudio_result_t open(const aaudio::AAudioStreamRequest &request) override;
+ aaudio_result_t open(const aaudio::AAudioStreamRequest &request) override
+ EXCLUDES(mUpMessageQueueLock);
aaudio_result_t startClient(const android::AudioClient& client,
const audio_attributes_t *attr,
diff --git a/services/oboeservice/AAudioServiceStreamShared.h b/services/oboeservice/AAudioServiceStreamShared.h
index 0b2513a..c6b74e1 100644
--- a/services/oboeservice/AAudioServiceStreamShared.h
+++ b/services/oboeservice/AAudioServiceStreamShared.h
@@ -50,7 +50,8 @@
std::string dump() const override;
- aaudio_result_t open(const aaudio::AAudioStreamRequest &request) override;
+ aaudio_result_t open(const aaudio::AAudioStreamRequest &request) override
+ EXCLUDES(mUpMessageQueueLock);
void writeDataIfRoom(int64_t mmapFramesRead, const void *buffer, int32_t numFrames);
@@ -107,7 +108,7 @@
private:
- std::shared_ptr<SharedRingBuffer> mAudioDataQueue GUARDED_BY(audioDataQueueLock);
+ std::shared_ptr<SharedRingBuffer> mAudioDataQueue PT_GUARDED_BY(audioDataQueueLock);
std::atomic<int64_t> mTimestampPositionOffset;
std::atomic<int32_t> mXRunCount;
diff --git a/services/oboeservice/AAudioStreamTracker.h b/services/oboeservice/AAudioStreamTracker.h
index 99f4b6c..51a783d 100644
--- a/services/oboeservice/AAudioStreamTracker.h
+++ b/services/oboeservice/AAudioStreamTracker.h
@@ -37,7 +37,7 @@
* @param streamHandle
* @return number of streams removed
*/
- int32_t removeStreamByHandle(aaudio_handle_t streamHandle);
+ int32_t removeStreamByHandle(aaudio_handle_t streamHandle) EXCLUDES(mHandleLock);
/**
* Look up a stream based on the handle.
@@ -46,7 +46,7 @@
* @return strong pointer to the stream if found, or nullptr
*/
android::sp<aaudio::AAudioServiceStreamBase> getStreamByHandle(
- aaudio_handle_t streamHandle);
+ aaudio_handle_t streamHandle) EXCLUDES(mHandleLock);
/**
* Look up a stream based on the AudioPolicy portHandle.
@@ -56,7 +56,7 @@
* @return strong pointer to the stream if found, or nullptr
*/
android::sp<aaudio::AAudioServiceStreamBase> findStreamByPortHandle(
- audio_port_handle_t portHandle);
+ audio_port_handle_t portHandle) EXCLUDES(mHandleLock);
/**
* Store a strong pointer to the stream and return a unique handle for future reference.
@@ -64,7 +64,8 @@
* @param serviceStream
* @return handle for identifying the stream
*/
- aaudio_handle_t addStreamForHandle(const android::sp<AAudioServiceStreamBase>& serviceStream);
+ aaudio_handle_t addStreamForHandle(const android::sp<AAudioServiceStreamBase>& serviceStream)
+ EXCLUDES(mHandleLock);
/**
* @return string that can be added to dumpsys