Merge "enable ssse3 for 64-bit emulator"
diff --git a/Makefile.android b/Makefile.android
index 350b72f..e509206 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -10,9 +10,8 @@
# This defines EMULATOR_BUILD_64BITS to indicate that 64-bit binaries
# must be generated by the build system. For now, only do it for
-# Linux and Darwin, since we the sources do not compile with Mingw-w64
-# yet due to differing procedure call ABI conventions.
-EMULATOR_BUILD_64BITS := $(strip $(filter linux darwin,$(HOST_OS)))
+# Windows, Linux and Darwin.
+EMULATOR_BUILD_64BITS := $(strip $(filter linux darwin windows,$(HOST_OS)))
# Disable 64-bit build for Darwin platform builds.
ifeq ($(HOST_OS),darwin)
@@ -78,18 +77,9 @@
ifeq ($(HOST_OS),windows)
# we need Win32 features that are available since Windows 2000 Professional/Server (NT 5.0)
MY_CFLAGS += -DWINVER=0x501
- MY_CFLAGS += -D_WIN32
# LARGEADDRESSAWARE gives more address space to 32-bit process
MY_LDFLAGS32 += -Xlinker --large-address-aware
- ifneq ($(HOST_IS_64_BIT),)
- # Microsoft 64-bit compiler define both _WIN32 and _WIN64
- MY_CFLAGS += -D_WIN64
- # amd64-mingw32msvc- toolchain still name it vfw32. May change it once amd64-mingw32msvc-
- # is stabilized
- MY_LDLIBS += -lvfw32
- else
- MY_LDLIBS += -lvfw32
- endif
+ MY_LDLIBS += -lvfw32
endif
ifeq ($(HOST_ARCH),ppc)
@@ -379,6 +369,9 @@
EMULATOR_TARGET_ARCH := mips
include $(LOCAL_PATH)/Makefile.target
+EMULATOR_TARGET_ARCH := arm64
+include $(LOCAL_PATH)/Makefile.qemu-launcher
+
##############################################################################
##############################################################################
###
diff --git a/Makefile.common b/Makefile.common
index 2ff49e8..c3f6820 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -103,6 +103,7 @@
# Android utility functions
#
common_LOCAL_SRC_FILES += \
+ android/android-constants.c \
android/async-console.c \
android/async-utils.c \
android/charmap.c \
diff --git a/Makefile.qemu-launcher b/Makefile.qemu-launcher
new file mode 100644
index 0000000..7be48d7
--- /dev/null
+++ b/Makefile.qemu-launcher
@@ -0,0 +1,42 @@
+##############################################################################
+##############################################################################
+###
+### emulator-$ARCH: Standalone launcher for QEMU executable.
+###
+###
+EMULATOR_TARGET_CPU := $(EMULATOR_TARGET_ARCH)
+ifeq ($(EMULATOR_TARGET_CPU),x86)
+ EMULATOR_TARGET_CPU := i386
+endif
+
+ifeq ($(EMULATOR_TARGET_CPU),arm64)
+
+qemu_launcher_SOURCES := \
+ android/qemu-launcher/emulator-qemu.cpp \
+ android/cmdline-option.c \
+ android/help.c \
+ android/main-common.c \
+
+qemu_launcher_CFLAGS := -DNO_SKIN=1
+
+qemu_launcher_LDLIBS := -lstdc++
+
+$(call start-emulator-program, emulator-arm64)
+LOCAL_SRC_FILES := $(qemu_launcher_SOURCES)
+LOCAL_CFLAGS := $(qemu_launcher_CFLAGS)
+LOCAL_STATIC_LIBRARIES := \
+ emulator-common
+LOCAL_LDLIBS := $(qemu_launcher_LDLIBS)
+$(call gen-hw-config-defs)
+$(call end-emulator-program)
+
+$(call start-emulator64-program, emulator64-arm64)
+LOCAL_SRC_FILES := $(qemu_launcher_SOURCES)
+LOCAL_CFLAGS := $(qemu_launcher_CFLAGS)
+LOCAL_STATIC_LIBRARIES := \
+ emulator64-common
+LOCAL_LDLIBS := $(qemu_launcher_LDLIBS)
+$(call gen-hw-config-defs)
+$(call end-emulator-program)
+
+endif # EMULATOR_TARGET_CPU == arm64
diff --git a/Makefile.target b/Makefile.target
index e2d2871..e68de28 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -306,10 +306,9 @@
android/display-core.c \
android/help.c \
android/main-common.c \
+ android/main-common-ui.c \
android/main.c \
android/opengles.c \
- android/protocol/core-commands-qemu.c \
- android/protocol/ui-commands-qemu.c \
android/user-events-qemu.c \
hw/core/loader.c \
ui/keymaps.c \
diff --git a/android-configure.sh b/android-configure.sh
index 42fe51d..3e13cc2 100755
--- a/android-configure.sh
+++ b/android-configure.sh
@@ -237,9 +237,16 @@
fi
fi # IN_ANDROID_BUILD = no
-if [ -n "$CCACHE" -a -f "$CCACHE" ] ; then
- CC="$CCACHE $CC"
- log "Prebuilt : CCACHE=$CCACHE"
+if [ -n "$CCACHE" -a -f "$CCACHE" ]; then
+ if [ "$HOST_OS" == "darwin" -a "$OPTION_DEBUG" == "yes" ]; then
+ # http://llvm.org/bugs/show_bug.cgi?id=20297
+ # ccache works for mingw/gdb, therefore probably works for gcc/gdb
+ log "Prebuilt : CCACHE disabled for OSX debug builds"
+ CCACHE=
+ else
+ CC="$CCACHE $CC"
+ log "Prebuilt : CCACHE=$CCACHE"
+ fi
else
log "Prebuilt : CCACHE can't be found"
CCACHE=
diff --git a/android-rebuild.sh b/android-rebuild.sh
index 8b54f09..8ca2c2a 100755
--- a/android-rebuild.sh
+++ b/android-rebuild.sh
@@ -75,12 +75,9 @@
run make -j$HOST_NUM_CPUS OBJS_DIR="$OUT_DIR" ||
panic "Could not build sources, please run 'make' to see why."
-RUN_64BIT_TESTS=true
-
TEST_SHELL=
EXE_SUFFIX=
if [ "$MINGW" ]; then
- RUN_64BIT_TESTS=
TEST_SHELL=wine
EXE_SUFFIX=.exe
@@ -100,13 +97,11 @@
run $TEST_SHELL $OUT_DIR/$UNIT_TEST$EXE_SUFFIX || FAILURES="$FAILURES $UNIT_TEST"
done
- if [ "$RUN_64BIT_TESTS" ]; then
- echo "Running 64-bit unit test suite."
- for UNIT_TEST in emulator64_unittests emugl64_common_host_unittests; do
- echo " - $UNIT_TEST"
- run $TEST_SHELL $OUT_DIR/$UNIT_TEST$EXE_SUFFIX || FAILURES="$FAILURES $UNIT_TEST"
- done
- fi
+ echo "Running 64-bit unit test suite."
+ for UNIT_TEST in emulator64_unittests emugl64_common_host_unittests; do
+ echo " - $UNIT_TEST"
+ run $TEST_SHELL $OUT_DIR/$UNIT_TEST$EXE_SUFFIX || FAILURES="$FAILURES $UNIT_TEST"
+ done
if [ "$FAILURES" ]; then
panic "Unit test failures: $FAILURES"
diff --git a/android/android-constants.c b/android/android-constants.c
new file mode 100644
index 0000000..aa73d70
--- /dev/null
+++ b/android/android-constants.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 2007 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/android.h"
+
+/* see http://en.wikipedia.org/wiki/List_of_device_bandwidths or a complete list */
+const NetworkSpeed android_netspeeds[] = {
+ { "gsm", "GSM/CSD", 14400, 14400 },
+ { "hscsd", "HSCSD", 14400, 43200 },
+ { "gprs", "GPRS", 40000, 80000 },
+ { "edge", "EDGE/EGPRS", 118400, 236800 },
+ { "umts", "UMTS/3G", 128000, 1920000 },
+ { "hsdpa", "HSDPA", 348000, 14400000 },
+ { "full", "no limit", 0, 0 },
+ { NULL, NULL, 0, 0 }
+};
+const size_t android_netspeeds_count =
+ sizeof(android_netspeeds) / sizeof(android_netspeeds[0]);
+
+const NetworkLatency android_netdelays[] = {
+ /* FIXME: these numbers are totally imaginary */
+ { "gprs", "GPRS", 150, 550 },
+ { "edge", "EDGE/EGPRS", 80, 400 },
+ { "umts", "UMTS/3G", 35, 200 },
+ { "none", "no latency", 0, 0 },
+ { NULL, NULL, 0, 0 }
+};
+const size_t android_netdelays_count =
+ sizeof(android_netdelays) / sizeof(android_netdelays[0]);
+
diff --git a/android/avd/hw-config.h b/android/avd/hw-config.h
index 82a3a5e..df9f1f0 100644
--- a/android/avd/hw-config.h
+++ b/android/avd/hw-config.h
@@ -13,8 +13,11 @@
#define _ANDROID_AVD_HW_CONFIG_H
#include <stdint.h>
+#include "android/utils/compiler.h"
#include "android/utils/ini.h"
+ANDROID_BEGIN_HEADER
+
typedef char hw_bool_t;
typedef int hw_int_t;
typedef int64_t hw_disksize_t;
@@ -86,4 +89,6 @@
// kernel.newDeviceNaming.
const char* androidHwConfig_getKernelSerialPrefix( AndroidHwConfig* config );
+ANDROID_END_HEADER
+
#endif /* _ANDROID_AVD_HW_CONFIG_H */
diff --git a/android/avd/info.h b/android/avd/info.h
index d2b0b74..f0fc1db 100644
--- a/android/avd/info.h
+++ b/android/avd/info.h
@@ -12,11 +12,14 @@
#ifndef ANDROID_AVD_INFO_H
#define ANDROID_AVD_INFO_H
+#include "android/utils/compiler.h"
#include "android/utils/ini.h"
#include "android/avd/hw-config.h"
#include "android/config/config.h"
#include "android/utils/file_data.h"
+ANDROID_BEGIN_HEADER
+
/* An Android Virtual Device (AVD for short) corresponds to a
* directory containing all kernel/disk images for a given virtual
* device, as well as information about its hardware capabilities,
@@ -284,6 +287,6 @@
*/
int avdInfo_getSnapshotPresent(AvdInfo* i);
-/* */
+ANDROID_END_HEADER
#endif /* ANDROID_AVD_INFO_H */
diff --git a/android/avd/util.c b/android/avd/util.c
index cbd6e9c..51236ac 100644
--- a/android/avd/util.c
+++ b/android/avd/util.c
@@ -338,6 +338,7 @@
{ "x86", "x86" },
{ "x86_64", "x86" },
{ "mips", "mips" },
+ { "arm64", "arm" },
// Add more if needed here.
};
size_t n;
diff --git a/android/avd/util_unittest.cpp b/android/avd/util_unittest.cpp
index 4197b0a..d73474f 100644
--- a/android/avd/util_unittest.cpp
+++ b/android/avd/util_unittest.cpp
@@ -19,10 +19,10 @@
EXPECT_STREQ("x86", emulator_getBackendSuffix("x86"));
EXPECT_STREQ("x86", emulator_getBackendSuffix("x86_64"));
EXPECT_STREQ("mips", emulator_getBackendSuffix("mips"));
+ EXPECT_STREQ("arm", emulator_getBackendSuffix("arm64"));
// TODO(digit): Add support for these CPU architectures to the emulator
// to change these to EXPECT_STREQ() calls.
- EXPECT_FALSE(emulator_getBackendSuffix("arm64"));
EXPECT_FALSE(emulator_getBackendSuffix("mips64"));
EXPECT_FALSE(emulator_getBackendSuffix(NULL));
diff --git a/android/build/common.sh b/android/build/common.sh
index 992b769..b859862 100644
--- a/android/build/common.sh
+++ b/android/build/common.sh
@@ -16,6 +16,7 @@
# It contains common definitions.
#
PROGNAME=`basename $0`
+PROGDIR=`dirname $0`
## Logging support
##
@@ -203,27 +204,25 @@
echo "Sorry, but mingw compilation is only supported on Linux !"
exit 1
fi
- # Do we have the binaries installed
- log "Mingw64 : Checking for mingw64 installation"
- MINGW64_PREFIX=x86_64-w64-mingw32
- find_program MINGW64_CC $MINGW64_PREFIX-gcc
- if [ -n "$MINGW64_CC" ]; then
- MINGW_CC=$MINGW64_CC
- MINGW_PREFIX=$MINGW64_PREFIX
- else
- log "Mingw : Checking for mingw32 installation"
- MINGW32_PREFIX=i586-mingw32msvc
- find_program MINGW32_CC $MINGW32_PREFIX-gcc
- if [ -z "$MINGW32_CC" ] ; then
- echo "ERROR: It looks like neither $MINGW64_PREFIX-cc nor $MINGW32_PREFIX-gcc"
- echo "are in your path. Please install the mingw32 package !"
- exit 1
- fi
- MINGW_CC=$MINGW32_CC
- MINGW_PREFIX=$MINGW32_PREFIX
- FORCE_32BIT=no
+ # Do we have our prebuilt mingw64 toolchain?
+ log "Mingw : Looking for prebuilt mingw64 toolchain."
+ MINGW_DIR=$PROGDIR/../../prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8
+ MINGW_CC=
+ if [ -d "$MINGW_DIR" ]; then
+ MINGW_PREFIX=$MINGW_DIR/bin/x86_64-w64-mingw32
+ find_program MINGW_CC "$MINGW_PREFIX-gcc"
fi
- log2 "Mingw : Found $MINGW32_CC"
+ if [ -z "$MINGW_CC" ]; then
+ log "Mingw : Looking for mingw64 toolchain."
+ MINGW_PREFIX=x86_64-w64-mingw32
+ find_program MINGW_CC $MINGW_PREFIX-gcc
+ fi
+ if [ -z "$MINGW_CC" ]; then
+ echo "ERROR: It looks like no Mingw64 toolchain is available!"
+ echo "Please install x86_64-w64-mingw32 package !"
+ exit 1
+ fi
+ log2 "Mingw : Found $MINGW_CC"
CC=$MINGW_CC
LD=$MINGW_CC
AR=$MINGW_PREFIX-ar
diff --git a/android/cmdline-option.h b/android/cmdline-option.h
index 6fba00a..cb650dd 100644
--- a/android/cmdline-option.h
+++ b/android/cmdline-option.h
@@ -12,6 +12,10 @@
#ifndef _ANDROID_OPTION_H
#define _ANDROID_OPTION_H
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/* a structure used to model a linked list of parameters
*/
typedef struct ParamList {
@@ -43,4 +47,6 @@
*/
#define DEFAULT_DEVICE_DPI 165
+ANDROID_END_HEADER
+
#endif /* _ANDROID_OPTION_H */
diff --git a/android/cmdline-options.h b/android/cmdline-options.h
index 1009af6..4653dfe 100644
--- a/android/cmdline-options.h
+++ b/android/cmdline-options.h
@@ -150,11 +150,6 @@
OPT_PARAM( nand_limits, "<nlimits>", "enforce NAND/Flash read/write thresholds" )
#endif
-#ifdef CONFIG_STANDALONE_UI
-OPT_PARAM( list_cores, "<host>", "list running core process" )
-OPT_PARAM( attach_core, "<console socket>", "attach to a running core process" )
-#endif // CONFIG_STANDALONE_UI
-
OPT_PARAM( gpu, "<mode>", "set hardware OpenGLES emulation mode" )
OPT_PARAM( camera_back, "<mode>", "set emulation mode for a camera facing back" )
diff --git a/android/console.c b/android/console.c
index dc55646..b033c1d 100644
--- a/android/console.c
+++ b/android/console.c
@@ -53,17 +53,13 @@
#include "android/keycode-array.h"
#include "android/charmap.h"
#include "android/display-core.h"
-#include "android/protocol/fb-updates-proxy.h"
-#include "android/protocol/user-events-impl.h"
-#include "android/protocol/ui-commands-api.h"
-#include "android/protocol/core-commands-impl.h"
-#include "android/protocol/ui-commands-proxy.h"
-#include "android/protocol/attach-ui-proxy.h"
#if defined(CONFIG_SLIRP)
#include "libslirp.h"
#endif
+extern void android_emulator_set_window_scale(double, int);
+
#define DEBUG 1
#if 1
@@ -2616,7 +2612,7 @@
}
}
- uicmd_set_window_scale( scale, is_dpi );
+ android_emulator_set_window_scale(scale, is_dpi);
return 0;
}
diff --git a/android/filesystems/ramdisk_extractor.cpp b/android/filesystems/ramdisk_extractor.cpp
index 62e4445..4c56e42 100644
--- a/android/filesystems/ramdisk_extractor.cpp
+++ b/android/filesystems/ramdisk_extractor.cpp
@@ -258,7 +258,7 @@
// The file data is 4-byte padded with NUL bytes too.
size_t skipFile = (entrySize + 3) & ~3;
- size_t skipCount = 0;
+ size_t skipCount = skipName + skipFile;
// Last record is named 'TRAILER!!!' and indicates end of archive.
static const char kTrailer[] = "TRAILER!!!";
@@ -267,7 +267,6 @@
if ((entrySize == 0 || nameSize != fileNameLen + 1U) &&
nameSize != kTrailerSize + 1U) {
D("---- %d Skipping\n", __LINE__);
- skipCount = skipName + skipFile;
} else {
// Read the name and compare it.
nameSize -= 1U;
diff --git a/android/filesystems/ramdisk_extractor_unittest.cpp b/android/filesystems/ramdisk_extractor_unittest.cpp
index 2462b5d..b87f888 100644
--- a/android/filesystems/ramdisk_extractor_unittest.cpp
+++ b/android/filesystems/ramdisk_extractor_unittest.cpp
@@ -80,6 +80,20 @@
free(out);
}
+TEST_F(RamdiskExtractorTest, FindZoo) {
+ static const char kExpected[] = "Meow!!\n";
+ static const size_t kExpectedSize = sizeof(kExpected) - 1U;
+ char* out = NULL;
+ size_t outSize = 0;
+
+ EXPECT_TRUE(fillData(kTestRamdiskImage, kTestRamdiskImageSize));
+ EXPECT_TRUE(android_extractRamdiskFile(path(), "zoo", &out, &outSize));
+ EXPECT_EQ(kExpectedSize, outSize);
+ EXPECT_TRUE(out);
+ EXPECT_TRUE(!memcmp(out, kExpected, outSize));
+ free(out);
+}
+
TEST_F(RamdiskExtractorTest, MissingFile) {
char* out = NULL;
size_t outSize = 0;
diff --git a/android/filesystems/testing/TestRamdiskImage.h b/android/filesystems/testing/TestRamdiskImage.h
index baec302..7430d0d 100644
--- a/android/filesystems/testing/TestRamdiskImage.h
+++ b/android/filesystems/testing/TestRamdiskImage.h
@@ -12,24 +12,26 @@
#ifndef ANDROID_FILESYSTEMS_TESTING_TEST_RAMDISK_IMAGE_H
#define ANDROID_FILESYSTEMS_TESTING_TEST_RAMDISK_IMAGE_H
-/* Auto-generated by create_ramdisk_test_data.sh on 2014-06-23 - DO NOT EDIT!! */
+/* Auto-generated by create_ramdisk_test_data.sh on 2014-07-15 - DO NOT EDIT!! */
static const unsigned char kTestRamdiskImage[] = {
- 0x1f, 0x8b, 0x08, 0x00, 0x6d, 0x1a, 0xa8, 0x53, 0x02, 0x03, 0xbd, 0x8e,
- 0x41, 0x0a, 0x83, 0x30, 0x10, 0x45, 0xb3, 0xee, 0x29, 0x26, 0x37, 0x98,
- 0xc4, 0x46, 0xd3, 0x65, 0xac, 0x86, 0x16, 0x5c, 0x49, 0xa1, 0x6b, 0x4b,
- 0x63, 0x11, 0x06, 0x43, 0xad, 0x7a, 0xfe, 0x2a, 0x41, 0x90, 0x2e, 0x8a,
- 0xdd, 0xf4, 0x6d, 0xfe, 0x1f, 0x66, 0x60, 0x1e, 0x26, 0x98, 0xa0, 0x40,
- 0x14, 0xb9, 0xd4, 0x07, 0x8b, 0x13, 0x5a, 0x98, 0x39, 0x30, 0xb6, 0x26,
- 0x9d, 0x53, 0x44, 0x5a, 0x63, 0x40, 0xa8, 0xc8, 0x4c, 0xeb, 0x38, 0x0b,
- 0xa3, 0x54, 0x21, 0xed, 0x11, 0xbf, 0xa3, 0x96, 0x72, 0xab, 0x3a, 0xc9,
- 0x58, 0x51, 0xc1, 0xd8, 0x38, 0x70, 0xaf, 0x1e, 0x86, 0x16, 0xc8, 0xb7,
- 0x0f, 0xa8, 0xc9, 0x0d, 0xa3, 0x83, 0xbe, 0xab, 0xda, 0xe7, 0xd0, 0x10,
- 0xb9, 0x1d, 0x63, 0x0c, 0xd7, 0x6e, 0xd9, 0x6f, 0x6e, 0x98, 0x6d, 0x74,
- 0xdb, 0x2f, 0xa5, 0xf6, 0x7e, 0xfa, 0x79, 0x72, 0x44, 0x1e, 0xae, 0xbe,
- 0xa3, 0x3b, 0x5f, 0x3b, 0x6c, 0x62, 0xeb, 0xdd, 0x27, 0xe9, 0x52, 0x2e,
- 0xa5, 0x39, 0x17, 0x79, 0xc9, 0x39, 0x67, 0x7f, 0xe2, 0x0d, 0xb9, 0x32,
- 0x87, 0xaa, 0x00, 0x02, 0x00, 0x00
+ 0x1f, 0x8b, 0x08, 0x00, 0xa7, 0xe0, 0xc4, 0x53, 0x02, 0x03, 0xed, 0x8f,
+ 0xcd, 0x0a, 0x82, 0x40, 0x14, 0x85, 0x67, 0xed, 0x53, 0xcc, 0xbc, 0xc1,
+ 0xbd, 0xfe, 0x8d, 0xdb, 0xd1, 0x46, 0x0a, 0x6c, 0x23, 0x41, 0x6b, 0xa3,
+ 0x31, 0x84, 0x61, 0x86, 0x4c, 0x0d, 0x7a, 0xfa, 0x34, 0x91, 0xa4, 0x45,
+ 0xe8, 0xba, 0xbe, 0xcd, 0x39, 0x03, 0x03, 0xdf, 0xb9, 0xc0, 0x81, 0x03,
+ 0x02, 0xa0, 0xf4, 0x50, 0x4a, 0xe8, 0x89, 0x50, 0x0c, 0x01, 0x61, 0x2a,
+ 0xe2, 0x21, 0xd1, 0x8b, 0x22, 0x18, 0xc1, 0xc0, 0x4b, 0x7c, 0x09, 0x82,
+ 0x8f, 0x4f, 0x37, 0x18, 0x33, 0x4d, 0xe0, 0x3b, 0xc1, 0x54, 0x4e, 0x45,
+ 0xed, 0x12, 0x92, 0x15, 0xb4, 0xab, 0x14, 0x55, 0xb7, 0x86, 0xb6, 0x86,
+ 0x6a, 0x6b, 0x2e, 0xb4, 0xd4, 0xaa, 0xed, 0x14, 0x6d, 0xea, 0xc2, 0x5c,
+ 0xdb, 0x4a, 0x6b, 0xe5, 0x10, 0x42, 0xe0, 0xbd, 0xcd, 0x85, 0x70, 0xdd,
+ 0x36, 0xe0, 0x0b, 0xb7, 0xf9, 0x53, 0x79, 0x58, 0xdb, 0x3b, 0xf7, 0xca,
+ 0xde, 0x19, 0x73, 0xe6, 0x6e, 0x94, 0x62, 0xa5, 0x7b, 0xb3, 0xd6, 0x5d,
+ 0xbe, 0xdc, 0x5b, 0xa5, 0xb5, 0xa5, 0x47, 0x5b, 0xeb, 0x33, 0x9b, 0xdf,
+ 0xbf, 0x88, 0xa5, 0xff, 0x3e, 0x89, 0xa7, 0x72, 0xc8, 0xc5, 0x2e, 0x93,
+ 0x39, 0x63, 0x8c, 0xfc, 0xf9, 0x19, 0x9e, 0x05, 0x57, 0xf3, 0x6c, 0x00,
+ 0x04, 0x00, 0x00
};
static const size_t kTestRamdiskImageSize = sizeof(kTestRamdiskImage);
diff --git a/android/filesystems/testing/create_ramdisk_test_data.sh b/android/filesystems/testing/create_ramdisk_test_data.sh
index 1bd3e42..39ce3dd 100755
--- a/android/filesystems/testing/create_ramdisk_test_data.sh
+++ b/android/filesystems/testing/create_ramdisk_test_data.sh
@@ -27,7 +27,9 @@
cat > bar2 <<EOF
La vie est un long fleuve tranquille
EOF
-
+cat > zoo <<EOF
+Meow!!
+EOF
echo "/* Auto-generated by $PROGNAME on $DATE - DO NOT EDIT!! */"
echo ""
echo "static const unsigned char kTestRamdiskImage[] = {"
diff --git a/android/help.c b/android/help.c
index 0fb7f40..acddfa8 100644
--- a/android/help.c
+++ b/android/help.c
@@ -4,13 +4,13 @@
#include "android/utils/bufprint.h"
#include "android/utils/debug.h"
#include "android/utils/misc.h"
+#ifndef NO_SKIN
#include "android/skin/keyset.h"
+#endif
#include "android/android.h"
#include <stdint.h>
-#include "audio/audio.h"
#include <string.h>
#include <stdlib.h>
-#include "android/protocol/core-commands-api.h"
/* XXX: TODO: put most of the help stuff in auto-generated files */
@@ -208,6 +208,7 @@
static void
help_keys(stralloc_t* out)
{
+#ifndef NO_SKIN
int pass, maxw = 0;
stralloc_add_str( out, " When running the emulator, use the following keypresses:\n\n");
@@ -244,6 +245,7 @@
}
PRINTF( "\n" );
PRINTF( " note that NumLock must be deactivated for keypad keys to work\n\n" );
+#endif // !NO_SKIN
}
@@ -281,6 +283,7 @@
static void
help_keyset_file(stralloc_t* out)
{
+#ifndef NO_SKIN
int n, count;
const char** strings;
char temp[MAX_PATH];
@@ -346,6 +349,7 @@
" CHANGE_LAYOUT_PREV Keypad_7,Ctrl-J # switch to a previous skin layout\n"
"\n"
);
+#endif // !NO_SKIN
}
@@ -809,8 +813,6 @@
help_shaper(stralloc_t* out)
{
int n;
- NetworkSpeed* android_netspeed;
- NetworkLatency* android_netdelay;
PRINTF(
" the Android emulator supports network throttling, i.e. slower network\n"
" bandwidth as well as higher connection latencies. this is done either through\n"
@@ -818,24 +820,30 @@
" the format of -netspeed is one of the following (numbers are kbits/s):\n\n" );
- for (n = 0; !corecmd_get_netspeed(n, &android_netspeed); n++) {
+ for (n = 0;; ++n) {
+ const NetworkSpeed* android_netspeed = &android_netspeeds[n];
+ if (!android_netspeed->name) {
+ break;
+ }
PRINTF( " -netspeed %-12s %-15s (up: %.1f, down: %.1f)\n",
android_netspeed->name,
android_netspeed->display,
android_netspeed->upload/1000.,
android_netspeed->download/1000. );
- free(android_netspeed);
}
PRINTF( "\n" );
PRINTF( " -netspeed %-12s %s", "<num>", "select both upload and download speed\n");
PRINTF( " -netspeed %-12s %s", "<up>:<down>", "select individual up and down speed\n");
PRINTF( "\n The format of -netdelay is one of the following (numbers are msec):\n\n" );
- for (n = 0; !corecmd_get_netdelay(n, &android_netdelay); n++) {
+ for (n = 0; ; ++n) {
+ const NetworkLatency* android_netdelay = &android_netdelays[n];
+ if (!android_netdelay->name) {
+ break;
+ }
PRINTF( " -netdelay %-10s %-15s (min %d, max %d)\n",
android_netdelay->name, android_netdelay->display,
android_netdelay->min_ms, android_netdelay->max_ms );
- free(android_netdelay);
}
PRINTF( " -netdelay %-10s %s", "<num>", "select exact latency\n");
PRINTF( " -netdelay %-10s %s", "<min>:<max>", "select min and max latencies\n\n");
@@ -971,33 +979,6 @@
);
}
-#ifdef CONFIG_STANDALONE_UI
-static void
-help_list_cores(stralloc_t* out)
-{
- PRINTF(
- " use '-list-cores localhost to list emulator core processes running on this machine.\n"
- " use '-list-cores host_name, or IP address to list emulator core processes running on\n"
- " a remote machine.\n"
- );
-}
-
-static void
-help_attach_core(stralloc_t* out)
-{
- PRINTF(
- " the -attach-core <console socket> options attaches the UI to a running emulator core process.\n\n"
-
- " the <console socket> parameter must be in the form [host:]port, where 'host' addresses the\n"
- " machine on which the core process is running, and 'port' addresses the console port number for\n"
- " the running core process. Note that 'host' value must be in the form that can be resolved\n"
- " into an IP address.\n\n"
-
- " Use -list-cores to enumerate console ports for all currently running core processes.\n"
- );
-}
-#endif // CONFIG_STANDALONE_UI
-
static void
help_show_kernel(stralloc_t* out)
{
diff --git a/android/help.h b/android/help.h
index ee15941..5624823 100644
--- a/android/help.h
+++ b/android/help.h
@@ -12,8 +12,11 @@
#ifndef _ANDROID_HELP_H
#define _ANDROID_HELP_H
+#include "android/utils/compiler.h"
#include "android/utils/stralloc.h"
+ANDROID_BEGIN_HEADER
+
/* these values give the maximum length of system property
* names and values. They must match the definitions for PROPERTY_MAX_NAME and
* PROPERTY_MAX_VALUE in the Android source tree
@@ -41,4 +44,6 @@
*/
extern int android_help_for_topic( const char* topic, stralloc_t* out );
+ANDROID_END_HEADER
+
#endif /* _ANDROID_HELP_H */
diff --git a/android/main-common-ui.c b/android/main-common-ui.c
new file mode 100644
index 0000000..5689a11
--- /dev/null
+++ b/android/main-common-ui.c
@@ -0,0 +1,756 @@
+/* Copyright (C) 2011 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 <SDL.h>
+#include <SDL_syswm.h>
+
+#include "android/avd/util.h"
+#include "android/globals.h"
+#include "android/main-common.h"
+#include "android/qemulator.h"
+#include "android/display.h"
+#include "android/resource.h"
+#include "android/skin/image.h"
+#include "android/skin/trackball.h"
+#include "android/skin/keyboard.h"
+#include "android/skin/file.h"
+#include "android/skin/window.h"
+#include "android/user-config.h"
+#include "android/utils/bufprint.h"
+#include "android/utils/debug.h"
+#include "android/utils/eintr_wrapper.h"
+#include "android/utils/path.h"
+
+#include "ui/console.h"
+
+#include <stdlib.h>
+
+#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
+
+/*** CONFIGURATION
+ ***/
+
+static AUserConfig* userConfig;
+
+void
+user_config_init( void )
+{
+ userConfig = auserConfig_new( android_avdInfo );
+}
+
+/* only call this function on normal exits, so that ^C doesn't save the configuration */
+void
+user_config_done( void )
+{
+ int win_x, win_y;
+
+ if (!userConfig) {
+ D("no user configuration?");
+ return;
+ }
+
+ SDL_WM_GetPos( &win_x, &win_y );
+ auserConfig_setWindowPos(userConfig, win_x, win_y);
+ auserConfig_save(userConfig);
+}
+
+void
+user_config_get_window_pos( int *window_x, int *window_y )
+{
+ *window_x = *window_y = 10;
+
+ if (userConfig)
+ auserConfig_getWindowPos(userConfig, window_x, window_y);
+}
+
+/***********************************************************************/
+/***********************************************************************/
+/***** *****/
+/***** K E Y S E T R O U T I N E S *****/
+/***** *****/
+/***********************************************************************/
+/***********************************************************************/
+
+#define KEYSET_FILE "default.keyset"
+
+SkinKeyset* android_keyset = NULL;
+
+static int
+load_keyset(const char* path)
+{
+ if (path_can_read(path)) {
+ AConfig* root = aconfig_node("","");
+ if (!aconfig_load_file(root, path)) {
+ android_keyset = skin_keyset_new(root);
+ if (android_keyset != NULL) {
+ D( "keyset loaded from: %s", path);
+ return 0;
+ }
+ }
+ }
+ return -1;
+}
+
+void
+parse_keyset(const char* keyset, AndroidOptions* opts)
+{
+ char kname[MAX_PATH];
+ char temp[MAX_PATH];
+ char* p;
+ char* end;
+
+ /* append .keyset suffix if needed */
+ if (strchr(keyset, '.') == NULL) {
+ p = kname;
+ end = p + sizeof(kname);
+ p = bufprint(p, end, "%s.keyset", keyset);
+ if (p >= end) {
+ derror( "keyset name too long: '%s'\n", keyset);
+ exit(1);
+ }
+ keyset = kname;
+ }
+
+ /* look for a the keyset file */
+ p = temp;
+ end = p + sizeof(temp);
+ p = bufprint_config_file(p, end, keyset);
+ if (p < end && load_keyset(temp) == 0)
+ return;
+
+ p = temp;
+ p = bufprint(p, end, "%s" PATH_SEP "keysets" PATH_SEP "%s", opts->sysdir, keyset);
+ if (p < end && load_keyset(temp) == 0)
+ return;
+
+ p = temp;
+ p = bufprint_app_dir(p, end);
+ p = bufprint(p, end, PATH_SEP "keysets" PATH_SEP "%s", keyset);
+ if (p < end && load_keyset(temp) == 0)
+ return;
+
+ return;
+}
+
+void
+write_default_keyset( void )
+{
+ char path[MAX_PATH];
+
+ bufprint_config_file( path, path+sizeof(path), KEYSET_FILE );
+
+ /* only write if there is no file here */
+ if (!path_exists(path)) {
+ int fd = open( path, O_WRONLY | O_CREAT, 0666 );
+ const char* ks = skin_keyset_get_default();
+
+
+ D( "writing default keyset file to %s", path );
+
+ if (fd < 0) {
+ D( "%s: could not create file: %s", __FUNCTION__, strerror(errno) );
+ return;
+ }
+ HANDLE_EINTR(write(fd, ks, strlen(ks)));
+ IGNORE_EINTR(close(fd));
+ }
+}
+
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***** *****/
+/***** S D L S U P P O R T *****/
+/***** *****/
+/***********************************************************************/
+/***********************************************************************/
+
+void *readpng(const unsigned char* base, size_t size, unsigned *_width, unsigned *_height);
+
+#ifdef CONFIG_DARWIN
+# define ANDROID_ICON_PNG "android_icon_256.png"
+#else
+# define ANDROID_ICON_PNG "android_icon_16.png"
+#endif
+
+static void
+sdl_set_window_icon( void )
+{
+ static int window_icon_set;
+
+ if (!window_icon_set)
+ {
+#ifdef _WIN32
+ HANDLE handle = GetModuleHandle( NULL );
+ HICON icon = LoadIcon( handle, MAKEINTRESOURCE(1) );
+ SDL_SysWMinfo wminfo;
+
+ SDL_GetWMInfo(&wminfo);
+
+ SetClassLongPtr( wminfo.window, GCLP_HICON, (LONG)icon );
+#else /* !_WIN32 */
+ unsigned icon_w, icon_h;
+ size_t icon_bytes;
+ const unsigned char* icon_data;
+ void* icon_pixels;
+
+ window_icon_set = 1;
+
+ icon_data = android_icon_find( ANDROID_ICON_PNG, &icon_bytes );
+ if ( !icon_data )
+ return;
+
+ icon_pixels = readpng( icon_data, icon_bytes, &icon_w, &icon_h );
+ if ( !icon_pixels )
+ return;
+
+ /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
+ * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
+ * on our CPU endianess
+ */
+ {
+ unsigned* d = icon_pixels;
+ unsigned* d_end = d + icon_w*icon_h;
+
+ for ( ; d < d_end; d++ ) {
+ unsigned pix = d[0];
+#if HOST_WORDS_BIGENDIAN
+ /* R,G,B,A read as RGBA => ARGB */
+ pix = ((pix >> 8) & 0xffffff) | (pix << 24);
+#else
+ /* R,G,B,A read as ABGR => ARGB */
+ pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
+#endif
+ d[0] = pix;
+ }
+ }
+
+ SDL_Surface* icon = sdl_surface_from_argb32( icon_pixels, icon_w, icon_h );
+ if (icon != NULL) {
+ SDL_WM_SetIcon(icon, NULL);
+ SDL_FreeSurface(icon);
+ free( icon_pixels );
+ }
+#endif /* !_WIN32 */
+ }
+}
+
+/***********************************************************************/
+/***********************************************************************/
+/***** *****/
+/***** S K I N S U P P O R T *****/
+/***** *****/
+/***********************************************************************/
+/***********************************************************************/
+
+const char* skin_network_speed = NULL;
+const char* skin_network_delay = NULL;
+
+
+static void sdl_at_exit(void)
+{
+ user_config_done();
+ qemulator_done(qemulator_get());
+ SDL_Quit();
+}
+
+
+void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
+{
+ QEmulator* emulator = qemulator_get();
+ SkinDisplay* disp = skin_layout_get_display(emulator->layout);
+ int width, height;
+ char buf[128];
+
+ if (disp->rotation & 1) {
+ width = disp->rect.size.h;
+ height = disp->rect.size.w;
+ } else {
+ width = disp->rect.size.w;
+ height = disp->rect.size.h;
+ }
+
+ snprintf(buf, sizeof buf, "width=%d,height=%d", width, height);
+ android_display_init(ds, qframebuffer_fifo_get());
+}
+
+typedef struct part_properties part_properties;
+struct part_properties {
+ const char* name;
+ int width;
+ int height;
+ part_properties* next;
+};
+
+part_properties*
+read_all_part_properties(AConfig* parts)
+{
+ part_properties* head = NULL;
+ part_properties* prev = NULL;
+
+ AConfig *node = parts->first_child;
+ while (node) {
+ part_properties* t = calloc(1, sizeof(part_properties));
+ t->name = node->name;
+
+ AConfig* bg = aconfig_find(node, "background");
+ if (bg != NULL) {
+ t->width = aconfig_int(bg, "width", 0);
+ t->height = aconfig_int(bg, "height", 0);
+ }
+
+ if (prev == NULL) {
+ head = t;
+ } else {
+ prev->next = t;
+ }
+ prev = t;
+ node = node->next;
+ }
+
+ return head;
+}
+
+void
+free_all_part_properties(part_properties* head)
+{
+ part_properties* prev = head;
+ while (head) {
+ prev = head;
+ head = head->next;
+ free(prev);
+ }
+}
+
+part_properties*
+get_part_properties(part_properties* allparts, char *partname)
+{
+ part_properties* p;
+ for (p = allparts; p != NULL; p = p->next) {
+ if (!strcmp(partname, p->name))
+ return p;
+ }
+
+ return NULL;
+}
+
+void
+add_parts_to_layout(AConfig* layout,
+ char* parts[],
+ int n_parts,
+ part_properties *props,
+ int xoffset,
+ int x_margin,
+ int y_margin)
+{
+ int i;
+ int y = 10;
+ char tmp[512];
+ for (i = 0; i < n_parts; i++) {
+ part_properties *p = get_part_properties(props, parts[i]);
+ snprintf(tmp, sizeof tmp,
+ "part%d {\n \
+ name %s\n \
+ x %d\n \
+ y %d\n \
+ }",
+ i + 2, // layout already has the device part as part1, so start from part2
+ p->name,
+ xoffset + x_margin,
+ y
+ );
+ y += p->height + y_margin;
+ aconfig_load(layout, strdup(tmp));
+ }
+}
+
+int
+load_dynamic_skin(AndroidHwConfig* hwConfig,
+ char** skinDirPath,
+ int width,
+ int height,
+ AConfig* root)
+{
+ char tmp[1024];
+ AConfig* node;
+ int i;
+ int max_part_width;
+
+ *skinDirPath = avdInfo_getDynamicSkinPath(android_avdInfo);
+ if (*skinDirPath == NULL) {
+ dwarning("Unable to locate dynamic skin directory. Will not use dynamic skin.");
+ return 0;
+ }
+
+ snprintf(tmp, sizeof(tmp), "%s/layout", *skinDirPath);
+ D("trying to load skin file '%s'", tmp);
+
+ if(aconfig_load_file(root, tmp) < 0) {
+ dwarning("could not load skin file '%s', won't use a skin\n", tmp);
+ return 0;
+ }
+
+ /* Fix the width and height specified for the "device" part in the layout */
+ node = aconfig_find(root, "parts");
+ if (node != NULL) {
+ node = aconfig_find(node, "device");
+ if (node != NULL) {
+ node = aconfig_find(node, "display");
+ if (node != NULL) {
+ snprintf(tmp, sizeof tmp, "%d", width);
+ aconfig_set(node, "width", strdup(tmp));
+ snprintf(tmp, sizeof tmp, "%d", height);
+ aconfig_set(node, "height", strdup(tmp));
+ }
+ }
+ }
+
+ /* The dynamic layout declares all the parts that are available statically
+ in the layout file. Now we need to dynamically generate the
+ appropriate layout based on the hardware config */
+
+ part_properties* props = read_all_part_properties(aconfig_find(root, "parts"));
+
+ const int N_PARTS = 4;
+ char* parts[N_PARTS];
+ parts[0] = "basic_controls";
+ parts[1] = hwConfig->hw_mainKeys ? "hwkeys_on" : "hwkeys_off";
+ parts[2] = hwConfig->hw_dPad ? "dpad_on" : "dpad_off";
+ parts[3] = hwConfig->hw_keyboard ? "keyboard_on" : "keyboard_off";
+
+ for (i = 0, max_part_width = 0; i < N_PARTS; i++) {
+ part_properties *p = get_part_properties(props, parts[i]);
+ if (p != NULL && p->width > max_part_width)
+ max_part_width = p->width;
+ }
+
+ int x_margin = 10;
+ int y_margin = 10;
+ snprintf(tmp, sizeof tmp,
+ "layouts {\n \
+ portrait {\n \
+ width %d\n \
+ height %d\n \
+ color 0x404040\n \
+ event EV_SW:0:1\n \
+ part1 {\n name device\n x 0\n y 0\n}\n \
+ }\n \
+ landscape {\n \
+ width %d\n \
+ height %d\n \
+ color 0x404040\n \
+ event EV_SW:0:0\n \
+ dpad-rotation 3\n \
+ part1 {\n name device\n x 0\n y %d\n rotation 3\n }\n \
+ }\n \
+ }\n \
+ }\n",
+ width + max_part_width + 2 * x_margin,
+ height,
+ height + max_part_width + 2 * x_margin,
+ width,
+ width);
+ aconfig_load(root, strdup(tmp));
+
+ /* Add parts to portrait orientation */
+ node = aconfig_find(root, "layouts");
+ if (node != NULL) {
+ node = aconfig_find(node, "portrait");
+ if (node != NULL) {
+ add_parts_to_layout(node, parts, N_PARTS, props, width, x_margin, y_margin);
+ }
+ }
+
+ /* Add parts to landscape orientation */
+ node = aconfig_find(root, "layouts");
+ if (node != NULL) {
+ node = aconfig_find(node, "landscape");
+ if (node != NULL) {
+ add_parts_to_layout(node, parts, N_PARTS, props, height, x_margin, y_margin);
+ }
+ }
+
+ free_all_part_properties(props);
+
+ return 1;
+}
+
+/* list of skin aliases */
+static const struct {
+ const char* name;
+ const char* alias;
+} skin_aliases[] = {
+ { "QVGA-L", "320x240" },
+ { "QVGA-P", "240x320" },
+ { "HVGA-L", "480x320" },
+ { "HVGA-P", "320x480" },
+ { "QVGA", "320x240" },
+ { "HVGA", "320x480" },
+ { NULL, NULL }
+};
+
+void
+parse_skin_files(const char* skinDirPath,
+ const char* skinName,
+ AndroidOptions* opts,
+ AndroidHwConfig* hwConfig,
+ AConfig* *skinConfig,
+ char* *skinPath)
+{
+ char tmp[1024];
+ AConfig* root;
+ const char* path = NULL;
+ AConfig* n;
+
+ root = aconfig_node("", "");
+
+ if (skinName == NULL)
+ goto DEFAULT_SKIN;
+
+ /* Support skin aliases like QVGA-H QVGA-P, etc...
+ But first we check if it's a directory that exist before applying
+ the alias */
+ int checkAlias = 1;
+
+ if (skinDirPath != NULL) {
+ bufprint(tmp, tmp+sizeof(tmp), "%s/%s", skinDirPath, skinName);
+ if (path_exists(tmp)) {
+ checkAlias = 0;
+ } else {
+ D("there is no '%s' skin in '%s'", skinName, skinDirPath);
+ }
+ }
+
+ if (checkAlias) {
+ int nn;
+
+ for (nn = 0; ; nn++ ) {
+ const char* skin_name = skin_aliases[nn].name;
+ const char* skin_alias = skin_aliases[nn].alias;
+
+ if (!skin_name)
+ break;
+
+ if (!strcasecmp( skin_name, skinName )) {
+ D("skin name '%s' aliased to '%s'", skinName, skin_alias);
+ skinName = skin_alias;
+ break;
+ }
+ }
+ }
+
+ /* Magically support skins like "320x240" or "320x240x16" */
+ if(isdigit(skinName[0])) {
+ char *x = strchr(skinName, 'x');
+ if(x && isdigit(x[1])) {
+ int width = atoi(skinName);
+ int height = atoi(x+1);
+ int bpp = 16;
+ char* y = strchr(x+1, 'x');
+ if (y && isdigit(y[1])) {
+ bpp = atoi(y+1);
+ }
+
+ if (opts->dynamic_skin) {
+ char *dynamicSkinDirPath;
+ if (load_dynamic_skin(hwConfig, &dynamicSkinDirPath, width, height, root)) {
+ path = dynamicSkinDirPath;
+ D("loaded dynamic skin width=%d height=%d bpp=%d\n", width, height, bpp);
+ goto FOUND_SKIN;
+ }
+ }
+
+ snprintf(tmp, sizeof tmp,
+ "display {\n width %d\n height %d\n bpp %d}\n",
+ width, height,bpp);
+ aconfig_load(root, strdup(tmp));
+ path = ":";
+ D("found magic skin width=%d height=%d bpp=%d\n", width, height, bpp);
+ goto FOUND_SKIN;
+ }
+ }
+
+ if (skinDirPath == NULL) {
+ derror("unknown skin name '%s'", skinName);
+ exit(1);
+ }
+
+ snprintf(tmp, sizeof tmp, "%s/%s/layout", skinDirPath, skinName);
+ D("trying to load skin file '%s'", tmp);
+
+ if(aconfig_load_file(root, tmp) < 0) {
+ dwarning("could not load skin file '%s', using built-in one\n",
+ tmp);
+ goto DEFAULT_SKIN;
+ }
+
+ snprintf(tmp, sizeof tmp, "%s/%s/", skinDirPath, skinName);
+ path = tmp;
+ goto FOUND_SKIN;
+
+FOUND_SKIN:
+ /* the default network speed and latency can now be specified by the device skin */
+ n = aconfig_find(root, "network");
+ if (n != NULL) {
+ skin_network_speed = aconfig_str(n, "speed", 0);
+ skin_network_delay = aconfig_str(n, "delay", 0);
+ }
+
+ /* extract framebuffer information from the skin.
+ *
+ * for version 1 of the skin format, they are in the top-level
+ * 'display' element.
+ *
+ * for version 2 of the skin format, they are under parts.device.display
+ */
+ n = aconfig_find(root, "display");
+ if (n == NULL) {
+ n = aconfig_find(root, "parts");
+ if (n != NULL) {
+ n = aconfig_find(n, "device");
+ if (n != NULL) {
+ n = aconfig_find(n, "display");
+ }
+ }
+ }
+
+ if (n != NULL) {
+ int width = aconfig_int(n, "width", hwConfig->hw_lcd_width);
+ int height = aconfig_int(n, "height", hwConfig->hw_lcd_height);
+ int depth = aconfig_int(n, "bpp", hwConfig->hw_lcd_depth);
+
+ if (width > 0 && height > 0) {
+ /* The emulated framebuffer wants sizes that are multiples of 4 */
+ if (((width|height) & 3) != 0) {
+ width = (width+3) & ~3;
+ height = (height+3) & ~3;
+ D("adjusting LCD dimensions to (%dx%dx)", width, height);
+ }
+
+ /* only depth values of 16 and 32 are correct. 16 is the default. */
+ if (depth != 32 && depth != 16) {
+ depth = 16;
+ D("adjusting LCD bit depth to %d", depth);
+ }
+
+ hwConfig->hw_lcd_width = width;
+ hwConfig->hw_lcd_height = height;
+ hwConfig->hw_lcd_depth = depth;
+ }
+ else {
+ D("ignoring invalid skin LCD dimensions (%dx%dx%d)",
+ width, height, depth);
+ }
+ }
+
+ *skinConfig = root;
+ *skinPath = strdup(path);
+ return;
+
+DEFAULT_SKIN:
+ {
+ const unsigned char* layout_base;
+ size_t layout_size;
+ char* base;
+
+ skinName = "<builtin>";
+
+ layout_base = android_resource_find( "layout", &layout_size );
+ if (layout_base == NULL) {
+ fprintf(stderr, "Couldn't load builtin skin\n");
+ exit(1);
+ }
+ base = malloc( layout_size+1 );
+ memcpy( base, layout_base, layout_size );
+ base[layout_size] = 0;
+
+ D("parsing built-in skin layout file (%d bytes)", (int)layout_size);
+ aconfig_load(root, base);
+ path = ":";
+ }
+ goto FOUND_SKIN;
+}
+
+
+void
+init_sdl_ui(AConfig* skinConfig,
+ const char* skinPath,
+ AndroidOptions* opts)
+{
+ int win_x, win_y, flags;
+
+ signal(SIGINT, SIG_DFL);
+#ifndef _WIN32
+ signal(SIGQUIT, SIG_DFL);
+#endif
+
+ /* we're not a game, so allow the screensaver to run */
+ setenv("SDL_VIDEO_ALLOW_SCREENSAVER","1",1);
+
+ flags = SDL_INIT_NOPARACHUTE;
+ if (!opts->no_window)
+ flags |= SDL_INIT_VIDEO;
+
+ if(SDL_Init(flags)){
+ fprintf(stderr, "SDL init failure, reason is: %s\n", SDL_GetError() );
+ exit(1);
+ }
+
+ if (!opts->no_window) {
+ SDL_EnableUNICODE(!opts->raw_keys);
+ SDL_EnableKeyRepeat(0,0);
+
+ sdl_set_window_icon();
+ }
+ else
+ {
+#ifndef _WIN32
+ /* prevent SIGTTIN and SIGTTOUT from stopping us. this is necessary to be
+ * able to run the emulator in the background (e.g. "emulator &").
+ * despite the fact that the emulator should not grab input or try to
+ * write to the output in normal cases, we're stopped on some systems
+ * (e.g. OS X)
+ */
+ signal(SIGTTIN, SIG_IGN);
+ signal(SIGTTOU, SIG_IGN);
+#endif
+ }
+ atexit(sdl_at_exit);
+
+ user_config_get_window_pos(&win_x, &win_y);
+
+ if ( qemulator_init(qemulator_get(), skinConfig, skinPath, win_x, win_y, opts) < 0 ) {
+ fprintf(stderr, "### Error: could not load emulator skin from '%s'\n", skinPath);
+ exit(1);
+ }
+
+ /* add an onion overlay image if needed */
+ if (opts->onion) {
+ SkinImage* onion = skin_image_find_simple( opts->onion );
+ int alpha, rotate;
+
+ if ( opts->onion_alpha && 1 == sscanf( opts->onion_alpha, "%d", &alpha ) ) {
+ alpha = (256*alpha)/100;
+ } else
+ alpha = 128;
+
+ if ( opts->onion_rotation && 1 == sscanf( opts->onion_rotation, "%d", &rotate ) ) {
+ rotate &= 3;
+ } else
+ rotate = SKIN_ROTATION_0;
+
+ qemulator_get()->onion = onion;
+ qemulator_get()->onion_alpha = alpha;
+ qemulator_get()->onion_rotation = rotate;
+ }
+}
diff --git a/android/main-common.c b/android/main-common.c
index 990c44b..ed3c584 100644
--- a/android/main-common.c
+++ b/android/main-common.c
@@ -9,39 +9,28 @@
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
*/
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <fcntl.h>
-#ifdef _WIN32
-#include <process.h>
-#endif
-
-#include <SDL.h>
-#include <SDL_syswm.h>
-
-#include "ui/console.h"
-
#include "android/avd/util.h"
+#include "android/utils/bufprint.h"
#include "android/utils/debug.h"
#include "android/utils/eintr_wrapper.h"
#include "android/utils/path.h"
-#include "android/utils/bufprint.h"
#include "android/utils/dirscanner.h"
#include "android/main-common.h"
#include "android/globals.h"
#include "android/resource.h"
#include "android/user-config.h"
-#include "android/qemulator.h"
-#include "android/display.h"
-#include "android/skin/image.h"
-#include "android/skin/trackball.h"
-#include "android/skin/keyboard.h"
-#include "android/skin/file.h"
-#include "android/skin/window.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#ifdef _WIN32
+#include <process.h>
+#endif
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
/***********************************************************************/
@@ -54,40 +43,9 @@
#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
-/*** CONFIGURATION
- ***/
-
-static AUserConfig* userConfig;
-
-void
-user_config_init( void )
-{
- userConfig = auserConfig_new( android_avdInfo );
-}
-
-/* only call this function on normal exits, so that ^C doesn't save the configuration */
-void
-user_config_done( void )
-{
- int win_x, win_y;
-
- if (!userConfig) {
- D("no user configuration?");
- return;
- }
-
- SDL_WM_GetPos( &win_x, &win_y );
- auserConfig_setWindowPos(userConfig, win_x, win_y);
- auserConfig_save(userConfig);
-}
-
-void
-user_config_get_window_pos( int *window_x, int *window_y )
-{
- *window_x = *window_y = 10;
-
- if (userConfig)
- auserConfig_getWindowPos(userConfig, window_x, window_y);
+void reassign_string(char** string, const char* new_value) {
+ free(*string);
+ *string = ASTRDUP(new_value);
}
unsigned convertBytesToMB( uint64_t size )
@@ -107,692 +65,6 @@
return ((uint64_t)megaBytes << 20);
}
-
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** K E Y S E T R O U T I N E S *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-
-#define KEYSET_FILE "default.keyset"
-
-SkinKeyset* android_keyset = NULL;
-
-static int
-load_keyset(const char* path)
-{
- if (path_can_read(path)) {
- AConfig* root = aconfig_node("","");
- if (!aconfig_load_file(root, path)) {
- android_keyset = skin_keyset_new(root);
- if (android_keyset != NULL) {
- D( "keyset loaded from: %s", path);
- return 0;
- }
- }
- }
- return -1;
-}
-
-void
-parse_keyset(const char* keyset, AndroidOptions* opts)
-{
- char kname[MAX_PATH];
- char temp[MAX_PATH];
- char* p;
- char* end;
-
- /* append .keyset suffix if needed */
- if (strchr(keyset, '.') == NULL) {
- p = kname;
- end = p + sizeof(kname);
- p = bufprint(p, end, "%s.keyset", keyset);
- if (p >= end) {
- derror( "keyset name too long: '%s'\n", keyset);
- exit(1);
- }
- keyset = kname;
- }
-
- /* look for a the keyset file */
- p = temp;
- end = p + sizeof(temp);
- p = bufprint_config_file(p, end, keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- p = temp;
- p = bufprint(p, end, "%s" PATH_SEP "keysets" PATH_SEP "%s", opts->sysdir, keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- p = temp;
- p = bufprint_app_dir(p, end);
- p = bufprint(p, end, PATH_SEP "keysets" PATH_SEP "%s", keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- return;
-}
-
-void
-write_default_keyset( void )
-{
- char path[MAX_PATH];
-
- bufprint_config_file( path, path+sizeof(path), KEYSET_FILE );
-
- /* only write if there is no file here */
- if (!path_exists(path)) {
- int fd = open( path, O_WRONLY | O_CREAT, 0666 );
- const char* ks = skin_keyset_get_default();
-
-
- D( "writing default keyset file to %s", path );
-
- if (fd < 0) {
- D( "%s: could not create file: %s", __FUNCTION__, strerror(errno) );
- return;
- }
- HANDLE_EINTR(write(fd, ks, strlen(ks)));
- IGNORE_EINTR(close(fd));
- }
-}
-
-
-
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** S D L S U P P O R T *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-
-void *readpng(const unsigned char* base, size_t size, unsigned *_width, unsigned *_height);
-
-#ifdef CONFIG_DARWIN
-# define ANDROID_ICON_PNG "android_icon_256.png"
-#else
-# define ANDROID_ICON_PNG "android_icon_16.png"
-#endif
-
-static void
-sdl_set_window_icon( void )
-{
- static int window_icon_set;
-
- if (!window_icon_set)
- {
-#ifdef _WIN32
- HANDLE handle = GetModuleHandle( NULL );
- HICON icon = LoadIcon( handle, MAKEINTRESOURCE(1) );
- SDL_SysWMinfo wminfo;
-
- SDL_GetWMInfo(&wminfo);
-
- SetClassLongPtr( wminfo.window, GCLP_HICON, (LONG)icon );
-#else /* !_WIN32 */
- unsigned icon_w, icon_h;
- size_t icon_bytes;
- const unsigned char* icon_data;
- void* icon_pixels;
-
- window_icon_set = 1;
-
- icon_data = android_icon_find( ANDROID_ICON_PNG, &icon_bytes );
- if ( !icon_data )
- return;
-
- icon_pixels = readpng( icon_data, icon_bytes, &icon_w, &icon_h );
- if ( !icon_pixels )
- return;
-
- /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
- * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
- * on our CPU endianess
- */
- {
- unsigned* d = icon_pixels;
- unsigned* d_end = d + icon_w*icon_h;
-
- for ( ; d < d_end; d++ ) {
- unsigned pix = d[0];
-#if HOST_WORDS_BIGENDIAN
- /* R,G,B,A read as RGBA => ARGB */
- pix = ((pix >> 8) & 0xffffff) | (pix << 24);
-#else
- /* R,G,B,A read as ABGR => ARGB */
- pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
-#endif
- d[0] = pix;
- }
- }
-
- SDL_Surface* icon = sdl_surface_from_argb32( icon_pixels, icon_w, icon_h );
- if (icon != NULL) {
- SDL_WM_SetIcon(icon, NULL);
- SDL_FreeSurface(icon);
- free( icon_pixels );
- }
-#endif /* !_WIN32 */
- }
-}
-
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** S K I N S U P P O R T *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-
-const char* skin_network_speed = NULL;
-const char* skin_network_delay = NULL;
-
-
-static void sdl_at_exit(void)
-{
- user_config_done();
- qemulator_done(qemulator_get());
- SDL_Quit();
-}
-
-
-void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
-{
- QEmulator* emulator = qemulator_get();
- SkinDisplay* disp = skin_layout_get_display(emulator->layout);
- int width, height;
- char buf[128];
-
- if (disp->rotation & 1) {
- width = disp->rect.size.h;
- height = disp->rect.size.w;
- } else {
- width = disp->rect.size.w;
- height = disp->rect.size.h;
- }
-
- snprintf(buf, sizeof buf, "width=%d,height=%d", width, height);
-#if !defined(CONFIG_STANDALONE_UI) && !defined(CONFIG_STANDALONE_CORE)
- android_display_init(ds, qframebuffer_fifo_get());
-#endif
-}
-
-typedef struct part_properties part_properties;
-struct part_properties {
- const char* name;
- int width;
- int height;
- part_properties* next;
-};
-
-part_properties*
-read_all_part_properties(AConfig* parts)
-{
- part_properties* head = NULL;
- part_properties* prev = NULL;
-
- AConfig *node = parts->first_child;
- while (node) {
- part_properties* t = calloc(1, sizeof(part_properties));
- t->name = node->name;
-
- AConfig* bg = aconfig_find(node, "background");
- if (bg != NULL) {
- t->width = aconfig_int(bg, "width", 0);
- t->height = aconfig_int(bg, "height", 0);
- }
-
- if (prev == NULL) {
- head = t;
- } else {
- prev->next = t;
- }
- prev = t;
- node = node->next;
- }
-
- return head;
-}
-
-void
-free_all_part_properties(part_properties* head)
-{
- part_properties* prev = head;
- while (head) {
- prev = head;
- head = head->next;
- free(prev);
- }
-}
-
-part_properties*
-get_part_properties(part_properties* allparts, char *partname)
-{
- part_properties* p;
- for (p = allparts; p != NULL; p = p->next) {
- if (!strcmp(partname, p->name))
- return p;
- }
-
- return NULL;
-}
-
-void
-add_parts_to_layout(AConfig* layout,
- char* parts[],
- int n_parts,
- part_properties *props,
- int xoffset,
- int x_margin,
- int y_margin)
-{
- int i;
- int y = 10;
- char tmp[512];
- for (i = 0; i < n_parts; i++) {
- part_properties *p = get_part_properties(props, parts[i]);
- snprintf(tmp, sizeof tmp,
- "part%d {\n \
- name %s\n \
- x %d\n \
- y %d\n \
- }",
- i + 2, // layout already has the device part as part1, so start from part2
- p->name,
- xoffset + x_margin,
- y
- );
- y += p->height + y_margin;
- aconfig_load(layout, strdup(tmp));
- }
-}
-
-int
-load_dynamic_skin(AndroidHwConfig* hwConfig,
- char** skinDirPath,
- int width,
- int height,
- AConfig* root)
-{
- char tmp[1024];
- AConfig* node;
- int i;
- int max_part_width;
-
- *skinDirPath = avdInfo_getDynamicSkinPath(android_avdInfo);
- if (*skinDirPath == NULL) {
- dwarning("Unable to locate dynamic skin directory. Will not use dynamic skin.");
- return 0;
- }
-
- snprintf(tmp, sizeof(tmp), "%s/layout", *skinDirPath);
- D("trying to load skin file '%s'", tmp);
-
- if(aconfig_load_file(root, tmp) < 0) {
- dwarning("could not load skin file '%s', won't use a skin\n", tmp);
- return 0;
- }
-
- /* Fix the width and height specified for the "device" part in the layout */
- node = aconfig_find(root, "parts");
- if (node != NULL) {
- node = aconfig_find(node, "device");
- if (node != NULL) {
- node = aconfig_find(node, "display");
- if (node != NULL) {
- snprintf(tmp, sizeof tmp, "%d", width);
- aconfig_set(node, "width", strdup(tmp));
- snprintf(tmp, sizeof tmp, "%d", height);
- aconfig_set(node, "height", strdup(tmp));
- }
- }
- }
-
- /* The dynamic layout declares all the parts that are available statically
- in the layout file. Now we need to dynamically generate the
- appropriate layout based on the hardware config */
-
- part_properties* props = read_all_part_properties(aconfig_find(root, "parts"));
-
- const int N_PARTS = 4;
- char* parts[N_PARTS];
- parts[0] = "basic_controls";
- parts[1] = hwConfig->hw_mainKeys ? "hwkeys_on" : "hwkeys_off";
- parts[2] = hwConfig->hw_dPad ? "dpad_on" : "dpad_off";
- parts[3] = hwConfig->hw_keyboard ? "keyboard_on" : "keyboard_off";
-
- for (i = 0, max_part_width = 0; i < N_PARTS; i++) {
- part_properties *p = get_part_properties(props, parts[i]);
- if (p != NULL && p->width > max_part_width)
- max_part_width = p->width;
- }
-
- int x_margin = 10;
- int y_margin = 10;
- snprintf(tmp, sizeof tmp,
- "layouts {\n \
- portrait {\n \
- width %d\n \
- height %d\n \
- color 0x404040\n \
- event EV_SW:0:1\n \
- part1 {\n name device\n x 0\n y 0\n}\n \
- }\n \
- landscape {\n \
- width %d\n \
- height %d\n \
- color 0x404040\n \
- event EV_SW:0:0\n \
- dpad-rotation 3\n \
- part1 {\n name device\n x 0\n y %d\n rotation 3\n }\n \
- }\n \
- }\n \
- }\n",
- width + max_part_width + 2 * x_margin,
- height,
- height + max_part_width + 2 * x_margin,
- width,
- width);
- aconfig_load(root, strdup(tmp));
-
- /* Add parts to portrait orientation */
- node = aconfig_find(root, "layouts");
- if (node != NULL) {
- node = aconfig_find(node, "portrait");
- if (node != NULL) {
- add_parts_to_layout(node, parts, N_PARTS, props, width, x_margin, y_margin);
- }
- }
-
- /* Add parts to landscape orientation */
- node = aconfig_find(root, "layouts");
- if (node != NULL) {
- node = aconfig_find(node, "landscape");
- if (node != NULL) {
- add_parts_to_layout(node, parts, N_PARTS, props, height, x_margin, y_margin);
- }
- }
-
- free_all_part_properties(props);
-
- return 1;
-}
-
-/* list of skin aliases */
-static const struct {
- const char* name;
- const char* alias;
-} skin_aliases[] = {
- { "QVGA-L", "320x240" },
- { "QVGA-P", "240x320" },
- { "HVGA-L", "480x320" },
- { "HVGA-P", "320x480" },
- { "QVGA", "320x240" },
- { "HVGA", "320x480" },
- { NULL, NULL }
-};
-
-void
-parse_skin_files(const char* skinDirPath,
- const char* skinName,
- AndroidOptions* opts,
- AndroidHwConfig* hwConfig,
- AConfig* *skinConfig,
- char* *skinPath)
-{
- char tmp[1024];
- AConfig* root;
- const char* path = NULL;
- AConfig* n;
-
- root = aconfig_node("", "");
-
- if (skinName == NULL)
- goto DEFAULT_SKIN;
-
- /* Support skin aliases like QVGA-H QVGA-P, etc...
- But first we check if it's a directory that exist before applying
- the alias */
- int checkAlias = 1;
-
- if (skinDirPath != NULL) {
- bufprint(tmp, tmp+sizeof(tmp), "%s/%s", skinDirPath, skinName);
- if (path_exists(tmp)) {
- checkAlias = 0;
- } else {
- D("there is no '%s' skin in '%s'", skinName, skinDirPath);
- }
- }
-
- if (checkAlias) {
- int nn;
-
- for (nn = 0; ; nn++ ) {
- const char* skin_name = skin_aliases[nn].name;
- const char* skin_alias = skin_aliases[nn].alias;
-
- if (!skin_name)
- break;
-
- if (!strcasecmp( skin_name, skinName )) {
- D("skin name '%s' aliased to '%s'", skinName, skin_alias);
- skinName = skin_alias;
- break;
- }
- }
- }
-
- /* Magically support skins like "320x240" or "320x240x16" */
- if(isdigit(skinName[0])) {
- char *x = strchr(skinName, 'x');
- if(x && isdigit(x[1])) {
- int width = atoi(skinName);
- int height = atoi(x+1);
- int bpp = 16;
- char* y = strchr(x+1, 'x');
- if (y && isdigit(y[1])) {
- bpp = atoi(y+1);
- }
-
- if (opts->dynamic_skin) {
- char *dynamicSkinDirPath;
- if (load_dynamic_skin(hwConfig, &dynamicSkinDirPath, width, height, root)) {
- path = dynamicSkinDirPath;
- D("loaded dynamic skin width=%d height=%d bpp=%d\n", width, height, bpp);
- goto FOUND_SKIN;
- }
- }
-
- snprintf(tmp, sizeof tmp,
- "display {\n width %d\n height %d\n bpp %d}\n",
- width, height,bpp);
- aconfig_load(root, strdup(tmp));
- path = ":";
- D("found magic skin width=%d height=%d bpp=%d\n", width, height, bpp);
- goto FOUND_SKIN;
- }
- }
-
- if (skinDirPath == NULL) {
- derror("unknown skin name '%s'", skinName);
- exit(1);
- }
-
- snprintf(tmp, sizeof tmp, "%s/%s/layout", skinDirPath, skinName);
- D("trying to load skin file '%s'", tmp);
-
- if(aconfig_load_file(root, tmp) < 0) {
- dwarning("could not load skin file '%s', using built-in one\n",
- tmp);
- goto DEFAULT_SKIN;
- }
-
- snprintf(tmp, sizeof tmp, "%s/%s/", skinDirPath, skinName);
- path = tmp;
- goto FOUND_SKIN;
-
-FOUND_SKIN:
- /* the default network speed and latency can now be specified by the device skin */
- n = aconfig_find(root, "network");
- if (n != NULL) {
- skin_network_speed = aconfig_str(n, "speed", 0);
- skin_network_delay = aconfig_str(n, "delay", 0);
- }
-
- /* extract framebuffer information from the skin.
- *
- * for version 1 of the skin format, they are in the top-level
- * 'display' element.
- *
- * for version 2 of the skin format, they are under parts.device.display
- */
- n = aconfig_find(root, "display");
- if (n == NULL) {
- n = aconfig_find(root, "parts");
- if (n != NULL) {
- n = aconfig_find(n, "device");
- if (n != NULL) {
- n = aconfig_find(n, "display");
- }
- }
- }
-
- if (n != NULL) {
- int width = aconfig_int(n, "width", hwConfig->hw_lcd_width);
- int height = aconfig_int(n, "height", hwConfig->hw_lcd_height);
- int depth = aconfig_int(n, "bpp", hwConfig->hw_lcd_depth);
-
- if (width > 0 && height > 0) {
- /* The emulated framebuffer wants sizes that are multiples of 4 */
- if (((width|height) & 3) != 0) {
- width = (width+3) & ~3;
- height = (height+3) & ~3;
- D("adjusting LCD dimensions to (%dx%dx)", width, height);
- }
-
- /* only depth values of 16 and 32 are correct. 16 is the default. */
- if (depth != 32 && depth != 16) {
- depth = 16;
- D("adjusting LCD bit depth to %d", depth);
- }
-
- hwConfig->hw_lcd_width = width;
- hwConfig->hw_lcd_height = height;
- hwConfig->hw_lcd_depth = depth;
- }
- else {
- D("ignoring invalid skin LCD dimensions (%dx%dx%d)",
- width, height, depth);
- }
- }
-
- *skinConfig = root;
- *skinPath = strdup(path);
- return;
-
-DEFAULT_SKIN:
- {
- const unsigned char* layout_base;
- size_t layout_size;
- char* base;
-
- skinName = "<builtin>";
-
- layout_base = android_resource_find( "layout", &layout_size );
- if (layout_base == NULL) {
- fprintf(stderr, "Couldn't load builtin skin\n");
- exit(1);
- }
- base = malloc( layout_size+1 );
- memcpy( base, layout_base, layout_size );
- base[layout_size] = 0;
-
- D("parsing built-in skin layout file (%d bytes)", (int)layout_size);
- aconfig_load(root, base);
- path = ":";
- }
- goto FOUND_SKIN;
-}
-
-
-void
-init_sdl_ui(AConfig* skinConfig,
- const char* skinPath,
- AndroidOptions* opts)
-{
- int win_x, win_y, flags;
-
- signal(SIGINT, SIG_DFL);
-#ifndef _WIN32
- signal(SIGQUIT, SIG_DFL);
-#endif
-
- /* we're not a game, so allow the screensaver to run */
- setenv("SDL_VIDEO_ALLOW_SCREENSAVER","1",1);
-
- flags = SDL_INIT_NOPARACHUTE;
- if (!opts->no_window)
- flags |= SDL_INIT_VIDEO;
-
- if(SDL_Init(flags)){
- fprintf(stderr, "SDL init failure, reason is: %s\n", SDL_GetError() );
- exit(1);
- }
-
- if (!opts->no_window) {
- SDL_EnableUNICODE(!opts->raw_keys);
- SDL_EnableKeyRepeat(0,0);
-
- sdl_set_window_icon();
- }
- else
- {
-#ifndef _WIN32
- /* prevent SIGTTIN and SIGTTOUT from stopping us. this is necessary to be
- * able to run the emulator in the background (e.g. "emulator &").
- * despite the fact that the emulator should not grab input or try to
- * write to the output in normal cases, we're stopped on some systems
- * (e.g. OS X)
- */
- signal(SIGTTIN, SIG_IGN);
- signal(SIGTTOU, SIG_IGN);
-#endif
- }
- atexit(sdl_at_exit);
-
- user_config_get_window_pos(&win_x, &win_y);
-
- if ( qemulator_init(qemulator_get(), skinConfig, skinPath, win_x, win_y, opts) < 0 ) {
- fprintf(stderr, "### Error: could not load emulator skin from '%s'\n", skinPath);
- exit(1);
- }
-
- /* add an onion overlay image if needed */
- if (opts->onion) {
- SkinImage* onion = skin_image_find_simple( opts->onion );
- int alpha, rotate;
-
- if ( opts->onion_alpha && 1 == sscanf( opts->onion_alpha, "%d", &alpha ) ) {
- alpha = (256*alpha)/100;
- } else
- alpha = 128;
-
- if ( opts->onion_rotation && 1 == sscanf( opts->onion_rotation, "%d", &rotate ) ) {
- rotate &= 3;
- } else
- rotate = SKIN_ROTATION_0;
-
- qemulator_get()->onion = onion;
- qemulator_get()->onion_alpha = alpha;
- qemulator_get()->onion_rotation = rotate;
- }
-}
-
/* this function is used to perform auto-detection of the
* system directory in the case of a SDK installation.
*
@@ -1141,234 +413,6 @@
return ret;
}
-
-
-
-#ifdef CONFIG_STANDALONE_UI
-
-#include "android/protocol/core-connection.h"
-#include "android/protocol/fb-updates-impl.h"
-#include "android/protocol/user-events-proxy.h"
-#include "android/protocol/core-commands-proxy.h"
-#include "android/protocol/ui-commands-impl.h"
-#include "android/protocol/attach-ui-impl.h"
-
-/* Emulator's core port. */
-int android_base_port = 0;
-
-// Base console port
-#define CORE_BASE_PORT 5554
-
-// Maximum number of core porocesses running simultaneously on a machine.
-#define MAX_CORE_PROCS 16
-
-// Socket timeout in millisec (set to 5 seconds)
-#define CORE_PORT_TIMEOUT_MS 5000
-
-#include "android/async-console.h"
-
-typedef struct {
- LoopIo io[1];
- int port;
- int ok;
- AsyncConsoleConnector connector[1];
-} CoreConsole;
-
-static void
-coreconsole_io_func(void* opaque, int fd, unsigned events)
-{
- CoreConsole* cc = opaque;
- AsyncStatus status;
- status = asyncConsoleConnector_run(cc->connector);
- if (status == ASYNC_COMPLETE) {
- cc->ok = 1;
- }
-}
-
-static void
-coreconsole_init(CoreConsole* cc, const SockAddress* address, Looper* looper)
-{
- int fd = socket_create_inet(SOCKET_STREAM);
- AsyncStatus status;
- cc->port = sock_address_get_port(address);
- cc->ok = 0;
- loopIo_init(cc->io, looper, fd, coreconsole_io_func, cc);
- if (fd >= 0) {
- status = asyncConsoleConnector_connect(cc->connector, address, cc->io);
- if (status == ASYNC_ERROR) {
- cc->ok = 0;
- }
- }
-}
-
-static void
-coreconsole_done(CoreConsole* cc)
-{
- socket_close(cc->io->fd);
- loopIo_done(cc->io);
-}
-
-/* List emulator core processes running on the given machine.
- * This routine is called from main() if -list-cores parameter is set in the
- * command line.
- * Param:
- * host Value passed with -list-core parameter. Must be either "localhost", or
- * an IP address of a machine where core processes must be enumerated.
- */
-static void
-list_running_cores(const char* host)
-{
- Looper* looper;
- CoreConsole cores[MAX_CORE_PROCS];
- SockAddress address;
- int nn, found;
-
- if (sock_address_init_resolve(&address, host, CORE_BASE_PORT, 0) < 0) {
- derror("Unable to resolve hostname %s: %s", host, errno_str);
- return;
- }
-
- looper = looper_newGeneric();
-
- for (nn = 0; nn < MAX_CORE_PROCS; nn++) {
- int port = CORE_BASE_PORT + nn*2;
- sock_address_set_port(&address, port);
- coreconsole_init(&cores[nn], &address, looper);
- }
-
- looper_runWithTimeout(looper, CORE_PORT_TIMEOUT_MS*2);
-
- found = 0;
- for (nn = 0; nn < MAX_CORE_PROCS; nn++) {
- int port = CORE_BASE_PORT + nn*2;
- if (cores[nn].ok) {
- if (found == 0) {
- fprintf(stdout, "Running emulator core processes:\n");
- }
- fprintf(stdout, "Emulator console port %d\n", port);
- found++;
- }
- coreconsole_done(&cores[nn]);
- }
- looper_free(looper);
-
- if (found == 0) {
- fprintf(stdout, "There were no running emulator core processes found on %s.\n",
- host);
- }
-}
-
-/* Attaches starting UI to a running core process.
- * This routine is called from main() when -attach-core parameter is set,
- * indicating that this UI instance should attach to a running core, rather than
- * start a new core process.
- * Param:
- * opts Android options containing non-NULL attach_core.
- * Return:
- * 0 on success, or -1 on failure.
- */
-static int
-attach_to_core(AndroidOptions* opts) {
- int iter;
- SockAddress console_socket;
- SockAddress** sockaddr_list;
- QEmulator* emulator;
-
- // Parse attach_core param extracting the host name, and the port name.
- char* console_address = strdup(opts->attach_core);
- char* host_name = console_address;
- char* port_num = strchr(console_address, ':');
- if (port_num == NULL) {
- // The host name is ommited, indicating the localhost
- host_name = "localhost";
- port_num = console_address;
- } else if (port_num == console_address) {
- // Invalid.
- derror("Invalid value %s for -attach-core parameter\n",
- opts->attach_core);
- return -1;
- } else {
- *port_num = '\0';
- port_num++;
- if (*port_num == '\0') {
- // Invalid.
- derror("Invalid value %s for -attach-core parameter\n",
- opts->attach_core);
- return -1;
- }
- }
-
- /* Create socket address list for the given address, and pull appropriate
- * address to use for connection. Note that we're fine copying that address
- * out of the list, since INET and IN6 will entirely fit into SockAddress
- * structure. */
- sockaddr_list =
- sock_address_list_create(host_name, port_num, SOCKET_LIST_FORCE_INET);
- free(console_address);
- if (sockaddr_list == NULL) {
- derror("Unable to resolve address %s: %s\n",
- opts->attach_core, errno_str);
- return -1;
- }
- for (iter = 0; sockaddr_list[iter] != NULL; iter++) {
- if (sock_address_get_family(sockaddr_list[iter]) == SOCKET_INET ||
- sock_address_get_family(sockaddr_list[iter]) == SOCKET_IN6) {
- memcpy(&console_socket, sockaddr_list[iter], sizeof(SockAddress));
- break;
- }
- }
- if (sockaddr_list[iter] == NULL) {
- derror("Unable to resolve address %s. Note that 'port' parameter passed to -attach-core\n"
- "must be resolvable into an IP address.\n", opts->attach_core);
- sock_address_list_free(sockaddr_list);
- return -1;
- }
- sock_address_list_free(sockaddr_list);
-
- if (attachUiImpl_create(&console_socket)) {
- return -1;
- }
-
- // Save core's port, and set the title.
- android_base_port = sock_address_get_port(&console_socket);
- emulator = qemulator_get();
- qemulator_set_title(emulator);
-
- return 0;
-}
-
-
-void handle_ui_options( AndroidOptions* opts )
-{
- // Lets see if user just wants to list core process.
- if (opts->list_cores) {
- fprintf(stdout, "Enumerating running core processes.\n");
- list_running_cores(opts->list_cores);
- exit(0);
- }
-}
-
-int attach_ui_to_core( AndroidOptions* opts )
-{
- // Lets see if we're attaching to a running core process here.
- if (opts->attach_core) {
- if (attach_to_core(opts)) {
- return -1;
- }
- // Connect to the core's UI control services.
- if (coreCmdProxy_create(attachUiImpl_get_console_socket())) {
- return -1;
- }
- // Connect to the core's user events service.
- if (userEventsProxy_create(attachUiImpl_get_console_socket())) {
- return -1;
- }
- }
- return 0;
-}
-
-#else /* !CONFIG_STANDALONE_UI */
-
void handle_ui_options( AndroidOptions* opts )
{
return;
@@ -1378,5 +422,3 @@
{
return 0;
}
-
-#endif /* CONFIG_STANDALONE_UI */
diff --git a/android/main-common.h b/android/main-common.h
index 523e441..53c9029 100644
--- a/android/main-common.h
+++ b/android/main-common.h
@@ -13,13 +13,20 @@
#define ANDROID_MAIN_COMMON_H
#include <stdint.h>
-#include "android/cmdline-option.h"
-#include "android/skin/keyset.h"
-#include "android/config-file.h"
#include "android/avd/hw-config.h"
+#include "android/cmdline-option.h"
+#include "android/config-file.h"
+#include "android/skin/keyset.h"
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
/* Common routines used by both android/main.c and android/main-ui.c */
+// Reset the value of |*string| to a copy of |new_value|. This
+// will free() the previous value of |*string| first.
+void reassign_string(char** string, const char* new_value);
+
/** Emulator user configuration (e.g. last window position)
**/
@@ -103,4 +110,6 @@
*/
int attach_ui_to_core( AndroidOptions* opts );
+ANDROID_END_HEADER
+
#endif /* ANDROID_MAIN_COMMON_H */
diff --git a/android/main-emulator.c b/android/main-emulator.c
index 3f09c33..f9f2976 100644
--- a/android/main-emulator.c
+++ b/android/main-emulator.c
@@ -332,6 +332,22 @@
}
}
+ // Special case: for arm64, first try to find emulator-arm64 before
+ // looking for emulator-arm.
+ if (!strcmp(avdArch, "arm64")) {
+ emulatorSuffix = "arm64";
+
+ D("Looking for emulator backend for %s CPU\n", avdArch);
+
+ result = probeTargetEmulatorPath(progDir,
+ emulatorSuffix,
+ search_for_64bit_emulator,
+ try_current_path);
+ if (result) {
+ return result;
+ }
+ }
+
// Now for the regular case.
emulatorSuffix = emulator_getBackendSuffix(avdArch);
if (!emulatorSuffix) {
diff --git a/android/main.c b/android/main.c
index 4f48291..b1a3053 100644
--- a/android/main.c
+++ b/android/main.c
@@ -405,14 +405,11 @@
/* Update CPU architecture for HW configs created from build dir. */
if (inAndroidBuild) {
#if defined(TARGET_ARM)
- free(android_hw->hw_cpu_arch);
- android_hw->hw_cpu_arch = ASTRDUP("arm");
+ reassign_string(&android_hw->hw_cpu_arch, "arm");
#elif defined(TARGET_I386)
- free(android_hw->hw_cpu_arch);
- android_hw->hw_cpu_arch = ASTRDUP("x86");
+ reassign_string(&android_hw->hw_cpu_arch, "x86");
#elif defined(TARGET_MIPS)
- free(android_hw->hw_cpu_arch);
- android_hw->hw_cpu_arch = ASTRDUP("mips");
+ reassign_string(&android_hw->hw_cpu_arch, "mips");
#endif
}
@@ -472,8 +469,7 @@
} else {
D("Auto-detect: Kernel image requires legacy device naming scheme.");
}
- AFREE(hw->kernel_newDeviceNaming);
- hw->kernel_newDeviceNaming = ASTRDUP(newDeviceNaming);
+ reassign_string(&hw->kernel_newDeviceNaming, newDeviceNaming);
}
// Auto-detect YAFFS2 partition support if needed.
@@ -486,8 +482,7 @@
} else {
D("Auto-detect: Kernel does not support YAFFS2 partitions.");
}
- AFREE(hw->kernel_supportsYaffs2);
- hw->kernel_supportsYaffs2 = ASTRDUP(newYaffs2Support);
+ reassign_string(&hw->kernel_supportsYaffs2, newYaffs2Support);
}
if (boot_prop_ip[0]) {
@@ -541,8 +536,7 @@
/* opts->ramdisk is never NULL (see createAVD) here */
if (opts->ramdisk) {
- AFREE(hw->disk_ramdisk_path);
- hw->disk_ramdisk_path = ASTRDUP(opts->ramdisk);
+ reassign_string(&hw->disk_ramdisk_path, opts->ramdisk);
}
else if (!hw->disk_ramdisk_path[0]) {
hw->disk_ramdisk_path = avdInfo_getRamdiskPath(avd);
@@ -1157,8 +1151,7 @@
*/
kcm_extract_charmap_name(opts->charmap, charmap_name,
sizeof(charmap_name));
- AFREE(hw->hw_keyboard_charmap);
- hw->hw_keyboard_charmap = ASTRDUP(charmap_name);
+ reassign_string(&hw->hw_keyboard_charmap, charmap_name);
}
if (opts->gpu) {
@@ -1247,8 +1240,7 @@
exit(1);
}
} else {
- AFREE(opts->accel);
- opts->accel = ASTRDUP("off");
+ reassign_string(&opts->accel, "off");
}
}
@@ -1382,8 +1374,7 @@
}
if (forceArmv7 != 0) {
- AFREE(hw->hw_cpu_model);
- hw->hw_cpu_model = ASTRDUP("cortex-a8");
+ reassign_string(&hw->hw_cpu_model, "cortex-a8");
D("Auto-config: -qemu -cpu %s", hw->hw_cpu_model);
}
@@ -1396,8 +1387,7 @@
char* arch = avdInfo_getTargetCpuArch(avd);
D("Target arch = '%s'", arch ? arch : "NULL");
if (arch != NULL && !strcmp(arch, "x86")) {
- AFREE(hw->hw_cpu_model);
- hw->hw_cpu_model = ASTRDUP("qemu32");
+ reassign_string(&hw->hw_cpu_model, "qemu32");
D("Auto-config: -qemu -cpu %s", hw->hw_cpu_model);
}
AFREE(arch);
diff --git a/android/opengles.c b/android/opengles.c
index 2570429..0d7855c 100644
--- a/android/opengles.c
+++ b/android/opengles.c
@@ -110,10 +110,8 @@
}
-#ifndef CONFIG_STANDALONE_UI
/* Defined in android/hw-pipe-net.c */
extern int android_init_opengles_pipes(void);
-#endif
static ADynamicLibrary* rendererLib;
static int rendererStarted;
@@ -135,10 +133,7 @@
return -1;
}
-#ifndef CONFIG_STANDALONE_UI
android_init_opengles_pipes();
-#endif
-
/* Resolve the functions */
if (initOpenglesEmulationFuncs(rendererLib) < 0) {
diff --git a/android/protocol/attach-ui-impl.c b/android/protocol/attach-ui-impl.c
deleted file mode 100644
index a61e546..0000000
--- a/android/protocol/attach-ui-impl.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the UI-side implementation of the "core-ui-control" service that is
- * part of the UI control protocol. Here we handle UI control commands received
- * from the Core.
- */
-
-#include "android/utils/debug.h"
-#include "android/utils/panic.h"
-#include "android/protocol/core-connection.h"
-#include "android/protocol/attach-ui-impl.h"
-
-/* Descriptor for the UI-side of the "attach-ui" service. */
-typedef struct AttachUIImpl {
- /* Address of the Core's console socket. */
- SockAddress console_socket;
-
- /* Core connection established for this service. */
- CoreConnection* core_connection;
-
- /* Socket descriptor for the UI service. */
- int sock;
-} AttachUIImpl;
-
-/* One and only one AttachUIImpl instance. */
-static AttachUIImpl _attachUiImpl;
-
-SockAddress*
-attachUiImpl_get_console_socket(void)
-{
- return &_attachUiImpl.console_socket;
-}
-
-int
-attachUiImpl_create(SockAddress* console_socket)
-{
- char* handshake = NULL;
-
- _attachUiImpl.console_socket = *console_socket;
-
- // Connect to the core-ui-control service.
- _attachUiImpl.core_connection =
- core_connection_create_and_switch(console_socket, "attach-UI",
- &handshake);
- if (_attachUiImpl.core_connection == NULL) {
- derror("Unable to connect to the attach-UI service: %s\n",
- errno_str);
- return -1;
- }
-
- fprintf(stdout, "UI is now attached to the core at %s.",
- sock_address_to_string(console_socket));
- if (handshake != NULL) {
- if (handshake[0] != '\0') {
- fprintf(stdout, " Handshake: %s", handshake);
- }
- free(handshake);
- }
- fprintf(stdout, "\n");
-
- return 0;
-}
-
-void
-attachUiImpl_destroy(void)
-{
- if (_attachUiImpl.core_connection != NULL) {
- core_connection_close(_attachUiImpl.core_connection);
- core_connection_free(_attachUiImpl.core_connection);
- _attachUiImpl.core_connection = NULL;
- }
-}
diff --git a/android/protocol/attach-ui-impl.h b/android/protocol/attach-ui-impl.h
deleted file mode 100644
index db63955..0000000
--- a/android/protocol/attach-ui-impl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_ATTACH_UI_IMPL_H
-#define _ANDROID_PROTOCOL_ATTACH_UI_IMPL_H
-
-#include "android/sockets.h"
-
-/*
- * Contains the UI-side implementation of the "attach-ui" service that is
- * used to establish connection between the UI and the Core.
- */
-
-/* Creates and initializes descriptor for the UI-side of the "atatch-ui"
- * service. Note that there can be only one instance of this service in the core.
- * Param:
- * console_socket - Addresses Core's console.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int attachUiImpl_create(SockAddress* console_socket);
-
-/* Destroys the descriptor for the UI-side of the "attach-ui" service. */
-extern void attachUiImpl_destroy(void);
-
-/* Gets Core's console socket address for the attached UI. */
-extern SockAddress* attachUiImpl_get_console_socket(void);
-
-#endif /* _ANDROID_PROTOCOL_ATTACH_UI_IMPL_H */
-
diff --git a/android/protocol/attach-ui-proxy.c b/android/protocol/attach-ui-proxy.c
deleted file mode 100644
index a0bc7fc..0000000
--- a/android/protocol/attach-ui-proxy.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the Core-side implementation of the "attach-ui" service that is
- * used to establish connection between the UI and the Core.
- */
-
-#include "android/android.h"
-#include "android/globals.h"
-#include "android/looper.h"
-#include "android/async-utils.h"
-#include "android/sync-utils.h"
-#include "android/utils/debug.h"
-#include "android/protocol/core-commands.h"
-#include "android/protocol/core-commands-impl.h"
-
-/* Descriptor for the UI attach-ui proxy. */
-typedef struct AttachUIProxy {
- /* Reader to detect UI disconnection. */
- AsyncReader async_reader;
-
- /* I/O associated with this descriptor. */
- LoopIo io;
-
- /* Looper used to communicate with the UI. */
- Looper* looper;
-
- /* Socket descriptor for this service. */
- int sock;
-} AttachUIProxy;
-
-/* One and only one AttachUIProxy instance. */
-static AttachUIProxy _attachUiProxy;
-
-/* Implemented in android/console.c */
-extern void destroy_attach_ui_client(void);
-
-/* Asynchronous I/O callback for AttachUIProxy instance.
- * We expect this callback to be called only on UI detachment condition. In this
- * case the event should be LOOP_IO_READ, and read should fail with errno set
- * to ECONNRESET.
- * Param:
- * opaque - AttachUIProxy instance.
- */
-static void
-_attachUiProxy_io_func(void* opaque, int fd, unsigned events)
-{
- AttachUIProxy* uicmd = (AttachUIProxy*)opaque;
- AsyncReader reader;
- AsyncStatus status;
- uint8_t read_buf[1];
-
- if (events & LOOP_IO_WRITE) {
- derror("Unexpected LOOP_IO_WRITE in _attachUiProxy_io_func.\n");
- return;
- }
-
- // Try to read
- asyncReader_init(&reader, read_buf, sizeof(read_buf), &uicmd->io);
- status = asyncReader_read(&reader);
- // We expect only error status here.
- if (status != ASYNC_ERROR) {
- derror("Unexpected read status %d in _attachUiProxy_io_func\n", status);
- return;
- }
- // We expect only socket disconnection error here.
- if (errno != ECONNRESET) {
- derror("Unexpected read error %d (%s) in _attachUiProxy_io_func.\n",
- errno, errno_str);
- return;
- }
-
- // Client got disconnectted.
- destroy_attach_ui_client();
-}
-
-int
-attachUiProxy_create(int fd)
-{
- // Initialize the only AttachUIProxy instance.
- _attachUiProxy.sock = fd;
- _attachUiProxy.looper = looper_newCore();
- loopIo_init(&_attachUiProxy.io, _attachUiProxy.looper, _attachUiProxy.sock,
- _attachUiProxy_io_func, &_attachUiProxy);
- loopIo_wantRead(&_attachUiProxy.io);
-
- return 0;
-}
-
-void
-attachUiProxy_destroy(void)
-{
- if (_attachUiProxy.looper != NULL) {
- // Stop all I/O that may still be going on.
- loopIo_done(&_attachUiProxy.io);
- looper_free(_attachUiProxy.looper);
- _attachUiProxy.looper = NULL;
- }
- _attachUiProxy.sock = -1;
-}
diff --git a/android/protocol/attach-ui-proxy.h b/android/protocol/attach-ui-proxy.h
deleted file mode 100644
index a7d54f4..0000000
--- a/android/protocol/attach-ui-proxy.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_ATTACH_UI_PROXY_H
-#define _ANDROID_PROTOCOL_ATTACH_UI_PROXY_H
-
-/*
- * Contains the Core-side implementation of the "attach-ui" service that is
- * used to establish connection between the UI and the Core.
- */
-
-/* Creates and initializes descriptor for the Core-side of the "atatch-ui"
- * service. Note that there can be only one instance of this service in the core.
- * Param:
- * fd - Socket descriptor for the proxy.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int attachUiProxy_create(int fd);
-
-/* Destroys the descriptor for the Core-side of the "attach-ui" service. */
-extern void attachUiProxy_destroy(void);
-
-#endif /* _ANDROID_PROTOCOL_ATTACH_UI_PROXY_H */
diff --git a/android/protocol/core-commands-api.h b/android/protocol/core-commands-api.h
deleted file mode 100644
index 93a569c..0000000
--- a/android/protocol/core-commands-api.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_CORE_COMMANDS_API_H
-#define _ANDROID_PROTOCOL_CORE_COMMANDS_API_H
-
-/*
- * Contains the API for calling into the Core with UI control commands.
- */
-
-#include "android/android.h"
-#include "android/hw-sensors.h"
-
-/* Instructs the Core to change the coarse orientation.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int corecmd_set_coarse_orientation(AndroidCoarseOrientation orient);
-
-/* Toggles the network in the Core.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int corecmd_toggle_network();
-
-/* Starts or stops tracing in the Core.
- * Param:
- * start - Starts (> 0), or stops (== 0) tracing.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int corecmd_trace_control(int start);
-
-/* Checks if network is disabled in the Core.
- * Return:
- * 0 if network is enabled, 1 if it is disabled, or < 0 on failure.
- */
-extern int corecmd_is_network_disabled();
-
-/* Requests a NetworkSpeed instance from the Core.
- * Param:
- * index - Index of an entry in the NetworkSpeed array.
- * netspeed - Upon success contains allocated and initialized NetworkSpeed
- * instance for the given index. Note that strings addressed by "name" and
- * "display" fileds in the returned NetworkSpeed instance are containd
- * inside the buffer allocated for the returned NetworkSpeed instance.
- * Caller of this routine must eventually free the buffer returned in this
- * parameter.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int corecmd_get_netspeed(int index, NetworkSpeed** netspeed);
-
-/* Requests a NetworkLatency instance from the Core.
- * Param:
- * index - Index of an entry in the NetworkLatency array.
- * netdelay - Upon success contains allocated and initialized NetworkLatency
- * instance for the given index. Note that strings addressed by "name" and
- * "display" fileds in the returned NetworkLatency instance are containd
- * inside the buffer allocated for the returned NetworkLatency instance.
- * Caller of this routine must eventually free the buffer returned in this
- * parameter.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int corecmd_get_netdelay(int index, NetworkLatency** netdelay);
-
-/* Requests a QEMU file path from the Core.
- * Param:
- * type, filename - Request parameters that define the file for which path is
- * requested.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int corecmd_get_qemu_path(int type,
- const char* filename,
- char* path,
- size_t path_buf_size);
-
-/* Gets LCD density property from the core properties.
- * Return:
- * LCD density on success, or < 0 on failure.
- */
-extern int corecmd_get_hw_lcd_density(void);
-
-#endif /* _ANDROID_PROTOCOL_CORE_COMMANDS_API_H */
diff --git a/android/protocol/core-commands-impl.c b/android/protocol/core-commands-impl.c
deleted file mode 100644
index 8ca18c0..0000000
--- a/android/protocol/core-commands-impl.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the Core-side implementation of the "ui-core-control" service that is
- * part of the UI control protocol. Here we handle UI control commands sent by
- * the UI to the Core.
- */
-
-#include "android/android.h"
-#include "android/globals.h"
-#include "telephony/modem_driver.h"
-#include "android/trace.h"
-#include "android/looper.h"
-#include "android/async-utils.h"
-#include "android/sync-utils.h"
-#include "android/utils/debug.h"
-#include "android/protocol/core-commands.h"
-#include "android/protocol/core-commands-impl.h"
-
-/* Enumerates state values for the command reader in the CoreCmdImpl descriptor.
- */
-typedef enum CoreCmdImplState {
- /* The reader is waiting on command header. */
- EXPECTS_HEADER,
-
- /* The reader is waiting on command parameters. */
- EXPECTS_PARAMETERS,
-} CoreCmdImplState;
-
-/* Descriptor for the Core-side implementation of the "ui-core-control" service.
- */
-typedef struct CoreCmdImpl {
- /* Reader to detect UI disconnection. */
- AsyncReader async_reader;
-
- /* I/O associated with this descriptor. */
- LoopIo io;
-
- /* Looper used to communicate with the UI. */
- Looper* looper;
-
- /* Writer to send responses to the UI commands. */
- SyncSocket* sync_writer;
-
- /* Socket descriptor for this service. */
- int sock;
-
- /* Command reader state. */
- CoreCmdImplState cmd_state;
-
- /* Incoming command header. */
- UICmdHeader cmd_header;
-
- /* A small preallocated buffer for command parameters. */
- uint8_t cmd_param[256];
-
- /* Buffer to use for reading command parameters. Depending on expected size
- * of the parameters this buffer can point to cmd_param field of this
- * structure (for small commands), or can be allocated for large commands. */
- void* cmd_param_buf;
-} CoreCmdImpl;
-
-/* One and only one CoreCmdImpl instance. */
-static CoreCmdImpl _coreCmdImpl;
-
-/* Implemented in android/console.c */
-extern void destroy_corecmd_client(void);
-/* Implemented in vl-android.c */
-extern char* qemu_find_file(int type, const char* filename);
-
-/* Properly initializes cmd_param_buf field in CoreCmdImpl instance to receive
- * the expected command parameters.
- */
-static uint8_t*
-_alloc_cmd_param_buf(CoreCmdImpl* corecmd, uint32_t size)
-{
- if (size < sizeof(corecmd->cmd_param)) {
- // cmd_param can contain all request data.
- corecmd->cmd_param_buf = &corecmd->cmd_param[0];
- } else {
- // Expected request us too large to fit into preallocated buffer.
- corecmd->cmd_param_buf = g_malloc(size);
- }
- return corecmd->cmd_param_buf;
-}
-
-/* Properly frees cmd_param_buf field in CoreCmdImpl instance.
- */
-static void
-_free_cmd_param_buf(CoreCmdImpl* corecmd)
-{
- if (corecmd->cmd_param_buf != &corecmd->cmd_param[0]) {
- g_free(corecmd->cmd_param_buf);
- corecmd->cmd_param_buf = &corecmd->cmd_param[0];
- }
-}
-
-/* Calculates timeout for transferring the given number of bytes via socket.
- * Return:
- * Number of milliseconds during which the entire number of bytes is expected
- * to be transferred via socket for this service.
- */
-static int
-_coreCmdImpl_get_timeout(size_t data_size)
-{
- // Min 2 seconds + 10 millisec for each transferring byte.
- // TODO: Come up with a better arithmetics here.
- return 2000 + data_size * 10;
-}
-
-/* Sends command response back to the UI.
- * Param:
- * corecmd - CoreCmdImpl instance to use to send the response.
- * resp - Response header.
- * resp_data - Response data. Data size is defined by the header.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-static int
-_coreCmdImpl_respond(CoreCmdImpl* corecmd, UICmdRespHeader* resp, void* resp_data)
-{
- int status = syncsocket_start_write(corecmd->sync_writer);
- if (!status) {
- // Write the header
- status = syncsocket_write(corecmd->sync_writer, resp,
- sizeof(UICmdRespHeader),
- _coreCmdImpl_get_timeout(sizeof(UICmdRespHeader)));
- // Write response data (if any).
- if (status > 0 && resp_data != NULL && resp->resp_data_size != 0) {
- status = syncsocket_write(corecmd->sync_writer, resp_data,
- resp->resp_data_size,
- _coreCmdImpl_get_timeout(resp->resp_data_size));
- }
- status = syncsocket_result(status);
- syncsocket_stop_write(corecmd->sync_writer);
- }
- if (status < 0) {
- derror("Core is unable to respond with %u bytes to the UI control command: %s\n",
- resp->resp_data_size, errno_str);
- }
- return status;
-}
-
-/* Handles UI control command received from the UI.
- * Param:
- * corecmd - CoreCmdImpl instance that received the command.
- * cmd_header - Command header.
- * cmd_param - Command data.
- */
-static void
-_coreCmdImpl_handle_command(CoreCmdImpl* corecmd,
- const UICmdHeader* cmd_header,
- const uint8_t* cmd_param)
-{
- switch (cmd_header->cmd_type) {
- case AUICMD_SET_COARSE_ORIENTATION:
- {
- UICmdSetCoarseOrientation* cmd =
- (UICmdSetCoarseOrientation*)cmd_param;
- android_sensors_set_coarse_orientation(cmd->orient);
- break;
- }
-
- case AUICMD_TOGGLE_NETWORK:
- qemu_net_disable = !qemu_net_disable;
- if (android_modem) {
- amodem_set_data_registration(
- android_modem,
- qemu_net_disable ? A_REGISTRATION_UNREGISTERED
- : A_REGISTRATION_HOME);
- }
- break;
-
- case AUICMD_TRACE_CONTROL:
- {
- UICmdTraceControl* cmd = (UICmdTraceControl*)cmd_param;
- if (cmd->start) {
- start_tracing();
- } else {
- stop_tracing();
- }
- break;
- }
-
- case AUICMD_CHK_NETWORK_DISABLED:
- {
- UICmdRespHeader resp;
- resp.resp_data_size = 0;
- resp.result = qemu_net_disable;
- _coreCmdImpl_respond(corecmd, &resp, NULL);
- break;
- }
-
- case AUICMD_GET_NETSPEED:
- {
- UICmdRespHeader resp;
- UICmdGetNetSpeedResp* resp_data = NULL;
- UICmdGetNetSpeed* cmd = (UICmdGetNetSpeed*)cmd_param;
-
- resp.resp_data_size = 0;
- resp.result = 0;
-
- if (cmd->index >= android_netspeeds_count ||
- android_netspeeds[cmd->index].name == NULL) {
- resp.result = -1;
- } else {
- const NetworkSpeed* netspeed = &android_netspeeds[cmd->index];
- // Calculate size of the response data:
- // fixed header + zero-terminated netspeed name.
- resp.resp_data_size = sizeof(UICmdGetNetSpeedResp) +
- strlen(netspeed->name) + 1;
- // Count in zero-terminated netspeed display.
- if (netspeed->display != NULL) {
- resp.resp_data_size += strlen(netspeed->display) + 1;
- } else {
- resp.resp_data_size++;
- }
- // Allocate and initialize response data buffer.
- resp_data =
- (UICmdGetNetSpeedResp*)g_malloc(resp.resp_data_size);
- resp_data->upload = netspeed->upload;
- resp_data->download = netspeed->download;
- strcpy(resp_data->name, netspeed->name);
- if (netspeed->display != NULL) {
- strcpy(resp_data->name + strlen(resp_data->name) + 1,
- netspeed->display);
- } else {
- strcpy(resp_data->name + strlen(resp_data->name) + 1, "");
- }
- }
- _coreCmdImpl_respond(corecmd, &resp, resp_data);
- if (resp_data != NULL) {
- g_free(resp_data);
- }
- break;
- }
-
- case AUICMD_GET_NETDELAY:
- {
- UICmdRespHeader resp;
- UICmdGetNetDelayResp* resp_data = NULL;
- UICmdGetNetDelay* cmd = (UICmdGetNetDelay*)cmd_param;
-
- resp.resp_data_size = 0;
- resp.result = 0;
-
- if (cmd->index >= android_netdelays_count ||
- android_netdelays[cmd->index].name == NULL) {
- resp.result = -1;
- } else {
- const NetworkLatency* netdelay = &android_netdelays[cmd->index];
- // Calculate size of the response data:
- // fixed header + zero-terminated netdelay name.
- resp.resp_data_size = sizeof(UICmdGetNetDelayResp) +
- strlen(netdelay->name) + 1;
- // Count in zero-terminated netdelay display.
- if (netdelay->display != NULL) {
- resp.resp_data_size += strlen(netdelay->display) + 1;
- } else {
- resp.resp_data_size++;
- }
- // Allocate and initialize response data buffer.
- resp_data =
- (UICmdGetNetDelayResp*)g_malloc(resp.resp_data_size);
- resp_data->min_ms = netdelay->min_ms;
- resp_data->max_ms = netdelay->max_ms;
- strcpy(resp_data->name, netdelay->name);
- if (netdelay->display != NULL) {
- strcpy(resp_data->name + strlen(resp_data->name) + 1,
- netdelay->display);
- } else {
- strcpy(resp_data->name + strlen(resp_data->name) + 1, "");
- }
- }
- _coreCmdImpl_respond(corecmd, &resp, resp_data);
- if (resp_data != NULL) {
- g_free(resp_data);
- }
- break;
- }
-
- case AUICMD_GET_QEMU_PATH:
- {
- UICmdRespHeader resp;
- UICmdGetQemuPath* cmd = (UICmdGetQemuPath*)cmd_param;
- char* filepath = NULL;
-
- resp.resp_data_size = 0;
- resp.result = -1;
- filepath = qemu_find_file(cmd->type, cmd->filename);
- if (filepath != NULL) {
- resp.resp_data_size = strlen(filepath) + 1;
- }
- _coreCmdImpl_respond(corecmd, &resp, filepath);
- if (filepath != NULL) {
- g_free(filepath);
- }
- break;
- }
-
- case AUICMD_GET_LCD_DENSITY:
- {
- UICmdRespHeader resp;
- resp.resp_data_size = 0;
- resp.result = android_hw->hw_lcd_density;
- _coreCmdImpl_respond(corecmd, &resp, NULL);
- break;
- }
-
- default:
- derror("Unknown UI control command %d is received by the Core.\n",
- cmd_header->cmd_type);
- break;
- }
-}
-
-/* Asynchronous I/O callback reading UI control commands.
- * Param:
- * opaque - CoreCmdImpl instance.
- * events - Lists I/O event (read or write) this callback is called for.
- */
-static void
-_coreCmdImpl_io_func(void* opaque, int fd, unsigned events)
-{
- AsyncStatus status;
- CoreCmdImpl* corecmd;
-
- if (events & LOOP_IO_WRITE) {
- // We don't use async writer here, so we don't expect
- // any write callbacks.
- derror("Unexpected LOOP_IO_WRITE in _coreCmdImpl_io_func\n");
- return;
- }
-
- corecmd = (CoreCmdImpl*)opaque;
-
- // Read whatever is expected from the socket.
- status = asyncReader_read(&corecmd->async_reader);
- switch (status) {
- case ASYNC_COMPLETE:
- switch (corecmd->cmd_state) {
- case EXPECTS_HEADER:
- // We just read the command header. Now we expect the param.
- if (corecmd->cmd_header.cmd_param_size != 0) {
- corecmd->cmd_state = EXPECTS_PARAMETERS;
- // Setup the reader to read expected amount of data.
- _alloc_cmd_param_buf(corecmd,
- corecmd->cmd_header.cmd_param_size);
- asyncReader_init(&corecmd->async_reader,
- corecmd->cmd_param_buf,
- corecmd->cmd_header.cmd_param_size,
- &corecmd->io);
- } else {
- // Command doesn't have param. Go ahead and handle it.
- _coreCmdImpl_handle_command(corecmd, &corecmd->cmd_header,
- NULL);
- // Prepare for the next header.
- corecmd->cmd_state = EXPECTS_HEADER;
- asyncReader_init(&corecmd->async_reader,
- &corecmd->cmd_header,
- sizeof(corecmd->cmd_header),
- &corecmd->io);
- }
- break;
-
- case EXPECTS_PARAMETERS:
- // Entore command is received. Handle it.
- _coreCmdImpl_handle_command(corecmd, &corecmd->cmd_header,
- corecmd->cmd_param_buf);
- _free_cmd_param_buf(corecmd);
- // Prepare for the next command.
- corecmd->cmd_state = EXPECTS_HEADER;
- asyncReader_init(&corecmd->async_reader, &corecmd->cmd_header,
- sizeof(corecmd->cmd_header), &corecmd->io);
- break;
- }
- break;
-
- case ASYNC_ERROR:
- loopIo_dontWantRead(&corecmd->io);
- if (errno == ECONNRESET) {
- // UI has exited. We need to destroy the service.
- destroy_corecmd_client();
- }
- break;
-
- case ASYNC_NEED_MORE:
- // Transfer will eventually come back into this routine.
- return;
- }
-}
-
-int
-coreCmdImpl_create(int fd)
-{
- _coreCmdImpl.sock = fd;
- _coreCmdImpl.looper = looper_newCore();
- loopIo_init(&_coreCmdImpl.io, _coreCmdImpl.looper, _coreCmdImpl.sock,
- _coreCmdImpl_io_func, &_coreCmdImpl);
- _coreCmdImpl.cmd_state = EXPECTS_HEADER;
- _coreCmdImpl.cmd_param_buf = &_coreCmdImpl.cmd_param[0];
- asyncReader_init(&_coreCmdImpl.async_reader, &_coreCmdImpl.cmd_header,
- sizeof(_coreCmdImpl.cmd_header), &_coreCmdImpl.io);
- _coreCmdImpl.sync_writer = syncsocket_init(fd);
- if (_coreCmdImpl.sync_writer == NULL) {
- derror("Unable to create writer for CoreCmdImpl instance: %s\n",
- errno_str);
- coreCmdImpl_destroy();
- return -1;
- }
- return 0;
-}
-
-void
-coreCmdImpl_destroy()
-{
- // Destroy the writer
- if (_coreCmdImpl.sync_writer != NULL) {
- syncsocket_close(_coreCmdImpl.sync_writer);
- syncsocket_free(_coreCmdImpl.sync_writer);
- }
- if (_coreCmdImpl.looper != NULL) {
- // Stop all I/O that may still be going on.
- loopIo_done(&_coreCmdImpl.io);
- looper_free(_coreCmdImpl.looper);
- _coreCmdImpl.looper = NULL;
- }
- // Free allocated memory.
- _free_cmd_param_buf(&_coreCmdImpl);
-}
diff --git a/android/protocol/core-commands-impl.h b/android/protocol/core-commands-impl.h
deleted file mode 100644
index 8690613..0000000
--- a/android/protocol/core-commands-impl.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_CORE_COMMANDS_IMPL_H
-#define _ANDROID_PROTOCOL_CORE_COMMANDS_IMPL_H
-
-/*
- * Contains the Core-side implementation of the "ui-core-control" service that is
- * part of the UI control protocol. Here we handle UI control commands sent by
- * the UI to the Core.
- */
-
-/* Creates and initializes descriptor for the Core-side of the "ui-core-control"
- * service. Note that there can be only one instance of this service in the core.
- * Param:
- * fd - Socket descriptor for the service.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int coreCmdImpl_create(int fd);
-
-/* Destroys the descriptor for the Core-side of the "ui-core-control" service. */
-extern void coreCmdImpl_destroy();
-
-#endif /* _ANDROID_PROTOCOL_CORE_COMMANDS_IMPL_H */
diff --git a/android/protocol/core-commands-proxy.c b/android/protocol/core-commands-proxy.c
deleted file mode 100644
index 3449952..0000000
--- a/android/protocol/core-commands-proxy.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the UI-side implementation of the "ui-core-control" service that is
- * part of the UI control protocol. Here we send UI control commands to the Core.
- */
-
-#include "ui/console.h"
-#include "android/looper.h"
-#include "android/async-utils.h"
-#include "android/sync-utils.h"
-#include "android/utils/debug.h"
-#include "android/utils/panic.h"
-#include "android/protocol/core-connection.h"
-#include "android/protocol/core-commands.h"
-#include "android/protocol/core-commands-proxy.h"
-#include "android/protocol/core-commands-api.h"
-
-/* Descriptor for the UI-side "ui-core-control" service. */
-typedef struct CoreCmdProxy {
- /* Core connection established for this service. */
- CoreConnection* core_connection;
-
- /* Socket descriptor for the UI service. */
- int sock;
-
- /* Socket wrapper for sync srites. */
- SyncSocket* sync_writer;
-
- /* Socket wrapper for sync reads. */
- SyncSocket* sync_reader;
-} CoreCmdProxy;
-
-/* One and only one CoreCmdProxy instance. */
-static CoreCmdProxy _coreCmdProxy = { 0 };
-
-/* Sends UI command to the core.
- * Param:
- * cmd_type, cmd_param, cmd_param_size - Define the command.
- * Return:
- * 0 On success, or < 0 on failure.
- */
-static int
-_coreCmdProxy_send_command(uint8_t cmd_type,
- void* cmd_param,
- uint32_t cmd_param_size)
-{
- int status;
- UICmdHeader header;
-
- // Prepare the command header.
- header.cmd_type = cmd_type;
- header.cmd_param_size = cmd_param_size;
- status = syncsocket_start_write(_coreCmdProxy.sync_writer);
- if (!status) {
- // Send the header.
- status = syncsocket_write(_coreCmdProxy.sync_writer, &header,
- sizeof(header),
- core_connection_get_timeout(sizeof(header)));
- // If there is request data, send it too.
- if (status > 0 && cmd_param != NULL && cmd_param_size > 0) {
- status = syncsocket_write(_coreCmdProxy.sync_writer, cmd_param,
- cmd_param_size,
- core_connection_get_timeout(cmd_param_size));
- }
- status = syncsocket_result(status);
- syncsocket_stop_write(_coreCmdProxy.sync_writer);
- }
- if (status < 0) {
- derror("Unable to send UI control command %d (size %u): %s\n",
- cmd_type, cmd_param_size, errno_str);
- }
- return status;
-}
-
-/* Reads UI control command response from the core.
- * Param:
- * resp - Upon success contains command response header.
- * resp_data - Upon success contains allocated reponse data (if any). The caller
- * is responsible for deallocating the memory returned here.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-static int
-_coreCmdProxy_get_response(UICmdRespHeader* resp, void** resp_data)
-{
- int status = syncsocket_start_read(_coreCmdProxy.sync_reader);
- if (!status) {
- // Read the header.
- status = syncsocket_read(_coreCmdProxy.sync_reader, resp,
- sizeof(UICmdRespHeader),
- core_connection_get_timeout(sizeof(UICmdRespHeader)));
- // Read response data (if any).
- if (status > 0 && resp->resp_data_size) {
- *resp_data = malloc(resp->resp_data_size);
- if (*resp_data == NULL) {
- APANIC("_coreCmdProxy_get_response is unable to allocate response data buffer.\n");
- }
- status = syncsocket_read(_coreCmdProxy.sync_reader, *resp_data,
- resp->resp_data_size,
- core_connection_get_timeout(resp->resp_data_size));
- }
- status = syncsocket_result(status);
- syncsocket_stop_read(_coreCmdProxy.sync_reader);
- }
- if (status < 0) {
- derror("Unable to get UI command response from the Core: %s\n",
- errno_str);
- }
- return status;
-}
-
-int
-corecmd_set_coarse_orientation(AndroidCoarseOrientation orient)
-{
- UICmdSetCoarseOrientation cmd;
- cmd.orient = orient;
- return _coreCmdProxy_send_command(AUICMD_SET_COARSE_ORIENTATION,
- &cmd, sizeof(cmd));
-}
-
-int
-corecmd_toggle_network()
-{
- return _coreCmdProxy_send_command(AUICMD_TOGGLE_NETWORK, NULL, 0);
-}
-
-int
-corecmd_trace_control(int start)
-{
- UICmdTraceControl cmd;
- cmd.start = start;
- return _coreCmdProxy_send_command(AUICMD_TRACE_CONTROL,
- &cmd, sizeof(cmd));
-}
-
-int
-corecmd_is_network_disabled()
-{
- UICmdRespHeader resp;
- void* tmp = NULL;
- int status;
-
- status = _coreCmdProxy_send_command(AUICMD_CHK_NETWORK_DISABLED, NULL, 0);
- if (status < 0) {
- return status;
- }
- status = _coreCmdProxy_get_response(&resp, &tmp);
- if (status < 0) {
- return status;
- }
- return resp.result;
-}
-
-int
-corecmd_get_netspeed(int index, NetworkSpeed** netspeed)
-{
- UICmdGetNetSpeed req;
- UICmdRespHeader resp;
- UICmdGetNetSpeedResp* resp_data = NULL;
- int status;
-
- // Initialize and send the query.
- req.index = index;
- status = _coreCmdProxy_send_command(AUICMD_GET_NETSPEED, &req, sizeof(req));
- if (status < 0) {
- return status;
- }
-
- // Obtain the response from the core.
- status = _coreCmdProxy_get_response(&resp, (void**)&resp_data);
- if (status < 0) {
- return status;
- }
- if (!resp.result) {
- NetworkSpeed* ret;
- // Allocate memory for the returning NetworkSpeed instance.
- // It includes: NetworkSpeed structure +
- // size of zero-terminated "name" and "display" strings saved in
- // resp_data.
- *netspeed = malloc(sizeof(NetworkSpeed) + 1 +
- resp.resp_data_size - sizeof(UICmdGetNetSpeedResp));
- ret = *netspeed;
-
- // Copy data obtained from the core to the returning NetworkSpeed
- // instance.
- ret->upload = resp_data->upload;
- ret->download = resp_data->download;
- ret->name = (char*)ret + sizeof(NetworkSpeed);
- strcpy((char*)ret->name, resp_data->name);
- ret->display = ret->name + strlen(ret->name) + 1;
- strcpy((char*)ret->display, resp_data->name + strlen(resp_data->name) + 1);
- }
- if (resp_data != NULL) {
- free(resp_data);
- }
- return resp.result;
-}
-
-int
-corecmd_get_netdelay(int index, NetworkLatency** netdelay)
-{
- UICmdGetNetDelay req;
- UICmdRespHeader resp;
- UICmdGetNetDelayResp* resp_data = NULL;
- int status;
-
- // Initialize and send the query.
- req.index = index;
- status = _coreCmdProxy_send_command(AUICMD_GET_NETDELAY, &req, sizeof(req));
- if (status < 0) {
- return status;
- }
-
- // Obtain the response from the core.
- status = _coreCmdProxy_get_response(&resp, (void**)&resp_data);
- if (status < 0) {
- return status;
- }
- if (!resp.result) {
- NetworkLatency* ret;
- // Allocate memory for the returning NetworkLatency instance.
- // It includes: NetworkLatency structure +
- // size of zero-terminated "name" and "display" strings saved in
- // resp_data.
- *netdelay = malloc(sizeof(NetworkLatency) + 1 +
- resp.resp_data_size - sizeof(UICmdGetNetDelayResp));
- ret = *netdelay;
-
- // Copy data obtained from the core to the returning NetworkLatency
- // instance.
- ret->min_ms = resp_data->min_ms;
- ret->max_ms = resp_data->max_ms;
- ret->name = (char*)ret + sizeof(NetworkLatency);
- strcpy((char*)ret->name, resp_data->name);
- ret->display = ret->name + strlen(ret->name) + 1;
- strcpy((char*)ret->display, resp_data->name + strlen(resp_data->name) + 1);
- }
- if (resp_data != NULL) {
- free(resp_data);
- }
- return resp.result;
-}
-
-int
-corecmd_get_qemu_path(int type,
- const char* filename,
- char* path,
- size_t path_buf_size)
-{
- UICmdRespHeader resp;
- char* resp_data = NULL;
- int status;
-
- // Initialize and send the query.
- uint32_t cmd_data_size = sizeof(UICmdGetQemuPath) + strlen(filename) + 1;
- UICmdGetQemuPath* req = (UICmdGetQemuPath*)malloc(cmd_data_size);
- if (req == NULL) {
- APANIC("corecmd_get_qemu_path is unable to allocate %u bytes\n",
- cmd_data_size);
- }
- req->type = type;
- strcpy(req->filename, filename);
- status = _coreCmdProxy_send_command(AUICMD_GET_QEMU_PATH, req,
- cmd_data_size);
- if (status < 0) {
- return status;
- }
-
- // Obtain the response from the core.
- status = _coreCmdProxy_get_response(&resp, (void**)&resp_data);
- if (status < 0) {
- return status;
- }
- if (!resp.result && resp_data != NULL) {
- strncpy(path, resp_data, path_buf_size);
- path[path_buf_size - 1] = '\0';
- }
- if (resp_data != NULL) {
- free(resp_data);
- }
- return resp.result;
-}
-
-int
-corecmd_get_hw_lcd_density(void)
-{
- UICmdRespHeader resp;
- void* tmp = NULL;
- int status;
-
- status = _coreCmdProxy_send_command(AUICMD_GET_LCD_DENSITY, NULL, 0);
- if (status < 0) {
- return status;
- }
- status = _coreCmdProxy_get_response(&resp, &tmp);
- if (status < 0) {
- return status;
- }
- return resp.result;
-}
-
-int
-coreCmdProxy_create(SockAddress* console_socket)
-{
- char* handshake = NULL;
-
- // Connect to the ui-core-control service.
- _coreCmdProxy.core_connection =
- core_connection_create_and_switch(console_socket, "ui-core-control",
- &handshake);
- if (_coreCmdProxy.core_connection == NULL) {
- derror("Unable to connect to the ui-core-control service: %s\n",
- errno_str);
- return -1;
- }
-
- // Initialze command writer and response reader.
- _coreCmdProxy.sock = core_connection_get_socket(_coreCmdProxy.core_connection);
- _coreCmdProxy.sync_writer = syncsocket_init(_coreCmdProxy.sock);
- if (_coreCmdProxy.sync_writer == NULL) {
- derror("Unable to initialize CoreCmdProxy writer: %s\n", errno_str);
- coreCmdProxy_destroy();
- return -1;
- }
- _coreCmdProxy.sync_reader = syncsocket_init(_coreCmdProxy.sock);
- if (_coreCmdProxy.sync_reader == NULL) {
- derror("Unable to initialize CoreCmdProxy reader: %s\n", errno_str);
- coreCmdProxy_destroy();
- return -1;
- }
-
-
- fprintf(stdout, "ui-core-control is now connected to the core at %s.",
- sock_address_to_string(console_socket));
- if (handshake != NULL) {
- if (handshake[0] != '\0') {
- fprintf(stdout, " Handshake: %s", handshake);
- }
- free(handshake);
- }
- fprintf(stdout, "\n");
-
- return 0;
-}
-
-/* Destroys CoreCmdProxy instance. */
-void
-coreCmdProxy_destroy(void)
-{
- if (_coreCmdProxy.sync_writer != NULL) {
- syncsocket_close(_coreCmdProxy.sync_writer);
- syncsocket_free(_coreCmdProxy.sync_writer);
- _coreCmdProxy.sync_writer = NULL;
- }
- if (_coreCmdProxy.sync_reader != NULL) {
- syncsocket_close(_coreCmdProxy.sync_reader);
- syncsocket_free(_coreCmdProxy.sync_reader);
- _coreCmdProxy.sync_reader = NULL;
- }
- if (_coreCmdProxy.core_connection != NULL) {
- core_connection_close(_coreCmdProxy.core_connection);
- core_connection_free(_coreCmdProxy.core_connection);
- _coreCmdProxy.core_connection = NULL;
- }
-}
diff --git a/android/protocol/core-commands-proxy.h b/android/protocol/core-commands-proxy.h
deleted file mode 100644
index 289421f..0000000
--- a/android/protocol/core-commands-proxy.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_CORE_COMMANDS_PROXY_H
-#define _ANDROID_PROTOCOL_CORE_COMMANDS_PROXY_H
-
-#include "android/sockets.h"
-
-/*
- * Contains the UI-side implementation of the "ui-core-control" service that is
- * part of the UI control protocol. Here we send UI control commands to the Core.
- */
-
-/* Creates and initializes descriptor for the UI-side of the "ui-core-control"
- * service. Note that there can be only one instance of this service in the UI.
- * Param:
- * console_socket - Addresses Core's console.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int coreCmdProxy_create(SockAddress* console_socket);
-
-/* Destroys the UI-side of the "ui-core-control" */
-void coreCmdProxy_destroy(void);
-
-#endif /* _ANDROID_PROTOCOL_CORE_COMMANDS_PROXY_H */
diff --git a/android/protocol/core-commands-qemu.c b/android/protocol/core-commands-qemu.c
deleted file mode 100644
index d26840c..0000000
--- a/android/protocol/core-commands-qemu.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains implementation of the API for calling into the Core with the UI
- * control commands for standalone (monolithic) emulator.
- */
-
-#include "android/android.h"
-#include "android/globals.h"
-#include "android/hw-sensors.h"
-#include "telephony/modem_driver.h"
-#include "audio/audio.h"
-#include "android/protocol/core-commands-api.h"
-
-/* Implemented in vl-android.c */
-extern char* qemu_find_file(int type, const char* filename);
-
-int
-corecmd_set_coarse_orientation(AndroidCoarseOrientation orient)
-{
- android_sensors_set_coarse_orientation(orient);
- return 0;
-}
-
-int
-corecmd_toggle_network()
-{
- qemu_net_disable = !qemu_net_disable;
- if (android_modem) {
- amodem_set_data_registration(
- android_modem,
- qemu_net_disable ? A_REGISTRATION_UNREGISTERED
- : A_REGISTRATION_HOME);
- }
- return 0;
-}
-
-int corecmd_trace_control(int start)
-{
- return 0;
-}
-
-int corecmd_is_network_disabled()
-{
- return qemu_net_disable;
-}
-
-int
-corecmd_get_netspeed(int index, NetworkSpeed** netspeed)
-{
- if (index >= android_netspeeds_count ||
- android_netspeeds[index].name == NULL) {
- return -1;
- }
- *netspeed = (NetworkSpeed*)malloc(sizeof(NetworkSpeed));
- memcpy(*netspeed, &android_netspeeds[index], sizeof(NetworkSpeed));
- return 0;
-}
-
-int
-corecmd_get_netdelay(int index, NetworkLatency** netdelay)
-{
- if (index >= android_netdelays_count ||
- android_netdelays[index].name == NULL) {
- return -1;
- }
- *netdelay = (NetworkLatency*)malloc(sizeof(NetworkLatency));
- memcpy(*netdelay, &android_netdelays[index], sizeof(NetworkLatency));
- return 0;
-}
-
-int
-corecmd_get_qemu_path(int type,
- const char* filename,
- char* path,
- size_t path_buf_size)
-{
- char* filepath = qemu_find_file(type, filename);
- if (filepath == NULL) {
- return -1;
- }
- strncpy(path, filepath, path_buf_size);
- path[path_buf_size - 1] = '\0';
- g_free(filepath);
- return 0;
-}
-
-int
-corecmd_get_hw_lcd_density(void)
-{
- return android_hw->hw_lcd_density;
-}
diff --git a/android/protocol/core-commands.h b/android/protocol/core-commands.h
deleted file mode 100644
index 3ac0ca5..0000000
--- a/android/protocol/core-commands.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_CORE_COMMANDS_H
-#define _ANDROID_PROTOCOL_CORE_COMMANDS_H
-
-/*
- * Contains declarations related to the UI control commands sent by the UI and
- * handled by the Core.
- */
-
-#include "android/hw-sensors.h"
-#include "android/protocol/ui-common.h"
-
-/* Sets coarse orientation. */
-#define AUICMD_SET_COARSE_ORIENTATION 1
-
-/* Toggles the network. */
-#define AUICMD_TOGGLE_NETWORK 2
-
-/* Starts / stops the tracing. */
-#define AUICMD_TRACE_CONTROL 3
-
-/* Checks if network is disabled. */
-#define AUICMD_CHK_NETWORK_DISABLED 4
-
-/* Gets network speed. */
-#define AUICMD_GET_NETSPEED 5
-
-/* Gets network delays */
-#define AUICMD_GET_NETDELAY 6
-
-/* Gets path to a QEMU file on local host. */
-#define AUICMD_GET_QEMU_PATH 7
-
-/* Gets LCD density. */
-#define AUICMD_GET_LCD_DENSITY 8
-
-/* Formats AUICMD_SET_COARSE_ORIENTATION UI control command parameters. */
-typedef struct UICmdSetCoarseOrientation {
- AndroidCoarseOrientation orient;
-} UICmdSetCoarseOrientation;
-
-/* Formats AUICMD_TRACE_CONTROL UI control command parameters. */
-typedef struct UICmdTraceControl {
- int start;
-} UICmdTraceControl;
-
-/* Formats AUICMD_GET_NETSPEED UI control command parameters. */
-typedef struct UICmdGetNetSpeed {
- int index;
-} UICmdGetNetSpeed;
-
-/* Formats AUICMD_GET_NETSPEED UI control command response.
- * Instances of this structure contains content of the NetworkSpeed structure,
- * including actual "name" and "display" strings. */
-typedef struct UICmdGetNetSpeedResp {
- int upload;
- int download;
- /* Zero-terminated NetworkSpeed's "name" strings starts here. The "display"
- * string begins inside this structure, right after the "name"'s
- * zero-terminator. */
- char name[0];
-} UICmdGetNetSpeedResp;
-
-/* Formats AUICMD_GET_NETDELAY UI control command parameters. */
-typedef struct UICmdGetNetDelay {
- int index;
-} UICmdGetNetDelay;
-
-/* Formats AUICMD_GET_NETDELAY UI control command response.
- * Instances of this structure contains content of the NetworkLatency structure,
- * including actual "name" and "display" strings. */
-typedef struct UICmdGetNetDelayResp {
- int min_ms;
- int max_ms;
- /* Zero-terminated NetworkLatency's "name" strings starts here. The "display"
- * string begins inside this structure, right after the "name"'s
- * zero-terminator. */
- char name[0];
-} UICmdGetNetDelayResp;
-
-/* Formats AUICMD_GET_QEMU_PATH UI control command parameters. */
-typedef struct UICmdGetQemuPath {
- int type;
- char filename[0];
-} UICmdGetQemuPath;
-
-/* Formats AUICMD_GET_QEMU_PATH UI control command response. */
-typedef struct UICmdGetQemuPathResp {
- /* Queried qemu path begins here. */
- char path[0];
-} UICmdGetQemuPathResp;
-
-#endif /* _ANDROID_PROTOCOL_CORE_COMMANDS_H */
diff --git a/android/protocol/core-connection.c b/android/protocol/core-connection.c
deleted file mode 100644
index 68831d4..0000000
--- a/android/protocol/core-connection.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* Copyright (C) 2010 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 <unistd.h>
-
-#include "android/sockets.h"
-#include "qemu-common.h"
-#include "errno.h"
-#include "android/iolooper.h"
-#include "android/android.h"
-#include "android/utils/debug.h"
-#include "android/globals.h"
-#include "android/utils/system.h"
-#include "android/protocol/core-connection.h"
-
-/* Descriptor for a client, connected to the core via console port. */
-struct CoreConnection {
- /* Socket address of the console. */
- SockAddress console_address;
-
- // Helper for performing sync I/O on the console socket.
- SyncSocket* ssocket;
-
- /* Stream name. Can be:
- * - NULL for the console itself.
- * - "attach-UI" for the attached UI client.
- */
- char* stream_name;
-};
-
-/*
- * Zero-terminates string buffer.
- * Param:
- * buf - Buffer containing the string.
- * buf_size - Buffer size.
- * eos - String size.
- */
-static inline void
-_zero_terminate(char* buf, size_t buf_size, size_t eos)
-{
- if (eos < buf_size) {
- buf[eos] = '\0';
- } else {
- buf[buf_size - 1] = '\0';
- }
-}
-
-/*
- * Checks if console has replied with "OK"
- * Param:
- * reply - String containing console's reply
- * Return:
- * boolean: true if reply was "OK", or false otherwise.
- */
-static int
-_is_reply_ok(const char* reply, int reply_size)
-{
- return (reply_size < 2) ? 0 : (reply[0] == 'O' && reply[1] == 'K');
-}
-
-/*
- * Checks if console has replied with "KO"
- * Param:
- * reply - String containing console's reply
- * Return:
- * boolean: true if reply was "KO", or false otherwise.
- */
-static int
-_is_reply_ko(const char* reply, int reply_size)
-{
- return (reply_size < 2) ? 0 : (reply[0] == 'K' && reply[1] == 'O');
-}
-
-SyncSocket*
-core_connection_open_socket(SockAddress* sockaddr)
-{
- SyncSocket* ssocket;
- int status;
- int64_t deadline;
- char buf[512];
-
- int fd = socket_create(sock_address_get_family(sockaddr), SOCKET_STREAM);
- if (fd < 0) {
- return NULL;
- }
-
- socket_set_xreuseaddr(fd);
-
- // Create sync connection to the console.
- ssocket = syncsocket_connect(fd, sockaddr, CORE_PORT_TIMEOUT_MS);
- if (ssocket == NULL) {
- derror("syncsocket_connect has failed: %s\n", errno_str);
- socket_close(fd);
- return NULL;
- }
-
- // Upon successful connection the console will reply with two strings:
- // "Android Console....", and "OK\r\n". Read them and check.
- status = syncsocket_start_read(ssocket);
- if (status < 0) {
- derror("syncsocket_start_read has failed: %s\n", errno_str);
- syncsocket_free(ssocket);
- return NULL;
- }
-
- deadline = iolooper_now() + CORE_PORT_TIMEOUT_MS;
- // Read first line.
- status = syncsocket_read_line_absolute(ssocket, buf, sizeof(buf), deadline);
- if (status <= 0) {
- derror("syncsocket_read_line_absolute has failed: %s\n", errno_str);
- syncsocket_free(ssocket);
- return NULL;
- }
- if (status < 15 || memcmp(buf, "Android Console", 15)) {
- _zero_terminate(buf, sizeof(buf), status);
- derror("console has failed the connection: %s\n", buf);
- syncsocket_free(ssocket);
- return NULL;
- }
- // Read second line
- status = syncsocket_read_line_absolute(ssocket, buf, sizeof(buf), deadline);
- syncsocket_stop_read(ssocket);
- if (status < 2 || !_is_reply_ok(buf, status)) {
- _zero_terminate(buf, sizeof(buf), status);
- derror("unexpected reply from the console: %s\n", buf);
- syncsocket_free(ssocket);
- return NULL;
- }
-
- return ssocket;
-}
-
-CoreConnection*
-core_connection_create(SockAddress* console_address)
-{
- CoreConnection* desc;
- ANEW0(desc);
- desc->console_address = console_address[0];
- desc->ssocket = NULL;
- desc->stream_name = NULL;
-
- return desc;
-}
-
-void
-core_connection_free(CoreConnection* desc)
-{
- if (desc == NULL) {
- return;
- }
- if (desc->ssocket != NULL) {
- syncsocket_free(desc->ssocket);
- }
- if (desc->stream_name != NULL) {
- free(desc->stream_name);
- }
- free(desc);
-}
-
-int
-core_connection_open(CoreConnection* desc)
-{
- if (desc == NULL) {
- errno = EINVAL;
- return -1;
- }
- if (desc->ssocket != NULL) {
- return 0;
- }
-
- desc->ssocket = core_connection_open_socket(&desc->console_address);
-
- return (desc->ssocket != NULL) ? 0 : -1;
-}
-
-void
-core_connection_close(CoreConnection* desc)
-{
- if (desc == NULL) {
- return;
- }
- if (desc->ssocket != NULL) {
- syncsocket_close(desc->ssocket);
- }
-}
-
-int
-core_connection_write(CoreConnection* desc,
- const void* buffer,
- size_t to_write,
- size_t* written_bytes)
-{
- ssize_t written;
-
- int status = syncsocket_start_write(desc->ssocket);
- if (status < 0) {
- derror("syncsocket_start_write failed: %s\n", errno_str);
- return status;
- }
-
- written =
- syncsocket_write(desc->ssocket, buffer, to_write, CORE_PORT_TIMEOUT_MS);
- syncsocket_stop_write(desc->ssocket);
- if (written <= 0) {
- derror("syncsocket_write failed: %s\n", errno_str);
- return -1;
- }
- if (written_bytes != NULL) {
- *written_bytes = written;
- }
-
- return 0;
-}
-
-int
-core_connection_read(CoreConnection* desc,
- void* buffer,
- size_t to_read,
- size_t* read_bytes)
-{
- ssize_t read_size;
-
- int status = syncsocket_start_read(desc->ssocket);
- if (status < 0) {
- derror("syncsocket_start_read failed: %s\n", errno_str);
- return status;
- }
-
- read_size =
- syncsocket_read(desc->ssocket, buffer, to_read, CORE_PORT_TIMEOUT_MS);
- syncsocket_stop_read(desc->ssocket);
- if (read_size <= 0) {
- derror("syncsocket_read failed: %s\n", errno_str);
- return -1;
- }
-
- if (read_bytes != NULL) {
- *read_bytes = read_size;
- }
- return 0;
-}
-
-int
-core_connection_switch_stream(CoreConnection* desc,
- const char* stream_name,
- char** handshake)
-{
- char buf[4096];
- int handshake_len;
- int status;
- int64_t deadline;
-
- *handshake = NULL;
- if (desc == NULL || desc->stream_name != NULL || stream_name == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- // Prepare and write "switch" command.
- snprintf(buf, sizeof(buf), "qemu %s\r\n", stream_name);
- if (core_connection_write(desc, buf, strlen(buf), NULL)) {
- return -1;
- }
-
- // Read result / handshake
- status = syncsocket_start_read(desc->ssocket);
- if (status < 0) {
- return -1;
- }
- deadline = iolooper_now() + CORE_PORT_TIMEOUT_MS;
- handshake_len =
- syncsocket_read_line_absolute(desc->ssocket, buf, sizeof(buf), deadline);
- _zero_terminate(buf, sizeof(buf), handshake_len);
- // Replace terminating "\r\n" with 0
- if (handshake_len >= 1) {
- if (buf[handshake_len - 1] == '\r' || buf[handshake_len - 1] == '\n') {
- buf[handshake_len - 1] = '\0';
- if (handshake_len >= 2 && (buf[handshake_len - 2] == '\r' ||
- buf[handshake_len - 2] == '\n')) {
- buf[handshake_len - 2] = '\0';
- }
- }
- }
- // Lets see what kind of response we've got here.
- if (_is_reply_ok(buf, handshake_len)) {
- *handshake = strdup(buf + 3);
- desc->stream_name = strdup(stream_name);
- // We expect an "OK" string here
- status = syncsocket_read_line_absolute(desc->ssocket, buf, sizeof(buf),
- deadline);
- syncsocket_stop_read(desc->ssocket);
- if (status < 0) {
- derror("error reading console reply on stream switch: %s\n", errno_str);
- return -1;
- } else if (!_is_reply_ok(buf, status)) {
- _zero_terminate(buf, sizeof(buf), status);
- derror("unexpected console reply when switching streams: %s\n", buf);
- return -1;
- }
- return 0;
- } else if (_is_reply_ko(buf, handshake_len)) {
- derror("console has rejected stream switch: %s\n", buf);
- syncsocket_stop_read(desc->ssocket);
- *handshake = strdup(buf + 3);
- return -1;
- } else {
- // No OK, no KO? Should be an error!
- derror("unexpected console reply when switching streams: %s\n", buf);
- syncsocket_stop_read(desc->ssocket);
- *handshake = strdup(buf);
- return -1;
- }
-}
-
-CoreConnection*
-core_connection_create_and_switch(SockAddress* console_socket,
- const char* stream_name,
- char** handshake)
-{
- char switch_cmd[256];
- CoreConnection* connection = NULL;
-
- // Connect to the console service.
- connection = core_connection_create(console_socket);
- if (connection == NULL) {
- return NULL;
- }
- if (core_connection_open(connection)) {
- core_connection_free(connection);
- return NULL;
- }
-
- // Perform the switch.
- snprintf(switch_cmd, sizeof(switch_cmd), "%s", stream_name);
- if (core_connection_switch_stream(connection, switch_cmd, handshake)) {
- core_connection_close(connection);
- core_connection_free(connection);
- return NULL;
- }
-
- return connection;
-}
-
-void
-core_connection_detach(CoreConnection* desc)
-{
- core_connection_write(desc, "\n", 1, NULL);
-}
-
-int
-core_connection_get_socket(CoreConnection* desc)
-{
- return (desc != NULL) ? syncsocket_get_socket(desc->ssocket) : -1;
-}
diff --git a/android/protocol/core-connection.h b/android/protocol/core-connection.h
deleted file mode 100644
index 5701f8c..0000000
--- a/android/protocol/core-connection.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * This file contains declaration related to communication between emulator's
- * UI and core through a console port.
- */
-
-#ifndef QEMU_ANDROID_CORE_CONNECTION_H
-#define QEMU_ANDROID_CORE_CONNECTION_H
-
-#include "android/sync-utils.h"
-
-// Opaque CoreConnection structure.
-typedef struct CoreConnection CoreConnection;
-
-// Base console port
-#define CORE_BASE_PORT 5554
-
-// Maximum number of core porocesses running simultaneously on a machine.
-#define MAX_CORE_PROCS 16
-
-// Socket timeout in millisec (set to 5 seconds)
-#define CORE_PORT_TIMEOUT_MS 5000
-
-/* Opens core console socket.
- * Param:
- * sockaddr Socket address to the core console.
- * Return:
- * Sync socket descriptor on success, or -1 on failure, with errno appropriately
- * set.
- */
-SyncSocket* core_connection_open_socket(SockAddress* sockaddr);
-
-/* Creates descriptor for a console client.
- * Param:
- * console_socket Socket address for the console.
- * Return:
- * Allocated and initialized descriptor for the client on success, or NULL
- * on failure.
- */
-CoreConnection* core_connection_create(SockAddress* console_socket);
-
-/* Frees descriptor allocated with core_connection_create.
- * Param:
- * desc Descriptor to free. Note that this routine will simply free the memory
- * used by the descriptor.
- */
-void core_connection_free(CoreConnection* desc);
-
-/* Opens a socket handle to the console.
- * Param:
- * desc Console client descriptor. Note that if the descriptor has been already
- * opened, this routine will simply return with success.
- * Return:
- * 0 on success, or -1 on failure with errno properly set. This routine will
- * return in at most one second.
- */
-int core_connection_open(CoreConnection* desc);
-
-/* Closes a socket handle to the console opened with core_connection_open.
- * Param:
- * desc Console client descriptor opened with core_connection_open.
- */
-void core_connection_close(CoreConnection* desc);
-
-/* Synchronously writes to the console. See CORE_PORT_TIMEOUT_MS for the timeout
- * value used to wait for the write operation to complete.
- * Param:
- * desc Console client descriptor opened with core_connection_open.
- * buffer Buffer to write.
- * to_write Number of bytes to write.
- * written_bytes Upon success, contains number of bytes written. This parameter
- * is optional, and can be NULL.
- * Return:
- * 0 on success, or -1 on failure.
- */
-int core_connection_write(CoreConnection* desc,
- const void* buffer,
- size_t to_write,
- size_t* written_bytes);
-
-/* Synchronously reads from the console. See CORE_PORT_TIMEOUT_MS for the
- * timeout value used to wait for the read operation to complete.
- * Param:
- * desc Console client descriptor opened with core_connection_open.
- * buffer Buffer to read data to.
- * to_read Number of bytes to read.
- * read_bytes Upon success, contains number of bytes that have been actually
- * read. This parameter is optional, and can be NULL.
- * Return:
- * 0 on success, or -1 on failure.
- */
-int core_connection_read(CoreConnection* desc,
- void* buffer,
- size_t to_read,
- size_t* read_bytes);
-
-/* Switches opened console client to a given stream.
- * Param:
- * desc Console client descriptor opened with core_connection_open. Note
- * that this descriptor should represent console itself. In other words,
- * there must have been no previous calls to this routine for that
- * descriptor.
- * stream_name Name of the stream to switch to.
- * handshake Address of a string to allocate for a handshake message on
- * success, or an error message on failure. If upon return from this
- * routine that string is not NULL, its buffer must be freed with 'free'.
- * Return:
- * 0 on success, or -1 on failure.
- */
-int core_connection_switch_stream(CoreConnection* desc,
- const char* stream_name,
- char** handshake);
-
-/* Creates a console client, and switches it to a given stream.
- * console_socket Socket address for the console.
- * stream_name Name of the stream to switch to.
- * handshake Address of a string to allocate for a handshake message on
- * success, or an error message on failure. If upon return from this
- * routine that string is not NULL, its buffer must be freed with 'free'.
- * Return:
- * Allocated and initialized descriptor for the switched client on success, or
- * NULL on failure.
- */
-CoreConnection* core_connection_create_and_switch(SockAddress* console_socket,
- const char* stream_name,
- char** handshake);
-
-/* Detaches opened console client from the console.
- * By console protocol, writing "\r\n" string to the console will destroy the
- * console client.
- * Param:
- * desc Console client descriptor opened with core_connection_open.
- */
-void core_connection_detach(CoreConnection* desc);
-
-/* Gets socket descriptor associated with the core connection.
- * Param:
- * desc Console client descriptor opened with core_connection_open.
- * Return
- * Socket descriptor associated with the core connection.
- */
-int core_connection_get_socket(CoreConnection* desc);
-
-/* Calculates timeout for transferring the given number of bytes via core
- * connection.
- * Return:
- * Number of milliseconds during which the entire number of bytes is expected
- * to be transferred via core connection.
- */
-static inline int
-core_connection_get_timeout(size_t data_size)
-{
- // Min 2 seconds + 10 millisec for each transferring byte.
- // TODO: Come up with a better arithmetics here.
- return 2000 + data_size * 10;
-}
-
-#endif // QEMU_ANDROID_CORE_CONNECTION_H
diff --git a/android/protocol/fb-updates-impl.c b/android/protocol/fb-updates-impl.c
deleted file mode 100644
index e36c4bf..0000000
--- a/android/protocol/fb-updates-impl.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains UI-side framebuffer client that receives framebuffer updates
- * from the core.
- */
-
-#include "android/utils/system.h"
-#include "android/utils/debug.h"
-#include "android/utils/eintr_wrapper.h"
-#include "android/utils/panic.h"
-#include "android/sync-utils.h"
-#include "android/protocol/core-connection.h"
-#include "android/protocol/fb-updates.h"
-#include "android/protocol/fb-updates-impl.h"
-
-/*Enumerates states for the client framebuffer update reader. */
-typedef enum FbImplState {
- /* The reader is waiting on update header. */
- EXPECTS_HEADER,
-
- /* The reader is waiting on pixels. */
- EXPECTS_PIXELS,
-} FbImplState;
-
-/* Descriptor for the UI-side implementation of the "framebufer" service.
- */
-typedef struct FrameBufferImpl {
- /* Framebuffer for this client. */
- QFrameBuffer* fb;
-
- /* Core connection instance for the framebuffer client. */
- CoreConnection* core_connection;
-
- /* Current update header. */
- FBUpdateMessage update_header;
-
- /* Reader's buffer. */
- uint8_t* reader_buffer;
-
- /* Offset in the reader's buffer where to read next chunk of data. */
- size_t reader_offset;
-
- /* Total number of bytes the reader expects to read. */
- size_t reader_bytes;
-
- /* Current state of the update reader. */
- FbImplState fb_state;
-
- /* Socket descriptor for the framebuffer client. */
- int sock;
-
- /* Custom i/o handler */
- LoopIo io[1];
-
- /* Number of bits used to encode single pixel. */
- int bits_per_pixel;
-} FrameBufferImpl;
-
-/* One and the only FrameBufferImpl instance. */
-static FrameBufferImpl _fbImpl;
-
-/*
- * Updates a display rectangle.
- * Param
- * fb - Framebuffer where to update the rectangle.
- * x, y, w, and h define rectangle to update.
- * bits_per_pixel define number of bits used to encode a single pixel.
- * pixels contains pixels for the rectangle. Buffer addressed by this parameter
- * must be eventually freed with free()
- */
-static void
-_update_rect(QFrameBuffer* fb, uint16_t x, uint16_t y, uint16_t w, uint16_t h,
- uint8_t bits_per_pixel, uint8_t* pixels)
-{
- if (fb != NULL) {
- uint16_t n;
- const uint8_t* src = pixels;
- const uint16_t src_line_size = w * ((bits_per_pixel + 7) / 8);
- uint8_t* dst = (uint8_t*)fb->pixels + y * fb->pitch + x *
- fb->bytes_per_pixel;
- for (n = 0; n < h; n++) {
- memcpy(dst, src, src_line_size);
- src += src_line_size;
- dst += fb->pitch;
- }
- qframebuffer_update(fb, x, y, w, h);
- }
- free(pixels);
-}
-
-/*
- * Asynchronous I/O callback launched when framebuffer notifications are ready
- * to be read.
- * Param:
- * opaque - FrameBufferImpl instance.
- */
-static void
-_fbUpdatesImpl_io_callback(void* opaque, int fd, unsigned events)
-{
- FrameBufferImpl* fbi = opaque;
- int ret;
-
- // Read updates while they are immediately available.
- for (;;) {
- // Read next chunk of data.
- ret = HANDLE_EINTR(
- socket_recv(fbi->sock,
- fbi->reader_buffer + fbi->reader_offset,
- fbi->reader_bytes - fbi->reader_offset));
- if (ret < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
- // Chunk is not avalable at this point. Come back later.
- return;
- }
- if (ret <= 0) {
- /* disconnection ! */
- derror("Unable to receive framebuffer data: %s\n",
- ret < 0 ? strerror(errno), "unexpected disconnection");
- fbUpdatesImpl_destroy();
- return;
- }
-
- fbi->reader_offset += ret;
- if (fbi->reader_offset != fbi->reader_bytes) {
- // There are still some data left in the pipe.
- continue;
- }
-
- // All expected data has been read. Time to change the state.
- if (fbi->fb_state == EXPECTS_HEADER) {
- // Update header has been read. Prepare for the pixels.
- fbi->fb_state = EXPECTS_PIXELS;
- fbi->reader_offset = 0;
- fbi->reader_bytes = fbi->update_header.w *
- fbi->update_header.h *
- (fbi->bits_per_pixel / 8);
- fbi->reader_buffer = malloc(fbi->reader_bytes);
- if (fbi->reader_buffer == NULL) {
- APANIC("Unable to allocate memory for framebuffer update\n");
- }
- } else {
- // Pixels have been read. Prepare for the header.
- uint8_t* pixels = fbi->reader_buffer;
-
- fbi->fb_state = EXPECTS_HEADER;
- fbi->reader_offset = 0;
- fbi->reader_bytes = sizeof(FBUpdateMessage);
- fbi->reader_buffer = (uint8_t*)&fbi->update_header;
-
- // Perform the update. Note that pixels buffer must be freed there.
- _update_rect(fbi->fb, fbi->update_header.x,
- fbi->update_header.y, fbi->update_header.w,
- fbi->update_header.h, fbi->bits_per_pixel,
- pixels);
- }
- }
-}
-
-int
-fbUpdatesImpl_create(SockAddress* console_socket,
- const char* protocol,
- QFrameBuffer* fb,
- Looper* looper)
-{
- FrameBufferImpl* fbi = &_fbImpl;
- char* handshake = NULL;
- char switch_cmd[256];
-
- // Initialize descriptor.
- fbi->fb = fb;
- fbi->reader_buffer = (uint8_t*)&fbi->update_header;
- fbi->reader_offset = 0;
- fbi->reader_bytes = sizeof(FBUpdateMessage);
-
- // Connect to the framebuffer service.
- snprintf(switch_cmd, sizeof(switch_cmd), "framebuffer %s", protocol);
- fbi->core_connection =
- core_connection_create_and_switch(console_socket, switch_cmd, &handshake);
- if (fbi->core_connection == NULL) {
- derror("Unable to connect to the framebuffer service: %s\n",
- errno_str);
- return -1;
- }
-
- // We expect core framebuffer to return us bits per pixel property in
- // the handshake message.
- fbi->bits_per_pixel = 0;
- if (handshake != NULL) {
- char* bpp = strstr(handshake, "bitsperpixel=");
- if (bpp != NULL) {
- char* end;
- bpp += strlen("bitsperpixel=");
- end = strchr(bpp, ' ');
- if (end == NULL) {
- end = bpp + strlen(bpp);
- }
- fbi->bits_per_pixel = strtol(bpp, &end, 0);
- }
- }
- if (!fbi->bits_per_pixel) {
- derror("Unexpected core framebuffer reply: %s\n"
- "Bits per pixel property is not there, or is invalid\n",
- handshake);
- fbUpdatesImpl_destroy();
- return -1;
- }
-
- fbi->sock = core_connection_get_socket(fbi->core_connection);
-
- // At last setup read callback, and start receiving the updates.
- loopIo_init(fbi->io, looper, fbi->sock,
- _fbUpdatesImpl_io_callback, &_fbImpl);
- loopIo_wantRead(fbi->io);
- {
- // Force the core to send us entire framebuffer now, when we're prepared
- // to receive it.
- FBRequestHeader hd;
- SyncSocket* sk = syncsocket_init(fbi->sock);
-
- hd.request_type = AFB_REQUEST_REFRESH;
- syncsocket_start_write(sk);
- syncsocket_write(sk, &hd, sizeof(hd), 5000);
- syncsocket_stop_write(sk);
- syncsocket_free(sk);
- }
-
- fprintf(stdout, "framebuffer is now connected to the core at %s.",
- sock_address_to_string(console_socket));
- if (handshake != NULL) {
- if (handshake[0] != '\0') {
- fprintf(stdout, " Handshake: %s", handshake);
- }
- free(handshake);
- }
- fprintf(stdout, "\n");
-
- return 0;
-}
-
-void
-fbUpdatesImpl_destroy(void)
-{
- FrameBufferImpl* fbi = &_fbImpl;
-
- if (fbi->core_connection != NULL) {
- // Disable the reader callback.
- loopIo_done(fbi->io);
-
- // Close framebuffer connection.
- core_connection_close(fbi->core_connection);
- core_connection_free(fbi->core_connection);
- fbi->core_connection = NULL;
- }
-
- fbi->fb = NULL;
- if (fbi->reader_buffer != NULL &&
- fbi->reader_buffer != (uint8_t*)&fbi->update_header) {
- free(fbi->reader_buffer);
- fbi->reader_buffer = (uint8_t*)&fbi->update_header;
- }
-}
diff --git a/android/protocol/fb-updates-impl.h b/android/protocol/fb-updates-impl.h
deleted file mode 100644
index 56d4860..0000000
--- a/android/protocol/fb-updates-impl.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains UI-side "framebuffer" client that receives framebuffer updates
- * from the Core.
- */
-
-#ifndef _ANDROID_FRAMEBUFFER_UI_H
-#define _ANDROID_FRAMEBUFFER_UI_H
-
-#include "android/looper.h"
-#include "android/framebuffer.h"
-#include "android/looper.h"
-#include "android/async-utils.h"
-
-/* Creates framebuffer client, and connects it with the core.
- * Param:
- * console_socket Address of the core's console socket.
- * protocol Protocol to use for the updates:
- * -raw Stream pixels over socket
- * -shared Use shared memory for pixels.
- * fb - Framebuffer associated with this FB client.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-int fbUpdatesImpl_create(SockAddress* console_socket,
- const char* protocol,
- QFrameBuffer* fb,
- Looper* looper);
-
-/* Disconnects and destroys framebuffer client. */
-void fbUpdatesImpl_destroy(void);
-
-#endif /* _ANDROID_FRAMEBUFFER_UI_H */
diff --git a/android/protocol/fb-updates-proxy.c b/android/protocol/fb-updates-proxy.c
deleted file mode 100644
index 10d1e71..0000000
--- a/android/protocol/fb-updates-proxy.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains core-side framebuffer service that sends framebuffer updates
- * to the UI connected to the core.
- */
-
-#include "ui/console.h"
-#include "android/looper.h"
-#include "android/display-core.h"
-#include "android/async-utils.h"
-#include "android/protocol/fb-updates.h"
-#include "android/protocol/fb-updates-proxy.h"
-#include "android/utils/system.h"
-#include "android/utils/debug.h"
-
-/* Descriptor for the Core-side implementation of the "framebufer" service.
- */
-struct ProxyFramebuffer {
- /* Writer used to send FB update notification messages. */
- AsyncWriter fb_update_writer;
-
- /* Reader used to read FB requests from the client. */
- AsyncReader fb_req_reader;
-
- /* I/O associated with this descriptor. */
- LoopIo io;
-
- /* Display state used for this service */
- DisplayState* ds;
- DisplayUpdateListener* ds_listener;
-
- /* Looper used to communicate framebuffer updates. */
- Looper* looper;
-
- /* Head of the list of pending FB update notifications. */
- struct FBUpdateNotify* fb_update_head;
-
- /* Tail of the list of pending FB update notifications. */
- struct FBUpdateNotify* fb_update_tail;
-
- /* Socket used to communicate framebuffer updates. */
- int sock;
-
- /* Framebuffer request header. */
- FBRequestHeader fb_req_header;
-};
-
-/* Framebuffer update notification descriptor. */
-typedef struct FBUpdateNotify {
- /* Links all pending FB update notifications. */
- struct FBUpdateNotify* next_fb_update;
-
- /* Core framebuffer instance that owns the message. */
- ProxyFramebuffer* proxy_fb;
-
- /* Size of the message to transfer. */
- size_t message_size;
-
- /* Update message. */
- FBUpdateMessage message;
-} FBUpdateNotify;
-
-/*
- * Gets pointer in framebuffer's pixels for the given pixel.
- * Param:
- * fb Framebuffer containing pixels.
- * x, and y identify the pixel to get pointer for.
- * Return:
- * Pointer in framebuffer's pixels for the given pixel.
- */
-static const uint8_t*
-_pixel_offset(const DisplaySurface* dsu, int x, int y)
-{
- return (const uint8_t*)dsu->data + y * dsu->linesize + x * dsu->pf.bytes_per_pixel;
-}
-
-/*
- * Copies pixels from a framebuffer rectangle.
- * Param:
- * rect - Buffer where to copy pixel.
- * fb - Framebuffer containing the rectangle to copy.
- * x, y, w, and h - dimensions of the rectangle to copy.
- */
-static void
-_copy_fb_rect(uint8_t* rect, const DisplaySurface* dsu, int x, int y, int w, int h)
-{
- const uint8_t* start = _pixel_offset(dsu, x, y);
- for (; h > 0; h--) {
- memcpy(rect, start, w * dsu->pf.bytes_per_pixel);
- start += dsu->linesize;
- rect += w * dsu->pf.bytes_per_pixel;
- }
-}
-
-/*
- * Allocates and initializes framebuffer update notification descriptor.
- * Param:
- * ds - Display state for the framebuffer.
- * fb Framebuffer containing pixels.
- * x, y, w, and h identify the rectangle that is being updated.
- * Return:
- * Initialized framebuffer update notification descriptor.
- */
-static FBUpdateNotify*
-fbupdatenotify_create(ProxyFramebuffer* proxy_fb,
- int x, int y, int w, int h)
-{
- const size_t rect_size = w * h * proxy_fb->ds->surface->pf.bytes_per_pixel;
- FBUpdateNotify* ret = malloc(sizeof(FBUpdateNotify) + rect_size);
-
- ret->next_fb_update = NULL;
- ret->proxy_fb = proxy_fb;
- ret->message_size = sizeof(FBUpdateMessage) + rect_size;
- ret->message.x = x;
- ret->message.y = y;
- ret->message.w = w;
- ret->message.h = h;
- _copy_fb_rect(ret->message.rect, proxy_fb->ds->surface, x, y, w, h);
- return ret;
-}
-
-/*
- * Deletes FBUpdateNotify descriptor, created with fbupdatenotify_create.
- * Param:
- * desc - Descreptor to delete.
- */
-static void
-fbupdatenotify_delete(FBUpdateNotify* desc)
-{
- if (desc != NULL) {
- free(desc);
- }
-}
-
-/*
- * Asynchronous write I/O callback launched when writing framebuffer
- * notifications to the socket.
- * Param:
- * proxy_fb - ProxyFramebuffer instance.
- */
-static void
-_proxyFb_io_write(ProxyFramebuffer* proxy_fb)
-{
- while (proxy_fb->fb_update_head != NULL) {
- FBUpdateNotify* current_update = proxy_fb->fb_update_head;
- // Lets continue writing of the current notification.
- const AsyncStatus status =
- asyncWriter_write(&proxy_fb->fb_update_writer);
- switch (status) {
- case ASYNC_COMPLETE:
- // Done with the current update. Move on to the next one.
- break;
- case ASYNC_ERROR:
- // Done with the current update. Move on to the next one.
- loopIo_dontWantWrite(&proxy_fb->io);
- break;
-
- case ASYNC_NEED_MORE:
- // Transfer will eventually come back into this routine.
- return;
- }
-
- // Advance the list of updates
- proxy_fb->fb_update_head = current_update->next_fb_update;
- if (proxy_fb->fb_update_head == NULL) {
- proxy_fb->fb_update_tail = NULL;
- }
- fbupdatenotify_delete(current_update);
-
- if (proxy_fb->fb_update_head != NULL) {
- // Schedule the next one.
- asyncWriter_init(&proxy_fb->fb_update_writer,
- &proxy_fb->fb_update_head->message,
- proxy_fb->fb_update_head->message_size,
- &proxy_fb->io);
- }
- }
-}
-
-static void proxyFb_update(void* opaque, int x, int y, int w, int h);
-
-/*
- * Asynchronous read I/O callback launched when reading framebuffer requests
- * from the socket.
- * Param:
- * proxy_fb - ProxyFramebuffer instance.
- */
-static void
-_proxyFb_io_read(ProxyFramebuffer* proxy_fb)
-{
- // Read the request header.
- DisplaySurface* dsu;
- const AsyncStatus status =
- asyncReader_read(&proxy_fb->fb_req_reader);
- switch (status) {
- case ASYNC_COMPLETE:
- // Request header is received
- switch (proxy_fb->fb_req_header.request_type) {
- case AFB_REQUEST_REFRESH:
- // Force full screen update to be sent
- dsu = proxy_fb->ds->surface;
- proxyFb_update(proxy_fb,
- 0, 0, dsu->width, dsu->height);
- break;
- default:
- derror("Unknown framebuffer request %d\n",
- proxy_fb->fb_req_header.request_type);
- break;
- }
- proxy_fb->fb_req_header.request_type = -1;
- asyncReader_init(&proxy_fb->fb_req_reader, &proxy_fb->fb_req_header,
- sizeof(proxy_fb->fb_req_header), &proxy_fb->io);
- break;
- case ASYNC_ERROR:
- loopIo_dontWantRead(&proxy_fb->io);
- if (errno == ECONNRESET) {
- // UI has exited. We need to destroy framebuffer service.
- proxyFb_destroy(proxy_fb);
- }
- break;
-
- case ASYNC_NEED_MORE:
- // Transfer will eventually come back into this routine.
- return;
- }
-}
-
-/*
- * Asynchronous I/O callback launched when writing framebuffer notifications
- * to the socket.
- * Param:
- * opaque - ProxyFramebuffer instance.
- */
-static void
-_proxyFb_io_fun(void* opaque, int fd, unsigned events)
-{
- if (events & LOOP_IO_READ) {
- _proxyFb_io_read((ProxyFramebuffer*)opaque);
- } else if (events & LOOP_IO_WRITE) {
- _proxyFb_io_write((ProxyFramebuffer*)opaque);
- }
-}
-
-ProxyFramebuffer*
-proxyFb_create(int sock, const char* protocol)
-{
- // At this point we're implementing the -raw protocol only.
- ProxyFramebuffer* ret;
- DisplayState* ds = get_displaystate();
- DisplayUpdateListener* dul;
-
- ANEW0(ret);
- ret->sock = sock;
- ret->looper = looper_newCore();
- ret->ds = ds;
-
- ANEW0(dul);
- dul->opaque = ret;
- dul->dpy_update = proxyFb_update;
- register_displayupdatelistener(ds, dul);
- ret->ds_listener = dul;
-
- ret->fb_update_head = NULL;
- ret->fb_update_tail = NULL;
- loopIo_init(&ret->io, ret->looper, sock, _proxyFb_io_fun, ret);
- asyncReader_init(&ret->fb_req_reader, &ret->fb_req_header,
- sizeof(ret->fb_req_header), &ret->io);
- return ret;
-}
-
-void
-proxyFb_destroy(ProxyFramebuffer* proxy_fb)
-{
- if (proxy_fb != NULL) {
- unregister_displayupdatelistener(proxy_fb->ds, proxy_fb->ds_listener);
- if (proxy_fb->looper != NULL) {
- // Stop all I/O that may still be going on.
- loopIo_done(&proxy_fb->io);
- // Delete all pending frame updates.
- while (proxy_fb->fb_update_head != NULL) {
- FBUpdateNotify* pending_update = proxy_fb->fb_update_head;
- proxy_fb->fb_update_head = pending_update->next_fb_update;
- fbupdatenotify_delete(pending_update);
- }
- proxy_fb->fb_update_tail = NULL;
- looper_free(proxy_fb->looper);
- proxy_fb->looper = NULL;
- }
- AFREE(proxy_fb);
- }
-}
-
-static void
-proxyFb_update(void* opaque, int x, int y, int w, int h)
-{
- ProxyFramebuffer* proxy_fb = opaque;
- AsyncStatus status;
- FBUpdateNotify* descr = fbupdatenotify_create(proxy_fb, x, y, w, h);
-
- // Lets see if we should list it behind other pending updates.
- if (proxy_fb->fb_update_tail != NULL) {
- proxy_fb->fb_update_tail->next_fb_update = descr;
- proxy_fb->fb_update_tail = descr;
- return;
- }
-
- // We're first in the list. Just send it now.
- proxy_fb->fb_update_head = proxy_fb->fb_update_tail = descr;
- asyncWriter_init(&proxy_fb->fb_update_writer,
- &proxy_fb->fb_update_head->message,
- proxy_fb->fb_update_head->message_size, &proxy_fb->io);
- status = asyncWriter_write(&proxy_fb->fb_update_writer);
- switch (status) {
- case ASYNC_COMPLETE:
- fbupdatenotify_delete(descr);
- proxy_fb->fb_update_head = proxy_fb->fb_update_tail = NULL;
- return;
- case ASYNC_ERROR:
- fbupdatenotify_delete(descr);
- proxy_fb->fb_update_head = proxy_fb->fb_update_tail = NULL;
- return;
- case ASYNC_NEED_MORE:
- // Update transfer will eventually complete in _proxyFb_io_fun
- return;
- }
-}
-
-int
-proxyFb_get_bits_per_pixel(ProxyFramebuffer* proxy_fb)
-{
- if (proxy_fb == NULL || proxy_fb->ds == NULL)
- return -1;
-
- return proxy_fb->ds->surface->pf.bits_per_pixel;
-}
diff --git a/android/protocol/fb-updates-proxy.h b/android/protocol/fb-updates-proxy.h
deleted file mode 100644
index 15b1d5b..0000000
--- a/android/protocol/fb-updates-proxy.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains core-side framebuffer service that sends framebuffer updates
- * to the UI connected to the core.
- */
-
-#ifndef _ANDROID_PROTOCOL_FB_UPDATES_PROXY_H
-#define _ANDROID_PROTOCOL_FB_UPDATES_PROXY_H
-
-/* Descriptor for a framebuffer core service instance */
-typedef struct ProxyFramebuffer ProxyFramebuffer;
-
-/*
- * Creates framebuffer service.
- * Param:
- * sock - Socket descriptor for the service
- * protocol - Defines protocol to use when sending FB updates to the UI. The
- * supported values ar:
- * -raw Transfers the updating rectangle buffer over the socket.
- * -shared Used a shared memory to transfer the updating rectangle buffer.
- * Return:
- * Framebuffer service descriptor.
- */
-ProxyFramebuffer* proxyFb_create(int sock, const char* protocol);
-
-/*
- * Destroys framebuffer service created with proxyFb_create.
- * Param:
- * core_fb - Framebuffer service descriptor created with proxyFb_create
- */
-void proxyFb_destroy(ProxyFramebuffer* core_fb);
-
-/*
- * Gets number of bits used to encode a single pixel.
- * Param:
- * core_fb - Framebuffer service descriptor created with proxyFb_create
- * Return:
- * Number of bits used to encode a single pixel.
- */
-int proxyFb_get_bits_per_pixel(ProxyFramebuffer* core_fb);
-
-#endif /* _ANDROID_PROTOCOL_FB_UPDATES_PROXY_H */
diff --git a/android/protocol/fb-updates.h b/android/protocol/fb-updates.h
deleted file mode 100644
index 9142599..0000000
--- a/android/protocol/fb-updates.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the API for calling into the UI with Core's framebuffer updates.
- */
-
-#ifndef _ANDROID_PROTOCOL_FB_UPDATES_H
-#define _ANDROID_PROTOCOL_FB_UPDATES_H
-
-#include "sysemu/sysemu.h"
-
-/* Requests the Core to refresh framebuffer.
- * This message is sent by the UI to the Core right after the UI is initialized.
- * This message forces the Core to send a full display update back to the UI. */
-#define AFB_REQUEST_REFRESH 1
-
-/* Header of framebuffer update message sent from the core to the UI. */
-typedef struct FBUpdateMessage {
- /* x, y, w, and h identify the rectangle that is being updated. */
- uint16_t x;
- uint16_t y;
- uint16_t w;
- uint16_t h;
-
- /* Contains updating rectangle copied over from the framebuffer's pixels. */
- uint8_t rect[0];
-} FBUpdateMessage;
-
-/* Header for framebuffer requests sent from the UI to the Core. */
-typedef struct FBRequestHeader {
- /* Request type. See AFB_REQUEST_XXX for the values. */
- uint8_t request_type;
-} FBRequestHeader;
-
-#endif /* _ANDROID_PROTOCOL_FB_UPDATES_H */
diff --git a/android/protocol/ui-commands-api.h b/android/protocol/ui-commands-api.h
deleted file mode 100644
index d9fe6b0..0000000
--- a/android/protocol/ui-commands-api.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_UI_COMMANDS_API_H
-#define _ANDROID_PROTOCOL_UI_COMMANDS_API_H
-
-/*
- * Contains the API for calling into the UI with the Core control commands.
- */
-
-/* Changes the scale of the emulator window at runtime.
- * Param:
- * scale, is_dpi - New window scale parameters
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int uicmd_set_window_scale(double scale, int is_dpi);
-
-/* This is temporary redeclaration for AndroidHwLightBrightnessFunc declared
- * in android/hw-control.h We redeclare it here in order to keep type
- * consistency between android_core_set_brightness_change_callback and
- * light_brightness field of AndroidHwControlFuncs structure.
- */
-typedef void (*AndroidHwLightBrightnessCallback)(void* opaque,
- const char* light,
- int brightness);
-
-/* Registers a UI callback to be called when brightness is changed by the core. */
-extern int uicmd_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback,
- void* opaque);
-
-#endif /* _ANDROID_PROTOCOL_UI_COMMANDS_API_H */
diff --git a/android/protocol/ui-commands-impl.c b/android/protocol/ui-commands-impl.c
deleted file mode 100644
index 307e7c7..0000000
--- a/android/protocol/ui-commands-impl.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the UI-side implementation of the "core-ui-control" service that is
- * part of the UI control protocol. Here we handle UI control commands received
- * from the Core.
- */
-
-#include <unistd.h>
-#include "android/looper.h"
-#include "android/async-utils.h"
-#include "android/sync-utils.h"
-#include "android/utils/system.h"
-#include "android/utils/debug.h"
-#include "android/utils/eintr_wrapper.h"
-#include "android/utils/panic.h"
-#include "android/protocol/core-connection.h"
-#include "android/protocol/ui-commands-impl.h"
-#include "android/protocol/ui-commands-api.h"
-
-/* Enumerates states for the command reader in UICmdImpl instance. */
-typedef enum UICmdImplState {
- /* The reader is waiting on command header. */
- EXPECTS_HEADER,
-
- /* The reader is waiting on command parameters. */
- EXPECTS_PARAMETERS,
-} UICmdImplState;
-
-/* Descriptor for the UI-side of the "core-ui-control" service. */
-typedef struct UICmdImpl {
- /* Core connection established for this service. */
- CoreConnection* core_connection;
-
- /* Socket descriptor for the UI service. */
- int sock;
-
- /* Custom i/o handler */
- LoopIo io[1];
-
- /* Command reader state. */
- UICmdImplState reader_state;
-
- /* Incoming command header. */
- UICmdHeader cmd_header;
-
- /* Reader's buffer. This field can point to the cmd_header field of this
- * structure (when we expect a command header), or to a buffer allocated for
- * the (when we expect command parameters). */
- uint8_t* reader_buffer;
-
- /* Offset in the reader's buffer where to read next chunk of data. */
- size_t reader_offset;
-
- /* Total number of bytes the reader expects to read. */
- size_t reader_bytes;
-} UICmdImpl;
-
-/* Implemented in android/qemulator.c */
-extern void android_emulator_set_window_scale(double scale, int is_dpi);
-
-/* One and only one UICmdImpl instance. */
-static UICmdImpl _uiCmdImpl;
-
-/* Display brightness change callback. */
-static AndroidHwLightBrightnessCallback _brightness_change_callback = NULL;
-static void* _brightness_change_callback_param = NULL;
-
-/* Handles UI control command received from the core.
- * Param:
- * uicmd - UICmdImpl instance that received the command.
- * header - UI control command header.
- * data - Command parameters formatted accordingly to the command type.
- */
-static void
-_uiCmdImpl_handle_command(UICmdImpl* uicmd,
- const UICmdHeader* header,
- const uint8_t* data)
-{
- switch (header->cmd_type) {
- case AUICMD_SET_WINDOWS_SCALE:
- {
- UICmdSetWindowsScale* cmd = (UICmdSetWindowsScale*)data;
- android_emulator_set_window_scale(cmd->scale, cmd->is_dpi);
- break;
- }
-
- case AUICMD_CHANGE_DISP_BRIGHTNESS:
- {
- UICmdChangeDispBrightness* cmd = (UICmdChangeDispBrightness*)data;
- if (_brightness_change_callback != NULL) {
- _brightness_change_callback(_brightness_change_callback_param,
- cmd->light, cmd->brightness);
- }
- break;
- }
-
- default:
- derror("Unknown command %d is received from the Core\n",
- header->cmd_type);
- break;
- }
-}
-
-/* Asynchronous I/O callback reading UI control commands.
- * Param:
- * opaque - UICmdImpl instance.
- */
-static void
-_uiCmdImpl_io_callback(void* opaque, int fd, unsigned events)
-{
- UICmdImpl* uicmd = opaque;
- int status;
-
- // Read requests while they are immediately available.
- for (;;) {
- // Read next chunk of data.
- status = HANDLE_EINTR(
- socket_recv(uicmd->sock,
- uicmd->reader_buffer + uicmd->reader_offset,
- uicmd->reader_bytes - uicmd->reader_offset));
- if (status < 0 && (errno == EWOULDBLOCK || errno == EGAIN) {
- // Chunk is not avalable at this point. Come back later.
- return;
- }
- if (status <= 0) {
- /* Disconnection, meaning that the core process got terminated. */
- fprintf(stderr,
- "core-ui-control service got disconnected: %s\n",
- status < 0 ?
- strerror(errno) :
- "unexpected disconnection");
- uiCmdImpl_destroy();
- return;
- }
-
- uicmd->reader_offset += status;
- if (uicmd->reader_offset != uicmd->reader_bytes) {
- // There are still some data left in the pipe.
- continue;
- }
-
- // All expected data has been read. Time to change the state.
- if (uicmd->reader_state == EXPECTS_HEADER) {
- // Header has been read.
- if (uicmd->cmd_header.cmd_param_size) {
- // Prepare for the command parameters.
- uicmd->reader_state = EXPECTS_PARAMETERS;
- uicmd->reader_offset = 0;
- uicmd->reader_bytes = uicmd->cmd_header.cmd_param_size;
- uicmd->reader_buffer = malloc(uicmd->reader_bytes);
- if (uicmd->reader_buffer == NULL) {
- APANIC("Unable to allocate memory for UI command parameters.\n");
- }
- } else {
- // This command doesn't have any parameters. Handle it now.
- _uiCmdImpl_handle_command(uicmd, &uicmd->cmd_header, NULL);
- // Prepare for the next command header.
- uicmd->reader_state = EXPECTS_HEADER;
- uicmd->reader_offset = 0;
- uicmd->reader_bytes = sizeof(uicmd->cmd_header);
- uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header;
- }
- } else {
- // All command data is in. Handle it.
- _uiCmdImpl_handle_command(uicmd, &uicmd->cmd_header,
- uicmd->reader_buffer);
- // Prepare for the next command header.
- free(uicmd->reader_buffer);
- uicmd->reader_state = EXPECTS_HEADER;
- uicmd->reader_offset = 0;
- uicmd->reader_bytes = sizeof(uicmd->cmd_header);
- uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header;
- }
- }
-}
-
-int
-uiCmdImpl_create(SockAddress* console_socket, Looper* looper)
-{
- UICmdImpl* uicmd = &_uiCmdImpl;
- char* handshake = NULL;
-
- // Setup command reader.
- uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header;
- uicmd->reader_state = EXPECTS_HEADER;
- uicmd->reader_offset = 0;
- uicmd->reader_bytes = sizeof(UICmdHeader);
-
- // Connect to the core-ui-control service.
- uicmd->core_connection =
- core_connection_create_and_switch(console_socket, "core-ui-control",
- &handshake);
- if (uicmd->core_connection == NULL) {
- derror("Unable to connect to the core-ui-control service: %s\n",
- errno_str);
- return -1;
- }
-
- // Initialize UI command reader.
- uicmd->sock = core_connection_get_socket(uicmd->core_connection);
- loopIo_init(uicmd->io, looper, uicmd->sock,
- _uiCmdImpl_io_callback,
- &_uiCmdImpl);
- loopIo_wantRead(uicmd->io);
-
- fprintf(stdout, "core-ui-control is now connected to the core at %s.",
- sock_address_to_string(console_socket));
- if (handshake != NULL) {
- if (handshake[0] != '\0') {
- fprintf(stdout, " Handshake: %s", handshake);
- }
- free(handshake);
- }
- fprintf(stdout, "\n");
-
- return 0;
-}
-
-void
-uiCmdImpl_destroy(void)
-{
- UICmdImpl* uicmd = &_uiCmdImpl;
-
- if (uicmd->core_connection != NULL) {
- // Disable I/O callbacks.
- loopIo_done(uicmd->io);
- core_connection_close(uicmd->core_connection);
- core_connection_free(uicmd->core_connection);
- uicmd->core_connection = NULL;
- }
- // Properly deallocate the reader buffer.
- if (uicmd->reader_buffer != NULL &&
- uicmd->reader_buffer != (uint8_t*)&uicmd->cmd_header) {
- free(uicmd->reader_buffer);
- uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header;
- }
-}
-
-int
-uicmd_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback,
- void* opaque)
-{
- _brightness_change_callback = callback;
- _brightness_change_callback_param = opaque;
- return 0;
-}
diff --git a/android/protocol/ui-commands-impl.h b/android/protocol/ui-commands-impl.h
deleted file mode 100644
index 717f6b6..0000000
--- a/android/protocol/ui-commands-impl.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_UI_COMMANDS_IMPL_H
-#define _ANDROID_PROTOCOL_UI_COMMANDS_IMPL_H
-
-#include "android/sockets.h"
-#include "android/looper.h"
-#include "android/protocol/ui-commands.h"
-
-/*
- * Contains the UI-side implementation of the "core-ui-control" service that is
- * part of the UI control protocol. Here we handle UI control commands sent by
- * the Core to the UI.
- */
-
-/* Creates and initializes descriptor for the UI-side of the "core-ui-control"
- * service. Note that there can be only one instance of this service in the UI.
- * Param:
- * console_socket - Addresses Core's console.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int uiCmdImpl_create(SockAddress* console_socket, Looper* looper);
-
-/* Destroys UI-side of the "core-ui-control" service. */
-extern void uiCmdImpl_destroy();
-
-#endif /* _ANDROID_PROTOCOL_UI_COMMANDS_IMPL_H */
diff --git a/android/protocol/ui-commands-proxy.c b/android/protocol/ui-commands-proxy.c
deleted file mode 100644
index 22994c5..0000000
--- a/android/protocol/ui-commands-proxy.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the Core-side implementation of the "core-ui-control" service that is
- * part of the UI control protocol. Here we send UI control commands to the UI.
- */
-
-#include "android/android.h"
-#include "android/hw-control.h"
-#include "android/looper.h"
-#include "android/async-utils.h"
-#include "android/sync-utils.h"
-#include "android/utils/debug.h"
-#include "android/protocol/ui-commands.h"
-#include "android/protocol/ui-commands-proxy.h"
-#include "android/protocol/ui-commands-api.h"
-
-/* Descriptor for the UI commands proxy. */
-typedef struct UICmdProxy {
- /* I/O associated with this descriptor. */
- LoopIo io;
-
- /* Looper associated with this descriptor. */
- Looper* looper;
-
- /* Writer to send UI commands. */
- SyncSocket* sync_writer;
-
- /* Socket descriptor for this service. */
- int sock;
-} UICmdProxy;
-
-/* One and only one UICmdProxy instance. */
-static UICmdProxy _uiCmdProxy;
-
-/* Implemented in android/console.c */
-extern void destroy_uicmd_client(void);
-
-/* Calculates timeout for transferring the given number of bytes via socket.
- * Return:
- * Number of milliseconds during which the entire number of bytes is expected
- * to be transferred via socket.
- */
-static int
-_uiCmdProxy_get_timeout(size_t data_size)
-{
- // Min 2 seconds + 10 millisec for each transferring byte.
- // TODO: Come up with a better arithmetics here.
- return 2000 + data_size * 10;
-}
-
-/* Sends request to the UI client of this service.
- * Param:
- * cmd_type, cmd_param, cmd_param_size - Define the command to send.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-static int
-_uiCmdProxy_send_command(uint8_t cmd_type,
- void* cmd_param,
- uint32_t cmd_param_size)
-{
- UICmdHeader header;
- int status = syncsocket_start_write(_uiCmdProxy.sync_writer);
- if (!status) {
- // Initialize and send the header.
- header.cmd_type = cmd_type;
- header.cmd_param_size = cmd_param_size;
- status = syncsocket_write(_uiCmdProxy.sync_writer, &header, sizeof(header),
- _uiCmdProxy_get_timeout(sizeof(header)));
- // If there are command parameters, send them too.
- if (status > 0 && cmd_param != NULL && cmd_param_size > 0) {
- status = syncsocket_write(_uiCmdProxy.sync_writer, cmd_param,
- cmd_param_size,
- _uiCmdProxy_get_timeout(cmd_param_size));
- }
- status = syncsocket_result(status);
- syncsocket_stop_write(_uiCmdProxy.sync_writer);
- }
- if (status < 0) {
- derror("Send UI command %d (%u bytes) has failed: %s\n",
- cmd_type, cmd_param_size, errno_str);
- }
- return status;
-}
-
-/* Asynchronous I/O callback for UICmdProxy instance.
- * We expect this callback to be called only on UI detachment condition. In this
- * case the event should be LOOP_IO_READ, and read should fail with errno set
- * to ECONNRESET.
- * Param:
- * opaque - UICmdProxy instance.
- */
-static void
-_uiCmdProxy_io_func(void* opaque, int fd, unsigned events)
-{
- UICmdProxy* uicmd = (UICmdProxy*)opaque;
- AsyncReader reader;
- AsyncStatus status;
- uint8_t read_buf[1];
-
- if (events & LOOP_IO_WRITE) {
- derror("Unexpected LOOP_IO_WRITE in _uiCmdProxy_io_func.\n");
- return;
- }
-
- // Try to read
- asyncReader_init(&reader, read_buf, sizeof(read_buf), &uicmd->io);
- status = asyncReader_read(&reader);
- // We expect only error status here.
- if (status != ASYNC_ERROR) {
- derror("Unexpected read status %d in _uiCmdProxy_io_func\n", status);
- return;
- }
- // We expect only socket disconnection error here.
- if (errno != ECONNRESET) {
- derror("Unexpected read error %d (%s) in _uiCmdProxy_io_func.\n",
- errno, errno_str);
- return;
- }
-
- // Client got disconnectted.
- destroy_uicmd_client();
-}
-/* a callback function called when the system wants to change the brightness
- * of a given light. 'light' is a string which can be one of:
- * 'lcd_backlight', 'button_backlight' or 'Keyboard_backlight'
- *
- * brightness is an integer (acceptable range are 0..255), however the
- * default is around 105, and we probably don't want to dim the emulator's
- * output at that level.
- */
-static void
-_uiCmdProxy_brightness_change_callback(void* opaque,
- const char* light,
- int brightness)
-{
- // Calculate size of the command parameters.
- const size_t cmd_size = sizeof(UICmdChangeDispBrightness) + strlen(light) + 1;
- // Allocate and initialize parameters.
- UICmdChangeDispBrightness* cmd =
- (UICmdChangeDispBrightness*)g_malloc(cmd_size);
- cmd->brightness = brightness;
- strcpy(cmd->light, light);
- // Send the command.
- _uiCmdProxy_send_command(AUICMD_CHANGE_DISP_BRIGHTNESS, cmd, cmd_size);
- g_free(cmd);
-}
-
-int
-uiCmdProxy_create(int fd)
-{
- // Initialize the only UICmdProxy instance.
- _uiCmdProxy.sock = fd;
- _uiCmdProxy.looper = looper_newCore();
- loopIo_init(&_uiCmdProxy.io, _uiCmdProxy.looper, _uiCmdProxy.sock,
- _uiCmdProxy_io_func, &_uiCmdProxy);
- loopIo_wantRead(&_uiCmdProxy.io);
- _uiCmdProxy.sync_writer = syncsocket_init(fd);
- if (_uiCmdProxy.sync_writer == NULL) {
- derror("Unable to initialize UICmdProxy writer: %s\n", errno_str);
- uiCmdProxy_destroy();
- return -1;
- }
- {
- // Set brighness change callback, so we can notify
- // the UI about the event.
- AndroidHwControlFuncs funcs;
- funcs.light_brightness = _uiCmdProxy_brightness_change_callback;
- android_hw_control_set(&_uiCmdProxy, &funcs);
- }
- return 0;
-}
-
-void
-uiCmdProxy_destroy()
-{
- // Destroy the sync writer.
- if (_uiCmdProxy.sync_writer != NULL) {
- syncsocket_close(_uiCmdProxy.sync_writer);
- syncsocket_free(_uiCmdProxy.sync_writer);
- }
- if (_uiCmdProxy.looper != NULL) {
- // Stop all I/O that may still be going on.
- loopIo_done(&_uiCmdProxy.io);
- looper_free(_uiCmdProxy.looper);
- _uiCmdProxy.looper = NULL;
- }
- _uiCmdProxy.sock = -1;
-}
-
-int
-uicmd_set_window_scale(double scale, int is_dpi)
-{
- UICmdSetWindowsScale cmd;
- cmd.scale = scale;
- cmd.is_dpi = is_dpi;
- return _uiCmdProxy_send_command(AUICMD_SET_WINDOWS_SCALE, &cmd, sizeof(cmd));
-}
diff --git a/android/protocol/ui-commands-proxy.h b/android/protocol/ui-commands-proxy.h
deleted file mode 100644
index 8627537..0000000
--- a/android/protocol/ui-commands-proxy.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_UI_COMMANDS_PROXY_H
-#define _ANDROID_PROTOCOL_UI_COMMANDS_PROXY_H
-
-/*
- * Contains the Core-side implementation of the "core-ui-control" service that is
- * part of the UI control protocol. Here we send UI control commands to the UI.
- */
-
-/* Creates and initializes descriptor for the Core-side of the "core-ui-control"
- * service. Note that there can be only one instance of this service in the core.
- * Param:
- * fd - Socket descriptor for the proxy.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int uiCmdProxy_create(int fd);
-
-/* Destroys the descriptor for the Core-side of the "core-ui-control" service. */
-extern void uiCmdProxy_destroy();
-
-/* Changes the scale of the emulator window at runtime.
- * Param:
- * scale, is_dpi - New window scale parameters
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int uicmd_set_window_scale(double scale, int is_dpi);
-
-#endif /* _ANDROID_PROTOCOL_UI_COMMANDS_PROXY_H */
diff --git a/android/protocol/ui-commands-qemu.c b/android/protocol/ui-commands-qemu.c
deleted file mode 100644
index 2bb22c9..0000000
--- a/android/protocol/ui-commands-qemu.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains implementation of the API for calling into the UI with the Core
- * control commands for standalone (monolithic) emulator.
- */
-
-#include "android/android.h"
-#include "android/hw-control.h"
-#include "android/protocol/ui-commands-api.h"
-
-/* Implemented in android/qemulator.c */
-extern void android_emulator_set_window_scale(double scale, int is_dpi);
-
-int
-uicmd_set_window_scale(double scale, int is_dpi)
-{
- android_emulator_set_window_scale(scale, is_dpi);
- return 0;
-}
-
-int
-uicmd_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback,
- void* opaque)
-{
- AndroidHwControlFuncs funcs;
- funcs.light_brightness = callback;
- android_hw_control_set(opaque, &funcs);
- return 0;
-}
diff --git a/android/protocol/ui-commands.h b/android/protocol/ui-commands.h
deleted file mode 100644
index 4e47b83..0000000
--- a/android/protocol/ui-commands.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_UI_COMMANDS_H
-#define _ANDROID_PROTOCOL_UI_COMMANDS_H
-
-/*
- * Contains declarations related to the UI control commands sent by the Core and
- * handled by the UI.
- */
-
-#include "android/protocol/ui-common.h"
-
-/* Sets window scale. */
-#define AUICMD_SET_WINDOWS_SCALE 1
-
-/* Changes display brightness. */
-#define AUICMD_CHANGE_DISP_BRIGHTNESS 2
-
-/* Formats AUICMD_SET_WINDOWS_SCALE UI control command parameters.
- * Contains parameters required by android_emulator_set_window_scale routine.
- */
-typedef struct UICmdSetWindowsScale {
- double scale;
- int is_dpi;
-} UICmdSetWindowsScale;
-
-/* Formats AUICMD_CHANGE_DISP_BRIGHTNESS UI control command parameters.
- */
-typedef struct UICmdChangeDispBrightness {
- int brightness;
- char light[0];
-} UICmdChangeDispBrightness;
-
-#endif /* _ANDROID_PROTOCOL_UI_COMMANDS_H */
diff --git a/android/protocol/ui-common.h b/android/protocol/ui-common.h
deleted file mode 100644
index 003ed6d..0000000
--- a/android/protocol/ui-common.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_UI_COMMON_H
-#define _ANDROID_PROTOCOL_UI_COMMON_H
-
-/*
- * Contains declarations for UI control protocol used by both the Core,
- * and the UI.
- */
-
-/* UI control command header.
- * Every UI control command sent by the Core, or by the UI begins with this
- * header, immediately followed by the command parameters (if there are any).
- * Command type is defined by cmd_type field of this header. If command doesn't
- * have any command-specific parameters, cmd_param_size field of this header
- * must be 0.
- */
-typedef struct UICmdHeader {
- /* Command type. */
- uint8_t cmd_type;
-
- /* Byte size of the buffer containing parameters for the comand defined by
- * the cmd_type field. The buffer containing parameters must immediately
- * follow this header. If command doesn't have any parameters, this field
- * must be 0 */
- uint32_t cmd_param_size;
-} UICmdHeader;
-
-/* UI control command response header.
- * If UI control command assumes a response from the remote end, the response
- * must start with this header, immediately followed by the response data buffer.
- */
-typedef struct UICmdRespHeader {
- /* Result of the command handling. */
- int result;
-
- /* Byte size of the buffer containing response data immediately following
- * this header. If there are no response data for the command, this field
- * must be 0. */
- uint32_t resp_data_size;
-} UICmdRespHeader;
-
-#endif /* _ANDROID_PROTOCOL_UI_COMMON_H */
diff --git a/android/protocol/user-events-impl.c b/android/protocol/user-events-impl.c
deleted file mode 100644
index f45169a..0000000
--- a/android/protocol/user-events-impl.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the Core-side of the "user events" service. Here we receive and
- * handle user events sent from the UI.
- */
-
-#include "android/user-events.h"
-#include "android/globals.h"
-#include "android/android.h"
-#include "android/looper.h"
-#include "android/async-utils.h"
-#include "android/sync-utils.h"
-#include "android/utils/system.h"
-#include "android/utils/debug.h"
-#include "android/protocol/user-events-protocol.h"
-#include "android/protocol/user-events-impl.h"
-
-/* Enumerates state values for the event reader in the UserEventsImpl descriptor.
- */
-typedef enum UserEventsImplState {
- /* The reader is waiting on event header. */
- EXPECTS_HEADER,
-
- /* The reader is waiting on event parameters. */
- EXPECTS_PARAMETERS,
-} UserEventsImplState;
-
-
-/* Core user events service descriptor. */
-typedef struct UserEventsImpl {
- /* Reader to receive user events. */
- AsyncReader user_events_reader;
-
- /* I/O associated with this descriptor. */
- LoopIo io;
-
- /* Looper used to communicate user events. */
- Looper* looper;
-
- /* Socket for this service. */
- int sock;
-
- /* State of the service (see UE_STATE_XXX for possible values). */
- UserEventsImplState state;
-
- /* Current event header. */
- UserEventHeader event_header;
-
- /* Current event parameters. */
- union {
- UserEventGeneric generic_event;
- UserEventMouse mouse_event;
- UserEventKeycode keycode_event;
- };
-} UserEventsImpl;
-
-/* Implemented in android/console.c */
-extern void destroy_user_events_client(void);
-
-/* One and only one UserEventsImpl instance. */
-static UserEventsImpl _UserEventsImpl;
-
-/* Asynchronous I/O callback reading user events.
- * Param:
- * opaque - UserEventsImpl instance.
- */
-static void
-_userEventsImpl_io_func(void* opaque, int fd, unsigned events)
-{
- UserEventsImpl* ueimpl;
- AsyncStatus status;
-
- if (events & LOOP_IO_WRITE) {
- // We don't use async writer here, so we don't expect
- // any write callbacks.
- derror("Unexpected LOOP_IO_WRITE in _userEventsImpl_io_func\n");
- return;
- }
-
- ueimpl = (UserEventsImpl*)opaque;
- // Read whatever is expected from the socket.
- status = asyncReader_read(&ueimpl->user_events_reader);
-
-
- switch (status) {
- case ASYNC_COMPLETE:
- switch (ueimpl->state) {
- case EXPECTS_HEADER:
- // We just read event header. Now we expect event parameters.
- ueimpl->state = EXPECTS_PARAMETERS;
- // Setup the reader depending on the event type.
- switch (ueimpl->event_header.event_type) {
- case AUSER_EVENT_MOUSE:
- asyncReader_init(&ueimpl->user_events_reader,
- &ueimpl->mouse_event,
- sizeof(ueimpl->mouse_event),
- &ueimpl->io);
- break;
-
- case AUSER_EVENT_KEYCODE:
- asyncReader_init(&ueimpl->user_events_reader,
- &ueimpl->keycode_event,
- sizeof(ueimpl->keycode_event),
- &ueimpl->io);
- break;
-
- case AUSER_EVENT_GENERIC:
- asyncReader_init(&ueimpl->user_events_reader,
- &ueimpl->generic_event,
- sizeof(ueimpl->generic_event),
- &ueimpl->io);
- break;
-
- default:
- derror("Unexpected user event type %d\n",
- ueimpl->event_header.event_type);
- break;
- }
- break;
-
- case EXPECTS_PARAMETERS:
- // We just read event parameters. Lets fire the event.
- switch (ueimpl->event_header.event_type) {
- case AUSER_EVENT_MOUSE:
- user_event_mouse(ueimpl->mouse_event.dx,
- ueimpl->mouse_event.dy,
- ueimpl->mouse_event.dz,
- ueimpl->mouse_event.buttons_state);
- break;
-
- case AUSER_EVENT_KEYCODE:
- user_event_keycode(ueimpl->keycode_event.keycode);
- break;
-
- case AUSER_EVENT_GENERIC:
- user_event_generic(ueimpl->generic_event.type,
- ueimpl->generic_event.code,
- ueimpl->generic_event.value);
- break;
-
- default:
- derror("Unexpected user event type %d\n",
- ueimpl->event_header.event_type);
- break;
- }
- // Prepare to receive the next event header.
- ueimpl->event_header.event_type = -1;
- ueimpl->state = EXPECTS_HEADER;
- asyncReader_init(&ueimpl->user_events_reader,
- &ueimpl->event_header,
- sizeof(ueimpl->event_header), &ueimpl->io);
- break;
- }
- break;
- case ASYNC_ERROR:
- loopIo_dontWantRead(&ueimpl->io);
- if (errno == ECONNRESET) {
- // UI has exited. We need to destroy user event service.
- destroy_user_events_client();
- } else {
- derror("User event read error %d -> %s\n", errno, errno_str);
- }
- break;
-
- case ASYNC_NEED_MORE:
- // Transfer will eventually come back into this routine.
- return;
- }
-}
-
-int
-userEventsImpl_create(int fd)
-{
- _UserEventsImpl.sock = fd;
- _UserEventsImpl.event_header.event_type = -1;
- _UserEventsImpl.state = EXPECTS_HEADER;
- _UserEventsImpl.looper = looper_newCore();
- loopIo_init(&_UserEventsImpl.io, _UserEventsImpl.looper, _UserEventsImpl.sock,
- _userEventsImpl_io_func, &_UserEventsImpl);
- asyncReader_init(&_UserEventsImpl.user_events_reader,
- &_UserEventsImpl.event_header,
- sizeof(_UserEventsImpl.event_header), &_UserEventsImpl.io);
- return 0;
-}
-
-void
-userEventsImpl_destroy(void)
-{
- if (_UserEventsImpl.looper != NULL) {
- // Stop all I/O that may still be going on.
- loopIo_done(&_UserEventsImpl.io);
- looper_free(_UserEventsImpl.looper);
- _UserEventsImpl.looper = NULL;
- }
-}
diff --git a/android/protocol/user-events-impl.h b/android/protocol/user-events-impl.h
deleted file mode 100644
index af5d5a4..0000000
--- a/android/protocol/user-events-impl.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the Core-side of the "user events" service. Here we receive and
- * handle user events sent from the UI.
- */
-
-#ifndef _ANDROID_PROTOCOL_USER_EVENTS_IMPL_H
-#define _ANDROID_PROTOCOL_USER_EVENTS_IMPL_H
-
-/* Creates and initializes descriptor for the Core-side of the "user-events"
- * service. Note that there can be only one instance of this service in the core.
- * Param:
- * fd - Socket descriptor for the service.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int userEventsImpl_create(int fd);
-
-/* Destroys the descriptor for the Core-side of the "user-events" service. */
-extern void userEventsImpl_destroy(void);
-
-#endif /* _ANDROID_PROTOCOL_USER_EVENTS_IMPL_H */
diff --git a/android/protocol/user-events-protocol.h b/android/protocol/user-events-protocol.h
deleted file mode 100644
index c1e64e2..0000000
--- a/android/protocol/user-events-protocol.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-#ifndef _ANDROID_PROTOCOL_USER_EVENTS_H
-#define _ANDROID_PROTOCOL_USER_EVENTS_H
-
-/*
- * Contains declarations related to the UI events handled by the Core.
- */
-
-#include "android/globals.h"
-
-/* Mouse event. */
-#define AUSER_EVENT_MOUSE 0
-/* Keycode event. */
-#define AUSER_EVENT_KEYCODE 1
-/* Generic event. */
-#define AUSER_EVENT_GENERIC 2
-
-/* Header for user event message sent from the UI to the Core.
- * Every user event sent by the UI begins with this header, immediately followed
- * by the event parameters (if there are any).
- */
-typedef struct UserEventHeader {
- /* Event type. See AUSER_EVENT_XXX for possible values. */
- uint8_t event_type;
-} UserEventHeader;
-
-/* Formats mouse event message (AUSER_EVENT_MOUSE) */
-typedef struct UserEventMouse {
- int dx;
- int dy;
- int dz;
- unsigned buttons_state;
-} UserEventMouse;
-
-/* Formats keycode event message (AUSER_EVENT_KEYCODE) */
-typedef struct UserEventKeycode {
- int keycode;
-} UserEventKeycode;
-
-/* Formats generic event message (AUSER_EVENT_GENERIC) */
-typedef struct UserEventGeneric {
- int type;
- int code;
- int value;
-} UserEventGeneric;
-
-#endif /* _ANDROID_PROTOCOL_USER_EVENTS_H */
diff --git a/android/protocol/user-events-proxy.c b/android/protocol/user-events-proxy.c
deleted file mode 100644
index 3bd0bee..0000000
--- a/android/protocol/user-events-proxy.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Copyright (C) 2010 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/user-events.h"
-#include "ui/console.h"
-#include "android/looper.h"
-#include "android/async-utils.h"
-#include "android/utils/debug.h"
-#include "android/protocol/core-connection.h"
-#include "android/protocol/user-events-protocol.h"
-#include "android/protocol/user-events-proxy.h"
-
-/* Descriptor for the user events client. */
-typedef struct UserEventsProxy {
- /* Core connection instance for the user events client. */
- CoreConnection* core_connection;
-
- /* Socket for the client. */
- int sock;
-
- /* Writes user events to the socket. */
- SyncSocket* sync_writer;
-} UserEventsProxy;
-
-/* One and only one user events client instance. */
-static UserEventsProxy _userEventsProxy = { 0 };
-
-/* Sends an event to the core.
- * Parameters:
- * event - Event type. Must be one of the AUSER_EVENT_XXX.
- * event_param - Event parameters.
- * size - Byte size of the event parameters buffer.
- * Return:
- * 0 on success, or -1 on failure.
- */
-static int
-_userEventsProxy_send(uint8_t event, const void* event_param, size_t size)
-{
- int res;
- UserEventHeader header;
-
- header.event_type = event;
- res = syncsocket_start_write(_userEventsProxy.sync_writer);
- if (!res) {
- // Send event type first (event header)
- res = syncsocket_write(_userEventsProxy.sync_writer, &header,
- sizeof(header),
- core_connection_get_timeout(sizeof(header)));
- if (res > 0) {
- // Send event param next.
- res = syncsocket_write(_userEventsProxy.sync_writer, event_param,
- size,
- core_connection_get_timeout(sizeof(size)));
- }
- res = syncsocket_result(res);
- syncsocket_stop_write(_userEventsProxy.sync_writer);
- }
- if (res < 0) {
- derror("Unable to send user event: %s\n", errno_str);
- }
- return res;
-}
-
-int
-userEventsProxy_create(SockAddress* console_socket)
-{
- char* handshake = NULL;
-
- // Connect to the user-events service.
- _userEventsProxy.core_connection =
- core_connection_create_and_switch(console_socket, "user-events",
- &handshake);
- if (_userEventsProxy.core_connection == NULL) {
- derror("Unable to connect to the user-events service: %s\n",
- errno_str);
- return -1;
- }
-
- // Initialze event writer.
- _userEventsProxy.sock =
- core_connection_get_socket(_userEventsProxy.core_connection);
- _userEventsProxy.sync_writer = syncsocket_init(_userEventsProxy.sock);
- if (_userEventsProxy.sync_writer == NULL) {
- derror("Unable to initialize UserEventsProxy writer: %s\n", errno_str);
- userEventsProxy_destroy();
- return -1;
- }
-
- fprintf(stdout, "user-events is now connected to the core at %s.",
- sock_address_to_string(console_socket));
- if (handshake != NULL) {
- if (handshake[0] != '\0') {
- fprintf(stdout, " Handshake: %s", handshake);
- }
- free(handshake);
- }
- fprintf(stdout, "\n");
-
- return 0;
-}
-
-void
-userEventsProxy_destroy(void)
-{
- if (_userEventsProxy.sync_writer != NULL) {
- syncsocket_close(_userEventsProxy.sync_writer);
- syncsocket_free(_userEventsProxy.sync_writer);
- _userEventsProxy.sync_writer = NULL;
- }
- if (_userEventsProxy.core_connection != NULL) {
- core_connection_close(_userEventsProxy.core_connection);
- core_connection_free(_userEventsProxy.core_connection);
- _userEventsProxy.core_connection = NULL;
- }
-}
-void
-user_event_keycodes(int *kcodes, int count)
-{
- int nn;
- for (nn = 0; nn < count; nn++)
- user_event_keycode(kcodes[nn]);
-}
-
-void
-user_event_keycode(int kcode)
-{
- UserEventKeycode message;
- message.keycode = kcode;
- _userEventsProxy_send(AUSER_EVENT_KEYCODE, &message, sizeof(message));
-}
-
-void
-user_event_key(unsigned code, unsigned down)
-{
- if(code == 0) {
- return;
- }
- if (VERBOSE_CHECK(keys))
- printf(">> KEY [0x%03x,%s]\n", (code & 0x1ff), down ? "down" : " up " );
-
- user_event_keycode((code & 0x1ff) | (down ? 0x200 : 0));
-}
-
-
-void
-user_event_mouse(int dx, int dy, int dz, unsigned buttons_state)
-{
- UserEventMouse message;
- message.dx = dx;
- message.dy = dy;
- message.dz = dz;
- message.buttons_state = buttons_state;
- _userEventsProxy_send(AUSER_EVENT_MOUSE, &message, sizeof(message));
-}
-
-void
-user_event_register_generic(void* opaque, QEMUPutGenericEvent *callback)
-{
-}
-
-void
-user_event_generic(int type, int code, int value)
-{
- UserEventGeneric message;
- message.type = type;
- message.code = code;
- message.value = value;
- _userEventsProxy_send(AUSER_EVENT_GENERIC, &message, sizeof(message));
-}
diff --git a/android/protocol/user-events-proxy.h b/android/protocol/user-events-proxy.h
deleted file mode 100644
index 08a80cf..0000000
--- a/android/protocol/user-events-proxy.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2010 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.
-*/
-
-/*
- * Contains the UI-side of the "user events" service. Here we send user events
- * to the Core.
- */
-
-#ifndef _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H
-#define _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H
-
-/* Creates and initializes descriptor for the UI-side of the "user-events"
- * service. Note that there can be only one instance of this service in the UI.
- * Param:
- * console_socket - Addresses Core's console.
- * Return:
- * 0 on success, or < 0 on failure.
- */
-extern int userEventsProxy_create(SockAddress* console_socket);
-
-/* Destroys the UI-side of the "user-events". */
-extern void userEventsProxy_destroy(void);
-
-#endif /* _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H */
diff --git a/android/qemu-launcher/emulator-qemu.cpp b/android/qemu-launcher/emulator-qemu.cpp
new file mode 100644
index 0000000..899cc9d
--- /dev/null
+++ b/android/qemu-launcher/emulator-qemu.cpp
@@ -0,0 +1,815 @@
+// 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.
+
+// This source file implements emulator-arm64 and emulator64-arm64
+// which are used to launch QEMU binaries located under
+// $PROGRAM_DIR/qemu/<host>/qemu-system-aarch64<exe>
+
+#include "android/base/containers/StringVector.h"
+#include "android/base/files/PathUtils.h"
+#include "android/base/Limits.h"
+#include "android/base/Log.h"
+#include "android/base/String.h"
+#include "android/base/StringFormat.h"
+
+#include "android/cmdline-option.h"
+#include "android/globals.h"
+#include "android/help.h"
+#include "android/kernel/kernel_utils.h"
+#include "android/main-common.h"
+#include "android/utils/bufprint.h"
+#include "android/utils/debug.h"
+#include "android/utils/path.h"
+#include "android/utils/stralloc.h"
+#include "android/utils/win32_cmdline_quote.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define STRINGIFY(x) _STRINGIFY(x)
+#define _STRINGIFY(x) #x
+
+#ifdef ANDROID_SDK_TOOLS_REVISION
+# define VERSION_STRING STRINGIFY(ANDROID_SDK_TOOLS_REVISION)".0"
+#else
+# define VERSION_STRING "standalone"
+#endif
+
+#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
+
+/* The execv() definition in older mingw is slightly bogus.
+ * It takes a second argument of type 'const char* const*'
+ * while POSIX mandates char** instead.
+ *
+ * To avoid compiler warnings, define the safe_execv macro
+ * to perform an explicit cast with mingw.
+ */
+#if defined(_WIN32) && !ANDROID_GCC_PREREQ(4,4)
+# define safe_execv(_filepath,_argv) execv((_filepath),(const char* const*)(_argv))
+#else
+# define safe_execv(_filepath,_argv) execv((_filepath),(_argv))
+#endif
+
+using namespace android::base;
+
+namespace {
+
+// The host CPU architecture.
+#ifdef __i386__
+const char kHostArch[] = "x86";
+#elif defined(__x86_64__)
+const char kHostArch[] = "x86_64";
+#else
+#error "Your host CPU is not supported!"
+#endif
+
+// The host operating system name.
+#ifdef __linux__
+static const char kHostOs[] = "linux";
+#elif defined(__APPLE__)
+static const char kHostOs[] = "darwin";
+#elif defined(_WIN32)
+static const char kHostOs[] = "windows";
+#endif
+
+// The target CPU architecture.
+const char kTargetArch[] = "aarch64";
+
+// Return the path of the QEMU executable
+String getQemuExecutablePath(const char* programPath) {
+ StringVector path = PathUtils::decompose(programPath);
+ if (path.size() < 1) {
+ return String();
+ }
+ // Remove program from path.
+ path.resize(path.size() - 1U);
+
+ // Add sub-directories.
+ path.append(String("qemu"));
+
+ String host = kHostOs;
+ host += "-";
+ host += kHostArch;
+ path.append(host);
+
+ String qemuProgram = "qemu-system-";
+ qemuProgram += kTargetArch;
+#ifdef _WIN32
+ qemuProgram += ".exe";
+#endif
+ path.append(qemuProgram);
+
+ return PathUtils::recompose(path);
+}
+
+void emulator_help( void ) {
+ STRALLOC_DEFINE(out);
+ android_help_main(out);
+ printf("%.*s", out->n, out->s);
+ stralloc_reset(out);
+ exit(1);
+}
+
+/* TODO: Put in shared source file */
+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/%s", rootPath, fileName);
+ if (p >= end) {
+ return NULL;
+ }
+ return ASTRDUP(temp);
+ }
+}
+
+uint64_t _adjustPartitionSize(const char* description,
+ uint64_t imageBytes,
+ uint64_t defaultBytes,
+ int inAndroidBuild ) {
+ char temp[64];
+ unsigned imageMB;
+ unsigned defaultMB;
+
+ if (imageBytes <= defaultBytes)
+ return defaultBytes;
+
+ imageMB = convertBytesToMB(imageBytes);
+ defaultMB = convertBytesToMB(defaultBytes);
+
+ if (imageMB > defaultMB) {
+ snprintf(temp, sizeof temp, "(%d MB > %d MB)", imageMB, defaultMB);
+ } else {
+ snprintf(temp, sizeof temp, "(%" PRIu64 " bytes > %" PRIu64 " bytes)", imageBytes, defaultBytes);
+ }
+
+ if (inAndroidBuild) {
+ dwarning("%s partition size adjusted to match image file %s\n", description, temp);
+ }
+
+ return convertMBToBytes(imageMB);
+}
+
+bool android_op_wipe_data;
+
+} // namespace
+
+extern "C" int main(int argc, char **argv, char **envp) {
+ if (argc < 1) {
+ fprintf(stderr, "Invalid invokation (no program path)\n");
+ return 1;
+ }
+
+ AndroidOptions opts[1];
+
+ if (android_parse_options(&argc, &argv, opts) < 0) {
+ return 1;
+ }
+
+ // TODO(digit): This code is very similar to the one in main.c,
+ // refactor everything so that it fits into a single shared source
+ // file, if possible, with the least amount of dependencies.
+
+ while (argc-- > 1) {
+ const char* opt = (++argv)[0];
+
+ if(!strcmp(opt, "-qemu")) {
+ argc--;
+ argv++;
+ break;
+ }
+
+ if (!strcmp(opt, "-help")) {
+ emulator_help();
+ }
+
+ if (!strncmp(opt, "-help-",6)) {
+ STRALLOC_DEFINE(out);
+ opt += 6;
+
+ if (!strcmp(opt, "all")) {
+ android_help_all(out);
+ }
+ else if (android_help_for_option(opt, out) == 0) {
+ /* ok */
+ }
+ else if (android_help_for_topic(opt, out) == 0) {
+ /* ok */
+ }
+ if (out->n > 0) {
+ printf("\n%.*s", out->n, out->s);
+ exit(0);
+ }
+
+ fprintf(stderr, "unknown option: -help-%s\n", opt);
+ fprintf(stderr, "please use -help for a list of valid topics\n");
+ exit(1);
+ }
+
+ if (opt[0] == '-') {
+ fprintf(stderr, "unknown option: %s\n", opt);
+ fprintf(stderr, "please use -help for a list of valid options\n");
+ exit(1);
+ }
+
+ fprintf(stderr, "invalid command-line parameter: %s.\n", opt);
+ fprintf(stderr, "Hint: use '@foo' to launch a virtual device named 'foo'.\n");
+ fprintf(stderr, "please use -help for more information\n");
+ exit(1);
+ }
+
+ if (opts->version) {
+ printf("Android emulator version %s\n"
+ "Copyright (C) 2006-2011 The Android Open Source Project and many others.\n"
+ "This program is a derivative of the QEMU CPU emulator (www.qemu.org).\n\n",
+#if defined ANDROID_BUILD_ID
+ VERSION_STRING " (build_id " STRINGIFY(ANDROID_BUILD_ID) ")" );
+#else
+ VERSION_STRING);
+#endif
+ printf(" This software is licensed under the terms of the GNU General Public\n"
+ " License version 2, as published by the Free Software Foundation, and\n"
+ " may be copied, distributed, and modified under those terms.\n\n"
+ " This program is distributed in the hope that it will be useful,\n"
+ " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ " GNU General Public License for more details.\n\n");
+
+ exit(0);
+ }
+
+ sanitizeOptions(opts);
+
+ // Ignore snapshot storage here.
+
+ int inAndroidBuild = 0;
+ AvdInfo* avd = createAVD(opts, &inAndroidBuild);
+
+ // Ignore skin options here.
+
+ // Read hardware configuration, apply overrides from options.
+ AndroidHwConfig* hw = android_hw;
+ if (avdInfo_initHwConfig(avd, hw) < 0) {
+ derror("could not read hardware configuration ?");
+ exit(1);
+ }
+
+ /* Update CPU architecture for HW configs created from build dir. */
+ if (inAndroidBuild) {
+#if defined(TARGET_ARM)
+ reassign_string(&android_hw->hw_cpu_arch, "arm");
+#elif defined(TARGET_I386)
+ reassign_string(&android_hw->hw_cpu_arch, "x86");
+#elif defined(TARGET_MIPS)
+ reassign_string(&android_hw->hw_cpu_arch, "mips");
+#elif defined(TARGET_ARM64)
+ reassign_string(&android_hw->hw_cpu_arch, "arm64");
+#endif
+ }
+
+ /* generate arguments for the underlying qemu main() */
+ {
+ char* kernelFile = opts->kernel;
+
+ if (kernelFile == NULL) {
+ kernelFile = avdInfo_getKernelPath(avd);
+ if (kernelFile == NULL) {
+ derror( "This AVD's configuration is missing a kernel file!!" );
+ exit(2);
+ }
+ D("autoconfig: -kernel %s", kernelFile);
+ }
+ if (!path_exists(kernelFile)) {
+ derror( "Invalid or missing kernel image file: %s", kernelFile );
+ exit(2);
+ }
+
+ hw->kernel_path = kernelFile;
+ }
+
+ KernelType kernelType = KERNEL_TYPE_LEGACY;
+ if (!android_pathProbeKernelType(hw->kernel_path, &kernelType)) {
+ D("WARNING: Could not determine kernel device naming scheme. Assuming legacy\n"
+ "If this AVD doesn't boot, and uses a recent kernel (3.10 or above) try setting\n"
+ "'kernel.newDeviceNaming' to 'yes' in its configuration.\n");
+ }
+
+ // Auto-detect kernel device naming scheme if needed.
+ if (androidHwConfig_getKernelDeviceNaming(hw) < 0) {
+ const char* newDeviceNaming = "no";
+ if (kernelType == KERNEL_TYPE_3_10_OR_ABOVE) {
+ D("Auto-detect: Kernel image requires new device naming scheme.");
+ newDeviceNaming = "yes";
+ } else {
+ D("Auto-detect: Kernel image requires legacy device naming scheme.");
+ }
+ AFREE(hw->kernel_newDeviceNaming);
+ hw->kernel_newDeviceNaming = ASTRDUP(newDeviceNaming);
+ }
+
+ // Auto-detect YAFFS2 partition support if needed.
+ if (androidHwConfig_getKernelYaffs2Support(hw) < 0) {
+ // Essentially, anything before API level 20 supports Yaffs2
+ const char* newYaffs2Support = "no";
+ if (avdInfo_getApiLevel(avd) < 20) {
+ newYaffs2Support = "yes";
+ D("Auto-detect: Kernel does support YAFFS2 partitions.");
+ } else {
+ D("Auto-detect: Kernel does not support YAFFS2 partitions.");
+ }
+ AFREE(hw->kernel_supportsYaffs2);
+ hw->kernel_supportsYaffs2 = ASTRDUP(newYaffs2Support);
+ }
+
+
+ /* opts->ramdisk is never NULL (see createAVD) here */
+ if (opts->ramdisk) {
+ reassign_string(&hw->disk_ramdisk_path, opts->ramdisk);
+ }
+ else if (!hw->disk_ramdisk_path[0]) {
+ hw->disk_ramdisk_path = avdInfo_getRamdiskPath(avd);
+ D("autoconfig: -ramdisk %s", hw->disk_ramdisk_path);
+ }
+
+ /* -partition-size is used to specify the max size of both the system
+ * and data partition sizes.
+ */
+ uint64_t defaultPartitionSize = convertMBToBytes(200);
+
+ if (opts->partition_size) {
+ char* end;
+ long sizeMB = strtol(opts->partition_size, &end, 0);
+ long minSizeMB = 10;
+ long maxSizeMB = LONG_MAX / ONE_MB;
+
+ if (sizeMB < 0 || *end != 0) {
+ derror( "-partition-size must be followed by a positive integer" );
+ exit(1);
+ }
+ if (sizeMB < minSizeMB || sizeMB > maxSizeMB) {
+ derror( "partition-size (%d) must be between %dMB and %dMB",
+ sizeMB, minSizeMB, maxSizeMB );
+ exit(1);
+ }
+ defaultPartitionSize = (uint64_t) sizeMB * ONE_MB;
+ }
+
+ /** SYSTEM PARTITION **/
+
+ if (opts->sysdir == NULL) {
+ if (avdInfo_inAndroidBuild(avd)) {
+ opts->sysdir = ASTRDUP(avdInfo_getContentPath(avd));
+ D("autoconfig: -sysdir %s", opts->sysdir);
+ }
+ }
+
+ if (opts->sysdir != NULL) {
+ if (!path_exists(opts->sysdir)) {
+ derror("Directory does not exist: %s", opts->sysdir);
+ exit(1);
+ }
+ }
+
+ {
+ char* rwImage = NULL;
+ char* initImage = NULL;
+
+ do {
+ if (opts->system == NULL) {
+ /* If -system is not used, try to find a runtime system image
+ * (i.e. system-qemu.img) in the content directory.
+ */
+ rwImage = avdInfo_getSystemImagePath(avd);
+ if (rwImage != NULL) {
+ break;
+ }
+ /* Otherwise, try to find the initial system image */
+ initImage = avdInfo_getSystemInitImagePath(avd);
+ if (initImage == NULL) {
+ derror("No initial system image for this configuration!");
+ exit(1);
+ }
+ break;
+ }
+
+ /* If -system <name> is used, use it to find the initial image */
+ if (opts->sysdir != NULL && !path_exists(opts->system)) {
+ initImage = _getFullFilePath(opts->sysdir, opts->system);
+ } else {
+ initImage = ASTRDUP(opts->system);
+ }
+ if (!path_exists(initImage)) {
+ derror("System image file doesn't exist: %s", initImage);
+ exit(1);
+ }
+
+ } while (0);
+
+ if (rwImage != NULL) {
+ /* Use the read/write image file directly */
+ hw->disk_systemPartition_path = rwImage;
+ hw->disk_systemPartition_initPath = NULL;
+ D("Using direct system image: %s", rwImage);
+ } else if (initImage != NULL) {
+ hw->disk_systemPartition_path = NULL;
+ hw->disk_systemPartition_initPath = initImage;
+ D("Using initial system image: %s", initImage);
+ }
+
+ /* Check the size of the system partition image.
+ * If we have an AVD, it must be smaller than
+ * the disk.systemPartition.size hardware property.
+ *
+ * Otherwise, we need to adjust the systemPartitionSize
+ * automatically, and print a warning.
+ *
+ */
+ const char* systemImage = hw->disk_systemPartition_path;
+ uint64_t systemBytes;
+
+ if (systemImage == NULL)
+ systemImage = hw->disk_systemPartition_initPath;
+
+ if (path_get_size(systemImage, &systemBytes) < 0) {
+ derror("Missing system image: %s", systemImage);
+ exit(1);
+ }
+
+ hw->disk_systemPartition_size =
+ _adjustPartitionSize("system", systemBytes, defaultPartitionSize,
+ avdInfo_inAndroidBuild(avd));
+ }
+
+ /** DATA PARTITION **/
+
+ if (opts->datadir) {
+ if (!path_exists(opts->datadir)) {
+ derror("Invalid -datadir directory: %s", opts->datadir);
+ }
+ }
+
+ {
+ char* dataImage = NULL;
+ char* initImage = NULL;
+
+ do {
+ if (!opts->data) {
+ dataImage = avdInfo_getDataImagePath(avd);
+ if (dataImage != NULL) {
+ D("autoconfig: -data %s", dataImage);
+ break;
+ }
+ dataImage = avdInfo_getDefaultDataImagePath(avd);
+ if (dataImage == NULL) {
+ derror("No data image path for this configuration!");
+ exit (1);
+ }
+ opts->wipe_data = 1;
+ break;
+ }
+
+ if (opts->datadir) {
+ dataImage = _getFullFilePath(opts->datadir, opts->data);
+ } else {
+ dataImage = ASTRDUP(opts->data);
+ }
+ } while (0);
+
+ if (opts->initdata != NULL) {
+ initImage = ASTRDUP(opts->initdata);
+ if (!path_exists(initImage)) {
+ derror("Invalid initial data image path: %s", initImage);
+ exit(1);
+ }
+ } else {
+ initImage = avdInfo_getDataInitImagePath(avd);
+ D("autoconfig: -initdata %s", initImage);
+ }
+
+ hw->disk_dataPartition_path = dataImage;
+ if (opts->wipe_data) {
+ hw->disk_dataPartition_initPath = initImage;
+ } else {
+ hw->disk_dataPartition_initPath = NULL;
+ }
+ android_op_wipe_data = opts->wipe_data;
+
+ uint64_t defaultBytes =
+ hw->disk_dataPartition_size == 0 ?
+ defaultPartitionSize :
+ hw->disk_dataPartition_size;
+ uint64_t dataBytes;
+ const char* dataPath = hw->disk_dataPartition_initPath;
+
+ if (dataPath == NULL)
+ dataPath = hw->disk_dataPartition_path;
+
+ path_get_size(dataPath, &dataBytes);
+
+ hw->disk_dataPartition_size =
+ _adjustPartitionSize("data", dataBytes, defaultBytes,
+ avdInfo_inAndroidBuild(avd));
+ }
+
+ /** CACHE PARTITION **/
+
+ if (opts->no_cache) {
+ /* No cache partition at all */
+ hw->disk_cachePartition = 0;
+ }
+ else if (!hw->disk_cachePartition) {
+ if (opts->cache) {
+ dwarning( "Emulated hardware doesn't support a cache partition. -cache option ignored!" );
+ opts->cache = NULL;
+ }
+ }
+ else
+ {
+ if (!opts->cache) {
+ /* Find the current cache partition file */
+ opts->cache = avdInfo_getCachePath(avd);
+ if (opts->cache == NULL) {
+ /* The file does not exists, we will force its creation
+ * if we are not in the Android build system. Otherwise,
+ * a temporary file will be used.
+ */
+ if (!avdInfo_inAndroidBuild(avd)) {
+ opts->cache = avdInfo_getDefaultCachePath(avd);
+ }
+ }
+ if (opts->cache) {
+ D("autoconfig: -cache %s", opts->cache);
+ }
+ }
+
+ if (opts->cache) {
+ hw->disk_cachePartition_path = ASTRDUP(opts->cache);
+ }
+ }
+
+ if (hw->disk_cachePartition_path && opts->cache_size) {
+ /* Set cache partition size per user options. */
+ char* end;
+ long sizeMB = strtol(opts->cache_size, &end, 0);
+
+ if (sizeMB < 0 || *end != 0) {
+ derror( "-cache-size must be followed by a positive integer" );
+ exit(1);
+ }
+ hw->disk_cachePartition_size = (uint64_t) sizeMB * ONE_MB;
+ }
+
+ /** SD CARD PARTITION */
+
+ if (!hw->hw_sdCard) {
+ /* No SD Card emulation, so -sdcard will be ignored */
+ if (opts->sdcard) {
+ dwarning( "Emulated hardware doesn't support SD Cards. -sdcard option ignored." );
+ opts->sdcard = NULL;
+ }
+ } else {
+ /* Auto-configure -sdcard if it is not available */
+ if (!opts->sdcard) {
+ do {
+ /* If -datadir <path> is used, look for a sdcard.img file here */
+ if (opts->datadir) {
+ char tmp[PATH_MAX], *tmpend = tmp + sizeof(tmp);
+ bufprint(tmp, tmpend, "%s/%s", opts->datadir, "system.img");
+ if (path_exists(tmp)) {
+ opts->sdcard = strdup(tmp);
+ break;
+ }
+ }
+
+ /* Otherwise, look at the AVD's content */
+ opts->sdcard = avdInfo_getSdCardPath(avd);
+ if (opts->sdcard != NULL) {
+ break;
+ }
+
+ /* Nothing */
+ } while (0);
+
+ if (opts->sdcard) {
+ D("autoconfig: -sdcard %s", opts->sdcard);
+ }
+ }
+ }
+
+ if(opts->sdcard) {
+ uint64_t size;
+ if (path_get_size(opts->sdcard, &size) == 0) {
+ /* see if we have an sdcard image. get its size if it exists */
+ /* due to what looks like limitations of the MMC protocol, one has
+ * to use an SD Card image that is equal or larger than 9 MB
+ */
+ if (size < 9*1024*1024ULL) {
+ fprintf(stderr, "### WARNING: SD Card files must be at least 9MB, ignoring '%s'\n", opts->sdcard);
+ } else {
+ hw->hw_sdCard_path = ASTRDUP(opts->sdcard);
+ }
+ } else {
+ dwarning("no SD Card image at '%s'", opts->sdcard);
+ }
+ }
+
+ if (opts->memory) {
+ char* end;
+ long ramSize = strtol(opts->memory, &end, 0);
+ if (ramSize < 0 || *end != 0) {
+ derror( "-memory must be followed by a positive integer" );
+ exit(1);
+ }
+ if (ramSize < 32 || ramSize > 4096) {
+ derror( "physical memory size must be between 32 and 4096 MB" );
+ exit(1);
+ }
+ hw->hw_ramSize = ramSize;
+ } else {
+ int ramSize = hw->hw_ramSize;
+ if (ramSize <= 0) {
+#if 1
+ // For ARM64, use 1GB by default.
+ ramSize = 1024 * 1024ULL;
+#else
+ /* Compute the default RAM size based on the size of screen.
+ * This is only used when the skin doesn't provide the ram
+ * size through its hardware.ini (i.e. legacy ones) or when
+ * in the full Android build system.
+ */
+ int64_t pixels = hw->hw_lcd_width * hw->hw_lcd_height;
+ /* The following thresholds are a bit liberal, but we
+ * essentially want to ensure the following mappings:
+ *
+ * 320x480 -> 96
+ * 800x600 -> 128
+ * 1024x768 -> 256
+ *
+ * These are just simple heuristics, they could change in
+ * the future.
+ */
+ if (pixels <= 250000)
+ ramSize = 96;
+ else if (pixels <= 500000)
+ ramSize = 128;
+ else
+ ramSize = 256;
+ }
+#endif
+ hw->hw_ramSize = ramSize;
+ }
+
+ D("Physical RAM size: %dMB\n", hw->hw_ramSize);
+
+ if (opts->gpu) {
+ const char* gpu = opts->gpu;
+ if (!strcmp(gpu,"on") || !strcmp(gpu,"enable")) {
+ hw->hw_gpu_enabled = 1;
+ } else if (!strcmp(gpu,"off") || !strcmp(gpu,"disable")) {
+ hw->hw_gpu_enabled = 0;
+ } else if (!strcmp(gpu,"auto")) {
+ /* Nothing to do */
+ } else {
+ derror("Invalid value for -gpu <mode> parameter: %s\n", gpu);
+ derror("Valid values are: on, off or auto\n");
+ exit(1);
+ }
+ }
+
+ hw->avd_name = ASTRDUP(avdInfo_getName(avd));
+
+ String qemuExecutable = getQemuExecutablePath(argv[0]);
+ D("QEMU EXECUTABLE=%s\n", qemuExecutable.c_str());
+
+ // Now build the QEMU parameters.
+ const char* args[128];
+ int n = 0;
+
+ args[n++] = qemuExecutable.c_str();
+
+ args[n++] = "-cpu";
+ args[n++] = "cortex-a57";
+ args[n++] = "-machine";
+ args[n++] = "type=ranchu";
+
+ // Memory size
+ args[n++] = "-m";
+ String memorySize = StringFormat("%ld", hw->hw_ramSize);
+ args[n++] = memorySize.c_str();
+
+ // Command-line
+ args[n++] = "-append";
+ String kernelCommandLine =
+ "console=ttyAMA0,38400 keep_bootcon earlyprintk=ttyAMA0";
+ args[n++] = kernelCommandLine.c_str();
+
+ args[n++] = "-serial";
+ args[n++] = "mon:stdio";
+
+ // Kernel image
+ args[n++] = "-kernel";
+ args[n++] = hw->kernel_path;
+
+ // Ramdisk
+ args[n++] = "-initrd";
+ args[n++] = hw->disk_ramdisk_path;
+
+ // Data partition.
+ args[n++] = "-drive";
+ String userDataParam =
+ StringFormat("index=2,id=userdata,file=%s",
+ hw->disk_dataPartition_path);
+ args[n++] = userDataParam.c_str();
+ args[n++] = "-device";
+ args[n++] = "virtio-blk-device,drive=userdata";
+
+ // Cache partition.
+ args[n++] = "-drive";
+ String cacheParam =
+ StringFormat("index=1,id=cache,file=%s",
+ hw->disk_cachePartition_path);
+ args[n++] = cacheParam.c_str();
+ args[n++] = "-device";
+ args[n++] = "virtio-blk-device,drive=cache";
+
+ // System partition.
+ args[n++] = "-drive";
+ String systemParam =
+ StringFormat("index=0,id=system,file=%s",
+ hw->disk_systemPartition_initPath);
+ args[n++] = systemParam.c_str();
+ args[n++] = "-device";
+ args[n++] = "virtio-blk-device,drive=system";
+
+ // Network
+ args[n++] = "-netdev";
+ args[n++] = "user,id=mynet";
+ args[n++] = "-device";
+ args[n++] = "virtio-net-device,netdev=mynet";
+ args[n++] = "-show-cursor";
+
+ if(VERBOSE_CHECK(init)) {
+ int i;
+ printf("QEMU options list:\n");
+ for(i = 0; i < n; i++) {
+ printf("emulator: argv[%02d] = \"%s\"\n", i, args[i]);
+ }
+ /* Dump final command-line option to make debugging the core easier */
+ printf("Concatenated QEMU options:\n");
+ for (i = 0; i < n; i++) {
+ /* To make it easier to copy-paste the output to a command-line,
+ * quote anything that contains spaces.
+ */
+ if (strchr(args[i], ' ') != NULL) {
+ printf(" '%s'", args[i]);
+ } else {
+ printf(" %s", args[i]);
+ }
+ }
+ printf("\n");
+ }
+
+ if (!path_exists(qemuExecutable.c_str())) {
+ fprintf(stderr, "Missing QEMU executable: %s\n",
+ qemuExecutable.c_str());
+ return 1;
+ }
+
+ // Now launch executable.
+#ifdef _WIN32
+ // Take care of quoting all parameters before sending them to execv().
+ // See the "Eveyone quotes command line arguments the wrong way" on
+ // MSDN.
+ int i;
+ for (i = 0; i < n; ++i) {
+ // Technically, this leaks the quoted strings, but we don't care
+ // since this process will terminate after the execv() anyway.
+ args[i] = win32_cmdline_quote(args[i]);
+ D("Quoted param: [%s]\n", args[i]);
+ }
+#endif
+
+ safe_execv(qemuExecutable.c_str(), (char* const*)args);
+
+ fprintf(stderr,
+ "Could not launch QEMU [%s]: %s\n",
+ qemuExecutable.c_str(),
+ strerror(errno));
+
+ return errno;
+}
+}
+}
+}
diff --git a/android/qemulator.c b/android/qemulator.c
index ffd547b..8c8aa0d 100644
--- a/android/qemulator.c
+++ b/android/qemulator.c
@@ -13,10 +13,10 @@
#include "android/utils/debug.h"
#include "android/utils/bufprint.h"
#include "android/globals.h"
+#include "android/hw-control.h"
#include "android/qemulator.h"
-#include "android/protocol/core-commands-api.h"
-#include "android/protocol/ui-commands-api.h"
#include "android/user-events.h"
+#include "telephony/modem_driver.h"
#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
static double get_default_scale( AndroidOptions* opts );
@@ -89,8 +89,9 @@
}
/* initialize hardware control support */
- uicmd_set_brightness_change_callback(qemulator_light_brightness,
- emulator);
+ AndroidHwControlFuncs funcs;
+ funcs.light_brightness = qemulator_light_brightness;
+ android_hw_control_set(emulator, &funcs);
}
static void
@@ -252,7 +253,7 @@
static int
get_device_dpi( AndroidOptions* opts )
{
- int dpi_device = corecmd_get_hw_lcd_density();
+ int dpi_device = android_hw->hw_lcd_density;
if (opts->dpi_device != NULL) {
char* end;
@@ -393,8 +394,14 @@
{
case SKIN_KEY_COMMAND_TOGGLE_NETWORK:
{
- corecmd_toggle_network();
- D( "network is now %s", corecmd_is_network_disabled() ?
+ qemu_net_disable = !qemu_net_disable;
+ if (android_modem) {
+ amodem_set_data_registration(
+ android_modem,
+ qemu_net_disable ? A_REGISTRATION_UNREGISTERED
+ : A_REGISTRATION_HOME);
+ }
+ D( "network is now %s", qemu_net_disable ?
"disconnected" : "connected" );
}
break;
@@ -588,7 +595,7 @@
}
void
-android_emulator_set_window_scale( double scale, int is_dpi )
+android_emulator_set_window_scale(double scale, int is_dpi)
{
QEmulator* emulator = qemulator;
diff --git a/android/qemulator.h b/android/qemulator.h
index 16cafcf..c3dce63 100644
--- a/android/qemulator.h
+++ b/android/qemulator.h
@@ -41,6 +41,9 @@
QEmulator*
qemulator_get(void);
+void
+android_emulator_set_window_scale(double scale, int is_dpi);
+
/* Initializes QEmulator structure instance. */
int
qemulator_init( QEmulator* emulator,
diff --git a/android/skin/window.c b/android/skin/window.c
index 23f2090..fd0d164 100644
--- a/android/skin/window.c
+++ b/android/skin/window.c
@@ -13,10 +13,10 @@
#include "android/skin/image.h"
#include "android/skin/scaler.h"
#include "android/charmap.h"
+#include "android/hw-sensors.h"
#include "android/utils/debug.h"
#include "android/utils/system.h"
#include "android/utils/duff.h"
-#include "android/protocol/core-commands-api.h"
#include <SDL_syswm.h>
#include "android/user-events.h"
#include <math.h>
@@ -1465,9 +1465,9 @@
user_event_generic( slayout->event_type, slayout->event_code, slayout->event_value );
/* XXX: hack, replace by better code here */
if (slayout->event_value != 0)
- corecmd_set_coarse_orientation( ANDROID_COARSE_PORTRAIT );
+ android_sensors_set_coarse_orientation(ANDROID_COARSE_PORTRAIT);
else
- corecmd_set_coarse_orientation( ANDROID_COARSE_LANDSCAPE );
+ android_sensors_set_coarse_orientation(ANDROID_COARSE_LANDSCAPE);
}
return 0;
diff --git a/android/utils/bufprint.h b/android/utils/bufprint.h
index b2407b2..e652bb9 100644
--- a/android/utils/bufprint.h
+++ b/android/utils/bufprint.h
@@ -15,9 +15,9 @@
#include <stdarg.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
/** FORMATTED BUFFER PRINTING
**
@@ -77,8 +77,6 @@
extern char* bufprint_temp_dir (char* buffer, char* buffend);
extern char* bufprint_temp_file (char* buffer, char* buffend, const char* suffix);
-#ifdef __cplusplus
-}
-#endif
+ANDROID_END_HEADER
#endif /* _ANDROID_UTILS_BUFPRINT_H */
diff --git a/android/utils/debug.h b/android/utils/debug.h
index 83b4188..af3718d 100644
--- a/android/utils/debug.h
+++ b/android/utils/debug.h
@@ -14,6 +14,10 @@
#include <stdarg.h>
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
#define VERBOSE_TAG_LIST \
_VERBOSE_TAG(init, "emulator initialization") \
_VERBOSE_TAG(console, "control console") \
@@ -99,6 +103,6 @@
extern void stdio_disable( void );
extern void stdio_enable( void );
-/* */
+ANDROID_END_HEADER
#endif /* _ANDROID_UTILS_DEBUG_H */
diff --git a/android/utils/dirscanner.h b/android/utils/dirscanner.h
index 871b05e..c8caff9 100644
--- a/android/utils/dirscanner.h
+++ b/android/utils/dirscanner.h
@@ -12,6 +12,10 @@
#ifndef _ANDROID_UTILS_DIR_H
#define _ANDROID_UTILS_DIR_H
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/* simple utility to parse directories for files */
/* needed because Unix and Windows don't use the same stuff */
@@ -46,6 +50,6 @@
*/
const char* dirScanner_nextFull( DirScanner* s );
-/* */
+ANDROID_END_HEADER
#endif /* _ANDROID_UTILS_DIR_H */
diff --git a/android/utils/dll.h b/android/utils/dll.h
index 66f3a6d..acd3f87 100644
--- a/android/utils/dll.h
+++ b/android/utils/dll.h
@@ -12,6 +12,10 @@
#ifndef ANDROID_UTILS_DLL_H
#define ANDROID_UTILS_DLL_H
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/* Opaque type to model a dynamic library handle */
typedef struct ADynamicLibrary ADynamicLibrary;
@@ -41,4 +45,6 @@
/* Close/unload a given dynamic library */
void adynamicLibrary_close( ADynamicLibrary* lib );
+ANDROID_END_HEADER
+
#endif /* ANDROID_UTILS_DLL_H */
diff --git a/android/utils/filelock.h b/android/utils/filelock.h
index 9bc86b5..8ada81a 100644
--- a/android/utils/filelock.h
+++ b/android/utils/filelock.h
@@ -13,6 +13,10 @@
#ifndef _ANDROID_UTILS_FILELOCK_H
#define _ANDROID_UTILS_FILELOCK_H
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/** FILE LOCKS SUPPORT
**
** a FileLock is useful to prevent several emulator instances from using the same
@@ -35,4 +39,6 @@
extern FileLock* filelock_create ( const char* path );
extern void filelock_release( FileLock* lock );
+ANDROID_END_HEADER
+
#endif /* _ANDROID_UTILS_FILELOCK_H */
diff --git a/android/utils/ini.h b/android/utils/ini.h
index fd56575..08bee97 100644
--- a/android/utils/ini.h
+++ b/android/utils/ini.h
@@ -14,6 +14,10 @@
#include <stdint.h>
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/* the emulator supports a simple .ini file format for its configuration
* files. See docs/ANDROID-CONFIG-FILES.TXT for details.
*/
@@ -107,6 +111,6 @@
void iniFile_setBoolean( IniFile* f, const char* key, int value );
void iniFile_setDiskSize( IniFile* f, const char* key, int64_t size );
-/* */
+ANDROID_END_HEADER
#endif /* _ANDROID_UTILS_INI_H */
diff --git a/android/utils/intmap.h b/android/utils/intmap.h
index 6fd450a..8a0d32a 100644
--- a/android/utils/intmap.h
+++ b/android/utils/intmap.h
@@ -12,6 +12,10 @@
#ifndef _ANDROID_UTILS_INTMAP_H
#define _ANDROID_UTILS_INTMAP_H
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/* A simple container that can hold a simple mapping from integers to
* references. I.e. a dictionary where keys are integers, and values
* are liberal pointer values (NULL is allowed).
@@ -103,4 +107,6 @@
aintMapIterator_done(__aintmap_foreach_iter); \
} while (0)
+ANDROID_END_HEADER
+
#endif /* _ANDROID_UTILS_INTMAP_H */
diff --git a/android/utils/jpeg-compress.h b/android/utils/jpeg-compress.h
index 1f84a5d..a13ef99 100644
--- a/android/utils/jpeg-compress.h
+++ b/android/utils/jpeg-compress.h
@@ -12,6 +12,10 @@
#ifndef _ANDROID_UTILS_JPEG_COMPRESS_H
#define _ANDROID_UTILS_JPEG_COMPRESS_H
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/*
* Contains declaration of utility routines that compress an RGB bitmap into
* a JPEG image.
@@ -96,4 +100,6 @@
int jpeg_quality,
int ydir);
+ANDROID_END_HEADER
+
#endif /* _ANDROID_UTILS_JPEG_COMPRESS_H */
diff --git a/android/utils/lineinput.h b/android/utils/lineinput.h
index 1870285..2fc6bd3 100644
--- a/android/utils/lineinput.h
+++ b/android/utils/lineinput.h
@@ -14,6 +14,10 @@
#include <stdio.h>
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/* A LineInput is used to read input text, one line at a time,
* into a temporary buffer owner by the LineInput object.
*/
@@ -53,4 +57,6 @@
/* Free a LineInput object. */
void lineInput_free( LineInput* input );
+ANDROID_END_HEADER
+
#endif /* _ANDROID_UTILS_LINEINPUT_H */
diff --git a/android/utils/list.h b/android/utils/list.h
index a4171ae..d163ae9 100644
--- a/android/utils/list.h
+++ b/android/utils/list.h
@@ -14,6 +14,10 @@
#include <inttypes.h>
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/* Encapsulates a double-linked, circular list.
* The list is organized in the following way:
* - List entries contain references to the next, and the previous entry in the
@@ -109,4 +113,6 @@
return entry;
}
+ANDROID_END_HEADER
+
#endif /* _ANDROID_UTILS_LIST_H */
diff --git a/android/utils/misc.h b/android/utils/misc.h
index 0d943f7..690249e 100644
--- a/android/utils/misc.h
+++ b/android/utils/misc.h
@@ -14,6 +14,10 @@
#include <stdint.h>
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/** TABULAR OUTPUT
**
** prints a list of strings in row/column format
@@ -121,4 +125,6 @@
*/
extern int get_token_value_int(const char* params, const char* name, int* value);
+ANDROID_END_HEADER
+
#endif /* _ANDROID_UTILS_MISC_H */
diff --git a/android/utils/reflist.h b/android/utils/reflist.h
index 7275f54..8c3783f 100644
--- a/android/utils/reflist.h
+++ b/android/utils/reflist.h
@@ -13,8 +13,12 @@
#define _ANDROID_GRAPHICS_REFLIST_H
#include <inttypes.h>
+
+#include "android/utils/compiler.h"
#include <android/utils/system.h>
+ANDROID_BEGIN_HEADER
+
/* Definitions for a smart list of references to generic objects.
* supports safe deletion and addition while they are being iterated
* with AREFLIST_FOREACH() macro.
@@ -205,4 +209,6 @@
void areflist_copy(ARefList* dst, const ARefList* src);
+ANDROID_END_HEADER
+
#endif /* _ANDROID_GRAPHICS_REFLIST_H */
diff --git a/android/utils/refset.h b/android/utils/refset.h
index 4db9b2b..30cf61f 100644
--- a/android/utils/refset.h
+++ b/android/utils/refset.h
@@ -12,8 +12,11 @@
#ifndef _ANDROID_UTILS_REFSET_H
#define _ANDROID_UTILS_REFSET_H
+#include "android/utils/compiler.h"
#include <android/utils/vector.h>
+ANDROID_BEGIN_HEADER
+
/* this implements a set of addresses in memory.
* NULL cannot be stored in the set.
*/
@@ -73,4 +76,6 @@
_arefSet_removeDeferred(_set); \
} while (0)
+ANDROID_END_HEADER
+
#endif /* _ANDROID_UTILS_REFSET_H */
diff --git a/android/utils/stralloc.h b/android/utils/stralloc.h
index 626a638..76558b6 100644
--- a/android/utils/stralloc.h
+++ b/android/utils/stralloc.h
@@ -16,6 +16,10 @@
#include <stddef.h>
#include <stdarg.h>
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/** DYNAMIC STRINGS
**/
@@ -62,4 +66,6 @@
extern char* stralloc_to_tempstr( stralloc_t* s );
+ANDROID_BEGIN_HEADER
+
#endif /* ANDROID_UTILS_STRALLOC_H */
diff --git a/android/utils/system.h b/android/utils/system.h
index a6b84d1..94c1581 100644
--- a/android/utils/system.h
+++ b/android/utils/system.h
@@ -14,7 +14,9 @@
#include <string.h>
#include <stdint.h>
+#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS 1
+#endif
#include <inttypes.h> /* for PRId64 et al. */
#include "android/utils/assert.h"
#include "android/utils/compiler.h"
diff --git a/android/utils/tempfile.h b/android/utils/tempfile.h
index 4264a84..150a15f 100644
--- a/android/utils/tempfile.h
+++ b/android/utils/tempfile.h
@@ -13,6 +13,10 @@
#ifndef _ANDROID_UTILS_TEMPFILE_H
#define _ANDROID_UTILS_TEMPFILE_H
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/** TEMP FILE SUPPORT
**
** simple interface to create an empty temporary file on the system.
@@ -49,4 +53,6 @@
extern void atexit_close_fd(int fd);
extern void atexit_close_fd_remove(int fd);
+ANDROID_END_HEADER
+
#endif /* _ANDROID_UTILS_TEMPFILE_H */
diff --git a/android/utils/timezone.h b/android/utils/timezone.h
index bf5f731..a1e95a2 100644
--- a/android/utils/timezone.h
+++ b/android/utils/timezone.h
@@ -12,6 +12,10 @@
#ifndef _ANDROID_UTILS_TIMEZONE_H
#define _ANDROID_UTILS_TIMEZONE_H
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
+
/* try to set the default host timezone, returns 0 on success, or -1 if
* 'tzname' is not in zoneinfo format (e.g. Area/Location)
*/
@@ -28,4 +32,6 @@
*/
extern char* bufprint_zoneinfo_timezone( char* buffer, char* end );
+ANDROID_END_HEADER
+
#endif /* _ANDROID_UTILS_TIMEZONE_H */
diff --git a/android/utils/vector.h b/android/utils/vector.h
index c576ec7..f77628e 100644
--- a/android/utils/vector.h
+++ b/android/utils/vector.h
@@ -12,8 +12,11 @@
#ifndef _ANDROID_UTILS_VECTOR_H
#define _ANDROID_UTILS_VECTOR_H
-#include "android/utils/system.h"
#include "android/utils/assert.h"
+#include "android/utils/compiler.h"
+#include "android/utils/system.h"
+
+ANDROID_BEGIN_HEADER
#define AVECTOR_DECL(ctype,name) \
ctype* name; \
@@ -80,6 +83,6 @@
} \
} while (0);
-/* */
+ANDROID_END_HEADER
#endif /* _ANDROID_UTILS_VECTOR_H */
diff --git a/android/utils/win32_cmdline_quote.h b/android/utils/win32_cmdline_quote.h
index 86d2384..0ae8bd3 100644
--- a/android/utils/win32_cmdline_quote.h
+++ b/android/utils/win32_cmdline_quote.h
@@ -12,9 +12,9 @@
#ifndef ANDROID_UTILS_WIN32_CMDLINE_QUOTE_H
#define ANDROID_UTILS_WIN32_CMDLINE_QUOTE_H
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "android/utils/compiler.h"
+
+ANDROID_BEGIN_HEADER
// Quote a given command-line command or parameter so that it can be
// sent to _execv() on Windows, and be received properly by the new
@@ -36,8 +36,6 @@
// must free the string with android_free() or AFREE().
char* win32_cmdline_quote(const char* param);
-#ifdef __cplusplus
-}
-#endif
+ANDROID_END_HEADER
#endif // ANDROID_UTILS_WIN32_CMDLINE_QUOTE_H
diff --git a/distrib/package-release.sh b/distrib/package-release.sh
index 03bc48a..a92f918 100755
--- a/distrib/package-release.sh
+++ b/distrib/package-release.sh
@@ -76,6 +76,26 @@
esac
}
+# Return the value of a given named variable.
+# $1: Variable name.
+# Out: Variable value as single string
+var_value () {
+ eval printf %s \"\$$1\"
+}
+
+# Assign a named variable to a specific value.
+# $1: Variable name
+# $2+: Variable value
+var_assign () {
+ local __var_assign_name=$1
+ local __var_assign_value
+ shift
+ # Escape any single quote in the value.
+ __var_assign_value=$(printf "%s" "$*" | sed -e "s/'/\\'/g")
+ # Assign the value to the variable.
+ eval $__var_assign_name=\'"$__var_assign_value"\'
+}
+
# $1: Source directory.
# $2: Destination directory.
# $3: List of files to copy, relative to $1 (if empty, all files will be copied).
@@ -162,11 +182,12 @@
VARNAME=$1
GIT_DIR=$2
# Extract the commit description, then escape (') characters in it.
- SHA1=$(cd $GIT_DIR && git log --oneline -1 .) || \
+ SHA1=$(cd $GIT_DIR && git log --oneline --no-merges -1 .) || \
panic "Not a Git directory: $GIT_DIR"
- SHA1=$(printf "%s" "$SHA1" | sed -e "s/'/\\'/g")
- eval $VARNAME=\'$SHA1\'
+ var_assign ${VARNAME}__TEXT "$SHA1"
+ SHA1=$(echo "$SHA1" | awk '{ print $1; }')
+ var_assign ${VARNAME} $SHA1
}
# Defaults.
@@ -327,6 +348,7 @@
SYSTEMS="$SYSTEMS darwin"
fi
+TARGET_AOSP=
if [ "$OPT_COPY_PREBUILTS" ]; then
if [ -z "$DARWIN_SSH" ]; then
panic "The --copy-prebuilts=<dir> option requires --darwin-ssh=<host>."
@@ -336,7 +358,15 @@
panic "Not an AOSP checkout / workspace: $TARGET_AOSP"
fi
TARGET_PREBUILTS_DIR=$TARGET_AOSP/prebuilts/android-emulator
+ log "Using AOSP prebuilts directory: $TARGET_PREBUILTS_DIR"
mkdir -p "$TARGET_PREBUILTS_DIR"
+elif [ -f "$PROGDIR/../../../build/envsetup.sh" ]; then
+ TARGET_AOSP=$(cd $PROGDIR/../../.. && pwd -P)
+ log "Found AOSP checkout directory: $TARGET_AOSP"
+ TARGET_PREBUILTS_DIR=$TARGET_AOSP/prebuilts/android-emulator
+ if [ ! -d "$TARGET_PREBUILTS_DIR" ]; then
+ TARGET_PREBUILTS_DIR=
+ fi
fi
case $VERBOSE in
@@ -389,33 +419,66 @@
exit 1
fi
-extract_git_commit_description QEMU_GIT_COMMIT "$QEMU_DIR"
-GTEST_DIR=$(dirname $QEMU_DIR)/gtest
-if [ ! -d "$GTEST_DIR" ]; then
- panic "Cannot find GoogleTest source directory: $GTEST_DIR"
-fi
-log "Found GoogleTest directory: $GTEST_DIR"
-extract_git_commit_description GTEST_GIT_COMMIT "$GTEST_DIR"
+get_aosp_subdir_varname () {
+ local __aosp_subdir="$1"
+ echo "AOSP_COMMIT_$(printf "%s" "$__aosp_subdir" | tr '/' '_')"
+}
-EMUGL_DIR=$QEMU_DIR/../../sdk/emulator/opengl
-if [ ! -d "$EMUGL_DIR" ]; then
- panic "Cannot find GPU emulation source directory: $EMUGL_DIR"
-fi
-log "Found GPU emulation directory: $EMUGL_DIR"
-extract_git_commit_description EMUGL_GIT_COMMIT "$EMUGL_DIR"
+get_aosp_subdir_commit () {
+ var_value $(get_aosp_subdir_varname $1)
+}
+
+get_aosp_subdir_commit_description () {
+ var_value $(get_aosp_subdir_varname $1)__TEXT
+}
+
+# $1: Variable name
+# $2: Path to README file
+# $3: AOSP source sub-directory (e.g. external/qemu)
+extract_previous_git_commit_from_readme () {
+ local SHA1
+ SHA1=$(awk '$1 == "'$3'" { print $2; }' "$2")
+ var_assign $1 "$SHA1"
+}
+
+# $1: AOSP sub-directory.
+extract_subdir_git_history () {
+ local VARNAME="$(get_aosp_subdir_varname $1)"
+ local SUBDIR="$TARGET_AOSP/$1"
+ if [ ! -d "$SUBDIR" ]; then
+ panic "Missing required source directory: $SUBDIR"
+ fi
+ log "Found source directory: $SUBDIR"
+ extract_git_commit_description $VARNAME "$SUBDIR"
+ log "Found current $1 commit: $(var_value $VARNAME)"
+ # If there is an old prebuilts directory somewhere, read
+ # the old README file to extract the previous commits there.
+ if [ "$TARGET_PREBUILTS_DIR" ]; then
+ README_FILE=$TARGET_PREBUILTS_DIR/README
+ if [ -f "$README_FILE" ]; then
+ extract_previous_git_commit_from_readme \
+ PREV_$VARNAME "$README_FILE" "$1"
+ log "Found previous $1 commit: $(var_value PREV_$VARNAME)"
+ fi
+ fi
+}
+
+# The list of AOSP directories that contain relevant sources for this
+# script.
+AOSP_SOURCE_SUBDIRS="external/qemu sdk/emulator/opengl external/gtest"
+
+for AOSP_SUBDIR in $AOSP_SOURCE_SUBDIRS; do
+ extract_subdir_git_history $AOSP_SUBDIR
+done
SOURCES_PKG_FILE=
if [ "$OPT_SOURCES" ]; then
BUILD_DIR=$TEMP_BUILD_DIR/sources/$PKG_PREFIX-$PKG_REVISION
PKG_NAME="$PKG_REVISION-sources"
- dump "[$PKG_NAME] Copying GoogleTest source files."
- copy_directory_git_files "$GTEST_DIR" "$BUILD_DIR"/gtest
-
- dump "[$PKG_NAME] Copying Emulator source files."
- copy_directory_git_files "$QEMU_DIR" "$BUILD_DIR"/qemu
-
- dump "[$PKG_NAME] Copying GPU emulation library sources."
- copy_directory_git_files "$EMUGL_DIR" "$BUILD_DIR"/opengl
+ for AOSP_SUBDIR in $AOSP_SOURCE_SUBDIRS; do
+ dump "[$PKG_NAME] Copying $AOSP_SUBDIR source files."
+ copy_directory_git_files "$TARGET_AOSP/$AOSP_SUBDIR" "$BUILD_DIR"/$(basename $AOSP_SUBDIR)
+ done
dump "[$PKG_NAME] Generating README file."
cat > "$BUILD_DIR"/README <<EOF
@@ -428,16 +491,13 @@
#!/bin/sh
# Auto-generated script used to rebuild the Android emulator binaries
-# from sources. Note that this does not include the GLES emulation
-# libraries.
+# from sources.
cd \$(dirname "\$0") &&
(cd qemu && ./android-rebuild.sh --ignore-audio) &&
mkdir -p bin/ &&
cp -rfp qemu/objs/emulator* bin/ &&
echo "Emulator binaries are under \$(pwd -P)/bin/"
-echo "IMPORTANT: The GLES emulation libraries must be copied to:"
-echo " \$(pwd -P)/bin/lib"
EOF
chmod +x "$BUILD_DIR"/rebuild.sh
@@ -524,13 +584,19 @@
for ARCH in arm x86 mips; do
FILES="$FILES emulator64-$ARCH"
done
+ for ARCH in x86_64 arm64; do
+ if [ -f "$SRC_DIR/tools/emulator64-$ARCH" ]; then
+ FILES="$FILES emulator64-$ARCH"
+ fi
+ done
for LIB in OpenglRender EGL_translator GLES_CM_translator GLES_V2_translator; do
FILES="$FILES lib/lib64$LIB$DLLEXT"
done
- (run cd "$SRC_DIR/tools" && tar cf - $FILES) | (cd $DST_DIR && tar xf -) ||
+ (cd "$SRC_DIR/tools" && tar cf - $FILES) | (cd $DST_DIR && tar xf -) ||
panic "Could not copy binaries to $DST_DIR"
done
- cat > $TARGET_PREBUILTS_DIR/README <<EOF
+ README_FILE=$TARGET_PREBUILTS_DIR/README
+ cat > $README_FILE <<EOF
This directory contains prebuilt emulator binaries that were generated by
running the following command on a 64-bit Linux machine:
@@ -543,11 +609,33 @@
Below is the list of specific commits for each input directory used:
-external/gtest $GTEST_GIT_COMMIT
-external/qemu $QEMU_GIT_COMMIT
-sdk/emulator/opengl $EMUGL_GIT_COMMIT
+EOF
+ for AOSP_SUBDIR in $AOSP_SOURCE_SUBDIRS; do
+ printf "%-20s %s\n" "$AOSP_SUBDIR" "$(get_aosp_subdir_commit_description $AOSP_SUBDIR)" >> $README_FILE
+ done
+
+ cat >> $README_FILE <<EOF
+
+Summary of changes:
EOF
+ for AOSP_SUBDIR in $AOSP_SOURCE_SUBDIRS; do
+ VARNAME=$(get_aosp_subdir_varname $AOSP_SUBDIR)
+ CUR_SHA1=$(var_value $VARNAME)
+ PREV_SHA1=$(var_value PREV_$VARNAME)
+ if [ "$CUR_SHA1" != "$PREV_SHA1" ]; then
+ GIT_LOG_COMMAND="cd $AOSP_SUBDIR && git log --oneline --no-merges $PREV_SHA1..$CUR_SHA1"
+ printf " $ %s\n" "$GIT_LOG_COMMAND" >> $README_FILE
+ (cd $TARGET_AOSP && eval $GIT_LOG_COMMAND) | while read LINE; do
+ printf " %s\n" "$LINE" >> $README_FILE
+ done
+ printf "\n" >> $README_FILE
+ else
+ cat >> $README_FILE <<EOF
+ # No changes to $AOSP_SUBDIR
+EOF
+ fi
+ done
fi
dump "Done. See $PKG_DIR"
diff --git a/net/net-android.c b/net/net-android.c
index f12e865..23db2f2 100644
--- a/net/net-android.c
+++ b/net/net-android.c
@@ -135,31 +135,6 @@
static VLANState *first_vlan;
-/* see http://en.wikipedia.org/wiki/List_of_device_bandwidths or a complete list */
-const NetworkSpeed android_netspeeds[] = {
- { "gsm", "GSM/CSD", 14400, 14400 },
- { "hscsd", "HSCSD", 14400, 43200 },
- { "gprs", "GPRS", 40000, 80000 },
- { "edge", "EDGE/EGPRS", 118400, 236800 },
- { "umts", "UMTS/3G", 128000, 1920000 },
- { "hsdpa", "HSDPA", 348000, 14400000 },
- { "full", "no limit", 0, 0 },
- { NULL, NULL, 0, 0 }
-};
-const size_t android_netspeeds_count =
- sizeof(android_netspeeds) / sizeof(android_netspeeds[0]);
-
-const NetworkLatency android_netdelays[] = {
- /* FIXME: these numbers are totally imaginary */
- { "gprs", "GPRS", 150, 550 },
- { "edge", "EDGE/EGPRS", 80, 400 },
- { "umts", "UMTS/3G", 35, 200 },
- { "none", "no latency", 0, 0 },
- { NULL, NULL, 0, 0 }
-};
-const size_t android_netdelays_count =
- sizeof(android_netdelays) / sizeof(android_netdelays[0]);
-
/***********************************************************/
/* network device redirectors */
diff --git a/ui/keymaps.c b/ui/keymaps.c
index feb360f..bab4b29 100644
--- a/ui/keymaps.c
+++ b/ui/keymaps.c
@@ -67,29 +67,16 @@
/* This file is used by both, UI and core components. There are differences
* in the way how keymap file path is obtained for these two different
* configurations. */
-#if defined(CONFIG_STANDALONE_UI)
- char filename[2048];
-#else
char * filename;
-#endif // CONFIG_STANDALONE_UI
char line[1024];
int len;
-#if defined(CONFIG_STANDALONE_UI)
- if (android_core_qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language,
- filename, sizeof(filename))) {
- fprintf(stderr,
- "Could not read keymap file: '%s'\n", language);
- return NULL;
- }
-#else
filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language);
if (!filename) {
fprintf(stderr,
"Could not read keymap file: '%s'\n", language);
return NULL;
}
-#endif // CONFIG_STANDALONE_UI
if (!k)
k = g_malloc0(sizeof(kbd_layout_t));
@@ -98,9 +85,6 @@
"Could not read keymap file: '%s'\n", language);
return NULL;
}
-#if defined(CONFIG_STANDALONE_UI)
- g_free(filename);
-#endif // CONFIG_STANDALONE_UI
for(;;) {
if (fgets(line, 1024, f) == NULL)
break;