/* Reads UI control command response from the core. * Param: * resp - Upon success contains command response header. * resp_data - Upon success contains allocated reponse data (if any). The caller * is responsible for deallocating the memory returned here. * Return: * 0 on success, or < 0 on failure. */ static int _coreCmdProxy_get_response(UICmdRespHeader* resp, void** resp_data) { int status = syncsocket_start_read(_coreCmdProxy.sync_reader); if (!status) { // Read the header. status = syncsocket_read(_coreCmdProxy.sync_reader, resp, sizeof(UICmdRespHeader), core_connection_get_timeout(sizeof(UICmdRespHeader))); // Read response data (if any). if (status > 0 && resp->resp_data_size) { *resp_data = malloc(resp->resp_data_size); if (*resp_data == NULL) { APANIC("_coreCmdProxy_get_response is unable to allocate response data buffer.\n"); } status = syncsocket_read(_coreCmdProxy.sync_reader, *resp_data, resp->resp_data_size, core_connection_get_timeout(resp->resp_data_size)); } status = syncsocket_result(status); syncsocket_stop_read(_coreCmdProxy.sync_reader); } if (status < 0) { derror("Unable to get UI command response from the Core: %s\n", errno_str); } return status; }
/* * Asynchronous I/O callback launched when framebuffer notifications are ready * to be read. * Param: * opaque - FrameBufferImpl instance. */ static void _fbUpdatesImpl_io_callback(void* opaque, int fd, unsigned events) { FrameBufferImpl* fbi = opaque; int ret; // Read updates while they are immediately available. for (;;) { // Read next chunk of data. ret = HANDLE_EINTR( socket_recv(fbi->sock, fbi->reader_buffer + fbi->reader_offset, fbi->reader_bytes - fbi->reader_offset)); if (ret < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { // Chunk is not avalable at this point. Come back later. return; } if (ret <= 0) { /* disconnection ! */ derror("Unable to receive framebuffer data: %s\n", ret < 0 ? strerror(errno), "unexpected disconnection"); fbUpdatesImpl_destroy(); return; } fbi->reader_offset += ret; if (fbi->reader_offset != fbi->reader_bytes) { // There are still some data left in the pipe. continue; } // All expected data has been read. Time to change the state. if (fbi->fb_state == EXPECTS_HEADER) { // Update header has been read. Prepare for the pixels. fbi->fb_state = EXPECTS_PIXELS; fbi->reader_offset = 0; fbi->reader_bytes = fbi->update_header.w * fbi->update_header.h * (fbi->bits_per_pixel / 8); fbi->reader_buffer = malloc(fbi->reader_bytes); if (fbi->reader_buffer == NULL) { APANIC("Unable to allocate memory for framebuffer update\n"); } } else { // Pixels have been read. Prepare for the header. uint8_t* pixels = fbi->reader_buffer; fbi->fb_state = EXPECTS_HEADER; fbi->reader_offset = 0; fbi->reader_bytes = sizeof(FBUpdateMessage); fbi->reader_buffer = (uint8_t*)&fbi->update_header; // Perform the update. Note that pixels buffer must be freed there. _update_rect(fbi->fb, fbi->update_header.x, fbi->update_header.y, fbi->update_header.w, fbi->update_header.h, fbi->bits_per_pixel, pixels); } }
const char* androidPartitionType_toString(AndroidPartitionType part_type) { for (size_t n = 0; n < kPartitionTypeMapSize; ++n) { if (kPartitionTypeMap[n].value == part_type) { return kPartitionTypeMap[n].name; } } APANIC("Invalid partition type value %d", part_type); return "unknown"; }
static char* _getAvdTargetArch(const char* avdPath) { IniFile* ini; char* targetArch = NULL; char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); p = bufprint(temp, end, "%s" PATH_SEP "config.ini", avdPath); if (p >= end) { APANIC("AVD path too long: %s\n", avdPath); } ini = iniFile_newFromFile(temp); if (ini == NULL) { APANIC("Could not open AVD config file: %s\n", temp); } targetArch = iniFile_getString(ini, "hw.cpu.arch", "arm"); iniFile_free(ini); return targetArch; }
char* path_getSdkHome(void) { char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); p = bufprint_config_path(temp, end); if (p >= end) { APANIC("User path too long!: %s\n", temp); } return strdup(temp); }
void goldfish_pipe_add_type(const char* pipeName, void* pipeOpaque, const GoldfishPipeFuncs* pipeFuncs ) { PipeServices* list = _pipeServices; int count = list->count; if (count >= MAX_PIPE_SERVICES) { APANIC("Too many goldfish pipe services (%d)", count); } if (strlen(pipeName) > MAX_PIPE_SERVICE_NAME_SIZE) { APANIC("Pipe service name too long: '%s'", pipeName); } list->services[count].name = pipeName; list->services[count].opaque = pipeOpaque; list->services[count].funcs = pipeFuncs[0]; list->count++; }
int corecmd_get_qemu_path(int type, const char* filename, char* path, size_t path_buf_size) { UICmdRespHeader resp; char* resp_data = NULL; int status; // Initialize and send the query. uint32_t cmd_data_size = sizeof(UICmdGetQemuPath) + strlen(filename) + 1; UICmdGetQemuPath* req = (UICmdGetQemuPath*)malloc(cmd_data_size); if (req == NULL) { APANIC("corecmd_get_qemu_path is unable to allocate %u bytes\n", cmd_data_size); } req->type = type; strcpy(req->filename, filename); status = _coreCmdProxy_send_command(AUICMD_GET_QEMU_PATH, req, cmd_data_size); if (status < 0) { return status; } // Obtain the response from the core. status = _coreCmdProxy_get_response(&resp, (void**)&resp_data); if (status < 0) { return status; } if (!resp.result && resp_data != NULL) { strncpy(path, resp_data, path_buf_size); path[path_buf_size - 1] = '\0'; } if (resp_data != NULL) { free(resp_data); } return resp.result; }
static char* _getAvdContentPath(const char* avdName) { char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); IniFile* ini = NULL; char* iniPath = path_getRootIniPath(avdName); char* avdPath = NULL; if (iniPath != NULL) { ini = iniFile_newFromFile(iniPath); AFREE(iniPath); } if (ini == NULL) { APANIC("Could not open: %s\n", iniPath == NULL ? avdName : iniPath); } avdPath = iniFile_getString(ini, ROOT_ABS_PATH_KEY, NULL); if (!path_is_dir(avdPath)) { // If the absolute path doesn't match an actual directory, try // the relative path if present. const char* relPath = iniFile_getString(ini, ROOT_REL_PATH_KEY, NULL); if (relPath != NULL) { p = bufprint_config_path(temp, end); p = bufprint(p, end, PATH_SEP "%s", relPath); if (p < end && path_is_dir(temp)) { AFREE(avdPath); avdPath = ASTRDUP(temp); } } } iniFile_free(ini); return avdPath; }
int qlooper_run(Looper* ll, Duration deadline_ms) { APANIC("Trying to run the QEMU main event loop explicitely!"); return EINVAL; }
/* * emulator engine selection process is * emulator -> * arm: * 32-bit: emulator(64)-arm * 64-bit: emulator(64)-arm64(NA) -> emulator(64)-ranchu-arm64 -> qemu/<host>/qemu-system-aarch64 * mips: * 32-bit: emulator(64)-mips * 64-bit: emulator(64)-mips64(NA) -> emulator(64)-ranchu-mips64 -> qemu/<host>/qemu-system-mips64 * x86: * 32-bit: (if '-ranchu') * emulator(64)-ranchu-x86 -> qemu/<host>/qemu-system-x86 * else * emulator(64)-x86 * 64-bit: (if '-ranchu') * emulator(64)-ranchu-x86_64 -> qemu/<host>/qemu-system-x86_64 * else * emulator(64)-x86 */ static char* getTargetEmulatorPath(const char* progDir, bool tryCurrentPath, const char* avdArch, const int force_32bit, bool* is_64bit) { char* result; char* ranchu_result; bool search_for_64bit_emulator = !force_32bit && android_getHostBitness() == 64; #ifdef _WIN32 // Using emulator64-arm.exe results in a kernel panic while // x86/x86_64 emulator executables don't have this issue if (!strcmp(avdArch, "arm")) { search_for_64bit_emulator = false; } #endif const char* emulatorSuffix; /* Try look for classic emulator first */ emulatorSuffix = emulator_getBackendSuffix(avdArch); if (!emulatorSuffix) { APANIC("This emulator cannot emulate %s CPUs!\n", avdArch); } D("Looking for emulator-%s to emulate '%s' CPU\n", emulatorSuffix, avdArch); result = probeTargetEmulatorPath(progDir, NULL, emulatorSuffix, search_for_64bit_emulator, tryCurrentPath, is_64bit); if (result && !ranchu) { /* found and not ranchu */ D("return result: %s\n", result); return result; } else { /* no classic emulator or prefer ranchu */ D("Looking for ranchu emulator backend for %s CPU\n", avdArch); ranchu_result = probeTargetEmulatorPath(progDir, "ranchu", avdArch, #ifdef _WIN32 true, // 32 bit ranchu does not work on windows #else search_for_64bit_emulator, #endif tryCurrentPath, is_64bit); if (ranchu_result) { D("return ranchu: %s\n", ranchu_result); return ranchu_result; } else { if (result) { /* ranchu not found, fallback to classic should NOT happen in current scenario just go ahead still and leave a message */ fprintf(stderr, "ERROR: requested 'ranchu' not available\n" "classic backend is used\n"); return result; } } } /* Otherwise, the program is missing */ APANIC("Missing emulator engine program for '%s' CPUS.\n", avdArch); return NULL; }
/* Find the target-specific emulator binary. This will be something * like <programDir>/emulator-<targetArch>, where <programDir> is * the directory of the current program. */ static char* getTargetEmulatorPath(const char* progName, const char* avdArch, const int force_32bit) { char* progDir; char path[PATH_MAX], *pathEnd=path+sizeof(path), *p; const char* emulatorPrefix = "emulator-"; const char* emulator64Prefix = "emulator64-"; #ifdef _WIN32 const char* exeExt = ".exe"; /* ToDo: currently amd64-mingw32msvc-gcc doesn't work (http://b/issue?id=5949152) which prevents us from generating 64-bit emulator for Windows */ int search_for_64bit_emulator = 0; #else const char* exeExt = ""; int search_for_64bit_emulator = !force_32bit && getHostOSBitness() == 64; #endif /* Get program's directory name in progDir */ path_split(progName, &progDir, NULL); if (search_for_64bit_emulator) { /* Find 64-bit emulator first */ p = bufprint(path, pathEnd, "%s/%s%s%s", progDir, emulator64Prefix, avdArch, exeExt); if (p >= pathEnd) { APANIC("Path too long: %s\n", progName); } if (path_exists(path)) { free(progDir); return strdup(path); } } /* Find 32-bit emulator */ p = bufprint(path, pathEnd, "%s/%s%s%s", progDir, emulatorPrefix, avdArch, exeExt); free(progDir); if (p >= pathEnd) { APANIC("Path too long: %s\n", progName); } if (path_exists(path)) { return strdup(path); } /* Mmm, the file doesn't exist, If there is no slash / backslash * in our path, we're going to try to search it in our path. */ #ifdef _WIN32 if (strchr(progName, '/') == NULL && strchr(progName, '\\') == NULL) { #else if (strchr(progName, '/') == NULL) { #endif if (search_for_64bit_emulator) { p = bufprint(path, pathEnd, "%s%s%s", emulator64Prefix, avdArch, exeExt); if (p < pathEnd) { char* resolved = path_search_exec(path); if (resolved != NULL) return resolved; } } p = bufprint(path, pathEnd, "%s%s%s", emulatorPrefix, avdArch, exeExt); if (p < pathEnd) { char* resolved = path_search_exec(path); if (resolved != NULL) return resolved; } } /* Otherwise, the program is missing */ APANIC("Missing arch-specific emulator program: %s\n", path); return NULL; } /* return 1 iff <path>/<filename> exists */ static int probePathForFile(const char* path, const char* filename) { char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); p = bufprint(temp, end, "%s/%s", path, filename); D("Probing for: %s\n", temp); return (p < end && path_exists(temp)); }