コード例 #1
0
/* 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;
}
コード例 #2
0
/*
 * 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);
        }
    }
コード例 #3
0
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";
}
コード例 #4
0
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;
}
コード例 #5
0
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);
}
コード例 #6
0
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++;
}
コード例 #7
0
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;
}
コード例 #8
0
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;
}
コード例 #9
0
int
qlooper_run(Looper* ll, Duration deadline_ms)
{
    APANIC("Trying to run the QEMU main event loop explicitely!");
    return EINVAL;
}
コード例 #10
0
/*
 * 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;
}
コード例 #11
0
/* 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));
}