diff --git a/automotive/evs/1.1/Android.bp b/automotive/evs/1.1/Android.bp index c850c91b21..d2e85f1304 100644 --- a/automotive/evs/1.1/Android.bp +++ b/automotive/evs/1.1/Android.bp @@ -10,15 +10,13 @@ hidl_interface { "types.hal", "IEvsCamera.hal", "IEvsCameraStream.hal", - "IEvsEnumerator.hal", ], interfaces: [ "android.hardware.automotive.evs@1.0", - "android.hardware.camera.device@3.2", "android.hardware.graphics.common@1.0", "android.hardware.graphics.common@1.1", "android.hardware.graphics.common@1.2", "android.hidl.base@1.0", ], - gen_java: false, + gen_java: true, } diff --git a/automotive/evs/1.1/IEvsCamera.hal b/automotive/evs/1.1/IEvsCamera.hal index 975b6c6cae..21ca79e91f 100644 --- a/automotive/evs/1.1/IEvsCamera.hal +++ b/automotive/evs/1.1/IEvsCamera.hal @@ -25,14 +25,6 @@ import IEvsCameraStream; * Represents a single camera and is the primary interface for capturing images. */ interface IEvsCamera extends @1.0::IEvsCamera { - /** - * Returns the description of this camera. - * - * @return info The description of this camera. This must be the same value as - * reported by EvsEnumerator::getCameraList_1_1(). - */ - getCameraInfo_1_1() generates (CameraDesc info); - /** * Requests to pause EVS camera stream events. * @@ -108,27 +100,7 @@ interface IEvsCamera extends @1.0::IEvsCamera { unsetMaster() generates (EvsResult result); /** - * Retrieves a list of parameters this camera supports. - * - * @return params A list of CameraParam that this camera supports. - */ - getParameterList() generates (vec params); - - /** - * Requests a valid value range of a camera parameter - * - * @param id The identifier of camera parameter, CameraParam enum. - * - * @return min The lower bound of valid parameter value range. - * @return max The upper bound of valid parameter value range. - * @return step The resolution of values in valid range. - */ - getIntParameterRange(CameraParam id) - generates (int32_t min, int32_t max, int32_t step); - - /** - * Requests to set a camera parameter. Only a request from the master - * client will be processed successfully. + * Requests to set a camera parameter. * * @param id The identifier of camera parameter, CameraParam enum. * value A desired parameter value. @@ -142,7 +114,7 @@ interface IEvsCamera extends @1.0::IEvsCamera { * from what the client gives if, for example, the * driver does not support a target parameter. */ - setIntParameter(CameraParam id, int32_t value) + setParameter(CameraParam id, int32_t value) generates (EvsResult result, int32_t effectiveValue); /** @@ -154,5 +126,5 @@ interface IEvsCamera extends @1.0::IEvsCamera { * not supported. * value A value of requested camera parameter. */ - getIntParameter(CameraParam id) generates(EvsResult result, int32_t value); + getParameter(CameraParam id) generates(EvsResult result, int32_t value); }; diff --git a/automotive/evs/1.1/IEvsCameraStream.hal b/automotive/evs/1.1/IEvsCameraStream.hal index 9e4ea19f1d..7c7f832103 100644 --- a/automotive/evs/1.1/IEvsCameraStream.hal +++ b/automotive/evs/1.1/IEvsCameraStream.hal @@ -17,32 +17,15 @@ package android.hardware.automotive.evs@1.1; import @1.0::IEvsCameraStream; -import @1.1::BufferDesc; -import @1.1::EvsEvent; /** * Implemented on client side to receive asynchronous streaming event deliveries. */ interface IEvsCameraStream extends @1.0::IEvsCameraStream { - - /** - * Receives calls from the HAL each time a video frame is ready for inspection. - * Buffer handles received by this method must be returned via calls to - * IEvsCamera::doneWithFrame_1_1(). When the video stream is stopped via a call - * to IEvsCamera::stopVideoStream(), this callback may continue to happen for - * some time as the pipeline drains. Each frame must still be returned. - * When the last frame in the stream has been delivered, STREAM_STOPPED - * event must be delivered. No further frame deliveries may happen - * thereafter. - * - * @param buffer a buffer descriptor of a delivered image frame. - */ - oneway deliverFrame_1_1(BufferDesc buffer); - /** * Receives calls from the HAL each time an event happens. * * @param event EVS event with possible event information. */ - oneway notify(EvsEvent event); + oneway notifyEvent(EvsEvent event); }; diff --git a/automotive/evs/1.1/IEvsEnumerator.hal b/automotive/evs/1.1/IEvsEnumerator.hal deleted file mode 100644 index 1695821baa..0000000000 --- a/automotive/evs/1.1/IEvsEnumerator.hal +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.automotive.evs@1.1; - -import IEvsCamera; -import @1.0::IEvsEnumerator; -import @1.0::EvsResult; -import android.hardware.camera.device@3.2::Stream; - -/** - * Provides the mechanism for EVS camera discovery - */ -interface IEvsEnumerator extends @1.0::IEvsEnumerator { - /** - * Returns a list of all EVS cameras available to the system - * - * @return cameras A list of cameras availale for EVS service. - */ - getCameraList_1_1() generates (vec cameras); - - /** - * Gets the IEvsCamera associated with a cameraId from a CameraDesc - * - * Given a camera's unique cameraId from CameraDesc, returns the - * IEvsCamera interface associated with the specified camera. When - * done using the camera, the caller may release it by calling closeCamera(). - * - * @param cameraId A unique identifier of the camera. - * @param streamCfg A stream configuration the client wants to use. - * @return evsCamera EvsCamera object associated with a given cameraId. - * Returned object would be null if a camera device does - * not support a given stream configuration or is already - * configured differently by another client. - */ - openCamera_1_1(string cameraId, Stream streamCfg) generates (IEvsCamera evsCamera); -}; diff --git a/automotive/evs/1.1/default/Android.bp b/automotive/evs/1.1/default/Android.bp index 41cb4265e5..a46347102f 100644 --- a/automotive/evs/1.1/default/Android.bp +++ b/automotive/evs/1.1/default/Android.bp @@ -7,41 +7,25 @@ cc_binary { "service.cpp", "EvsCamera.cpp", "EvsEnumerator.cpp", - "EvsDisplay.cpp", - "ConfigManager.cpp", - "ConfigManagerUtil.cpp", + "EvsDisplay.cpp" ], init_rc: ["android.hardware.automotive.evs@1.1-service.rc"], shared_libs: [ "android.hardware.automotive.evs@1.0", "android.hardware.automotive.evs@1.1", - "android.hardware.camera.device@3.2", "libbase", "libbinder", - "liblog", + "libcutils", "libhardware", "libhidlbase", "liblog", "libui", "libutils", - "libcamera_metadata", - "libtinyxml2", ], cflags: [ "-O0", "-g", ], - - required: [ - "evs_default_configuration.xml", - ], -} - -prebuilt_etc { - name: "evs_default_configuration.xml", - - src: "resources/evs_default_configuration.xml", - sub_dir: "automotive/evs", } diff --git a/automotive/evs/1.1/default/ConfigManager.cpp b/automotive/evs/1.1/default/ConfigManager.cpp deleted file mode 100644 index 4f46f9dbca..0000000000 --- a/automotive/evs/1.1/default/ConfigManager.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include -#include -#include - -#include "ConfigManager.h" - -using ::android::hardware::camera::device::V3_2::StreamRotation; - - -ConfigManager::~ConfigManager() { - /* Nothing to do */ -} - - -void ConfigManager::readCameraInfo(const XMLElement * const aCameraElem) { - if (aCameraElem == nullptr) { - ALOGW("XML file does not have required camera element"); - return; - } - - const XMLElement *curElem = aCameraElem->FirstChildElement(); - while (curElem != nullptr) { - if (!strcmp(curElem->Name(), "group")) { - /* camera group identifier */ - const char *group_id = curElem->FindAttribute("group_id")->Value(); - - /* create CameraGroup */ - unique_ptr aCameraGroup(new ConfigManager::CameraGroup()); - - /* add a camera device to its group */ - addCameraDevices(curElem->FindAttribute("device_id")->Value(), aCameraGroup); - - /* a list of camera stream configurations */ - const XMLElement *childElem = - curElem->FirstChildElement("caps")->FirstChildElement("stream"); - while (childElem != nullptr) { - /* read 5 attributes */ - const XMLAttribute *idAttr = childElem->FindAttribute("id"); - const XMLAttribute *widthAttr = childElem->FindAttribute("width"); - const XMLAttribute *heightAttr = childElem->FindAttribute("height"); - const XMLAttribute *fmtAttr = childElem->FindAttribute("format"); - const XMLAttribute *fpsAttr = childElem->FindAttribute("framerate"); - - const int32_t id = stoi(idAttr->Value()); - int32_t framerate = 0; - if (fpsAttr != nullptr) { - framerate = stoi(fpsAttr->Value()); - } - - int32_t pixFormat; - if (ConfigManagerUtil::convertToPixelFormat(fmtAttr->Value(), - pixFormat)) { - RawStreamConfiguration cfg = { - id, - stoi(widthAttr->Value()), - stoi(heightAttr->Value()), - pixFormat, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - framerate - }; - aCameraGroup->streamConfigurations[id] = cfg; - } - - childElem = childElem->NextSiblingElement("stream"); - } - - /* camera group synchronization */ - const char *sync = curElem->FindAttribute("synchronized")->Value(); - aCameraGroup->synchronized = - static_cast(strcmp(sync, "false")); - - /* add a group to hash map */ - mCameraGroups[group_id] = std::move(aCameraGroup); - } else if (!strcmp(curElem->Name(), "device")) { - /* camera unique identifier */ - const char *id = curElem->FindAttribute("id")->Value(); - - /* camera mount location */ - const char *pos = curElem->FindAttribute("position")->Value(); - - /* store read camera module information */ - mCameraInfo[id] = readCameraDeviceInfo(curElem); - - /* assign a camera device to a position group */ - mCameraPosition[pos].emplace(id); - } else { - /* ignore other device types */ - ALOGD("Unknown element %s is ignored", curElem->Name()); - } - - curElem = curElem->NextSiblingElement(); - } -} - - -unique_ptr -ConfigManager::readCameraDeviceInfo(const XMLElement *aDeviceElem) { - if (aDeviceElem == nullptr) { - return nullptr; - } - - /* create a CameraInfo to be filled */ - unique_ptr aCamera(new ConfigManager::CameraInfo()); - - /* size information to allocate camera_metadata_t */ - size_t totalEntries = 0; - size_t totalDataSize = 0; - - /* read device capabilities */ - totalEntries += - readCameraCapabilities(aDeviceElem->FirstChildElement("caps"), - aCamera, - totalDataSize); - - - /* read camera metadata */ - totalEntries += - readCameraMetadata(aDeviceElem->FirstChildElement("characteristics"), - aCamera, - totalDataSize); - - /* construct camera_metadata_t */ - if (!constructCameraMetadata(aCamera, totalEntries, totalDataSize)) { - ALOGW("Either failed to allocate memory or " - "allocated memory was not large enough"); - } - - return aCamera; -} - - -size_t ConfigManager::readCameraCapabilities(const XMLElement * const aCapElem, - unique_ptr &aCamera, - size_t &dataSize) { - if (aCapElem == nullptr) { - return 0; - } - - string token; - const XMLElement *curElem = nullptr; - - /* a list of supported camera parameters/controls */ - curElem = aCapElem->FirstChildElement("supported_controls"); - if (curElem != nullptr) { - const XMLElement *ctrlElem = curElem->FirstChildElement("control"); - while (ctrlElem != nullptr) { - const char *nameAttr = ctrlElem->FindAttribute("name")->Value();; - const int32_t minVal = stoi(ctrlElem->FindAttribute("min")->Value()); - const int32_t maxVal = stoi(ctrlElem->FindAttribute("max")->Value()); - - int32_t stepVal = 1; - const XMLAttribute *stepAttr = ctrlElem->FindAttribute("step"); - if (stepAttr != nullptr) { - stepVal = stoi(stepAttr->Value()); - } - - CameraParam aParam; - if (ConfigManagerUtil::convertToEvsCameraParam(nameAttr, - aParam)) { - aCamera->controls.emplace( - aParam, - make_tuple(minVal, maxVal, stepVal) - ); - } - - ctrlElem = ctrlElem->NextSiblingElement("control"); - } - } - - /* a list of camera stream configurations */ - curElem = aCapElem->FirstChildElement("stream"); - while (curElem != nullptr) { - /* read 5 attributes */ - const XMLAttribute *idAttr = curElem->FindAttribute("id"); - const XMLAttribute *widthAttr = curElem->FindAttribute("width"); - const XMLAttribute *heightAttr = curElem->FindAttribute("height"); - const XMLAttribute *fmtAttr = curElem->FindAttribute("format"); - const XMLAttribute *fpsAttr = curElem->FindAttribute("framerate"); - - const int32_t id = stoi(idAttr->Value()); - int32_t framerate = 0; - if (fpsAttr != nullptr) { - framerate = stoi(fpsAttr->Value()); - } - - int32_t pixFormat; - if (ConfigManagerUtil::convertToPixelFormat(fmtAttr->Value(), - pixFormat)) { - RawStreamConfiguration cfg = { - id, - stoi(widthAttr->Value()), - stoi(heightAttr->Value()), - pixFormat, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - framerate - }; - aCamera->streamConfigurations[id] = cfg; - } - - curElem = curElem->NextSiblingElement("stream"); - } - - dataSize = calculate_camera_metadata_entry_data_size( - get_camera_metadata_tag_type( - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS - ), - aCamera->streamConfigurations.size() * kStreamCfgSz - ); - - /* a single camera metadata entry contains multiple stream configurations */ - return dataSize > 0 ? 1 : 0; -} - - -size_t ConfigManager::readCameraMetadata(const XMLElement * const aParamElem, - unique_ptr &aCamera, - size_t &dataSize) { - if (aParamElem == nullptr) { - return 0; - } - - const XMLElement *curElem = aParamElem->FirstChildElement("parameter"); - size_t numEntries = 0; - camera_metadata_tag_t tag; - while (curElem != nullptr) { - if (!ConfigManagerUtil::convertToMetadataTag(curElem->FindAttribute("name")->Value(), - tag)) { - switch(tag) { - case ANDROID_LENS_DISTORTION: - case ANDROID_LENS_POSE_ROTATION: - case ANDROID_LENS_POSE_TRANSLATION: - case ANDROID_LENS_INTRINSIC_CALIBRATION: { - /* float[] */ - size_t count = 0; - void *data = ConfigManagerUtil::convertFloatArray( - curElem->FindAttribute("size")->Value(), - curElem->FindAttribute("value")->Value(), - count - ); - - aCamera->cameraMetadata[tag] = - make_pair(make_unique(data), count); - - ++numEntries; - dataSize += calculate_camera_metadata_entry_data_size( - get_camera_metadata_tag_type(tag), count - ); - - break; - } - - default: - ALOGW("Parameter %s is not supported", - curElem->FindAttribute("name")->Value()); - break; - } - } - - curElem = curElem->NextSiblingElement("parameter"); - } - - return numEntries; -} - - -bool ConfigManager::constructCameraMetadata(unique_ptr &aCamera, - const size_t totalEntries, - const size_t totalDataSize) { - if (!aCamera->allocate(totalEntries, totalDataSize)) { - ALOGE("Failed to allocate memory for camera metadata"); - return false; - } - - const size_t numStreamConfigs = aCamera->streamConfigurations.size(); - unique_ptr data(new int32_t[kStreamCfgSz * numStreamConfigs]); - int32_t *ptr = data.get(); - for (auto &cfg : aCamera->streamConfigurations) { - for (auto i = 0; i < kStreamCfgSz; ++i) { - *ptr++ = cfg.second[i]; - } - } - int32_t err = add_camera_metadata_entry(aCamera->characteristics, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, - data.get(), - numStreamConfigs * kStreamCfgSz); - - if (err) { - ALOGE("Failed to add stream configurations to metadata, ignored"); - return false; - } - - bool success = true; - for (auto &[tag, entry] : aCamera->cameraMetadata) { - /* try to add new camera metadata entry */ - int32_t err = add_camera_metadata_entry(aCamera->characteristics, - tag, - entry.first.get(), - entry.second); - if (err) { - ALOGE("Failed to add an entry with a tag 0x%X", tag); - - /* may exceed preallocated capacity */ - ALOGE("Camera metadata has %ld / %ld entries and %ld / %ld bytes are filled", - get_camera_metadata_entry_count(aCamera->characteristics), - get_camera_metadata_entry_capacity(aCamera->characteristics), - get_camera_metadata_data_count(aCamera->characteristics), - get_camera_metadata_data_capacity(aCamera->characteristics)); - ALOGE("\tCurrent metadata entry requires %ld bytes", - calculate_camera_metadata_entry_data_size(tag, entry.second)); - - success = false; - } - } - - ALOGV("Camera metadata has %ld / %ld entries and %ld / %ld bytes are filled", - get_camera_metadata_entry_count(aCamera->characteristics), - get_camera_metadata_entry_capacity(aCamera->characteristics), - get_camera_metadata_data_count(aCamera->characteristics), - get_camera_metadata_data_capacity(aCamera->characteristics)); - - return success; -} - - -void ConfigManager::readSystemInfo(const XMLElement * const aSysElem) { - if (aSysElem == nullptr) { - return; - } - - /* - * Please note that this function assumes that a given system XML element - * and its child elements follow DTD. If it does not, it will cause a - * segmentation fault due to the failure of finding expected attributes. - */ - - /* read number of cameras available in the system */ - const XMLElement *xmlElem = aSysElem->FirstChildElement("num_cameras"); - if (xmlElem != nullptr) { - mSystemInfo.numCameras = - stoi(xmlElem->FindAttribute("value")->Value()); - } -} - - -void ConfigManager::readDisplayInfo(const XMLElement * const aDisplayElem) { - if (aDisplayElem == nullptr) { - ALOGW("XML file does not have required camera element"); - return; - } - - const XMLElement *curDev = aDisplayElem->FirstChildElement("device"); - while (curDev != nullptr) { - const char *id = curDev->FindAttribute("id")->Value(); - //const char *pos = curDev->FirstAttribute("position")->Value(); - - unique_ptr dpy(new DisplayInfo()); - if (dpy == nullptr) { - ALOGE("Failed to allocate memory for DisplayInfo"); - return; - } - - const XMLElement *cap = curDev->FirstChildElement("caps"); - if (cap != nullptr) { - const XMLElement *curStream = cap->FirstChildElement("stream"); - while (curStream != nullptr) { - /* read 4 attributes */ - const XMLAttribute *idAttr = curStream->FindAttribute("id"); - const XMLAttribute *widthAttr = curStream->FindAttribute("width"); - const XMLAttribute *heightAttr = curStream->FindAttribute("height"); - const XMLAttribute *fmtAttr = curStream->FindAttribute("format"); - - const int32_t id = stoi(idAttr->Value()); - int32_t pixFormat; - if (ConfigManagerUtil::convertToPixelFormat(fmtAttr->Value(), - pixFormat)) { - RawStreamConfiguration cfg = { - id, - stoi(widthAttr->Value()), - stoi(heightAttr->Value()), - pixFormat, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT, - 0 // unused - }; - dpy->streamConfigurations[id] = cfg; - } - - curStream = curStream->NextSiblingElement("stream"); - } - } - - mDisplayInfo[id] = std::move(dpy); - curDev = curDev->NextSiblingElement("device"); - } - - return; -} - - -bool ConfigManager::readConfigDataFromXML() noexcept { - XMLDocument xmlDoc; - - const int64_t parsingStart = android::elapsedRealtimeNano(); - - /* load and parse a configuration file */ - xmlDoc.LoadFile(mConfigFilePath); - if (xmlDoc.ErrorID() != XML_SUCCESS) { - ALOGE("Failed to load and/or parse a configuration file, %s", xmlDoc.ErrorStr()); - return false; - } - - /* retrieve the root element */ - const XMLElement *rootElem = xmlDoc.RootElement(); - if (strcmp(rootElem->Name(), "configuration")) { - ALOGE("A configuration file is not in the required format. " - "See /etc/automotive/evs/evs_configuration.dtd"); - return false; - } - - /* - * parse camera information; this needs to be done before reading system - * information - */ - readCameraInfo(rootElem->FirstChildElement("camera")); - - /* parse system information */ - readSystemInfo(rootElem->FirstChildElement("system")); - - /* parse display information */ - readDisplayInfo(rootElem->FirstChildElement("display")); - - const int64_t parsingEnd = android::elapsedRealtimeNano(); - ALOGI("Parsing configuration file takes %lf (ms)", - (double)(parsingEnd - parsingStart) / 1000000.0); - - - return true; -} - - -void ConfigManager::addCameraDevices(const char *devices, - unique_ptr &aGroup) { - stringstream device_list(devices); - string token; - while (getline(device_list, token, ',')) { - aGroup->devices.emplace(token); - } -} - - -std::unique_ptr ConfigManager::Create(const char *path) { - unique_ptr cfgMgr(new ConfigManager(path)); - - /* - * Read a configuration from XML file - * - * If this is too slow, ConfigManager::readConfigDataFromBinary() and - * ConfigManager::writeConfigDataToBinary()can serialize CameraInfo object - * to the filesystem and construct CameraInfo instead; this was - * evaluated as 10x faster. - */ - if (!cfgMgr->readConfigDataFromXML()) { - return nullptr; - } else { - return cfgMgr; - } -} - diff --git a/automotive/evs/1.1/default/ConfigManager.h b/automotive/evs/1.1/default/ConfigManager.h deleted file mode 100644 index 0275f904e5..0000000000 --- a/automotive/evs/1.1/default/ConfigManager.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef CONFIG_MANAGER_H -#define CONFIG_MANAGER_H - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "ConfigManagerUtil.h" - -using namespace std; -using namespace tinyxml2; - -using ::android::hardware::hidl_vec; -using ::android::hardware::camera::device::V3_2::Stream; -using ::android::hardware::automotive::evs::V1_1::CameraParam; - -/* - * Plese note that this is different from what is defined in - * libhardware/modules/camera/3_4/metadata/types.h; this has one additional - * field to store a framerate. - */ -const size_t kStreamCfgSz = 6; -typedef std::array RawStreamConfiguration; - -class ConfigManager { -public: - static std::unique_ptr Create(const char *path = ""); - ConfigManager(const ConfigManager&) = delete; - ConfigManager& operator=(const ConfigManager&) = delete; - - virtual ~ConfigManager(); - - /* Camera device's capabilities and metadata */ - class CameraInfo { - public: - CameraInfo() : - characteristics(nullptr) { - /* Nothing to do */ - } - - virtual ~CameraInfo() { - free_camera_metadata(characteristics); - } - - /* Allocate memory for camera_metadata_t */ - bool allocate(size_t entry_cap, size_t data_cap) { - if (characteristics != nullptr) { - ALOGE("Camera metadata is already allocated"); - return false; - } - - characteristics = allocate_camera_metadata(entry_cap, data_cap); - return characteristics != nullptr; - } - - /* - * List of supported controls that the master client can program. - * Paraemters are stored with its valid range - */ - unordered_map> controls; - - /* List of supported frame rates */ - unordered_set frameRates; - - /* - * List of supported output stream configurations; each array stores - * format, width, height, and direction values in the order. - */ - unordered_map streamConfigurations; - - /* - * Internal storage for camera metadata. Each entry holds a pointer to - * data and number of elements - */ - unordered_map, size_t>> cameraMetadata; - - /* Camera module characteristics */ - camera_metadata_t *characteristics; - }; - - class CameraGroup { - public: - CameraGroup() {} - - /* ID of member camera devices */ - unordered_set devices; - - /* The capture operation of member camera devices are synchronized */ - bool synchronized = false; - - /* - * List of stream configurations that are supposed by all camera devices - * in this group. - */ - unordered_map streamConfigurations; - }; - - class SystemInfo { - public: - /* number of available cameras */ - int32_t numCameras = 0; - }; - - class DisplayInfo { - public: - /* - * List of supported input stream configurations; each array stores - * format, width, height, and direction values in the order. - */ - unordered_map streamConfigurations; - }; - - /* - * Return system information - * - * @return SystemInfo - * Constant reference of SystemInfo. - */ - const SystemInfo &getSystemInfo() { - return mSystemInfo; - } - - /* - * Return a list of cameras - * - * This function assumes that it is not being called frequently. - * - * @return vector - * A vector that contains unique camera device identifiers. - */ - vector getCameraList() { - vector aList; - for (auto &v : mCameraInfo) { - aList.emplace_back(v.first); - } - - return aList; - } - - - /* - * Return a list of cameras - * - * @return CameraGroup - * A pointer to a camera group identified by a given id. - */ - unique_ptr& getCameraGroup(const string& gid) { - return mCameraGroups[gid]; - } - - - /* - * Return a camera metadata - * - * @param cameraId - * Unique camera node identifier in string - * - * @return unique_ptr - * A pointer to CameraInfo that is associated with a given camera - * ID. This returns a null pointer if this does not recognize a - * given camera identifier. - */ - unique_ptr& getCameraInfo(const string cameraId) noexcept { - return mCameraInfo[cameraId]; - } - -private: - /* Constructors */ - ConfigManager(const char *xmlPath) : - mConfigFilePath(xmlPath) { - } - - /* System configuration */ - SystemInfo mSystemInfo; - - /* Internal data structure for camera device information */ - unordered_map> mCameraInfo; - - /* Internal data structure for camera device information */ - unordered_map> mDisplayInfo; - - /* Camera groups are stored in hash map */ - unordered_map> mCameraGroups; - - /* - * Camera positions are stored in hash map. - * The position must be one of front, rear, left, and right. - */ - unordered_map> mCameraPosition; - - /* A path to XML configuration file */ - const char *mConfigFilePath; - - /* - * Parse a given EVS configuration file and store the information - * internally. - * - * @return bool - * True if it completes parsing a file successfully. - */ - bool readConfigDataFromXML() noexcept; - - /* - * read the information of the vehicle - * - * @param aSysElem - * A pointer to "system" XML element. - */ - void readSystemInfo(const XMLElement * const aSysElem); - - /* - * read the information of camera devices - * - * @param aCameraElem - * A pointer to "camera" XML element that may contain multiple - * "device" elements. - */ - void readCameraInfo(const XMLElement * const aCameraElem); - - /* - * read display device information - * - * @param aDisplayElem - * A pointer to "display" XML element that may contain multiple - * "device" elements. - */ - void readDisplayInfo(const XMLElement * const aDisplayElem); - - /* - * read camera device information - * - * @param aDeviceElem - * A pointer to "device" XML element that contains camera module - * capability info and its characteristics. - * - * @return unique_ptr - * A pointer to CameraInfo class that contains camera module - * capability and characteristics. Please note that this transfers - * the ownership of created CameraInfo to the caller. - */ - unique_ptr readCameraDeviceInfo(const XMLElement *aDeviceElem); - - /* - * read camera metadata - * - * @param aCapElem - * A pointer to "cap" XML element. - * @param aCamera - * A pointer to CameraInfo that is being filled by this method. - * @param dataSize - * Required size of memory to store camera metadata found in this - * method. This is calculated in this method and returned to the - * caller for camera_metadata allocation. - * - * @return size_t - * Number of camera metadata entries - */ - size_t readCameraCapabilities(const XMLElement * const aCapElem, - unique_ptr &aCamera, - size_t &dataSize); - - /* - * read camera metadata - * - * @param aParamElem - * A pointer to "characteristics" XML element. - * @param aCamera - * A pointer to CameraInfo that is being filled by this method. - * @param dataSize - * Required size of memory to store camera metadata found in this - * method. - * - * @return size_t - * Number of camera metadata entries - */ - size_t readCameraMetadata(const XMLElement * const aParamElem, - unique_ptr &aCamera, - size_t &dataSize); - - /* - * construct camera_metadata_t from camera capabilities and metadata - * - * @param aCamera - * A pointer to CameraInfo that is being filled by this method. - * @param totalEntries - * Number of camera metadata entries to be added. - * @param totalDataSize - * Sum of sizes of camera metadata entries to be added. - * - * @return bool - * False if either it fails to allocate memory for camera metadata - * or its size is not large enough to add all found camera metadata - * entries. - */ - bool constructCameraMetadata(unique_ptr &aCamera, - const size_t totalEntries, - const size_t totalDataSize); - - /* - * parse a comma-separated list of camera devices and add them to - * CameraGroup. - * - * @param devices - * A comma-separated list of camera device identifiers. - * @param aGroup - * Camera group which cameras will be added to. - */ - void addCameraDevices(const char *devices, - unique_ptr &aGroup); -}; -#endif // CONFIG_MANAGER_H - diff --git a/automotive/evs/1.1/default/ConfigManagerUtil.cpp b/automotive/evs/1.1/default/ConfigManagerUtil.cpp deleted file mode 100644 index 8206daa6d7..0000000000 --- a/automotive/evs/1.1/default/ConfigManagerUtil.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ConfigManagerUtil.h" - -#include -#include -#include - -#include -#include - - -bool ConfigManagerUtil::convertToEvsCameraParam(const string &id, - CameraParam &camParam) { - string trimmed = ConfigManagerUtil::trimString(id); - bool success = true; - - if (!trimmed.compare("BRIGHTNESS")) { - camParam = CameraParam::BRIGHTNESS; - } else if (!trimmed.compare("CONTRAST")) { - camParam = CameraParam::CONTRAST; - } else if (!trimmed.compare("AUTOGAIN")) { - camParam = CameraParam::AUTOGAIN; - } else if (!trimmed.compare("GAIN")) { - camParam = CameraParam::GAIN; - } else if (!trimmed.compare("AUTO_WHITE_BALANCE")) { - camParam = CameraParam::AUTO_WHITE_BALANCE; - } else if (!trimmed.compare("WHITE_BALANCE_TEMPERATURE")) { - camParam = CameraParam::WHITE_BALANCE_TEMPERATURE; - } else if (!trimmed.compare("SHARPNESS")) { - camParam = CameraParam::SHARPNESS; - } else if (!trimmed.compare("AUTO_EXPOSURE")) { - camParam = CameraParam::AUTO_EXPOSURE; - } else if (!trimmed.compare("ABSOLUTE_EXPOSURE")) { - camParam = CameraParam::ABSOLUTE_EXPOSURE; - } else if (!trimmed.compare("ABSOLUTE_FOCUS")) { - camParam = CameraParam::ABSOLUTE_FOCUS; - } else if (!trimmed.compare("AUTO_FOCUS")) { - camParam = CameraParam::AUTO_FOCUS; - } else if (!trimmed.compare("ABSOLUTE_ZOOM")) { - camParam = CameraParam::ABSOLUTE_ZOOM; - } else { - success = false; - } - - return success; -} - - -bool ConfigManagerUtil::convertToPixelFormat(const string &format, - int32_t &pixFormat) { - string trimmed = ConfigManagerUtil::trimString(format); - bool success = true; - - if (!trimmed.compare("RGBA_8888")) { - pixFormat = HAL_PIXEL_FORMAT_RGBA_8888; - } else if (!trimmed.compare("YCRCB_420_SP")) { - pixFormat = HAL_PIXEL_FORMAT_YCRCB_420_SP; - } else if (!trimmed.compare("YCBCR_422_I")) { - pixFormat = HAL_PIXEL_FORMAT_YCBCR_422_I; - } else { - success = false; - } - - return success; -} - - -bool ConfigManagerUtil::convertToMetadataTag(const char *name, - camera_metadata_tag &aTag) { - if (!strcmp(name, "LENS_DISTORTION")) { - aTag = ANDROID_LENS_DISTORTION; - } else if (!strcmp(name, "LENS_INTRINSIC_CALIBRATION")) { - aTag = ANDROID_LENS_INTRINSIC_CALIBRATION; - } else if (!strcmp(name, "LENS_POSE_ROTATION")) { - aTag = ANDROID_LENS_POSE_ROTATION; - } else if (!strcmp(name, "LENS_POSE_TRANSLATION")) { - aTag = ANDROID_LENS_POSE_TRANSLATION; - } else { - return false; - } - - return true; -} - - -float *ConfigManagerUtil::convertFloatArray(const char *sz, const char *vals, - size_t &count, const char delimiter) { - string size_string(sz); - string value_string(vals); - - count = stoi(size_string); - float *result = new float[count]; - stringstream values(value_string); - - int32_t idx = 0; - string token; - while (getline(values, token, delimiter)) { - result[idx++] = stof(token); - } - - return result; -} - - -string ConfigManagerUtil::trimString(const string &src, const string &ws) { - const auto s = src.find_first_not_of(ws); - if (s == string::npos) { - return ""; - } - - const auto e = src.find_last_not_of(ws); - const auto r = e - s + 1; - - return src.substr(s, r); -} - diff --git a/automotive/evs/1.1/default/ConfigManagerUtil.h b/automotive/evs/1.1/default/ConfigManagerUtil.h deleted file mode 100644 index 8c89ae7745..0000000000 --- a/automotive/evs/1.1/default/ConfigManagerUtil.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef CONFIG_MANAGER_UTIL_H -#define CONFIG_MANAGER_UTIL_H - -#include -#include -#include -#include - -using namespace std; -using ::android::hardware::automotive::evs::V1_1::CameraParam; - - -class ConfigManagerUtil { -public: - /** - * Convert a given string into V4L2_CID_* - */ - static bool convertToEvsCameraParam(const string &id, - CameraParam &camParam); - /** - * Convert a given string into android.hardware.graphics.common.PixelFormat - */ - static bool convertToPixelFormat(const string &format, - int32_t &pixelFormat); - /** - * Convert a given string into corresponding camera metadata data tag defined in - * system/media/camera/include/system/camera_metadta_tags.h - */ - static bool convertToMetadataTag(const char *name, - camera_metadata_tag &aTag); - /** - * Convert a given string into a floating value array - */ - static float *convertFloatArray(const char *sz, - const char *vals, - size_t &count, - const char delimiter = ','); - /** - * Trim a string - */ - static string trimString(const string &src, - const string &ws = " \n\r\t\f\v"); -}; - -#endif // CONFIG_MANAGER_UTIL_H - diff --git a/automotive/evs/1.1/default/EvsCamera.cpp b/automotive/evs/1.1/default/EvsCamera.cpp index 5ba753da2e..2d55566349 100644 --- a/automotive/evs/1.1/default/EvsCamera.cpp +++ b/automotive/evs/1.1/default/EvsCamera.cpp @@ -40,21 +40,28 @@ const char EvsCamera::kCameraName_Backup[] = "backup"; const unsigned MAX_BUFFERS_IN_FLIGHT = 100; -EvsCamera::EvsCamera(const char *id, - unique_ptr &camInfo) : +EvsCamera::EvsCamera(const char *id) : mFramesAllowed(0), mFramesInUse(0), - mStreamState(STOPPED), - mCameraInfo(camInfo) { + mStreamState(STOPPED) { ALOGD("EvsCamera instantiated"); - /* set a camera id */ - mDescription.v1.cameraId = id; + mDescription.cameraId = id; - /* set camera metadata */ - mDescription.metadata.setToExternal((uint8_t *)camInfo->characteristics, - get_camera_metadata_size(camInfo->characteristics)); + // Set up dummy data for testing + if (mDescription.cameraId == kCameraName_Backup) { + mWidth = 640; // full NTSC/VGA + mHeight = 480; // full NTSC/VGA + mDescription.vendorFlags = 0xFFFFFFFF; // Arbitrary value + } else { + mWidth = 320; // 1/2 NTSC/VGA + mHeight = 240; // 1/2 NTSC/VGA + } + + mFormat = HAL_PIXEL_FORMAT_RGBA_8888; + mUsage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE | + GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY; } @@ -102,7 +109,7 @@ Return EvsCamera::getCameraInfo(getCameraInfo_cb _hidl_cb) { ALOGD("getCameraInfo"); // Send back our self description - _hidl_cb(mDescription.v1); + _hidl_cb(mDescription); return Void(); } @@ -187,7 +194,7 @@ Return EvsCamera::stopVideoStream() { // Block outside the mutex until the "stop" flag has been acknowledged // We won't send any more frames, but the client might still get some already in flight - ALOGD("Waiting for stream thread to end..."); + ALOGD("Waiting for stream thread to end.."); lock.unlock(); mCaptureThread.join(); lock.lock(); @@ -231,15 +238,6 @@ Return EvsCamera::setExtendedInfo(uint32_t /*opaqueIdentifier*/, int3 // Methods from ::android::hardware::automotive::evs::V1_1::IEvsCamera follow. -Return EvsCamera::getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) { - ALOGD("getCameraInfo_1_1"); - - // Send back our self description - _hidl_cb(mDescription); - return Void(); -} - - Return EvsCamera::doneWithFrame_1_1(const BufferDesc_1_1& bufDesc) { std::lock_guard lock(mAccessLock); returnBuffer(bufDesc.bufferId, bufDesc.buffer.nativeHandle); @@ -280,29 +278,8 @@ Return EvsCamera::unsetMaster() { } -Return EvsCamera::getParameterList(getParameterList_cb _hidl_cb) { - hidl_vec hidlCtrls; - hidlCtrls.resize(mCameraInfo->controls.size()); - unsigned idx = 0; - for (auto& [cid, cfg] : mCameraInfo->controls) { - hidlCtrls[idx++] = cid; - } - - _hidl_cb(hidlCtrls); - return Void(); -} - - -Return EvsCamera::getIntParameterRange(CameraParam id, - getIntParameterRange_cb _hidl_cb) { - auto range = mCameraInfo->controls[id]; - _hidl_cb(get<0>(range), get<1>(range), get<2>(range)); - return Void(); -} - - -Return EvsCamera::setIntParameter(CameraParam id, int32_t value, - setIntParameter_cb _hidl_cb) { +Return EvsCamera::setParameter(CameraParam id, int32_t value, + setParameter_cb _hidl_cb) { // Default implementation does not support this. (void)id; (void)value; @@ -311,8 +288,7 @@ Return EvsCamera::setIntParameter(CameraParam id, int32_t value, } -Return EvsCamera::getIntParameter(CameraParam id, - getIntParameter_cb _hidl_cb) { +Return EvsCamera::getParameter(CameraParam id, getParameter_cb _hidl_cb) { // Default implementation does not support this. (void)id; _hidl_cb(EvsResult::INVALID_ARG, 0); @@ -495,7 +471,9 @@ void EvsCamera::generateFrames() { fillTestFrame(newBuffer); // Issue the (asynchronous) callback to the client -- can't be holding the lock - auto result = mStream->deliverFrame_1_1(newBuffer); + EvsEvent event; + event.buffer(newBuffer); + auto result = mStream->notifyEvent(event); if (result.isOk()) { ALOGD("Delivered %p as id %d", newBuffer.buffer.nativeHandle.getNativeHandle(), newBuffer.bufferId); @@ -528,8 +506,10 @@ void EvsCamera::generateFrames() { // If we've been asked to stop, send an event to signal the actual end of stream EvsEvent event; - event.aType = EvsEventType::STREAM_STOPPED; - auto result = mStream->notify(event); + InfoEventDesc desc = {}; + desc.aType = InfoEventType::STREAM_STOPPED; + event.info(desc); + auto result = mStream->notifyEvent(event); if (!result.isOk()) { ALOGE("Error delivering end of stream marker"); } @@ -636,38 +616,6 @@ void EvsCamera::returnBuffer(const uint32_t bufferId, const buffer_handle_t memH } -sp EvsCamera::Create(const char *deviceName) { - unique_ptr nullCamInfo = nullptr; - - return Create(deviceName, nullCamInfo); -} - - -sp EvsCamera::Create(const char *deviceName, - unique_ptr &camInfo, - const Stream *streamCfg) { - sp evsCamera = new EvsCamera(deviceName, camInfo); - if (evsCamera == nullptr) { - return nullptr; - } - - /* default implementation does not use a given configuration */ - (void)streamCfg; - - /* Use the first resolution from the list for the testing */ - auto it = camInfo->streamConfigurations.begin(); - evsCamera->mWidth = it->second[1]; - evsCamera->mHeight = it->second[2]; - evsCamera->mDescription.v1.vendorFlags = 0xFFFFFFFF; // Arbitrary test value - - evsCamera->mFormat = HAL_PIXEL_FORMAT_RGBA_8888; - evsCamera->mUsage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE | - GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY; - - return evsCamera; -} - - } // namespace implementation } // namespace V1_0 } // namespace evs diff --git a/automotive/evs/1.1/default/EvsCamera.h b/automotive/evs/1.1/default/EvsCamera.h index c15b4b117b..47a3164892 100644 --- a/automotive/evs/1.1/default/EvsCamera.h +++ b/automotive/evs/1.1/default/EvsCamera.h @@ -25,8 +25,6 @@ #include -#include "ConfigManager.h" - using BufferDesc_1_0 = ::android::hardware::automotive::evs::V1_0::BufferDesc; using BufferDesc_1_1 = ::android::hardware::automotive::evs::V1_1::BufferDesc; using IEvsCameraStream_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCameraStream; @@ -61,28 +59,18 @@ public: Return setExtendedInfo(uint32_t opaqueIdentifier, int32_t opaqueValue) override; // Methods from ::android::hardware::automotive::evs::V1_1::IEvsCamera follow. - Return getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) override; Return pauseVideoStream() override; Return resumeVideoStream() override; Return doneWithFrame_1_1(const BufferDesc_1_1& buffer) override; Return setMaster() override; Return forceMaster(const sp& display) override; Return unsetMaster() override; - Return getParameterList(getParameterList_cb _hidl_cb) override; - Return getIntParameterRange(CameraParam id, - getIntParameterRange_cb _hidl_cb) override; - Return setIntParameter(CameraParam id, int32_t value, - setIntParameter_cb _hidl_cb) override; - Return getIntParameter(CameraParam id, - getIntParameter_cb _hidl_cb) override; - - static sp Create(const char *deviceName); - static sp Create(const char *deviceName, - unique_ptr &camInfo, - const Stream *streamCfg = nullptr); - EvsCamera(const EvsCamera&) = delete; - EvsCamera& operator=(const EvsCamera&) = delete; + Return setParameter(CameraParam id, int32_t value, + setParameter_cb _hidl_cb) override; + Return getParameter(CameraParam id, getParameter_cb _hidl_cb) override; + // Implementation details + EvsCamera(const char *id); virtual ~EvsCamera() override; void forceShutdown(); // This gets called if another caller "steals" ownership of the camera @@ -91,10 +79,7 @@ public: static const char kCameraName_Backup[]; private: - EvsCamera(const char *id, - unique_ptr &camInfo); // These three functions are expected to be called while mAccessLock is held - // bool setAvailableFrames_Locked(unsigned bufferCount); unsigned increaseAvailableFrames_Locked(unsigned numToAdd); unsigned decreaseAvailableFrames_Locked(unsigned numToRemove); @@ -139,9 +124,6 @@ private: // Synchronization necessary to deconflict mCaptureThread from the main service thread std::mutex mAccessLock; - - // Static camera module information - unique_ptr &mCameraInfo; }; } // namespace implementation diff --git a/automotive/evs/1.1/default/EvsEnumerator.cpp b/automotive/evs/1.1/default/EvsEnumerator.cpp index a010729ce6..b3249071ae 100644 --- a/automotive/evs/1.1/default/EvsEnumerator.cpp +++ b/automotive/evs/1.1/default/EvsEnumerator.cpp @@ -33,7 +33,6 @@ namespace implementation { // constructs a new instance for each client. std::list EvsEnumerator::sCameraList; wp EvsEnumerator::sActiveDisplay; -unique_ptr EvsEnumerator::sConfigManager; EvsEnumerator::EvsEnumerator() { @@ -41,11 +40,9 @@ EvsEnumerator::EvsEnumerator() { // Add sample camera data to our list of cameras // In a real driver, this would be expected to can the available hardware - sConfigManager = - ConfigManager::Create("/etc/automotive/evs/evs_sample_configuration.xml"); - for (auto v : sConfigManager->getCameraList()) { - sCameraList.emplace_back(v.c_str()); - } + sCameraList.emplace_back(EvsCamera::kCameraName_Backup); + sCameraList.emplace_back("LaneView"); + sCameraList.emplace_back("right turn"); } @@ -60,7 +57,7 @@ Return EvsEnumerator::getCameraList(getCameraList_cb _hidl_cb) { std::vector descriptions; descriptions.reserve(numCameras); for (const auto& cam : sCameraList) { - descriptions.push_back( cam.desc.v1 ); + descriptions.push_back( cam.desc ); } // Encapsulate our camera descriptions in the HIDL vec type @@ -81,7 +78,7 @@ Return> EvsEnumerator::openCamera(const hidl_string& cameraId // Find the named camera CameraRecord *pRecord = nullptr; for (auto &&cam : sCameraList) { - if (cam.desc.v1.cameraId == cameraId) { + if (cam.desc.cameraId == cameraId) { // Found a match! pRecord = &cam; break; @@ -102,12 +99,7 @@ Return> EvsEnumerator::openCamera(const hidl_string& cameraId } // Construct a camera instance for the caller - if (sConfigManager == nullptr) { - pActiveCamera = EvsCamera::Create(cameraId.c_str()); - } else { - pActiveCamera = EvsCamera::Create(cameraId.c_str(), - sConfigManager->getCameraInfo(cameraId)); - } + pActiveCamera = new EvsCamera(cameraId.c_str()); pRecord->activeInstance = pActiveCamera; if (pActiveCamera == nullptr) { ALOGE("Failed to allocate new EvsCamera object for %s\n", cameraId.c_str()); @@ -128,15 +120,15 @@ Return EvsEnumerator::closeCamera(const ::android::sp& pCa // Get the camera id so we can find it in our list std::string cameraId; - pCamera_1_1->getCameraInfo_1_1([&cameraId](CameraDesc desc) { - cameraId = desc.v1.cameraId; + pCamera_1_1->getCameraInfo([&cameraId](CameraDesc desc) { + cameraId = desc.cameraId; } ); // Find the named camera CameraRecord *pRecord = nullptr; for (auto &&cam : sCameraList) { - if (cam.desc.v1.cameraId == cameraId) { + if (cam.desc.cameraId == cameraId) { // Found a match! pRecord = &cam; break; @@ -217,89 +209,6 @@ Return EvsEnumerator::getDisplayState() { } -// Methods from ::android::hardware::automotive::evs::V1_1::IEvsEnumerator follow. -Return EvsEnumerator::getCameraList_1_1(getCameraList_1_1_cb _hidl_cb) { - ALOGD("getCameraList"); - - const unsigned numCameras = sCameraList.size(); - - // Build up a packed array of CameraDesc for return - // NOTE: Only has to live until the callback returns - std::vector descriptions; - descriptions.reserve(numCameras); - for (const auto& cam : sCameraList) { - descriptions.push_back( cam.desc ); - } - - // Encapsulate our camera descriptions in the HIDL vec type - hidl_vec hidlCameras(descriptions); - - // Send back the results - ALOGD("reporting %zu cameras available", hidlCameras.size()); - _hidl_cb(hidlCameras); - - // HIDL convention says we return Void if we sent our result back via callback - return Void(); -} - -Return> -EvsEnumerator::openCamera_1_1(const hidl_string& cameraId, - const Stream& streamCfg) { - // Find the named camera - CameraRecord *pRecord = nullptr; - for (auto &&cam : sCameraList) { - if (cam.desc.v1.cameraId == cameraId) { - // Found a match! - pRecord = &cam; - break; - } - } - - // Is this a recognized camera id? - if (!pRecord) { - ALOGE("Requested camera %s not found", cameraId.c_str()); - return nullptr; - } - - // Has this camera already been instantiated by another caller? - sp pActiveCamera = pRecord->activeInstance.promote(); - if (pActiveCamera != nullptr) { - ALOGW("Killing previous camera because of new caller"); - closeCamera(pActiveCamera); - } - - // Construct a camera instance for the caller - if (sConfigManager == nullptr) { - pActiveCamera = EvsCamera::Create(cameraId.c_str()); - } else { - pActiveCamera = EvsCamera::Create(cameraId.c_str(), - sConfigManager->getCameraInfo(cameraId), - &streamCfg); - } - - pRecord->activeInstance = pActiveCamera; - if (pActiveCamera == nullptr) { - ALOGE("Failed to allocate new EvsCamera object for %s\n", cameraId.c_str()); - } - - return pActiveCamera; -} - - -EvsEnumerator::CameraRecord* EvsEnumerator::findCameraById(const std::string& cameraId) { - // Find the named camera - CameraRecord *pRecord = nullptr; - for (auto &&cam : sCameraList) { - if (cam.desc.v1.cameraId == cameraId) { - // Found a match! - pRecord = &cam; - break; - } - } - - return pRecord; -} - } // namespace implementation } // namespace V1_1 } // namespace evs diff --git a/automotive/evs/1.1/default/EvsEnumerator.h b/automotive/evs/1.1/default/EvsEnumerator.h index 475ec76b93..11c2170632 100644 --- a/automotive/evs/1.1/default/EvsEnumerator.h +++ b/automotive/evs/1.1/default/EvsEnumerator.h @@ -17,20 +17,18 @@ #ifndef ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_EVSCAMERAENUMERATOR_H #define ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_EVSCAMERAENUMERATOR_H -#include +#include #include #include -#include "ConfigManager.h" - using ::android::hardware::automotive::evs::V1_0::EvsResult; using ::android::hardware::automotive::evs::V1_0::IEvsDisplay; using ::android::hardware::automotive::evs::V1_0::DisplayState; +using ::android::hardware::automotive::evs::V1_0::IEvsEnumerator; using IEvsCamera_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCamera; using IEvsCamera_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCamera; using CameraDesc_1_0 = ::android::hardware::automotive::evs::V1_0::CameraDesc; -using CameraDesc_1_1 = ::android::hardware::automotive::evs::V1_1::CameraDesc; namespace android { @@ -55,11 +53,6 @@ public: Return closeDisplay(const ::android::sp& display) override; Return getDisplayState() override; - // Methods from ::android::hardware::automotive::evs::V1_1::IEvsEnumerator follow. - Return getCameraList_1_1(getCameraList_1_1_cb _hidl_cb) override; - Return> openCamera_1_1(const hidl_string& cameraId, - const Stream& streamCfg) override; - // Implementation details EvsEnumerator(); @@ -68,20 +61,14 @@ private: // That is to say, this is effectively a singleton despite the fact that HIDL // constructs a new instance for each client. struct CameraRecord { - CameraDesc_1_1 desc; + CameraDesc_1_0 desc; wp activeInstance; - CameraRecord(const char *cameraId) : desc() { desc.v1.cameraId = cameraId; } + CameraRecord(const char *cameraId) : desc() { desc.cameraId = cameraId; } }; + static std::list sCameraList; - static CameraRecord* findCameraById(const std::string& cameraId); - - static std::list sCameraList; - - // Weak pointer. Object destructs if client dies. - static wp sActiveDisplay; - - static unique_ptr sConfigManager; + static wp sActiveDisplay; // Weak pointer. Object destructs if client dies. }; } // namespace implementation diff --git a/automotive/evs/1.1/default/resources/evs_default_configuration.xml b/automotive/evs/1.1/default/resources/evs_default_configuration.xml deleted file mode 100644 index 692102ed38..0000000000 --- a/automotive/evs/1.1/default/resources/evs_default_configuration.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/automotive/evs/1.1/default/service.cpp b/automotive/evs/1.1/default/service.cpp index 5135864e88..128a14aa30 100644 --- a/automotive/evs/1.1/default/service.cpp +++ b/automotive/evs/1.1/default/service.cpp @@ -33,7 +33,7 @@ using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; // Generated HIDL files -using android::hardware::automotive::evs::V1_1::IEvsEnumerator; +using android::hardware::automotive::evs::V1_0::IEvsEnumerator; using android::hardware::automotive::evs::V1_0::IEvsDisplay; // The namespace in which all our implementation code lives diff --git a/automotive/evs/1.1/types.hal b/automotive/evs/1.1/types.hal index dcb2abb0e9..2c6b2ed589 100644 --- a/automotive/evs/1.1/types.hal +++ b/automotive/evs/1.1/types.hal @@ -21,22 +21,6 @@ import @1.0::DisplayDesc; import @1.0::DisplayState; import @1.0::EvsResult; import android.hardware.graphics.common@1.2::HardwareBuffer; -import android.hardware.camera.device@3.2::CameraMetadata; - -/** - * Structure describing the basic properties of an EVS camera, extended from its - * v1.0 declaration. - * - * The HAL is responsible for filling out this structure for each - * EVS camera in the system. - */ -struct CameraDesc { - @1.0::CameraDesc v1; - /** - * Store camera metadata such as lens characteristics. - */ - CameraMetadata metadata; -}; /** * Structure representing an image buffer through our APIs @@ -66,7 +50,7 @@ struct BufferDesc { /** * Types of informative streaming events */ -enum EvsEventType : uint32_t { +enum InfoEventType : uint32_t { /** * Video stream is started */ @@ -97,17 +81,31 @@ enum EvsEventType : uint32_t { /** * Structure that describes informative events occurred during EVS is streaming */ -struct EvsEvent { +struct InfoEventDesc { /** * Type of an informative event */ - EvsEventType aType; + InfoEventType aType; /** * Possible additional information */ uint32_t[4] payload; }; +/** + * EVS event definition + */ +safe_union EvsEvent { + /** + * A buffer descriptor of an image frame + */ + BufferDesc buffer; + /** + * General streaming events + */ + InfoEventDesc info; +}; + /** * EVS Camera Parameter */ @@ -128,6 +126,14 @@ enum CameraParam : uint32_t { * Gain control */ GAIN, + /** + * Mirror the image horizontally + */ + HFLIP, + /** + * Mirror the image vertically + */ + VFLIP, /** * Automatic Whitebalance */ @@ -149,6 +155,11 @@ enum CameraParam : uint32_t { * Manual exposure time of the camera */ ABSOLUTE_EXPOSURE, + /** + * When AEC is running in either auto or aperture priority, this parameter + * sets whether a frame rate varies. + */ + AUTO_EXPOSURE_PRIORITY, /** * Set the focal point of the camera to the specified position. This * parameter may not be effective when auto focus is enabled. diff --git a/automotive/evs/1.1/vts/functional/Android.bp b/automotive/evs/1.1/vts/functional/Android.bp index 4753933f7f..55c50a42b8 100644 --- a/automotive/evs/1.1/vts/functional/Android.bp +++ b/automotive/evs/1.1/vts/functional/Android.bp @@ -23,7 +23,6 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], shared_libs: [ "libui", - "libcamera_metadata", ], static_libs: [ "android.hardware.automotive.evs@1.0", @@ -32,7 +31,6 @@ cc_test { "android.hardware.graphics.common@1.0", "android.hardware.graphics.common@1.1", "android.hardware.graphics.common@1.2", - "android.hardware.camera.device@3.2", ], test_suites: ["general-tests"], cflags: [ diff --git a/automotive/evs/1.1/vts/functional/FrameHandler.cpp b/automotive/evs/1.1/vts/functional/FrameHandler.cpp index 6d53652f86..16276891f0 100644 --- a/automotive/evs/1.1/vts/functional/FrameHandler.cpp +++ b/automotive/evs/1.1/vts/functional/FrameHandler.cpp @@ -138,93 +138,93 @@ Return FrameHandler::deliverFrame(const BufferDesc_1_0& bufferArg) { } -Return FrameHandler::deliverFrame_1_1(const BufferDesc_1_1& bufDesc) { - const AHardwareBuffer_Desc* pDesc = - reinterpret_cast(&bufDesc.buffer.description); - ALOGD("Received a frame from the camera (%p)", - bufDesc.buffer.nativeHandle.getNativeHandle()); - - // Store a dimension of a received frame. - mFrameWidth = pDesc->width; - mFrameHeight = pDesc->height; - - // If we were given an opened display at construction time, then send the received - // image back down the camera. - if (mDisplay.get()) { - // Get the output buffer we'll use to display the imagery - BufferDesc_1_0 tgtBuffer = {}; - mDisplay->getTargetBuffer([&tgtBuffer](const BufferDesc_1_0& buff) { - tgtBuffer = buff; - } - ); - - if (tgtBuffer.memHandle == nullptr) { - printf("Didn't get target buffer - frame lost\n"); - ALOGE("Didn't get requested output buffer -- skipping this frame."); +Return FrameHandler::notifyEvent(const EvsEvent& event) { + // Local flag we use to keep track of when the stream is stopping + auto type = event.getDiscriminator(); + if (type == EvsEvent::hidl_discriminator::info) { + mLock.lock(); + mLatestEventDesc = event.info(); + if (mLatestEventDesc.aType == InfoEventType::STREAM_STOPPED) { + // Signal that the last frame has been received and the stream is stopped + mRunning = false; + } else if (mLatestEventDesc.aType == InfoEventType::PARAMETER_CHANGED) { + ALOGD("Camera parameter 0x%X is changed to 0x%X", + mLatestEventDesc.payload[0], mLatestEventDesc.payload[1]); } else { - // Copy the contents of the of buffer.memHandle into tgtBuffer - copyBufferContents(tgtBuffer, bufDesc); + ALOGD("Received an event %s", eventToString(mLatestEventDesc.aType)); + } + mLock.unlock(); + mEventSignal.notify_all(); + } else { + auto bufDesc = event.buffer(); + const AHardwareBuffer_Desc* pDesc = + reinterpret_cast(&bufDesc.buffer.description); + ALOGD("Received a frame from the camera (%p)", + bufDesc.buffer.nativeHandle.getNativeHandle()); - // Send the target buffer back for display - Return result = mDisplay->returnTargetBufferForDisplay(tgtBuffer); - if (!result.isOk()) { - printf("HIDL error on display buffer (%s)- frame lost\n", - result.description().c_str()); - ALOGE("Error making the remote function call. HIDL said %s", - result.description().c_str()); - } else if (result != EvsResult::OK) { - printf("Display reported error - frame lost\n"); - ALOGE("We encountered error %d when returning a buffer to the display!", - (EvsResult) result); + // Store a dimension of a received frame. + mFrameWidth = pDesc->width; + mFrameHeight = pDesc->height; + + // If we were given an opened display at construction time, then send the received + // image back down the camera. + if (mDisplay.get()) { + // Get the output buffer we'll use to display the imagery + BufferDesc_1_0 tgtBuffer = {}; + mDisplay->getTargetBuffer([&tgtBuffer](const BufferDesc_1_0& buff) { + tgtBuffer = buff; + } + ); + + if (tgtBuffer.memHandle == nullptr) { + printf("Didn't get target buffer - frame lost\n"); + ALOGE("Didn't get requested output buffer -- skipping this frame."); } else { - // Everything looks good! - // Keep track so tests or watch dogs can monitor progress - mLock.lock(); - mFramesDisplayed++; - mLock.unlock(); + // Copy the contents of the of buffer.memHandle into tgtBuffer + copyBufferContents(tgtBuffer, bufDesc); + + // Send the target buffer back for display + Return result = mDisplay->returnTargetBufferForDisplay(tgtBuffer); + if (!result.isOk()) { + printf("HIDL error on display buffer (%s)- frame lost\n", + result.description().c_str()); + ALOGE("Error making the remote function call. HIDL said %s", + result.description().c_str()); + } else if (result != EvsResult::OK) { + printf("Display reported error - frame lost\n"); + ALOGE("We encountered error %d when returning a buffer to the display!", + (EvsResult) result); + } else { + // Everything looks good! + // Keep track so tests or watch dogs can monitor progress + mLock.lock(); + mFramesDisplayed++; + mLock.unlock(); + } } } + + + switch (mReturnMode) { + case eAutoReturn: + // Send the camera buffer back now that the client has seen it + ALOGD("Calling doneWithFrame"); + // TODO: Why is it that we get a HIDL crash if we pass back the cloned buffer? + mCamera->doneWithFrame_1_1(bufDesc); + break; + case eNoAutoReturn: + // Hang onto the buffer handle for now -- the client will return it explicitly later + mHeldBuffers.push(bufDesc); + } + + mLock.lock(); + ++mFramesReceived; + mLock.unlock(); + mFrameSignal.notify_all(); + + ALOGD("Frame handling complete"); } - - switch (mReturnMode) { - case eAutoReturn: - // Send the camera buffer back now that the client has seen it - ALOGD("Calling doneWithFrame"); - mCamera->doneWithFrame_1_1(bufDesc); - break; - case eNoAutoReturn: - // Hang onto the buffer handle for now -- the client will return it explicitly later - mHeldBuffers.push(bufDesc); - } - - mLock.lock(); - ++mFramesReceived; - mLock.unlock(); - mFrameSignal.notify_all(); - - ALOGD("Frame handling complete"); - - return Void(); -} - - -Return FrameHandler::notify(const EvsEvent& event) { - // Local flag we use to keep track of when the stream is stopping - mLock.lock(); - mLatestEventDesc = event; - if (mLatestEventDesc.aType == EvsEventType::STREAM_STOPPED) { - // Signal that the last frame has been received and the stream is stopped - mRunning = false; - } else if (mLatestEventDesc.aType == EvsEventType::PARAMETER_CHANGED) { - ALOGD("Camera parameter 0x%X is changed to 0x%X", - mLatestEventDesc.payload[0], mLatestEventDesc.payload[1]); - } else { - ALOGD("Received an event %s", eventToString(mLatestEventDesc.aType)); - } - mLock.unlock(); - mEventSignal.notify_all(); - return Void(); } @@ -342,18 +342,18 @@ void FrameHandler::getFrameDimension(unsigned* width, unsigned* height) { } } -bool FrameHandler::waitForEvent(const EvsEventType aTargetEvent, - EvsEvent &event) { +bool FrameHandler::waitForEvent(const InfoEventType aTargetEvent, + InfoEventDesc &eventDesc) { // Wait until we get an expected parameter change event. std::unique_lock lock(mLock); auto now = std::chrono::system_clock::now(); bool result = mEventSignal.wait_until(lock, now + 5s, - [this, aTargetEvent, &event](){ + [this, aTargetEvent, &eventDesc](){ bool flag = mLatestEventDesc.aType == aTargetEvent; if (flag) { - event.aType = mLatestEventDesc.aType; - event.payload[0] = mLatestEventDesc.payload[0]; - event.payload[1] = mLatestEventDesc.payload[1]; + eventDesc.aType = mLatestEventDesc.aType; + eventDesc.payload[0] = mLatestEventDesc.payload[0]; + eventDesc.payload[1] = mLatestEventDesc.payload[1]; } return flag; @@ -363,22 +363,21 @@ bool FrameHandler::waitForEvent(const EvsEventType aTargetEvent, return !result; } -const char *FrameHandler::eventToString(const EvsEventType aType) { +const char *FrameHandler::eventToString(const InfoEventType aType) { switch (aType) { - case EvsEventType::STREAM_STARTED: + case InfoEventType::STREAM_STARTED: return "STREAM_STARTED"; - case EvsEventType::STREAM_STOPPED: + case InfoEventType::STREAM_STOPPED: return "STREAM_STOPPED"; - case EvsEventType::FRAME_DROPPED: + case InfoEventType::FRAME_DROPPED: return "FRAME_DROPPED"; - case EvsEventType::TIMEOUT: + case InfoEventType::TIMEOUT: return "TIMEOUT"; - case EvsEventType::PARAMETER_CHANGED: + case InfoEventType::PARAMETER_CHANGED: return "PARAMETER_CHANGED"; - case EvsEventType::MASTER_RELEASED: + case InfoEventType::MASTER_RELEASED: return "MASTER_RELEASED"; default: return "Unknown"; } } - diff --git a/automotive/evs/1.1/vts/functional/FrameHandler.h b/automotive/evs/1.1/vts/functional/FrameHandler.h index e5f1b8f112..7f87cb4409 100644 --- a/automotive/evs/1.1/vts/functional/FrameHandler.h +++ b/automotive/evs/1.1/vts/functional/FrameHandler.h @@ -33,6 +33,7 @@ using ::android::hardware::hidl_handle; using ::android::sp; using ::android::hardware::automotive::evs::V1_0::IEvsDisplay; using ::android::hardware::automotive::evs::V1_0::EvsResult; +using ::android::hardware::automotive::evs::V1_0::CameraDesc; using BufferDesc_1_0 = ::android::hardware::automotive::evs::V1_0::BufferDesc; using BufferDesc_1_1 = ::android::hardware::automotive::evs::V1_1::BufferDesc; @@ -55,13 +56,6 @@ public: FrameHandler(android::sp pCamera, CameraDesc cameraInfo, android::sp pDisplay = nullptr, BufferControlFlag mode = eAutoReturn); - virtual ~FrameHandler() { - if (mCamera != nullptr) { - /* shutdown a camera explicitly */ - shutdown(); - } - } - void shutdown(); bool startStream(); @@ -73,22 +67,19 @@ public: bool isRunning(); void waitForFrameCount(unsigned frameCount); - bool waitForEvent(const EvsEventType aTargetEvent, - EvsEvent &eventDesc); + bool waitForEvent(const InfoEventType aTargetEvent, + InfoEventDesc &eventDesc); void getFramesCounters(unsigned* received, unsigned* displayed); void getFrameDimension(unsigned* width, unsigned* height); private: - // Implementation for ::android::hardware::automotive::evs::V1_0::IEvsCameraStream - Return deliverFrame(const BufferDesc_1_0& buffer) override; - // Implementation for ::android::hardware::automotive::evs::V1_1::IEvsCameraStream - Return deliverFrame_1_1(const BufferDesc_1_1& buffer) override; - Return notify(const EvsEvent& event) override; + Return deliverFrame(const BufferDesc_1_0& buffer) override; + Return notifyEvent(const EvsEvent& event) override; // Local implementation details bool copyBufferContents(const BufferDesc_1_0& tgtBuffer, const BufferDesc_1_1& srcBuffer); - const char *eventToString(const EvsEventType aType); + const char *eventToString(const InfoEventType aType); // Values initialized as startup android::sp mCamera; @@ -109,7 +100,7 @@ private: unsigned mFramesDisplayed = 0; // Simple counter -- rolls over eventually! unsigned mFrameWidth = 0; unsigned mFrameHeight = 0; - EvsEvent mLatestEventDesc; + InfoEventDesc mLatestEventDesc; }; diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp index 1d3fd87356..a6e4881d4d 100644 --- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp +++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp @@ -38,9 +38,8 @@ static const float kNanoToSeconds = 0.000000001f; #include "FrameHandler.h" -#include -#include -#include +#include +#include #include #include @@ -51,10 +50,8 @@ static const float kNanoToSeconds = 0.000000001f; #include #include #include -#include +#include #include -#include -#include #include #include @@ -67,28 +64,13 @@ using ::android::hardware::hidl_vec; using ::android::hardware::hidl_handle; using ::android::hardware::hidl_string; using ::android::sp; -using ::android::hardware::camera::device::V3_2::Stream; +using ::android::hardware::automotive::evs::V1_0::CameraDesc; using ::android::hardware::automotive::evs::V1_0::DisplayDesc; using ::android::hardware::automotive::evs::V1_0::DisplayState; -using ::android::hardware::graphics::common::V1_0::PixelFormat; +using ::android::hardware::automotive::evs::V1_0::IEvsEnumerator; using IEvsCamera_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCamera; using IEvsCamera_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCamera; -/* - * Plese note that this is different from what is defined in - * libhardware/modules/camera/3_4/metadata/types.h; this has one additional - * field to store a framerate. - */ -const size_t kStreamCfgSz = 5; -typedef struct { - int32_t width; - int32_t height; - int32_t format; - int32_t direction; - int32_t framerate; -} RawStreamConfig; - - // Test environment for Evs HIDL HAL. class EvsHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { public: @@ -125,16 +107,15 @@ protected: assert(pEnumerator != nullptr); // Get the camera list - pEnumerator->getCameraList_1_1( - [this](hidl_vec cameraList) { - ALOGI("Camera list callback received %zu cameras", - cameraList.size()); - cameraInfo.reserve(cameraList.size()); - for (auto&& cam: cameraList) { - ALOGI("Found camera %s", cam.v1.cameraId.c_str()); - cameraInfo.push_back(cam); - } - } + pEnumerator->getCameraList([this](hidl_vec cameraList) { + ALOGI("Camera list callback received %zu cameras", + cameraList.size()); + cameraInfo.reserve(cameraList.size()); + for (auto&& cam: cameraList) { + ALOGI("Found camera %s", cam.cameraId.c_str()); + cameraInfo.push_back(cam); + } + } ); // We insist on at least one camera for EVS to pass any camera tests @@ -162,23 +143,19 @@ TEST_F(EvsHidlTest, CameraOpenClean) { // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Open and close each camera twice for (auto&& cam: cameraInfo) { for (int pass = 0; pass < 2; pass++) { sp pCam = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam, nullptr); // Verify that this camera self-identifies correctly - pCam->getCameraInfo_1_1([&cam](CameraDesc desc) { - ALOGD("Found camera %s", desc.v1.cameraId.c_str()); - EXPECT_EQ(cam.v1.cameraId, desc.v1.cameraId); - } + pCam->getCameraInfo([&cam](CameraDesc desc) { + ALOGD("Found camera %s", desc.cameraId.c_str()); + EXPECT_EQ(cam.cameraId, desc.cameraId); + } ); // Explicitly close the camera so resources are released right away @@ -200,26 +177,22 @@ TEST_F(EvsHidlTest, CameraOpenAggressive) { // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Open and close each camera twice for (auto&& cam: cameraInfo) { sp pCam = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam, nullptr); // Verify that this camera self-identifies correctly - pCam->getCameraInfo_1_1([&cam](CameraDesc desc) { - ALOGD("Found camera %s", desc.v1.cameraId.c_str()); - EXPECT_EQ(cam.v1.cameraId, desc.v1.cameraId); - } + pCam->getCameraInfo([&cam](CameraDesc desc) { + ALOGD("Found camera %s", desc.cameraId.c_str()); + EXPECT_EQ(cam.cameraId, desc.cameraId); + } ); sp pCam2 = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam, pCam2); ASSERT_NE(pCam2, nullptr); @@ -237,10 +210,10 @@ TEST_F(EvsHidlTest, CameraOpenAggressive) { pEnumerator->closeCamera(pCam); // Verify that the second camera instance self-identifies correctly - pCam2->getCameraInfo_1_1([&cam](CameraDesc desc) { - ALOGD("Found camera %s", desc.v1.cameraId.c_str()); - EXPECT_EQ(cam.v1.cameraId, desc.v1.cameraId); - } + pCam2->getCameraInfo([&cam](CameraDesc desc) { + ALOGD("Found camera %s", desc.cameraId.c_str()); + EXPECT_EQ(cam.cameraId, desc.cameraId); + } ); // Close the second camera instance @@ -262,14 +235,10 @@ TEST_F(EvsHidlTest, CameraStreamPerformance) { // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Test each reported camera for (auto&& cam: cameraInfo) { sp pCam = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam, nullptr); @@ -334,15 +303,11 @@ TEST_F(EvsHidlTest, CameraStreamBuffering) { // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Test each reported camera for (auto&& cam: cameraInfo) { sp pCam = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam, nullptr); @@ -406,10 +371,6 @@ TEST_F(EvsHidlTest, CameraToDisplayRoundTrip) { // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Request exclusive access to the EVS display sp pDisplay = pEnumerator->openDisplay(); ASSERT_NE(pDisplay, nullptr); @@ -417,7 +378,7 @@ TEST_F(EvsHidlTest, CameraToDisplayRoundTrip) { // Test each reported camera for (auto&& cam: cameraInfo) { sp pCam = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam, nullptr); @@ -478,20 +439,16 @@ TEST_F(EvsHidlTest, MultiCameraStream) { // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Test each reported camera for (auto&& cam: cameraInfo) { // Create two camera clients. sp pCam0 = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam0, nullptr); sp pCam1 = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam1, nullptr); @@ -529,6 +486,7 @@ TEST_F(EvsHidlTest, MultiCameraStream) { nsecs_t runTime = end - firstFrame; float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds); float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds); + printf("Measured camera rate %3.2f fps and %3.2f fps\n", framesPerSecond0, framesPerSecond1); ALOGI("Measured camera rate %3.2f fps and %3.2f fps", framesPerSecond0, framesPerSecond1); EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond); EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond); @@ -568,33 +526,14 @@ TEST_F(EvsHidlTest, CameraParameter) { // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Test each reported camera - Return result = EvsResult::OK; for (auto&& cam: cameraInfo) { // Create a camera client sp pCam = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam, nullptr); - // Get the parameter list - std::vector cmds; - pCam->getParameterList([&cmds](hidl_vec cmdList) { - cmds.reserve(cmdList.size()); - for (auto &&cmd : cmdList) { - cmds.push_back(cmd); - } - } - ); - - if (cmds.size() < 1) { - continue; - } - // Set up per-client frame receiver objects which will fire up its own thread sp frameHandler = new FrameHandler(pCam, cam, nullptr, @@ -608,70 +547,83 @@ TEST_F(EvsHidlTest, CameraParameter) { // Ensure the stream starts frameHandler->waitForFrameCount(1); + // Try to program few parameters + EvsResult result = EvsResult::OK; + int32_t val0 = 100; + int32_t val1 = 0; + result = pCam->setMaster(); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK); - for (auto &cmd : cmds) { - // Get a valid parameter value range - int32_t minVal, maxVal, step; - pCam->getIntParameterRange( - cmd, - [&minVal, &maxVal, &step](int32_t val0, int32_t val1, int32_t val2) { - minVal = val0; - maxVal = val1; - step = val2; - } - ); + pCam->setParameter(CameraParam::BRIGHTNESS, val0, + [&result, &val1](auto status, auto effectiveValue) { + result = status; + val1 = effectiveValue; + }); + ASSERT_TRUE(result == EvsResult::OK || + result == EvsResult::INVALID_ARG); - EvsResult result = EvsResult::OK; - if (cmd == CameraParam::ABSOLUTE_FOCUS) { - // Try to turn off auto-focus - int32_t val1 = 0; - pCam->getIntParameter(CameraParam::AUTO_FOCUS, - [&result, &val1](auto status, auto value) { - result = status; - if (status == EvsResult::OK) { - val1 = value; - } - }); - if (val1 != 0) { - pCam->setIntParameter(CameraParam::AUTO_FOCUS, 0, - [&result, &val1](auto status, auto effectiveValue) { - result = status; - val1 = effectiveValue; - }); - ASSERT_EQ(EvsResult::OK, result); - ASSERT_EQ(val1, 0); - } - } - - // Try to program a parameter with a random value [minVal, maxVal] - int32_t val0 = minVal + (std::rand() % (maxVal - minVal)); - int32_t val1 = 0; - - // Rounding down - val0 = val0 - (val0 % step); - pCam->setIntParameter(cmd, val0, - [&result, &val1](auto status, auto effectiveValue) { - result = status; - val1 = effectiveValue; - }); - - ASSERT_EQ(EvsResult::OK, result); - - pCam->getIntParameter(cmd, + if (result == EvsResult::OK) { + pCam->getParameter(CameraParam::BRIGHTNESS, [&result, &val1](auto status, auto value) { result = status; if (status == EvsResult::OK) { val1 = value; } }); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK || + result == EvsResult::INVALID_ARG); + ASSERT_EQ(val0, val1) << "Values are not matched."; + } + + val0 = 80; + val1 = 0; + pCam->setParameter(CameraParam::CONTRAST, val0, + [&result, &val1](auto status, auto effectiveValue) { + result = status; + val1 = effectiveValue; + }); + ASSERT_TRUE(result == EvsResult::OK || + result == EvsResult::INVALID_ARG); + + if (result == EvsResult::OK) { + pCam->getParameter(CameraParam::CONTRAST, + [&result, &val1](auto status, auto value) { + result = status; + if (status == EvsResult::OK) { + val1 = value; + } + }); + ASSERT_TRUE(result == EvsResult::OK || + result == EvsResult::INVALID_ARG); + ASSERT_EQ(val0, val1) << "Values are not matched."; + } + + val0 = 300; + val1 = 0; + pCam->setParameter(CameraParam::ABSOLUTE_ZOOM, val0, + [&result, &val1](auto status, auto effectiveValue) { + result = status; + val1 = effectiveValue; + }); + ASSERT_TRUE(result == EvsResult::OK || + result == EvsResult::INVALID_ARG); + + if (result == EvsResult::OK) { + pCam->getParameter(CameraParam::ABSOLUTE_ZOOM, + [&result, &val1](auto status, auto value) { + result = status; + if (status == EvsResult::OK) { + val1 = value; + } + }); + ASSERT_TRUE(result == EvsResult::OK || + result == EvsResult::INVALID_ARG); ASSERT_EQ(val0, val1) << "Values are not matched."; } result = pCam->unsetMaster(); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK); // Shutdown frameHandler->shutdown(); @@ -698,19 +650,15 @@ TEST_F(EvsHidlTest, CameraMasterRelease) { // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Test each reported camera for (auto&& cam: cameraInfo) { // Create two camera clients. sp pCamMaster = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCamMaster, nullptr); sp pCamNonMaster = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCamNonMaster, nullptr); @@ -750,15 +698,15 @@ TEST_F(EvsHidlTest, CameraMasterRelease) { // Non-master client expects to receive a master role relesed // notification. - EvsEvent aNotification = {}; + InfoEventDesc aNotification = {}; // Release a master role. pCamMaster->unsetMaster(); // Verify a change notification. - frameHandlerNonMaster->waitForEvent(EvsEventType::MASTER_RELEASED, aNotification); - ASSERT_EQ(EvsEventType::MASTER_RELEASED, - static_cast(aNotification.aType)); + frameHandlerNonMaster->waitForEvent(InfoEventType::MASTER_RELEASED, aNotification); + ASSERT_EQ(InfoEventType::MASTER_RELEASED, + static_cast(aNotification.aType)); // Non-master becomes a master. result = pCamNonMaster->setMaster(); @@ -772,9 +720,9 @@ TEST_F(EvsHidlTest, CameraMasterRelease) { frameHandlerNonMaster->shutdown(); // Verify a change notification. - frameHandlerMaster->waitForEvent(EvsEventType::MASTER_RELEASED, aNotification); - ASSERT_EQ(EvsEventType::MASTER_RELEASED, - static_cast(aNotification.aType)); + frameHandlerMaster->waitForEvent(InfoEventType::MASTER_RELEASED, aNotification); + ASSERT_EQ(InfoEventType::MASTER_RELEASED, + static_cast(aNotification.aType)); // Closing another stream. frameHandlerMaster->shutdown(); @@ -804,46 +752,18 @@ TEST_F(EvsHidlTest, MultiCameraParameter) { // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Test each reported camera for (auto&& cam: cameraInfo) { // Create two camera clients. sp pCamMaster = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCamMaster, nullptr); sp pCamNonMaster = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCamNonMaster, nullptr); - // Get the parameter list - std::vector camMasterCmds, camNonMasterCmds; - pCamMaster->getParameterList([&camMasterCmds](hidl_vec cmdList) { - camMasterCmds.reserve(cmdList.size()); - for (auto &&cmd : cmdList) { - camMasterCmds.push_back(cmd); - } - } - ); - - pCamNonMaster->getParameterList([&camNonMasterCmds](hidl_vec cmdList) { - camNonMasterCmds.reserve(cmdList.size()); - for (auto &&cmd : cmdList) { - camNonMasterCmds.push_back(cmd); - } - } - ); - - if (camMasterCmds.size() < 1 || - camNonMasterCmds.size() < 1) { - // Skip a camera device if it does not support any parameter. - continue; - } - // Set up per-client frame receiver objects which will fire up its own thread sp frameHandlerMaster = new FrameHandler(pCamMaster, cam, @@ -858,11 +778,11 @@ TEST_F(EvsHidlTest, MultiCameraParameter) { // Set one client as the master EvsResult result = pCamMaster->setMaster(); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK); // Try to set another client as the master. result = pCamNonMaster->setMaster(); - ASSERT_EQ(EvsResult::OWNERSHIP_LOST, result); + ASSERT_TRUE(result == EvsResult::OWNERSHIP_LOST); // Start the camera's video stream via a master client. bool startResult = frameHandlerMaster->startStream(); @@ -878,168 +798,131 @@ TEST_F(EvsHidlTest, MultiCameraParameter) { // Ensure the stream starts frameHandlerNonMaster->waitForFrameCount(1); - int32_t val0 = 0; + // Try to program CameraParam::BRIGHTNESS + int32_t val0 = 100; int32_t val1 = 0; - for (auto &cmd : camMasterCmds) { - // Get a valid parameter value range - int32_t minVal, maxVal, step; - pCamMaster->getIntParameterRange( - cmd, - [&minVal, &maxVal, &step](int32_t val0, int32_t val1, int32_t val2) { - minVal = val0; - maxVal = val1; - step = val2; - } - ); - EvsResult result = EvsResult::OK; - if (cmd == CameraParam::ABSOLUTE_FOCUS) { - // Try to turn off auto-focus - int32_t val1 = 1; - pCamMaster->setIntParameter(CameraParam::AUTO_FOCUS, 0, - [&result, &val1](auto status, auto effectiveValue) { - result = status; - val1 = effectiveValue; - }); - ASSERT_EQ(EvsResult::OK, result); - ASSERT_EQ(val1, 0); - } + pCamMaster->setParameter(CameraParam::BRIGHTNESS, val0, + [&result, &val1](auto status, auto effectiveValue) { + result = status; + val1 = effectiveValue; + }); + ASSERT_TRUE(result == EvsResult::OK || // Succeeded to program + result == EvsResult::INVALID_ARG); // Camera parameter is not supported - // Try to program a parameter - val0 = minVal + (std::rand() % (maxVal - minVal)); + // Non-master client expects to receive a parameter change notification + // whenever a master client adjusts it. + InfoEventDesc aNotification = {}; - // Rounding down - val0 = val0 - (val0 % step); - pCamMaster->setIntParameter(cmd, val0, - [&result, &val1](auto status, auto effectiveValue) { - result = status; - val1 = effectiveValue; - }); - ASSERT_EQ(EvsResult::OK, result); + pCamMaster->getParameter(CameraParam::BRIGHTNESS, + [&result, &val1](auto status, auto value) { + result = status; + if (status == EvsResult::OK) { + val1 = value; + } + }); + ASSERT_TRUE(result == EvsResult::OK || // Succeeded to program + result == EvsResult::INVALID_ARG); // Camera parameter is not supported + if (result == EvsResult::OK) { + ASSERT_EQ(val0, val1) << "Values are not matched."; - // Wait a moment - sleep(1); + // Verify a change notification + frameHandlerNonMaster->waitForEvent(InfoEventType::PARAMETER_CHANGED, aNotification); + ASSERT_EQ(InfoEventType::PARAMETER_CHANGED, + static_cast(aNotification.aType)); + ASSERT_EQ(CameraParam::BRIGHTNESS, + static_cast(aNotification.payload[0])); + ASSERT_EQ(val1, + static_cast(aNotification.payload[1])); + } - // Non-master client expects to receive a parameter change notification - // whenever a master client adjusts it. - EvsEvent aNotification = {}; + // Try to program CameraParam::CONTRAST + val0 = 80; + val1 = 0; + pCamMaster->setParameter(CameraParam::CONTRAST, val0, + [&result, &val1](auto status, auto effectiveValue) { + result = status; + val1 = effectiveValue; + }); + ASSERT_TRUE(result == EvsResult::OK || // Succeeded to program + result == EvsResult::INVALID_ARG); // Camera parameter is not supported - pCamMaster->getIntParameter(cmd, + if (result == EvsResult::OK) { + pCamMaster->getParameter(CameraParam::CONTRAST, [&result, &val1](auto status, auto value) { result = status; if (status == EvsResult::OK) { val1 = value; } }); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK); ASSERT_EQ(val0, val1) << "Values are not matched."; + // Verify a change notification - frameHandlerNonMaster->waitForEvent(EvsEventType::PARAMETER_CHANGED, aNotification); - ASSERT_EQ(EvsEventType::PARAMETER_CHANGED, - static_cast(aNotification.aType)); - ASSERT_EQ(cmd, + frameHandlerNonMaster->waitForEvent(InfoEventType::PARAMETER_CHANGED, aNotification); + ASSERT_EQ(InfoEventType::PARAMETER_CHANGED, + static_cast(aNotification.aType)); + ASSERT_EQ(CameraParam::CONTRAST, static_cast(aNotification.payload[0])); ASSERT_EQ(val1, static_cast(aNotification.payload[1])); } // Try to adjust a parameter via non-master client - pCamNonMaster->setIntParameter(camNonMasterCmds[0], val0, + pCamNonMaster->setParameter(CameraParam::CONTRAST, val0, [&result, &val1](auto status, auto effectiveValue) { result = status; val1 = effectiveValue; }); - ASSERT_EQ(EvsResult::INVALID_ARG, result); + ASSERT_TRUE(result == EvsResult::INVALID_ARG); // Non-master client attemps to be a master result = pCamNonMaster->setMaster(); - ASSERT_EQ(EvsResult::OWNERSHIP_LOST, result); + ASSERT_TRUE(result == EvsResult::OWNERSHIP_LOST); // Master client retires from a master role result = pCamMaster->unsetMaster(); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK); // Try to adjust a parameter after being retired - pCamMaster->setIntParameter(camMasterCmds[0], val0, + pCamMaster->setParameter(CameraParam::BRIGHTNESS, val0, [&result, &val1](auto status, auto effectiveValue) { result = status; val1 = effectiveValue; }); - ASSERT_EQ(EvsResult::INVALID_ARG, result); + ASSERT_TRUE(result == EvsResult::INVALID_ARG); // Non-master client becomes a master result = pCamNonMaster->setMaster(); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK); // Try to adjust a parameter via new master client - for (auto &cmd : camNonMasterCmds) { - // Get a valid parameter value range - int32_t minVal, maxVal, step; - pCamNonMaster->getIntParameterRange( - cmd, - [&minVal, &maxVal, &step](int32_t val0, int32_t val1, int32_t val2) { - minVal = val0; - maxVal = val1; - step = val2; - } - ); + pCamNonMaster->setParameter(CameraParam::BRIGHTNESS, val0, + [&result, &val1](auto status, auto effectiveValue) { + result = status; + val1 = effectiveValue; + }); + ASSERT_TRUE(result == EvsResult::OK || // Succeeded to program + result == EvsResult::INVALID_ARG); // Camera parameter is not supported - EvsResult result = EvsResult::OK; - if (cmd == CameraParam::ABSOLUTE_FOCUS) { - // Try to turn off auto-focus - int32_t val1 = 1; - pCamNonMaster->setIntParameter(CameraParam::AUTO_FOCUS, 0, - [&result, &val1](auto status, auto effectiveValue) { - result = status; - val1 = effectiveValue; - }); - ASSERT_EQ(EvsResult::OK, result); - ASSERT_EQ(val1, 0); - } + // Wait a moment + sleep(1); - // Try to program a parameter - val0 = minVal + (std::rand() % (maxVal - minVal)); - - // Rounding down - val0 = val0 - (val0 % step); - pCamNonMaster->setIntParameter(cmd, val0, - [&result, &val1](auto status, auto effectiveValue) { - result = status; - val1 = effectiveValue; - }); - ASSERT_EQ(EvsResult::OK, result); - - // Wait a moment - sleep(1); - - // Non-master client expects to receive a parameter change notification - // whenever a master client adjusts it. - EvsEvent aNotification = {}; - - pCamNonMaster->getIntParameter(cmd, - [&result, &val1](auto status, auto value) { - result = status; - if (status == EvsResult::OK) { - val1 = value; - } - }); - ASSERT_EQ(EvsResult::OK, result); - ASSERT_EQ(val0, val1) << "Values are not matched."; - - // Verify a change notification - frameHandlerMaster->waitForEvent(EvsEventType::PARAMETER_CHANGED, aNotification); - ASSERT_EQ(EvsEventType::PARAMETER_CHANGED, - static_cast(aNotification.aType)); - ASSERT_EQ(cmd, - static_cast(aNotification.payload[0])); + // Verify a change notification + if (result == EvsResult::OK) { + frameHandlerMaster->waitForEvent(InfoEventType::PARAMETER_CHANGED, aNotification); + ASSERT_EQ(static_cast(aNotification.aType), + InfoEventType::PARAMETER_CHANGED); + ASSERT_EQ(static_cast(aNotification.payload[0]), + CameraParam::BRIGHTNESS); ASSERT_EQ(val1, static_cast(aNotification.payload[1])); } // New master retires from a master role result = pCamNonMaster->unsetMaster(); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK); // Shutdown frameHandlerMaster->shutdown(); @@ -1060,18 +943,9 @@ TEST_F(EvsHidlTest, MultiCameraParameter) { TEST_F(EvsHidlTest, HighPriorityCameraClient) { ALOGI("Starting HighPriorityCameraClient test"); - if (mIsHwModule) { - // This test is not for HW module implementation. - return; - } - // Get the camera list loadCameraList(); - // Using null stream configuration makes EVS uses the default resolution and - // output format. - Stream nullCfg = {}; - // Request exclusive access to the EVS display sp pDisplay = pEnumerator->openDisplay(); ASSERT_NE(pDisplay, nullptr); @@ -1080,38 +954,15 @@ TEST_F(EvsHidlTest, HighPriorityCameraClient) { for (auto&& cam: cameraInfo) { // Create two clients sp pCam0 = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam0, nullptr); sp pCam1 = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) + IEvsCamera_1_1::castFrom(pEnumerator->openCamera(cam.cameraId)) .withDefault(nullptr); ASSERT_NE(pCam1, nullptr); - // Get the parameter list; this test will use the first command in both - // lists. - std::vector cam0Cmds, cam1Cmds; - pCam0->getParameterList([&cam0Cmds](hidl_vec cmdList) { - cam0Cmds.reserve(cmdList.size()); - for (auto &&cmd : cmdList) { - cam0Cmds.push_back(cmd); - } - } - ); - - pCam1->getParameterList([&cam1Cmds](hidl_vec cmdList) { - cam1Cmds.reserve(cmdList.size()); - for (auto &&cmd : cmdList) { - cam1Cmds.push_back(cmd); - } - } - ); - if (cam0Cmds.size() < 1 || cam1Cmds.size() < 1) { - // Cannot execute this test. - return; - } - // Set up a frame receiver object which will fire up its own thread. sp frameHandler0 = new FrameHandler(pCam0, cam, pDisplay, @@ -1131,121 +982,67 @@ TEST_F(EvsHidlTest, HighPriorityCameraClient) { frameHandler0->waitForFrameCount(1); frameHandler1->waitForFrameCount(1); - // Client 1 becomes a master and programs a parameter. + // Client 1 becomes a master and programs a brightness. EvsResult result = EvsResult::OK; - // Get a valid parameter value range - int32_t minVal, maxVal, step; - pCam1->getIntParameterRange( - cam1Cmds[0], - [&minVal, &maxVal, &step](int32_t val0, int32_t val1, int32_t val2) { - minVal = val0; - maxVal = val1; - step = val2; - } - ); - - if (cam1Cmds[0] == CameraParam::ABSOLUTE_FOCUS) { - // Try to turn off auto-focus - int32_t val1 = 0; - pCam1->getIntParameter(CameraParam::AUTO_FOCUS, - [&result, &val1](auto status, auto value) { - result = status; - if (status == EvsResult::OK) { - val1 = value; - } - }); - if (val1 != 0) { - pCam1->setIntParameter(CameraParam::AUTO_FOCUS, 0, - [&result, &val1](auto status, auto effectiveValue) { - result = status; - val1 = effectiveValue; - }); - ASSERT_EQ(EvsResult::OK, result); - ASSERT_EQ(val1, 0); - } - } - - // Try to program a parameter with a random value [minVal, maxVal] - int32_t val0 = minVal + (std::rand() % (maxVal - minVal)); + int32_t val0 = 100; int32_t val1 = 0; - // Rounding down - val0 = val0 - (val0 % step); - result = pCam1->setMaster(); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK); - pCam1->setIntParameter(cam1Cmds[0], val0, + pCam1->setParameter(CameraParam::BRIGHTNESS, val0, [&result, &val1](auto status, auto effectiveValue) { result = status; val1 = effectiveValue; }); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK || + result == EvsResult::INVALID_ARG); + // Verify a change notification - EvsEvent aNotification = {}; - bool timeout = - frameHandler0->waitForEvent(EvsEventType::PARAMETER_CHANGED, aNotification); - ASSERT_FALSE(timeout) << "Expected event does not arrive"; - ASSERT_EQ(static_cast(aNotification.aType), - EvsEventType::PARAMETER_CHANGED); - ASSERT_EQ(static_cast(aNotification.payload[0]), - cam1Cmds[0]); - ASSERT_EQ(val1, - static_cast(aNotification.payload[1])); + InfoEventDesc aNotification = {}; + if (result == EvsResult::OK) { + bool timeout = + frameHandler0->waitForEvent(InfoEventType::PARAMETER_CHANGED, aNotification); + ASSERT_FALSE(timeout) << "Expected event does not arrive"; + ASSERT_EQ(static_cast(aNotification.aType), + InfoEventType::PARAMETER_CHANGED); + ASSERT_EQ(static_cast(aNotification.payload[0]), + CameraParam::BRIGHTNESS); + ASSERT_EQ(val1, + static_cast(aNotification.payload[1])); + } // Client 0 steals a master role ASSERT_EQ(EvsResult::OK, pCam0->forceMaster(pDisplay)); - frameHandler1->waitForEvent(EvsEventType::MASTER_RELEASED, aNotification); - ASSERT_EQ(static_cast(aNotification.aType), - EvsEventType::MASTER_RELEASED); + frameHandler1->waitForEvent(InfoEventType::MASTER_RELEASED, aNotification); + ASSERT_EQ(static_cast(aNotification.aType), + InfoEventType::MASTER_RELEASED); - // Client 0 programs a parameter - val0 = minVal + (std::rand() % (maxVal - minVal)); + // Client 0 programs a brightness + val0 = 50; val1 = 0; - - // Rounding down - val0 = val0 - (val0 % step); - - if (cam0Cmds[0] == CameraParam::ABSOLUTE_FOCUS) { - // Try to turn off auto-focus - int32_t val1 = 0; - pCam0->getIntParameter(CameraParam::AUTO_FOCUS, - [&result, &val1](auto status, auto value) { - result = status; - if (status == EvsResult::OK) { - val1 = value; - } - }); - if (val1 != 0) { - pCam0->setIntParameter(CameraParam::AUTO_FOCUS, 0, - [&result, &val1](auto status, auto effectiveValue) { - result = status; - val1 = effectiveValue; - }); - ASSERT_EQ(EvsResult::OK, result); - ASSERT_EQ(val1, 0); - } - } - - pCam0->setIntParameter(cam0Cmds[0], val0, + pCam0->setParameter(CameraParam::BRIGHTNESS, val0, [&result, &val1](auto status, auto effectiveValue) { result = status; val1 = effectiveValue; }); - ASSERT_EQ(EvsResult::OK, result); + ASSERT_TRUE(result == EvsResult::OK || + result == EvsResult::INVALID_ARG); // Verify a change notification - timeout = - frameHandler1->waitForEvent(EvsEventType::PARAMETER_CHANGED, aNotification); - ASSERT_FALSE(timeout) << "Expected event does not arrive"; - ASSERT_EQ(static_cast(aNotification.aType), - EvsEventType::PARAMETER_CHANGED); - ASSERT_EQ(static_cast(aNotification.payload[0]), - cam0Cmds[0]); - ASSERT_EQ(val1, - static_cast(aNotification.payload[1])); + if (result == EvsResult::OK) { + bool timeout = + frameHandler1->waitForEvent(InfoEventType::PARAMETER_CHANGED, aNotification); + ASSERT_FALSE(timeout) << "Expected event does not arrive"; + ASSERT_EQ(static_cast(aNotification.aType), + InfoEventType::PARAMETER_CHANGED); + ASSERT_EQ(static_cast(aNotification.payload[0]), + CameraParam::BRIGHTNESS); + ASSERT_EQ(val1, + static_cast(aNotification.payload[1])); + } // Turn off the display (yes, before the stream stops -- it should be handled) pDisplay->setDisplayState(DisplayState::NOT_VISIBLE); @@ -1264,248 +1061,6 @@ TEST_F(EvsHidlTest, HighPriorityCameraClient) { } -/* - * CameraUseStreamConfigToDisplay: - * End to end test of data flowing from the camera to the display. Similar to - * CameraToDisplayRoundTrip test case but this case retrieves available stream - * configurations from EVS and uses one of them to start a video stream. - */ -TEST_F(EvsHidlTest, CameraUseStreamConfigToDisplay) { - ALOGI("Starting CameraUseStreamConfigToDisplay test"); - - // Get the camera list - loadCameraList(); - - // Request exclusive access to the EVS display - sp pDisplay = pEnumerator->openDisplay(); - ASSERT_NE(pDisplay, nullptr); - - // Test each reported camera - for (auto&& cam: cameraInfo) { - // choose a configuration that has a frame rate faster than minReqFps. - Stream targetCfg = {}; - const int32_t minReqFps = 15; - int32_t maxArea = 0; - camera_metadata_entry_t streamCfgs; - bool foundCfg = false; - if (!find_camera_metadata_entry( - reinterpret_cast(cam.metadata.data()), - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, - &streamCfgs)) { - // Stream configurations are found in metadata - RawStreamConfig *ptr = reinterpret_cast(streamCfgs.data.i32); - for (unsigned idx = 0; idx < streamCfgs.count; idx += kStreamCfgSz) { - if (ptr->direction == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT && - ptr->format == HAL_PIXEL_FORMAT_RGBA_8888) { - - if (ptr->width * ptr->height > maxArea && - ptr->framerate >= minReqFps) { - targetCfg.width = ptr->width; - targetCfg.height = ptr->height; - - maxArea = ptr->width * ptr->height; - foundCfg = true; - } - } - ++ptr; - } - } - targetCfg.format = - static_cast(HAL_PIXEL_FORMAT_RGBA_8888); - - if (!foundCfg) { - // Current EVS camera does not provide stream configurations in the - // metadata. - continue; - } - - sp pCam = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, targetCfg)) - .withDefault(nullptr); - ASSERT_NE(pCam, nullptr); - - // Set up a frame receiver object which will fire up its own thread. - sp frameHandler = new FrameHandler(pCam, cam, - pDisplay, - FrameHandler::eAutoReturn); - - - // Activate the display - pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME); - - // Start the camera's video stream - bool startResult = frameHandler->startStream(); - ASSERT_TRUE(startResult); - - // Wait a while to let the data flow - static const int kSecondsToWait = 5; - const int streamTimeMs = kSecondsToWait * kSecondsToMilliseconds - - kMaxStreamStartMilliseconds; - const unsigned minimumFramesExpected = streamTimeMs * kMinimumFramesPerSecond / - kSecondsToMilliseconds; - sleep(kSecondsToWait); - unsigned framesReceived = 0; - unsigned framesDisplayed = 0; - frameHandler->getFramesCounters(&framesReceived, &framesDisplayed); - EXPECT_EQ(framesReceived, framesDisplayed); - EXPECT_GE(framesDisplayed, minimumFramesExpected); - - // Turn off the display (yes, before the stream stops -- it should be handled) - pDisplay->setDisplayState(DisplayState::NOT_VISIBLE); - - // Shut down the streamer - frameHandler->shutdown(); - - // Explicitly release the camera - pEnumerator->closeCamera(pCam); - } - - // Explicitly release the display - pEnumerator->closeDisplay(pDisplay); -} - - -/* - * MultiCameraStreamUseConfig: - * Verify that each client can start and stop video streams on the same - * underlying camera with same configuration. - */ -TEST_F(EvsHidlTest, MultiCameraStreamUseConfig) { - ALOGI("Starting MultiCameraStream test"); - - if (mIsHwModule) { - // This test is not for HW module implementation. - return; - } - - // Get the camera list - loadCameraList(); - - // Test each reported camera - for (auto&& cam: cameraInfo) { - // choose a configuration that has a frame rate faster than minReqFps. - Stream targetCfg = {}; - const int32_t minReqFps = 15; - int32_t maxArea = 0; - camera_metadata_entry_t streamCfgs; - bool foundCfg = false; - if (!find_camera_metadata_entry( - reinterpret_cast(cam.metadata.data()), - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, - &streamCfgs)) { - // Stream configurations are found in metadata - RawStreamConfig *ptr = reinterpret_cast(streamCfgs.data.i32); - for (unsigned idx = 0; idx < streamCfgs.count; idx += kStreamCfgSz) { - if (ptr->direction == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT && - ptr->format == HAL_PIXEL_FORMAT_RGBA_8888) { - - if (ptr->width * ptr->height > maxArea && - ptr->framerate >= minReqFps) { - targetCfg.width = ptr->width; - targetCfg.height = ptr->height; - - maxArea = ptr->width * ptr->height; - foundCfg = true; - } - } - ++ptr; - } - } - targetCfg.format = - static_cast(HAL_PIXEL_FORMAT_RGBA_8888); - - if (!foundCfg) { - ALOGI("Device %s does not provide a list of supported stream configurations, skipped", - cam.v1.cameraId.c_str()); - - continue; - } - - // Create the first camera client with a selected stream configuration. - sp pCam0 = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, targetCfg)) - .withDefault(nullptr); - ASSERT_NE(pCam0, nullptr); - - // Try to create the second camera client with different stream - // configuration. - int32_t id = targetCfg.id; - targetCfg.id += 1; // EVS manager sees only the stream id. - sp pCam1 = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, targetCfg)) - .withDefault(nullptr); - ASSERT_EQ(pCam1, nullptr); - - // Try again with same stream configuration. - targetCfg.id = id; - pCam1 = - IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, targetCfg)) - .withDefault(nullptr); - ASSERT_NE(pCam1, nullptr); - - // Set up per-client frame receiver objects which will fire up its own thread - sp frameHandler0 = new FrameHandler(pCam0, cam, - nullptr, - FrameHandler::eAutoReturn); - ASSERT_NE(frameHandler0, nullptr); - - sp frameHandler1 = new FrameHandler(pCam1, cam, - nullptr, - FrameHandler::eAutoReturn); - ASSERT_NE(frameHandler1, nullptr); - - // Start the camera's video stream via client 0 - bool startResult = false; - startResult = frameHandler0->startStream() && - frameHandler1->startStream(); - ASSERT_TRUE(startResult); - - // Ensure the stream starts - frameHandler0->waitForFrameCount(1); - frameHandler1->waitForFrameCount(1); - - nsecs_t firstFrame = systemTime(SYSTEM_TIME_MONOTONIC); - - // Wait a bit, then ensure both clients get at least the required minimum number of frames - sleep(5); - nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC); - unsigned framesReceived0 = 0, framesReceived1 = 0; - frameHandler0->getFramesCounters(&framesReceived0, nullptr); - frameHandler1->getFramesCounters(&framesReceived1, nullptr); - framesReceived0 = framesReceived0 - 1; // Back out the first frame we already waited for - framesReceived1 = framesReceived1 - 1; // Back out the first frame we already waited for - nsecs_t runTime = end - firstFrame; - float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds); - float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds); - ALOGI("Measured camera rate %3.2f fps and %3.2f fps", framesPerSecond0, framesPerSecond1); - EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond); - EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond); - - // Shutdown one client - frameHandler0->shutdown(); - - // Read frame counters again - frameHandler0->getFramesCounters(&framesReceived0, nullptr); - frameHandler1->getFramesCounters(&framesReceived1, nullptr); - - // Wait a bit again - sleep(5); - unsigned framesReceivedAfterStop0 = 0, framesReceivedAfterStop1 = 0; - frameHandler0->getFramesCounters(&framesReceivedAfterStop0, nullptr); - frameHandler1->getFramesCounters(&framesReceivedAfterStop1, nullptr); - EXPECT_EQ(framesReceived0, framesReceivedAfterStop0); - EXPECT_LT(framesReceived1, framesReceivedAfterStop1); - - // Shutdown another - frameHandler1->shutdown(); - - // Explicitly release the camera - pEnumerator->closeCamera(pCam0); - pEnumerator->closeCamera(pCam1); - } -} - - int main(int argc, char** argv) { ::testing::AddGlobalTestEnvironment(EvsHidlEnvironment::Instance()); ::testing::InitGoogleTest(&argc, argv);