From 7485c2989d727a1d0c14a66fb75e140f885a1583 Mon Sep 17 00:00:00 2001 From: Vladimir Chtchetkine Date: Mon, 19 Mar 2012 11:35:29 -0700 Subject: Refactor HW config to use hw.camera_back, and hw.camera_front properties. This is a continuation of an effort to simplify HW config, and make the UI for it clearer. This CL gets rid of multiple camera emulation properties, combining everything into just two properties: - hw.camera_back that controls emulation of a camera facing back, and - hw.camera_front that controls emulation of a camera facing front. Change-Id: Ia114ae4caf2053685cbff00f39088e5b5be2952c --- android/avd/hardware-properties.ini | 125 +++------------------------- android/camera/camera-service.c | 139 ++++++++++++------------------- android/cmdline-options.h | 5 +- android/help.c | 34 ++++---- android/main.c | 161 ++++++------------------------------ hw/goldfish_events_device.c | 4 +- vl-android.c | 17 +++- 7 files changed, 126 insertions(+), 359 deletions(-) diff --git a/android/avd/hardware-properties.ini b/android/avd/hardware-properties.ini index fdabcb5..4ea63ca 100644 --- a/android/avd/hardware-properties.ini +++ b/android/avd/hardware-properties.ini @@ -114,13 +114,6 @@ default = yes abstract = GSM modem support description = Whether there is a GSM modem in the device. -# Camera support -name = hw.camera -type = boolean -default = yes -abstract = Camera support -description = Whether the device has a camera. - # GPS support name = hw.gps type = boolean @@ -227,119 +220,21 @@ default = no abstract = GPU emulation description = Enable/Disable emulated OpenGLES GPU -# Fake camera support -# -name = hw.fakeCamera -type = string -default = back -abstract = Fake camera control -description = Must be 'back', if fake camera is facing back, 'front', if fake camera is facing front, or 'off' if fake camera is disabled. - -# Number of emulated web cameras -# -name = hw.webcam.count -type = integer -default = 6 -abstract = Number of emulated web cameras -description = Defines number of web cameras to emulate. 0 disables webcam emulation. - -# Defines name of the emulated webcam with index 0 -# -name = hw.webcam.0.name -type = string -default = webcam0 -abstract = Name of the 1-st emulated web camera -description = Emulator-generated platform-independent name identifying a camera in the list of enumerated web cameras. - -# Defines name of the emulated webcam with index 1 -# -name = hw.webcam.1.name -type = string -default = webcam1 -abstract = Name of the 2-nd emulated web camera -description = Emulator-generated platform-independent camera name. - -# Defines name of the emulated webcam with index 2 -# -name = hw.webcam.2.name -type = string -default = webcam2 -abstract = Name of the 3-rd emulated web camera -description = Emulator-generated platform-independent camera name. - -# Defines name of the emulated webcam with index 3 -# -name = hw.webcam.3.name -type = string -default = webcam3 -abstract = Name of the 4-th emulated web camera -description = Emulator-generated platform-independent camera name. - -# Defines name of the emulated webcam with index 4 -# -name = hw.webcam.4.name -type = string -default = webcam4 -abstract = Name of the 5-th emulated web camera -description = Emulator-generated platform-independent camera name. - -# Defines name of the emulated webcam with index 5 -# -name = hw.webcam.5.name -type = string -default = webcam5 -abstract = Name of the 6-th emulated web camera -description = Emulator-generated platform-independent camera name. - -# Defines direction of the emulated webcam with index 0 -# -name = hw.webcam.0.direction -type = string -default = front -abstract = 1-st emulated web camera direction -description = Direction of the 1-st emulated web camera - -# Defines direction of the emulated webcam with index 1 -# Note that first two cameras must face in opposite directions in order to enable -# camera switch in the camera application. -# -name = hw.webcam.1.direction -type = string -default = back -abstract = 2-nd emulated web camera direction -description = Direction of the 2-nd emulated web camera - -# Defines direction of the emulated webcam with index 2 -# -name = hw.webcam.2.direction -type = string -default = front -abstract = 3-rd emulated web camera direction -description = Direction of the 3-rd emulated web camera - -# Defines direction of the emulated webcam with index 3 -# -name = hw.webcam.3.direction -type = string -default = front -abstract = 4-th emulated web camera direction -description = Direction of the 4-th emulated web camera - -# Defines direction of the emulated webcam with index 4 +# Configures camera facing back # -name = hw.webcam.4.direction +name = hw.camera.back type = string -default = front -abstract = 5-th emulated web camera direction -description = Direction of the 5-th emulated web camera +default = emulated +abstract = Configures camera facing back +description = Must be 'emulated' for a fake camera, 'webcam' for a web camera, or 'none' if back camera is disabled. -# Defines direction of the emulated webcam with index 5 +# Configures camera facing front # -name = hw.webcam.5.direction +name = hw.camera.front type = string -default = front -abstract = 6-th emulated web camera direction -description = Direction of the 6-th emulated web camera +default = none +abstract = Configures camera facing front +description = Must be 'emulated' for a fake camera, 'webcam' for a web camera, or 'none' if front camera is disabled. # Maximum VM heap size # Higher values are required for high-dpi devices diff --git a/android/camera/camera-service.c b/android/camera/camera-service.c index 51af2de..173b6f5 100644 --- a/android/camera/camera-service.c +++ b/android/camera/camera-service.c @@ -233,7 +233,8 @@ _camera_info_get_by_display_name(const char* disp_name, CameraInfo* arr, int num { int n; for (n = 0; n < num; n++) { - if (arr[n].display_name != NULL && !strcmp(arr[n].display_name, disp_name)) { + if (!arr[n].in_use && arr[n].display_name != NULL && + !strcmp(arr[n].display_name, disp_name)) { return &arr[n]; } } @@ -265,6 +266,47 @@ _camera_info_get_by_device_name(const char* device_name, CameraInfo* arr, int nu * CameraServiceDesc API *******************************************************************************/ +/* Initialized webcam emulation record in camera service descriptor. + * Param: + * csd - Camera service descriptor to initialize a record in. + * disp_name - Display name of a web camera ('webcam') to use for emulation. + * dir - Direction ('back', or 'front') that emulated camera is facing. + * ci, ci_cnt - Array of webcam information for enumerated web cameras connected + * to the host. + */ +static void +_wecam_setup(CameraServiceDesc* csd, + const char* disp_name, + const char* dir, + CameraInfo* ci, + int ci_cnt) +{ + /* Find webcam record in the list of enumerated web cameras. */ + CameraInfo* found = _camera_info_get_by_display_name(disp_name, ci, ci_cnt); + if (found == NULL) { + W("Camera name '%s' is not found in the list of connected cameras.\n" + "Use '-webcam-list' emulator option to obtain the list of connected camera names.\n", + disp_name); + return; + } + + /* Save to the camera info array that will be used by the service. */ + memcpy(csd->camera_info + csd->camera_count, found, sizeof(CameraInfo)); + /* This camera is taken. */ + found->in_use = 1; + /* Update direction parameter. */ + if (csd->camera_info[csd->camera_count].direction != NULL) { + free(csd->camera_info[csd->camera_count].direction); + } + csd->camera_info[csd->camera_count].direction = ASTRDUP(dir); + D("Camera %d '%s' connected to '%s' facing %s using %.4s pixel format", + csd->camera_count, csd->camera_info[csd->camera_count].display_name, + csd->camera_info[csd->camera_count].device_name, + csd->camera_info[csd->camera_count].direction, + (const char*)(&csd->camera_info[csd->camera_count].pixel_format)); + csd->camera_count++; +} + /* Initializes camera service descriptor. */ static void @@ -272,107 +314,34 @@ _camera_service_init(CameraServiceDesc* csd) { CameraInfo ci[MAX_CAMERA]; int connected_cnt; - int i; /* Enumerate camera devices connected to the host. */ memset(ci, 0, sizeof(CameraInfo) * MAX_CAMERA); memset(csd->camera_info, 0, sizeof(CameraInfo) * MAX_CAMERA); csd->camera_count = 0; - if (android_hw->hw_camera == 0) { - /* Camera emulation is disabled. Skip enumeration of webcameras. */ + /* Lets see if HW config uses web cameras. */ + if (memcmp(android_hw->hw_camera_back, "webcam", 6) && + memcmp(android_hw->hw_camera_front, "webcam", 6)) { + /* Web camera emulation is disabled. Skip enumeration of webcameras. */ return; } + /* Enumerate web cameras connected to the host. */ connected_cnt = enumerate_camera_devices(ci, MAX_CAMERA); if (connected_cnt <= 0) { /* Nothing is connected - nothing to emulate. */ return; } - /* For each webcam declared in hw.ini find an actual camera information - * descriptor, and save it into the service descriptor for the emulation. - * Stop the loop when all the connected cameras have been added to the - * service. */ - for (i = 0; i < android_hw->hw_webcam_count && - csd->camera_count < connected_cnt; i++) { - const char* disp_name; - const char* dir; - CameraInfo* found; - - switch (i) { - case 0: - disp_name = android_hw->hw_webcam_0_name; - dir = android_hw->hw_webcam_0_direction; - break; - case 1: - disp_name = android_hw->hw_webcam_1_name; - dir = android_hw->hw_webcam_1_direction; - break; - case 2: - disp_name = android_hw->hw_webcam_2_name; - dir = android_hw->hw_webcam_2_direction; - break; - case 3: - disp_name = android_hw->hw_webcam_3_name; - dir = android_hw->hw_webcam_3_direction; - break; - case 4: - disp_name = android_hw->hw_webcam_4_name; - dir = android_hw->hw_webcam_4_direction; - break; - case 5: - default: - disp_name = android_hw->hw_webcam_5_name; - dir = android_hw->hw_webcam_5_direction; - break; - } - found = _camera_info_get_by_display_name(disp_name, ci, connected_cnt); - if (found != NULL) { - /* Save to the camera info array that will be used by the service. - * Note that we just copy everything over, and NULL the source - * record. */ - memcpy(csd->camera_info + csd->camera_count, found, sizeof(CameraInfo)); - /* Update direction parameter. */ - if (csd->camera_info[csd->camera_count].direction != NULL) { - free(csd->camera_info[csd->camera_count].direction); - } - csd->camera_info[csd->camera_count].direction = ASTRDUP(dir); - D("Camera %d '%s' connected to '%s' facing %s using %.4s pixel format", - csd->camera_count, csd->camera_info[csd->camera_count].display_name, - csd->camera_info[csd->camera_count].device_name, - csd->camera_info[csd->camera_count].direction, - (const char*)(&csd->camera_info[csd->camera_count].pixel_format)); - csd->camera_count++; - memset(found, 0, sizeof(CameraInfo)); - } else { - W("Camera name '%s' is not found in the list of connected cameras.\n" - "Use '-webcam list' emulator option to obtain the list of connected camera names.\n", - disp_name); - } + /* Set up back camera emulation. */ + if (!memcmp(android_hw->hw_camera_back, "webcam", 6)) { + _wecam_setup(csd, android_hw->hw_camera_back, "back", ci, connected_cnt); } - /* Make sure that camera 0 and camera 1 are facing in opposite directions. - * If they don't the camera application will crash on an attempt to switch - * cameras. */ - if (csd->camera_count > 0) { - const char* cam2_dir = NULL; - const char* cam2_name = NULL; - if (csd->camera_count >= 2) { - cam2_dir = csd->camera_info[1].direction; - cam2_name = csd->camera_info[1].display_name; - } else if (strcmp(android_hw->hw_fakeCamera, "off")) { - cam2_dir = android_hw->hw_fakeCamera; - cam2_name = "fake camera"; - } - if (cam2_dir != NULL && !strcmp(csd->camera_info[0].direction, cam2_dir)) { - W("Cameras '%s' and '%s' are both facing %s.\n" - "It is required by the camera application that first two emulated cameras\n" - "are facing in opposite directions. If they both are facing in the same direction,\n" - "the camera application will crash on an attempt to switch the camera.\n", - csd->camera_info[0].display_name, cam2_name, cam2_dir); - - } + /* Set up front camera emulation. */ + if (!memcmp(android_hw->hw_camera_front, "webcam", 6)) { + _wecam_setup(csd, android_hw->hw_camera_front, "front", ci, connected_cnt); } } diff --git a/android/cmdline-options.h b/android/cmdline-options.h index d490e40..aa85c0e 100644 --- a/android/cmdline-options.h +++ b/android/cmdline-options.h @@ -156,8 +156,9 @@ OPT_PARAM( attach_core, "", "attach to a running core process" ) OPT_PARAM( gpu, "", "set hardware OpenGLES emulation mode" ) -OPT_PARAM( fake_camera, "", "set fake camera emulation mode" ) -OPT_LIST( webcam, "name=[,dir=]", "setup web camera emulation" ) +OPT_PARAM( camera_back, "", "set emulation mode for a camera facing back" ) +OPT_PARAM( camera_front, "", "set emulation mode for a camera facing front" ) +OPT_FLAG( webcam_list, "lists web cameras available for emulation" ) OPT_PARAM( screen, "", "set emulated screen mode" ) diff --git a/android/help.c b/android/help.c index db630e0..54d2f10 100644 --- a/android/help.c +++ b/android/help.c @@ -1457,34 +1457,36 @@ help_gpu(stralloc_t* out) } static void -help_fake_camera(stralloc_t* out) +help_camera_back(stralloc_t* out) { PRINTF( - " Use -fake-camera to control fake camera emulation.\n" + " Use -camera-back to control emulation of a camera facing back.\n" " Valid values for are:\n\n" - " off -> disable fake camera emulation\n" - " back -> fake camera is facing back\n" - " front -> fake camera is facing front\n\n" + " emulated -> camera will be emulated using software ('fake') camera emulation\n" + " webcam -> camera will be emulated using a webcamera connected to the host\n" + " none -> camera emulation will be disabled\n\n" ); } static void -help_webcam(stralloc_t* out) +help_camera_front(stralloc_t* out) { PRINTF( - " Use -webcam off to disable web camera emulation.\n" - " Use -webcam list to list web cameras available for emulation.\n" - " Use -webcam name=[,dir=] to setup parameters for web camera emulation.\n" - - " platform-independent name identifying emulated camera device.\n" - " use '-webcam list' to obtain the list of emulated camera devices.\n" - " defines direction the camera is facing. Valid values are:\n\n" + " Use -camera-front to control emulation of a camera facing front.\n" + " Valid values for are:\n\n" - " front -> emulate camera as facing front\n" - " back -> emulate camera as facing back\n\n" + " emulated -> camera will be emulated using software ('fake') camera emulation\n" + " webcam -> camera will be emulated using a webcamera connected to the host\n" + " none -> camera emulation will be disabled\n\n" + ); +} - " Default direction value for emulated web camera is 'front'\n\n" +static void +help_webcam_list(stralloc_t* out) +{ + PRINTF( + " Use -webcam-list to list web cameras available for emulation.\n\n" ); } diff --git a/android/main.c b/android/main.c index f8ad54b..9a763e5 100644 --- a/android/main.c +++ b/android/main.c @@ -155,65 +155,6 @@ _adjustPartitionSize( const char* description, return convertMBToBytes(imageMB); } -/* Parses a -webcam option, extracting 'name', and 'dir' values. - * Param: - * param - -webcam option, that should be formatted as such: - * name=[,dir=] - * name, name_size - buffer (and its size) where to receive - * dir, dir_size - buffer (and its size) where to receive - */ -static void -_parseWebcamOption(const char* param, - char* name, size_t name_size, - char* dir, size_t dir_size) -{ - const char* dr; - const char* wc_opt = param; - - /* Must start with 'name=' */ - if (strlen(wc_opt) <= 5 || memcmp(wc_opt, "name=", 5)) { - derror("Invalid value for -webcam parameter: %s\n", param); - exit(1); - } - - /* Move on to 'name' value. */ - wc_opt += 5; - dr = strchr(wc_opt, ','); - if (dr == NULL) { - dr = wc_opt + strlen(wc_opt); - } - - /* Make sure that fits */ - if ((dr - wc_opt) < name_size) { - memcpy(name, wc_opt, dr - wc_opt); - name[dr - wc_opt] = '\0'; - if (*dr == '\0') { - /* Default direction value is 'front' */ - strcpy(dir, "front"); - return; - } else { - dr++; - } - } else { - derror("Invalid value for -webcam parameter: %s\n", param); - exit(1); - } - - /* Parse 'dir'. Must begin with 'dir=' */ - if (strlen(dr) <= 4 || memcmp(dr, "dir=", 4)) { - derror("Invalid value for -webcam parameter: %s\n", param); - exit(1); - } - dr += 4; - /* Check the bounds, and the values */ - if (strlen(dr) >= dir_size || (strcmp(dr, "front") && strcmp(dr, "back"))) { - derror("Invalid value for -webcam parameter: %s\n" - "Valid values are: 'front', or 'back'\n", param); - exit(1); - } - strcpy(dir, dr); -} - int main(int argc, char **argv) { char tmp[MAX_PATH]; @@ -1164,90 +1105,36 @@ int main(int argc, char **argv) exit(1); } - if (opts->fake_camera) { - if (!strcmp(opts->fake_camera, "back") || - !strcmp(opts->fake_camera, "front") || - !strcmp(opts->fake_camera, "off")) { - hw->hw_fakeCamera = ASTRDUP(opts->fake_camera); - } else { - derror("Invalid value for -fake-camera parameter: %s\n", - opts->fake_camera); - derror("Valid values are: back, front, or off\n"); - exit(1); - } + /* Deal with camera emulation */ + if (opts->webcam_list) { + /* List connected webcameras */ + args[n++] = "-list-webcam"; } - int webcam_num = 0; - if (opts->webcam != NULL) { - ParamList* pl = opts->webcam; - for ( ; pl != NULL; pl = pl->next ) { - char webcam_name[64]; - char webcam_dir[16]; - if (!strcmp(pl->param, "off")) { - /* If 'off' is passed, there must be no other -webcam options. */ - if (webcam_num || pl->next != NULL) { - derror("'-webcam off' cannot be combined with other -webcam otions\n"); - exit(1); - } - break; - } - if (!strcmp(pl->param, "list")) { - /* If 'list' is passed, there must be no other -webcam options. */ - if (webcam_num || pl->next != NULL) { - derror("'-webcam list' cannot be combined with other -webcam otions\n"); - exit(1); - } - args[n++] = "-list-webcam"; - break; - } - /* Extract name, and direction */ - _parseWebcamOption(pl->param, webcam_name, sizeof(webcam_name), - webcam_dir, sizeof(webcam_dir)); - /* Save them to appropriate field in hw.ini */ - switch (webcam_num) { - case 0: - hw->hw_webcam_0_name = ASTRDUP(webcam_name); - hw->hw_webcam_0_direction = ASTRDUP(webcam_dir); - break; - case 1: - hw->hw_webcam_1_name = ASTRDUP(webcam_name); - hw->hw_webcam_1_direction = ASTRDUP(webcam_dir); - break; - case 2: - hw->hw_webcam_2_name = ASTRDUP(webcam_name); - hw->hw_webcam_2_direction = ASTRDUP(webcam_dir); - break; - case 3: - hw->hw_webcam_3_name = ASTRDUP(webcam_name); - hw->hw_webcam_3_direction = ASTRDUP(webcam_dir); - break; - case 4: - hw->hw_webcam_4_name = ASTRDUP(webcam_name); - hw->hw_webcam_4_direction = ASTRDUP(webcam_dir); - break; - case 5: - hw->hw_webcam_5_name = ASTRDUP(webcam_name); - hw->hw_webcam_5_direction = ASTRDUP(webcam_dir); - break; - default: - derror("Too many -webcam options. Maximum number of -webcam options is 6\n"); - exit(1); - } - webcam_num++; + if (opts->camera_back) { + /* Validate parameter. */ + if (memcmp(opts->camera_back, "webcam", 6) && + strcmp(opts->camera_back, "emulated") && + strcmp(opts->camera_back, "none")) { + derror("Invalid value for -camera-back parameter: %s\n" + "Valid values are: 'emulated', 'webcam', or 'none'\n", + opts->camera_back); + exit(1); } - hw->hw_webcam_count = webcam_num; + hw->hw_camera_back = ASTRDUP(opts->camera_back); } - /* Command line options related to webcam, and fake camera should - * override camera emulation flag, set in AVD. */ - if (hw->hw_camera == 0) { - /* Camera emulation is disabled in AVD. Lets see if command line enables - * webcam, or fake camera emulation. */ - if (webcam_num != 0 || - (opts->fake_camera && strcmp(hw->hw_fakeCamera, "off") != 0)) { - /* Command line parameters enable camera emulation. */ - hw->hw_camera = 1; + if (opts->camera_front) { + /* Validate parameter. */ + if (memcmp(opts->camera_front, "webcam", 6) && + strcmp(opts->camera_front, "emulated") && + strcmp(opts->camera_front, "none")) { + derror("Invalid value for -camera-front parameter: %s\n" + "Valid values are: 'emulated', 'webcam', or 'none'\n", + opts->camera_front); + exit(1); } + hw->hw_camera_front = ASTRDUP(opts->camera_front); } /* physical memory is now in hw->hw_ramSize */ diff --git a/hw/goldfish_events_device.c b/hw/goldfish_events_device.c index 0aa5a1f..dad76ad 100644 --- a/hw/goldfish_events_device.c +++ b/hw/goldfish_events_device.c @@ -406,7 +406,9 @@ void events_dev_init(uint32_t base, qemu_irq irq) events_set_bit(s, EV_KEY, BTN_TOUCH); } - if (config->hw_camera) { + if (strcmp(config->hw_camera_back, "none") || + strcmp(config->hw_camera_front, "none")) { + /* Camera emulation is enabled. */ events_set_bit(s, EV_KEY, KEY_CAMERA); } diff --git a/vl-android.c b/vl-android.c index ebff1eb..1ec910b 100644 --- a/vl-android.c +++ b/vl-android.c @@ -3764,10 +3764,21 @@ int main(int argc, char **argv, char **envp) //android_hw_opengles_init(); /* Initialize fake camera */ - if (android_hw->hw_fakeCamera) { - boot_property_add("qemu.sf.fake_camera", android_hw->hw_fakeCamera); + if (strcmp(android_hw->hw_camera_back, "emulated") && + strcmp(android_hw->hw_camera_front, "emulated")) { + /* Fake camera is not used for camera emulation. */ + boot_property_add("qemu.sf.fake_camera", "none"); } else { - boot_property_add("qemu.sf.fake_camera", "back"); + /* Fake camera is used for at least one camera emulation. */ + if (!strcmp(android_hw->hw_camera_back, "emulated") && + !strcmp(android_hw->hw_camera_front, "emulated")) { + /* Fake camera is used for both, front and back camera emulation. */ + boot_property_add("qemu.sf.fake_camera", "both"); + } else if (!strcmp(android_hw->hw_camera_back, "emulated")) { + boot_property_add("qemu.sf.fake_camera", "back"); + } else { + boot_property_add("qemu.sf.fake_camera", "front"); + } } /* Initialize camera emulation. */ -- cgit v1.1