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