Refactored emulated camera HAL to comply with code style
Change-Id: If57b536ae6b1f9bad4213630488591a3b3cc9fdd
This commit is contained in:
315
tools/emulator/system/camera/EmulatedCameraFactory.cpp
Executable file
315
tools/emulator/system/camera/EmulatedCameraFactory.cpp
Executable file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Contains implementation of a class EmulatedCameraFactory that manages cameras
|
||||
* available for emulation.
|
||||
*/
|
||||
|
||||
#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "EmulatedCamera_Factory"
|
||||
#include <cutils/log.h>
|
||||
#include "EmulatedQemuCamera.h"
|
||||
#include "EmulatedFakeCamera.h"
|
||||
#include "EmulatedCameraFactory.h"
|
||||
|
||||
extern camera_module_t HAL_MODULE_INFO_SYM;
|
||||
|
||||
/* A global instance of EmulatedCameraFactory is statically instantiated and
|
||||
* initialized when camera emulation HAL is loaded.
|
||||
*/
|
||||
android::EmulatedCameraFactory gEmulatedCameraFactory;
|
||||
|
||||
namespace android {
|
||||
|
||||
EmulatedCameraFactory::EmulatedCameraFactory()
|
||||
: mQemuClient(),
|
||||
mEmulatedCameras(NULL),
|
||||
mEmulatedCameraNum(0),
|
||||
mFakeCameraID(-1),
|
||||
mConstructedOK(false)
|
||||
|
||||
{
|
||||
/* If qemu camera emulation is on, try to connect to the factory service in
|
||||
* the emulator. */
|
||||
if (isQemuCameraEmulationOn() && mQemuClient.connectClient(NULL) == NO_ERROR) {
|
||||
/* Connection has succeeded. Create emulated cameras for each camera
|
||||
* device, reported by the service. */
|
||||
createQemuCameras();
|
||||
}
|
||||
|
||||
if (isFakeCameraEmulationOn()) {
|
||||
/* ID fake camera with the number of created 'qemud' cameras. */
|
||||
mFakeCameraID = mEmulatedCameraNum;
|
||||
mEmulatedCameraNum++;
|
||||
|
||||
/* Make sure that array is allocated (in case there were no 'qemu'
|
||||
* cameras created. */
|
||||
if (mEmulatedCameras == NULL) {
|
||||
mEmulatedCameras = new EmulatedCamera*[mEmulatedCameraNum];
|
||||
if (mEmulatedCameras == NULL) {
|
||||
LOGE("%s: Unable to allocate emulated camera array for %d entries",
|
||||
__FUNCTION__, mEmulatedCameraNum);
|
||||
return;
|
||||
}
|
||||
memset(mEmulatedCameras, 0, mEmulatedCameraNum * sizeof(EmulatedCamera*));
|
||||
}
|
||||
|
||||
/* Create, and initialize the fake camera */
|
||||
mEmulatedCameras[mFakeCameraID] =
|
||||
new EmulatedFakeCamera(mFakeCameraID, &HAL_MODULE_INFO_SYM.common);
|
||||
if (mEmulatedCameras[mFakeCameraID] != NULL) {
|
||||
if (mEmulatedCameras[mFakeCameraID]->Initialize() != NO_ERROR) {
|
||||
delete mEmulatedCameras[mFakeCameraID];
|
||||
mEmulatedCameras--;
|
||||
mFakeCameraID = -1;
|
||||
}
|
||||
} else {
|
||||
mEmulatedCameras--;
|
||||
mFakeCameraID = -1;
|
||||
LOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
LOGV("%d cameras are being emulated. Fake camera ID is %d",
|
||||
mEmulatedCameraNum, mFakeCameraID);
|
||||
|
||||
mConstructedOK = true;
|
||||
}
|
||||
|
||||
EmulatedCameraFactory::~EmulatedCameraFactory()
|
||||
{
|
||||
if (mEmulatedCameras != NULL) {
|
||||
for (int n = 0; n < mEmulatedCameraNum; n++) {
|
||||
if (mEmulatedCameras[n] != NULL) {
|
||||
delete mEmulatedCameras[n];
|
||||
}
|
||||
}
|
||||
delete[] mEmulatedCameras;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Camera HAL API handlers.
|
||||
*
|
||||
* Each handler simply verifies existence of an appropriate EmulatedCamera
|
||||
* instance, and dispatches the call to that instance.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
|
||||
{
|
||||
*device = NULL;
|
||||
|
||||
if (!isConstructedOK()) {
|
||||
LOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (camera_id >= getEmulatedCameraNum()) {
|
||||
LOGE("%s: Camera id %d is out of bounds (%d)",
|
||||
__FUNCTION__, camera_id, getEmulatedCameraNum());
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return mEmulatedCameras[camera_id]->connectCamera(device);
|
||||
}
|
||||
|
||||
int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
|
||||
{
|
||||
if (!isConstructedOK()) {
|
||||
LOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (camera_id >= getEmulatedCameraNum()) {
|
||||
LOGE("%s: Camera id %d is out of bounds (%d)",
|
||||
__FUNCTION__, camera_id, getEmulatedCameraNum());
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return mEmulatedCameras[camera_id]->getCameraInfo(info);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Camera HAL API callbacks.
|
||||
***************************************************************************/
|
||||
|
||||
int EmulatedCameraFactory::device_open(const hw_module_t* module,
|
||||
const char* name,
|
||||
hw_device_t** device)
|
||||
{
|
||||
/*
|
||||
* Simply verify the parameters, and dispatch the call inside the
|
||||
* EmulatedCameraFactory instance.
|
||||
*/
|
||||
|
||||
if (module != &HAL_MODULE_INFO_SYM.common) {
|
||||
LOGE("%s: Invalid module %p expected %p",
|
||||
__FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (name == NULL) {
|
||||
LOGE("%s: NULL name is not expected here", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
|
||||
}
|
||||
|
||||
int EmulatedCameraFactory::get_number_of_cameras(void)
|
||||
{
|
||||
return gEmulatedCameraFactory.getEmulatedCameraNum();
|
||||
}
|
||||
|
||||
int EmulatedCameraFactory::get_camera_info(int camera_id,
|
||||
struct camera_info* info)
|
||||
{
|
||||
return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Internal API
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* Camera information tokens passed in response to the "list" factory query.
|
||||
*/
|
||||
|
||||
/* Device name token. */
|
||||
static const char lListNameToken[] = "name=";
|
||||
/* Frame dimensions token. */
|
||||
static const char lListDimsToken[] = "framedims=";
|
||||
|
||||
void EmulatedCameraFactory::createQemuCameras()
|
||||
{
|
||||
/* Obtain camera list. */
|
||||
char* camera_list = NULL;
|
||||
status_t res = mQemuClient.listCameras(&camera_list);
|
||||
/* Empty list, or list containing just an EOL means that there were no
|
||||
* connected cameras found. */
|
||||
if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' ||
|
||||
*camera_list == '\n') {
|
||||
if (camera_list != NULL) {
|
||||
free(camera_list);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate number of connected cameras. Number of EOLs in the camera list
|
||||
* is the number of the connected cameras.
|
||||
*/
|
||||
|
||||
int num = 0;
|
||||
const char* eol = strchr(camera_list, '\n');
|
||||
while (eol != NULL) {
|
||||
num++;
|
||||
eol = strchr(eol + 1, '\n');
|
||||
}
|
||||
|
||||
/* Allocate the array for emulated camera instances. Note that we allocate
|
||||
* one more entry for the fake camera emulation. */
|
||||
mEmulatedCameras = new EmulatedCamera*[num + 1];
|
||||
if (mEmulatedCameras == NULL) {
|
||||
LOGE("%s: Unable to allocate emulated camera array for %d entries",
|
||||
__FUNCTION__, num + 1);
|
||||
free(camera_list);
|
||||
return;
|
||||
}
|
||||
memset(mEmulatedCameras, 0, sizeof(EmulatedCamera*) * (num + 1));
|
||||
|
||||
/*
|
||||
* Iterate the list, creating, and initializin emulated qemu cameras for each
|
||||
* entry (line) in the list.
|
||||
*/
|
||||
|
||||
int index = 0;
|
||||
char* cur_entry = camera_list;
|
||||
while (cur_entry != NULL && *cur_entry != '\0' && index < num) {
|
||||
/* Find the end of the current camera entry, and terminate it with zero
|
||||
* for simpler string manipulation. */
|
||||
char* next_entry = strchr(cur_entry, '\n');
|
||||
if (next_entry != NULL) {
|
||||
*next_entry = '\0';
|
||||
next_entry++; // Start of the next entry.
|
||||
}
|
||||
|
||||
/* Find 'name', and 'framedims' tokens that are required here. */
|
||||
char* name_start = strstr(cur_entry, lListNameToken);
|
||||
char* dim_start = strstr(cur_entry, lListDimsToken);
|
||||
if (name_start != NULL && dim_start != NULL) {
|
||||
/* Advance to the token values. */
|
||||
name_start += strlen(lListNameToken);
|
||||
dim_start += strlen(lListDimsToken);
|
||||
|
||||
/* Terminate token values with zero. */
|
||||
char* s = strchr(name_start, ' ');
|
||||
if (s != NULL) {
|
||||
*s = '\0';
|
||||
}
|
||||
s = strchr(dim_start, ' ');
|
||||
if (s != NULL) {
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
/* Create and initialize qemu camera. */
|
||||
EmulatedQemuCamera* qemu_cam =
|
||||
new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common);
|
||||
if (NULL != qemu_cam) {
|
||||
res = qemu_cam->Initialize(name_start, dim_start);
|
||||
if (res == NO_ERROR) {
|
||||
mEmulatedCameras[index] = qemu_cam;
|
||||
index++;
|
||||
} else {
|
||||
delete qemu_cam;
|
||||
}
|
||||
} else {
|
||||
LOGE("%s: Unable to instantiate EmulatedQemuCamera",
|
||||
__FUNCTION__);
|
||||
}
|
||||
} else {
|
||||
LOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry);
|
||||
}
|
||||
|
||||
cur_entry = next_entry;
|
||||
}
|
||||
|
||||
mEmulatedCameraNum = index;
|
||||
}
|
||||
|
||||
bool EmulatedCameraFactory::isQemuCameraEmulationOn()
|
||||
{
|
||||
/* TODO: Have a boot property that controls that! */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmulatedCameraFactory::isFakeCameraEmulationOn()
|
||||
{
|
||||
/* TODO: Have a boot property that controls that! */
|
||||
return true;
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Initializer for the static member structure.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Entry point for camera HAL API. */
|
||||
struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
|
||||
open: EmulatedCameraFactory::device_open
|
||||
};
|
||||
|
||||
}; /* namespace android */
|
||||
Reference in New Issue
Block a user