| /* |
| * Copyright (C) 2011 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 HW_EMULATOR_CAMERA_QEMU_CLIENT_H |
| #define HW_EMULATOR_CAMERA_QEMU_CLIENT_H |
| |
| /* |
| * Contains declaration of classes that encapsulate connection to camera services |
| * in the emulator via qemu pipe. |
| */ |
| |
| #include <hardware/qemud.h> |
| |
| namespace android { |
| |
| /**************************************************************************** |
| * Qemu query |
| ***************************************************************************/ |
| |
| /* Encapsulates a query to the emulator. |
| * Guest exchanges data with the emulator via queries sent over the qemu pipe. |
| * The queries as well as replies to the queries are all strings (except for the |
| * 'frame' query where reply is a framebuffer). |
| * Each query is formatted as such: |
| * |
| * "<query name>[ <parameters>]", |
| * |
| * where <query name> is a string representing query name, and <parameters> are |
| * optional parameters for the query. If parameters are present, they must be |
| * separated from the query name with a single space, and they must be formatted |
| * as such: |
| * |
| * "<name1>=<value1> <name2>=<value2> ... <nameN>=<valueN>" |
| * |
| * I.e.: |
| * - Every parameter must have a name, and a value. |
| * - Name and value must be separated with '='. |
| * - No spaces are allowed around '=' separating name and value. |
| * - Parameters must be separated with a single space character. |
| * - No '=' character is allowed in name and in value. |
| * |
| * There are certain restrictions on strings used in the query: |
| * - Spaces are allowed only as separators. |
| * - '=' are allowed only to divide parameter names from parameter values. |
| * |
| * Emulator replies to each query in two chunks: |
| * - 8 bytes encoding the payload size as a string containing hexadecimal |
| * representation of the payload size value. This is done in order to simplify |
| * dealing with different endianness on the host, and on the guest. |
| * - Payload, whose size is defined by the first chunk. |
| * |
| * Every payload always begins with two characters, encoding the result of the |
| * query: |
| * - 'ok' Encoding the success |
| * - 'ko' Encoding a failure. |
| * After that payload may have optional data. If payload has more data following |
| * the query result, there is a ':' character separating them. If payload carries |
| * only the result, it always ends with a zero-terminator. So, payload 'ok'/'ko' |
| * prefix is always 3 bytes long: it either includes a zero-terminator, if there |
| * is no data, or a ':' separator. |
| */ |
| class QemuQuery { |
| public: |
| /* Constructs an uninitialized QemuQuery instance. */ |
| QemuQuery(); |
| |
| /* Constructs and initializes QemuQuery instance for a query. |
| * Param: |
| * query_string - Query string. This constructor can also be used to |
| * construct a query that doesn't have parameters. In this case query |
| * name can be passed as a parameter here. |
| */ |
| explicit QemuQuery(const char* query_string); |
| |
| /* Constructs and initializes QemuQuery instance for a query with parameters. |
| * Param: |
| * query_name - Query name. |
| * query_param - Query parameters. Can be NULL. |
| */ |
| QemuQuery(const char* query_name, const char* query_param); |
| |
| /* Destructs QemuQuery instance. */ |
| ~QemuQuery(); |
| |
| /**************************************************************************** |
| * Public API |
| ***************************************************************************/ |
| |
| /* Creates new query. |
| * Note: this method will reset this instance prior to creating a new query |
| * in order to discard possible "leftovers" from the previous query. |
| * Param: |
| * query_name - Query name. |
| * query_param - Query parameters. Can be NULL. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status. |
| */ |
| status_t createQuery(const char* name, const char* param); |
| |
| /* Completes the query after a reply from the emulator. |
| * This method will parse the reply buffer, and calculate the final query |
| * status, which depends not only on the transport success / failure, but |
| * also on 'ok' / 'ko' in the reply buffer. |
| * Param: |
| * status - Query delivery status. This status doesn't necessarily reflects |
| * the final query status (which is defined by 'ok'/'ko' prefix in the |
| * reply buffer). This status simply states whether or not the query has |
| * been sent, and a reply has been received successfuly. However, if |
| * this status indicates a failure, it means that the entire query has |
| * failed. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. Note that |
| * status returned here just signals whether or not the method has succeeded. |
| * Use isQuerySucceeded() / getCompletionStatus() methods of this class to |
| * check the final query status. |
| */ |
| status_t completeQuery(status_t status); |
| |
| /* Resets the query from a previous use. */ |
| void resetQuery(); |
| |
| /* Checks if query has succeeded. |
| * Note that this method must be called after completeQuery() method of this |
| * class has been executed. |
| */ |
| inline bool isQuerySucceeded() const { |
| return mQueryDeliveryStatus == NO_ERROR && mReplyStatus != 0; |
| } |
| |
| /* Gets final completion status of the query. |
| * Note that this method must be called after completeQuery() method of this |
| * class has been executed. |
| * Return: |
| * NO_ERROR if query has succeeded, or an appropriate error status on query |
| * failure. |
| */ |
| inline status_t getCompletionStatus() const { |
| if (mQueryDeliveryStatus == NO_ERROR) { |
| if (mReplyStatus) { |
| return NO_ERROR; |
| } else { |
| return EINVAL; |
| } |
| } else { |
| return mQueryDeliveryStatus; |
| } |
| } |
| |
| /**************************************************************************** |
| * Public data memebers |
| ***************************************************************************/ |
| |
| public: |
| /* Query string. */ |
| char* mQuery; |
| /* Query delivery status. */ |
| status_t mQueryDeliveryStatus; |
| /* Reply buffer */ |
| char* mReplyBuffer; |
| /* Reply data (past 'ok'/'ko'). If NULL, there were no data in reply. */ |
| char* mReplyData; |
| /* Reply buffer size. */ |
| size_t mReplySize; |
| /* Reply data size. */ |
| size_t mReplyDataSize; |
| /* Reply status: 1 - ok, 0 - ko. */ |
| int mReplyStatus; |
| |
| /**************************************************************************** |
| * Private data memebers |
| ***************************************************************************/ |
| |
| protected: |
| /* Preallocated buffer for small queries. */ |
| char mQueryPrealloc[256]; |
| }; |
| |
| /**************************************************************************** |
| * Qemu client base |
| ***************************************************************************/ |
| |
| /* Encapsulates a connection to the 'camera' service in the emulator via qemu |
| * pipe. |
| */ |
| class QemuClient { |
| public: |
| /* Constructs QemuClient instance. */ |
| QemuClient(); |
| |
| /* Destructs QemuClient instance. */ |
| virtual ~QemuClient(); |
| |
| /**************************************************************************** |
| * Qemu client API |
| ***************************************************************************/ |
| |
| public: |
| /* Connects to the 'camera' service in the emulator via qemu pipe. |
| * Param: |
| * param - Parameters to pass to the camera service. There are two types of |
| * camera services implemented by the emulator. The first one is a |
| * 'camera factory' type of service that provides list of cameras |
| * connected to the host. Another one is an 'emulated camera' type of |
| * service that provides interface to a camera connected to the host. At |
| * the connection time emulator makes distinction between the two by |
| * looking at connection parameters: no parameters means connection to |
| * the 'factory' service, while connection with parameters means |
| * connection to an 'emulated camera' service, where camera is identified |
| * by one of the connection parameters. So, passing NULL, or an empty |
| * string to this method will establish a connection with the 'factory' |
| * service, while not empty string passed here will establish connection |
| * with an 'emulated camera' service. Parameters defining the emulated |
| * camera must be formatted as such: |
| * |
| * "name=<device name> [inp_channel=<input channel #>]", |
| * |
| * where 'device name' is a required parameter defining name of the |
| * camera device, and 'input channel' is an optional parameter (positive |
| * integer), defining the input channel to use on the camera device. |
| * Note that device name passed here must have been previously obtained |
| * from the factory service using 'list' query. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status. |
| */ |
| virtual status_t connectClient(const char* param); |
| |
| /* Disconnects from the service. */ |
| virtual void disconnectClient(); |
| |
| /* Sends data to the service. |
| * Param: |
| * data, data_size - Data to send. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. |
| */ |
| virtual status_t sendMessage(const void* data, size_t data_size); |
| |
| /* Receives data from the service. |
| * This method assumes that data to receive will come in two chunks: 8 |
| * characters encoding the payload size in hexadecimal string, followed by |
| * the paylod (if any). |
| * This method will allocate data buffer where to receive the response. |
| * Param: |
| * data - Upon success contains address of the allocated data buffer with |
| * the data received from the service. The caller is responsible for |
| * freeing allocated data buffer. |
| * data_size - Upon success contains size of the data received from the |
| * service. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. |
| */ |
| virtual status_t receiveMessage(void** data, size_t* data_size); |
| |
| /* Sends a query, and receives a response from the service. |
| * Param: |
| * query - Query to send to the service. When this method returns, the query |
| * is completed, and all its relevant data members are properly initialized. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. Note that |
| * status returned here is not the final query status. Use isQuerySucceeded(), |
| * or getCompletionStatus() method on the query object to see if it has |
| * succeeded. However, if this method returns a failure, it means that the |
| * query has failed, and there is no guarantee that its data members are |
| * properly initialized (except for the 'mQueryDeliveryStatus', which is |
| * always in the proper state). |
| */ |
| virtual status_t doQuery(QemuQuery* query); |
| |
| /**************************************************************************** |
| * Data members |
| ***************************************************************************/ |
| |
| protected: |
| /* Qemu pipe handle. */ |
| int mPipeFD; |
| |
| private: |
| /* Camera service name. */ |
| static const char mCameraServiceName[]; |
| }; |
| |
| /**************************************************************************** |
| * Qemu client for the 'factory' service. |
| ***************************************************************************/ |
| |
| /* Encapsulates QemuClient for the 'factory' service. */ |
| class FactoryQemuClient : public QemuClient { |
| public: |
| /* Constructs FactoryQemuClient instance. */ |
| FactoryQemuClient(); |
| |
| /* Destructs FactoryQemuClient instance. */ |
| ~FactoryQemuClient(); |
| |
| /**************************************************************************** |
| * Public API |
| ***************************************************************************/ |
| |
| public: |
| /* Lists camera devices connected to the host. |
| * Param: |
| * list - Upon success contains a list of cameras connected to the host. The |
| * list returned here is represented as a string, containing multiple |
| * lines separated with '\n', where each line represents a camera. Each |
| * camera line is formatted as such: |
| * |
| * "name=<device name> channel=<num> pix=<num> framedims=<dimensions>\n" |
| * |
| * Where: |
| * - 'name' is the name of the camera device attached to the host. This |
| * name must be used for subsequent connection to the 'emulated camera' |
| * service for that camera. |
| * - 'channel' - input channel number (positive int) to use to communicate |
| * with the camera. |
| * - 'pix' - pixel format (a "fourcc" uint), chosen for the video frames |
| * by the camera service. |
| * - 'framedims' contains a list of frame dimensions supported by the |
| * camera for the chosen pixel format. Each etry in the list is in form |
| * '<width>x<height>', where 'width' and 'height' are numeric values |
| * for width and height of a supported frame dimension. Entries in |
| * this list are separated with ',' with no spaces between the entries. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. |
| */ |
| status_t listCameras(char** list); |
| |
| /**************************************************************************** |
| * Names of the queries available for the emulated camera factory. |
| ***************************************************************************/ |
| |
| private: |
| /* List cameras connected to the host. */ |
| static const char mQueryList[]; |
| }; |
| |
| /**************************************************************************** |
| * Qemu client for an 'emulated camera' service. |
| ***************************************************************************/ |
| |
| /* Encapsulates QemuClient for an 'emulated camera' service. |
| */ |
| class CameraQemuClient : public QemuClient { |
| public: |
| /* Constructs CameraQemuClient instance. */ |
| CameraQemuClient(); |
| |
| /* Destructs CameraQemuClient instance. */ |
| ~CameraQemuClient(); |
| |
| /**************************************************************************** |
| * Public API |
| ***************************************************************************/ |
| |
| public: |
| /* Queries camera connection. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. |
| */ |
| status_t queryConnect(); |
| |
| /* Queries camera disconnection. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. |
| */ |
| status_t queryDisconnect(); |
| |
| /* Queries camera to start capturing video. |
| * Param: |
| * pixel_format - Pixel format that is used by the client to push video |
| * frames to the camera framework. |
| * width, height - Frame dimensions, requested by the framework. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. |
| */ |
| status_t queryStart(uint32_t pixel_format, int width, int height); |
| |
| /* Queries camera to stop capturing video. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. |
| */ |
| status_t queryStop(); |
| |
| /* Queries camera for the next video frame. |
| * Param: |
| * vframe, vframe_size - Define buffer, allocated to receive a video frame. |
| * Any of these parameters can be 0, indicating that the caller is |
| * interested only in preview frame. |
| * pframe, pframe_size - Define buffer, allocated to receive a preview frame. |
| * Any of these parameters can be 0, indicating that the caller is |
| * interested only in video frame. |
| * r_scale, g_scale, b_scale - White balance scale. |
| * exposure_comp - Expsoure compensation. |
| * Return: |
| * NO_ERROR on success, or an appropriate error status on failure. |
| */ |
| status_t queryFrame(void* vframe, |
| void* pframe, |
| size_t vframe_size, |
| size_t pframe_size, |
| float r_scale, |
| float g_scale, |
| float b_scale, |
| float exposure_comp); |
| |
| /**************************************************************************** |
| * Names of the queries available for the emulated camera. |
| ***************************************************************************/ |
| |
| private: |
| /* Connect to the camera. */ |
| static const char mQueryConnect[]; |
| /* Disconnect from the camera. */ |
| static const char mQueryDisconnect[]; |
| /* Start video capturing. */ |
| static const char mQueryStart[]; |
| /* Stop video capturing. */ |
| static const char mQueryStop[]; |
| /* Query frame(s). */ |
| static const char mQueryFrame[]; |
| }; |
| |
| }; /* namespace android */ |
| |
| #endif /* HW_EMULATOR_CAMERA_QEMU_CLIENT_H */ |