Merge "wifi: Add provision to create/delete dynamic interface(s)"
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
index ac32c95..7792b31 100644
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ b/camera/common/1.0/default/HandleImporter.cpp
@@ -182,9 +182,8 @@
}
Mutex::Autolock lock(mLock);
- if (mMapperV4 == nullptr && mMapperV3 == nullptr && mMapperV2 == nullptr) {
- ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
- return;
+ if (!mInitialized) {
+ initializeLocked();
}
if (mMapperV4 != nullptr) {
diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp
index 4a6381e..62a4c87 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -519,6 +519,7 @@
yLines[i] = static_cast<JSAMPROW>(py + li * inLayout.yStride);
if(i < paddedHeight / cVSubSampling)
{
+ li = std::min(i, (inSz.height - 1) / cVSubSampling);
crLines[i] = static_cast<JSAMPROW>(pcr + li * inLayout.cStride);
cbLines[i] = static_cast<JSAMPROW>(pcb + li * inLayout.cStride);
}
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index ecab9cf..180f0c1 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -321,7 +321,7 @@
const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
const std::vector<SupportedV4L2Format> mSupportedFormats;
const CroppingType mCroppingType;
- const std::string& mCameraId;
+ const std::string mCameraId;
// Not protected by mLock, this is almost a const.
// Setup in constructor, reset in close() after OutputThread is joined
diff --git a/camera/device/3.6/default/ExternalCameraDeviceSession.cpp b/camera/device/3.6/default/ExternalCameraDeviceSession.cpp
index 0cc81bb..60a1a10 100644
--- a/camera/device/3.6/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.6/default/ExternalCameraDeviceSession.cpp
@@ -149,10 +149,6 @@
info->offlineStreams.resize(offlineStreams.size());
info->offlineRequests.resize(offlineReqs.size());
- std::unordered_map<int32_t, uint32_t> outstandingBufs(offlineStreams.size());
- for (const auto streamId : offlineStreams) {
- outstandingBufs.insert({streamId, 0});
- }
// Fill in offline reqs and count outstanding buffers
for (size_t i = 0; i < offlineReqs.size(); i++) {
info->offlineRequests[i].frameNumber = offlineReqs[i]->frameNumber;
@@ -160,14 +156,15 @@
for (size_t bIdx = 0; bIdx < offlineReqs[i]->buffers.size(); bIdx++) {
int32_t streamId = offlineReqs[i]->buffers[bIdx].streamId;
info->offlineRequests[i].pendingStreams[bIdx] = streamId;
- outstandingBufs[streamId]++;
}
}
for (size_t i = 0; i < offlineStreams.size(); i++) {
int32_t streamId = offlineStreams[i];
info->offlineStreams[i].id = streamId;
- info->offlineStreams[i].numOutstandingBuffers = outstandingBufs[streamId];
+ // outstanding buffers are 0 since we are doing hal buffer management and
+ // offline session will ask for those buffers later
+ info->offlineStreams[i].numOutstandingBuffers = 0;
const CirculatingBuffers& bufIdMap = circulatingBuffers.at(streamId);
info->offlineStreams[i].circulatingBufferIds.resize(bufIdMap.size());
size_t bIdx = 0;
@@ -345,7 +342,12 @@
return Status::INTERNAL_ERROR;
}
- *session = sessionImpl->getInterface();
+ // No need to return session if there is no offline requests left
+ if (offlineReqs.size() != 0) {
+ *session = sessionImpl->getInterface();
+ } else {
+ *session = nullptr;
+ }
return Status::OK;
}
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 15f5c9a..4b9d6f1 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -38,7 +38,8 @@
"android.hardware.camera.device@3.3",
"android.hardware.camera.device@3.4",
"android.hardware.camera.device@3.5",
- "android.hardware.camera.metadata@3.4",
+ "android.hardware.camera.device@3.6",
+ "android.hardware.camera.metadata@3.4",
"android.hardware.camera.provider@2.4",
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index b4092ca..e3e53dd 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -37,6 +37,7 @@
#include <android/hardware/camera/device/3.5/ICameraDevice.h>
#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.6/ICameraDeviceSession.h>
#include <android/hardware/camera/metadata/3.4/types.h>
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
@@ -133,6 +134,8 @@
const uint32_t kMaxPreviewWidth = 1920;
const uint32_t kMaxPreviewHeight = 1080;
+const uint32_t kMaxStillWidth = 2048;
+const uint32_t kMaxStillHeight = 1536;
const uint32_t kMaxVideoWidth = 4096;
const uint32_t kMaxVideoHeight = 2160;
const int64_t kStreamBufferTimeoutSec = 3;
@@ -162,11 +165,13 @@
namespace {
// "device@<version>/legacy/<id>"
const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
+ const int CAMERA_DEVICE_API_VERSION_3_6 = 0x306;
const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304;
const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
+ const char *kHAL3_6 = "3.6";
const char *kHAL3_5 = "3.5";
const char *kHAL3_4 = "3.4";
const char *kHAL3_3 = "3.3";
@@ -202,7 +207,9 @@
return -1;
}
- if (version.compare(kHAL3_5) == 0) {
+ if (version.compare(kHAL3_6) == 0) {
+ return CAMERA_DEVICE_API_VERSION_3_6;
+ } else if (version.compare(kHAL3_5) == 0) {
return CAMERA_DEVICE_API_VERSION_3_5;
} else if (version.compare(kHAL3_4) == 0) {
return CAMERA_DEVICE_API_VERSION_3_4;
@@ -717,7 +724,8 @@
void castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
- sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/);
+ sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
+ sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/);
void castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion,
sp<device::V3_5::ICameraDevice> *device3_5/*out*/);
void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
@@ -727,6 +735,17 @@
::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5,
uint32_t jpegBufferSize = 0);
+ void configureOfflineStillStream(const std::string &name, int32_t deviceVersion,
+ sp<ICameraProvider> provider,
+ const AvailableStream *threshold,
+ sp<device::V3_6::ICameraDeviceSession> *session/*out*/,
+ V3_2::Stream *stream /*out*/,
+ device::V3_6::HalStreamConfiguration *halStreamConfig /*out*/,
+ bool *supportsPartialResults /*out*/,
+ uint32_t *partialResultCount /*out*/,
+ sp<DeviceCb> *outCb /*out*/,
+ uint32_t *jpegBufferSize /*out*/,
+ bool *useHalBufManager /*out*/);
void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
sp<ICameraProvider> provider,
const AvailableStream *previewThreshold,
@@ -792,6 +811,7 @@
uint32_t* outBufSize);
static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
static Status isLogicalMultiCamera(const camera_metadata_t *staticMeta);
+ static Status isOfflineSessionSupported(const camera_metadata_t *staticMeta);
static Status getPhysicalCameraIds(const camera_metadata_t *staticMeta,
std::unordered_set<std::string> *physicalIds/*out*/);
static Status getSupportedKeys(camera_metadata_t *staticMeta,
@@ -818,6 +838,9 @@
CameraParameters &cameraParams, const char *mode) ;
static Status isMonochromeCamera(const camera_metadata_t *staticMeta);
+ // Used by switchToOffline where a new result queue is created for offline reqs
+ void updateInflightResultQueue(std::shared_ptr<ResultMetadataQueue> resultQueue);
+
protected:
// In-flight queue for tracking completion of capture requests.
@@ -1442,7 +1465,13 @@
hidl_vec<StreamBuffer> tmpRetBuffers(bufReq.numBuffersRequested);
for (size_t j = 0; j < bufReq.numBuffersRequested; j++) {
hidl_handle buffer_handle;
- mParent->allocateGraphicBuffer(stream.v3_2.width, stream.v3_2.height,
+ uint32_t w = stream.v3_2.width;
+ uint32_t h = stream.v3_2.height;
+ if (stream.v3_2.format == PixelFormat::BLOB) {
+ w = stream.bufferSize;
+ h = 1;
+ }
+ mParent->allocateGraphicBuffer(w, h,
android_convertGralloc1To0Usage(
halStream.producerUsage, halStream.consumerUsage),
halStream.overrideFormat, &buffer_handle);
@@ -1706,6 +1735,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
@@ -1748,6 +1778,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
@@ -2489,6 +2520,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
@@ -2568,6 +2600,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
@@ -2694,6 +2727,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
@@ -2759,6 +2793,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
@@ -2788,8 +2823,12 @@
sp<device::V3_3::ICameraDeviceSession> sessionV3_3;
sp<device::V3_4::ICameraDeviceSession> sessionV3_4;
sp<device::V3_5::ICameraDeviceSession> sessionV3_5;
- castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4, &sessionV3_5);
- if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
+ sp<device::V3_6::ICameraDeviceSession> sessionV3_6;
+ castSession(session, deviceVersion, &sessionV3_3,
+ &sessionV3_4, &sessionV3_5, &sessionV3_6);
+ if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
+ ASSERT_TRUE(sessionV3_6.get() != nullptr);
+ } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
ASSERT_TRUE(sessionV3_5.get() != nullptr);
} else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
ASSERT_TRUE(sessionV3_4.get() != nullptr);
@@ -2851,6 +2890,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
case CAMERA_DEVICE_API_VERSION_3_3:
@@ -2949,11 +2989,12 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider,
&session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
outputStreams.clear();
@@ -3057,11 +3098,12 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
outputStreams.clear();
@@ -3254,11 +3296,12 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
Status rc = isZSLModeAvailable(staticMeta);
@@ -3421,8 +3464,9 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
ASSERT_NE(session3_4, nullptr);
} else {
@@ -3543,11 +3587,12 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
// Check if camera support depth only
@@ -3660,11 +3705,12 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
Status rc = isConstrainedModeAvailable(staticMeta);
@@ -3871,11 +3917,12 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
// Check if camera support depth only
@@ -4613,6 +4660,207 @@
}
}
+// Verify camera offline session behavior
+TEST_P(CameraHidlTest, switchToOffline) {
+ hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+ AvailableStream threshold = {kMaxStillWidth, kMaxStillHeight,
+ static_cast<int32_t>(PixelFormat::BLOB)};
+ uint64_t bufferId = 1;
+ uint32_t frameNumber = 1;
+ ::android::hardware::hidl_vec<uint8_t> settings;
+
+ for (const auto& name : cameraDeviceNames) {
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
+ continue;
+ } else if (deviceVersion <= 0) {
+ ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+ ADD_FAILURE();
+ return;
+ }
+
+ camera_metadata_t* staticMetaBuffer;
+ {
+ Return<void> ret;
+ sp<ICameraDeviceSession> session;
+ openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
+ staticMetaBuffer);
+
+ if (isOfflineSessionSupported(staticMetaBuffer) != Status::OK) {
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ continue;
+ }
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ }
+
+ bool supportsPartialResults = false;
+ uint32_t partialResultCount = 0;
+ V3_2::Stream stream;
+ V3_6::HalStreamConfiguration halStreamConfig;
+ sp<V3_6::ICameraDeviceSession> session;
+ sp<DeviceCb> cb;
+ uint32_t jpegBufferSize;
+ bool useHalBufManager;
+ configureOfflineStillStream(name, deviceVersion, mProvider, &threshold,
+ &session /*out*/, &stream /*out*/, &halStreamConfig /*out*/,
+ &supportsPartialResults /*out*/, &partialResultCount /*out*/, &cb /*out*/,
+ &jpegBufferSize /*out*/, &useHalBufManager /*out*/);
+
+ auto ret = session->constructDefaultRequestSettings(RequestTemplate::STILL_CAPTURE,
+ [&](auto status, const auto& req) {
+ ASSERT_EQ(Status::OK, status);
+ settings = req; });
+ ASSERT_TRUE(ret.isOk());
+
+ std::shared_ptr<ResultMetadataQueue> resultQueue;
+ auto resultQueueRet =
+ session->getCaptureResultMetadataQueue(
+ [&resultQueue](const auto& descriptor) {
+ resultQueue = std::make_shared<ResultMetadataQueue>(
+ descriptor);
+ if (!resultQueue->isValid() ||
+ resultQueue->availableToWrite() <= 0) {
+ ALOGE("%s: HAL returns empty result metadata fmq,"
+ " not use it", __func__);
+ resultQueue = nullptr;
+ // Don't use the queue onwards.
+ }
+ });
+ ASSERT_TRUE(resultQueueRet.isOk());
+
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
+ StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
+ hidl_handle buffers[kBurstFrameCount];
+ StreamBuffer outputBuffers[kBurstFrameCount];
+ CaptureRequest requests[kBurstFrameCount];
+ InFlightRequest inflightReqs[kBurstFrameCount];
+ hidl_vec<uint8_t> requestSettings[kBurstFrameCount];
+ auto halStreamConfig3_2 = halStreamConfig.streams[0].v3_4.v3_3.v3_2;
+ for (uint32_t i = 0; i < kBurstFrameCount; i++) {
+ std::unique_lock<std::mutex> l(mLock);
+
+ if (useHalBufManager) {
+ outputBuffers[i] = {halStreamConfig3_2.id, /*bufferId*/ 0,
+ buffers[i], BufferStatus::OK, nullptr, nullptr};
+ } else {
+ // jpeg buffer (w,h) = (blobLen, 1)
+ allocateGraphicBuffer(jpegBufferSize, /*height*/1,
+ android_convertGralloc1To0Usage(halStreamConfig3_2.producerUsage,
+ halStreamConfig3_2.consumerUsage),
+ halStreamConfig3_2.overrideFormat, &buffers[i]);
+ outputBuffers[i] = {halStreamConfig3_2.id, bufferId + i,
+ buffers[i], BufferStatus::OK, nullptr, nullptr};
+ }
+
+ requestMeta.clear();
+ requestMeta.append(reinterpret_cast<camera_metadata_t *> (settings.data()));
+
+ camera_metadata_t *metaBuffer = requestMeta.release();
+ requestSettings[i].setToExternal(reinterpret_cast<uint8_t *> (metaBuffer),
+ get_camera_metadata_size(metaBuffer), true);
+
+ requests[i] = {frameNumber + i, 0 /* fmqSettingsSize */, requestSettings[i],
+ emptyInputBuffer, {outputBuffers[i]}};
+
+ inflightReqs[i] = {1, false, supportsPartialResults, partialResultCount,
+ resultQueue};
+ mInflightMap.add(frameNumber + i, &inflightReqs[i]);
+ }
+
+ Status status = Status::INTERNAL_ERROR;
+ uint32_t numRequestProcessed = 0;
+ hidl_vec<BufferCache> cachesToRemove;
+ hidl_vec<CaptureRequest> burstRequest;
+ burstRequest.setToExternal(requests, kBurstFrameCount);
+ Return<void> returnStatus = session->processCaptureRequest(burstRequest, cachesToRemove,
+ [&status, &numRequestProcessed] (auto s, uint32_t n) {
+ status = s;
+ numRequestProcessed = n;
+ });
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_EQ(numRequestProcessed, kBurstFrameCount);
+
+ hidl_vec<int32_t> offlineStreamIds = {halStreamConfig3_2.id};
+ V3_6::CameraOfflineSessionInfo offlineSessionInfo;
+ sp<device::V3_6::ICameraOfflineSession> offlineSession;
+ returnStatus = session->switchToOffline(offlineStreamIds,
+ [&status, &offlineSessionInfo, &offlineSession] (auto stat, auto info,
+ auto offSession) {
+ status = stat;
+ offlineSessionInfo = info;
+ offlineSession = offSession;
+ });
+ ASSERT_TRUE(returnStatus.isOk());
+
+ if (!halStreamConfig.streams[0].supportOffline) {
+ ASSERT_EQ(status, Status::ILLEGAL_ARGUMENT);
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ continue;
+ }
+
+ ASSERT_EQ(status, Status::OK);
+ // Hal might be unable to find any requests qualified for offline mode.
+ if (offlineSession == nullptr) {
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ continue;
+ }
+
+ ASSERT_EQ(offlineSessionInfo.offlineStreams.size(), 1u);
+ ASSERT_EQ(offlineSessionInfo.offlineStreams[0].id, halStreamConfig3_2.id);
+ ASSERT_NE(offlineSessionInfo.offlineRequests.size(), 0u);
+
+ // close device session to make sure offline session does not rely on it
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+
+ std::shared_ptr<ResultMetadataQueue> offlineResultQueue;
+ auto offlineResultQueueRet =
+ offlineSession->getCaptureResultMetadataQueue(
+ [&offlineResultQueue](const auto& descriptor) {
+ offlineResultQueue = std::make_shared<ResultMetadataQueue>(
+ descriptor);
+ if (!offlineResultQueue->isValid() ||
+ offlineResultQueue->availableToWrite() <= 0) {
+ ALOGE("%s: offline session returns empty result metadata fmq,"
+ " not use it", __func__);
+ offlineResultQueue = nullptr;
+ // Don't use the queue onwards.
+ }
+ });
+ ASSERT_TRUE(offlineResultQueueRet.isOk());
+
+ updateInflightResultQueue(offlineResultQueue);
+
+ ret = offlineSession->setCallback(cb);
+ ASSERT_TRUE(ret.isOk());
+
+ for (size_t i = 0; i < kBurstFrameCount; i++) {
+ std::unique_lock<std::mutex> l(mLock);
+ while (!inflightReqs[i].errorCodeValid && ((0 < inflightReqs[i].numBuffersLeft) ||
+ (!inflightReqs[i].haveResultMetadata))) {
+ auto timeout = std::chrono::system_clock::now() +
+ std::chrono::seconds(kStreamBufferTimeoutSec);
+ ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+ }
+
+ ASSERT_FALSE(inflightReqs[i].errorCodeValid);
+ ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
+ ASSERT_EQ(stream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
+ ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
+ }
+
+
+ ret = offlineSession->close();
+ ASSERT_TRUE(ret.isOk());
+ }
+}
+
// Check whether an invalid capture request with missing output buffers
// will be reported correctly.
TEST_P(CameraHidlTest, processCaptureRequestInvalidBuffer) {
@@ -4972,6 +5220,30 @@
return ret;
}
+// Check if the camera device has logical multi-camera capability.
+Status CameraHidlTest::isOfflineSessionSupported(const camera_metadata_t *staticMeta) {
+ Status ret = Status::METHOD_NOT_SUPPORTED;
+ if (nullptr == staticMeta) {
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ camera_metadata_ro_entry entry;
+ int rc = find_camera_metadata_ro_entry(staticMeta,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
+ if (0 != rc) {
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ for (size_t i = 0; i < entry.count; i++) {
+ if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING == entry.data.u8[i]) {
+ ret = Status::OK;
+ break;
+ }
+ }
+
+ return ret;
+}
+
// Generate a list of physical camera ids backing a logical multi-camera.
Status CameraHidlTest::getPhysicalCameraIds(const camera_metadata_t *staticMeta,
std::unordered_set<std::string> *physicalIds) {
@@ -5330,7 +5602,8 @@
*outCb = cb;
sp<device::V3_3::ICameraDeviceSession> session3_3;
- castSession(session, deviceVersion, &session3_3, session3_4, session3_5);
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
+ castSession(session, deviceVersion, &session3_3, session3_4, session3_5, &session3_6);
ASSERT_NE(nullptr, (*session3_4).get());
*useHalBufManager = false;
@@ -5423,6 +5696,142 @@
ASSERT_TRUE(ret.isOk());
}
+// Configure preview stream with possible offline session support
+void CameraHidlTest::configureOfflineStillStream(const std::string &name,
+ int32_t deviceVersion,
+ sp<ICameraProvider> provider,
+ const AvailableStream *threshold,
+ sp<device::V3_6::ICameraDeviceSession> *session/*out*/,
+ V3_2::Stream *stream /*out*/,
+ device::V3_6::HalStreamConfiguration *halStreamConfig /*out*/,
+ bool *supportsPartialResults /*out*/,
+ uint32_t *partialResultCount /*out*/,
+ sp<DeviceCb> *outCb /*out*/,
+ uint32_t *jpegBufferSize /*out*/,
+ bool *useHalBufManager /*out*/) {
+ ASSERT_NE(nullptr, session);
+ ASSERT_NE(nullptr, halStreamConfig);
+ ASSERT_NE(nullptr, stream);
+ ASSERT_NE(nullptr, supportsPartialResults);
+ ASSERT_NE(nullptr, partialResultCount);
+ ASSERT_NE(nullptr, outCb);
+ ASSERT_NE(nullptr, jpegBufferSize);
+ ASSERT_NE(nullptr, useHalBufManager);
+
+ std::vector<AvailableStream> outputStreams;
+ ::android::sp<ICameraDevice> cameraDevice;
+ ALOGI("configureStreams: Testing camera device %s", name.c_str());
+ Return<void> ret;
+ ret = provider->getCameraDeviceInterface_V3_x(
+ name,
+ [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+ (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ cameraDevice = device;
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ camera_metadata_t *staticMeta;
+ ret = cameraDevice->getCameraCharacteristics([&] (Status s,
+ CameraMetadata metadata) {
+ ASSERT_EQ(Status::OK, s);
+ staticMeta = clone_camera_metadata(
+ reinterpret_cast<const camera_metadata_t*>(metadata.data()));
+ ASSERT_NE(nullptr, staticMeta);
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ camera_metadata_ro_entry entry;
+ auto status = find_camera_metadata_ro_entry(staticMeta,
+ ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
+ if ((0 == status) && (entry.count > 0)) {
+ *partialResultCount = entry.data.i32[0];
+ *supportsPartialResults = (*partialResultCount > 1);
+ }
+
+ *useHalBufManager = false;
+ status = find_camera_metadata_ro_entry(staticMeta,
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
+ if ((0 == status) && (entry.count == 1)) {
+ *useHalBufManager = (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ }
+
+ auto st = getJpegBufferSize(staticMeta, jpegBufferSize);
+ ASSERT_EQ(st, Status::OK);
+
+ sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta);
+ ret = cameraDevice->open(cb, [&session](auto status, const auto& newSession) {
+ ALOGI("device::open returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(newSession, nullptr);
+ auto castResult = device::V3_6::ICameraDeviceSession::castFrom(newSession);
+ ASSERT_TRUE(castResult.isOk());
+ *session = castResult;
+ });
+ ASSERT_TRUE(ret.isOk());
+ *outCb = cb;
+
+ outputStreams.clear();
+ auto rc = getAvailableOutputStreams(staticMeta,
+ outputStreams, threshold);
+ size_t idx = 0;
+ int currLargest = outputStreams[0].width * outputStreams[0].height;
+ for (size_t i = 0; i < outputStreams.size(); i++) {
+ int area = outputStreams[i].width * outputStreams[i].height;
+ if (area > currLargest) {
+ idx = i;
+ currLargest = area;
+ }
+ }
+ free_camera_metadata(staticMeta);
+ ASSERT_EQ(Status::OK, rc);
+ ASSERT_FALSE(outputStreams.empty());
+
+ V3_2::DataspaceFlags dataspaceFlag = 0;
+ switch (static_cast<PixelFormat>(outputStreams[idx].format)) {
+ case PixelFormat::BLOB:
+ dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF);
+ break;
+ case PixelFormat::Y16:
+ dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
+ break;
+ default:
+ dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
+ }
+
+ ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(/*size*/1);
+ V3_4::Stream stream3_4 = {{ 0 /*streamId*/, StreamType::OUTPUT,
+ static_cast<uint32_t> (outputStreams[idx].width),
+ static_cast<uint32_t> (outputStreams[idx].height),
+ static_cast<PixelFormat> (outputStreams[idx].format),
+ GRALLOC1_CONSUMER_USAGE_CPU_READ, dataspaceFlag, StreamRotation::ROTATION_0},
+ nullptr /*physicalId*/, /*bufferSize*/ *jpegBufferSize};
+ streams3_4[0] = stream3_4;
+
+ ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
+ ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
+ config3_4 = {streams3_4, StreamConfigurationMode::NORMAL_MODE, {}};
+
+ config3_5.v3_4 = config3_4;
+ config3_5.streamConfigCounter = 0;
+ ret = (*session)->configureStreams_3_6(config3_5,
+ [&] (Status s, device::V3_6::HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ *halStreamConfig = halConfig;
+
+ if (*useHalBufManager) {
+ hidl_vec<V3_2::HalStream> halStreams3_2(1);
+ halStreams3_2[0] = halConfig.streams[0].v3_4.v3_3.v3_2;
+ cb->setCurrentStreamConfig(streams3_4, halStreams3_2);
+ }
+ });
+ *stream = streams3_4[0].v3_2;
+ ASSERT_TRUE(ret.isOk());
+}
+
bool CameraHidlTest::isDepthOnly(camera_metadata_t* staticMeta) {
camera_metadata_ro_entry scalarEntry;
camera_metadata_ro_entry depthEntry;
@@ -5454,6 +5863,14 @@
return false;
}
+void CameraHidlTest::updateInflightResultQueue(std::shared_ptr<ResultMetadataQueue> resultQueue) {
+ std::unique_lock<std::mutex> l(mLock);
+ for (size_t i = 0; i < mInflightMap.size(); i++) {
+ auto& req = mInflightMap.editValueAt(i);
+ req->resultQueue = resultQueue;
+ }
+}
+
// Open a device session and configure a preview stream.
void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion,
sp<ICameraProvider> provider,
@@ -5522,7 +5939,8 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
- castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5);
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
+ castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
*useHalBufManager = false;
status = find_camera_metadata_ro_entry(staticMeta,
@@ -5657,12 +6075,20 @@
void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
- sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/) {
+ sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
+ sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/) {
ASSERT_NE(nullptr, session3_3);
ASSERT_NE(nullptr, session3_4);
ASSERT_NE(nullptr, session3_5);
+ ASSERT_NE(nullptr, session3_6);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_6: {
+ auto castResult = device::V3_6::ICameraDeviceSession::castFrom(session);
+ ASSERT_TRUE(castResult.isOk());
+ *session3_6 = castResult;
+ }
+ [[fallthrough]];
case CAMERA_DEVICE_API_VERSION_3_5: {
auto castResult = device::V3_5::ICameraDeviceSession::castFrom(session);
ASSERT_TRUE(castResult.isOk());
@@ -6261,7 +6687,8 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
ASSERT_NE(nullptr, session3_5.get());
hidl_vec<int32_t> streamIds(1);
diff --git a/current.txt b/current.txt
index 477e634..b4a30a0 100644
--- a/current.txt
+++ b/current.txt
@@ -675,7 +675,7 @@
3646950b10f7cacdafca13609b0e18496cea942f3bdfe920494661856eff48bb android.hardware.neuralnetworks@1.3::types
3e01d4446cd69fd1c48f8572efd97487bc179564b32bd795800b97bbe10be37b android.hardware.wifi@1.4::IWifi
c67aaf26a7a40d14ea61e70e20afacbd0bb906df1704d585ac8599fbb69dd44b android.hardware.wifi.hostapd@1.2::IHostapd
-11f6448d15336361180391c8ebcdfd2d7cf77b3782d577e594d583aadc9c2877 android.hardware.wifi.hostapd@1.2::types
+2b5a7ea572b736030c64a3b4043af244425477c4672301780fe15aba5ed393d9 android.hardware.wifi.hostapd@1.2::types
a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardware.wifi.supplicant@1.3::ISupplicant
8aed0a8e03e7a67bfdfb78ad7529a9ae95bea36e6060473b204c89d772522126 android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
def77c7db95d374f11a111bfc4ed60f92451303642a43276c4e291988fcee625 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
diff --git a/wifi/hostapd/1.2/types.hal b/wifi/hostapd/1.2/types.hal
index 54e6529..9c187fa 100644
--- a/wifi/hostapd/1.2/types.hal
+++ b/wifi/hostapd/1.2/types.hal
@@ -38,6 +38,9 @@
WLAN_REASON_DISASSOC_AP_BUSY = 5,
};
+/**
+ * Mac Address type. 6 octets representing physical address of a device.
+ */
typedef uint8_t[6] MacAddress;
/**