You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2001 lines
62 KiB
2001 lines
62 KiB
// Copyright 2020 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
#include "info.h"
|
|
|
|
#include "util.h"
|
|
#include "keys.h"
|
|
#include "base/ArraySize.h"
|
|
#include "base/export.h"
|
|
#include "host-common/feature_control.h"
|
|
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
/* global variables - see android/globals.h */
|
|
AvdInfoParams android_avdParams[1];
|
|
AvdInfo* android_avdInfo;
|
|
|
|
AEMU_EXPORT AvdInfo** aemu_get_android_avdInfoPtr() {
|
|
return &android_avdInfo;
|
|
}
|
|
|
|
/* set to 1 for debugging */
|
|
#define DEBUG 0
|
|
|
|
#if DEBUG >= 1
|
|
#include <stdio.h>
|
|
#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
|
|
#define DD(...) VERBOSE_PRINT(avd_config,__VA_ARGS__)
|
|
#else
|
|
#define D(...) (void)0
|
|
#define DD(...) (void)0
|
|
#endif
|
|
|
|
/* technical note on how all of this is supposed to work:
|
|
*
|
|
* Each AVD corresponds to a "content directory" that is used to
|
|
* store persistent disk images and configuration files. Most remarkable
|
|
* are:
|
|
*
|
|
* - a "config.ini" file used to hold configuration information for the
|
|
* AVD
|
|
*
|
|
* - mandatory user data image ("userdata-qemu.img") and cache image
|
|
* ("cache.img")
|
|
*
|
|
* - optional mutable system image ("system-qemu.img"), kernel image
|
|
* ("kernel-qemu") and read-only ramdisk ("ramdisk.img")
|
|
*
|
|
* When starting up an AVD, the emulator looks for relevant disk images
|
|
* in the content directory. If it doesn't find a given image there, it
|
|
* will try to search in the list of system directories listed in the
|
|
* 'config.ini' file through one of the following (key,value) pairs:
|
|
*
|
|
* images.sysdir.1 = <first search path>
|
|
* images.sysdir.2 = <second search path>
|
|
*
|
|
* The search paths can be absolute, or relative to the root SDK installation
|
|
* path (which is determined from the emulator program's location, or from the
|
|
* ANDROID_SDK_ROOT environment variable).
|
|
*
|
|
* Individual image disk search patch can be over-riden on the command-line
|
|
* with one of the usual options.
|
|
*/
|
|
|
|
/* certain disk image files are mounted read/write by the emulator
|
|
* to ensure that several emulators referencing the same files
|
|
* do not corrupt these files, we need to lock them and respond
|
|
* to collision depending on the image type.
|
|
*
|
|
* the enumeration below is used to record information about
|
|
* each image file path.
|
|
*
|
|
* READONLY means that the file will be mounted read-only
|
|
* and this doesn't need to be locked. must be first in list
|
|
*
|
|
* MUSTLOCK means that the file should be locked before
|
|
* being mounted by the emulator
|
|
*
|
|
* TEMPORARY means that the file has been copied to a
|
|
* temporary image, which can be mounted read/write
|
|
* but doesn't require locking.
|
|
*/
|
|
typedef enum {
|
|
IMAGE_STATE_READONLY, /* unlocked */
|
|
IMAGE_STATE_MUSTLOCK, /* must be locked */
|
|
IMAGE_STATE_LOCKED, /* locked */
|
|
IMAGE_STATE_LOCKED_EMPTY, /* locked and empty */
|
|
IMAGE_STATE_TEMPORARY, /* copied to temp file (no lock needed) */
|
|
} AvdImageState;
|
|
|
|
struct AvdInfo {
|
|
/* for the Android build system case */
|
|
char inAndroidBuild;
|
|
char* androidOut;
|
|
char* androidBuildRoot;
|
|
char* targetArch;
|
|
char* targetAbi;
|
|
char* acpiIniPath;
|
|
|
|
/* for the normal virtual device case */
|
|
char* deviceName;
|
|
char* deviceId;
|
|
char* sdkRootPath;
|
|
char* searchPaths[ MAX_SEARCH_PATHS ];
|
|
int numSearchPaths;
|
|
char* contentPath;
|
|
char* rootIniPath;
|
|
CIniFile* rootIni; /* root <foo>.ini file, empty if missing */
|
|
CIniFile* configIni; /* virtual device's config.ini, NULL if missing */
|
|
CIniFile* skinHardwareIni; /* skin-specific hardware.ini */
|
|
|
|
/* for both */
|
|
int apiLevel;
|
|
int incrementalVersion;
|
|
|
|
/* For preview releases where we don't know the exact API level this flag
|
|
* indicates that at least we know it's M+ (for some code that needs to
|
|
* select either legacy or modern operation mode.
|
|
*/
|
|
bool isMarshmallowOrHigher;
|
|
bool isGoogleApis;
|
|
bool isUserBuild;
|
|
AvdFlavor flavor;
|
|
char* skinName; /* skin name */
|
|
char* skinDirPath; /* skin directory */
|
|
char* coreHardwareIniPath; /* core hardware.ini path */
|
|
char* snapshotLockPath; /* core snapshot.lock path */
|
|
char* multiInstanceLockPath;
|
|
|
|
// FileData buildProperties[1]; /* build.prop file */
|
|
// FileData bootProperties[1]; /* boot.prop file */
|
|
|
|
/* image files */
|
|
char* imagePath [ AVD_IMAGE_MAX ];
|
|
char imageState[ AVD_IMAGE_MAX ];
|
|
|
|
/* skip checks */
|
|
bool noChecks;
|
|
};
|
|
|
|
|
|
// void
|
|
// avdInfo_free( AvdInfo* i )
|
|
// {
|
|
// if (i) {
|
|
// int nn;
|
|
//
|
|
// for (nn = 0; nn < AVD_IMAGE_MAX; nn++)
|
|
// AFREE(i->imagePath[nn]);
|
|
//
|
|
// AFREE(i->skinName);
|
|
// AFREE(i->skinDirPath);
|
|
// AFREE(i->coreHardwareIniPath);
|
|
// AFREE(i->snapshotLockPath);
|
|
//
|
|
// fileData_done(i->buildProperties);
|
|
// fileData_done(i->bootProperties);
|
|
//
|
|
// for (nn = 0; nn < i->numSearchPaths; nn++)
|
|
// AFREE(i->searchPaths[nn]);
|
|
//
|
|
// i->numSearchPaths = 0;
|
|
//
|
|
// if (i->configIni) {
|
|
// iniFile_free(i->configIni);
|
|
// i->configIni = NULL;
|
|
// }
|
|
//
|
|
// if (i->skinHardwareIni) {
|
|
// iniFile_free(i->skinHardwareIni);
|
|
// i->skinHardwareIni = NULL;
|
|
// }
|
|
//
|
|
// if (i->rootIni) {
|
|
// iniFile_free(i->rootIni);
|
|
// i->rootIni = NULL;
|
|
// }
|
|
//
|
|
// AFREE(i->contentPath);
|
|
// AFREE(i->sdkRootPath);
|
|
// AFREE(i->rootIniPath);
|
|
// AFREE(i->targetArch);
|
|
// AFREE(i->targetAbi);
|
|
//
|
|
// if (i->inAndroidBuild) {
|
|
// AFREE(i->androidOut);
|
|
// AFREE(i->androidBuildRoot);
|
|
// AFREE(i->acpiIniPath);
|
|
// }
|
|
//
|
|
// AFREE(i->deviceName);
|
|
// AFREE(i->deviceId);
|
|
// AFREE(i);
|
|
// }
|
|
// }
|
|
//
|
|
// /* list of default file names for each supported image file type */
|
|
// static const char* const _imageFileNames[ AVD_IMAGE_MAX ] = {
|
|
// #define _AVD_IMG(x,y,z) y,
|
|
// AVD_IMAGE_LIST
|
|
// #undef _AVD_IMG
|
|
// };
|
|
//
|
|
// /***************************************************************
|
|
// ***************************************************************
|
|
// *****
|
|
// ***** UTILITY FUNCTIONS
|
|
// *****
|
|
// ***** The following functions do not depend on the AvdInfo
|
|
// ***** structure and could easily be moved elsewhere.
|
|
// *****
|
|
// *****/
|
|
//
|
|
// /* Parse a given config.ini file and extract the list of SDK search paths
|
|
// * from it. Returns the number of valid paths stored in 'searchPaths', or -1
|
|
// * in case of problem.
|
|
// *
|
|
// * Relative search paths in the config.ini will be stored as full pathnames
|
|
// * relative to 'sdkRootPath'.
|
|
// *
|
|
// * 'searchPaths' must be an array of char* pointers of at most 'maxSearchPaths'
|
|
// * entries.
|
|
// */
|
|
// static int _getSearchPaths(CIniFile* configIni,
|
|
// const char* sdkRootPath,
|
|
// int maxSearchPaths,
|
|
// char** searchPaths) {
|
|
// char temp[PATH_MAX], *p = temp, *end= p+sizeof temp;
|
|
// int nn, count = 0;
|
|
//
|
|
// for (nn = 0; nn < maxSearchPaths; nn++) {
|
|
// char* path;
|
|
//
|
|
// p = bufprint(temp, end, "%s%d", SEARCH_PREFIX, nn+1 );
|
|
// if (p >= end)
|
|
// continue;
|
|
//
|
|
// path = iniFile_getString(configIni, temp, NULL);
|
|
// if (path != NULL) {
|
|
// DD(" found image search path: %s", path);
|
|
// if (!path_is_absolute(path)) {
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"%s", sdkRootPath, path);
|
|
// AFREE(path);
|
|
// path = ASTRDUP(temp);
|
|
// }
|
|
// searchPaths[count++] = path;
|
|
// }
|
|
// }
|
|
// return count;
|
|
// }
|
|
//
|
|
// /* Check that an AVD name is valid. Returns 1 on success, 0 otherwise.
|
|
// */
|
|
// static int
|
|
// _checkAvdName( const char* name )
|
|
// {
|
|
// int len = strlen(name);
|
|
// int len2 = strspn(name, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
// "abcdefghijklmnopqrstuvwxyz"
|
|
// "0123456789_.-");
|
|
// return (len == len2);
|
|
// }
|
|
//
|
|
// /* Returns the full path of a given file.
|
|
// *
|
|
// * If 'fileName' is an absolute path, this returns a simple copy.
|
|
// * Otherwise, this returns a new string corresponding to <rootPath>/<fileName>
|
|
// *
|
|
// * This returns NULL if the paths are too long.
|
|
// */
|
|
// static char*
|
|
// _getFullFilePath( const char* rootPath, const char* fileName )
|
|
// {
|
|
// if (path_is_absolute(fileName)) {
|
|
// return ASTRDUP(fileName);
|
|
// } else {
|
|
// char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
|
|
//
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"%s", rootPath, fileName);
|
|
// if (p >= end) {
|
|
// return NULL;
|
|
// }
|
|
// return ASTRDUP(temp);
|
|
// }
|
|
// }
|
|
//
|
|
// /* check that a given directory contains a valid skin.
|
|
// * returns 1 on success, 0 on failure.
|
|
// */
|
|
// static int
|
|
// _checkSkinPath( const char* skinPath )
|
|
// {
|
|
// char temp[MAX_PATH], *p=temp, *end=p+sizeof(temp);
|
|
//
|
|
// /* for now, if it has a 'layout' file, it is a valid skin path */
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"layout", skinPath);
|
|
// if (p >= end || !path_exists(temp))
|
|
// return 0;
|
|
//
|
|
// return 1;
|
|
// }
|
|
//
|
|
// /* Check that there is a skin named 'skinName' listed from 'skinDirRoot'
|
|
// * this returns the full path of the skin directory (after alias expansions),
|
|
// * including the skin name, or NULL on failure.
|
|
// */
|
|
// static char*
|
|
// _checkSkinSkinsDir( const char* skinDirRoot,
|
|
// const char* skinName )
|
|
// {
|
|
// DirScanner* scanner;
|
|
// char* result;
|
|
// char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp);
|
|
//
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"skins"PATH_SEP"%s", skinDirRoot, skinName);
|
|
// DD("Probing skin directory: %s", temp);
|
|
// if (p >= end || !path_exists(temp)) {
|
|
// DD(" ignore bad skin directory %s", temp);
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// /* first, is this a normal skin directory ? */
|
|
// if (_checkSkinPath(temp)) {
|
|
// /* yes */
|
|
// DD(" found skin directory: %s", temp);
|
|
// return ASTRDUP(temp);
|
|
// }
|
|
//
|
|
// /* second, is it an alias to another skin ? */
|
|
// *p = 0;
|
|
// result = NULL;
|
|
// scanner = dirScanner_new(temp);
|
|
// if (scanner != NULL) {
|
|
// for (;;) {
|
|
// const char* file = dirScanner_next(scanner);
|
|
//
|
|
// if (file == NULL)
|
|
// break;
|
|
//
|
|
// if (strncmp(file, "alias-", 6) || file[6] == 0)
|
|
// continue;
|
|
//
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"skins"PATH_SEP"%s", skinDirRoot, file+6);
|
|
// if (p < end && _checkSkinPath(temp)) {
|
|
// /* yes, it's an alias */
|
|
// DD(" skin alias '%s' points to skin directory: %s",
|
|
// file+6, temp);
|
|
// result = ASTRDUP(temp);
|
|
// break;
|
|
// }
|
|
// }
|
|
// dirScanner_free(scanner);
|
|
// }
|
|
// return result;
|
|
// }
|
|
//
|
|
// /* try to see if the skin name leads to a magic skin or skin path directly
|
|
// * returns 1 on success, 0 on error.
|
|
// *
|
|
// * on success, this sets up '*pSkinName' and '*pSkinDir'
|
|
// */
|
|
// static int
|
|
// _getSkinPathFromName( const char* skinName,
|
|
// const char* sdkRootPath,
|
|
// char** pSkinName,
|
|
// char** pSkinDir )
|
|
// {
|
|
// char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
|
|
//
|
|
// /* if the skin name has the format 'NNNNxNNN' where
|
|
// * NNN is a decimal value, then this is a 'magic' skin
|
|
// * name that doesn't require a skin directory
|
|
// */
|
|
// if (isdigit(skinName[0])) {
|
|
// int width, height;
|
|
// if (sscanf(skinName, "%dx%d", &width, &height) == 2) {
|
|
// D("'magic' skin format detected: %s", skinName);
|
|
// *pSkinName = ASTRDUP(skinName);
|
|
// *pSkinDir = NULL;
|
|
// return 1;
|
|
// }
|
|
// }
|
|
//
|
|
// /* is the skin name a direct path to the skin directory ? */
|
|
// if (path_is_absolute(skinName) && _checkSkinPath(skinName)) {
|
|
// goto FOUND_IT;
|
|
// }
|
|
//
|
|
// /* is the skin name a relative path from the SDK root ? */
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"%s", sdkRootPath, skinName);
|
|
// if (p < end && _checkSkinPath(temp)) {
|
|
// skinName = temp;
|
|
// goto FOUND_IT;
|
|
// }
|
|
//
|
|
// /* nope */
|
|
// return 0;
|
|
//
|
|
// FOUND_IT:
|
|
// if (path_split(skinName, pSkinDir, pSkinName) < 0) {
|
|
// derror("malformed skin name: %s", skinName);
|
|
// return 0;
|
|
// }
|
|
// D("found skin '%s' in directory: %s", *pSkinName, *pSkinDir);
|
|
// return 1;
|
|
// }
|
|
//
|
|
// /***************************************************************
|
|
// ***************************************************************
|
|
// *****
|
|
// ***** NORMAL VIRTUAL DEVICE SUPPORT
|
|
// *****
|
|
// *****/
|
|
//
|
|
// /* compute path to the root SDK directory
|
|
// * assume we are in $SDKROOT/tools/emulator[.exe]
|
|
// */
|
|
// static int
|
|
// _avdInfo_getSdkRoot( AvdInfo* i )
|
|
// {
|
|
//
|
|
// i->sdkRootPath = path_getSdkRoot();
|
|
// if (i->sdkRootPath == NULL) {
|
|
// derror("can't find SDK installation directory");
|
|
// return -1;
|
|
// }
|
|
// return 0;
|
|
// }
|
|
//
|
|
// /* parse the root config .ini file. it is located in
|
|
// * ~/.android/avd/<name>.ini or Windows equivalent
|
|
// */
|
|
// static int
|
|
// _avdInfo_getRootIni( AvdInfo* i )
|
|
// {
|
|
// i->rootIniPath = path_getRootIniPath( i->deviceName );
|
|
//
|
|
// if (i->rootIniPath == NULL) {
|
|
// derror("unknown virtual device name: '%s'", i->deviceName);
|
|
// return -1;
|
|
// }
|
|
//
|
|
// D("Android virtual device file at: %s", i->rootIniPath);
|
|
//
|
|
// i->rootIni = iniFile_newFromFile(i->rootIniPath);
|
|
//
|
|
// if (i->rootIni == NULL) {
|
|
// derror("Corrupt virtual device config file!");
|
|
// return -1;
|
|
// }
|
|
// return 0;
|
|
// }
|
|
//
|
|
// /* Returns the AVD's content path, i.e. the directory that contains
|
|
// * the AVD's content files (e.g. data partition, cache, sd card, etc...).
|
|
// *
|
|
// * We extract this by parsing the root config .ini file, looking for
|
|
// * a "path" elements.
|
|
// */
|
|
// static int
|
|
// _avdInfo_getContentPath( AvdInfo* i )
|
|
// {
|
|
// if (i->inAndroidBuild && i->androidOut && i->contentPath) {
|
|
// return 0;
|
|
// }
|
|
//
|
|
// char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
|
|
//
|
|
// i->contentPath = iniFile_getString(i->rootIni, ROOT_ABS_PATH_KEY, NULL);
|
|
//
|
|
// if (i->contentPath == NULL) {
|
|
// derror("bad config: %s",
|
|
// "virtual device file lacks a "ROOT_ABS_PATH_KEY" entry");
|
|
// return -1;
|
|
// }
|
|
//
|
|
// if (!path_is_dir(i->contentPath)) {
|
|
// // If the absolute path doesn't match an actual directory, try
|
|
// // the relative path if present.
|
|
// const char* relPath = iniFile_getString(i->rootIni, ROOT_REL_PATH_KEY, NULL);
|
|
// if (relPath != NULL) {
|
|
// p = bufprint_config_path(temp, end);
|
|
// p = bufprint(p, end, PATH_SEP "%s", relPath);
|
|
// if (p < end && path_is_dir(temp)) {
|
|
// str_reset(&i->contentPath, temp);
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// D("virtual device content at %s", i->contentPath);
|
|
// return 0;
|
|
// }
|
|
//
|
|
// static int
|
|
// _avdInfo_getApiLevel(AvdInfo* i, bool* isMarshmallowOrHigher)
|
|
// {
|
|
// char* target;
|
|
// const char* p;
|
|
// const int defaultLevel = kUnknownApiLevel;
|
|
// int level = defaultLevel;
|
|
//
|
|
// # define ROOT_TARGET_KEY "target"
|
|
//
|
|
// target = iniFile_getString(i->rootIni, ROOT_TARGET_KEY, NULL);
|
|
// if (target == NULL) {
|
|
// D("No target field in root AVD .ini file?");
|
|
// D("Defaulting to API level %d", level);
|
|
// return level;
|
|
// }
|
|
//
|
|
// DD("Found target field in root AVD .ini file: '%s'", target);
|
|
//
|
|
// /* There are two acceptable formats for the target key.
|
|
// *
|
|
// * 1/ android-<level>
|
|
// * 2/ <vendor-name>:<add-on-name>:<level>
|
|
// *
|
|
// * Where <level> can be either a _name_ (for experimental/preview SDK builds)
|
|
// * or a decimal number. Note that if a _name_, it can start with a digit.
|
|
// */
|
|
//
|
|
// /* First, extract the level */
|
|
// if (!memcmp(target, "android-", 8))
|
|
// p = target + 8;
|
|
// else {
|
|
// /* skip two columns */
|
|
// p = strchr(target, ':');
|
|
// if (p != NULL) {
|
|
// p = strchr(p+1, ':');
|
|
// if (p != NULL)
|
|
// p += 1;
|
|
// }
|
|
// }
|
|
// if (p == NULL || !isdigit(*p)) {
|
|
// // preview versions usually have a single letter instead of the API
|
|
// // level.
|
|
// if (p && isalpha(p[0]) && p[1] == 0) {
|
|
// level = avdInfo_getApiLevelFromLetter(p[0]);
|
|
// if (level > 99 && toupper(p[0]) >= 'M') {
|
|
// *isMarshmallowOrHigher = true;
|
|
// }
|
|
// } else {
|
|
// goto NOT_A_NUMBER;
|
|
// }
|
|
// } else {
|
|
// char* end;
|
|
// long val = strtol(p, &end, 10);
|
|
// if (end == NULL || *end != '\0' || val != (int)val) {
|
|
// goto NOT_A_NUMBER;
|
|
// }
|
|
// level = (int)val;
|
|
//
|
|
// /* Sanity check, we don't support anything prior to Android 1.5 */
|
|
// if (level < 3)
|
|
// level = 3;
|
|
//
|
|
// D("Found AVD target API level: %d", level);
|
|
// }
|
|
// EXIT:
|
|
// AFREE(target);
|
|
// return level;
|
|
//
|
|
// NOT_A_NUMBER:
|
|
// if (p == NULL) {
|
|
// D("Invalid target field in root AVD .ini file");
|
|
// } else {
|
|
// D("Target AVD api level is not a number");
|
|
// }
|
|
// D("Defaulting to API level %d", level);
|
|
// goto EXIT;
|
|
// }
|
|
//
|
|
// bool
|
|
// avdInfo_isGoogleApis(const AvdInfo* i) {
|
|
// return i->isGoogleApis;
|
|
// }
|
|
//
|
|
// bool
|
|
// avdInfo_isUserBuild(const AvdInfo* i) {
|
|
// return i->isUserBuild;
|
|
// }
|
|
//
|
|
// AvdFlavor avdInfo_getAvdFlavor(const AvdInfo* i) {
|
|
// return i->flavor;
|
|
// }
|
|
//
|
|
// int
|
|
// avdInfo_getApiLevel(const AvdInfo* i) {
|
|
// return i->apiLevel;
|
|
// }
|
|
//
|
|
// // This information was taken from the SDK Manager:
|
|
// // Appearances & Behavior > System Settings > Android SDK > SDK Platforms
|
|
// static const struct {
|
|
// int apiLevel;
|
|
// const char* dessertName;
|
|
// const char* fullName;
|
|
// } kApiLevelInfo[] = {
|
|
// { 10, "Gingerbread", "2.3.3 (Gingerbread) - API 10 (Rev 2)" },
|
|
// { 14, "Ice Cream Sandwich", "4.0 (Ice Cream Sandwich) - API 14 (Rev 4)" },
|
|
// { 15, "Ice Cream Sandwich", "4.0.3 (Ice Cream Sandwich) - API 15 (Rev 5)" },
|
|
// { 16, "Jelly Bean", "4.1 (Jelly Bean) - API 16 (Rev 5)" },
|
|
// { 17, "Jelly Bean", "4.2 (Jelly Bean) - API 17 (Rev 3)" },
|
|
// { 18, "Jelly Bean", "4.3 (Jelly Bean) - API 18 (Rev 3)" },
|
|
// { 19, "KitKat", "4.4 (KitKat) - API 19 (Rev 4)" },
|
|
// { 20, "KitKat", "4.4 (KitKat Wear) - API 20 (Rev 2)" },
|
|
// { 21, "Lollipop", "5.0 (Lollipop) - API 21 (Rev 2)" },
|
|
// { 22, "Lollipop", "5.1 (Lollipop) - API 22 (Rev 2)" },
|
|
// { 23, "Marshmallow", "6.0 (Marshmallow) - API 23 (Rev 1)" },
|
|
// { 24, "Nougat", "7.0 (Nougat) - API 24" },
|
|
// { 25, "Nougat", "7.1 (Nougat) - API 25" },
|
|
// { 26, "Oreo", "8.0 (Oreo) - API 26" },
|
|
// { 27, "Oreo", "8.1 (Oreo) - API 27" },
|
|
// { 28, "Pie", "9.0 (Pie) - API 28" },
|
|
// { 29, "Q", "10.0 (Q) - API 29" },
|
|
// { 30, "R", "11.0 (R) - API 30"}
|
|
// };
|
|
//
|
|
// const char* avdInfo_getApiDessertName(int apiLevel) {
|
|
// int i = 0;
|
|
// for (; i < ARRAY_SIZE(kApiLevelInfo); ++i) {
|
|
// if (kApiLevelInfo[i].apiLevel == apiLevel) {
|
|
// return kApiLevelInfo[i].dessertName;
|
|
// }
|
|
// }
|
|
// return "";
|
|
// }
|
|
//
|
|
// void avdInfo_getFullApiName(int apiLevel, char* nameStr, int strLen) {
|
|
// if (apiLevel < 0 || apiLevel > 99) {
|
|
// strncpy(nameStr, "Unknown API version", strLen);
|
|
// return;
|
|
// }
|
|
//
|
|
// int i = 0;
|
|
// for (; i < ARRAY_SIZE(kApiLevelInfo); ++i) {
|
|
// if (kApiLevelInfo[i].apiLevel == apiLevel) {
|
|
// strncpy(nameStr, kApiLevelInfo[i].fullName, strLen);
|
|
// return;
|
|
// }
|
|
// }
|
|
// snprintf(nameStr, strLen, "API %d", apiLevel);
|
|
// }
|
|
//
|
|
// int avdInfo_getApiLevelFromLetter(char letter) {
|
|
// const char letterUpper = toupper(letter);
|
|
// int i = 0;
|
|
// for (; i < ARRAY_SIZE(kApiLevelInfo); ++i) {
|
|
// if (toupper(kApiLevelInfo[i].dessertName[0]) == letterUpper) {
|
|
// return kApiLevelInfo[i].apiLevel;
|
|
// }
|
|
// }
|
|
// return kUnknownApiLevel;
|
|
// }
|
|
//
|
|
// /* Look for a named file inside the AVD's content directory.
|
|
// * Returns NULL if it doesn't exist, or a strdup() copy otherwise.
|
|
// */
|
|
// static char*
|
|
// _avdInfo_getContentFilePath(const AvdInfo* i, const char* fileName)
|
|
// {
|
|
// char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp);
|
|
//
|
|
// p = bufprint(p, end, "%s"PATH_SEP"%s", i->contentPath, fileName);
|
|
// if (p >= end) {
|
|
// derror("can't access virtual device content directory");
|
|
// return NULL;
|
|
// }
|
|
// if (!path_exists(temp)) {
|
|
// return NULL;
|
|
// }
|
|
// return ASTRDUP(temp);
|
|
// }
|
|
//
|
|
// /* find and parse the config.ini file from the content directory */
|
|
// static int
|
|
// _avdInfo_getConfigIni(AvdInfo* i)
|
|
// {
|
|
// char* iniPath = _avdInfo_getContentFilePath(i, CORE_CONFIG_INI);
|
|
//
|
|
// /* Allow non-existing config.ini */
|
|
// if (iniPath == NULL) {
|
|
// D("virtual device has no config file - no problem");
|
|
// return 0;
|
|
// }
|
|
//
|
|
// D("virtual device config file: %s", iniPath);
|
|
// i->configIni = iniFile_newFromFile(iniPath);
|
|
// AFREE(iniPath);
|
|
//
|
|
// if (i->configIni == NULL) {
|
|
// derror("bad config: %s",
|
|
// "virtual device has corrupted " CORE_CONFIG_INI);
|
|
// return -1;
|
|
// }
|
|
// return 0;
|
|
// }
|
|
//
|
|
// /* The AVD's config.ini contains a list of search paths (all beginning
|
|
// * with SEARCH_PREFIX) which are directory locations searched for
|
|
// * AVD platform files.
|
|
// */
|
|
// static bool
|
|
// _avdInfo_getSearchPaths( AvdInfo* i )
|
|
// {
|
|
// if (i->configIni == NULL)
|
|
// return true;
|
|
//
|
|
// if (android_cmdLineOptions && android_cmdLineOptions->sysdir) {
|
|
// // The user specified a path on the command line.
|
|
// // Use only that.
|
|
// i->numSearchPaths = 1;
|
|
// i->searchPaths[0] = android_cmdLineOptions->sysdir;
|
|
// DD("using one search path from the command line for this AVD");
|
|
// return true;
|
|
// }
|
|
//
|
|
// i->numSearchPaths = _getSearchPaths( i->configIni,
|
|
// i->sdkRootPath,
|
|
// MAX_SEARCH_PATHS,
|
|
// i->searchPaths );
|
|
// if (i->numSearchPaths == 0) {
|
|
// derror("no search paths found in this AVD's configuration.\n"
|
|
// "Weird, the AVD's " CORE_CONFIG_INI " file is malformed. "
|
|
// "Try re-creating it.\n");
|
|
// return false;
|
|
// }
|
|
// else
|
|
// DD("found a total of %d search paths for this AVD", i->numSearchPaths);
|
|
// return true;
|
|
// }
|
|
//
|
|
// /* Search a file in the SDK search directories. Return NULL if not found,
|
|
// * or a strdup() otherwise.
|
|
// */
|
|
// static char*
|
|
// _avdInfo_getSdkFilePath(const AvdInfo* i, const char* fileName)
|
|
// {
|
|
// char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp);
|
|
//
|
|
// do {
|
|
// /* try the search paths */
|
|
// int nn;
|
|
//
|
|
// for (nn = 0; nn < i->numSearchPaths; nn++) {
|
|
// const char* searchDir = i->searchPaths[nn];
|
|
//
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"%s", searchDir, fileName);
|
|
// if (p < end && path_exists(temp)) {
|
|
// DD("found %s in search dir: %s", fileName, searchDir);
|
|
// goto FOUND;
|
|
// }
|
|
// DD(" no %s in search dir: %s", fileName, searchDir);
|
|
// }
|
|
//
|
|
// return NULL;
|
|
//
|
|
// } while (0);
|
|
//
|
|
// FOUND:
|
|
// return ASTRDUP(temp);
|
|
// }
|
|
//
|
|
// /* Search for a file in the content directory, and if not found, in the
|
|
// * SDK search directory. Returns NULL if not found.
|
|
// */
|
|
// static char*
|
|
// _avdInfo_getContentOrSdkFilePath(const AvdInfo* i, const char* fileName)
|
|
// {
|
|
// char* path;
|
|
//
|
|
// path = _avdInfo_getContentFilePath(i, fileName);
|
|
// if (path)
|
|
// return path;
|
|
//
|
|
// path = _avdInfo_getSdkFilePath(i, fileName);
|
|
// if (path)
|
|
// return path;
|
|
//
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// #if 0
|
|
// static int
|
|
// _avdInfo_findContentOrSdkImage(const AvdInfo* i, AvdImageType id)
|
|
// {
|
|
// const char* fileName = _imageFileNames[id];
|
|
// char* path = _avdInfo_getContentOrSdkFilePath(i, fileName);
|
|
//
|
|
// i->imagePath[id] = path;
|
|
// i->imageState[id] = IMAGE_STATE_READONLY;
|
|
//
|
|
// if (path == NULL)
|
|
// return -1;
|
|
// else
|
|
// return 0;
|
|
// }
|
|
// #endif
|
|
//
|
|
// /* Returns path to the core hardware .ini file. This contains the
|
|
// * hardware configuration that is read by the core. The content of this
|
|
// * file is auto-generated before launching a core, but we need to know
|
|
// * its path before that.
|
|
// */
|
|
// static int
|
|
// _avdInfo_getCoreHwIniPath( AvdInfo* i, const char* basePath )
|
|
// {
|
|
// i->coreHardwareIniPath = _getFullFilePath(basePath, CORE_HARDWARE_INI);
|
|
// if (i->coreHardwareIniPath == NULL) {
|
|
// DD("Path too long for %s: %s", CORE_HARDWARE_INI, basePath);
|
|
// return -1;
|
|
// }
|
|
// D("using core hw config path: %s", i->coreHardwareIniPath);
|
|
// return 0;
|
|
// }
|
|
//
|
|
// static int
|
|
// _avdInfo_getSnapshotLockFilePath( AvdInfo* i, const char* basePath )
|
|
// {
|
|
// i->snapshotLockPath = _getFullFilePath(basePath, SNAPSHOT_LOCK);
|
|
// if (i->snapshotLockPath == NULL) {
|
|
// DD("Path too long for %s: %s", SNAPSHOT_LOCK, basePath);
|
|
// return -1;
|
|
// }
|
|
// D("using snapshot lock path: %s", i->snapshotLockPath);
|
|
// return 0;
|
|
// }
|
|
//
|
|
// static int
|
|
// _avdInfo_getMultiInstanceLockFilePath( AvdInfo* i, const char* basePath )
|
|
// {
|
|
// i->multiInstanceLockPath = _getFullFilePath(basePath, MULTIINSTANCE_LOCK);
|
|
// if (i->multiInstanceLockPath == NULL) {
|
|
// DD("Path too long for %s: %s", MULTIINSTANCE_LOCK, basePath);
|
|
// return -1;
|
|
// }
|
|
// D("using multi-instance lock path: %s", i->multiInstanceLockPath);
|
|
// return 0;
|
|
// }
|
|
//
|
|
// static void
|
|
// _avdInfo_readPropertyFile(const AvdInfo* i,
|
|
// const char* filePath,
|
|
// FileData* data) {
|
|
// int ret = fileData_initFromFile(data, filePath);
|
|
// if (ret < 0) {
|
|
// D("Error reading property file %s: %s", filePath, strerror(-ret));
|
|
// } else {
|
|
// D("Read property file at %s", filePath);
|
|
// }
|
|
// }
|
|
//
|
|
// static void
|
|
// _avdInfo_extractBuildProperties(AvdInfo* i) {
|
|
// i->targetArch = propertyFile_getTargetArch(i->buildProperties);
|
|
// if (!i->targetArch) {
|
|
// str_reset(&i->targetArch, "arm");
|
|
// D("Cannot find target CPU architecture, defaulting to '%s'",
|
|
// i->targetArch);
|
|
// }
|
|
// i->targetAbi = propertyFile_getTargetAbi(i->buildProperties);
|
|
// if (!i->targetAbi) {
|
|
// str_reset(&i->targetAbi, "armeabi");
|
|
// D("Cannot find target CPU ABI, defaulting to '%s'",
|
|
// i->targetAbi);
|
|
// }
|
|
// if (!i->apiLevel) {
|
|
// // Note: for regular AVDs, the API level is already extracted
|
|
// // from config.ini, besides, for older SDK platform images,
|
|
// // there is no build.prop file and the following function
|
|
// // would always return 1000, making the AVD unbootable!.
|
|
// i->apiLevel = propertyFile_getApiLevel(i->buildProperties);
|
|
// if (i->apiLevel < 3) {
|
|
// i->apiLevel = 3;
|
|
// D("Cannot find target API level, defaulting to %d",
|
|
// i->apiLevel);
|
|
// }
|
|
// }
|
|
//
|
|
// i->flavor = propertyFile_getAvdFlavor(i->buildProperties);
|
|
//
|
|
// i->isGoogleApis = propertyFile_isGoogleApis(i->buildProperties);
|
|
// i->isUserBuild = propertyFile_isUserBuild(i->buildProperties);
|
|
// i->incrementalVersion = propertyFile_getInt(
|
|
// i->buildProperties,
|
|
// "ro.build.version.incremental",
|
|
// -1,
|
|
// NULL);
|
|
// }
|
|
//
|
|
//
|
|
// static void
|
|
// _avdInfo_getPropertyFile(AvdInfo* i,
|
|
// const char* propFileName,
|
|
// FileData* data ) {
|
|
// char* filePath = _avdInfo_getContentOrSdkFilePath(i, propFileName);
|
|
// if (!filePath) {
|
|
// D("No %s property file found.", propFileName);
|
|
// return;
|
|
// }
|
|
//
|
|
// _avdInfo_readPropertyFile(i, filePath, data);
|
|
// free(filePath);
|
|
// }
|
|
//
|
|
// AvdInfo*
|
|
// avdInfo_new( const char* name, AvdInfoParams* params )
|
|
// {
|
|
// AvdInfo* i;
|
|
//
|
|
// if (name == NULL)
|
|
// return NULL;
|
|
//
|
|
// if (!_checkAvdName(name)) {
|
|
// derror("virtual device name contains invalid characters");
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// ANEW0(i);
|
|
// str_reset(&i->deviceName, name);
|
|
// str_reset(&i->deviceId, name);
|
|
// i->noChecks = false;
|
|
//
|
|
// if ( _avdInfo_getSdkRoot(i) < 0 ||
|
|
// _avdInfo_getRootIni(i) < 0 ||
|
|
// _avdInfo_getContentPath(i) < 0 ||
|
|
// _avdInfo_getConfigIni(i) < 0 ||
|
|
// _avdInfo_getCoreHwIniPath(i, i->contentPath) < 0 ||
|
|
// _avdInfo_getSnapshotLockFilePath(i, i->contentPath) < 0 ||
|
|
// _avdInfo_getMultiInstanceLockFilePath(i, i->contentPath) < 0)
|
|
// goto FAIL;
|
|
//
|
|
// i->apiLevel = _avdInfo_getApiLevel(i, &i->isMarshmallowOrHigher);
|
|
//
|
|
// /* look for image search paths. handle post 1.1/pre cupcake
|
|
// * obsolete SDKs.
|
|
// */
|
|
// if (!_avdInfo_getSearchPaths(i)) {
|
|
// goto FAIL;
|
|
// }
|
|
//
|
|
// // Find the build.prop and boot.prop files and read them.
|
|
// _avdInfo_getPropertyFile(i, "build.prop", i->buildProperties);
|
|
// _avdInfo_getPropertyFile(i, "boot.prop", i->bootProperties);
|
|
//
|
|
// _avdInfo_extractBuildProperties(i);
|
|
//
|
|
// /* don't need this anymore */
|
|
// iniFile_free(i->rootIni);
|
|
// i->rootIni = NULL;
|
|
//
|
|
// return i;
|
|
//
|
|
// FAIL:
|
|
// avdInfo_free(i);
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// void avdInfo_setAvdId( AvdInfo* i, const char* avdId)
|
|
// {
|
|
// if (i == NULL) return;
|
|
//
|
|
// str_reset(&i->deviceId, avdId);
|
|
// }
|
|
//
|
|
// /***************************************************************
|
|
// ***************************************************************
|
|
// *****
|
|
// ***** ANDROID BUILD SUPPORT
|
|
// *****
|
|
// ***** The code below corresponds to the case where we're
|
|
// ***** starting the emulator inside the Android build
|
|
// ***** system. The main differences are that:
|
|
// *****
|
|
// ***** - the $ANDROID_PRODUCT_OUT directory is used as the
|
|
// ***** content file.
|
|
// *****
|
|
// ***** - built images must not be modified by the emulator,
|
|
// ***** so system.img must be copied to a temporary file
|
|
// ***** and userdata.img must be copied to userdata-qemu.img
|
|
// ***** if the latter doesn't exist.
|
|
// *****
|
|
// ***** - the kernel and default skin directory are taken from
|
|
// ***** prebuilt
|
|
// *****
|
|
// ***** - there is no root .ini file, or any config.ini in
|
|
// ***** the content directory, no SDK images search path.
|
|
// *****/
|
|
//
|
|
// /* Read a hardware.ini if it is located in the skin directory */
|
|
// static int
|
|
// _avdInfo_getBuildSkinHardwareIni( AvdInfo* i )
|
|
// {
|
|
// char* skinName;
|
|
// char* skinDirPath;
|
|
//
|
|
// avdInfo_getSkinInfo(i, &skinName, &skinDirPath);
|
|
// if (skinDirPath == NULL)
|
|
// return 0;
|
|
//
|
|
// int result = avdInfo_getSkinHardwareIni(i, skinName, skinDirPath);
|
|
//
|
|
// AFREE(skinName);
|
|
// AFREE(skinDirPath);
|
|
//
|
|
// return result;
|
|
// }
|
|
//
|
|
// int avdInfo_getSkinHardwareIni( AvdInfo* i, char* skinName, char* skinDirPath)
|
|
// {
|
|
// char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
|
|
//
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"%s"PATH_SEP"hardware.ini", skinDirPath, skinName);
|
|
// if (p >= end || !path_exists(temp)) {
|
|
// DD("no skin-specific hardware.ini in %s", skinDirPath);
|
|
// return 0;
|
|
// }
|
|
//
|
|
// D("found skin-specific hardware.ini: %s", temp);
|
|
// if (i->skinHardwareIni != NULL)
|
|
// iniFile_free(i->skinHardwareIni);
|
|
// i->skinHardwareIni = iniFile_newFromFile(temp);
|
|
// if (i->skinHardwareIni == NULL)
|
|
// return -1;
|
|
//
|
|
// return 0;
|
|
// }
|
|
//
|
|
// AvdInfo*
|
|
// avdInfo_newForAndroidBuild( const char* androidBuildRoot,
|
|
// const char* androidOut,
|
|
// AvdInfoParams* params )
|
|
// {
|
|
// AvdInfo* i;
|
|
//
|
|
// ANEW0(i);
|
|
//
|
|
// i->inAndroidBuild = 1;
|
|
// str_reset(&i->androidBuildRoot, androidBuildRoot);
|
|
// str_reset(&i->androidOut, androidOut);
|
|
// str_reset(&i->contentPath, androidOut);
|
|
//
|
|
// // Find the build.prop file and read it.
|
|
// char* buildPropPath = path_getBuildBuildProp(i->androidOut);
|
|
// if (buildPropPath) {
|
|
// _avdInfo_readPropertyFile(i, buildPropPath, i->buildProperties);
|
|
// free(buildPropPath);
|
|
// }
|
|
//
|
|
// // FInd the boot.prop file and read it.
|
|
// char* bootPropPath = path_getBuildBootProp(i->androidOut);
|
|
// if (bootPropPath) {
|
|
// _avdInfo_readPropertyFile(i, bootPropPath, i->bootProperties);
|
|
// free(bootPropPath);
|
|
// }
|
|
//
|
|
// _avdInfo_extractBuildProperties(i);
|
|
//
|
|
// str_reset(&i->deviceName, "<build>");
|
|
// str_reset(&i->deviceId, "<build>");
|
|
//
|
|
// i->numSearchPaths = 1;
|
|
// i->searchPaths[0] = strdup(androidOut);
|
|
// /* out/target/product/<name>/config.ini, if exists, provide configuration
|
|
// * from build files. */
|
|
// if (_avdInfo_getConfigIni(i) < 0 ||
|
|
// _avdInfo_getCoreHwIniPath(i, i->androidOut) < 0 ||
|
|
// _avdInfo_getSnapshotLockFilePath(i, i->androidOut) < 0 ||
|
|
// _avdInfo_getMultiInstanceLockFilePath(i, i->androidOut) < 0)
|
|
// goto FAIL;
|
|
//
|
|
// /* Read the build skin's hardware.ini, if any */
|
|
// _avdInfo_getBuildSkinHardwareIni(i);
|
|
//
|
|
// return i;
|
|
//
|
|
// FAIL:
|
|
// avdInfo_free(i);
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// const char*
|
|
// avdInfo_getName( const AvdInfo* i )
|
|
// {
|
|
// return i ? i->deviceName : NULL;
|
|
// }
|
|
//
|
|
// const char*
|
|
// avdInfo_getId( const AvdInfo* i )
|
|
// {
|
|
// return i ? i->deviceId : NULL;
|
|
// }
|
|
//
|
|
// const char*
|
|
// avdInfo_getImageFile( const AvdInfo* i, AvdImageType imageType )
|
|
// {
|
|
// if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX)
|
|
// return NULL;
|
|
//
|
|
// return i->imagePath[imageType];
|
|
// }
|
|
//
|
|
// uint64_t
|
|
// avdInfo_getImageFileSize( const AvdInfo* i, AvdImageType imageType )
|
|
// {
|
|
// const char* file = avdInfo_getImageFile(i, imageType);
|
|
// uint64_t size;
|
|
//
|
|
// if (file == NULL)
|
|
// return 0ULL;
|
|
//
|
|
// if (path_get_size(file, &size) < 0)
|
|
// return 0ULL;
|
|
//
|
|
// return size;
|
|
// }
|
|
//
|
|
// int
|
|
// avdInfo_isImageReadOnly( const AvdInfo* i, AvdImageType imageType )
|
|
// {
|
|
// if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX)
|
|
// return 1;
|
|
//
|
|
// return (i->imageState[imageType] == IMAGE_STATE_READONLY);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getKernelPath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_KERNEL ];
|
|
//
|
|
// char* kernelPath = _avdInfo_getContentOrSdkFilePath(i, imageName);
|
|
//
|
|
// do {
|
|
// if (kernelPath || !i->inAndroidBuild)
|
|
// break;
|
|
//
|
|
// /* When in the Android build, look into the prebuilt directory
|
|
// * for our target architecture.
|
|
// */
|
|
// char temp[PATH_MAX], *p = temp, *end = p + sizeof(temp);
|
|
// const char* suffix = "";
|
|
//
|
|
// // If the target ABI is armeabi-v7a, then look for
|
|
// // kernel-qemu-armv7 instead of kernel-qemu in the prebuilt
|
|
// // directory.
|
|
// if (!strcmp(i->targetAbi, "armeabi-v7a")) {
|
|
// suffix = "-armv7";
|
|
// }
|
|
//
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"kernel", i->androidOut);
|
|
// if (p < end && path_exists(temp)) {
|
|
// str_reset(&kernelPath, temp);
|
|
// break;
|
|
// }
|
|
//
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"prebuilts"PATH_SEP"qemu-kernel"PATH_SEP"%s"PATH_SEP"kernel-qemu%s",
|
|
// i->androidBuildRoot, i->targetArch, suffix);
|
|
// if (p >= end || !path_exists(temp)) {
|
|
// derror("bad workspace: cannot find prebuilt kernel in: %s", temp);
|
|
// kernelPath = NULL;
|
|
// break;
|
|
// }
|
|
// str_reset(&kernelPath, temp);
|
|
//
|
|
// } while (0);
|
|
//
|
|
// return kernelPath;
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getRanchuKernelPath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_KERNELRANCHU64 ];
|
|
// char* kernelPath = _avdInfo_getContentOrSdkFilePath(i, imageName);
|
|
// if (kernelPath) {
|
|
// return kernelPath;
|
|
// }
|
|
//
|
|
// imageName = _imageFileNames[ AVD_IMAGE_KERNELRANCHU ];
|
|
// kernelPath = _avdInfo_getContentOrSdkFilePath(i, imageName);
|
|
//
|
|
// //old flow, checks the prebuilds/qemu-kernel, ignore //32bit-image-on-64bit scenario:
|
|
// //the build process should have a copy of kernel-ranchu/kernel-ranchu-64 in the
|
|
// //android out already,and will be handled by _avdInfo_getContentOrSdkFilePath()
|
|
// do {
|
|
// if (kernelPath || !i->inAndroidBuild)
|
|
// break;
|
|
//
|
|
// /* When in the Android build, look into the prebuilt directory
|
|
// * for our target architecture.
|
|
// */
|
|
// char temp[PATH_MAX], *p = temp, *end = p + sizeof(temp);
|
|
// const char* suffix = "";
|
|
//
|
|
// /* mips/ranchu holds distinct images for mips & mips32[r5|r6] */
|
|
// if (!strcmp(i->targetAbi, "mips32r6")) {
|
|
// suffix = "-mips32r6";
|
|
// } else if (!strcmp(i->targetAbi, "mips32r5")) {
|
|
// suffix = "-mips32r5";
|
|
// }
|
|
//
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"prebuilts"PATH_SEP"qemu-kernel"PATH_SEP"%s"PATH_SEP"ranchu"PATH_SEP"kernel-qemu%s",
|
|
// i->androidBuildRoot, i->targetArch, suffix);
|
|
// if (p >= end || !path_exists(temp)) {
|
|
// /* arm64 and mips64 are special: their kernel-qemu is actually kernel-ranchu */
|
|
// if (!strcmp(i->targetArch, "arm64") || !strcmp(i->targetArch, "mips64")) {
|
|
// return avdInfo_getKernelPath(i);
|
|
// } else {
|
|
// derror("bad workspace: cannot find prebuilt ranchu kernel in: %s", temp);
|
|
// kernelPath = NULL;
|
|
// break;
|
|
// }
|
|
// }
|
|
// str_reset(&kernelPath, temp);
|
|
// } while (0);
|
|
//
|
|
// return kernelPath;
|
|
// }
|
|
//
|
|
//
|
|
// char*
|
|
// avdInfo_getRamdiskPath( const AvdInfo* i )
|
|
// {
|
|
// const char* userImageName = _imageFileNames[ AVD_IMAGE_USERRAMDISK ];
|
|
// char* result = _avdInfo_getContentOrSdkFilePath(i, userImageName);
|
|
// if (result) return result;
|
|
//
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_RAMDISK ];
|
|
// return _avdInfo_getContentOrSdkFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char* avdInfo_getCachePath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_CACHE ];
|
|
// return _avdInfo_getContentFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char* avdInfo_getDefaultCachePath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_CACHE ];
|
|
// return _getFullFilePath(i->contentPath, imageName);
|
|
// }
|
|
//
|
|
// char* avdInfo_getSdCardPath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_SDCARD ];
|
|
// char* path;
|
|
//
|
|
// /* Special case, the config.ini can have a SDCARD_PATH entry
|
|
// * that gives the full path to the SD Card.
|
|
// */
|
|
// if (i->configIni != NULL) {
|
|
// path = iniFile_getString(i->configIni, SDCARD_PATH, NULL);
|
|
// if (path != NULL) {
|
|
// if (path_exists(path))
|
|
// return path;
|
|
//
|
|
// dwarning("Ignoring invalid SDCard path: %s", path);
|
|
// AFREE(path);
|
|
// }
|
|
// }
|
|
//
|
|
// if (i->imagePath[ AVD_IMAGE_SDCARD ] != NULL) {
|
|
// path = ASTRDUP(i->imagePath[ AVD_IMAGE_SDCARD ]);
|
|
// if (path_exists(path))
|
|
// return path;
|
|
//
|
|
// dwarning("Ignoring invalid SDCard path: %s", path);
|
|
// AFREE(path);
|
|
// }
|
|
//
|
|
// /* Otherwise, simply look into the content directory */
|
|
// return _avdInfo_getContentFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char* avdInfo_getEncryptionKeyImagePath(const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_ENCRYPTIONKEY ];
|
|
// return _avdInfo_getContentFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getSnapStoragePath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_SNAPSHOTS ];
|
|
// return _avdInfo_getContentFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getSystemImagePath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_USERSYSTEM ];
|
|
// return _avdInfo_getContentFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getVerifiedBootParamsPath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_VERIFIEDBOOTPARAMS ];
|
|
// return _avdInfo_getContentOrSdkFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getSystemInitImagePath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_INITSYSTEM ];
|
|
// return _avdInfo_getContentOrSdkFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getVendorImagePath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_USERVENDOR ];
|
|
// return _avdInfo_getContentFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getVendorInitImagePath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_INITVENDOR ];
|
|
// return _avdInfo_getContentOrSdkFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// static bool
|
|
// is_x86ish(const AvdInfo* i)
|
|
// {
|
|
// if (strncmp(i->targetAbi, "x86", 3) == 0) {
|
|
// return true;
|
|
// } else {
|
|
// return false;
|
|
// }
|
|
// }
|
|
//
|
|
// static bool
|
|
// is_armish(const AvdInfo* i)
|
|
// {
|
|
// if (strncmp(i->targetAbi, "arm", 3) == 0) {
|
|
// return true;
|
|
// } else {
|
|
// return false;
|
|
// }
|
|
// }
|
|
//
|
|
// static bool
|
|
// is_mipsish(const AvdInfo* i)
|
|
// {
|
|
// if (strncmp(i->targetAbi, "mips", 4) == 0) {
|
|
// return true;
|
|
// } else {
|
|
// return false;
|
|
// }
|
|
// }
|
|
//
|
|
// /*
|
|
// arm is pretty tricky: the system image device path
|
|
// changes depending on the number of disks: the last
|
|
// one seems always a003e00, we need to know how many
|
|
// devices it actually has
|
|
// */
|
|
// const char* const arm_device_id[] = {
|
|
// "a003e00",
|
|
// "a003c00",
|
|
// "a003a00",
|
|
// "a003800",
|
|
// "a003600",
|
|
// "a003400",
|
|
// };
|
|
//
|
|
// const char* const mips_device_id[] = {
|
|
// "1f03d000",
|
|
// "1f03d200",
|
|
// "1f03d400",
|
|
// "1f03d600",
|
|
// "1f03d800",
|
|
// };
|
|
//
|
|
// static
|
|
// bool has_sdcard(const AvdInfo* i) {
|
|
// char* path = avdInfo_getSdCardPath(i);
|
|
// if (path) {
|
|
// free(path);
|
|
// return true;
|
|
// }
|
|
// return false;
|
|
// }
|
|
//
|
|
// static
|
|
// bool has_vendor(const AvdInfo* i) {
|
|
// char* path = avdInfo_getVendorInitImagePath(i);
|
|
// if (path) {
|
|
// free(path);
|
|
// return true;
|
|
// }
|
|
// path = avdInfo_getVendorImagePath(i);
|
|
// if (path) {
|
|
// free(path);
|
|
// return true;
|
|
// }
|
|
// return false;
|
|
// }
|
|
//
|
|
// static
|
|
// bool has_encryption(const AvdInfo* i) {
|
|
// char* path = avdInfo_getEncryptionKeyImagePath(i);
|
|
// if (path) {
|
|
// free(path);
|
|
// return true;
|
|
// }
|
|
// return false;
|
|
// }
|
|
//
|
|
//
|
|
// static
|
|
// char* get_device_path(const AvdInfo* info, const char* image)
|
|
// {
|
|
// const char* device_table[6] = {"", "","" ,"" ,"" , ""};
|
|
// int i = 0;
|
|
// if (has_sdcard(info)) {
|
|
// device_table[i++] = "sdcard";
|
|
// }
|
|
// if (has_vendor(info)) {
|
|
// device_table[i++] = "vendor";
|
|
// }
|
|
// if (has_encryption(info)) {
|
|
// device_table[i++] = "encryption";
|
|
// }
|
|
// device_table[i++] = "userdata";
|
|
// device_table[i++] = "cache";
|
|
// device_table[i++] = "system";
|
|
// int count = ARRAY_SIZE(device_table);
|
|
// for ( i=0; i < count; ++i) {
|
|
// if (strcmp(image, device_table[i]) ==0) {
|
|
// break;
|
|
// }
|
|
// }
|
|
// if (i == count) {
|
|
// return NULL;
|
|
// }
|
|
// char buf[1024];
|
|
//
|
|
// if (is_armish(info)) {
|
|
// snprintf(buf, sizeof(buf), "/dev/block/platform/%s.virtio_mmio/by-name/%s",
|
|
// arm_device_id[i], image);
|
|
// } else if (is_mipsish(info)) {
|
|
// snprintf(buf, sizeof(buf), "/dev/block/platform/%s.virtio_mmio/by-name/%s",
|
|
// mips_device_id[i], image);
|
|
// }
|
|
// return strdup(buf);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getVendorImageDevicePathInGuest( const AvdInfo* i )
|
|
// {
|
|
// if (!has_vendor(i)) {
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// if (is_x86ish(i)) {
|
|
// if (has_encryption(i)) {
|
|
// return strdup("/dev/block/pci/pci0000:00/0000:00:07.0/by-name/vendor");
|
|
// } else {
|
|
// return strdup("/dev/block/pci/pci0000:00/0000:00:06.0/by-name/vendor");
|
|
// }
|
|
// } else {
|
|
// return get_device_path(i, "vendor");
|
|
// }
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getDynamicPartitionBootDevice( const AvdInfo* i )
|
|
// {
|
|
// if (is_x86ish(i)) {
|
|
// return strdup("pci0000:00/0000:00:03.0");
|
|
// }
|
|
//
|
|
// char* system_path = get_device_path(i, "system");
|
|
// if (!system_path) {
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// char* bootdev = strdup(system_path + strlen("/dev/block/platform/"));
|
|
// char* end = strstr(bootdev, "/by-name/system");
|
|
// *end = '\0';
|
|
// return bootdev;
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getSystemImageDevicePathInGuest( const AvdInfo* i )
|
|
// {
|
|
// if (feature_is_enabled(kFeature_SystemAsRoot)) {
|
|
// return NULL;
|
|
// }
|
|
// if (is_x86ish(i)) {
|
|
// return strdup("/dev/block/pci/pci0000:00/0000:00:03.0/by-name/system");
|
|
// } else {
|
|
// return get_device_path(i, "system");
|
|
// }
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getDataImagePath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ];
|
|
// return _avdInfo_getContentFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getDefaultDataImagePath( const AvdInfo* i )
|
|
// {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ];
|
|
// return _getFullFilePath(i->contentPath, imageName);
|
|
// }
|
|
//
|
|
// char* avdInfo_getDefaultSystemFeatureControlPath(const AvdInfo* i) {
|
|
// char* retVal = _avdInfo_getSdkFilePath(i, "advancedFeatures.ini");
|
|
// return retVal;
|
|
// }
|
|
//
|
|
// char* avdInfo_getDataInitImagePath(const AvdInfo* i) {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_INITDATA ];
|
|
// return _avdInfo_getContentOrSdkFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// char* avdInfo_getDataInitDirPath(const AvdInfo* i) {
|
|
// const char* imageName = _imageFileNames[ AVD_IMAGE_INITZIP ];
|
|
// return _avdInfo_getSdkFilePath(i, imageName);
|
|
// }
|
|
//
|
|
// int
|
|
// avdInfo_initHwConfig(const AvdInfo* i, AndroidHwConfig* hw, bool isQemu2)
|
|
// {
|
|
// int ret = 0;
|
|
//
|
|
// androidHwConfig_init(hw, i->apiLevel);
|
|
//
|
|
// /* First read the skin's hardware.ini, if any */
|
|
// if (i->skinHardwareIni != NULL) {
|
|
// ret = androidHwConfig_read(hw, i->skinHardwareIni);
|
|
// }
|
|
//
|
|
// /* The device's config.ini can override the skin's values
|
|
// * (which is preferable to the opposite order)
|
|
// */
|
|
// if (ret == 0 && i->configIni != NULL) {
|
|
// ret = androidHwConfig_read(hw, i->configIni);
|
|
// /* We will set hw.arc in avd manager when creating new avd.
|
|
// * Before new avd manager released, we check tag.id to see
|
|
// * if it's a Chrome OS image.
|
|
// */
|
|
// if (ret == 0 && !hw->hw_arc) {
|
|
// char *tag = iniFile_getString(i->configIni, TAG_ID, "default");
|
|
// if (!strcmp(tag, TAG_ID_CHROMEOS)) {
|
|
// hw->hw_arc = true;
|
|
// }
|
|
// AFREE(tag);
|
|
// }
|
|
// }
|
|
//
|
|
// /* Auto-disable keyboard emulation on sapphire platform builds */
|
|
// if (i->androidOut != NULL) {
|
|
// char* p = strrchr(i->androidOut, *PATH_SEP);
|
|
// if (p != NULL && !strcmp(p,"sapphire")) {
|
|
// hw->hw_keyboard = 0;
|
|
// }
|
|
// }
|
|
//
|
|
// // for api <= 10 there is no multi-touch support in any of the ranchu
|
|
// // or goldfish kernels and GUI won't respond as a result;
|
|
// // force it to be "touch"
|
|
// //
|
|
// // for api <= 21 the goldfish kernel is not updated to
|
|
// // support multi-touch yet; so just force touch
|
|
// // bug: https://code.google.com/p/android/issues/detail?id=199289
|
|
// //
|
|
// // System images above 10 support multi-touch if they have a ranchu kernel
|
|
// // and we're using QEMU2 as indicated by the isQemu2 flag.
|
|
// //
|
|
// // TODO: There is currently an issue related to this to track the release of
|
|
// // system images with ranchu kernels for API 21 and below at:
|
|
// // https://code.google.com/p/android/issues/detail?id=200332
|
|
// if (i->apiLevel <= 10 || (!isQemu2 && i->apiLevel <= 21)) {
|
|
// str_reset(&hw->hw_screen, "touch");
|
|
// }
|
|
//
|
|
// if (hw->hw_arc) {
|
|
// // Chrome OS GPU acceleration is not perfect now, disable it
|
|
// // in "default" mode, it still can be enabled with explicit
|
|
// // setting.
|
|
// if (hw->hw_gpu_mode == NULL || !strcmp(hw->hw_gpu_mode, "auto"))
|
|
// str_reset(&hw->hw_gpu_mode, "off");
|
|
// str_reset(&hw->hw_cpu_arch, "x86_64");
|
|
// }
|
|
//
|
|
// return ret;
|
|
// }
|
|
//
|
|
// void
|
|
// avdInfo_setImageFile( AvdInfo* i, AvdImageType imageType,
|
|
// const char* imagePath )
|
|
// {
|
|
// assert(i != NULL && (unsigned)imageType < AVD_IMAGE_MAX);
|
|
//
|
|
// i->imagePath[imageType] = ASTRDUP(imagePath);
|
|
// }
|
|
//
|
|
// void
|
|
// avdInfo_setAcpiIniPath( AvdInfo* i, const char* iniPath )
|
|
// {
|
|
// assert(i != NULL);
|
|
//
|
|
// i->acpiIniPath = ASTRDUP(iniPath);
|
|
// }
|
|
// const char*
|
|
// avdInfo_getContentPath( const AvdInfo* i )
|
|
// {
|
|
// return i->contentPath;
|
|
// }
|
|
//
|
|
// const char*
|
|
// avdInfo_getRootIniPath( const AvdInfo* i )
|
|
// {
|
|
// return i->rootIniPath;
|
|
// }
|
|
//
|
|
// const char*
|
|
// avdInfo_getAcpiIniPath( const AvdInfo* i )
|
|
// {
|
|
// return i->acpiIniPath;
|
|
// }
|
|
//
|
|
// int
|
|
// avdInfo_inAndroidBuild( const AvdInfo* i )
|
|
// {
|
|
// return i->inAndroidBuild;
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getTargetCpuArch(const AvdInfo* i) {
|
|
// return ASTRDUP(i->targetArch);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getTargetAbi( const AvdInfo* i )
|
|
// {
|
|
// /* For now, we can't get the ABI from SDK AVDs */
|
|
// return ASTRDUP(i->targetAbi);
|
|
// }
|
|
//
|
|
// bool avdInfo_is_x86ish(const AvdInfo* i)
|
|
// {
|
|
// return is_x86ish(i);
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getCodeProfilePath( const AvdInfo* i, const char* profileName )
|
|
// {
|
|
// char tmp[MAX_PATH], *p=tmp, *end=p + sizeof(tmp);
|
|
//
|
|
// if (i == NULL || profileName == NULL || profileName[0] == 0)
|
|
// return NULL;
|
|
//
|
|
// if (i->inAndroidBuild) {
|
|
// p = bufprint( p, end, "%s" PATH_SEP "profiles" PATH_SEP "%s",
|
|
// i->androidOut, profileName );
|
|
// } else {
|
|
// p = bufprint( p, end, "%s" PATH_SEP "profiles" PATH_SEP "%s",
|
|
// i->contentPath, profileName );
|
|
// }
|
|
// return ASTRDUP(tmp);
|
|
// }
|
|
//
|
|
// const char*
|
|
// avdInfo_getCoreHwIniPath( const AvdInfo* i )
|
|
// {
|
|
// return i->coreHardwareIniPath;
|
|
// }
|
|
//
|
|
// const char*
|
|
// avdInfo_getSnapshotLockFilePath( const AvdInfo* i )
|
|
// {
|
|
// return i->snapshotLockPath;
|
|
// }
|
|
//
|
|
// const char*
|
|
// avdInfo_getMultiInstanceLockFilePath( const AvdInfo* i )
|
|
// {
|
|
// return i->multiInstanceLockPath;
|
|
// }
|
|
//
|
|
// void
|
|
// avdInfo_getSkinInfo( const AvdInfo* i, char** pSkinName, char** pSkinDir )
|
|
// {
|
|
// char* skinName = NULL;
|
|
// char* skinPath;
|
|
// char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
|
|
//
|
|
// *pSkinName = NULL;
|
|
// *pSkinDir = NULL;
|
|
//
|
|
// if (!i->contentPath) {
|
|
// *pSkinName = ASTRDUP(SKIN_DEFAULT);
|
|
// return;
|
|
// }
|
|
//
|
|
// /* First, see if the config.ini contains a SKIN_PATH entry that
|
|
// * names the full directory path for the skin.
|
|
// */
|
|
// if (i->configIni != NULL ) {
|
|
// skinPath = iniFile_getString( i->configIni, SKIN_PATH, NULL );
|
|
// if (skinPath != NULL) {
|
|
// /* If this skin name is magic or a direct directory path
|
|
// * we have our result right here.
|
|
// */
|
|
// if (_getSkinPathFromName(skinPath, i->sdkRootPath,
|
|
// pSkinName, pSkinDir )) {
|
|
// AFREE(skinPath);
|
|
// return;
|
|
// }
|
|
// }
|
|
//
|
|
// /* The SKIN_PATH entry was not valid, so look at SKIN_NAME */
|
|
// D("Warning: " CORE_CONFIG_INI " contains invalid %s entry: %s",
|
|
// SKIN_PATH, skinPath);
|
|
// AFREE(skinPath);
|
|
//
|
|
// skinName = iniFile_getString( i->configIni, SKIN_NAME, NULL );
|
|
// }
|
|
//
|
|
// if (skinName == NULL) {
|
|
// /* If there is no skin listed in the config.ini, try to see if
|
|
// * there is one single 'skin' directory in the content directory.
|
|
// */
|
|
// p = bufprint(temp, end, "%s"PATH_SEP"skin", i->contentPath);
|
|
// if (p < end && _checkSkinPath(temp)) {
|
|
// D("using skin content from %s", temp);
|
|
// AFREE(i->skinName);
|
|
// *pSkinName = ASTRDUP("skin");
|
|
// *pSkinDir = ASTRDUP(i->contentPath);
|
|
// return;
|
|
// }
|
|
//
|
|
// if (i->configIni != NULL ) {
|
|
// /* We need to create a name.
|
|
// * Make a "magical" name using the screen size from config.ini
|
|
// * (parse_skin_files() in main-common-ui.c parses this name
|
|
// * to determine the screen size.)
|
|
// */
|
|
// int width = iniFile_getInteger(i->configIni, "hw.lcd.width", 0);
|
|
// int height = iniFile_getInteger(i->configIni, "hw.lcd.height", 0);
|
|
// if (width > 0 && height > 0) {
|
|
// char skinNameBuf[64];
|
|
// snprintf(skinNameBuf, sizeof skinNameBuf, "%dx%d", width, height);
|
|
// skinName = ASTRDUP(skinNameBuf);
|
|
// } else {
|
|
// skinName = ASTRDUP(SKIN_DEFAULT);
|
|
// }
|
|
// } else {
|
|
// skinName = ASTRDUP(SKIN_DEFAULT);
|
|
// }
|
|
// }
|
|
//
|
|
// /* now try to find the skin directory for that name -
|
|
// */
|
|
// do {
|
|
// /* first try the content directory, i.e. $CONTENT/skins/<name> */
|
|
// skinPath = _checkSkinSkinsDir(i->contentPath, skinName);
|
|
// if (skinPath != NULL)
|
|
// break;
|
|
//
|
|
// #define PREBUILT_SKINS_ROOT "development"PATH_SEP"tools"PATH_SEP"emulator"
|
|
//
|
|
// /* if we are in the Android build, try the prebuilt directory */
|
|
// if (i->inAndroidBuild) {
|
|
// p = bufprint( temp, end, "%s"PATH_SEP"%s",
|
|
// i->androidBuildRoot, PREBUILT_SKINS_ROOT );
|
|
// if (p < end) {
|
|
// skinPath = _checkSkinSkinsDir(temp, skinName);
|
|
// if (skinPath != NULL)
|
|
// break;
|
|
// }
|
|
//
|
|
// /* or in the parent directory of the system dir */
|
|
// {
|
|
// char* parentDir = path_parent(i->androidOut, 1);
|
|
// if (parentDir != NULL) {
|
|
// skinPath = _checkSkinSkinsDir(parentDir, skinName);
|
|
// AFREE(parentDir);
|
|
// if (skinPath != NULL)
|
|
// break;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// /* look in the search paths. For each <dir> in the list,
|
|
// * look into <dir>/../skins/<name>/ */
|
|
// {
|
|
// int nn;
|
|
// for (nn = 0; nn < i->numSearchPaths; nn++) {
|
|
// char* parentDir = path_parent(i->searchPaths[nn], 1);
|
|
// if (parentDir == NULL)
|
|
// continue;
|
|
// skinPath = _checkSkinSkinsDir(parentDir, skinName);
|
|
// AFREE(parentDir);
|
|
// if (skinPath != NULL)
|
|
// break;
|
|
// }
|
|
// if (nn < i->numSearchPaths)
|
|
// break;
|
|
// }
|
|
//
|
|
// /* We didn't find anything ! */
|
|
// *pSkinName = skinName;
|
|
// return;
|
|
//
|
|
// } while (0);
|
|
//
|
|
// if (path_split(skinPath, pSkinDir, pSkinName) < 0) {
|
|
// derror("weird skin path: %s", skinPath);
|
|
// AFREE(skinPath);
|
|
// return;
|
|
// }
|
|
// DD("found skin '%s' in directory: %s", *pSkinName, *pSkinDir);
|
|
// AFREE(skinPath);
|
|
// return;
|
|
// }
|
|
//
|
|
// char*
|
|
// avdInfo_getCharmapFile( const AvdInfo* i, const char* charmapName )
|
|
// {
|
|
// char fileNameBuff[PATH_MAX];
|
|
// const char* fileName;
|
|
//
|
|
// if (charmapName == NULL || charmapName[0] == '\0')
|
|
// return NULL;
|
|
//
|
|
// if (strstr(charmapName, ".kcm") == NULL) {
|
|
// snprintf(fileNameBuff, sizeof fileNameBuff, "%s.kcm", charmapName);
|
|
// fileName = fileNameBuff;
|
|
// } else {
|
|
// fileName = charmapName;
|
|
// }
|
|
//
|
|
// return _avdInfo_getContentOrSdkFilePath(i, fileName);
|
|
// }
|
|
//
|
|
// AdbdCommunicationMode avdInfo_getAdbdCommunicationMode(const AvdInfo* i,
|
|
// bool isQemu2)
|
|
// {
|
|
// if (isQemu2) {
|
|
// // All qemu2-compatible system images support modern communication mode.
|
|
// return ADBD_COMMUNICATION_MODE_PIPE;
|
|
// }
|
|
//
|
|
// if (i->apiLevel < 16 || (i->apiLevel > 99 && !i->isMarshmallowOrHigher)) {
|
|
// // QEMU pipe for ADB communication was added in android-4.1.1_r1 API 16
|
|
// D("API < 16 or unknown, forcing ro.adb.qemud==0");
|
|
// return ADBD_COMMUNICATION_MODE_LEGACY;
|
|
// }
|
|
//
|
|
// // Ignore property file since all system images have been updated a long
|
|
// // time ago to support the pipe service for API level >= 16.
|
|
// return ADBD_COMMUNICATION_MODE_PIPE;
|
|
// }
|
|
//
|
|
// int avdInfo_getSnapshotPresent(const AvdInfo* i)
|
|
// {
|
|
// if (i->configIni == NULL) {
|
|
// return 0;
|
|
// } else {
|
|
// return iniFile_getBoolean(i->configIni, SNAPSHOT_PRESENT, "no");
|
|
// }
|
|
// }
|
|
//
|
|
// const FileData* avdInfo_getBootProperties(const AvdInfo* i) {
|
|
// return i->bootProperties;
|
|
// }
|
|
//
|
|
// const FileData* avdInfo_getBuildProperties(const AvdInfo* i) {
|
|
// return i->buildProperties;
|
|
// }
|
|
//
|
|
// CIniFile* avdInfo_getConfigIni(const AvdInfo* i) {
|
|
// return i->configIni;
|
|
// }
|
|
//
|
|
// int avdInfo_getSysImgIncrementalVersion(const AvdInfo* i) {
|
|
// return i->incrementalVersion;
|
|
// }
|
|
//
|
|
// const char* avdInfo_getTag(const AvdInfo* i) {
|
|
// char temp[PATH_MAX];
|
|
// char* tagId = "default";
|
|
// char* tagDisplay = "Default";
|
|
// if (i->configIni) {
|
|
// tagId = iniFile_getString(i->configIni, TAG_ID, "default");
|
|
// tagDisplay = iniFile_getString(i->configIni, TAG_DISPLAY, "Default");
|
|
// }
|
|
// snprintf(temp, PATH_MAX, "%s [%s]", tagId, tagDisplay);
|
|
// return ASTRDUP(temp);
|
|
// }
|
|
//
|
|
// const char* avdInfo_getSdCardSize(const AvdInfo* i) {
|
|
// return (i->configIni) ? iniFile_getString(i->configIni, SDCARD_SIZE, "")
|
|
// : NULL;
|
|
// }
|
|
//
|
|
// // Guest rendering is deprecated in future API level. This function controls
|
|
// // the current guest rendering blacklist status; particular builds of system
|
|
// // images and particular API levels cannot run guest rendering.
|
|
// bool avdInfo_sysImgGuestRenderingBlacklisted(const AvdInfo* i) {
|
|
// switch (i->apiLevel) {
|
|
// // Allow guest rendering for older API levels
|
|
// case 9:
|
|
// case 10:
|
|
// case 15:
|
|
// case 16:
|
|
// case 17:
|
|
// case 18:
|
|
// return false;
|
|
// // Disallow guest rendering for some problematic builds
|
|
// case 19:
|
|
// return i->incrementalVersion == 4087698;
|
|
// case 21:
|
|
// return i->incrementalVersion == 4088174;
|
|
// case 22:
|
|
// return i->incrementalVersion == 4088218;
|
|
// case 23:
|
|
// return i->incrementalVersion == 4088240;
|
|
// case 24:
|
|
// return i->incrementalVersion == 4088244;
|
|
// case 25:
|
|
// return i->incrementalVersion == 4153093;
|
|
// case 26:
|
|
// return i->incrementalVersion == 4074420;
|
|
// case 27:
|
|
// return false;
|
|
// // bug 111971822
|
|
// // Guest side Swiftshader becomes much harder to maintain
|
|
// // after SELinux changes that disallow executable memory.
|
|
// case 28:
|
|
// default:
|
|
// return true;
|
|
// }
|
|
// }
|
|
//
|
|
// void avdInfo_replaceDataPartitionSizeInConfigIni(AvdInfo* i, int64_t sizeBytes) {
|
|
// if (!i || !i->configIni) return;
|
|
// iniFile_setInt64(i->configIni, "disk.dataPartition.size", sizeBytes);
|
|
//
|
|
// char* iniPath = _avdInfo_getContentFilePath(i, CORE_CONFIG_INI);
|
|
// iniFile_saveToFile(i->configIni, iniPath);
|
|
// }
|
|
//
|
|
// bool avdInfo_isMarshmallowOrHigher(AvdInfo* i) {
|
|
// return i->isMarshmallowOrHigher;
|
|
// }
|
|
|
|
AvdInfo* avdInfo_newCustom(
|
|
const char* name,
|
|
int apiLevel,
|
|
const char* abi,
|
|
const char* arch,
|
|
bool isGoogleApis,
|
|
AvdFlavor flavor) {
|
|
|
|
AvdInfo* i = new AvdInfo;
|
|
memset(i, 0, sizeof(AvdInfo));
|
|
|
|
i->deviceName = strdup(name);
|
|
i->deviceId = strdup(name);
|
|
|
|
i->noChecks = true;
|
|
|
|
i->apiLevel = apiLevel;
|
|
i->targetAbi = strdup(abi);
|
|
i->targetArch = strdup(arch);
|
|
i->isGoogleApis = isGoogleApis;
|
|
i->flavor = flavor;
|
|
|
|
return i;
|
|
}
|