info.c revision c6e0caedac5585546cb68605418eedc9e726b44b
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
490b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turnerstatic int
491b64325d15d9e767c652491414c95f4fc148b0211David '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
56025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Look for a named file inside the AVD's content directory.
56125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * Returns NULL if it doesn't exist, or a strdup() copy otherwise.
56225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */
56325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char*
56425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getContentFilePath(AvdInfo*  i, const char* fileName)
56525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{
56625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp);
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
56825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    p = bufprint(p, end, "%s/%s", i->contentPath, fileName);
56925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (p >= end) {
57025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        derror("can't access virtual device content directory");
57125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return NULL;
57225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
57325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (!path_exists(temp)) {
57425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return NULL;
57525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
57625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    return ASTRDUP(temp);
57725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner}
57825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
57925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* find and parse the config.ini file from the content directory */
58025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int
58125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getConfigIni(AvdInfo*  i)
58225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{
58325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char*  iniPath = _avdInfo_getContentFilePath(i, "config.ini");
58425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
58525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    /* Allow non-existing config.ini */
58625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (iniPath == NULL) {
58725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        D("virtual device has no config file - no problem");
58825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return 0;
58925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
59025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
59125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    D("virtual device config file: %s", iniPath);
59225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    i->configIni = iniFile_newFromFile(iniPath);
59325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    AFREE(iniPath);
59425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
59525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (i->configIni == NULL) {
59625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        derror("bad config: %s",
59725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner               "virtual device has corrupted config.ini");
59825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return -1;
59925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
60025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    return 0;
60125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner}
60225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
60325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* The AVD's config.ini contains a list of search paths (all beginning
60425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * with SEARCH_PREFIX) which are directory locations searched for
60525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * AVD platform files.
60625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */
60725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic void
60825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getSearchPaths( AvdInfo*  i )
60925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{
61025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (i->configIni == NULL)
61125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return;
61225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
61325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    i->numSearchPaths = _getSearchPaths( i->configIni,
61425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                                         i->sdkRootPath,
61525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                                         MAX_SEARCH_PATHS,
61625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                                         i->searchPaths );
61725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (i->numSearchPaths == 0) {
61892c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project        derror("no search paths found in this AVD's configuration.\n"
61992c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project               "Weird, the AVD's config.ini file is malformed. Try re-creating it.\n");
62092c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project        exit(2);
62192c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project    }
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
62325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        DD("found a total of %d search paths for this AVD", i->numSearchPaths);
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
62625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Search a file in the SDK search directories. Return NULL if not found,
62725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * or a strdup() otherwise.
62825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */
62925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char*
63025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getSdkFilePath(AvdInfo*  i, const char*  fileName)
63125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{
63225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp);
63325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
63425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    do {
63525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        /* try the search paths */
63625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        int  nn;
63725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
63825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        for (nn = 0; nn < i->numSearchPaths; nn++) {
63925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            const char* searchDir = i->searchPaths[nn];
64025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
64125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            p = bufprint(temp, end, "%s/%s", searchDir, fileName);
64225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            if (p < end && path_exists(temp)) {
64325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                DD("found %s in search dir: %s", fileName, searchDir);
64425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                goto FOUND;
64525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            }
64625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            DD("    no %s in search dir: %s", fileName, searchDir);
64725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        }
64825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
64925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return NULL;
65025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
65125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    } while (0);
65225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
65325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' TurnerFOUND:
65425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    return ASTRDUP(temp);
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
65725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Search for a file in the content directory, and if not found, in the
65825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * SDK search directory. Returns NULL if not found.
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
66025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic char*
66125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getContentOrSdkFilePath(AvdInfo*  i, const char*  fileName)
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
66325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char*  path;
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
66525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    path = _avdInfo_getContentFilePath(i, fileName);
66625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (path)
66725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return path;
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
66925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    path = _avdInfo_getSdkFilePath(i, fileName);
67025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (path)
67125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return path;
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
67325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    return NULL;
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
67625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner#if 0
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
67825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_findContentOrSdkImage(AvdInfo* i, AvdImageType id)
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
68025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    const char* fileName = _imageFileNames[id];
68125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char*       path     = _avdInfo_getContentOrSdkFilePath(i, fileName);
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
68325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    i->imagePath[id]  = path;
68425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    i->imageState[id] = IMAGE_STATE_READONLY;
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
68625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (path == NULL)
68725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return -1;
68825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    else
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
69025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner}
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
69325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner/* Returns path to the core hardware .ini file. This contains the
69425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * hardware configuration that is read by the core. The content of this
69525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * file is auto-generated before launching a core, but we need to know
69625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner * its path before that.
69725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner */
69825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnerstatic int
69925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getCoreHwIniPath( AvdInfo* i, const char* basePath )
70025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{
70125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    i->coreHardwareIniPath = _getFullFilePath(basePath, CORE_HARDWARE_INI);
70225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (i->coreHardwareIniPath == NULL) {
70325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        DD("Path too long for %s: %s", CORE_HARDWARE_INI, basePath);
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
70625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    D("using core hw config path: %s", i->coreHardwareIniPath);
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7105ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
7115ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turnerstatic void
7125ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner_avdInfo_readPropertyFile(AvdInfo* i,
7135ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner                          const char* filePath,
7145ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner                          FileData* data) {
7155ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    int ret = fileData_initFromFile(data, filePath);
7165ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    if (ret < 0) {
7175ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        D("Error reading property file %s: %s", filePath, strerror(-ret));
7185ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    } else {
7195ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        D("Read property file at %s", filePath);
7205ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    }
7215ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner}
7225ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
7235ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
7245ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turnerstatic void
7255ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner_avdInfo_extractBuildProperties(AvdInfo* i) {
7265ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    i->targetArch = propertyFile_getTargetArch(i->buildProperties);
7275ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    if (!i->targetArch) {
7285ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        i->targetArch = ASTRDUP("arm");
7295ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        D("Cannot find target CPU architecture, defaulting to '%s'",
7305ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner          i->targetArch);
7315ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    }
7325ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    i->targetAbi = propertyFile_getTargetAbi(i->buildProperties);
7335ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    if (!i->targetAbi) {
7345ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        i->targetAbi = ASTRDUP("armeabi");
7355ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        D("Cannot find target CPU ABI, defaulting to '%s'",
7365ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner          i->targetAbi);
7375ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    }
7385ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    i->apiLevel = propertyFile_getApiLevel(i->buildProperties);
7395ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    if (i->apiLevel < 3) {
7405ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        i->apiLevel = 3;
7415ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        D("Cannot find target API level, defaulting to %d",
7425ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner          i->apiLevel);
7435ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    }
7445ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner}
7455ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
7465ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
7475ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turnerstatic void
7485ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner_avdInfo_getPropertyFile(AvdInfo* i,
7495ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner                         const char* propFileName,
7505ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner                         FileData* data ) {
7515ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    char* filePath = _avdInfo_getContentOrSdkFilePath(i, propFileName);
7525ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    if (!filePath) {
7535ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        D("No %s property file found.", propFileName);
7545ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        return;
7555ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    }
7565ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
7575ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    _avdInfo_readPropertyFile(i, filePath, data);
7585ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    free(filePath);
7595ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner}
7605ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfo*
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_new( const char*  name, AvdInfoParams*  params )
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AvdInfo*  i;
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (name == NULL)
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!_checkAvdName(name)) {
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        derror("virtual device name contains invalid characters");
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ANEW0(i);
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i->deviceName = ASTRDUP(name);
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
77725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if ( _avdInfo_getSdkRoot(i) < 0     ||
77825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner         _avdInfo_getRootIni(i) < 0     ||
77925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner         _avdInfo_getContentPath(i) < 0 ||
78025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner         _avdInfo_getConfigIni(i)   < 0 ||
78125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner         _avdInfo_getCoreHwIniPath(i, i->contentPath) < 0 )
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto FAIL;
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
784b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    i->apiLevel = _avdInfo_getApiLevel(i);
785b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* look for image search paths. handle post 1.1/pre cupcake
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * obsolete SDKs.
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
78925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    _avdInfo_getSearchPaths(i);
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7915ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    // Find the build.prop and boot.prop files and read them.
7925ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    _avdInfo_getPropertyFile(i, "build.prop", i->buildProperties);
7935ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    _avdInfo_getPropertyFile(i, "boot.prop", i->bootProperties);
7945ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* don't need this anymore */
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    iniFile_free(i->rootIni);
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i->rootIni = NULL;
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return i;
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFAIL:
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    avdInfo_free(i);
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/***************************************************************
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ***************************************************************
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****    ANDROID BUILD SUPPORT
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****    The code below corresponds to the case where we're
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****    starting the emulator inside the Android build
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****    system. The main differences are that:
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****    - the $ANDROID_PRODUCT_OUT directory is used as the
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****      content file.
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****    - built images must not be modified by the emulator,
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****      so system.img must be copied to a temporary file
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****      and userdata.img must be copied to userdata-qemu.img
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****      if the latter doesn't exist.
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****    - the kernel and default skin directory are taken from
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****      prebuilt
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****    - there is no root .ini file, or any config.ini in
82792c7311b1cb354745ec7b59b0e03910b3fe4c205The Android Open Source Project *****      the content directory, no SDK images search path.
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *****/
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
830fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner/* Read a hardware.ini if it is located in the skin directory */
831fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turnerstatic int
83225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner_avdInfo_getBuildSkinHardwareIni( AvdInfo*  i )
833fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner{
83425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char* skinName;
83525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char* skinDirPath;
836fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner
83725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    avdInfo_getSkinInfo(i, &skinName, &skinDirPath);
83825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (skinDirPath == NULL)
839fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner        return 0;
840fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner
841689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet    int result = avdInfo_getSkinHardwareIni(i, skinName, skinDirPath);
842689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet
843689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet    AFREE(skinName);
844689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet    AFREE(skinDirPath);
845689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet
846689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet    return result;
847689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet}
848689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet
849689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohetint avdInfo_getSkinHardwareIni( AvdInfo* i, char* skinName, char* skinDirPath)
850689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet{
851689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet    char  temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
852689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet
85325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    p = bufprint(temp, end, "%s/%s/hardware.ini", skinDirPath, skinName);
854fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner    if (p >= end || !path_exists(temp)) {
85525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        DD("no skin-specific hardware.ini in %s", skinDirPath);
856fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner        return 0;
857fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner    }
858fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner
859fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner    D("found skin-specific hardware.ini: %s", temp);
860689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet    if (i->skinHardwareIni != NULL)
861689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet        iniFile_free(i->skinHardwareIni);
86242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner    i->skinHardwareIni = iniFile_newFromFile(temp);
86342074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner    if (i->skinHardwareIni == NULL)
864fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner        return -1;
865fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner
866fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner    return 0;
867fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner}
868fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAvdInfo*
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_newForAndroidBuild( const char*     androidBuildRoot,
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            const char*     androidOut,
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            AvdInfoParams*  params )
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AvdInfo*  i;
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ANEW0(i);
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i->inAndroidBuild   = 1;
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i->androidBuildRoot = ASTRDUP(androidBuildRoot);
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i->androidOut       = ASTRDUP(androidOut);
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i->contentPath      = ASTRDUP(androidOut);
8825ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
8835ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    // Find the build.prop file and read it.
8845ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    char* buildPropPath = path_getBuildBuildProp(i->androidOut);
8855ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    if (buildPropPath) {
8865ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        _avdInfo_readPropertyFile(i, buildPropPath, i->buildProperties);
8875ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        free(buildPropPath);
8885ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    }
8895ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
8905ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    // FInd the boot.prop file and read it.
8915ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    char* bootPropPath = path_getBuildBootProp(i->androidOut);
8925ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    if (bootPropPath) {
8935ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        _avdInfo_readPropertyFile(i, bootPropPath, i->bootProperties);
8945ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        free(bootPropPath);
8955ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    }
896c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner
8975ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    _avdInfo_extractBuildProperties(i);
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* TODO: find a way to provide better information from the build files */
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i->deviceName = ASTRDUP("<build>");
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
90225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    /* There is no config.ini in the build */
90325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    i->configIni = NULL;
90425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
905fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    if (_avdInfo_getCoreHwIniPath(i, i->androidOut) < 0 )
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto FAIL;
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
90825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    /* Read the build skin's hardware.ini, if any */
90925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    _avdInfo_getBuildSkinHardwareIni(i);
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return i;
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFAIL:
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    avdInfo_free(i);
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getName( AvdInfo*  i )
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return i ? i->deviceName : NULL;
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getImageFile( AvdInfo*  i, AvdImageType  imageType )
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX)
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return i->imagePath[imageType];
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
933cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turneruint64_t
934cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' TurneravdInfo_getImageFileSize( AvdInfo*  i, AvdImageType  imageType )
935cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner{
936cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner    const char* file = avdInfo_getImageFile(i, imageType);
937cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner    uint64_t    size;
938cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner
939cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner    if (file == NULL)
940cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner        return 0ULL;
941cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner
942cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner    if (path_get_size(file, &size) < 0)
943cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner        return 0ULL;
944cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner
945cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner    return size;
946cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner}
947cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_isImageReadOnly( AvdInfo*  i, AvdImageType  imageType )
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX)
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (i->imageState[imageType] == IMAGE_STATE_READONLY);
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9570b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar*
9580b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getKernelPath( AvdInfo*  i )
9590b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{
9600b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_KERNEL ];
9610b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
9620b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    char*  kernelPath = _avdInfo_getContentOrSdkFilePath(i, imageName);
9630b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
9645ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    do {
9655ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        if (kernelPath || !i->inAndroidBuild)
9665ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner            break;
9675ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
9680b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        /* When in the Android build, look into the prebuilt directory
9690b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner         * for our target architecture.
9700b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner         */
9710b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        char temp[PATH_MAX], *p = temp, *end = p + sizeof(temp);
9722ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        const char* suffix = "";
9732ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
9745ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        // If the target ABI is armeabi-v7a, then look for
9755ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        // kernel-qemu-armv7 instead of kernel-qemu in the prebuilt
9765ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        // directory.
9775ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner        if (!strcmp(i->targetAbi, "armeabi-v7a")) {
9782ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            suffix = "-armv7";
9792ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        }
9800b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
981c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner        p = bufprint(temp, end, "%s/kernel", i->androidOut);
982c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner        if (p < end && path_exists(temp)) {
983c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner            kernelPath = ASTRDUP(temp);
984c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner            break;
985c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner        }
986c6e0caedac5585546cb68605418eedc9e726b44bDavid 'Digit' Turner
98718006f77ef9e760c225d1aa0dbbbe9cf5401aa8eJean-Baptiste Queru        p = bufprint(temp, end, "%s/prebuilts/qemu-kernel/%s/kernel-qemu%s",
9882ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner                     i->androidBuildRoot, i->targetArch, suffix);
9890b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        if (p >= end || !path_exists(temp)) {
9900b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            derror("bad workspace: cannot find prebuilt kernel in: %s", temp);
9910b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            exit(1);
9920b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        }
9930b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        kernelPath = ASTRDUP(temp);
9945ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
9955ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    } while (0);
9965ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
9970b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    return kernelPath;
9980b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner}
9990b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
10000b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
10010b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar*
10020b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getRamdiskPath( AvdInfo* i )
10030b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{
10040b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_RAMDISK ];
10050b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    return _avdInfo_getContentOrSdkFilePath(i, imageName);
10060b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner}
10070b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
1008c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turnerchar*  avdInfo_getCachePath( AvdInfo*  i )
1009c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner{
1010c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_CACHE ];
1011c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    return _avdInfo_getContentFilePath(i, imageName);
1012c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner}
1013c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
1014c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turnerchar*  avdInfo_getDefaultCachePath( AvdInfo*  i )
1015c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner{
1016c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_CACHE ];
1017c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    return _getFullFilePath(i->contentPath, imageName);
1018c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner}
1019c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
102048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turnerchar*  avdInfo_getSdCardPath( AvdInfo* i )
102148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner{
102248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_SDCARD ];
102348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    char*       path;
102448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
102548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    /* Special case, the config.ini can have a SDCARD_PATH entry
102648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner     * that gives the full path to the SD Card.
102748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner     */
102848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    if (i->configIni != NULL) {
102948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        path = iniFile_getString(i->configIni, SDCARD_PATH, NULL);
103048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        if (path != NULL) {
103148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            if (path_exists(path))
103248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                return path;
103348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
103448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            dwarning("Ignoring invalid SDCard path: %s", path);
103548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            AFREE(path);
103648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        }
103748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    }
103848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
103948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    /* Otherwise, simply look into the content directory */
104048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    return _avdInfo_getContentFilePath(i, imageName);
104148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner}
104248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
10430b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar*
10445f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' TurneravdInfo_getSnapStoragePath( AvdInfo* i )
10455f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner{
10465f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_SNAPSHOTS ];
10475f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    return _avdInfo_getContentFilePath(i, imageName);
10485f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner}
10495f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
10505f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turnerchar*
105140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' TurneravdInfo_getSystemImagePath( AvdInfo*  i )
105240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner{
105340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_USERSYSTEM ];
105440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    return _avdInfo_getContentFilePath(i, imageName);
105540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner}
105640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
105740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turnerchar*
10580b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getSystemInitImagePath( AvdInfo*  i )
10590b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{
10600b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_INITSYSTEM ];
10610b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    return _avdInfo_getContentOrSdkFilePath(i, imageName);
10620b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner}
10630b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
10640b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turnerchar*
1065fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' TurneravdInfo_getDataImagePath( AvdInfo*  i )
1066fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner{
1067fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ];
1068fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    return _avdInfo_getContentFilePath(i, imageName);
1069fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner}
1070fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
1071fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turnerchar*
1072fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' TurneravdInfo_getDefaultDataImagePath( AvdInfo*  i )
1073fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner{
1074fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ];
1075fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    return _getFullFilePath(i->contentPath, imageName);
1076fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner}
1077fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
1078fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turnerchar*
10790b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' TurneravdInfo_getDataInitImagePath( AvdInfo* i )
10800b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner{
10810b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    const char* imageName = _imageFileNames[ AVD_IMAGE_INITDATA ];
10820b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    return _avdInfo_getContentOrSdkFilePath(i, imageName);
10830b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner}
10840b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
1086b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' TurneravdInfo_initHwConfig( AvdInfo*  i, AndroidHwConfig*  hw )
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1088b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    int  ret = 0;
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1090b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    androidHwConfig_init(hw, i->apiLevel);
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1092b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    /* First read the config.ini, if any */
1093b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    if (i->configIni != NULL) {
1094b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner        ret = androidHwConfig_read(hw, i->configIni);
1095b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    }
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1097b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    /* The skin's hardware.ini can override values */
109842074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner    if (ret == 0 && i->skinHardwareIni != NULL) {
109942074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        ret = androidHwConfig_read(hw, i->skinHardwareIni);
1100fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner    }
1101fbcab322c2a12bfe49d0faaef91fccdc7bb97d4eDavid 'Digit' Turner
1102b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    /* Auto-disable keyboard emulation on sapphire platform builds */
1103b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    if (i->androidOut != NULL) {
11042f7bb38681802b4cf6f83ea97fddcab469224f93David Turner        char*  p = strrchr(i->androidOut, '/');
1105b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner        if (p != NULL && !strcmp(p,"sapphire")) {
1106b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner            hw->hw_keyboard = 0;
11072f7bb38681802b4cf6f83ea97fddcab469224f93David Turner        }
11082f7bb38681802b4cf6f83ea97fddcab469224f93David Turner    }
11092f7bb38681802b4cf6f83ea97fddcab469224f93David Turner
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getContentPath( AvdInfo*  i )
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return i->contentPath;
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_inAndroidBuild( AvdInfo*  i )
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return i->inAndroidBuild;
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar*
11262ed457ee5259b236bf39701404897f4c486326e8David 'Digit' TurneravdInfo_getTargetAbi( AvdInfo* i )
11272ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner{
11282ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    /* For now, we can't get the ABI from SDK AVDs */
11295ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    return ASTRDUP(i->targetAbi);
11302ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner}
11312ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
11322ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turnerchar*
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectavdInfo_getTracePath( AvdInfo*  i, const char*  traceName )
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char   tmp[MAX_PATH], *p=tmp, *end=p + sizeof(tmp);
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (i == NULL || traceName == NULL || traceName[0] == 0)
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (i->inAndroidBuild) {
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = bufprint( p, end, "%s" PATH_SEP "traces" PATH_SEP "%s",
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      i->androidOut, traceName );
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = bufprint( p, end, "%s" PATH_SEP "traces" PATH_SEP "%s",
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      i->contentPath, traceName );
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ASTRDUP(tmp);
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
114942074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner
115042074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turnerconst char*
115142074e5e184aed78dee0efb14d7376325516c070David 'Digit' TurneravdInfo_getCoreHwIniPath( AvdInfo* i )
115242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner{
115342074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner    return i->coreHardwareIniPath;
115442074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner}
115525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
115625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
115725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnervoid
115825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' TurneravdInfo_getSkinInfo( AvdInfo*  i, char** pSkinName, char** pSkinDir )
115925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{
116025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char*  skinName = NULL;
116125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char*  skinPath;
116225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char   temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
116325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
116425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    *pSkinName = NULL;
116525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    *pSkinDir  = NULL;
116625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
116725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    /* First, see if the config.ini contains a SKIN_PATH entry that
116825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner     * names the full directory path for the skin.
116925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner     */
1170689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet    if (i->configIni != NULL ) {
117125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        skinPath = iniFile_getString( i->configIni, SKIN_PATH, NULL );
117225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        if (skinPath != NULL) {
117325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            /* If this skin name is magic or a direct directory path
117425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            * we have our result right here.
117525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            */
117625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            if (_getSkinPathFromName(skinPath, i->sdkRootPath,
117725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                                     pSkinName, pSkinDir )) {
117825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                AFREE(skinPath);
117925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                return;
118025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            }
118125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        }
118225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
118325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        /* The SKIN_PATH entry was not valid, so look at SKIN_NAME */
118425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        D("Warning: config.ini contains invalid %s entry: %s", SKIN_PATH, skinPath);
118525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        AFREE(skinPath);
118625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
118725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        skinName = iniFile_getString( i->configIni, SKIN_NAME, NULL );
118825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
118925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
119025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (skinName == NULL) {
119125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        /* If there is no skin listed in the config.ini, try to see if
119225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner         * there is one single 'skin' directory in the content directory.
119325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner         */
119425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        p = bufprint(temp, end, "%s/skin", i->contentPath);
119525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        if (p < end && _checkSkinPath(temp)) {
119625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            D("using skin content from %s", temp);
119725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            AFREE(i->skinName);
119825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            *pSkinName = ASTRDUP("skin");
119925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            *pSkinDir  = ASTRDUP(i->contentPath);
120025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            return;
120125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        }
120225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
120325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        /* otherwise, use the default name */
120425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        skinName = ASTRDUP(SKIN_DEFAULT);
120525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
120625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
120725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    /* now try to find the skin directory for that name -
120825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner     */
120925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    do {
121025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        /* first try the content directory, i.e. $CONTENT/skins/<name> */
121125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        skinPath = _checkSkinSkinsDir(i->contentPath, skinName);
121225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        if (skinPath != NULL)
121325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            break;
121425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
121525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner#define  PREBUILT_SKINS_ROOT "development/tools/emulator"
121625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
121725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        /* if we are in the Android build, try the prebuilt directory */
121825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        if (i->inAndroidBuild) {
121925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            p = bufprint( temp, end, "%s/%s",
122025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                        i->androidBuildRoot, PREBUILT_SKINS_ROOT );
122125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            if (p < end) {
122225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                skinPath = _checkSkinSkinsDir(temp, skinName);
122325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                if (skinPath != NULL)
122425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                    break;
122525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            }
1226adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner
1227adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner            /* or in the parent directory of the system dir */
1228adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner            {
1229adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner                char* parentDir = path_parent(i->androidOut, 1);
1230adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner                if (parentDir != NULL) {
1231adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner                    skinPath = _checkSkinSkinsDir(parentDir, skinName);
1232adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner                    AFREE(parentDir);
1233adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner                    if (skinPath != NULL)
1234adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner                        break;
1235adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner                }
1236adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner            }
123725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        }
123825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
123925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        /* look in the search paths. For each <dir> in the list,
124025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner         * look into <dir>/../skins/<name>/ */
124125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        {
124225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            int  nn;
124325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            for (nn = 0; nn < i->numSearchPaths; nn++) {
124425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                char*  parentDir = path_parent(i->searchPaths[nn], 1);
124525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                if (parentDir == NULL)
124625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                    continue;
124725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                skinPath = _checkSkinSkinsDir(parentDir, skinName);
124825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                AFREE(parentDir);
124925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                if (skinPath != NULL)
125025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                  break;
125125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            }
125225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            if (nn < i->numSearchPaths)
125325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner                break;
125425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        }
125525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
125625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        /* We didn't find anything ! */
1257adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner        *pSkinName = skinName;
125825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return;
125925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
126025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    } while (0);
126125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
126225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (path_split(skinPath, pSkinDir, pSkinName) < 0) {
126325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        derror("weird skin path: %s", skinPath);
126425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        AFREE(skinPath);
126525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        return;
126625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
126725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    DD("found skin '%s' in directory: %s", *pSkinName, *pSkinDir);
126825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    AFREE(skinPath);
126925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    return;
127025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner}
127172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet
1272d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamyint
1273d899918690d5e392897e001abfb00b151ba2b13eSiva VelusamyavdInfo_shouldUseDynamicSkin( AvdInfo* i)
1274d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy{
1275d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy    if (i == NULL || i->configIni == NULL)
1276d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy        return 0;
1277d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy    return iniFile_getBoolean( i->configIni, SKIN_DYNAMIC, "no" );
1278d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy}
1279d899918690d5e392897e001abfb00b151ba2b13eSiva Velusamy
128072d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohetchar*
128172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier DucrohetavdInfo_getCharmapFile( AvdInfo* i, const char* charmapName )
128272d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet{
128372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    char        fileNameBuff[PATH_MAX];
128472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    const char* fileName;
128572d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet
128672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    if (charmapName == NULL || charmapName[0] == '\0')
128772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        return NULL;
128872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet
128972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    if (strstr(charmapName, ".kcm") == NULL) {
129072d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        snprintf(fileNameBuff, sizeof fileNameBuff, "%s.kcm", charmapName);
129172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        fileName = fileNameBuff;
129272d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    } else {
129372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        fileName = charmapName;
129472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    }
129572d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet
129672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    return _avdInfo_getContentOrSdkFilePath(i, fileName);
129772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet}
1298d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
1299d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkineint avdInfo_getAdbdCommunicationMode( AvdInfo* i )
1300d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine{
13015ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    return propertyFile_getAdbdCommunicationMode(i->buildProperties);
1302d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine}
1303873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine
1304873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkineint avdInfo_getSnapshotPresent(AvdInfo* i)
1305873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine{
1306873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine    if (i->configIni == NULL) {
1307873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine        return 0;
1308873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine    } else {
1309873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine        return iniFile_getBoolean(i->configIni, "snapshot.present", "no");
1310873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine    }
1311873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine}
13125ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner
13135ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turnerconst FileData* avdInfo_getBootProperties(AvdInfo* i) {
13145ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner    return i->bootProperties;
13155ea914899e5dbef4e8a7454b40a3c6648173f086David 'Digit' Turner}
1316