Build the opengl host support code
Bug: 171711491
Change-Id: Ie29cff78c68ee76ecb242679ba1a7bf63d0ea318
diff --git a/base/ArraySize.h b/base/ArraySize.h
index 6f04107..9650e67 100644
--- a/base/ArraySize.h
+++ b/base/ArraySize.h
@@ -27,6 +27,7 @@
#else
#include <array>
+#include <stddef.h>
namespace android {
namespace base {
diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt
index 7996b22..76ca1a2 100644
--- a/base/CMakeLists.txt
+++ b/base/CMakeLists.txt
@@ -6,6 +6,7 @@
CompressingStream.cpp
CpuTime.cpp
DecompressingStream.cpp
+ FileUtils.cpp
FunctorThread.cpp
GLObjectCounter.cpp
LayoutResolver.cpp
diff --git a/base/FileUtils.cpp b/base/FileUtils.cpp
new file mode 100644
index 0000000..d30d95b
--- /dev/null
+++ b/base/FileUtils.cpp
@@ -0,0 +1,98 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#include "base/FileUtils.h"
+#include "base/EintrWrapper.h"
+
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#ifdef _MSC_VER
+#include "msvc-posix.h"
+#else
+#include <unistd.h>
+#endif
+
+#ifdef _WIN32
+#include <io.h>
+#endif
+
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <utility>
+
+namespace android {
+
+bool readFileIntoString(int fd, std::string* file_contents) {
+#ifdef _MSC_VER
+ if (fd < 0) return false; // msvc does not handle fd -1 very well.
+#endif
+
+ off_t size = lseek(fd, 0, SEEK_END);
+ if (size == (off_t)-1) {
+ return false;
+ }
+ off_t err = lseek(fd, 0, SEEK_SET);
+ if (err == (off_t)-1) {
+ return false;
+ }
+
+ std::string buf((size_t)size, '\0');
+ ssize_t result = HANDLE_EINTR(read(fd, &buf[0], size));
+ if (result != size) {
+ return false;
+ }
+ *file_contents = std::move(buf);
+ return true;
+}
+
+bool writeStringToFile(int fd, const std::string& file_contents) {
+#ifdef _MSC_VER
+ // msvc does not handle fd -1 very well.
+ if (fd < 0) return false;
+
+ ssize_t result = HANDLE_EINTR(
+ _write(fd, file_contents.c_str(), file_contents.size()));
+#else
+ ssize_t result = HANDLE_EINTR(
+ write(fd, file_contents.c_str(), file_contents.size()));
+#endif
+ if (result != (ssize_t)file_contents.size()) {
+ return false;
+ }
+ return true;
+}
+
+base::Optional<std::string> readFileIntoString(const std::string& name) {
+ std::ifstream is(name, std::ios_base::binary);
+ if (!is) {
+ return {};
+ }
+
+ std::ostringstream ss;
+ ss << is.rdbuf();
+ return ss.str();
+}
+
+bool setFileSize(int fd, int64_t size) {
+#ifdef _WIN32
+#ifdef _MSC_VER
+ if (fd < 0) return false; // msvc does not handle fd -1 very well.
+#endif
+ return _chsize_s(fd, size) == 0;
+#else
+ return ftruncate(fd, size) == 0;
+#endif
+}
+
+} // namespace android
diff --git a/base/FileUtils.h b/base/FileUtils.h
new file mode 100644
index 0000000..91dfc7c
--- /dev/null
+++ b/base/FileUtils.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#pragma once
+
+#include "base/Optional.h"
+
+#include <string>
+
+namespace android {
+
+// Reads from |fd| into |file_contents|
+// Returns false if something went wrong
+bool readFileIntoString(int fd, std::string* file_contents);
+
+// Reads |name| file
+base::Optional<std::string> readFileIntoString(const std::string& filename);
+
+// Writes |file_contents| to |fd|
+// Returns false if something went wrong
+bool writeStringToFile(int fd, const std::string& file_contents);
+
+// Sets the file size to |size|, could either extend or truncate it.
+bool setFileSize(int fd, int64_t size);
+
+} // namespace android
diff --git a/base/FileUtils_unittest.cpp b/base/FileUtils_unittest.cpp
new file mode 100644
index 0000000..d975f6e
--- /dev/null
+++ b/base/FileUtils_unittest.cpp
@@ -0,0 +1,89 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#include "android/base/misc/FileUtils.h"
+
+#include "android/base/files/ScopedFd.h"
+#include "android/utils/eintr_wrapper.h"
+#include "android/utils/file_io.h"
+#include "android/utils/tempfile.h"
+
+#include <fcntl.h>
+#include <gtest/gtest.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <limits>
+#include <string>
+
+using android::base::ScopedFd;
+
+namespace android {
+
+TEST(FileUtils, stringToFile) {
+ const char test_pattern[] = "test pattern";
+ TempFile* tf = tempfile_create();
+
+ ScopedFd fd(HANDLE_EINTR(open(tempfile_path(tf), O_RDWR, 0600)));
+ EXPECT_NE(-1, fd.get());
+
+ EXPECT_FALSE(writeStringToFile(-1, test_pattern));
+ EXPECT_TRUE(writeStringToFile(fd.get(), test_pattern));
+
+ std::string dummy_buffer("dummy");
+ EXPECT_FALSE(readFileIntoString(-1, &dummy_buffer));
+ EXPECT_STREQ("dummy", dummy_buffer.c_str());
+
+ std::string read_buffer;
+ EXPECT_TRUE(readFileIntoString(fd.get(), &read_buffer));
+ EXPECT_STREQ(test_pattern, read_buffer.c_str());
+
+ fd.close();
+
+ auto readFailedRes = readFileIntoString("!@#%R#$%W$*@#$*");
+ EXPECT_FALSE(readFailedRes);
+
+ auto readSucceededRes = readFileIntoString(tempfile_path(tf));
+ EXPECT_TRUE(readSucceededRes);
+ EXPECT_STREQ(test_pattern, readSucceededRes->c_str());
+
+ tempfile_close(tf);
+}
+
+// Tests readFileIntoString
+TEST(FileUtils, fileToString) {
+ const int bytesToTest = 100;
+
+ std::vector<uint8_t> testPattern;
+
+ for (int i = 0; i < bytesToTest; i++) {
+ testPattern.push_back(i % 3 == 0 ? 0x0 : 0x1a);
+ }
+
+ TempFile* tf = tempfile_create();
+
+ ScopedFd fd(HANDLE_EINTR(open(tempfile_path(tf), O_RDWR, 0600)));
+ EXPECT_NE(-1, fd.get());
+
+ HANDLE_EINTR(write(fd.get(), testPattern.data(), bytesToTest));
+
+ fd.close();
+
+ const auto testOutput = readFileIntoString(tempfile_path(tf));
+
+ EXPECT_TRUE(testOutput);
+ EXPECT_EQ(bytesToTest, testOutput->size());
+
+ for (int i = 0; i < bytesToTest; i++) {
+ EXPECT_EQ((char)testPattern[i], (char)testOutput->at(i));
+ }
+}
+
+} // namespace android
diff --git a/base/ScopedFd.h b/base/ScopedFd.h
new file mode 100644
index 0000000..ee6035e
--- /dev/null
+++ b/base/ScopedFd.h
@@ -0,0 +1,87 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#pragma once
+
+#include "base/Compiler.h"
+
+#include <errno.h>
+#ifdef _MSC_VER
+#include "msvc-posix.h"
+#else
+#include <unistd.h>
+#endif
+
+namespace android {
+namespace base {
+
+// Helper class to hold an integer file descriptor, and have the 'close'
+// function called automatically on scope exit, unless the 'release'
+// method was called previously.
+class ScopedFd {
+public:
+ // Default constructor will hold an invalid descriptor.
+ ScopedFd() : fd_(-1) {}
+
+ // Constructor takes ownership of |fd|.
+ explicit ScopedFd(int fd) : fd_(fd) {}
+
+ // Make it movable.
+ ScopedFd(ScopedFd&& other) : fd_(other.fd_) {
+ other.fd_ = -1;
+ }
+
+ ScopedFd& operator=(ScopedFd&& other) {
+ swap(&other);
+ return *this;
+ }
+
+ // Destructor calls close().
+ ~ScopedFd() { close(); }
+
+ // Return the file descriptor value, does _not_ transfer ownership.
+ int get() const { return fd_; }
+
+ // Return the file descriptor value, transfers ownership to the caller.
+ int release() {
+ int fd = fd_;
+ fd_ = -1;
+ return fd;
+ }
+
+ // Return true iff the file descriptor is valid.
+ bool valid() const { return fd_ >= 0; }
+
+ // Close the file descriptor (and make the wrapped value invalid).
+ void close() {
+ if (fd_ != -1) {
+ int save_errno = errno;
+ ::close(fd_);
+ fd_ = -1;
+ errno = save_errno;
+ }
+ }
+
+ // Swap two ScopedFd instances.
+ void swap(ScopedFd* other) {
+ int fd = fd_;
+ fd_ = other->fd_;
+ other->fd_ = fd;
+ }
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedFd);
+
+ int fd_;
+};
+
+} // namespace base
+} // namespace android
diff --git a/base/ScopedFd_unittest.cpp b/base/ScopedFd_unittest.cpp
new file mode 100644
index 0000000..10c38c3
--- /dev/null
+++ b/base/ScopedFd_unittest.cpp
@@ -0,0 +1,80 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#include "android/base/files/ScopedFd.h"
+
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace base {
+
+namespace {
+
+// The path of a file that can always be opened for reading on any platform.
+#ifdef _WIN32
+static const char kNullFile[] = "NUL";
+#else
+static const char kNullFile[] = "/dev/null";
+#endif
+
+int OpenNull() {
+ return ::open(kNullFile, O_RDONLY);
+}
+
+} // namespace
+
+TEST(ScopedFd, DefaultConstructor) {
+ ScopedFd f;
+ EXPECT_FALSE(f.valid());
+ EXPECT_EQ(-1, f.get());
+}
+
+TEST(ScopedFd, Constructor) {
+ ScopedFd f(OpenNull());
+ EXPECT_TRUE(f.valid());
+}
+
+TEST(ScopedFd, Release) {
+ ScopedFd f(OpenNull());
+ EXPECT_TRUE(f.valid());
+ int fd = f.release();
+ EXPECT_FALSE(f.valid());
+ EXPECT_NE(-1, fd);
+ ::close(fd);
+}
+
+TEST(ScopedFd, Close) {
+ ScopedFd f(OpenNull());
+ EXPECT_TRUE(f.valid());
+ f.close();
+ EXPECT_FALSE(f.valid());
+}
+
+TEST(ScopedFd, Swap) {
+ ScopedFd f1;
+ ScopedFd f2(OpenNull());
+ EXPECT_FALSE(f1.valid());
+ EXPECT_TRUE(f2.valid());
+ int fd = f2.get();
+ f1.swap(&f2);
+ EXPECT_FALSE(f2.valid());
+ EXPECT_TRUE(f1.valid());
+ EXPECT_EQ(fd, f1.get());
+}
+
+
+} // namespace base
+} // namespace android
diff --git a/host-common/CMakeLists.txt b/host-common/CMakeLists.txt
index ef6d093..dbb7f0b 100644
--- a/host-common/CMakeLists.txt
+++ b/host-common/CMakeLists.txt
@@ -1,6 +1,20 @@
+if (APPLE)
+ set(gfxstream-host-common-opengles-platform-sources
+ opengl/macTouchOpengl.m
+ opengl/NativeGpuInfo_darwin.cpp)
+elseif (WIN32)
+ set(gfxstream-host-common-opengles-platform-sources
+ opengl/NativeGpuInfo_windows.cpp)
+else()
+ set(gfxstream-host-common-opengles-platform-sources
+ opengl/NativeGpuInfo_linux.cpp)
+endif()
+
add_library(
gfxstream-host-common
STATIC
+
+ # emugl glue
address_space_device_control_ops.cpp
crash_reporter.cpp
vm_operations.cpp
@@ -8,9 +22,35 @@
dma_device.cpp
sync_device.cpp
misc.cpp
- window_operations.cpp)
+ window_operations.cpp
+
+
+ # What used to be android-emu
+ HostmemIdMapping.cpp
+
+ # android-emu avd globals
+ avd/info.cpp
+
+ # general opengles host stuff, incl process pipe
+ # and opengl es pipe
+ opengles.cpp
+ opengl/EmuglBackendList.cpp
+ # opengl/EmuglBackendList_unittest.cpp
+ opengl/emugl_config.cpp
+ # opengl/emugl_config_unittest.cpp
+ opengl/GLProcessPipe.cpp
+ opengl/GpuFrameBridge.cpp
+ # opengl/GpuFrameBridge_unittest.cpp
+ opengl/gpuinfo.cpp
+ # opengl/gpuinfo_unittest.cpp
+ opengl/logger.cpp
+ opengl/OpenglEsPipe.cpp
+ ${gfxstream-host-common-opengles-platform-sources}
+
+ )
target_include_directories(
gfxstream-host-common
PRIVATE
${GFXSTREAM_REPO_ROOT}
+ ${GFXSTREAM_REPO_ROOT}/include
${GFXSTREAM_REPO_ROOT}/stream-servers)
diff --git a/host-common/HostmemIdMapping.cpp b/host-common/HostmemIdMapping.cpp
index c859ea4..56d9835 100644
--- a/host-common/HostmemIdMapping.cpp
+++ b/host-common/HostmemIdMapping.cpp
@@ -26,7 +26,7 @@
// static
HostmemIdMapping* HostmemIdMapping::get() {
- return sMapping.ptr();
+ return sMapping();
}
// TODO: Add registerHostmemFixed version that takes a predetermined id,
diff --git a/host-common/avd/info.c b/host-common/avd/info.c
deleted file mode 100644
index 4fba5b8..0000000
--- a/host-common/avd/info.c
+++ /dev/null
@@ -1,2069 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/avd/info.h"
-
-#include "android/android.h"
-#include "android/avd/util.h"
-#include "android/avd/keys.h"
-#include "android/base/ArraySize.h"
-#include "android/base/export.h"
-#include "android/cmdline-option.h"
-#include "android/emulation/bufprint_config_dirs.h"
-#include "android/featurecontrol/feature_control.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/debug.h"
-#include "android/utils/dirscanner.h"
-#include "android/utils/file_data.h"
-#include "android/utils/filelock.h"
-#include "android/utils/path.h"
-#include "android/utils/property_file.h"
-#include "android/utils/string.h"
-#include "android/utils/tempfile.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;
- ANEW0(i);
- str_reset(&i->deviceName, name);
- str_reset(&i->deviceId, name);
- i->noChecks = true;
-
- i->apiLevel = apiLevel;
- i->targetAbi = strdup(abi);
- i->targetArch = strdup(arch);
- i->isGoogleApis = isGoogleApis;
- i->flavor = flavor;
-
- return i;
-}
-
-void avdInfo_setCustomContentPath(AvdInfo* info, const char* path) {
- info->contentPath = strdup(path);
-}
-
-void avdInfo_setCustomCoreHwIniPath(AvdInfo* info, const char* path) {
- info->coreHardwareIniPath = strdup(path);
-}
-
-void avdInfo_replaceMultiDisplayInConfigIni(AvdInfo* i, int index,
- int x, int y,
- int w, int h,
- int dpi, int flag ) {
- if (!i || !i->configIni) return;
-
-// char x_s[] = "hw.display0.xOffset";
-// char y_s[] = "hw.display0.yOffset";
- char w_s[] = "hw.display0.width";
- char h_s[] = "hw.display0.height";
- char d_s[] = "hw.display0.density";
- char f_s[] = "hw.display0.flag";
- bool write = false;
-
-// x_s[10] += index;
-// y_s[10] += index;
- w_s[10] += index;
- h_s[10] += index;
- d_s[10] += index;
- f_s[10] += index;
-
-// if (iniFile_getInteger(i->configIni, x_s, -1) != x) {
-// iniFile_setInteger(i->configIni, x_s, x);
-// write = true;
-// }
-// if (iniFile_getInteger(i->configIni, y_s, -1) != y) {
-// iniFile_setInteger(i->configIni, y_s, y);
-// write = true;
-// }
- if (iniFile_getInteger(i->configIni, w_s, 0) != w) {
- iniFile_setInteger(i->configIni, w_s, w);
- write = true;
- }
- if (iniFile_getInteger(i->configIni, h_s, 0) != h) {
- iniFile_setInteger(i->configIni, h_s, h);
- write = true;
- }
- if (iniFile_getInteger(i->configIni, d_s, 0) != dpi) {
- iniFile_setInteger(i->configIni, d_s, dpi);
- write = true;
- }
- if (iniFile_getInteger(i->configIni, f_s, 0) != flag) {
- iniFile_setInteger(i->configIni, f_s, flag);
- write = true;
- }
-
- char* iniPath = _avdInfo_getContentFilePath(i, CORE_CONFIG_INI);
- if (iniPath && write)
- iniFile_saveToFile(i->configIni, iniPath);
-}
-
-
diff --git a/host-common/avd/info.cpp b/host-common/avd/info.cpp
new file mode 100644
index 0000000..b9d11b9
--- /dev/null
+++ b/host-common/avd/info.cpp
@@ -0,0 +1,1998 @@
+/* Copyright (C) 2008 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+*/
+#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;
+}
diff --git a/host-common/opengl/EmuglBackendList.cpp b/host-common/opengl/EmuglBackendList.cpp
index f4d5bee..50bc220 100644
--- a/host-common/opengl/EmuglBackendList.cpp
+++ b/host-common/opengl/EmuglBackendList.cpp
@@ -9,13 +9,11 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-#include "android/opengl/EmuglBackendList.h"
+#include "EmuglBackendList.h"
-#include "android/base/Log.h"
-#include "android/base/StringFormat.h"
-#include "android/base/system/System.h"
-#include "android/opengl/EmuglBackendScanner.h"
-#include "android/utils/path.h"
+#include "base/StringFormat.h"
+#include "base/System.h"
+#include "base/PathUtils.h"
#define DEBUG 0
@@ -29,20 +27,6 @@
namespace android {
namespace opengl {
-using android::base::System;
-
-EmuglBackendList::EmuglBackendList(const char* execDir,
- int programBitness) :
- mDefaultName("auto"), mNames(), mProgramBitness(0), mExecDir(execDir) {
- // Fix host bitness if needed.
- if (!programBitness) {
- programBitness = System::get()->getProgramBitness();
- }
- mProgramBitness = programBitness;
-
- mNames = EmuglBackendScanner::scanDir(execDir, programBitness);
-}
-
EmuglBackendList::EmuglBackendList(int programBitness,
const std::vector<std::string>& names) :
mDefaultName("auto"), mNames(names), mProgramBitness(programBitness) { }
@@ -58,18 +42,14 @@
std::string EmuglBackendList::getLibDirPath(const char* name) {
// remove the "_indirect" suffix
- static constexpr android::base::StringView suffix("_indirect");
+ std::string suffix("_indirect");
std::string nameNoSuffix(name);
int nameNoSuffixLen = (int)nameNoSuffix.size() - (int)suffix.size();
if (nameNoSuffixLen > 0 &&
suffix == nameNoSuffix.c_str() + nameNoSuffixLen) {
nameNoSuffix.erase(nameNoSuffixLen);
}
- return android::base::StringFormat(
- "%s" PATH_SEP "%s" PATH_SEP "gles_%s",
- mExecDir,
- mProgramBitness == 64 ? "lib64" : "lib",
- nameNoSuffix.c_str());
+ return android::base::pj({mExecDir, "lib64", std::string("gles_%s") + nameNoSuffix});
}
#ifdef _WIN32
@@ -97,17 +77,9 @@
return false;
}
- std::string path = android::base::StringFormat(
- "%s" PATH_SEP "lib%s%s",
- getLibDirPath(name),
- libraryName,
- kLibSuffix);
+ std::string path = android::base::pj({
+ getLibDirPath(name), std::string("lib") + libraryName + kLibSuffix});
- if (!System::get()->pathIsFile(path)) {
- D("%s(name=%s lib=%s): File does not exist: %s\n",
- __FUNCTION__, name, libraryName, path.c_str());
- return false;
- }
*libPath = path;
return true;
}
diff --git a/host-common/opengl/EmuglBackendScanner.cpp b/host-common/opengl/EmuglBackendScanner.cpp
index 5de9215..0b2acdd 100644
--- a/host-common/opengl/EmuglBackendScanner.cpp
+++ b/host-common/opengl/EmuglBackendScanner.cpp
@@ -9,14 +9,10 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-#include "android/opengl/EmuglBackendScanner.h"
+#include "EmuglBackendScanner.h"
-#include "android/base/Log.h"
-#include "android/base/StringFormat.h"
-#include "android/base/system/System.h"
-#include "android/base/misc/StringUtils.h"
-
-#include "android/utils/path.h"
+#include "base/StringFormat.h"
+#include "base/System.h"
#include <algorithm>
#include <string>
@@ -26,20 +22,21 @@
namespace opengl {
using android::base::StringFormat;
-using android::base::System;
// static
std::vector<std::string> EmuglBackendScanner::scanDir(const char* execDir,
int programBitness) {
std::vector<std::string> names;
- if (!execDir || !System::get()->pathExists(execDir)) {
- LOG(ERROR) << "Invalid executable directory: " << execDir;
+ if (!execDir) {
+ fpritnf(stderr, "%s: invalid exec dir: %s\n", __func__, execDir);
return names;
}
+
if (!programBitness) {
programBitness = System::get()->getProgramBitness();
}
+
const char* subdir = (programBitness == 64) ? "lib64" : "lib";
std::string subDir = StringFormat("%s" PATH_SEP "%s" PATH_SEP, execDir, subdir);
diff --git a/host-common/opengl/GLProcessPipe.cpp b/host-common/opengl/GLProcessPipe.cpp
index 63c234f..e263423 100644
--- a/host-common/opengl/GLProcessPipe.cpp
+++ b/host-common/opengl/GLProcessPipe.cpp
@@ -9,13 +9,15 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-#include "android/emulation/AndroidPipe.h"
+#include "../AndroidPipe.h"
-#include "android/opengles.h"
+#include "../opengles.h"
#include <assert.h>
#include <atomic>
#include <memory>
+#include <string.h>
+
namespace android {
namespace opengl {
diff --git a/host-common/opengl/GpuFrameBridge.cpp b/host-common/opengl/GpuFrameBridge.cpp
index c6a2702..ea3c0d7 100644
--- a/host-common/opengl/GpuFrameBridge.cpp
+++ b/host-common/opengl/GpuFrameBridge.cpp
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "android/opengl/GpuFrameBridge.h"
+#include "GpuFrameBridge.h"
#include <stdio.h> // for printf
#include <stdlib.h> // for NULL, free, malloc
@@ -21,11 +21,9 @@
#include <atomic> // for atomic_bool, memory_o...
#include <memory> // for unique_ptr
-#include "android/base/async/Looper.h" // for Looper::Timer, Looper
-#include "android/base/async/ThreadLooper.h" // for ThreadLooper
-#include "android/base/synchronization/Lock.h" // for Lock, AutoLock
-#include "android/base/synchronization/MessageChannel.h"
-#include "android/opengles.h" // for android_getFlushReadP...
+#include "base/Lock.h" // for Lock, AutoLock
+#include "base/MessageChannel.h"
+#include "..//opengles.h" // for android_getFlushReadP...
#ifdef _WIN32
#undef ERROR
@@ -36,7 +34,6 @@
using android::base::AutoLock;
using android::base::Lock;
-using android::base::Looper;
using android::base::MessageChannel;
namespace {
@@ -90,20 +87,20 @@
}
}
- virtual void setLooper(android::base::Looper* aLooper) override {
- mTimer = std::unique_ptr<android::base::Looper::Timer>(
- aLooper->createTimer(_on_frame_notify, this));
- }
+ // virtual void setLooper(android::base::Looper* aLooper) override {
+ // mTimer = std::unique_ptr<android::base::Looper::Timer>(
+ // aLooper->createTimer(_on_frame_notify, this));
+ // }
void notify() {
AutoLock delay(mDelayLock);
switch (mDelayCallback) {
case FrameDelay::Reschedule:
- mTimer->startRelative(kFrameDelayMs);
+ // mTimer->startRelative(kFrameDelayMs);
mDelayCallback = FrameDelay::Scheduled;
break;
case FrameDelay::Scheduled:
- mTimer->stop();
+ // mTimer->stop();
mDelayCallback = FrameDelay::Firing;
delay.unlock();
mFlushPixelPipeline(mDisplayId);
@@ -113,11 +110,11 @@
}
}
- static void _on_frame_notify(void* opaque,
- android::base::Looper::Timer* timer) {
- Bridge* worker = static_cast<Bridge*>(opaque);
- worker->notify();
- }
+ // static void _on_frame_notify(void* opaque,
+ // android::base::Looper::Timer* timer) {
+ // Bridge* worker = static_cast<Bridge*>(opaque);
+ // worker->notify();
+ // }
// Implementation of the GpuFrameBridge::postRecordFrame() method, must be
// called from the EmuGL thread.
@@ -196,7 +193,7 @@
AutoLock delay(mDelayLock);
switch (mDelayCallback) {
case FrameDelay::NotScheduled:
- mTimer->startRelative(kFrameDelayMs);
+ // mTimer->startRelative(kFrameDelayMs);
mDelayCallback = FrameDelay::Scheduled;
break;
case FrameDelay::Firing:
@@ -231,7 +228,7 @@
uint32_t mDisplayId = 0;
FlushReadPixelPipeline mFlushPixelPipeline = 0;
- std::unique_ptr<android::base::Looper::Timer> mTimer;
+ // std::unique_ptr<android::base::Looper::Timer> mTimer;
Lock mDelayLock;
FrameDelay mDelayCallback{FrameDelay::NotScheduled};
};
diff --git a/host-common/opengl/GpuFrameBridge.h b/host-common/opengl/GpuFrameBridge.h
index 083004f..03bc1d5 100644
--- a/host-common/opengl/GpuFrameBridge.h
+++ b/host-common/opengl/GpuFrameBridge.h
@@ -15,7 +15,6 @@
#pragma once
#include <cstdint>
-#include "android/base/async/Looper.h"
class Looper;
namespace android {
@@ -67,7 +66,7 @@
virtual void setDisplayId(uint32_t displayId) = 0;
- virtual void setLooper(android::base::Looper* aLooper) = 0;
+ // virtual void setLooper(android::base::Looper* aLooper) = 0;
protected:
GpuFrameBridge() {}
diff --git a/host-common/opengl/NativeGpuInfo.h b/host-common/opengl/NativeGpuInfo.h
index 07753a3..d5b96e0 100644
--- a/host-common/opengl/NativeGpuInfo.h
+++ b/host-common/opengl/NativeGpuInfo.h
@@ -14,7 +14,7 @@
#pragma once
-#include "android/opengl/gpuinfo.h"
+#include "gpuinfo.h"
void getGpuInfoListNative(GpuInfoList*);
diff --git a/host-common/opengl/NativeGpuInfo_linux.cpp b/host-common/opengl/NativeGpuInfo_linux.cpp
index 98a0154..1641133 100644
--- a/host-common/opengl/NativeGpuInfo_linux.cpp
+++ b/host-common/opengl/NativeGpuInfo_linux.cpp
@@ -12,32 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "android/opengl/NativeGpuInfo.h"
+#include "NativeGpuInfo.h"
-#include "android/base/StringView.h"
-#include "android/base/files/PathUtils.h"
-#include "android/base/files/ScopedFd.h"
-#include "android/base/memory/ScopedPtr.h"
-#include "android/base/misc/FileUtils.h"
-#include "android/base/system/System.h"
+#include "base/PathUtils.h"
+#include "base/ScopedFd.h"
+#include "base/FileUtils.h"
+#include "base/System.h"
#include <string>
-using android::base::makeCustomScopedPtr;
using android::base::PathUtils;
-using android::base::RunOptions;
using android::base::ScopedFd;
-using android::base::StringView;
-using android::base::System;
static const int kGPUInfoQueryTimeoutMs = 5000;
-static std::string load_gpu_info() {
- // Execute the command to get GPU info.
- return System::get()
- ->runCommandWithResult({"lspci", "-mvnn"}, kGPUInfoQueryTimeoutMs)
- .valueOr({});
-}
+// static std::string load_gpu_info() {
+// // Execute the command to get GPU info.
+// return System::get()
+// ->runCommandWithResult({"lspci", "-mvnn"}, kGPUInfoQueryTimeoutMs)
+// .valueOr({});
+// }
static std::string parse_last_hexbrackets(const std::string& str) {
size_t closebrace_p = str.rfind("]");
@@ -91,6 +85,7 @@
}
void getGpuInfoListNative(GpuInfoList* gpulist) {
+ (void)gpulist;
// Load it in a traditional way - by parsing output of external process.
// TODO: Don't do GPU info detection on Linux for now---lspci can be
@@ -98,9 +93,9 @@
#ifdef ANDROID_DEBUG
// Workaround for b/77586363, clang -O0 introduces some unexpected behavior
// when it comes to the else. See the bug for details
- load_gpu_info();
+ // load_gpu_info();
#else
- (void)load_gpu_info; // Make Werror happy
+ // (void)load_gpu_info; // Make Werror happy
#endif
// std::string gpu_info = load_gpu_info();
// parse_gpu_info_list_linux(gpu_info, gpulist);
diff --git a/host-common/opengl/OpenglEsPipe.cpp b/host-common/opengl/OpenglEsPipe.cpp
index dc14907..581972c 100644
--- a/host-common/opengl/OpenglEsPipe.cpp
+++ b/host-common/opengl/OpenglEsPipe.cpp
@@ -8,22 +8,21 @@
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-#include "android/opengl/OpenglEsPipe.h"
+#include "OpenglEsPipe.h"
-#include "android/base/Optional.h"
-#include "android/base/Stopwatch.h"
-#include "android/base/async/Looper.h"
-#include "android/base/files/PathUtils.h"
-#include "android/base/files/StreamSerializing.h"
-#include "android/base/threads/FunctorThread.h"
-#include "android/globals.h"
-#include "android/loadpng.h"
-#include "android/opengl/GLProcessPipe.h"
-#include "android/opengles-pipe.h"
-#include "android/opengles.h"
-#include "android/snapshot/Loader.h"
-#include "android/snapshot/Saver.h"
-#include "android/snapshot/Snapshotter.h"
+#include "base/Optional.h"
+#include "base/PathUtils.h"
+#include "base/StreamSerializing.h"
+#include "base/FunctorThread.h"
+#include "base/System.h"
+#include "../globals.h"
+// #include "loadpng.h"
+#include "GLProcessPipe.h"
+#include "../opengles-pipe.h"
+#include "../opengles.h"
+// #include "snapshot/Loader.h"
+// #include "snapshot/Saver.h"
+// #include "snapshot/Snapshotter.h"
#include <atomic>
@@ -51,8 +50,8 @@
using emugl::RenderChannelPtr;
using ChannelState = emugl::RenderChannel::State;
using IoResult = emugl::RenderChannel::IoResult;
-using android::base::Stopwatch;
-using android::snapshot::Snapshotter;
+// using android::base::Stopwatch;
+// using android::snapshot::Snapshotter;
#define OPENGL_SAVE_VERSION 1
@@ -88,25 +87,25 @@
bool canLoad() const override { return true; }
virtual void preLoad(android::base::Stream* stream) override {
-#ifdef SNAPSHOT_PROFILE
- mLoadMeter.restartUs();
-#endif
- const bool hasRenderer = stream->getByte();
- const auto& renderer = android_getOpenglesRenderer();
- if (hasRenderer != (bool)renderer) {
- // die?
- return;
- }
- if (!hasRenderer) {
- return;
- }
- int version = stream->getBe32();
- (void)version;
- renderer->load(stream, Snapshotter::get().loader().textureLoader());
-#ifdef SNAPSHOT_PROFILE
- printf("OpenglEs preload time: %lld ms\n",
- (long long)(mLoadMeter.elapsedUs() / 1000));
-#endif
+// #ifdef SNAPSHOT_PROFILE
+// mLoadMeter.restartUs();
+// #endif
+// const bool hasRenderer = stream->getByte();
+// const auto& renderer = android_getOpenglesRenderer();
+// if (hasRenderer != (bool)renderer) {
+// // die?
+// return;
+// }
+// if (!hasRenderer) {
+// return;
+// }
+// int version = stream->getBe32();
+// (void)version;
+// renderer->load(stream, Snapshotter::get().loader().textureLoader());
+// #ifdef SNAPSHOT_PROFILE
+// printf("OpenglEs preload time: %lld ms\n",
+// (long long)(mLoadMeter.elapsedUs() / 1000));
+// #endif
}
void postLoad(android::base::Stream* stream) override {
@@ -120,20 +119,20 @@
}
void preSave(android::base::Stream* stream) override {
-#ifdef SNAPSHOT_PROFILE
- mSaveMeter.restartUs();
-#endif
- if (const auto& renderer = android_getOpenglesRenderer()) {
- renderer->pauseAllPreSave();
- stream->putByte(1);
- stream->putBe32(OPENGL_SAVE_VERSION);
- renderer->save(stream,
- Snapshotter::get().saver().textureSaver());
-
- writeScreenshot(*renderer);
- } else {
- stream->putByte(0);
- }
+// #ifdef SNAPSHOT_PROFILE
+// mSaveMeter.restartUs();
+// #endif
+// if (const auto& renderer = android_getOpenglesRenderer()) {
+// renderer->pauseAllPreSave();
+// stream->putByte(1);
+// stream->putBe32(OPENGL_SAVE_VERSION);
+// renderer->save(stream,
+// Snapshotter::get().saver().textureSaver());
+//
+// writeScreenshot(*renderer);
+// } else {
+// stream->putByte(0);
+// }
}
void postSave(android::base::Stream* stream) override {
@@ -176,59 +175,59 @@
}
void writeScreenshot(emugl::Renderer& renderer) {
-#if SNAPSHOT_PROFILE > 1
- Stopwatch sw;
-#endif
- if (!mSnapshotCallbackRegistered) {
- // We have to wait for the screenshot saving thread, but
- // there's no need to join it too soon: it is ok to only
- // block when the rest of snapshot saving is complete.
- Snapshotter::get().addOperationCallback(
- [this](Snapshotter::Operation op,
- Snapshotter::Stage stage) {
- if (op == Snapshotter::Operation::Save &&
- stage == Snapshotter::Stage::End) {
- if (mScreenshotSaver) {
- mScreenshotSaver->wait();
- mScreenshotSaver.clear();
- }
- }
- });
- mSnapshotCallbackRegistered = true;
- }
- // always do 4 channel screenshot because swiftshader_indirect
- // has issues with 3 channels
- const unsigned int nChannels = 4;
- unsigned int width;
- unsigned int height;
- std::vector<unsigned char> pixels;
- renderer.getScreenshot(nChannels, &width, &height, pixels);
-#if SNAPSHOT_PROFILE > 1
- printf("Screenshot load texture time %lld ms\n",
- (long long)(sw.elapsedUs() / 1000));
-#endif
- if (width > 0 && height > 0) {
- std::string dataDir =
- Snapshotter::get().saver().snapshot().dataDir();
- mScreenshotSaver.emplace([nChannels, width, height,
- dataDir = std::move(dataDir),
- pixels = std::move(pixels)] {
-#if SNAPSHOT_PROFILE > 1
- Stopwatch sw;
-#endif
- std::string fileName = android::base::PathUtils::join(
- dataDir, "screenshot.png");
- // TODO: fix the screenshot rotation?
- savepng(fileName.c_str(), nChannels, width, height,
- SKIN_ROTATION_0,
- const_cast<unsigned char*>(pixels.data()));
-#if SNAPSHOT_PROFILE > 1
- printf("Screenshot image write time %lld ms\n",
- (long long)(sw.elapsedUs() / 1000));
-#endif
- });
- mScreenshotSaver->start();
- }
+// #if SNAPSHOT_PROFILE > 1
+// Stopwatch sw;
+// #endif
+// if (!mSnapshotCallbackRegistered) {
+// // We have to wait for the screenshot saving thread, but
+// // there's no need to join it too soon: it is ok to only
+// // block when the rest of snapshot saving is complete.
+// // Snapshotter::get().addOperationCallback(
+// // [this](Snapshotter::Operation op,
+// // Snapshotter::Stage stage) {
+// // if (op == Snapshotter::Operation::Save &&
+// // stage == Snapshotter::Stage::End) {
+// // if (mScreenshotSaver) {
+// // mScreenshotSaver->wait();
+// // mScreenshotSaver.clear();
+// // }
+// // }
+// // });
+// mSnapshotCallbackRegistered = true;
+// }
+// // always do 4 channel screenshot because swiftshader_indirect
+// // has issues with 3 channels
+// const unsigned int nChannels = 4;
+// unsigned int width;
+// unsigned int height;
+// std::vector<unsigned char> pixels;
+// renderer.getScreenshot(nChannels, &width, &height, pixels);
+// #if SNAPSHOT_PROFILE > 1
+// printf("Screenshot load texture time %lld ms\n",
+// (long long)(sw.elapsedUs() / 1000));
+// #endif
+// if (width > 0 && height > 0) {
+// std::string dataDir =
+// Snapshotter::get().saver().snapshot().dataDir();
+// mScreenshotSaver.emplace([nChannels, width, height,
+// dataDir = std::move(dataDir),
+// pixels = std::move(pixels)] {
+// #if SNAPSHOT_PROFILE > 1
+// Stopwatch sw;
+// #endif
+// std::string fileName = android::base::PathUtils::join(
+// dataDir, "screenshot.png");
+// // TODO: fix the screenshot rotation?
+// savepng(fileName.c_str(), nChannels, width, height,
+// SKIN_ROTATION_0,
+// const_cast<unsigned char*>(pixels.data()));
+// #if SNAPSHOT_PROFILE > 1
+// printf("Screenshot image write time %lld ms\n",
+// (long long)(sw.elapsedUs() / 1000));
+// #endif
+// });
+// mScreenshotSaver->start();
+// }
}
bool mSnapshotCallbackRegistered = false;
@@ -320,7 +319,7 @@
int len = 0;
size_t buffOffset = 0;
- static constexpr android::base::System::Duration kBlockReportIntervalUs = 1000000ULL;
+ static constexpr uint64_t kBlockReportIntervalUs = 1000000ULL;
auto buff = buffers;
const auto buffEnd = buff + numBuffers;
while (buff != buffEnd) {
@@ -369,10 +368,10 @@
// the guest block on work that takes a significant
// amount of time.
- static constexpr android::base::System::Duration kBlockReportIntervalUs = 1000000ULL;
+ static constexpr uint64_t kBlockReportIntervalUs = 1000000ULL;
const RenderChannel::Duration kBlockAtMostUs = 100;
- auto currTime = android::base::System::get()->getUnixTimeUs();
+ auto currTime = android::base::getUnixTimeUs();
auto result = mChannel->readBefore(&mDataForReading, currTime + kBlockAtMostUs);
if (result != IoResult::Ok) {
@@ -407,14 +406,14 @@
// the guest block on work that takes a significant
// amount of time.
- static constexpr android::base::System::Duration kBlockReportIntervalUs = 1000000ULL;
+ static constexpr uint64_t kBlockReportIntervalUs = 1000000ULL;
- auto currUs = android::base::System::get()->getHighResTimeUs();
+ auto currUs = android::base::getHighResTimeUs();
const RenderChannel::Duration kBlockAtMostUs = 10000;
- auto currTime = android::base::System::get()->getUnixTimeUs();
+ auto currTime = android::base::getUnixTimeUs();
auto result = mChannel->readBefore(&mDataForReading, currTime + kBlockAtMostUs);
- auto nextUs = android::base::System::get()->getHighResTimeUs();
+ auto nextUs = android::base::getHighResTimeUs();
if (result != IoResult::Ok) {
DD("%s: tryRead() failed with %d", __func__, (int)result);
diff --git a/host-common/opengl/OpenglEsPipe.h b/host-common/opengl/OpenglEsPipe.h
index 60cc9b9..f5f298a 100644
--- a/host-common/opengl/OpenglEsPipe.h
+++ b/host-common/opengl/OpenglEsPipe.h
@@ -10,10 +10,10 @@
// GNU General Public License for more details.
#pragma once
-#include "android/base/Compiler.h"
-#include "android/emulation/AndroidPipe.h"
+#include "base/Compiler.h"
+#include "..//AndroidPipe.h"
-#include "OpenglRender/RenderChannel.h"
+#include "../../stream-servers/RenderChannel.h"
namespace android {
namespace opengl {
diff --git a/host-common/opengl/emugl_config.cpp b/host-common/opengl/emugl_config.cpp
index b012e2d..438442f 100644
--- a/host-common/opengl/emugl_config.cpp
+++ b/host-common/opengl/emugl_config.cpp
@@ -9,15 +9,14 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-#include "android/opengl/emugl_config.h"
-#include "android/opengl/gpuinfo.h"
+#include "emugl_config.h"
+#include "gpuinfo.h"
-#include "android/base/StringFormat.h"
+#include "base/StringFormat.h"
#include "base/System.h"
-#include "android/crashreport/crash-handler.h"
-#include "android/globals.h"
-#include "android/opengl/EmuglBackendList.h"
-#include "android/skin/winsys.h"
+#include "../globals.h"
+#include "../misc.h"
+#include "EmuglBackendList.h"
#include <string>
@@ -32,28 +31,22 @@
#if DEBUG
#define D(...) printf(__VA_ARGS__)
#else
-#define D(...) crashhandler_append_message_format(__VA_ARGS__)
+// #define D(...) crashhandler_append_message_format(__VA_ARGS__)
+#define D(...)
#endif
-using android::base::RunOptions;
using android::base::StringFormat;
-using android::base::System;
using android::opengl::EmuglBackendList;
static EmuglBackendList* sBackendList = NULL;
static void resetBackendList(int bitness) {
delete sBackendList;
- if (System::getEnvironmentVariable("ANDROID_EMUGL_FIXED_BACKEND_LIST") == "1") {
- std::vector<std::string> fixedBackendNames = {
- "swiftshader_indirect",
- "angle_indirect",
- };
- sBackendList = new EmuglBackendList(64, fixedBackendNames);
- } else {
- sBackendList = new EmuglBackendList(
- System::get()->getLauncherDirectory().c_str(), bitness);
- }
+ std::vector<std::string> fixedBackendNames = {
+ "swiftshader_indirect",
+ "angle_indirect",
+ };
+ sBackendList = new EmuglBackendList(64, fixedBackendNames);
}
static bool stringVectorContains(const std::vector<std::string>& list,
@@ -275,7 +268,7 @@
}
if (!bitness) {
- bitness = System::get()->getProgramBitness();
+ bitness = 64;
}
config->bitness = bitness;
@@ -291,22 +284,7 @@
// 1. NX or Chrome Remote Desktop is detected, or |no_window| is true.
// 2. The user's host GPU is on the blacklist.
std::string sessionType;
- if (System::get()->isRemoteSession(&sessionType)) {
- D("%s: %s session detected\n", __FUNCTION__, sessionType.c_str());
- if (!sBackendList->contains("swiftshader")) {
- config->enabled = false;
- gpu_mode = "off";
- snprintf(config->backend, sizeof(config->backend), "%s", gpu_mode);
- snprintf(config->status, sizeof(config->status),
- "GPU emulation is disabled under %s without Swiftshader",
- sessionType.c_str());
- setCurrentRenderer(gpu_mode);
- return true;
- }
- D("%s: 'swiftshader_indirect' mode auto-selected\n", __FUNCTION__);
- gpu_mode = "swiftshader_indirect";
- }
- else if (!has_auto_no_window && (no_window || (blacklisted && !hasUiPreference))) {
+ if (!has_auto_no_window && (no_window || (blacklisted && !hasUiPreference))) {
if (stringVectorContains(sBackendList->names(), "swiftshader")) {
D("%s: Headless mode or blacklisted GPU driver, "
"using Swiftshader backend\n",
@@ -402,13 +380,11 @@
}
void emuglConfig_setupEnv(const EmuglConfig* config) {
- System* system = System::get();
-
if (config->use_host_vulkan) {
- system->envSet("ANDROID_EMU_VK_ICD", NULL);
+ android::base::setEnvironmentVariable("ANDROID_EMU_VK_ICD", NULL);
} else if (sCurrentRenderer == SELECTED_RENDERER_SWIFTSHADER_INDIRECT) {
// Use Swiftshader vk icd if using swiftshader_indirect
- system->envSet("ANDROID_EMU_VK_ICD", "swiftshader");
+ android::base::setEnvironmentVariable("ANDROID_EMU_VK_ICD", "swiftshader");
}
if (!config->enabled) {
@@ -417,7 +393,7 @@
// software SDL renderer is being used. This allows one
// to run with '-gpu off' under NX and Chrome Remote Desktop
// properly.
- system->envSet("SDL_RENDER_DRIVER", "software");
+ android::base::setEnvironmentVariable("SDL_RENDER_DRIVER", "software");
return;
}
@@ -430,7 +406,9 @@
std::string dir = sBackendList->getLibDirPath(config->backend);
if (dir.size()) {
D("Adding to the library search path: %s\n", dir.c_str());
- system->addLibrarySearchDir(dir);
+ fprintf(stderr, "%s: non-host backends not supported\n", __func__);
+ abort();
+ // android::base::addLibrarySearchDir(dir);
}
}
@@ -441,7 +419,7 @@
if (!strcmp(config->backend, "angle_indirect")
|| !strcmp(config->backend, "swiftshader_indirect")) {
- system->envSet("ANDROID_EGL_ON_EGL", "1");
+ android::base::setEnvironmentVariable("ANDROID_EGL_ON_EGL", "1");
return;
}
@@ -456,11 +434,11 @@
std::string lib;
if (sBackendList->getBackendLibPath(
config->backend, EmuglBackendList::LIBRARY_EGL, &lib)) {
- system->envSet("ANDROID_EGL_LIB", lib);
+ android::base::setEnvironmentVariable("ANDROID_EGL_LIB", lib);
}
if (sBackendList->getBackendLibPath(
config->backend, EmuglBackendList::LIBRARY_GLESv1, &lib)) {
- system->envSet("ANDROID_GLESv1_LIB", lib);
+ android::base::setEnvironmentVariable("ANDROID_GLESv1_LIB", lib);
} else if (strcmp(config->backend, "mesa")) {
fprintf(stderr, "OpenGL backend '%s' without OpenGL ES 1.x library detected. "
"Using GLESv2 only.\n",
@@ -471,13 +449,13 @@
if (sBackendList->getBackendLibPath(
config->backend, EmuglBackendList::LIBRARY_GLESv2, &lib)) {
- system->envSet("ANDROID_GLESv2_LIB", lib);
+ android::base::setEnvironmentVariable("ANDROID_GLESv2_LIB", lib);
}
if (!strcmp(config->backend, "mesa")) {
fprintf(stderr, "WARNING: The Mesa software renderer is deprecated. "
"Use Swiftshader (-gpu swiftshader) for software rendering.\n");
- system->envSet("ANDROID_GL_LIB", "mesa");
- system->envSet("ANDROID_GL_SOFTWARE_RENDERER", "1");
+ android::base::setEnvironmentVariable("ANDROID_GL_LIB", "mesa");
+ android::base::setEnvironmentVariable("ANDROID_GL_SOFTWARE_RENDERER", "1");
}
}
diff --git a/host-common/opengl/gpuinfo.cpp b/host-common/opengl/gpuinfo.cpp
index 2e88ea6..01f0702 100644
--- a/host-common/opengl/gpuinfo.cpp
+++ b/host-common/opengl/gpuinfo.cpp
@@ -9,14 +9,13 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-#include "android/opengl/gpuinfo.h"
+#include "gpuinfo.h"
-#include "android/base/ArraySize.h"
-#include "android/base/memory/LazyInstance.h"
-#include "android/base/system/System.h"
-#include "android/base/threads/FunctorThread.h"
-#include "android/opengl/gpuinfo.h"
-#include "android/opengl/NativeGpuInfo.h"
+#include "base/ArraySize.h"
+#include "base/System.h"
+#include "base/FunctorThread.h"
+#include "gpuinfo.h"
+#include "NativeGpuInfo.h"
#include <assert.h>
#include <inttypes.h>
@@ -28,8 +27,6 @@
using android::base::arraySize;
using android::base::FunctorThread;
-using android::base::LazyInstance;
-using android::base::System;
// Try to switch to NVIDIA on Optimus systems,
// and AMD GPU on AmdPowerXpress.
@@ -52,8 +49,8 @@
#undef FLAG_EXPORT
-static const System::Duration kGPUInfoQueryTimeoutMs = 5000;
-static const System::Duration kQueryCheckIntervalMs = 66;
+static const uint64_t kGPUInfoQueryTimeoutMs = 5000;
+static const uint64_t kQueryCheckIntervalMs = 66;
void GpuInfo::addDll(std::string dll_str) {
dlls.push_back(std::move(dll_str));
@@ -391,14 +388,17 @@
} // namespace
-static LazyInstance<Globals> sGlobals = LAZY_INSTANCE_INIT;
+static Globals* sGlobals() {
+ static Globals* g = new Globals;
+ return g;
+}
void async_query_host_gpu_start() {
- sGlobals.get();
+ sGlobals();
}
const GpuInfoList& globalGpuInfoList() {
- return sGlobals->gpuInfoList();
+ return sGlobals()->gpuInfoList();
}
bool async_query_host_gpu_blacklisted() {
diff --git a/host-common/opengl/gpuinfo.h b/host-common/opengl/gpuinfo.h
index a73d689..30f784d 100644
--- a/host-common/opengl/gpuinfo.h
+++ b/host-common/opengl/gpuinfo.h
@@ -10,7 +10,7 @@
// GNU General Public License for more details.
#pragma once
-#include "android/base/Compiler.h"
+#include "base/Compiler.h"
#include <stdbool.h>
#include <stdio.h>
diff --git a/host-common/opengl/logger.cpp b/host-common/opengl/logger.cpp
index 593e87d..9f42df6 100644
--- a/host-common/opengl/logger.cpp
+++ b/host-common/opengl/logger.cpp
@@ -9,12 +9,10 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-#include "android/opengl/logger.h"
+#include "logger.h"
-#include "android/base/files/PathUtils.h"
-#include "android/base/memory/LazyInstance.h"
-#include "android/base/synchronization/Lock.h"
-#include "android/crashreport/CrashReporter.h"
+#include "base/PathUtils.h"
+#include "base/Lock.h"
#include <algorithm>
#include <fstream>
@@ -30,7 +28,6 @@
using android::base::AutoLock;
using android::base::Lock;
using android::base::PathUtils;
-using android::crashreport::CrashReporter;
// The purpose of the OpenGL logger is to log
// information about such things as EGL initialization
@@ -79,25 +76,28 @@
DISALLOW_COPY_ASSIGN_AND_MOVE(OpenGLLogger);
};
-::android::base::LazyInstance<OpenGLLogger> sOpenGLLogger = LAZY_INSTANCE_INIT;
+static OpenGLLogger* sOpenGLLogger() {
+ static OpenGLLogger* g = new OpenGLLogger;
+ return g;
+}
OpenGLLogger* OpenGLLogger::get() {
- return sOpenGLLogger.ptr();
+ return sOpenGLLogger();
}
OpenGLLogger::OpenGLLogger() {
-#ifdef AEMU_MIN
+// #ifdef AEMU_MIN
return;
-#else
- const std::string& data_dir =
- CrashReporter::get()->getDataExchangeDir();
- mFileName = PathUtils::join(data_dir,
- "opengl_log.txt");
- mFileHandle.open(mFileName, std::ios::app);
- mFineLogFileName = PathUtils::join(data_dir,
- "opengl_cxt_log.txt");
- mFineLogFileHandle.open(mFineLogFileName, std::ios::app);
-#endif
+// #else
+// const std::string& data_dir =
+// CrashReporter::get()->getDataExchangeDir();
+// mFileName = PathUtils::join(data_dir,
+// "opengl_log.txt");
+// mFileHandle.open(mFileName, std::ios::app);
+// mFineLogFileName = PathUtils::join(data_dir,
+// "opengl_cxt_log.txt");
+// mFineLogFileHandle.open(mFineLogFileName, std::ios::app);
+// #endif
}
OpenGLLogger::OpenGLLogger(const char* filename) :
diff --git a/host-common/opengl/logger.h b/host-common/opengl/logger.h
index c6334ac..85b3292 100644
--- a/host-common/opengl/logger.h
+++ b/host-common/opengl/logger.h
@@ -11,10 +11,6 @@
#pragma once
-#include "android/utils/compiler.h"
-
-ANDROID_BEGIN_HEADER
-
// The purpose of the OpenGL logger is to log
// information about such things as EGL initialization
// and possibly miscellanous OpenGL commands,
@@ -44,5 +40,3 @@
// contexts (cxts). Only called when emugl is compiled
// with -DOPENGL_DEBUG_PRINTOUT.
void android_opengl_cxt_logger_write(const char* fmt, ...);
-
-ANDROID_END_HEADER
diff --git a/host-common/opengles.cpp b/host-common/opengles.cpp
index bc50873..5ba3744 100644
--- a/host-common/opengles.cpp
+++ b/host-common/opengles.cpp
@@ -10,57 +10,54 @@
** GNU General Public License for more details.
*/
-#include "android/opengles.h"
+#include "opengles.h"
-#include "android/base/CpuUsage.h"
-#include "android/base/GLObjectCounter.h"
-#include "android/base/files/PathUtils.h"
-#include "android/base/files/Stream.h"
-#include "android/base/memory/MemoryTracker.h"
-#include "android/base/system/System.h"
-#include "android/crashreport/crash-handler.h"
-#include "android/emulation/address_space_device.h"
-#include "android/emulation/address_space_graphics.h"
-#include "android/emulation/address_space_graphics_types.h"
-#include "android/emulation/GoldfishDma.h"
-#include "android/emulation/RefcountPipe.h"
-#include "android/featurecontrol/FeatureControl.h"
-#include "android/globals.h"
-#include "android/opengl/emugl_config.h"
-#include "android/opengl/logger.h"
-#include "android/snapshot/PathUtils.h"
-#include "android/snapshot/Snapshotter.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/debug.h"
-#include "android/utils/dll.h"
-#include "android/utils/path.h"
-#include "config-host.h"
+#include "base/GLObjectCounter.h"
+#include "base/PathUtils.h"
+#include "base/Stream.h"
+#include "base/MemoryTracker.h"
+#include "base/SharedLibrary.h"
+#include "base/System.h"
+#include "host-common/address_space_device.h"
+#include "host-common/address_space_graphics.h"
+#include "host-common/address_space_graphics_types.h"
+#include "host-common/GoldfishDma.h"
+#include "host-common/RefcountPipe.h"
+#include "host-common/FeatureControl.h"
+#include "host-common/globals.h"
+#include "host-common/opengl/emugl_config.h"
+#include "host-common/opengl/logger.h"
+#include "host-common/opengl/gpuinfo.h"
-#include "OpenglRender/render_api_functions.h"
-#include "OpenGLESDispatch/EGLDispatch.h"
-#include "OpenGLESDispatch/GLESv2Dispatch.h"
+#include "../stream-servers/render_api_functions.h"
+#include "../stream-servers/OpenGLESDispatch/EGLDispatch.h"
+#include "../stream-servers/OpenGLESDispatch/GLESv2Dispatch.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
-#define D(...) do { \
- VERBOSE_PRINT(init,__VA_ARGS__); \
- android_opengl_logger_write(__VA_ARGS__); \
-} while(0);
+#define D(...)
+#define DD(...)
+#define E(...)
-#define DD(...) do { \
- VERBOSE_PRINT(gles,__VA_ARGS__); \
- android_opengl_logger_write(__VA_ARGS__); \
-} while(0);
-
-#define E(fmt,...) do { \
- derror(fmt, ##__VA_ARGS__); \
- android_opengl_logger_write(fmt "\n", ##__VA_ARGS__); \
-} while(0);
+// #define D(...) do { \
+// VERBOSE_PRINT(init,__VA_ARGS__); \
+// android_opengl_logger_write(__VA_ARGS__); \
+// } while(0);
+//
+// #define DD(...) do { \
+// VERBOSE_PRINT(gles,__VA_ARGS__); \
+// android_opengl_logger_write(__VA_ARGS__); \
+// } while(0);
+//
+// #define E(fmt,...) do { \
+// derror(fmt, ##__VA_ARGS__); \
+// android_opengl_logger_write(fmt "\n", ##__VA_ARGS__); \
+// } while(0);
using android::base::pj;
-using android::base::System;
+using android::base::SharedLibrary;
using android::emulation::asg::AddressSpaceGraphicsContext;
using android::emulation::asg::ConsumerInterface;
using android::emulation::asg::ConsumerCallbacks;
@@ -77,42 +74,20 @@
LIST_RENDER_API_FUNCTIONS(FUNCTION_)
#undef FUNCTION_
-// Define a function that initializes the function pointers by looking up
-// the symbols from the shared library.
-static int initOpenglesEmulationFuncs(ADynamicLibrary* rendererLib) {
- void* symbol;
- char* error;
-
-#define FUNCTION_(ret, name, sig, params) \
- symbol = adynamicLibrary_findSymbol(rendererLib, #name, &error); \
- if (symbol != NULL) { \
- using type = ret(sig); \
- name = (type*)symbol; \
- } else { \
- E("GLES emulation: Could not find required symbol (%s): %s", #name, error); \
- free(error); \
- return -1; \
- }
- LIST_RENDER_API_FUNCTIONS(FUNCTION_)
-#undef FUNCTION_
-
- return 0;
-}
-
static bool sOpenglLoggerInitialized = false;
static bool sRendererUsesSubWindow = false;
static bool sEgl2egl = false;
-static emugl::RenderLibPtr sRenderLib = nullptr;
+static emugl::RenderLib* sRenderLib = nullptr;
static emugl::RendererPtr sRenderer = nullptr;
static const EGLDispatch* sEgl = nullptr;
static const GLESv2Dispatch* sGlesv2 = nullptr;
-int android_initOpenglesEmulation() {
+int android_prepareOpenglesEmulation() {
android_init_opengl_logger();
- bool glFineLogging = System::get()->envGet("ANDROID_EMUGL_FINE_LOG") == "1";
- bool glLogPrinting = System::get()->envGet("ANDROID_EMUGL_LOG_PRINT") == "1";
+ bool glFineLogging = android::base::getEnvironmentVariable("ANDROID_EMUGL_FINE_LOG") == "1";
+ bool glLogPrinting = android::base::getEnvironmentVariable("ANDROID_EMUGL_LOG_PRINT") == "1";
AndroidOpenglLoggerFlags loggerFlags =
static_cast<AndroidOpenglLoggerFlags>(
@@ -122,74 +97,95 @@
android_opengl_logger_set_flags(loggerFlags);
sOpenglLoggerInitialized = true;
-
- char* error = NULL;
-
- if (sRenderLib != NULL)
- return 0;
-
- D("Initializing hardware OpenGLES emulation support");
-
- ADynamicLibrary* rendererSo =
- adynamicLibrary_open(RENDERER_LIB_NAME, &error);
- if (rendererSo == NULL) {
- E("Could not load OpenGLES emulation library [%s]: %s",
- RENDERER_LIB_NAME, error);
-
- E("Retrying in program directory/lib64...");
-
- auto progDir = System::get()->getProgramDirectory();
-
- auto retryLibPath =
- pj(progDir, "lib64", RENDERER_LIB_NAME);
-
- rendererSo = adynamicLibrary_open(retryLibPath.c_str(), &error);
-
- if (rendererSo == nullptr) {
- E("Could not load OpenGLES emulation library [%s]: %s (2nd try)",
- retryLibPath.c_str(), error);
- return -1;
- }
- }
-
- /* Resolve the functions */
- if (initOpenglesEmulationFuncs(rendererSo) < 0) {
- E("OpenGLES emulation library mismatch. Be sure to use the correct version!");
- crashhandler_append_message_format(
- "OpenGLES emulation library mismatch. Be sure to use the correct version!");
- goto BAD_EXIT;
- }
-
- sRenderLib = initLibrary();
- if (!sRenderLib) {
- E("OpenGLES initialization failed!");
- crashhandler_append_message_format("OpenGLES initialization failed!");
- goto BAD_EXIT;
- }
-
sRendererUsesSubWindow = true;
- if (const char* env = getenv("ANDROID_GL_SOFTWARE_RENDERER")) {
- if (env[0] != '\0' && env[0] != '0') {
- sRendererUsesSubWindow = false;
- }
- }
sEgl2egl = false;
- if (const char* env = getenv("ANDROID_EGL_ON_EGL")) {
- if (env[0] != '\0' && env[0] == '1') {
- sEgl2egl = true;
- }
+ if (android::base::getEnvironmentVariable("ANDROID_EGL_ON_EGL") == "1") {
+ sEgl2egl = true;
}
- sEgl = (const EGLDispatch *)sRenderLib->getEGLDispatch();
- sGlesv2 = (const GLESv2Dispatch *)sRenderLib->getGLESv2Dispatch();
-
return 0;
+}
+//
+// char* error = NULL;
+//
+// if (sRenderLib != NULL)
+// return 0;
+//
+// D("Initializing hardware OpenGLES emulation support");
+//
+// SharedLibrary* rendererSo =
+// SharedLibrary::open(RENDERER_LIB_NAME);
+// if (rendererSo == NULL) {
+// E("Could not load OpenGLES emulation library [%s]: %s",
+// RENDERER_LIB_NAME, error);
+//
+// E("Retrying in program directory/lib64...");
+//
+// auto progDir = System::get()->getProgramDirectory();
+//
+// auto retryLibPath =
+// pj(progDir, "lib64", RENDERER_LIB_NAME);
+//
+// rendererSo = adynamicLibrary_open(retryLibPath.c_str(), &error);
+//
+// if (rendererSo == nullptr) {
+// E("Could not load OpenGLES emulation library [%s]: %s (2nd try)",
+// retryLibPath.c_str(), error);
+// return -1;
+// }
+// }
+//
+// /* Resolve the functions */
+// if (initOpenglesEmulationFuncs(rendererSo) < 0) {
+// E("OpenGLES emulation library mismatch. Be sure to use the correct version!");
+// crashhandler_append_message_format(
+// "OpenGLES emulation library mismatch. Be sure to use the correct version!");
+// goto BAD_EXIT;
+// }
+//
+// sRenderLib = initLibrary();
+// if (!sRenderLib) {
+// E("OpenGLES initialization failed!");
+// crashhandler_append_message_format("OpenGLES initialization failed!");
+// goto BAD_EXIT;
+// }
+//
+// sRendererUsesSubWindow = true;
+// if (const char* env = getenv("ANDROID_GL_SOFTWARE_RENDERER")) {
+// if (env[0] != '\0' && env[0] != '0') {
+// sRendererUsesSubWindow = false;
+// }
+// }
+//
+// sEgl2egl = false;
+// if (const char* env = getenv("ANDROID_EGL_ON_EGL")) {
+// if (env[0] != '\0' && env[0] == '1') {
+// sEgl2egl = true;
+// }
+// }
+//
+// sEgl = (const EGLDispatch *)sRenderLib->getEGLDispatch();
+// sGlesv2 = (const GLESv2Dispatch *)sRenderLib->getGLESv2Dispatch();
+//
+// return 0;
+//
+// BAD_EXIT:
+// E("OpenGLES emulation library could not be initialized!");
+// adynamicLibrary_close(rendererSo);
+// return -1;
+//
-BAD_EXIT:
- E("OpenGLES emulation library could not be initialized!");
- adynamicLibrary_close(rendererSo);
- return -1;
+int android_setOpenglesEmulation(void* renderLib, void* eglDispatch, void* glesv2Dispatch) {
+ sRenderLib = (emugl::RenderLib*)renderLib;
+ sEgl = (EGLDispatch*)eglDispatch;
+ sGlesv2 = (GLESv2Dispatch*)glesv2Dispatch;
+ return 0;
+}
+
+int android_initOpenglesEmulation() {
+ fprintf(stderr, "%s: Not meant to call android_initOpenglesEmulation in the new build\n", __func__);
+ abort();
}
int
@@ -226,7 +222,7 @@
sRenderLib->setRenderer(emuglConfig_get_current_renderer());
sRenderLib->setAvdInfo(guestPhoneApi, guestApiLevel);
- sRenderLib->setCrashReporter(&crashhandler_die_format);
+ // sRenderLib->setCrashReporter(&crashhandler_die_format);
sRenderLib->setFeatureController(&android::featurecontrol::isEnabled);
sRenderLib->setSyncDevice(goldfish_sync_create_timeline,
goldfish_sync_create_fence,
@@ -247,16 +243,16 @@
sRenderLib->setVmOps(*vm_operations);
sRenderLib->setAddressSpaceDeviceControlOps(get_address_space_device_control_ops());
sRenderLib->setWindowOps(*window_agent, *multi_display_agent);
- sRenderLib->setUsageTracker(android::base::CpuUsage::get(),
- android::base::MemoryTracker::get());
+ // sRenderLib->setUsageTracker(android::base::CpuUsage::get(),
+ // android::base::MemoryTracker::get());
sRenderer = sRenderLib->initRenderer(width, height, sRendererUsesSubWindow, sEgl2egl);
- android::snapshot::Snapshotter::get().addOperationCallback(
- [](android::snapshot::Snapshotter::Operation op,
- android::snapshot::Snapshotter::Stage stage) {
- sRenderer->snapshotOperationCallback(op, stage);
- });
+ // android::snapshot::Snapshotter::get().addOperationCallback(
+ // [](android::snapshot::Snapshotter::Operation op,
+ // android::snapshot::Snapshotter::Stage stage) {
+ // sRenderer->snapshotOperationCallback(op, stage);
+ // });
android::emulation::registerOnLastRefCallback(
sRenderLib->getOnLastColorBufferRef());
diff --git a/host-common/opengles.h b/host-common/opengles.h
index 33af88e..764fc32 100644
--- a/host-common/opengles.h
+++ b/host-common/opengles.h
@@ -19,6 +19,12 @@
#include "host-common/vm_operations.h"
#include "host-common/window_agent.h"
#include "host-common/opengl/virtio_gpu_ops.h"
+#include "../stream-servers/RenderLib.h"
+
+/* A version of android_initOpenglesEmulation that is called from a library
+ * that has static access to libOpenglRender. */
+AEMU_EXPORT int android_prepareOpenglesEmulation(void);
+AEMU_EXPORT int android_setOpenglesEmulation(void* renderLib, void* eglDispatch, void* glesv2Dispatch);
/* Call this function to initialize the hardware opengles emulation.
* This function will abort if we can't find the corresponding host
@@ -127,7 +133,7 @@
class Renderer;
}
-AEMU_EXPORT const emugl::Renderer* android_getOpenglesRenderer();
+AEMU_EXPORT const emugl::RendererPtr& android_getOpenglesRenderer();
AEMU_EXPORT struct AndroidVirtioGpuOps* android_getVirtioGpuOps(void);
diff --git a/stream-servers/GfxStreamBackend.cpp b/stream-servers/GfxStreamBackend.cpp
index 71dd73c..4dc32f6 100644
--- a/stream-servers/GfxStreamBackend.cpp
+++ b/stream-servers/GfxStreamBackend.cpp
@@ -38,6 +38,7 @@
#include "VulkanDispatch.h"
#include "GfxStreamAgents.h"
+#include "render_api.h"
#define GFXSTREAM_DEBUG_LEVEL 1
@@ -423,7 +424,16 @@
emuglConfig_setupEnv(&config);
- android_initOpenglesEmulation();
+ android_prepareOpenglesEmulation();
+
+ {
+ static emugl::RenderLibPtr renderLibPtr = initLibrary();
+ void* egldispatch = renderLibPtr->getEGLDispatch();
+ void* glesv2Dispatch = renderLibPtr->getGLESv2Dispatch();
+ android_setOpenglesEmulation(
+ renderLibPtr.get(), egldispatch, glesv2Dispatch);
+ }
+
int maj;
int min;
android_startOpenglesRenderer(
diff --git a/stream-servers/render_api.h b/stream-servers/render_api.h
index f8e2009..de0561f 100644
--- a/stream-servers/render_api.h
+++ b/stream-servers/render_api.h
@@ -32,3 +32,5 @@
RENDER_APICALL return_type RENDER_APIENTRY func_name signature;
LIST_RENDER_API_FUNCTIONS(RENDER_API_DECLARE)
+
+RENDER_APICALL emugl::RenderLibPtr RENDER_APIENTRY initLibrary();