Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef HW_EMULATOR_CAMERA_QEMU_CLIENT_H
     18 #define HW_EMULATOR_CAMERA_QEMU_CLIENT_H
     19 
     20 /*
     21  * Contains declaration of classes that encapsulate connection to camera services
     22  * in the emulator via qemu pipe.
     23  */
     24 
     25 #include <hardware/qemud.h>
     26 
     27 namespace android {
     28 
     29 /****************************************************************************
     30  * Qemu query
     31  ***************************************************************************/
     32 
     33 /* Encapsulates a query to the emulator.
     34  * Guest exchanges data with the emulator via queries sent over the qemu pipe.
     35  * The queries as well as replies to the queries are all strings (except for the
     36  * 'frame' query where reply is a framebuffer).
     37  * Each query is formatted as such:
     38  *
     39  *      "<query name>[ <parameters>]",
     40  *
     41  * where <query name> is a string representing query name, and <parameters> are
     42  * optional parameters for the query. If parameters are present, they must be
     43  * separated from the query name with a single space, and they must be formatted
     44  * as such:
     45  *
     46  *      "<name1>=<value1> <name2>=<value2> ... <nameN>=<valueN>"
     47  *
     48  * I.e.:
     49  *  - Every parameter must have a name, and a value.
     50  *  - Name and value must be separated with '='.
     51  *  - No spaces are allowed around '=' separating name and value.
     52  *  - Parameters must be separated with a single space character.
     53  *  - No '=' character is allowed in name and in value.
     54  *
     55  * There are certain restrictions on strings used in the query:
     56  *  - Spaces are allowed only as separators.
     57  *  - '=' are allowed only to divide parameter names from parameter values.
     58  *
     59  * Emulator replies to each query in two chunks:
     60  * - 8 bytes encoding the payload size as a string containing hexadecimal
     61  *   representation of the payload size value. This is done in order to simplify
     62  *   dealing with different endianness on the host, and on the guest.
     63  * - Payload, whose size is defined by the first chunk.
     64  *
     65  * Every payload always begins with two characters, encoding the result of the
     66  * query:
     67  *  - 'ok' Encoding the success
     68  *  - 'ko' Encoding a failure.
     69  * After that payload may have optional data. If payload has more data following
     70  * the query result, there is a ':' character separating them. If payload carries
     71  * only the result, it always ends with a zero-terminator. So, payload 'ok'/'ko'
     72  * prefix is always 3 bytes long: it either includes a zero-terminator, if there
     73  * is no data, or a ':' separator.
     74  */
     75 class QemuQuery {
     76 public:
     77     /* Constructs an uninitialized QemuQuery instance. */
     78     QemuQuery();
     79 
     80     /* Constructs and initializes QemuQuery instance for a query.
     81      * Param:
     82      *  query_string - Query string. This constructor can also be used to
     83      *      construct a query that doesn't have parameters. In this case query
     84      *      name can be passed as a parameter here.
     85      */
     86     explicit QemuQuery(const char* query_string);
     87 
     88     /* Constructs and initializes QemuQuery instance for a query with parameters.
     89      * Param:
     90      *  query_name - Query name.
     91      *  query_param - Query parameters. Can be NULL.
     92      */
     93     QemuQuery(const char* query_name, const char* query_param);
     94 
     95     /* Destructs QemuQuery instance. */
     96     ~QemuQuery();
     97 
     98     /****************************************************************************
     99      * Public API
    100      ***************************************************************************/
    101 
    102     /* Creates new query.
    103      * Note: this method will reset this instance prior to creating a new query
    104      * in order to discard possible "leftovers" from the previous query.
    105      * Param:
    106      *  query_name - Query name.
    107      *  query_param - Query parameters. Can be NULL.
    108      * Return:
    109      *  NO_ERROR on success, or an appropriate error status.
    110      */
    111     status_t createQuery(const char* name, const char* param);
    112 
    113     /* Completes the query after a reply from the emulator.
    114      * This method will parse the reply buffer, and calculate the final query
    115      * status, which depends not only on the transport success / failure, but
    116      * also on 'ok' / 'ko' in the reply buffer.
    117      * Param:
    118      *  status - Query delivery status. This status doesn't necessarily reflects
    119      *      the final query status (which is defined by 'ok'/'ko' prefix in the
    120      *      reply buffer). This status simply states whether or not the query has
    121      *      been sent, and a reply has been received successfuly. However, if
    122      *      this status indicates a failure, it means that the entire query has
    123      *      failed.
    124      * Return:
    125      *  NO_ERROR on success, or an appropriate error status on failure. Note that
    126      *  status returned here just signals whether or not the method has succeeded.
    127      *  Use isQuerySucceeded() / getCompletionStatus() methods of this class to
    128      *  check the final query status.
    129      */
    130     status_t completeQuery(status_t status);
    131 
    132     /* Resets the query from a previous use. */
    133     void resetQuery();
    134 
    135     /* Checks if query has succeeded.
    136      * Note that this method must be called after completeQuery() method of this
    137      * class has been executed.
    138      */
    139     inline bool isQuerySucceeded() const {
    140         return mQueryDeliveryStatus == NO_ERROR && mReplyStatus != 0;
    141     }
    142 
    143     /* Gets final completion status of the query.
    144      * Note that this method must be called after completeQuery() method of this
    145      * class has been executed.
    146      * Return:
    147      *  NO_ERROR if query has succeeded, or an appropriate error status on query
    148      *  failure.
    149      */
    150     inline status_t getCompletionStatus() const {
    151         if (mQueryDeliveryStatus == NO_ERROR) {
    152             if (mReplyStatus) {
    153                 return NO_ERROR;
    154             } else {
    155                 return EINVAL;
    156             }
    157         } else {
    158             return mQueryDeliveryStatus;
    159         }
    160     }
    161 
    162     /****************************************************************************
    163      * Public data memebers
    164      ***************************************************************************/
    165 
    166 public:
    167     /* Query string. */
    168     char*       mQuery;
    169     /* Query delivery status. */
    170     status_t    mQueryDeliveryStatus;
    171     /* Reply buffer */
    172     char*       mReplyBuffer;
    173     /* Reply data (past 'ok'/'ko'). If NULL, there were no data in reply. */
    174     char*       mReplyData;
    175     /* Reply buffer size. */
    176     size_t      mReplySize;
    177     /* Reply data size. */
    178     size_t      mReplyDataSize;
    179     /* Reply status: 1 - ok, 0 - ko. */
    180     int         mReplyStatus;
    181 
    182     /****************************************************************************
    183      * Private data memebers
    184      ***************************************************************************/
    185 
    186 protected:
    187     /* Preallocated buffer for small queries. */
    188     char    mQueryPrealloc[256];
    189 };
    190 
    191 /****************************************************************************
    192  * Qemu client base
    193  ***************************************************************************/
    194 
    195 /* Encapsulates a connection to the 'camera' service in the emulator via qemu
    196  * pipe.
    197  */
    198 class QemuClient {
    199 public:
    200     /* Constructs QemuClient instance. */
    201     QemuClient();
    202 
    203     /* Destructs QemuClient instance. */
    204     virtual ~QemuClient();
    205 
    206     /****************************************************************************
    207      * Qemu client API
    208      ***************************************************************************/
    209 
    210 public:
    211     /* Connects to the 'camera' service in the emulator via qemu pipe.
    212      * Param:
    213      *  param - Parameters to pass to the camera service. There are two types of
    214      *      camera services implemented by the emulator. The first one is a
    215      *      'camera factory' type of service that provides list of cameras
    216      *      connected to the host. Another one is an 'emulated camera' type of
    217      *      service that provides interface to a camera connected to the host. At
    218      *      the connection time emulator makes distinction between the two by
    219      *      looking at connection parameters: no parameters means connection to
    220      *      the 'factory' service, while connection with parameters means
    221      *      connection to an 'emulated camera' service, where camera is identified
    222      *      by one of the connection parameters. So, passing NULL, or an empty
    223      *      string to this method will establish a connection with the 'factory'
    224      *      service, while not empty string passed here will establish connection
    225      *      with an 'emulated camera' service. Parameters defining the emulated
    226      *      camera must be formatted as such:
    227      *
    228      *          "name=<device name> [inp_channel=<input channel #>]",
    229      *
    230      *      where 'device name' is a required parameter defining name of the
    231      *      camera device, and 'input channel' is an optional parameter (positive
    232      *      integer), defining the input channel to use on the camera device.
    233      *      Note that device name passed here must have been previously obtained
    234      *      from the factory service using 'list' query.
    235      * Return:
    236      *  NO_ERROR on success, or an appropriate error status.
    237      */
    238     virtual status_t connectClient(const char* param);
    239 
    240     /* Disconnects from the service. */
    241     virtual void disconnectClient();
    242 
    243     /* Sends data to the service.
    244      * Param:
    245      *  data, data_size - Data to send.
    246      * Return:
    247      *  NO_ERROR on success, or an appropriate error status on failure.
    248      */
    249     virtual status_t sendMessage(const void* data, size_t data_size);
    250 
    251     /* Receives data from the service.
    252      * This method assumes that data to receive will come in two chunks: 8
    253      * characters encoding the payload size in hexadecimal string, followed by
    254      * the paylod (if any).
    255      * This method will allocate data buffer where to receive the response.
    256      * Param:
    257      *  data - Upon success contains address of the allocated data buffer with
    258      *      the data received from the service. The caller is responsible for
    259      *      freeing allocated data buffer.
    260      *  data_size - Upon success contains size of the data received from the
    261      *      service.
    262      * Return:
    263      *  NO_ERROR on success, or an appropriate error status on failure.
    264      */
    265     virtual status_t receiveMessage(void** data, size_t* data_size);
    266 
    267     /* Sends a query, and receives a response from the service.
    268      * Param:
    269      *  query - Query to send to the service. When this method returns, the query
    270      *  is completed, and all its relevant data members are properly initialized.
    271      * Return:
    272      *  NO_ERROR on success, or an appropriate error status on failure. Note that
    273      *  status returned here is not the final query status. Use isQuerySucceeded(),
    274      *  or getCompletionStatus() method on the query object to see if it has
    275      *  succeeded. However, if this method returns a failure, it means that the
    276      *  query has failed, and there is no guarantee that its data members are
    277      *  properly initialized (except for the 'mQueryDeliveryStatus', which is
    278      *  always in the proper state).
    279      */
    280     virtual status_t doQuery(QemuQuery* query);
    281 
    282     /****************************************************************************
    283      * Data members
    284      ***************************************************************************/
    285 
    286 protected:
    287     /* Qemu pipe handle. */
    288     int     mPipeFD;
    289 
    290 private:
    291     /* Camera service name. */
    292     static const char mCameraServiceName[];
    293 };
    294 
    295 /****************************************************************************
    296  * Qemu client for the 'factory' service.
    297  ***************************************************************************/
    298 
    299 /* Encapsulates QemuClient for the 'factory' service. */
    300 class FactoryQemuClient : public QemuClient {
    301 public:
    302     /* Constructs FactoryQemuClient instance. */
    303     FactoryQemuClient();
    304 
    305     /* Destructs FactoryQemuClient instance. */
    306     ~FactoryQemuClient();
    307 
    308     /****************************************************************************
    309      * Public API
    310      ***************************************************************************/
    311 
    312 public:
    313     /* Lists camera devices connected to the host.
    314      * Param:
    315      *  list - Upon success contains a list of cameras connected to the host. The
    316      *      list returned here is represented as a string, containing multiple
    317      *      lines separated with '\n', where each line represents a camera. Each
    318      *      camera line is formatted as such:
    319      *
    320      *          "name=<device name> channel=<num> pix=<num> framedims=<dimensions>\n"
    321      *
    322      *      Where:
    323      *      - 'name' is the name of the camera device attached to the host. This
    324      *        name must be used for subsequent connection to the 'emulated camera'
    325      *        service for that camera.
    326      *      - 'channel' - input channel number (positive int) to use to communicate
    327      *        with the camera.
    328      *      - 'pix' - pixel format (a "fourcc" uint), chosen for the video frames
    329      *        by the camera service.
    330      *      - 'framedims' contains a list of frame dimensions supported by the
    331      *        camera for the chosen pixel format. Each etry in the list is in form
    332      *        '<width>x<height>', where 'width' and 'height' are numeric values
    333      *        for width and height of a supported frame dimension. Entries in
    334      *        this list are separated with ',' with no spaces between the entries.
    335      * Return:
    336      *  NO_ERROR on success, or an appropriate error status on failure.
    337      */
    338     status_t listCameras(char** list);
    339 
    340     /****************************************************************************
    341      * Names of the queries available for the emulated camera factory.
    342      ***************************************************************************/
    343 
    344 private:
    345     /* List cameras connected to the host. */
    346     static const char mQueryList[];
    347 };
    348 
    349 /****************************************************************************
    350  * Qemu client for an 'emulated camera' service.
    351  ***************************************************************************/
    352 
    353 /* Encapsulates QemuClient for an 'emulated camera' service.
    354  */
    355 class CameraQemuClient : public QemuClient {
    356 public:
    357     /* Constructs CameraQemuClient instance. */
    358     CameraQemuClient();
    359 
    360     /* Destructs CameraQemuClient instance. */
    361     ~CameraQemuClient();
    362 
    363     /****************************************************************************
    364      * Public API
    365      ***************************************************************************/
    366 
    367 public:
    368     /* Queries camera connection.
    369      * Return:
    370      *  NO_ERROR on success, or an appropriate error status on failure.
    371      */
    372     status_t queryConnect();
    373 
    374     /* Queries camera disconnection.
    375      * Return:
    376      *  NO_ERROR on success, or an appropriate error status on failure.
    377      */
    378     status_t queryDisconnect();
    379 
    380     /* Queries camera to start capturing video.
    381      * Param:
    382      *  pixel_format - Pixel format that is used by the client to push video
    383      *      frames to the camera framework.
    384      *  width, height - Frame dimensions, requested by the framework.
    385      * Return:
    386      *  NO_ERROR on success, or an appropriate error status on failure.
    387      */
    388     status_t queryStart(uint32_t pixel_format, int width, int height);
    389 
    390     /* Queries camera to stop capturing video.
    391      * Return:
    392      *  NO_ERROR on success, or an appropriate error status on failure.
    393      */
    394     status_t queryStop();
    395 
    396     /* Queries camera for the next video frame.
    397      * Param:
    398      *  vframe, vframe_size - Define buffer, allocated to receive a video frame.
    399      *      Any of these parameters can be 0, indicating that the caller is
    400      *      interested only in preview frame.
    401      *  pframe, pframe_size - Define buffer, allocated to receive a preview frame.
    402      *      Any of these parameters can be 0, indicating that the caller is
    403      *      interested only in video frame.
    404      *  r_scale, g_scale, b_scale - White balance scale.
    405      *  exposure_comp - Expsoure compensation.
    406      * Return:
    407      *  NO_ERROR on success, or an appropriate error status on failure.
    408      */
    409     status_t queryFrame(void* vframe,
    410                         void* pframe,
    411                         size_t vframe_size,
    412                         size_t pframe_size,
    413                         float r_scale,
    414                         float g_scale,
    415                         float b_scale,
    416                         float exposure_comp);
    417 
    418     /****************************************************************************
    419      * Names of the queries available for the emulated camera.
    420      ***************************************************************************/
    421 
    422 private:
    423     /* Connect to the camera. */
    424     static const char mQueryConnect[];
    425     /* Disconnect from the camera. */
    426     static const char mQueryDisconnect[];
    427     /* Start video capturing. */
    428     static const char mQueryStart[];
    429     /* Stop video capturing. */
    430     static const char mQueryStop[];
    431     /* Query frame(s). */
    432     static const char mQueryFrame[];
    433 };
    434 
    435 }; /* namespace android */
    436 
    437 #endif  /* HW_EMULATOR_CAMERA_QEMU_CLIENT_H */
    438