12d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner/* Copyright (C) 2011 The Android Open Source Project
22d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner**
32d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner** This software is licensed under the terms of the GNU General Public
42d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner** License version 2, as published by the Free Software Foundation, and
52d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner** may be copied, distributed, and modified under those terms.
62d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner**
72d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner** This program is distributed in the hope that it will be useful,
82d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner** but WITHOUT ANY WARRANTY; without even the implied warranty of
92d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
102d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner** GNU General Public License for more details.
112d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner*/
122d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include <stdlib.h>
132d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include <stdio.h>
142d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include <errno.h>
152d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include "android/utils/debug.h"
162d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include "android/utils/bufprint.h"
172d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include "android/utils/ini.h"
182d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include "android/utils/panic.h"
192d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include "android/utils/path.h"
202d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include "android/utils/system.h"
212d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include "android/avd/util.h"
222d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
232d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
242d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
252d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner/* this is the subdirectory of $HOME/.android where all
262d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * root configuration files (and default content directories)
272d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * are located.
282d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner */
292d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#define  ANDROID_AVD_DIR    "avd"
302d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
312d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
322d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner/* Return the path to the Android SDK root installation.
332d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner *
342d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * (*pFromEnv) will be set to 1 if it comes from the $ANDROID_SDK_ROOT
352d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * environment variable, or 0 otherwise.
362d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner *
372d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * Caller must free() returned string.
382d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner */
392d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerchar*
402d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerpath_getSdkRoot( char *pFromEnv )
412d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
422d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    const char*  env;
432d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*        sdkPath;
442d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char         temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
452d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
462d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    /* If ANDROID_SDK_ROOT is defined is must point to a directory
472d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner     * containing a valid SDK installation.
482d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner     */
492d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#define  SDK_ROOT_ENV  "ANDROID_SDK_ROOT"
502d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
512d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    env = getenv(SDK_ROOT_ENV);
522d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (env != NULL && env[0] != 0) {
532d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (path_exists(env)) {
542d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            D("found " SDK_ROOT_ENV ": %s", env);
552d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            *pFromEnv = 1;
562d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            return ASTRDUP(env);
572d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        }
582d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        D(SDK_ROOT_ENV " points to unknown directory: %s", env);
592d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
602d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
612d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    *pFromEnv = 0;
622d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
632d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    /* We assume the emulator binary is under tools/ so use its
642d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner     * parent as the Android SDK root.
652d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner     */
662d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    (void) bufprint_app_dir(temp, end);
672d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    sdkPath = path_parent(temp, 1);
682d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (sdkPath == NULL) {
692d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        derror("can't find root of SDK directory");
702d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        return NULL;
712d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
722d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    D("found SDK root at %s", sdkPath);
732d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    return sdkPath;
742d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
752d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
762d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
772d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner/* Return the path to the AVD's root configuration .ini file. it is located in
782d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * ~/.android/avd/<name>.ini or Windows equivalent
792d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner *
802d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * This file contains the path to the AVD's content directory, which
812d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * includes its own config.ini.
822d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner */
832d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerchar*
842d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerpath_getRootIniPath( const char*  avdName )
852d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
862d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
872d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
882d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    p = bufprint_config_path(temp, end);
892d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    p = bufprint(p, end, "/" ANDROID_AVD_DIR "/%s.ini", avdName);
902d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (p >= end) {
912d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        return NULL;
922d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
932d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (!path_exists(temp)) {
942d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        return NULL;
952d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
962d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    return ASTRDUP(temp);
972d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
982d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
992d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1002d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerchar*
1012d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerpath_getSdkHome(void)
1022d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
103107be29100b6c422c8be58ca898687bf99534350David 'Digit' Turner    char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
104107be29100b6c422c8be58ca898687bf99534350David 'Digit' Turner    p = bufprint_config_path(temp, end);
105107be29100b6c422c8be58ca898687bf99534350David 'Digit' Turner    if (p >= end) {
106107be29100b6c422c8be58ca898687bf99534350David 'Digit' Turner        APANIC("User path too long!: %s\n", temp);
1072d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
108107be29100b6c422c8be58ca898687bf99534350David 'Digit' Turner    return strdup(temp);
1092d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
1102d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1112d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1122d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerstatic char*
1132d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner_getAvdContentPath(const char* avdName)
1142d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
1152d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*    sdkHome = path_getSdkHome();
1162d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*    avdPath = NULL;
1172d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    IniFile* ini;
1182d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char     temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
1192d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1202d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    /* Look for the root .ini file */
1212d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    p = bufprint(temp, end, "%s/avd/%s.ini", sdkHome, avdName);
1222d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (p >= end) {
1232d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        APANIC("AVD Name too long: %s\n", avdName);
1242d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
1252d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1262d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    ini = iniFile_newFromFile(temp);
1272d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (ini == NULL) {
1282d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        APANIC("Could not open: %s", temp);
1292d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
1302d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1312d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    avdPath = iniFile_getString(ini, "path", NULL);
1322d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1332d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    iniFile_free(ini);
1342d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    AFREE(sdkHome);
1352d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1362d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    return avdPath;
1372d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
1382d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1392d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1402d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerstatic char*
1412d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner_getAvdTargetArch(const char* avdPath)
1422d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
1432d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    IniFile* ini;
1442d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*    targetArch = NULL;
1452d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char     temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
1462d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    p = bufprint(temp, end, "%s/config.ini", avdPath);
1472d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (p >= end) {
1482d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        APANIC("AVD path too long: %s\n", avdPath);
1492d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
1502d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    ini = iniFile_newFromFile(temp);
1512d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (ini == NULL) {
1522d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        APANIC("Could not open AVD config file: %s", temp);
1532d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
1542d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    targetArch = iniFile_getString(ini, "hw.cpu.arch", "arm");
1552d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    iniFile_free(ini);
1562d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1572d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    return targetArch;
1582d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
1592d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1602d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerchar*
1612d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerpath_getAvdTargetArch( const char* avdName )
1622d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
1632d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*  avdPath = _getAvdContentPath(avdName);
1642d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*  avdArch = _getAvdTargetArch(avdPath);
1652d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1662d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    return avdArch;
1672d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
1682d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1692d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner/* Retrieves the value of a given system property defined in a .prop
1702d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * file. This is a text file that contains definitions of the format:
1712d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * <name>=<value>
1722d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner *
1732d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * Returns NULL if property <name> is undefined or empty.
1742d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner * Returned string must be freed by the caller.
1752d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner */
1762d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerstatic char*
1772d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner_getSystemProperty( const char* propFile, const char* propName )
1782d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
1792d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    FILE*  file;
1802d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char   temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
1812d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    int    propNameLen = strlen(propName);
1822d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*  result = NULL;
1832d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1842d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    file = fopen(propFile, "rb");
1852d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (file == NULL) {
186bdd020b108b63fcfccefb2905b9d0401f739981aVladimir Chtchetkine        D("Could not open file: %s: %s", propFile, strerror(errno));
1872d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        return NULL;
1882d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
1892d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
1902d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    while (fgets(temp, sizeof temp, file) != NULL) {
1912d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        /* Trim trailing newlines, if any */
1922d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        p = memchr(temp, '\0', sizeof temp);
1932d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (p == NULL)
1942d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            p = end;
1952d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (p > temp && p[-1] == '\n') {
1962d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            *--p = '\0';
1972d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        }
1982d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (p > temp && p[-1] == '\r') {
1992d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            *--p = '\0';
2002d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        }
2012d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        /* force zero-termination in case of full-buffer */
2022d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (p == end)
2032d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            *--p = '\0';
2042d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2052d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        /* check that the line starts with the property name */
2062d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (memcmp(temp, propName, propNameLen) != 0) {
2072d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            continue;
2082d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        }
2092d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        p = temp + propNameLen;
2102d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2112d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        /* followed by an equal sign */
2122d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (p >= end || *p != '=')
2132d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            continue;
2142d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        p++;
2152d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2162d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        /* followed by something */
2172d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (p >= end || !*p)
2182d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            break;
2192d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2202d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        result = ASTRDUP(p);
2212d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        break;
2222d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
2232d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    fclose(file);
2242d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    return result;
2252d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
2262d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2272d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerstatic char*
2282d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner_getBuildProperty( const char* androidOut, const char* propName )
2292d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
2302d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
2312d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2322d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    p = bufprint(temp, end, "%s/system/build.prop", androidOut);
2332d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (p >= end) {
2342d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        D("%s: ANDROID_PRODUCT_OUT too long: %s", __FUNCTION__, androidOut);
2352d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        return NULL;
2362d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
2372d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    return _getSystemProperty(temp, propName);
2382d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
2392d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2402d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerchar*
2412d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerpath_getBuildTargetArch( const char* androidOut )
2422d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
2432d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    const char* defaultArch = "arm";
2442d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*       result = NULL;
2452d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*       cpuAbi = _getBuildProperty(androidOut, "ro.product.cpu.abi");
2462d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2472d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (cpuAbi == NULL) {
2482d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        D("Coult not find CPU ABI in build properties!");
2492d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        D("Default target architecture=%s", defaultArch);
2502d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        result = ASTRDUP(defaultArch);
2512d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    } else {
2522d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        /* Translate ABI to cpu arch if necessary */
2532d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (!strcmp("armeabi",cpuAbi))
2542d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            result = "arm";
2552d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        else if (!strcmp("armeabi-v7a", cpuAbi))
2562d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            result = "arm";
257741dc13597ac064e6a48bb2a6ec069cbc1cd0dbbBhanu Chetlapalli        else if (!strncmp("mips", cpuAbi, 4))
258741dc13597ac064e6a48bb2a6ec069cbc1cd0dbbBhanu Chetlapalli            result = "mips";
2592d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        else
2602d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            result = cpuAbi;
2612d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2622d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        D("Found target ABI=%s, architecture=%s", cpuAbi, result);
2632d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        result = ASTRDUP(result);
2642d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        AFREE(cpuAbi);
2652d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
2662d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    return result;
2672d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
2682d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2692ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turnerchar*
2702ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turnerpath_getBuildTargetAbi( const char* androidOut )
2712ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner{
2722ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    const char* defaultAbi = "armeabi";
2732ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    char*       result = NULL;
2742ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    char*       cpuAbi = _getBuildProperty(androidOut, "ro.product.cpu.abi");
2752ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
2762ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    if (cpuAbi == NULL) {
2772ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        D("Coult not find CPU ABI in build properties!");
2782ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        D("Default target ABI: %s", defaultAbi);
2792ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        result = ASTRDUP(defaultAbi);
2802ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    } else {
2812ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        D("Found target ABI=%s", cpuAbi);
2822ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        result = cpuAbi;
2832ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    }
2842ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    return result;
2852ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner}
2862ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
2872d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2882d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerint
2892d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turnerpath_getBuildTargetApiLevel( const char* androidOut )
2902d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner{
2912d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    const int  defaultLevel = 1000;
2922d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    int        level        = defaultLevel;
2932d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    char*      sdkVersion = _getBuildProperty(androidOut, "ro.build.version.sdk");
2942d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
2952d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (sdkVersion != NULL) {
2962d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        long  value;
2972d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        char* end;
2982d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        value = strtol(sdkVersion, &end, 10);
2992d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        if (end == NULL || *end != '\0' || value != (int)value) {
3002d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            D("Invalid SDK version build property: '%s'", sdkVersion);
3012d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            D("Defaulting to target API level %d", level);
3022d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        } else {
3032d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            level = (int)value;
3042d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            /* Sanity check, the Android SDK doesn't support anything
3052d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner             * before Android 1.5, a.k.a API level 3 */
3062d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            if (level < 3)
3072d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner                level = 3;
3082d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner            D("Found target API level: %d", level);
3092d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        }
3102d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        AFREE(sdkVersion);
3112d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    } else {
3122d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        D("Could not find target API level / SDK version in build properties!");
3132d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        D("Default target API level: %d", level);
3142d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
3152d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    return level;
3162d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner}
3172d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
318d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineint
319d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkinepath_getAdbdCommunicationMode( const char* androidOut )
320d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
321d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    char* prop = _getBuildProperty(androidOut, "ro.adb.qemud");
322d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    if (prop != NULL) {
323d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        long val = 0;
324d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        char* end;
325d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        val = strtol(prop, &end, 10);
326d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        if (end == NULL || *end != '\0' || val != (int)val) {
327d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            D("Invalid ro.adb.qemud build property: '%s'", prop);
328d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            val = 0;
329d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        } else {
330d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            D("Found ro.adb.qemud build property: %d", val);
331d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        }
332d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        AFREE(prop);
333d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        return (int)val;
334d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    } else {
335d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        /* Missing ro.adb.qemud means "legacy" ADBD. */
336d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        return 0;
337d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    }
338d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
339