info.c revision cef730bbc330b4a0ad84d12c71fdcb010ddb3772
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2008 The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful, 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/avd/info.h" 132d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#include "android/avd/util.h" 14cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll#include "android/avd/keys.h" 15353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije#include "android/config/config.h" 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/path.h" 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/bufprint.h" 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/filelock.h" 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/tempfile.h" 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h" 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/dirscanner.h" 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <ctype.h> 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stddef.h> 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h> 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h> 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h> 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* global variables - see android/globals.h */ 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfoParams android_avdParams[1]; 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfo* android_avdInfo; 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for debugging */ 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define D(...) VERBOSE_PRINT(init,__VA_ARGS__) 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DD(...) VERBOSE_PRINT(avd_config,__VA_ARGS__) 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* technical note on how all of this is supposed to work: 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Each AVD corresponds to a "content directory" that is used to 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * store persistent disk images and configuration files. Most remarkable 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * are: 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - a "config.ini" file used to hold configuration information for the 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * AVD 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - mandatory user data image ("userdata-qemu.img") and cache image 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ("cache.img") 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - optional mutable system image ("system-qemu.img"), kernel image 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ("kernel-qemu") and read-only ramdisk ("ramdisk.img") 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * When starting up an AVD, the emulator looks for relevant disk images 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the content directory. If it doesn't find a given image there, it 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * will try to search in the list of system directories listed in the 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 'config.ini' file through one of the following (key,value) pairs: 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * images.sysdir.1 = <first search path> 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * images.sysdir.2 = <second search path> 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The search paths can be absolute, or relative to the root SDK installation 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * path (which is determined from the emulator program's location, or from the 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ANDROID_SDK_ROOT environment variable). 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Individual image disk search patch can be over-riden on the command-line 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * with one of the usual options. 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6842074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner/* the name of the .ini file that will contain the complete hardware 6942074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner * properties for the AVD. This will be used to launch the corresponding 7042074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner * core from the UI. 7142074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner */ 7225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner#define CORE_HARDWARE_INI "hardware-qemu.ini" 7342074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* certain disk image files are mounted read/write by the emulator 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to ensure that several emulators referencing the same files 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * do not corrupt these files, we need to lock them and respond 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to collision depending on the image type. 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the enumeration below is used to record information about 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * each image file path. 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * READONLY means that the file will be mounted read-only 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and this doesn't need to be locked. must be first in list 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * MUSTLOCK means that the file should be locked before 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * being mounted by the emulator 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * TEMPORARY means that the file has been copied to a 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * temporary image, which can be mounted read/write 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but doesn't require locking. 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef enum { 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_READONLY, /* unlocked */ 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_MUSTLOCK, /* must be locked */ 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_LOCKED, /* locked */ 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_LOCKED_EMPTY, /* locked and empty */ 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_TEMPORARY, /* copied to temp file (no lock needed) */ 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} AvdImageState; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct AvdInfo { 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* for the Android build system case */ 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char inAndroidBuild; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* androidOut; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* androidBuildRoot; 105dd90991bb911bc61c885f710a848692b593b72c3David 'Digit' Turner char* targetArch; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* for the normal virtual device case */ 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* deviceName; 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* sdkRootPath; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char sdkRootPathFromEnv; 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* searchPaths[ MAX_SEARCH_PATHS ]; 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int numSearchPaths; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* contentPath; 11425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner IniFile* rootIni; /* root <foo>.ini file, empty if missing */ 11525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner IniFile* configIni; /* virtual device's config.ini, NULL if missing */ 11642074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner IniFile* skinHardwareIni; /* skin-specific hardware.ini */ 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* for both */ 119b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner int apiLevel; 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* skinName; /* skin name */ 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* skinDirPath; /* skin directory */ 12242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner char* coreHardwareIniPath; /* core hardware.ini path */ 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* image files */ 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* imagePath [ AVD_IMAGE_MAX ]; 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char imageState[ AVD_IMAGE_MAX ]; 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_free( AvdInfo* i ) 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i) { 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn < AVD_IMAGE_MAX; nn++) 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->imagePath[nn]); 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->skinName); 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->skinDirPath); 14142074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner AFREE(i->coreHardwareIniPath); 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn < i->numSearchPaths; nn++) 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->searchPaths[nn]); 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->numSearchPaths = 0; 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i->configIni) { 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iniFile_free(i->configIni); 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->configIni = NULL; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15342074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner if (i->skinHardwareIni) { 15442074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner iniFile_free(i->skinHardwareIni); 15542074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner i->skinHardwareIni = NULL; 156fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner } 157fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i->rootIni) { 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iniFile_free(i->rootIni); 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->rootIni = NULL; 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->contentPath); 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->sdkRootPath); 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i->inAndroidBuild) { 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->androidOut); 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->androidBuildRoot); 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->deviceName); 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i); 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* list of default file names for each supported image file type */ 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char* const _imageFileNames[ AVD_IMAGE_MAX ] = { 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define _AVD_IMG(x,y,z) y, 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AVD_IMAGE_LIST 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef _AVD_IMG 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* list of short text description for each supported image file type */ 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char* const _imageFileText[ AVD_IMAGE_MAX ] = { 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define _AVD_IMG(x,y,z) z, 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AVD_IMAGE_LIST 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef _AVD_IMG 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*************************************************************** 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *************************************************************** 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 19325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** UTILITY FUNCTIONS 19425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** 19525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** The following functions do not depend on the AvdInfo 19625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** structure and could easily be moved elsewhere. 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****/ 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Parse a given config.ini file and extract the list of SDK search paths 20125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * from it. Returns the number of valid paths stored in 'searchPaths', or -1 20225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * in case of problem. 20325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 20425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * Relative search paths in the config.ini will be stored as full pathnames 20525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * relative to 'sdkRootPath'. 20625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 20725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 'searchPaths' must be an array of char* pointers of at most 'maxSearchPaths' 20825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * entries. 20925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 21025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 21125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_getSearchPaths( IniFile* configIni, 21225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* sdkRootPath, 21325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int maxSearchPaths, 21425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char** searchPaths ) 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char temp[PATH_MAX], *p = temp, *end= p+sizeof temp; 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn, count = 0; 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner for (nn = 0; nn < maxSearchPaths; nn++) { 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* path; 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = bufprint(temp, end, "%s%d", SEARCH_PREFIX, nn+1 ); 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p >= end) 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner path = iniFile_getString(configIni, temp, NULL); 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (path != NULL) { 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DD(" found image search path: %s", path); 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!path_is_absolute(path)) { 23025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s", sdkRootPath, path); 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(path); 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project path = ASTRDUP(temp); 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner searchPaths[count++] = path; 23525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 23625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 23725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return count; 23825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 23925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 24025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Check that an AVD name is valid. Returns 1 on success, 0 otherwise. 24125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 24225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 24325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_checkAvdName( const char* name ) 24425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 24525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int len = strlen(name); 24625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int len2 = strspn(name, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 24725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner "abcdefghijklmnopqrstuvwxyz" 24825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner "0123456789_.-"); 24925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return (len == len2); 25025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 25125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 25225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Returns the full path of a given file. 25325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 25425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * If 'fileName' is an absolute path, this returns a simple copy. 25525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * Otherwise, this returns a new string corresponding to <rootPath>/<fileName> 25625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 25725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * This returns NULL if the paths are too long. 25825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 25925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 26025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_getFullFilePath( const char* rootPath, const char* fileName ) 26125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 26225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path_is_absolute(fileName)) { 26325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(fileName); 26425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } else { 26525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 26625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 26725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s", rootPath, fileName); 26825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p >= end) { 26925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 27025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 27125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(temp); 27225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 27325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 27425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 27525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* check that a given directory contains a valid skin. 27625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * returns 1 on success, 0 on failure. 27725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 27825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 27925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_checkSkinPath( const char* skinPath ) 28025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 28125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[MAX_PATH], *p=temp, *end=p+sizeof(temp); 28225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 28325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* for now, if it has a 'layout' file, it is a valid skin path */ 28425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/layout", skinPath); 28525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p >= end || !path_exists(temp)) 28625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 28725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 28825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 1; 28925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 29025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 29125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Check that there is a skin named 'skinName' listed from 'skinDirRoot' 29225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * this returns the full path of the skin directory (after alias expansions), 29325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * including the skin name, or NULL on failure. 29425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 29525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 29625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_checkSkinSkinsDir( const char* skinDirRoot, 2972d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner const char* skinName ) 29825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 29925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DirScanner* scanner; 30025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* result; 30125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); 30225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 30325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/skins/%s", skinDirRoot, skinName); 30440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner DD("Probing skin directory: %s", temp); 30525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p >= end || !path_exists(temp)) { 30625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD(" ignore bad skin directory %s", temp); 30725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 30825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 30925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 31025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* first, is this a normal skin directory ? */ 31125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (_checkSkinPath(temp)) { 31225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* yes */ 31325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD(" found skin directory: %s", temp); 31425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(temp); 31525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 31625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 31725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* second, is it an alias to another skin ? */ 31825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *p = 0; 31925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner result = NULL; 32025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner scanner = dirScanner_new(temp); 32125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (scanner != NULL) { 32225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner for (;;) { 32325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* file = dirScanner_next(scanner); 32425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 32525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (file == NULL) 32625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 32725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 32825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (strncmp(file, "alias-", 6) || file[6] == 0) 32925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner continue; 33025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 33125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/skins/%s", skinDirRoot, file+6); 33225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end && _checkSkinPath(temp)) { 33325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* yes, it's an alias */ 33425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD(" skin alias '%s' points to skin directory: %s", 33525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner file+6, temp); 33625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner result = ASTRDUP(temp); 33725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 33825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 34025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner dirScanner_free(scanner); 34125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 34225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return result; 34325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 34425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 34525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* try to see if the skin name leads to a magic skin or skin path directly 34625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * returns 1 on success, 0 on error. 34725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 34825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * on success, this sets up '*pSkinName' and '*pSkinDir' 34925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 35025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 35125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_getSkinPathFromName( const char* skinName, 35225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* sdkRootPath, 35325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char** pSkinName, 35425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char** pSkinDir ) 35525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 35625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 35725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 35825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* if the skin name has the format 'NNNNxNNN' where 35925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * NNN is a decimal value, then this is a 'magic' skin 36025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * name that doesn't require a skin directory 36125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 36225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (isdigit(skinName[0])) { 36325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int width, height; 36425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (sscanf(skinName, "%dx%d", &width, &height) == 2) { 36525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("'magic' skin format detected: %s", skinName); 36625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinName = ASTRDUP(skinName); 36725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinDir = NULL; 36825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 1; 36925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 37025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 37125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 37225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* is the skin name a direct path to the skin directory ? */ 37325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path_is_absolute(skinName) && _checkSkinPath(skinName)) { 37425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner goto FOUND_IT; 37525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 37625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 37725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* is the skin name a relative path from the SDK root ? */ 37825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s", sdkRootPath, skinName); 37925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end && _checkSkinPath(temp)) { 38025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinName = temp; 38125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner goto FOUND_IT; 38225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 38325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 38425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* nope */ 38525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 38625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 38725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' TurnerFOUND_IT: 38825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path_split(skinName, pSkinDir, pSkinName) < 0) { 38925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("malformed skin name: %s", skinName); 39025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner exit(2); 39125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 39225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("found skin '%s' in directory: %s", *pSkinName, *pSkinDir); 39325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 1; 39425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 39525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 39625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/*************************************************************** 39725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *************************************************************** 39825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** 39925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** NORMAL VIRTUAL DEVICE SUPPORT 40025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** 40125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *****/ 40225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 40325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* compute path to the root SDK directory 40425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * assume we are in $SDKROOT/tools/emulator[.exe] 40525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 40625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 40725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getSdkRoot( AvdInfo* i ) 40825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 40925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 4102d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner i->sdkRootPath = path_getSdkRoot(&i->sdkRootPathFromEnv); 41125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->sdkRootPath == NULL) 41225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 41325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 41425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 41525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 41625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 41725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* parse the root config .ini file. it is located in 41825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * ~/.android/avd/<name>.ini or Windows equivalent 41925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 42025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 42125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getRootIni( AvdInfo* i ) 42225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 4232d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner char* iniPath = path_getRootIniPath( i->deviceName ); 42425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 42525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (iniPath == NULL) { 42625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("unknown virtual device name: '%s'", i->deviceName); 42725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 42825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 42925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 43025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("Android virtual device file at: %s", iniPath); 43125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 43225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->rootIni = iniFile_newFromFile(iniPath); 43325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(iniPath); 43425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 43525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->rootIni == NULL) { 43625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("Corrupt virtual device config file!"); 43725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 43825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 43925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 44025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 44125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 44225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Returns the AVD's content path, i.e. the directory that contains 44325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * the AVD's content files (e.g. data partition, cache, sd card, etc...). 44425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 44525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * We extract this by parsing the root config .ini file, looking for 44625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * a "path" elements. 44725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 44825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 44925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getContentPath( AvdInfo* i ) 45025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 451cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 45225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 453cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll i->contentPath = iniFile_getString(i->rootIni, ROOT_ABS_PATH_KEY, NULL); 45425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 45525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->contentPath == NULL) { 45625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("bad config: %s", 457cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll "virtual device file lacks a "ROOT_ABS_PATH_KEY" entry"); 45825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 460cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll 461cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll if (!path_is_dir(i->contentPath)) { 462cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll // If the absolute path doesn't match an actual directory, try 463cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll // the relative path if present. 464cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll const char* relPath = iniFile_getString(i->rootIni, ROOT_REL_PATH_KEY, NULL); 465cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll if (relPath != NULL) { 466cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll p = bufprint_config_path(temp, end); 467cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll p = bufprint(p, end, PATH_SEP "%s", relPath); 468cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll if (p < end && path_is_dir(temp)) { 469cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll AFREE(i->contentPath); 470cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll i->contentPath = ASTRDUP(temp); 471cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll } 472cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll } 473cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll } 474cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll 47525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("virtual device content at %s", i->contentPath); 47625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 47725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 47825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 479b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turnerstatic int 480b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner_avdInfo_getApiLevel( AvdInfo* i ) 481b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner{ 482b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner char* target; 483b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner const char* p; 484b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner const int defaultLevel = 1000; 485b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner int level = defaultLevel; 486b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 487b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner# define ROOT_TARGET_KEY "target" 488b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 489b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner target = iniFile_getString(i->rootIni, ROOT_TARGET_KEY, NULL); 490b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (target == NULL) { 491b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("No target field in root AVD .ini file?"); 492b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Defaulting to API level %d", level); 493b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner return level; 494b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 495b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 496b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner DD("Found target field in root AVD .ini file: '%s'", target); 497b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 498b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* There are two acceptable formats for the target key. 499b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * 500b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * 1/ android-<level> 501b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * 2/ <vendor-name>:<add-on-name>:<level> 502b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * 503b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * Where <level> can be either a _name_ (for experimental/preview SDK builds) 504b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * or a decimal number. Note that if a _name_, it can start with a digit. 505b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner */ 506b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 507b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* First, extract the level */ 508b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (!memcmp(target, "android-", 8)) 509b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner p = target + 8; 510b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner else { 511b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* skip two columns */ 512b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner p = strchr(target, ':'); 513b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p != NULL) { 514b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner p = strchr(p+1, ':'); 515b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p != NULL) 516b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner p += 1; 517b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 518b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 519b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p == NULL || !isdigit(*p)) { 520b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner goto NOT_A_NUMBER; 521b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } else { 522b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner char* end; 523b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner long val = strtol(p, &end, 10); 524b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (end == NULL || *end != '\0' || val != (int)val) { 525b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner goto NOT_A_NUMBER; 526b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 527b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner level = (int)val; 528b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 529b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* Sanity check, we don't support anything prior to Android 1.5 */ 530b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (level < 3) 531b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner level = 3; 532b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 533b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Found AVD target API level: %d", level); 534b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 535b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' TurnerEXIT: 536b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner AFREE(target); 537b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner return level; 538b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 539b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' TurnerNOT_A_NUMBER: 540b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p == NULL) { 541b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Invalid target field in root AVD .ini file"); 542b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } else { 543b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Target AVD api level is not a number"); 544b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 545b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Defaulting to API level %d", level); 546b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner goto EXIT; 547b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner} 548b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 54925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Look for a named file inside the AVD's content directory. 55025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * Returns NULL if it doesn't exist, or a strdup() copy otherwise. 55125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 55225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 55325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getContentFilePath(AvdInfo* i, const char* fileName) 55425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 55525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 55725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(p, end, "%s/%s", i->contentPath, fileName); 55825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p >= end) { 55925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("can't access virtual device content directory"); 56025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 56125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 56225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (!path_exists(temp)) { 56325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 56425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 56525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(temp); 56625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 56725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 56825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* find and parse the config.ini file from the content directory */ 56925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 57025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getConfigIni(AvdInfo* i) 57125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 57225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* iniPath = _avdInfo_getContentFilePath(i, "config.ini"); 57325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 57425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* Allow non-existing config.ini */ 57525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (iniPath == NULL) { 57625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("virtual device has no config file - no problem"); 57725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 57825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 57925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 58025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("virtual device config file: %s", iniPath); 58125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->configIni = iniFile_newFromFile(iniPath); 58225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(iniPath); 58325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 58425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->configIni == NULL) { 58525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("bad config: %s", 58625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner "virtual device has corrupted config.ini"); 58725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 58825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 58925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 59025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 59125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 59225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* The AVD's config.ini contains a list of search paths (all beginning 59325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * with SEARCH_PREFIX) which are directory locations searched for 59425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * AVD platform files. 59525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 59625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic void 59725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getSearchPaths( AvdInfo* i ) 59825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 59925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->configIni == NULL) 60025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 60125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 60225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->numSearchPaths = _getSearchPaths( i->configIni, 60325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->sdkRootPath, 60425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner MAX_SEARCH_PATHS, 60525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->searchPaths ); 60625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->numSearchPaths == 0) { 60792c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project derror("no search paths found in this AVD's configuration.\n" 60892c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project "Weird, the AVD's config.ini file is malformed. Try re-creating it.\n"); 60992c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project exit(2); 61092c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project } 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 61225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("found a total of %d search paths for this AVD", i->numSearchPaths); 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 61525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Search a file in the SDK search directories. Return NULL if not found, 61625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * or a strdup() otherwise. 61725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 61825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 61925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getSdkFilePath(AvdInfo* i, const char* fileName) 62025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 62125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); 62225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 62325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner do { 62425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* try the search paths */ 62525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int nn; 62625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 62725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner for (nn = 0; nn < i->numSearchPaths; nn++) { 62825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* searchDir = i->searchPaths[nn]; 62925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 63025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s", searchDir, fileName); 63125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end && path_exists(temp)) { 63225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("found %s in search dir: %s", fileName, searchDir); 63325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner goto FOUND; 63425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 63525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD(" no %s in search dir: %s", fileName, searchDir); 63625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 63725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 63825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 63925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 64025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } while (0); 64125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 64225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' TurnerFOUND: 64325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(temp); 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 64625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Search for a file in the content directory, and if not found, in the 64725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * SDK search directory. Returns NULL if not found. 6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 64925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 65025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getContentOrSdkFilePath(AvdInfo* i, const char* fileName) 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 65225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* path; 6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 65425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner path = _avdInfo_getContentFilePath(i, fileName); 65525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path) 65625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return path; 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 65825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner path = _avdInfo_getSdkFilePath(i, fileName); 65925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path) 66025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return path; 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 66225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 66525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner#if 0 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 66725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_findContentOrSdkImage(AvdInfo* i, AvdImageType id) 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 66925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* fileName = _imageFileNames[id]; 67025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* path = _avdInfo_getContentOrSdkFilePath(i, fileName); 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 67225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->imagePath[id] = path; 67325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->imageState[id] = IMAGE_STATE_READONLY; 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 67525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path == NULL) 67625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 67725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner else 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 67925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 68225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Returns path to the core hardware .ini file. This contains the 68325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * hardware configuration that is read by the core. The content of this 68425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * file is auto-generated before launching a core, but we need to know 68525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * its path before that. 68625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 68725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 68825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getCoreHwIniPath( AvdInfo* i, const char* basePath ) 68925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 69025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->coreHardwareIniPath = _getFullFilePath(basePath, CORE_HARDWARE_INI); 69125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->coreHardwareIniPath == NULL) { 69225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("Path too long for %s: %s", CORE_HARDWARE_INI, basePath); 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 69525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("using core hw config path: %s", i->coreHardwareIniPath); 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfo* 7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_new( const char* name, AvdInfoParams* params ) 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AvdInfo* i; 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (name == NULL) 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!_checkAvdName(name)) { 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project derror("virtual device name contains invalid characters"); 7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project exit(1); 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ANEW0(i); 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->deviceName = ASTRDUP(name); 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 71525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if ( _avdInfo_getSdkRoot(i) < 0 || 71625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getRootIni(i) < 0 || 71725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getContentPath(i) < 0 || 71825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getConfigIni(i) < 0 || 71925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getCoreHwIniPath(i, i->contentPath) < 0 ) 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto FAIL; 7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 722b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner i->apiLevel = _avdInfo_getApiLevel(i); 723b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* look for image search paths. handle post 1.1/pre cupcake 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * obsolete SDKs. 7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 72725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getSearchPaths(i); 7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* don't need this anymore */ 7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iniFile_free(i->rootIni); 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->rootIni = NULL; 7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i; 7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFAIL: 7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project avdInfo_free(i); 7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*************************************************************** 7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *************************************************************** 7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** ANDROID BUILD SUPPORT 7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** The code below corresponds to the case where we're 7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** starting the emulator inside the Android build 7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** system. The main differences are that: 7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** - the $ANDROID_PRODUCT_OUT directory is used as the 7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** content file. 7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** - built images must not be modified by the emulator, 7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** so system.img must be copied to a temporary file 7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** and userdata.img must be copied to userdata-qemu.img 7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** if the latter doesn't exist. 7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** - the kernel and default skin directory are taken from 7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** prebuilt 7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** - there is no root .ini file, or any config.ini in 76192c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project ***** the content directory, no SDK images search path. 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****/ 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 764fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner/* Read a hardware.ini if it is located in the skin directory */ 765fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turnerstatic int 76625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getBuildSkinHardwareIni( AvdInfo* i ) 767fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner{ 76825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* skinName; 76925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* skinDirPath; 770fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 77125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner avdInfo_getSkinInfo(i, &skinName, &skinDirPath); 77225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinDirPath == NULL) 773fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner return 0; 774fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 775689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet int result = avdInfo_getSkinHardwareIni(i, skinName, skinDirPath); 776689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet 777689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet AFREE(skinName); 778689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet AFREE(skinDirPath); 779689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet 780689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet return result; 781689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet} 782689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet 783689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohetint avdInfo_getSkinHardwareIni( AvdInfo* i, char* skinName, char* skinDirPath) 784689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet{ 785689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 786689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet 78725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s/hardware.ini", skinDirPath, skinName); 788fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner if (p >= end || !path_exists(temp)) { 78925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("no skin-specific hardware.ini in %s", skinDirPath); 790fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner return 0; 791fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner } 792fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 793fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner D("found skin-specific hardware.ini: %s", temp); 794689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet if (i->skinHardwareIni != NULL) 795689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet iniFile_free(i->skinHardwareIni); 79642074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner i->skinHardwareIni = iniFile_newFromFile(temp); 79742074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner if (i->skinHardwareIni == NULL) 798fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner return -1; 799fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 800fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner return 0; 801fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner} 802fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfo* 8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_newForAndroidBuild( const char* androidBuildRoot, 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* androidOut, 8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AvdInfoParams* params ) 8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AvdInfo* i; 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ANEW0(i); 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->inAndroidBuild = 1; 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->androidBuildRoot = ASTRDUP(androidBuildRoot); 8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->androidOut = ASTRDUP(androidOut); 8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->contentPath = ASTRDUP(androidOut); 8162d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner i->targetArch = path_getBuildTargetArch(i->androidOut); 8172d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner i->apiLevel = path_getBuildTargetApiLevel(i->androidOut); 8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* TODO: find a way to provide better information from the build files */ 8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->deviceName = ASTRDUP("<build>"); 8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 82225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* There is no config.ini in the build */ 82325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->configIni = NULL; 82425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 825fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner if (_avdInfo_getCoreHwIniPath(i, i->androidOut) < 0 ) 8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto FAIL; 8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 82825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* Read the build skin's hardware.ini, if any */ 82925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getBuildSkinHardwareIni(i); 8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i; 8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFAIL: 8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project avdInfo_free(i); 8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getName( AvdInfo* i ) 8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i ? i->deviceName : NULL; 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getImageFile( AvdInfo* i, AvdImageType imageType ) 8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX) 8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i->imagePath[imageType]; 8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 853cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turneruint64_t 854cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' TurneravdInfo_getImageFileSize( AvdInfo* i, AvdImageType imageType ) 855cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner{ 856cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner const char* file = avdInfo_getImageFile(i, imageType); 857cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner uint64_t size; 858cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner 859cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner if (file == NULL) 860cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner return 0ULL; 861cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner 862cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner if (path_get_size(file, &size) < 0) 863cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner return 0ULL; 864cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner 865cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner return size; 866cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner} 867cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_isImageReadOnly( AvdInfo* i, AvdImageType imageType ) 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX) 8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (i->imageState[imageType] == IMAGE_STATE_READONLY); 8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8770b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar* 8780b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getKernelPath( AvdInfo* i ) 8790b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{ 8800b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_KERNEL ]; 8810b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 8820b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner char* kernelPath = _avdInfo_getContentOrSdkFilePath(i, imageName); 8830b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 8840b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner if (kernelPath == NULL && i->inAndroidBuild) { 8850b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner /* When in the Android build, look into the prebuilt directory 8860b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner * for our target architecture. 8870b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner */ 8880b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner char temp[PATH_MAX], *p = temp, *end = p + sizeof(temp); 8892ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner const char* suffix = ""; 8902ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner char* abi; 8912ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner 8922ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner /* If the target ABI is armeabi-v7a, then look for 8932ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner * kernel-qemu-armv7 instead of kernel-qemu in the prebuilt 8942ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner * directory. */ 8952ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner abi = path_getBuildTargetAbi(i->androidOut); 8962ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner if (!strcmp(abi,"armeabi-v7a")) { 8972ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner suffix = "-armv7"; 8982ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner } 8992ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner AFREE(abi); 9000b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 90118006f77ef9e760c225d1aa0dbbbe9cf5401aa8eJean-Baptiste Queru p = bufprint(temp, end, "%s/prebuilts/qemu-kernel/%s/kernel-qemu%s", 9022ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner i->androidBuildRoot, i->targetArch, suffix); 9030b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner if (p >= end || !path_exists(temp)) { 9040b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner derror("bad workspace: cannot find prebuilt kernel in: %s", temp); 9050b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner exit(1); 9060b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner } 9070b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner kernelPath = ASTRDUP(temp); 9080b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner } 9090b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner return kernelPath; 9100b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner} 9110b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 9120b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 9130b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar* 9140b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getRamdiskPath( AvdInfo* i ) 9150b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{ 9160b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_RAMDISK ]; 9170b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner return _avdInfo_getContentOrSdkFilePath(i, imageName); 9180b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner} 9190b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 920c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turnerchar* avdInfo_getCachePath( AvdInfo* i ) 921c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner{ 922c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_CACHE ]; 923c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 924c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner} 925c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner 926c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turnerchar* avdInfo_getDefaultCachePath( AvdInfo* i ) 927c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner{ 928c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_CACHE ]; 929c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner return _getFullFilePath(i->contentPath, imageName); 930c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner} 931c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner 93248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turnerchar* avdInfo_getSdCardPath( AvdInfo* i ) 93348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner{ 93448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_SDCARD ]; 93548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner char* path; 93648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner 93748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner /* Special case, the config.ini can have a SDCARD_PATH entry 93848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner * that gives the full path to the SD Card. 93948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner */ 94048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner if (i->configIni != NULL) { 94148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner path = iniFile_getString(i->configIni, SDCARD_PATH, NULL); 94248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner if (path != NULL) { 94348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner if (path_exists(path)) 94448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner return path; 94548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner 94648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner dwarning("Ignoring invalid SDCard path: %s", path); 94748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner AFREE(path); 94848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner } 94948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner } 95048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner 95148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner /* Otherwise, simply look into the content directory */ 95248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 95348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner} 95448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner 9550b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar* 9565f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' TurneravdInfo_getSnapStoragePath( AvdInfo* i ) 9575f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner{ 9585f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_SNAPSHOTS ]; 9595f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 9605f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner} 9615f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner 9625f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turnerchar* 96340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' TurneravdInfo_getSystemImagePath( AvdInfo* i ) 96440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner{ 96540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_USERSYSTEM ]; 96640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 96740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner} 96840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner 96940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turnerchar* 9700b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getSystemInitImagePath( AvdInfo* i ) 9710b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{ 9720b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_INITSYSTEM ]; 9730b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner return _avdInfo_getContentOrSdkFilePath(i, imageName); 9740b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner} 9750b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 9760b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar* 977fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' TurneravdInfo_getDataImagePath( AvdInfo* i ) 978fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner{ 979fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ]; 980fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 981fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner} 982fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner 983fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turnerchar* 984fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' TurneravdInfo_getDefaultDataImagePath( AvdInfo* i ) 985fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner{ 986fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ]; 987fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner return _getFullFilePath(i->contentPath, imageName); 988fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner} 989fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner 990fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turnerchar* 9910b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getDataInitImagePath( AvdInfo* i ) 9920b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{ 9930b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_INITDATA ]; 9940b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner return _avdInfo_getContentOrSdkFilePath(i, imageName); 9950b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner} 9960b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 998b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' TurneravdInfo_initHwConfig( AvdInfo* i, AndroidHwConfig* hw ) 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1000b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner int ret = 0; 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1002b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner androidHwConfig_init(hw, i->apiLevel); 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1004b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* First read the config.ini, if any */ 1005b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (i->configIni != NULL) { 1006b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner ret = androidHwConfig_read(hw, i->configIni); 1007b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1009b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* The skin's hardware.ini can override values */ 101042074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner if (ret == 0 && i->skinHardwareIni != NULL) { 101142074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner ret = androidHwConfig_read(hw, i->skinHardwareIni); 1012fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner } 1013fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 1014b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* Auto-disable keyboard emulation on sapphire platform builds */ 1015b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (i->androidOut != NULL) { 10162f7bb38681802b4cf6f83ea97fddcab469224f93David Turner char* p = strrchr(i->androidOut, '/'); 1017b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p != NULL && !strcmp(p,"sapphire")) { 1018b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner hw->hw_keyboard = 0; 10192f7bb38681802b4cf6f83ea97fddcab469224f93David Turner } 10202f7bb38681802b4cf6f83ea97fddcab469224f93David Turner } 10212f7bb38681802b4cf6f83ea97fddcab469224f93David Turner 1022b5b78438ae9ff3b90aafdab0f4f25585affc22fbLogan Chien /* Set hw.useext4=yes, if the Ext4 file system is used. */ 1023cef730bbc330b4a0ad84d12c71fdcb010ddb3772David 'Digit' Turner char* p = avdInfo_getSystemInitImagePath(i); 1024b5b78438ae9ff3b90aafdab0f4f25585affc22fbLogan Chien if (path_isExt4Image(p)) { 1025b5b78438ae9ff3b90aafdab0f4f25585affc22fbLogan Chien hw->hw_useext4 = 1; 1026b5b78438ae9ff3b90aafdab0f4f25585affc22fbLogan Chien } 1027b5b78438ae9ff3b90aafdab0f4f25585affc22fbLogan Chien AFREE(p); 1028b5b78438ae9ff3b90aafdab0f4f25585affc22fbLogan Chien 10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getContentPath( AvdInfo* i ) 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i->contentPath; 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_inAndroidBuild( AvdInfo* i ) 10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i->inAndroidBuild; 10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar* 10452ed457ee5259b236bf39701404897f4c486326e8David 'Digit' TurneravdInfo_getTargetAbi( AvdInfo* i ) 10462ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner{ 10472ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner /* For now, we can't get the ABI from SDK AVDs */ 10482ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner if (!i->inAndroidBuild) 10492ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner return NULL; 10502ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner 10512ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner return path_getBuildTargetAbi(i->androidOut); 10522ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner} 10532ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner 10542ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turnerchar* 10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getTracePath( AvdInfo* i, const char* traceName ) 10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char tmp[MAX_PATH], *p=tmp, *end=p + sizeof(tmp); 10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i == NULL || traceName == NULL || traceName[0] == 0) 10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i->inAndroidBuild) { 10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = bufprint( p, end, "%s" PATH_SEP "traces" PATH_SEP "%s", 10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->androidOut, traceName ); 10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = bufprint( p, end, "%s" PATH_SEP "traces" PATH_SEP "%s", 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->contentPath, traceName ); 10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ASTRDUP(tmp); 10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 107142074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner 107242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turnerconst char* 107342074e5e184aed78dee0efb14d7376325516c070David 'Digit' TurneravdInfo_getCoreHwIniPath( AvdInfo* i ) 107442074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner{ 107542074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner return i->coreHardwareIniPath; 107642074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner} 107725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 107825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 107925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnervoid 108025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' TurneravdInfo_getSkinInfo( AvdInfo* i, char** pSkinName, char** pSkinDir ) 108125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 108225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* skinName = NULL; 108325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* skinPath; 108425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 108525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 108625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinName = NULL; 108725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinDir = NULL; 108825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 108925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* First, see if the config.ini contains a SKIN_PATH entry that 109025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * names the full directory path for the skin. 109125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 1092689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet if (i->configIni != NULL ) { 109325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinPath = iniFile_getString( i->configIni, SKIN_PATH, NULL ); 109425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinPath != NULL) { 109525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* If this skin name is magic or a direct directory path 109625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * we have our result right here. 109725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 109825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (_getSkinPathFromName(skinPath, i->sdkRootPath, 109925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner pSkinName, pSkinDir )) { 110025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(skinPath); 110125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 110225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 110325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 110425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 110525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* The SKIN_PATH entry was not valid, so look at SKIN_NAME */ 110625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("Warning: config.ini contains invalid %s entry: %s", SKIN_PATH, skinPath); 110725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(skinPath); 110825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 110925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinName = iniFile_getString( i->configIni, SKIN_NAME, NULL ); 111025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 111125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 111225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinName == NULL) { 111325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* If there is no skin listed in the config.ini, try to see if 111425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * there is one single 'skin' directory in the content directory. 111525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 111625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/skin", i->contentPath); 111725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end && _checkSkinPath(temp)) { 111825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("using skin content from %s", temp); 111925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(i->skinName); 112025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinName = ASTRDUP("skin"); 112125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinDir = ASTRDUP(i->contentPath); 112225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 112325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 112425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 112525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* otherwise, use the default name */ 112625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinName = ASTRDUP(SKIN_DEFAULT); 112725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 112825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 112925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* now try to find the skin directory for that name - 113025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 113125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner do { 113225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* first try the content directory, i.e. $CONTENT/skins/<name> */ 113325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinPath = _checkSkinSkinsDir(i->contentPath, skinName); 113425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinPath != NULL) 113525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 113625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 113725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner#define PREBUILT_SKINS_ROOT "development/tools/emulator" 113825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 113925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* if we are in the Android build, try the prebuilt directory */ 114025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->inAndroidBuild) { 114125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint( temp, end, "%s/%s", 114225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->androidBuildRoot, PREBUILT_SKINS_ROOT ); 114325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end) { 114425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinPath = _checkSkinSkinsDir(temp, skinName); 114525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinPath != NULL) 114625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 114725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 1148adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner 1149adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner /* or in the parent directory of the system dir */ 1150adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner { 1151adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner char* parentDir = path_parent(i->androidOut, 1); 1152adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner if (parentDir != NULL) { 1153adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner skinPath = _checkSkinSkinsDir(parentDir, skinName); 1154adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner AFREE(parentDir); 1155adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner if (skinPath != NULL) 1156adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner break; 1157adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner } 1158adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner } 115925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 116025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 116125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* look in the search paths. For each <dir> in the list, 116225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * look into <dir>/../skins/<name>/ */ 116325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner { 116425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int nn; 116525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner for (nn = 0; nn < i->numSearchPaths; nn++) { 116625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* parentDir = path_parent(i->searchPaths[nn], 1); 116725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (parentDir == NULL) 116825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner continue; 116925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinPath = _checkSkinSkinsDir(parentDir, skinName); 117025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(parentDir); 117125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinPath != NULL) 117225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 117325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 117425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (nn < i->numSearchPaths) 117525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 117625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 117725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 117825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* We didn't find anything ! */ 1179adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner *pSkinName = skinName; 118025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 118125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 118225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } while (0); 118325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 118425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path_split(skinPath, pSkinDir, pSkinName) < 0) { 118525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("weird skin path: %s", skinPath); 118625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(skinPath); 118725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 118825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 118925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("found skin '%s' in directory: %s", *pSkinName, *pSkinDir); 119025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(skinPath); 119125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 119225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 119372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet 1194d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamyint 1195d899918690d5e392897e001abfb00b151ba2b13eSiva VelusamyavdInfo_shouldUseDynamicSkin( AvdInfo* i) 1196d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy{ 1197d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy if (i == NULL || i->configIni == NULL) 1198d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy return 0; 1199d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy return iniFile_getBoolean( i->configIni, SKIN_DYNAMIC, "no" ); 1200d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy} 1201d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy 120272d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohetchar* 120372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier DucrohetavdInfo_getCharmapFile( AvdInfo* i, const char* charmapName ) 120472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet{ 120572d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet char fileNameBuff[PATH_MAX]; 120672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet const char* fileName; 120772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet 120872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet if (charmapName == NULL || charmapName[0] == '\0') 120972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet return NULL; 121072d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet 121172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet if (strstr(charmapName, ".kcm") == NULL) { 121272d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet snprintf(fileNameBuff, sizeof fileNameBuff, "%s.kcm", charmapName); 121372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet fileName = fileNameBuff; 121472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet } else { 121572d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet fileName = charmapName; 121672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet } 121772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet 121872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet return _avdInfo_getContentOrSdkFilePath(i, fileName); 121972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet} 1220d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 1221d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineint avdInfo_getAdbdCommunicationMode( AvdInfo* i ) 1222d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 1223d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine return path_getAdbdCommunicationMode(i->androidOut); 1224d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 1225873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine 1226873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkineint avdInfo_getSnapshotPresent(AvdInfo* i) 1227873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine{ 1228873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine if (i->configIni == NULL) { 1229873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine return 0; 1230873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine } else { 1231873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine return iniFile_getBoolean(i->configIni, "snapshot.present", "no"); 1232873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine } 1233873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine} 1234