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