QemuClient.cpp revision 629719e390ce66be822c3563bbd248ce15eaae7b
133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* 233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Copyright (C) 2011 The Android Open Source Project 333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * 433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Licensed under the Apache License, Version 2.0 (the "License"); 533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * you may not use this file except in compliance with the License. 633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * You may obtain a copy of the License at 733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * 833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * http://www.apache.org/licenses/LICENSE-2.0 933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * 1033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Unless required by applicable law or agreed to in writing, software 1133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * distributed under the License is distributed on an "AS IS" BASIS, 1233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * See the License for the specific language governing permissions and 1433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * limitations under the License. 1533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine */ 1633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 1733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* 1833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Contains implementation of classes that encapsulate connection to camera 1933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * services in the emulator via qemu pipe. 2033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine */ 2133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 2249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine#define LOG_NDEBUG 1 2333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine#define LOG_TAG "EmulatedCamera_QemuClient" 2433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine#include <cutils/log.h> 255467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine#include "EmulatedCamera.h" 2633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine#include "QemuClient.h" 2733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 284d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine#define LOG_QUERIES 0 294d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine#if LOG_QUERIES 304d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine#define LOGQ(...) LOGD(__VA_ARGS__) 314d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine#else 324d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine#define LOGQ(...) (void(0)) 334d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine 344d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine#endif // LOG_QUERIES 3533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkinenamespace android { 3633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 3733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/**************************************************************************** 3833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Qemu query 3933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine ***************************************************************************/ 4033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 4133bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineQemuQuery::QemuQuery() 425467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine : mQuery(mQueryPrealloc), 4349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus(NO_ERROR), 445467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyBuffer(NULL), 455467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyData(NULL), 465467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplySize(0), 475467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyDataSize(0), 485467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyStatus(0) 4933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 505467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine *mQuery = '\0'; 5133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 5233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 5333bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineQemuQuery::QemuQuery(const char* query_string) 545467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine : mQuery(mQueryPrealloc), 5549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus(NO_ERROR), 565467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyBuffer(NULL), 575467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyData(NULL), 585467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplySize(0), 595467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyDataSize(0), 605467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyStatus(0) 6133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 6249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = QemuQuery::createQuery(query_string, NULL); 6333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 6433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 6533bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineQemuQuery::QemuQuery(const char* query_name, const char* query_param) 665467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine : mQuery(mQueryPrealloc), 6749842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus(NO_ERROR), 685467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyBuffer(NULL), 695467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyData(NULL), 705467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplySize(0), 715467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyDataSize(0), 725467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyStatus(0) 7333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 7449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = QemuQuery::createQuery(query_name, query_param); 7533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 7633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 7733bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineQemuQuery::~QemuQuery() 7833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 795467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine QemuQuery::resetQuery(); 8033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 8133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 825467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t QemuQuery::createQuery(const char* name, const char* param) 8333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 8433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Reset from the previous use. */ 855467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine resetQuery(); 8633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 8733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Query name cannot be NULL or an empty string. */ 8833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (name == NULL || *name == '\0') { 8933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: NULL or an empty string is passed as query name.", 9033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine __FUNCTION__); 9149842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = EINVAL; 9233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EINVAL; 9333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 9433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 9533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine const size_t name_len = strlen(name); 9633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine const size_t param_len = (param != NULL) ? strlen(param) : 0; 9733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine const size_t required = strlen(name) + (param_len ? (param_len + 2) : 1); 9833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 995467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (required > sizeof(mQueryPrealloc)) { 10033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Preallocated buffer was too small. Allocate a bigger query buffer. */ 1015467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mQuery = new char[required]; 1025467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mQuery == NULL) { 10333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Unable to allocate %d bytes for query buffer", 10433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine __FUNCTION__, required); 10549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = ENOMEM; 10633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return ENOMEM; 10733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 10833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 10933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 1105467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine /* At this point mQuery buffer is big enough for the query. */ 11133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (param_len) { 1125467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine sprintf(mQuery, "%s %s", name, param); 11333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } else { 1145467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine memcpy(mQuery, name, name_len + 1); 11533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 11633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 11733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return NO_ERROR; 11833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 11933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 1205467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t QemuQuery::completeQuery(status_t status) 12133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 12233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Save query completion status. */ 12349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = status; 12449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine if (mQueryDeliveryStatus != NO_ERROR) { 12549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine return mQueryDeliveryStatus; 12633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 12733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 12833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Make sure reply buffer contains at least 'ok', or 'ko'. 12933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Note that 'ok', or 'ko' prefixes are always 3 characters long: in case 13033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * there are more data in the reply, that data will be separated from 'ok'/'ko' 13133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * with a ':'. If there is no more data in the reply, the prefix will be 13233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * zero-terminated, and the terminator will be inculded in the reply. */ 1335467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mReplyBuffer == NULL || mReplySize < 3) { 13433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Invalid reply to the query", __FUNCTION__); 13549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = EINVAL; 13633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EINVAL; 13733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 13833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 13933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Lets see the reply status. */ 1405467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (!memcmp(mReplyBuffer, "ok", 2)) { 1415467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyStatus = 1; 1425467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine } else if (!memcmp(mReplyBuffer, "ko", 2)) { 1435467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyStatus = 0; 14433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } else { 1455467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine LOGE("%s: Invalid query reply: '%s'", __FUNCTION__, mReplyBuffer); 14649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = EINVAL; 14733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EINVAL; 14833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 14933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 15033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Lets see if there are reply data that follow. */ 1515467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mReplySize > 3) { 15233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* There are extra data. Make sure they are separated from the status 15333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * with a ':' */ 1545467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mReplyBuffer[2] != ':') { 1555467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine LOGE("%s: Invalid query reply: '%s'", __FUNCTION__, mReplyBuffer); 15649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = EINVAL; 15733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EINVAL; 15833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 1595467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyData = mReplyBuffer + 3; 1605467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyDataSize = mReplySize - 3; 16133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } else { 16233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Make sure reply buffer containing just 'ok'/'ko' ends with 16333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * zero-terminator. */ 1645467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mReplyBuffer[2] != '\0') { 1655467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine LOGE("%s: Invalid query reply: '%s'", __FUNCTION__, mReplyBuffer); 16649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = EINVAL; 16733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EINVAL; 16833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 16933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 17033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 17133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return NO_ERROR; 17233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 17333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 1745467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinevoid QemuQuery::resetQuery() 17533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 1765467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mQuery != NULL && mQuery != mQueryPrealloc) { 1775467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine delete[] mQuery; 17833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 1795467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mQuery = mQueryPrealloc; 18049842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mQueryDeliveryStatus = NO_ERROR; 1815467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mReplyBuffer != NULL) { 1825467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine free(mReplyBuffer); 1835467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyBuffer = NULL; 18433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 1855467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyData = NULL; 18649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine mReplySize = mReplyDataSize = 0; 1875467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mReplyStatus = 0; 18833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 18933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 19033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/**************************************************************************** 19133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Qemu client base 19233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine ***************************************************************************/ 19333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 19433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* Camera service name. */ 1955467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkineconst char QemuClient::mCameraServiceName[] = "camera"; 19633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 19733bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineQemuClient::QemuClient() 1985467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine : mPipeFD(-1) 19933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 20033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 20133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 20233bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineQemuClient::~QemuClient() 20333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 2045467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mPipeFD >= 0) { 2055467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine close(mPipeFD); 20633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 20733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 20833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 20933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/**************************************************************************** 21033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Qemu client API 21133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine ***************************************************************************/ 21233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 2135467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t QemuClient::connectClient(const char* param) 21433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 215629719e390ce66be822c3563bbd248ce15eaae7bSteve Block ALOGV("%s: '%s'", __FUNCTION__, param ? param : ""); 21633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 21733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Make sure that client is not connected already. */ 2185467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mPipeFD >= 0) { 21933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Qemu client is already connected", __FUNCTION__); 22033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EINVAL; 22133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 22233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 22333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Select one of the two: 'factory', or 'emulated camera' service */ 22433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (param == NULL || *param == '\0') { 22533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* No parameters: connect to the factory service. */ 22633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine char pipe_name[512]; 2275467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", mCameraServiceName); 2285467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mPipeFD = qemu_pipe_open(pipe_name); 22933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } else { 23033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* One extra char ':' that separates service name and parameters + six 23133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * characters for 'qemud:'. This is required by qemu pipe protocol. */ 2325467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine char* connection_str = new char[strlen(mCameraServiceName) + 23333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine strlen(param) + 8]; 2345467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine sprintf(connection_str, "qemud:%s:%s", mCameraServiceName, param); 23533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 2365467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mPipeFD = qemu_pipe_open(connection_str); 23733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine delete[] connection_str; 23833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 2395467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mPipeFD < 0) { 24033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Unable to connect to the camera service '%s': %s", 24133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine __FUNCTION__, param ? param : "Factory", strerror(errno)); 24233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return errno ? errno : EINVAL; 24333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 24433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 24533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return NO_ERROR; 24633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 24733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 2485467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinevoid QemuClient::disconnectClient() 24933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 250629719e390ce66be822c3563bbd248ce15eaae7bSteve Block ALOGV("%s", __FUNCTION__); 25116232484c709c565adfbf557025c52f61295c058Vladimir Chtchetkine 2525467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mPipeFD >= 0) { 2535467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine close(mPipeFD); 2545467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mPipeFD = -1; 25533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 25633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 25733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 2585467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t QemuClient::sendMessage(const void* data, size_t data_size) 25933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 2605467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mPipeFD < 0) { 26133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Qemu client is not connected", __FUNCTION__); 26233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EINVAL; 26333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 26433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 26533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Note that we don't use here qemud_client_send, since with qemu pipes we 26633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * don't need to provide payload size prior to payload when we're writing to 26733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * the pipe. So, we can use simple write, and qemu pipe will take care of the 26833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * rest, calling the receiving end with the number of bytes transferred. */ 2695467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine const size_t written = qemud_fd_write(mPipeFD, data, data_size); 27033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (written == data_size) { 27133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return NO_ERROR; 27233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } else { 27349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE("%s: Error sending data via qemu pipe: '%s'", 27433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine __FUNCTION__, strerror(errno)); 27549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine return errno ? errno : EIO; 27633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 27733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 27833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 2795467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t QemuClient::receiveMessage(void** data, size_t* data_size) 28033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 28133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine *data = NULL; 28233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine *data_size = 0; 28333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 2845467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (mPipeFD < 0) { 28533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Qemu client is not connected", __FUNCTION__); 28633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EINVAL; 28733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 28833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 28933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* The way the service replies to a query, it sends payload size first, and 29033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * then it sends the payload itself. Note that payload size is sent as a 29133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * string, containing 8 characters representing a hexadecimal payload size 29233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * value. Note also, that the string doesn't contain zero-terminator. */ 29333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine size_t payload_size; 29433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine char payload_size_str[9]; 2955467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine int rd_res = qemud_fd_read(mPipeFD, payload_size_str, 8); 29633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (rd_res != 8) { 29733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Unable to obtain payload size: %s", 29833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine __FUNCTION__, strerror(errno)); 29933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return errno ? errno : EIO; 30033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 30133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 30233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Convert payload size. */ 30333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine errno = 0; 30433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine payload_size_str[8] = '\0'; 30533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine payload_size = strtol(payload_size_str, NULL, 16); 30633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (errno) { 30733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Invalid payload size '%s'", __FUNCTION__, payload_size_str); 30833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EIO; 30933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 31033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 31133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Allocate payload data buffer, and read the payload there. */ 31233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine *data = malloc(payload_size); 31333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (*data == NULL) { 31433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Unable to allocate %d bytes payload buffer", 31533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine __FUNCTION__, payload_size); 31633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return ENOMEM; 31733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 3185467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine rd_res = qemud_fd_read(mPipeFD, *data, payload_size); 31933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (static_cast<size_t>(rd_res) == payload_size) { 32033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine *data_size = payload_size; 32133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return NO_ERROR; 32233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } else { 32333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Read size %d doesnt match expected payload size %d: %s", 32433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine __FUNCTION__, rd_res, payload_size, strerror(errno)); 32533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine free(*data); 32633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine *data = NULL; 32733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return errno ? errno : EIO; 32833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 32933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 33033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 3315467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t QemuClient::doQuery(QemuQuery* query) 33233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 33333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Make sure that query has been successfuly constructed. */ 33449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine if (query->mQueryDeliveryStatus != NO_ERROR) { 33533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Query is invalid", __FUNCTION__); 33649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine return query->mQueryDeliveryStatus; 33733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 33833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 3394d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine LOGQ("Send query '%s'", query->mQuery); 3404d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine 34133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Send the query. */ 3425467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine status_t res = sendMessage(query->mQuery, strlen(query->mQuery) + 1); 34333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (res == NO_ERROR) { 34433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Read the response. */ 3455467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine res = receiveMessage(reinterpret_cast<void**>(&query->mReplyBuffer), 3465467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine &query->mReplySize); 3474d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine if (res == NO_ERROR) { 3484d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine LOGQ("Response to query '%s': Status = '%.2s', %d bytes in response", 3494d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine query->mQuery, query->mReplyBuffer, query->mReplySize); 3504d4736067242295ccd8dc9fef989b04cac242a75Vladimir Chtchetkine } else { 35133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s Response to query '%s' has failed: %s", 3525467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine __FUNCTION__, query->mQuery, strerror(res)); 35333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 35433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } else { 35533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Send query '%s' failed: %s", 3565467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine __FUNCTION__, query->mQuery, strerror(res)); 35733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 35833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 35933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Complete the query, and return its completion handling status. */ 36049842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine const status_t res1 = query->completeQuery(res); 36149842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE_IF(res1 != NO_ERROR && res1 != res, 36249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine "%s: Error %d in query '%s' completion", 36349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine __FUNCTION__, res1, query->mQuery); 36449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine return res1; 36533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 36633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 36733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/**************************************************************************** 36833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Qemu client for the 'factory' service. 36933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine ***************************************************************************/ 37033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 37133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* 37233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Factory service queries. 37333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine */ 37433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 37533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* Queries list of cameras connected to the host. */ 3765467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkineconst char FactoryQemuClient::mQueryList[] = "list"; 37733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 37833bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineFactoryQemuClient::FactoryQemuClient() 37933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine : QemuClient() 38033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 38133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 38233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 38333bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineFactoryQemuClient::~FactoryQemuClient() 38433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 38533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 38633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 3875467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t FactoryQemuClient::listCameras(char** list) 38833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 389629719e390ce66be822c3563bbd248ce15eaae7bSteve Block ALOGV("%s", __FUNCTION__); 39016232484c709c565adfbf557025c52f61295c058Vladimir Chtchetkine 3915467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine QemuQuery query(mQueryList); 39249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine if (doQuery(&query) || !query.isQuerySucceeded()) { 39349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE("%s: List cameras query failed: %s", __FUNCTION__, 39449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine query.mReplyData ? query.mReplyData : "No error message"); 3955467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine return query.getCompletionStatus(); 39633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 39733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 39833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Make sure there is a list returned. */ 3995467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine if (query.mReplyDataSize == 0) { 40033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: No camera list is returned.", __FUNCTION__); 40133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return EINVAL; 40233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 40333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 40433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine /* Copy the list over. */ 4055467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine *list = (char*)malloc(query.mReplyDataSize); 40633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine if (*list != NULL) { 4075467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine memcpy(*list, query.mReplyData, query.mReplyDataSize); 40833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGD("Emulated camera list: %s", *list); 40933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return NO_ERROR; 41033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } else { 41133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine LOGE("%s: Unable to allocate %d bytes", 4125467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine __FUNCTION__, query.mReplyDataSize); 41333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return ENOMEM; 41433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 41533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 41633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 41733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/**************************************************************************** 41833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Qemu client for an 'emulated camera' service. 41933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine ***************************************************************************/ 42033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 42133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* 42233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine * Emulated camera queries 42333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine */ 42433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 42533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* Connect to the camera device. */ 4265467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkineconst char CameraQemuClient::mQueryConnect[] = "connect"; 42733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* Disconect from the camera device. */ 4285467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkineconst char CameraQemuClient::mQueryDisconnect[] = "disconnect"; 42933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* Start capturing video from the camera device. */ 4305467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkineconst char CameraQemuClient::mQueryStart[] = "start"; 43133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* Stop capturing video from the camera device. */ 4325467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkineconst char CameraQemuClient::mQueryStop[] = "stop"; 43333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine/* Get next video frame from the camera device. */ 4345467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkineconst char CameraQemuClient::mQueryFrame[] = "frame"; 43533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 43633bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineCameraQemuClient::CameraQemuClient() 43733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine : QemuClient() 43833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 43933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 44033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 44133bda475286a625337ed184e7053fc29e403d57bVladimir ChtchetkineCameraQemuClient::~CameraQemuClient() 44233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 44333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 44433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 44533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 4465467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t CameraQemuClient::queryConnect() 44733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 448629719e390ce66be822c3563bbd248ce15eaae7bSteve Block ALOGV("%s", __FUNCTION__); 44916232484c709c565adfbf557025c52f61295c058Vladimir Chtchetkine 4505467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine QemuQuery query(mQueryConnect); 4515467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine doQuery(&query); 4525467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine const status_t res = query.getCompletionStatus(); 45349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE_IF(res != NO_ERROR, "%s: Query failed: %s", 4545467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine __FUNCTION__, query.mReplyData ? query.mReplyData : 45549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine "No error message"); 45633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return res; 45733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 45833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 4595467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t CameraQemuClient::queryDisconnect() 46033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 461629719e390ce66be822c3563bbd248ce15eaae7bSteve Block ALOGV("%s", __FUNCTION__); 46216232484c709c565adfbf557025c52f61295c058Vladimir Chtchetkine 4635467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine QemuQuery query(mQueryDisconnect); 4645467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine doQuery(&query); 4655467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine const status_t res = query.getCompletionStatus(); 46649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE_IF(res != NO_ERROR, "%s: Query failed: %s", 4675467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine __FUNCTION__, query.mReplyData ? query.mReplyData : 46849842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine "No error message"); 46933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return res; 47033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 47133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 4725467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t CameraQemuClient::queryStart(uint32_t pixel_format, 47333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine int width, 47433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine int height) 47533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 476629719e390ce66be822c3563bbd248ce15eaae7bSteve Block ALOGV("%s", __FUNCTION__); 47716232484c709c565adfbf557025c52f61295c058Vladimir Chtchetkine 47833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine char query_str[256]; 47933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine snprintf(query_str, sizeof(query_str), "%s dim=%dx%d pix=%d", 4805467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mQueryStart, width, height, pixel_format); 48133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine QemuQuery query(query_str); 4825467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine doQuery(&query); 4835467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine const status_t res = query.getCompletionStatus(); 48449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE_IF(res != NO_ERROR, "%s: Query failed: %s", 4855467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine __FUNCTION__, query.mReplyData ? query.mReplyData : 48649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine "No error message"); 48733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return res; 48833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 48933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 4905467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t CameraQemuClient::queryStop() 49133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 492629719e390ce66be822c3563bbd248ce15eaae7bSteve Block ALOGV("%s", __FUNCTION__); 49316232484c709c565adfbf557025c52f61295c058Vladimir Chtchetkine 4945467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine QemuQuery query(mQueryStop); 4955467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine doQuery(&query); 4965467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine const status_t res = query.getCompletionStatus(); 49749842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE_IF(res != NO_ERROR, "%s: Query failed: %s", 4985467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine __FUNCTION__, query.mReplyData ? query.mReplyData : 49949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine "No error message"); 50033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine return res; 50133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 50233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 5035467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkinestatus_t CameraQemuClient::queryFrame(void* vframe, 50433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine void* pframe, 50533bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine size_t vframe_size, 50633bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine size_t pframe_size) 50733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine{ 508629719e390ce66be822c3563bbd248ce15eaae7bSteve Block ALOGV("%s", __FUNCTION__); 50949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine 51033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine char query_str[256]; 51133bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine snprintf(query_str, sizeof(query_str), "%s video=%d preview=%d", 5125467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine mQueryFrame, (vframe && vframe_size) ? vframe_size : 0, 51333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine (pframe && pframe_size) ? pframe_size : 0); 51433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine QemuQuery query(query_str); 5155467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine doQuery(&query); 5165467be2eefc007ebf09baf109dafe058abc1ffc5Vladimir Chtchetkine const status_t res = query.getCompletionStatus(); 51749842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine if( res != NO_ERROR) { 51849842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE("%s: Query failed: %s", 51949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine __FUNCTION__, query.mReplyData ? query.mReplyData : 52033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine "No error message"); 52149842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine return res; 52249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine } 52349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine 52449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine /* Copy requested frames. */ 52549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine size_t cur_offset = 0; 52649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine const uint8_t* frame = reinterpret_cast<const uint8_t*>(query.mReplyData); 52749842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine /* Video frame is always first. */ 52849842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine if (vframe != NULL && vframe_size != 0) { 52949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine /* Make sure that video frame is in. */ 53049842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine if ((query.mReplyDataSize - cur_offset) >= vframe_size) { 53149842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine memcpy(vframe, frame, vframe_size); 53249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine cur_offset += vframe_size; 53349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine } else { 53449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE("%s: Reply %d bytes is to small to contain %d bytes video frame", 53549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine __FUNCTION__, query.mReplyDataSize - cur_offset, vframe_size); 53649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine return EINVAL; 53733bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 53849842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine } 53949842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine if (pframe != NULL && pframe_size != 0) { 54049842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine /* Make sure that preview frame is in. */ 54149842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine if ((query.mReplyDataSize - cur_offset) >= pframe_size) { 54249842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine memcpy(pframe, frame + cur_offset, pframe_size); 54349842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine cur_offset += pframe_size; 54449842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine } else { 54549842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine LOGE("%s: Reply %d bytes is to small to contain %d bytes preview frame", 54649842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine __FUNCTION__, query.mReplyDataSize - cur_offset, pframe_size); 54749842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine return EINVAL; 54833bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 54933bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine } 55033bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 55149842cee0549befb6d7a4353247190820037e1c4Vladimir Chtchetkine return NO_ERROR; 55233bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine} 55333bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine 55433bda475286a625337ed184e7053fc29e403d57bVladimir Chtchetkine}; /* namespace android */ 555