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" 165ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner#include "android/utils/file_data.h" 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/path.h" 185ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner#include "android/utils/property_file.h" 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/bufprint.h" 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/filelock.h" 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/tempfile.h" 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h" 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/dirscanner.h" 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <ctype.h> 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stddef.h> 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h> 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h> 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h> 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* global variables - see android/globals.h */ 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfoParams android_avdParams[1]; 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfo* android_avdInfo; 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for debugging */ 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define D(...) VERBOSE_PRINT(init,__VA_ARGS__) 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DD(...) VERBOSE_PRINT(avd_config,__VA_ARGS__) 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* technical note on how all of this is supposed to work: 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Each AVD corresponds to a "content directory" that is used to 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * store persistent disk images and configuration files. Most remarkable 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * are: 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - a "config.ini" file used to hold configuration information for the 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * AVD 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - mandatory user data image ("userdata-qemu.img") and cache image 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ("cache.img") 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - optional mutable system image ("system-qemu.img"), kernel image 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ("kernel-qemu") and read-only ramdisk ("ramdisk.img") 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * When starting up an AVD, the emulator looks for relevant disk images 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the content directory. If it doesn't find a given image there, it 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * will try to search in the list of system directories listed in the 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 'config.ini' file through one of the following (key,value) pairs: 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * images.sysdir.1 = <first search path> 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * images.sysdir.2 = <second search path> 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The search paths can be absolute, or relative to the root SDK installation 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * path (which is determined from the emulator program's location, or from the 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ANDROID_SDK_ROOT environment variable). 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Individual image disk search patch can be over-riden on the command-line 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * with one of the usual options. 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7042074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner/* the name of the .ini file that will contain the complete hardware 7142074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner * properties for the AVD. This will be used to launch the corresponding 7242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner * core from the UI. 7342074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner */ 7425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner#define CORE_HARDWARE_INI "hardware-qemu.ini" 7542074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* certain disk image files are mounted read/write by the emulator 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to ensure that several emulators referencing the same files 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * do not corrupt these files, we need to lock them and respond 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to collision depending on the image type. 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the enumeration below is used to record information about 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * each image file path. 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * READONLY means that the file will be mounted read-only 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and this doesn't need to be locked. must be first in list 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * MUSTLOCK means that the file should be locked before 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * being mounted by the emulator 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * TEMPORARY means that the file has been copied to a 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * temporary image, which can be mounted read/write 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but doesn't require locking. 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef enum { 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_READONLY, /* unlocked */ 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_MUSTLOCK, /* must be locked */ 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_LOCKED, /* locked */ 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_LOCKED_EMPTY, /* locked and empty */ 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IMAGE_STATE_TEMPORARY, /* copied to temp file (no lock needed) */ 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} AvdImageState; 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct AvdInfo { 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* for the Android build system case */ 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char inAndroidBuild; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* androidOut; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* androidBuildRoot; 107dd90991bb911bc61c885f710a848692b593b72c3David 'Digit' Turner char* targetArch; 1085ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner char* targetAbi; 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* for the normal virtual device case */ 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* deviceName; 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* sdkRootPath; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char sdkRootPathFromEnv; 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* searchPaths[ MAX_SEARCH_PATHS ]; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int numSearchPaths; 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* contentPath; 11725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner IniFile* rootIni; /* root <foo>.ini file, empty if missing */ 11825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner IniFile* configIni; /* virtual device's config.ini, NULL if missing */ 11942074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner IniFile* skinHardwareIni; /* skin-specific hardware.ini */ 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* for both */ 122b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner int apiLevel; 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* skinName; /* skin name */ 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* skinDirPath; /* skin directory */ 12542074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner char* coreHardwareIniPath; /* core hardware.ini path */ 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1275ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner FileData buildProperties[1]; /* build.prop file */ 1285ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner FileData bootProperties[1]; /* boot.prop file */ 1295ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* image files */ 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* imagePath [ AVD_IMAGE_MAX ]; 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char imageState[ AVD_IMAGE_MAX ]; 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_free( AvdInfo* i ) 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i) { 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn < AVD_IMAGE_MAX; nn++) 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->imagePath[nn]); 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->skinName); 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->skinDirPath); 14742074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner AFREE(i->coreHardwareIniPath); 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1495ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner fileData_done(i->buildProperties); 1505ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner fileData_done(i->bootProperties); 1515ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn < i->numSearchPaths; nn++) 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->searchPaths[nn]); 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->numSearchPaths = 0; 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i->configIni) { 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iniFile_free(i->configIni); 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->configIni = NULL; 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner if (i->skinHardwareIni) { 16342074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner iniFile_free(i->skinHardwareIni); 16442074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner i->skinHardwareIni = NULL; 165fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner } 166fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i->rootIni) { 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iniFile_free(i->rootIni); 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->rootIni = NULL; 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->contentPath); 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->sdkRootPath); 1745ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner AFREE(i->targetArch); 1755ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner AFREE(i->targetAbi); 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i->inAndroidBuild) { 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->androidOut); 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->androidBuildRoot); 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i->deviceName); 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(i); 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* list of default file names for each supported image file type */ 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char* const _imageFileNames[ AVD_IMAGE_MAX ] = { 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define _AVD_IMG(x,y,z) y, 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AVD_IMAGE_LIST 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef _AVD_IMG 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* list of short text description for each supported image file type */ 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char* const _imageFileText[ AVD_IMAGE_MAX ] = { 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define _AVD_IMG(x,y,z) z, 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AVD_IMAGE_LIST 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef _AVD_IMG 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*************************************************************** 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *************************************************************** 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 20425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** UTILITY FUNCTIONS 20525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** 20625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** The following functions do not depend on the AvdInfo 20725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** structure and could easily be moved elsewhere. 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****/ 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Parse a given config.ini file and extract the list of SDK search paths 21225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * from it. Returns the number of valid paths stored in 'searchPaths', or -1 21325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * in case of problem. 21425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 21525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * Relative search paths in the config.ini will be stored as full pathnames 21625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * relative to 'sdkRootPath'. 21725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 21825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 'searchPaths' must be an array of char* pointers of at most 'maxSearchPaths' 21925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * entries. 22025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 22125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 22225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_getSearchPaths( IniFile* configIni, 22325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* sdkRootPath, 22425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int maxSearchPaths, 22525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char** searchPaths ) 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char temp[PATH_MAX], *p = temp, *end= p+sizeof temp; 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn, count = 0; 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner for (nn = 0; nn < maxSearchPaths; nn++) { 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* path; 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = bufprint(temp, end, "%s%d", SEARCH_PREFIX, nn+1 ); 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p >= end) 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner path = iniFile_getString(configIni, temp, NULL); 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (path != NULL) { 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DD(" found image search path: %s", path); 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!path_is_absolute(path)) { 24125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s", sdkRootPath, path); 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(path); 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project path = ASTRDUP(temp); 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner searchPaths[count++] = path; 24625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 24725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 24825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return count; 24925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 25025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 25125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Check that an AVD name is valid. Returns 1 on success, 0 otherwise. 25225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 25325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 25425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_checkAvdName( const char* name ) 25525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 25625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int len = strlen(name); 25725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int len2 = strspn(name, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 25825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner "abcdefghijklmnopqrstuvwxyz" 25925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner "0123456789_.-"); 26025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return (len == len2); 26125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 26225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 26325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Returns the full path of a given file. 26425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 26525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * If 'fileName' is an absolute path, this returns a simple copy. 26625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * Otherwise, this returns a new string corresponding to <rootPath>/<fileName> 26725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 26825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * This returns NULL if the paths are too long. 26925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 27025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 27125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_getFullFilePath( const char* rootPath, const char* fileName ) 27225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 27325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path_is_absolute(fileName)) { 27425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(fileName); 27525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } else { 27625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 27725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 27825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s", rootPath, fileName); 27925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p >= end) { 28025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 28125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 28225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(temp); 28325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 28425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 28525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 28625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* check that a given directory contains a valid skin. 28725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * returns 1 on success, 0 on failure. 28825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 28925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 29025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_checkSkinPath( const char* skinPath ) 29125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 29225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[MAX_PATH], *p=temp, *end=p+sizeof(temp); 29325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 29425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* for now, if it has a 'layout' file, it is a valid skin path */ 29525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/layout", skinPath); 29625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p >= end || !path_exists(temp)) 29725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 29825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 29925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 1; 30025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 30125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 30225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Check that there is a skin named 'skinName' listed from 'skinDirRoot' 30325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * this returns the full path of the skin directory (after alias expansions), 30425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * including the skin name, or NULL on failure. 30525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 30625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 30725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_checkSkinSkinsDir( const char* skinDirRoot, 3082d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner const char* skinName ) 30925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 31025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DirScanner* scanner; 31125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* result; 31225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); 31325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 31425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/skins/%s", skinDirRoot, skinName); 31540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner DD("Probing skin directory: %s", temp); 31625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p >= end || !path_exists(temp)) { 31725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD(" ignore bad skin directory %s", temp); 31825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 31925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 32025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 32125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* first, is this a normal skin directory ? */ 32225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (_checkSkinPath(temp)) { 32325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* yes */ 32425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD(" found skin directory: %s", temp); 32525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(temp); 32625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 32725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 32825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* second, is it an alias to another skin ? */ 32925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *p = 0; 33025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner result = NULL; 33125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner scanner = dirScanner_new(temp); 33225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (scanner != NULL) { 33325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner for (;;) { 33425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* file = dirScanner_next(scanner); 33525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 33625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (file == NULL) 33725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 33825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 33925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (strncmp(file, "alias-", 6) || file[6] == 0) 34025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner continue; 34125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 34225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/skins/%s", skinDirRoot, file+6); 34325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end && _checkSkinPath(temp)) { 34425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* yes, it's an alias */ 34525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD(" skin alias '%s' points to skin directory: %s", 34625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner file+6, temp); 34725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner result = ASTRDUP(temp); 34825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 34925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 35125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner dirScanner_free(scanner); 35225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 35325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return result; 35425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 35525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 35625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* try to see if the skin name leads to a magic skin or skin path directly 35725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * returns 1 on success, 0 on error. 35825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 35925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * on success, this sets up '*pSkinName' and '*pSkinDir' 36025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 36125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 36225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_getSkinPathFromName( const char* skinName, 36325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* sdkRootPath, 36425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char** pSkinName, 36525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char** pSkinDir ) 36625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 36725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 36825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 36925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* if the skin name has the format 'NNNNxNNN' where 37025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * NNN is a decimal value, then this is a 'magic' skin 37125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * name that doesn't require a skin directory 37225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 37325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (isdigit(skinName[0])) { 37425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int width, height; 37525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (sscanf(skinName, "%dx%d", &width, &height) == 2) { 37625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("'magic' skin format detected: %s", skinName); 37725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinName = ASTRDUP(skinName); 37825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinDir = NULL; 37925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 1; 38025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 38125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 38225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 38325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* is the skin name a direct path to the skin directory ? */ 38425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path_is_absolute(skinName) && _checkSkinPath(skinName)) { 38525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner goto FOUND_IT; 38625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 38725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 38825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* is the skin name a relative path from the SDK root ? */ 38925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s", sdkRootPath, skinName); 39025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end && _checkSkinPath(temp)) { 39125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinName = temp; 39225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner goto FOUND_IT; 39325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 39425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 39525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* nope */ 39625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 39725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 39825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' TurnerFOUND_IT: 39925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path_split(skinName, pSkinDir, pSkinName) < 0) { 40025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("malformed skin name: %s", skinName); 40125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner exit(2); 40225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 40325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("found skin '%s' in directory: %s", *pSkinName, *pSkinDir); 40425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 1; 40525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 40625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 40725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/*************************************************************** 40825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *************************************************************** 40925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** 41025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** NORMAL VIRTUAL DEVICE SUPPORT 41125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner ***** 41225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *****/ 41325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 41425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* compute path to the root SDK directory 41525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * assume we are in $SDKROOT/tools/emulator[.exe] 41625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 41725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 41825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getSdkRoot( AvdInfo* i ) 41925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 42025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 4212d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner i->sdkRootPath = path_getSdkRoot(&i->sdkRootPathFromEnv); 42225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->sdkRootPath == NULL) 42325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 42425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 42525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 42625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 42725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 42825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* parse the root config .ini file. it is located in 42925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * ~/.android/avd/<name>.ini or Windows equivalent 43025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 43125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 43225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getRootIni( AvdInfo* i ) 43325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 4342d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner char* iniPath = path_getRootIniPath( i->deviceName ); 43525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 43625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (iniPath == NULL) { 43725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("unknown virtual device name: '%s'", i->deviceName); 43825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 43925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 44025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 44125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("Android virtual device file at: %s", iniPath); 44225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 44325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->rootIni = iniFile_newFromFile(iniPath); 44425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(iniPath); 44525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 44625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->rootIni == NULL) { 44725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("Corrupt virtual device config file!"); 44825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 44925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 45025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 45125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 45225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 45325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Returns the AVD's content path, i.e. the directory that contains 45425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * the AVD's content files (e.g. data partition, cache, sd card, etc...). 45525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * 45625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * We extract this by parsing the root config .ini file, looking for 45725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * a "path" elements. 45825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 45925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 46025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getContentPath( AvdInfo* i ) 46125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 462cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 46325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 464cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll i->contentPath = iniFile_getString(i->rootIni, ROOT_ABS_PATH_KEY, NULL); 46525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 46625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->contentPath == NULL) { 46725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("bad config: %s", 468cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll "virtual device file lacks a "ROOT_ABS_PATH_KEY" entry"); 46925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 471cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll 472cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll if (!path_is_dir(i->contentPath)) { 473cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll // If the absolute path doesn't match an actual directory, try 474cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll // the relative path if present. 475cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll const char* relPath = iniFile_getString(i->rootIni, ROOT_REL_PATH_KEY, NULL); 476cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll if (relPath != NULL) { 477cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll p = bufprint_config_path(temp, end); 478cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll p = bufprint(p, end, PATH_SEP "%s", relPath); 479cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll if (p < end && path_is_dir(temp)) { 480cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll AFREE(i->contentPath); 481cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll i->contentPath = ASTRDUP(temp); 482cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll } 483cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll } 484cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll } 485cf9426292dc19d91bcf11f72d30613f83dbc3d6cRaphael Moll 48625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("virtual device content at %s", i->contentPath); 48725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 48825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 48925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 490fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turnerstatic int 491fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner_avdInfo_getApiLevel( AvdInfo* i ) 492b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner{ 493b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner char* target; 494b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner const char* p; 495b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner const int defaultLevel = 1000; 496b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner int level = defaultLevel; 497b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 498b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner# define ROOT_TARGET_KEY "target" 499b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 500b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner target = iniFile_getString(i->rootIni, ROOT_TARGET_KEY, NULL); 501b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (target == NULL) { 502b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("No target field in root AVD .ini file?"); 503b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Defaulting to API level %d", level); 504b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner return level; 505b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 506b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 507b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner DD("Found target field in root AVD .ini file: '%s'", target); 508b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 509b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* There are two acceptable formats for the target key. 510b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * 511b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * 1/ android-<level> 512b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * 2/ <vendor-name>:<add-on-name>:<level> 513b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * 514b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * Where <level> can be either a _name_ (for experimental/preview SDK builds) 515b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner * or a decimal number. Note that if a _name_, it can start with a digit. 516b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner */ 517b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 518b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* First, extract the level */ 519b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (!memcmp(target, "android-", 8)) 520b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner p = target + 8; 521b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner else { 522b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* skip two columns */ 523b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner p = strchr(target, ':'); 524b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p != NULL) { 525b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner p = strchr(p+1, ':'); 526b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p != NULL) 527b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner p += 1; 528b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 529b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 530b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p == NULL || !isdigit(*p)) { 531b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner goto NOT_A_NUMBER; 532b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } else { 533b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner char* end; 534b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner long val = strtol(p, &end, 10); 535b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (end == NULL || *end != '\0' || val != (int)val) { 536b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner goto NOT_A_NUMBER; 537b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 538b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner level = (int)val; 539b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 540b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* Sanity check, we don't support anything prior to Android 1.5 */ 541b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (level < 3) 542b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner level = 3; 543b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 544b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Found AVD target API level: %d", level); 545b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 546b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' TurnerEXIT: 547b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner AFREE(target); 548b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner return level; 549b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 550b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' TurnerNOT_A_NUMBER: 551b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p == NULL) { 552b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Invalid target field in root AVD .ini file"); 553b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } else { 554b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Target AVD api level is not a number"); 555b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 556b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner D("Defaulting to API level %d", level); 557b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner goto EXIT; 558b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner} 559b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 560fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner 561fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turnerint 562fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' TurneravdInfo_getApiLevel(AvdInfo* i) { 563fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner return i->apiLevel; 564fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner} 565fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner 56625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Look for a named file inside the AVD's content directory. 56725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * Returns NULL if it doesn't exist, or a strdup() copy otherwise. 56825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 56925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 57025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getContentFilePath(AvdInfo* i, const char* fileName) 57125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 57225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 57425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(p, end, "%s/%s", i->contentPath, fileName); 57525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p >= end) { 57625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("can't access virtual device content directory"); 57725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 57825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 57925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (!path_exists(temp)) { 58025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 58125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 58225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(temp); 58325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 58425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 58525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* find and parse the config.ini file from the content directory */ 58625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 58725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getConfigIni(AvdInfo* i) 58825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 58925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* iniPath = _avdInfo_getContentFilePath(i, "config.ini"); 59025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 59125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* Allow non-existing config.ini */ 59225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (iniPath == NULL) { 59325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("virtual device has no config file - no problem"); 59425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 59525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 59625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 59725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("virtual device config file: %s", iniPath); 59825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->configIni = iniFile_newFromFile(iniPath); 59925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(iniPath); 60025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 60125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->configIni == NULL) { 60225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("bad config: %s", 60325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner "virtual device has corrupted config.ini"); 60425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 60525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 60625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return 0; 60725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 60825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 60925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* The AVD's config.ini contains a list of search paths (all beginning 61025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * with SEARCH_PREFIX) which are directory locations searched for 61125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * AVD platform files. 61225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 61325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic void 61425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getSearchPaths( AvdInfo* i ) 61525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 61625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->configIni == NULL) 61725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 61825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 61925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->numSearchPaths = _getSearchPaths( i->configIni, 62025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->sdkRootPath, 62125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner MAX_SEARCH_PATHS, 62225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->searchPaths ); 62325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->numSearchPaths == 0) { 62492c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project derror("no search paths found in this AVD's configuration.\n" 62592c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project "Weird, the AVD's config.ini file is malformed. Try re-creating it.\n"); 62692c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project exit(2); 62792c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project } 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 62925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("found a total of %d search paths for this AVD", i->numSearchPaths); 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 63225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Search a file in the SDK search directories. Return NULL if not found, 63325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * or a strdup() otherwise. 63425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 63525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 63625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getSdkFilePath(AvdInfo* i, const char* fileName) 63725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 63825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); 63925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 64025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner do { 64125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* try the search paths */ 64225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int nn; 64325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 64425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner for (nn = 0; nn < i->numSearchPaths; nn++) { 64525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* searchDir = i->searchPaths[nn]; 64625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 64725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s", searchDir, fileName); 64825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end && path_exists(temp)) { 64925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("found %s in search dir: %s", fileName, searchDir); 65025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner goto FOUND; 65125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 65225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD(" no %s in search dir: %s", fileName, searchDir); 65325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 65425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 65525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 65625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 65725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } while (0); 65825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 65925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' TurnerFOUND: 66025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return ASTRDUP(temp); 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 66325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Search for a file in the content directory, and if not found, in the 66425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * SDK search directory. Returns NULL if not found. 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 66625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char* 66725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getContentOrSdkFilePath(AvdInfo* i, const char* fileName) 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 66925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* path; 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 67125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner path = _avdInfo_getContentFilePath(i, fileName); 67225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path) 67325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return path; 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 67525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner path = _avdInfo_getSdkFilePath(i, fileName); 67625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path) 67725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return path; 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 67925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return NULL; 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 68225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner#if 0 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 68425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_findContentOrSdkImage(AvdInfo* i, AvdImageType id) 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 68625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner const char* fileName = _imageFileNames[id]; 68725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* path = _avdInfo_getContentOrSdkFilePath(i, fileName); 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 68925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->imagePath[id] = path; 69025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->imageState[id] = IMAGE_STATE_READONLY; 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 69225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path == NULL) 69325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return -1; 69425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner else 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 69625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 69925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Returns path to the core hardware .ini file. This contains the 70025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * hardware configuration that is read by the core. The content of this 70125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * file is auto-generated before launching a core, but we need to know 70225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * its path before that. 70325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 70425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int 70525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getCoreHwIniPath( AvdInfo* i, const char* basePath ) 70625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 70725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->coreHardwareIniPath = _getFullFilePath(basePath, CORE_HARDWARE_INI); 70825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->coreHardwareIniPath == NULL) { 70925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("Path too long for %s: %s", CORE_HARDWARE_INI, basePath); 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 71225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("using core hw config path: %s", i->coreHardwareIniPath); 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7165ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 7175ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turnerstatic void 7185ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner_avdInfo_readPropertyFile(AvdInfo* i, 7195ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner const char* filePath, 7205ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner FileData* data) { 7215ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner int ret = fileData_initFromFile(data, filePath); 7225ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner if (ret < 0) { 7235ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner D("Error reading property file %s: %s", filePath, strerror(-ret)); 7245ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner } else { 7255ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner D("Read property file at %s", filePath); 7265ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner } 7275ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner} 7285ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 7295ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 7305ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turnerstatic void 7315ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner_avdInfo_extractBuildProperties(AvdInfo* i) { 7325ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner i->targetArch = propertyFile_getTargetArch(i->buildProperties); 7335ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner if (!i->targetArch) { 7345ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner i->targetArch = ASTRDUP("arm"); 7355ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner D("Cannot find target CPU architecture, defaulting to '%s'", 7365ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner i->targetArch); 7375ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner } 7385ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner i->targetAbi = propertyFile_getTargetAbi(i->buildProperties); 7395ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner if (!i->targetAbi) { 7405ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner i->targetAbi = ASTRDUP("armeabi"); 7415ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner D("Cannot find target CPU ABI, defaulting to '%s'", 7425ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner i->targetAbi); 7435ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner } 744fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner if (!i->apiLevel) { 745fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner // Note: for regular AVDs, the API level is already extracted 746fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner // from config.ini, besides, for older SDK platform images, 747fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner // there is no build.prop file and the following function 748fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner // would always return 1000, making the AVD unbootable!. 749fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner i->apiLevel = propertyFile_getApiLevel(i->buildProperties); 750fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner if (i->apiLevel < 3) { 751fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner i->apiLevel = 3; 752fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner D("Cannot find target API level, defaulting to %d", 753fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner i->apiLevel); 754fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner } 7555ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner } 7565ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner} 7575ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 7585ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 7595ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turnerstatic void 7605ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner_avdInfo_getPropertyFile(AvdInfo* i, 7615ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner const char* propFileName, 7625ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner FileData* data ) { 7635ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner char* filePath = _avdInfo_getContentOrSdkFilePath(i, propFileName); 7645ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner if (!filePath) { 7655ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner D("No %s property file found.", propFileName); 7665ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner return; 7675ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner } 7685ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 7695ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner _avdInfo_readPropertyFile(i, filePath, data); 7705ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner free(filePath); 7715ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner} 7725ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfo* 7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_new( const char* name, AvdInfoParams* params ) 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AvdInfo* i; 7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (name == NULL) 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!_checkAvdName(name)) { 7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project derror("virtual device name contains invalid characters"); 7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project exit(1); 7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ANEW0(i); 7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->deviceName = ASTRDUP(name); 7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 78925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if ( _avdInfo_getSdkRoot(i) < 0 || 79025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getRootIni(i) < 0 || 79125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getContentPath(i) < 0 || 79225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getConfigIni(i) < 0 || 79325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getCoreHwIniPath(i, i->contentPath) < 0 ) 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto FAIL; 7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 796fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner i->apiLevel = _avdInfo_getApiLevel(i); 797b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* look for image search paths. handle post 1.1/pre cupcake 7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * obsolete SDKs. 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 80125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getSearchPaths(i); 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8035ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner // Find the build.prop and boot.prop files and read them. 8045ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner _avdInfo_getPropertyFile(i, "build.prop", i->buildProperties); 8055ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner _avdInfo_getPropertyFile(i, "boot.prop", i->bootProperties); 8065ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 8077666d5ff750aa2da0e23f05fee360d6ed2cdd826David 'Digit' Turner _avdInfo_extractBuildProperties(i); 8087666d5ff750aa2da0e23f05fee360d6ed2cdd826David 'Digit' Turner 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* don't need this anymore */ 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iniFile_free(i->rootIni); 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->rootIni = NULL; 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i; 8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFAIL: 8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project avdInfo_free(i); 8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*************************************************************** 8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *************************************************************** 8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** ANDROID BUILD SUPPORT 8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** The code below corresponds to the case where we're 8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** starting the emulator inside the Android build 8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** system. The main differences are that: 8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** - the $ANDROID_PRODUCT_OUT directory is used as the 8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** content file. 8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** - built images must not be modified by the emulator, 8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** so system.img must be copied to a temporary file 8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** and userdata.img must be copied to userdata-qemu.img 8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** if the latter doesn't exist. 8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** - the kernel and default skin directory are taken from 8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** prebuilt 8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** 8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***** - there is no root .ini file, or any config.ini in 84192c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project ***** the content directory, no SDK images search path. 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****/ 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 844fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner/* Read a hardware.ini if it is located in the skin directory */ 845fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turnerstatic int 84625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getBuildSkinHardwareIni( AvdInfo* i ) 847fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner{ 84825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* skinName; 84925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* skinDirPath; 850fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 85125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner avdInfo_getSkinInfo(i, &skinName, &skinDirPath); 85225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinDirPath == NULL) 853fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner return 0; 854fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 855689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet int result = avdInfo_getSkinHardwareIni(i, skinName, skinDirPath); 856689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet 857689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet AFREE(skinName); 858689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet AFREE(skinDirPath); 859689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet 860689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet return result; 861689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet} 862689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet 863689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohetint avdInfo_getSkinHardwareIni( AvdInfo* i, char* skinName, char* skinDirPath) 864689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet{ 865689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 866689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet 86725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/%s/hardware.ini", skinDirPath, skinName); 868fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner if (p >= end || !path_exists(temp)) { 86925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("no skin-specific hardware.ini in %s", skinDirPath); 870fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner return 0; 871fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner } 872fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 873fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner D("found skin-specific hardware.ini: %s", temp); 874689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet if (i->skinHardwareIni != NULL) 875689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet iniFile_free(i->skinHardwareIni); 87642074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner i->skinHardwareIni = iniFile_newFromFile(temp); 87742074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner if (i->skinHardwareIni == NULL) 878fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner return -1; 879fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 880fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner return 0; 881fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner} 882fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfo* 8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_newForAndroidBuild( const char* androidBuildRoot, 8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* androidOut, 8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AvdInfoParams* params ) 8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AvdInfo* i; 8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ANEW0(i); 8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->inAndroidBuild = 1; 8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->androidBuildRoot = ASTRDUP(androidBuildRoot); 8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->androidOut = ASTRDUP(androidOut); 8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->contentPath = ASTRDUP(androidOut); 8965ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 8975ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner // Find the build.prop file and read it. 8985ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner char* buildPropPath = path_getBuildBuildProp(i->androidOut); 8995ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner if (buildPropPath) { 9005ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner _avdInfo_readPropertyFile(i, buildPropPath, i->buildProperties); 9015ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner free(buildPropPath); 9025ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner } 9035ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 9045ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner // FInd the boot.prop file and read it. 9055ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner char* bootPropPath = path_getBuildBootProp(i->androidOut); 9065ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner if (bootPropPath) { 9075ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner _avdInfo_readPropertyFile(i, bootPropPath, i->bootProperties); 9085ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner free(bootPropPath); 9095ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner } 910c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 9115ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner _avdInfo_extractBuildProperties(i); 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->deviceName = ASTRDUP("<build>"); 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 915874512319361370762ddbe02039077ad5ea377b6Ji-Hwan Lee /* out/target/product/<name>/config.ini, if exists, provide configuration 916874512319361370762ddbe02039077ad5ea377b6Ji-Hwan Lee * from build files. */ 917874512319361370762ddbe02039077ad5ea377b6Ji-Hwan Lee if (_avdInfo_getConfigIni(i) < 0 || 918874512319361370762ddbe02039077ad5ea377b6Ji-Hwan Lee _avdInfo_getCoreHwIniPath(i, i->androidOut) < 0) 9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto FAIL; 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 92125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* Read the build skin's hardware.ini, if any */ 92225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner _avdInfo_getBuildSkinHardwareIni(i); 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i; 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFAIL: 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project avdInfo_free(i); 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getName( AvdInfo* i ) 9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i ? i->deviceName : NULL; 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getImageFile( AvdInfo* i, AvdImageType imageType ) 9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX) 9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i->imagePath[imageType]; 9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 946cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turneruint64_t 947cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' TurneravdInfo_getImageFileSize( AvdInfo* i, AvdImageType imageType ) 948cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner{ 949cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner const char* file = avdInfo_getImageFile(i, imageType); 950cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner uint64_t size; 951cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner 952cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner if (file == NULL) 953cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner return 0ULL; 954cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner 955cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner if (path_get_size(file, &size) < 0) 956cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner return 0ULL; 957cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner 958cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner return size; 959cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner} 960cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner 9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_isImageReadOnly( AvdInfo* i, AvdImageType imageType ) 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX) 9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (i->imageState[imageType] == IMAGE_STATE_READONLY); 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9700b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar* 9710b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getKernelPath( AvdInfo* i ) 9720b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{ 9730b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_KERNEL ]; 9740b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 9750b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner char* kernelPath = _avdInfo_getContentOrSdkFilePath(i, imageName); 9760b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 9775ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner do { 9785ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner if (kernelPath || !i->inAndroidBuild) 9795ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner break; 9805ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 9810b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner /* When in the Android build, look into the prebuilt directory 9820b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner * for our target architecture. 9830b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner */ 9840b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner char temp[PATH_MAX], *p = temp, *end = p + sizeof(temp); 9852ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner const char* suffix = ""; 9862ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner 9875ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner // If the target ABI is armeabi-v7a, then look for 9885ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner // kernel-qemu-armv7 instead of kernel-qemu in the prebuilt 9895ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner // directory. 9905ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner if (!strcmp(i->targetAbi, "armeabi-v7a")) { 9912ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner suffix = "-armv7"; 9922ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner } 9930b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 994c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner p = bufprint(temp, end, "%s/kernel", i->androidOut); 995c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner if (p < end && path_exists(temp)) { 996c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner kernelPath = ASTRDUP(temp); 997c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner break; 998c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner } 999c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner 100018006f77ef9e760c225d1aa0dbbbe9cf5401aa8eJean-Baptiste Queru p = bufprint(temp, end, "%s/prebuilts/qemu-kernel/%s/kernel-qemu%s", 10012ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner i->androidBuildRoot, i->targetArch, suffix); 10020b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner if (p >= end || !path_exists(temp)) { 10030b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner derror("bad workspace: cannot find prebuilt kernel in: %s", temp); 10040b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner exit(1); 10050b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner } 10060b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner kernelPath = ASTRDUP(temp); 10075ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 10085ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner } while (0); 10095ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 10100b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner return kernelPath; 10110b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner} 10120b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 10130b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 10140b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar* 10150b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getRamdiskPath( AvdInfo* i ) 10160b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{ 10170b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_RAMDISK ]; 10180b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner return _avdInfo_getContentOrSdkFilePath(i, imageName); 10190b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner} 10200b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 1021c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turnerchar* avdInfo_getCachePath( AvdInfo* i ) 1022c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner{ 1023c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_CACHE ]; 1024c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 1025c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner} 1026c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner 1027c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turnerchar* avdInfo_getDefaultCachePath( AvdInfo* i ) 1028c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner{ 1029c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_CACHE ]; 1030c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner return _getFullFilePath(i->contentPath, imageName); 1031c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner} 1032c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner 103348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turnerchar* avdInfo_getSdCardPath( AvdInfo* i ) 103448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner{ 103548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_SDCARD ]; 103648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner char* path; 103748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner 103848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner /* Special case, the config.ini can have a SDCARD_PATH entry 103948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner * that gives the full path to the SD Card. 104048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner */ 104148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner if (i->configIni != NULL) { 104248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner path = iniFile_getString(i->configIni, SDCARD_PATH, NULL); 104348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner if (path != NULL) { 104448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner if (path_exists(path)) 104548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner return path; 104648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner 104748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner dwarning("Ignoring invalid SDCard path: %s", path); 104848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner AFREE(path); 104948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner } 105048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner } 105148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner 105248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner /* Otherwise, simply look into the content directory */ 105348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 105448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner} 105548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner 10560b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar* 10575f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' TurneravdInfo_getSnapStoragePath( AvdInfo* i ) 10585f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner{ 10595f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_SNAPSHOTS ]; 10605f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 10615f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner} 10625f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner 10635f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turnerchar* 106440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' TurneravdInfo_getSystemImagePath( AvdInfo* i ) 106540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner{ 106640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_USERSYSTEM ]; 106740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 106840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner} 106940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner 107040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turnerchar* 10710b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getSystemInitImagePath( AvdInfo* i ) 10720b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{ 10730b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_INITSYSTEM ]; 10740b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner return _avdInfo_getContentOrSdkFilePath(i, imageName); 10750b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner} 10760b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 10770b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar* 1078fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' TurneravdInfo_getDataImagePath( AvdInfo* i ) 1079fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner{ 1080fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ]; 1081fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner return _avdInfo_getContentFilePath(i, imageName); 1082fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner} 1083fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner 1084fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turnerchar* 1085fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' TurneravdInfo_getDefaultDataImagePath( AvdInfo* i ) 1086fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner{ 1087fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ]; 1088fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner return _getFullFilePath(i->contentPath, imageName); 1089fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner} 1090fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner 1091fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turnerchar* 10920b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getDataInitImagePath( AvdInfo* i ) 10930b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{ 10940b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner const char* imageName = _imageFileNames[ AVD_IMAGE_INITDATA ]; 10950b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner return _avdInfo_getContentOrSdkFilePath(i, imageName); 10960b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner} 10970b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner 10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 1099b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' TurneravdInfo_initHwConfig( AvdInfo* i, AndroidHwConfig* hw ) 11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1101b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner int ret = 0; 11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1103b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner androidHwConfig_init(hw, i->apiLevel); 11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1105b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* First read the config.ini, if any */ 1106b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (i->configIni != NULL) { 1107b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner ret = androidHwConfig_read(hw, i->configIni); 1108b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner } 11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1110b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* The skin's hardware.ini can override values */ 111142074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner if (ret == 0 && i->skinHardwareIni != NULL) { 111242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner ret = androidHwConfig_read(hw, i->skinHardwareIni); 1113fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner } 1114fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner 1115b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner /* Auto-disable keyboard emulation on sapphire platform builds */ 1116b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (i->androidOut != NULL) { 11172f7bb38681802b4cf6f83ea97fddcab469224f93David Turner char* p = strrchr(i->androidOut, '/'); 1118b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner if (p != NULL && !strcmp(p,"sapphire")) { 1119b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner hw->hw_keyboard = 0; 11202f7bb38681802b4cf6f83ea97fddcab469224f93David Turner } 11212f7bb38681802b4cf6f83ea97fddcab469224f93David Turner } 11222f7bb38681802b4cf6f83ea97fddcab469224f93David Turner 11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getContentPath( AvdInfo* i ) 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i->contentPath; 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_inAndroidBuild( AvdInfo* i ) 11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return i->inAndroidBuild; 11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar* 11397666d5ff750aa2da0e23f05fee360d6ed2cdd826David 'Digit' TurneravdInfo_getTargetCpuArch(AvdInfo* i) { 11407666d5ff750aa2da0e23f05fee360d6ed2cdd826David 'Digit' Turner return ASTRDUP(i->targetArch); 11417666d5ff750aa2da0e23f05fee360d6ed2cdd826David 'Digit' Turner} 11427666d5ff750aa2da0e23f05fee360d6ed2cdd826David 'Digit' Turner 11437666d5ff750aa2da0e23f05fee360d6ed2cdd826David 'Digit' Turnerchar* 11442ed457ee5259b236bf39701404897f4c486326e8David 'Digit' TurneravdInfo_getTargetAbi( AvdInfo* i ) 11452ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner{ 11462ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner /* For now, we can't get the ABI from SDK AVDs */ 11475ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner return ASTRDUP(i->targetAbi); 11482ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner} 11492ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner 11502ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turnerchar* 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getTracePath( AvdInfo* i, const char* traceName ) 11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char tmp[MAX_PATH], *p=tmp, *end=p + sizeof(tmp); 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i == NULL || traceName == NULL || traceName[0] == 0) 11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (i->inAndroidBuild) { 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = bufprint( p, end, "%s" PATH_SEP "traces" PATH_SEP "%s", 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->androidOut, traceName ); 11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = bufprint( p, end, "%s" PATH_SEP "traces" PATH_SEP "%s", 11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i->contentPath, traceName ); 11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ASTRDUP(tmp); 11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 116742074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner 116842074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turnerconst char* 116942074e5e184aed78dee0efb14d7376325516c070David 'Digit' TurneravdInfo_getCoreHwIniPath( AvdInfo* i ) 117042074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner{ 117142074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner return i->coreHardwareIniPath; 117242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner} 117325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 117425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 117525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnervoid 117625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' TurneravdInfo_getSkinInfo( AvdInfo* i, char** pSkinName, char** pSkinDir ) 117725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{ 117825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* skinName = NULL; 117925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* skinPath; 118025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); 118125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 118225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinName = NULL; 118325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinDir = NULL; 118425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 118525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* First, see if the config.ini contains a SKIN_PATH entry that 118625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * names the full directory path for the skin. 118725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 1188689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet if (i->configIni != NULL ) { 118925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinPath = iniFile_getString( i->configIni, SKIN_PATH, NULL ); 119025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinPath != NULL) { 119125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* If this skin name is magic or a direct directory path 119225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * we have our result right here. 119325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 119425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (_getSkinPathFromName(skinPath, i->sdkRootPath, 119525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner pSkinName, pSkinDir )) { 119625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(skinPath); 119725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 119825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 119925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 120025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 120125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* The SKIN_PATH entry was not valid, so look at SKIN_NAME */ 120225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("Warning: config.ini contains invalid %s entry: %s", SKIN_PATH, skinPath); 120325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(skinPath); 120425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 120525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinName = iniFile_getString( i->configIni, SKIN_NAME, NULL ); 120625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 120725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 120825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinName == NULL) { 120925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* If there is no skin listed in the config.ini, try to see if 121025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * there is one single 'skin' directory in the content directory. 121125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 121225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint(temp, end, "%s/skin", i->contentPath); 121325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end && _checkSkinPath(temp)) { 121425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner D("using skin content from %s", temp); 121525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(i->skinName); 121625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinName = ASTRDUP("skin"); 121725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner *pSkinDir = ASTRDUP(i->contentPath); 121825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 121925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 122025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 122125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* otherwise, use the default name */ 122225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinName = ASTRDUP(SKIN_DEFAULT); 122325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 122425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 122525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* now try to find the skin directory for that name - 122625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */ 122725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner do { 122825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* first try the content directory, i.e. $CONTENT/skins/<name> */ 122925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinPath = _checkSkinSkinsDir(i->contentPath, skinName); 123025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinPath != NULL) 123125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 123225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 123325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner#define PREBUILT_SKINS_ROOT "development/tools/emulator" 123425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 123525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* if we are in the Android build, try the prebuilt directory */ 123625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (i->inAndroidBuild) { 123725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner p = bufprint( temp, end, "%s/%s", 123825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner i->androidBuildRoot, PREBUILT_SKINS_ROOT ); 123925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (p < end) { 124025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinPath = _checkSkinSkinsDir(temp, skinName); 124125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinPath != NULL) 124225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 124325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 1244adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner 1245adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner /* or in the parent directory of the system dir */ 1246adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner { 1247adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner char* parentDir = path_parent(i->androidOut, 1); 1248adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner if (parentDir != NULL) { 1249adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner skinPath = _checkSkinSkinsDir(parentDir, skinName); 1250adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner AFREE(parentDir); 1251adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner if (skinPath != NULL) 1252adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner break; 1253adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner } 1254adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner } 125525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 125625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 125725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* look in the search paths. For each <dir> in the list, 125825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * look into <dir>/../skins/<name>/ */ 125925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner { 126025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner int nn; 126125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner for (nn = 0; nn < i->numSearchPaths; nn++) { 126225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner char* parentDir = path_parent(i->searchPaths[nn], 1); 126325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (parentDir == NULL) 126425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner continue; 126525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner skinPath = _checkSkinSkinsDir(parentDir, skinName); 126625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(parentDir); 126725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (skinPath != NULL) 126825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 126925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 127025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (nn < i->numSearchPaths) 127125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner break; 127225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 127325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 127425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner /* We didn't find anything ! */ 1275adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner *pSkinName = skinName; 127625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 127725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 127825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } while (0); 127925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner 128025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner if (path_split(skinPath, pSkinDir, pSkinName) < 0) { 128125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner derror("weird skin path: %s", skinPath); 128225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(skinPath); 128325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 128425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner } 128525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner DD("found skin '%s' in directory: %s", *pSkinName, *pSkinDir); 128625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner AFREE(skinPath); 128725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner return; 128825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner} 128972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet 1290d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamyint 1291d899918690d5e392897e001abfb00b151ba2b13eSiva VelusamyavdInfo_shouldUseDynamicSkin( AvdInfo* i) 1292d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy{ 1293d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy if (i == NULL || i->configIni == NULL) 1294d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy return 0; 1295d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy return iniFile_getBoolean( i->configIni, SKIN_DYNAMIC, "no" ); 1296d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy} 1297d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy 129872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohetchar* 1299916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan LeeavdInfo_getDynamicSkinPath( AvdInfo* i) 1300916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee{ 1301916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee char tmp[PATH_MAX]; 1302916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee 1303916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee if (i->inAndroidBuild) { 1304916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee snprintf(tmp, sizeof(tmp), "%s/sdk/emulator/skins/dynamic/", i->androidBuildRoot); 1305916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee } else { 1306916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee snprintf(tmp, sizeof(tmp), "%s/tools/lib/emulator/skins/dynamic/", i->sdkRootPath); 1307916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee } 1308916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee 1309916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee if (!path_exists(tmp)) 1310916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee return NULL; 1311916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee 1312916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee return ASTRDUP(tmp); 1313916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee} 1314916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Lee 1315916f9cc4b9adf4eca98b4a6cc4366d43c4971617Ji-Hwan Leechar* 131672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier DucrohetavdInfo_getCharmapFile( AvdInfo* i, const char* charmapName ) 131772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet{ 131872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet char fileNameBuff[PATH_MAX]; 131972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet const char* fileName; 132072d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet 132172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet if (charmapName == NULL || charmapName[0] == '\0') 132272d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet return NULL; 132372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet 132472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet if (strstr(charmapName, ".kcm") == NULL) { 132572d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet snprintf(fileNameBuff, sizeof fileNameBuff, "%s.kcm", charmapName); 132672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet fileName = fileNameBuff; 132772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet } else { 132872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet fileName = charmapName; 132972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet } 133072d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet 133172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet return _avdInfo_getContentOrSdkFilePath(i, fileName); 133272d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet} 1333d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine 1334d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineint avdInfo_getAdbdCommunicationMode( AvdInfo* i ) 1335d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{ 1336fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner if (i->apiLevel < 16) { 1337fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner // QEMU pipe for ADB communication was added in android-4.1.1_r1 API 16 1338fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner D("API < 16, forcing ro.adb.qemud==0"); 1339fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner return 0; 1340fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner } 1341fb8aca0ae8f679e356ee0b06fe206e9df4408f9eDavid 'Digit' Turner 13425ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner return propertyFile_getAdbdCommunicationMode(i->buildProperties); 1343d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine} 1344873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine 1345873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkineint avdInfo_getSnapshotPresent(AvdInfo* i) 1346873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine{ 1347873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine if (i->configIni == NULL) { 1348873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine return 0; 1349873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine } else { 1350873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine return iniFile_getBoolean(i->configIni, "snapshot.present", "no"); 1351873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine } 1352873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine} 13535ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner 13545ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turnerconst FileData* avdInfo_getBootProperties(AvdInfo* i) { 13555ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner return i->bootProperties; 13565ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner} 1357