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