TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / android / camera / QemuClient.h
diff --git a/src/type3_AndroidCloud/anbox-master/android/camera/QemuClient.h b/src/type3_AndroidCloud/anbox-master/android/camera/QemuClient.h
new file mode 100644 (file)
index 0000000..1644321
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * 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 */