diff options
57 files changed, 776 insertions, 289 deletions
diff --git a/cmds/atrace/Android.mk b/cmds/atrace/Android.mk index 028ca8f35a..a787e95942 100644 --- a/cmds/atrace/Android.mk +++ b/cmds/atrace/Android.mk @@ -17,4 +17,6 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libz \ +LOCAL_INIT_RC := atrace.rc + include $(BUILD_EXECUTABLE) diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp index 26c5b4ac35..d63019b683 100644 --- a/cmds/atrace/atrace.cpp +++ b/cmds/atrace/atrace.cpp @@ -36,6 +36,7 @@ #include <utils/String8.h> #include <utils/Timers.h> +#include <utils/Tokenizer.h> #include <utils/Trace.h> using namespace android; @@ -90,6 +91,8 @@ static const TracingCategory k_categories[] = { { "rs", "RenderScript", ATRACE_TAG_RS, { } }, { "bionic", "Bionic C Library", ATRACE_TAG_BIONIC, { } }, { "power", "Power Management", ATRACE_TAG_POWER, { } }, + { "pm", "Package Manager", ATRACE_TAG_PACKAGE_MANAGER, { } }, + { "ss", "System Server", ATRACE_TAG_SYSTEM_SERVER, { } }, { "sched", "CPU Scheduling", 0, { { REQ, "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" }, { REQ, "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" }, @@ -140,6 +143,15 @@ static const TracingCategory k_categories[] = { { "regulators", "Voltage and Current Regulators", 0, { { REQ, "/sys/kernel/debug/tracing/events/regulator/enable" }, } }, + { "binder_driver", "Binder Kernel driver", 0, { + { REQ, "/sys/kernel/debug/tracing/events/binder/binder_transaction/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/binder/binder_transaction_received/enable" }, + } }, + { "binder_lock", "Binder global lock trace", 0, { + { REQ, "/sys/kernel/debug/tracing/events/binder/binder_lock/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/binder/binder_locked/enable" }, + { REQ, "/sys/kernel/debug/tracing/events/binder/binder_unlock/enable" }, + } }, }; /* Command line options */ @@ -149,6 +161,7 @@ static int g_traceBufferSizeKB = 2048; static bool g_compress = false; static bool g_nohup = false; static int g_initialSleepSecs = 0; +static const char* g_categoriesFile = NULL; static const char* g_kernelTraceFuncs = NULL; static const char* g_debugAppCmdLine = ""; @@ -584,6 +597,52 @@ static bool setKernelTraceFuncs(const char* funcs) return ok; } +static bool setCategoryEnable(const char* name, bool enable) +{ + for (int i = 0; i < NELEM(k_categories); i++) { + const TracingCategory& c = k_categories[i]; + if (strcmp(name, c.name) == 0) { + if (isCategorySupported(c)) { + g_categoryEnables[i] = enable; + return true; + } else { + if (isCategorySupportedForRoot(c)) { + fprintf(stderr, "error: category \"%s\" requires root " + "privileges.\n", name); + } else { + fprintf(stderr, "error: category \"%s\" is not supported " + "on this device.\n", name); + } + return false; + } + } + } + fprintf(stderr, "error: unknown tracing category \"%s\"\n", name); + return false; +} + +static bool setCategoriesEnableFromFile(const char* categories_file) +{ + if (!categories_file) { + return true; + } + Tokenizer* tokenizer = NULL; + if (Tokenizer::open(String8(categories_file), &tokenizer) != NO_ERROR) { + return false; + } + bool ok = true; + while (!tokenizer->isEol()) { + String8 token = tokenizer->nextToken(" "); + if (token.isEmpty()) { + tokenizer->skipDelimiters(" "); + continue; + } + ok &= setCategoryEnable(token.string(), true); + } + delete tokenizer; + return ok; +} + // Set all the kernel tracing settings to the desired state for this trace // capture. static bool setUpTrace() @@ -591,6 +650,7 @@ static bool setUpTrace() bool ok = true; // Set up the tracing options. + ok &= setCategoriesEnableFromFile(g_categoriesFile); ok &= setTraceOverwriteEnable(g_traceOverwrite); ok &= setTraceBufferSizeKB(g_traceBufferSizeKB); ok &= setGlobalClockEnable(true); @@ -783,30 +843,6 @@ static void registerSigHandler() sigaction(SIGTERM, &sa, NULL); } -static bool setCategoryEnable(const char* name, bool enable) -{ - for (int i = 0; i < NELEM(k_categories); i++) { - const TracingCategory& c = k_categories[i]; - if (strcmp(name, c.name) == 0) { - if (isCategorySupported(c)) { - g_categoryEnables[i] = enable; - return true; - } else { - if (isCategorySupportedForRoot(c)) { - fprintf(stderr, "error: category \"%s\" requires root " - "privileges.\n", name); - } else { - fprintf(stderr, "error: category \"%s\" is not supported " - "on this device.\n", name); - } - return false; - } - } - } - fprintf(stderr, "error: unknown tracing category \"%s\"\n", name); - return false; -} - static void listSupportedCategories() { for (int i = 0; i < NELEM(k_categories); i++) { @@ -826,6 +862,8 @@ static void showHelp(const char *cmd) "separated list of cmdlines\n" " -b N use a trace buffer size of N KB\n" " -c trace into a circular buffer\n" + " -f filename use the categories written in a file as space-separated\n" + " values in a line\n" " -k fname,... trace the listed kernel functions\n" " -n ignore signals\n" " -s N sleep for N seconds before tracing [default 0]\n" @@ -863,7 +901,7 @@ int main(int argc, char **argv) { 0, 0, 0, 0 } }; - ret = getopt_long(argc, argv, "a:b:ck:ns:t:z", + ret = getopt_long(argc, argv, "a:b:cf:k:ns:t:z", long_options, &option_index); if (ret < 0) { @@ -889,6 +927,10 @@ int main(int argc, char **argv) g_traceOverwrite = true; break; + case 'f': + g_categoriesFile = optarg; + break; + case 'k': g_kernelTraceFuncs = optarg; break; diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc new file mode 100644 index 0000000000..cde9c37a9a --- /dev/null +++ b/cmds/atrace/atrace.rc @@ -0,0 +1,62 @@ +## Permissions to allow system-wide tracing to the kernel trace buffer. +## +on boot + +# Allow writing to the kernel trace log. + chmod 0222 /sys/kernel/debug/tracing/trace_marker + +# Allow the shell group to enable (some) kernel tracing. + chown root shell /sys/kernel/debug/tracing/trace_clock + chown root shell /sys/kernel/debug/tracing/buffer_size_kb + chown root shell /sys/kernel/debug/tracing/options/overwrite + chown root shell /sys/kernel/debug/tracing/options/print-tgid + chown root shell /sys/kernel/debug/tracing/events/sched/sched_switch/enable + chown root shell /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable + chown root shell /sys/kernel/debug/tracing/events/power/cpu_frequency/enable + chown root shell /sys/kernel/debug/tracing/events/power/cpu_idle/enable + chown root shell /sys/kernel/debug/tracing/events/power/clock_set_rate/enable + chown root shell /sys/kernel/debug/tracing/events/cpufreq_interactive/enable + chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin/enable + chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_end/enable + chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_wake/enable + chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_sleep/enable + chown root shell /sys/kernel/debug/tracing/events/binder/binder_transaction/enable + chown root shell /sys/kernel/debug/tracing/events/binder/binder_transaction_received/enable + chown root shell /sys/kernel/debug/tracing/events/binder/binder_lock/enable + chown root shell /sys/kernel/debug/tracing/events/binder/binder_locked/enable + chown root shell /sys/kernel/debug/tracing/events/binder/binder_unlock/enable + + chown root shell /sys/kernel/debug/tracing/tracing_on + + chmod 0664 /sys/kernel/debug/tracing/trace_clock + chmod 0664 /sys/kernel/debug/tracing/buffer_size_kb + chmod 0664 /sys/kernel/debug/tracing/options/overwrite + chmod 0664 /sys/kernel/debug/tracing/options/print-tgid + chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_switch/enable + chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable + chmod 0664 /sys/kernel/debug/tracing/events/power/cpu_frequency/enable + chmod 0664 /sys/kernel/debug/tracing/events/power/cpu_idle/enable + chmod 0664 /sys/kernel/debug/tracing/events/power/clock_set_rate/enable + chmod 0664 /sys/kernel/debug/tracing/events/cpufreq_interactive/enable + chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin/enable + chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_end/enable + chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_wake/enable + chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_sleep/enable + chmod 0664 /sys/kernel/debug/tracing/tracing_on + chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_transaction/enable + chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_transaction_received/enable + chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_lock/enable + chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_locked/enable + chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_unlock/enable + +# Allow only the shell group to read and truncate the kernel trace. + chown root shell /sys/kernel/debug/tracing/trace + chmod 0660 /sys/kernel/debug/tracing/trace + +on property:persist.debug.atrace.boottrace=1 + start boottrace + +# Run atrace with the categories written in a file +service boottrace /system/bin/atrace --async_start -f /data/misc/boottrace/categories + disabled + oneshot diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk index 9065ee1d2c..8c7c4a840e 100644 --- a/cmds/dumpstate/Android.mk +++ b/cmds/dumpstate/Android.mk @@ -17,5 +17,6 @@ LOCAL_MODULE := dumpstate LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux LOCAL_HAL_STATIC_LIBRARIES := libdumpstate LOCAL_CFLAGS += -Wall -Wno-unused-parameter -std=gnu99 +LOCAL_INIT_RC := dumpstate.rc include $(BUILD_EXECUTABLE) diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index 713634c4db..1da7308961 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -300,7 +300,7 @@ static void dumpstate() { dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd); dump_file("MEMORY INFO", "/proc/meminfo"); run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL); - run_command("PROCRANK", 20, "procrank", NULL); + run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL); dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat"); dump_file("VMALLOC INFO", "/proc/vmallocinfo"); dump_file("SLAB INFO", "/proc/slabinfo"); @@ -337,17 +337,28 @@ static void dumpstate() { if (timeout < 20000) { timeout = 20000; } - run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", "-d", "*:v", NULL); + run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", + "-v", "printable", + "-d", + "*:v", NULL); timeout = logcat_timeout("events"); if (timeout < 20000) { timeout = 20000; } - run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL); + run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", + "-v", "threadtime", + "-v", "printable", + "-d", + "*:v", NULL); timeout = logcat_timeout("radio"); if (timeout < 20000) { timeout = 20000; } - run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL); + run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", + "-v", "threadtime", + "-v", "printable", + "-d", + "*:v", NULL); run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); @@ -419,8 +430,12 @@ static void dumpstate() { } /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ - run_command("LAST LOGCAT", 10, "logcat", "-L", "-v", "threadtime", - "-b", "all", "-d", "*:v", NULL); + run_command("LAST LOGCAT", 10, "logcat", "-L", + "-b", "all", + "-v", "threadtime", + "-v", "printable", + "-d", + "*:v", NULL); /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */ diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc new file mode 100644 index 0000000000..cd5d6c4d53 --- /dev/null +++ b/cmds/dumpstate/dumpstate.rc @@ -0,0 +1,5 @@ +service dumpstate /system/bin/dumpstate -s + class main + socket dumpstate stream 0660 shell log + disabled + oneshot diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c index d679787966..0dd0c21a9f 100644 --- a/cmds/dumpstate/utils.c +++ b/cmds/dumpstate/utils.c @@ -626,24 +626,6 @@ const char *dump_traces() { return NULL; // Can't rename old traces.txt -- no permission? -- leave it alone instead } - /* make the directory if necessary */ - char anr_traces_dir[PATH_MAX]; - strlcpy(anr_traces_dir, traces_path, sizeof(anr_traces_dir)); - char *slash = strrchr(anr_traces_dir, '/'); - if (slash != NULL) { - *slash = '\0'; - if (!mkdir(anr_traces_dir, 0775)) { - chown(anr_traces_dir, AID_SYSTEM, AID_SYSTEM); - chmod(anr_traces_dir, 0775); - if (selinux_android_restorecon(anr_traces_dir, 0) == -1) { - fprintf(stderr, "restorecon failed for %s: %s\n", anr_traces_dir, strerror(errno)); - } - } else if (errno != EEXIST) { - fprintf(stderr, "mkdir(%s): %s\n", anr_traces_dir, strerror(errno)); - return NULL; - } - } - /* create a new, empty traces.txt file to receive stack dumps */ int fd = TEMP_FAILURE_RETRY(open(traces_path, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW | O_CLOEXEC, 0666)); /* -rw-rw-rw- */ diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk index 6dec7f6895..eaeeb2226e 100644 --- a/cmds/installd/Android.mk +++ b/cmds/installd/Android.mk @@ -38,5 +38,6 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := libdiskusage LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk +LOCAL_INIT_RC := installd.rc LOCAL_CLANG := true include $(BUILD_EXECUTABLE) diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp index c05a3d3cb5..46d72fd0fc 100644 --- a/cmds/installd/commands.cpp +++ b/cmds/installd/commands.cpp @@ -746,7 +746,7 @@ static bool check_boolean_property(const char* property_name, bool default_value static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, const char* output_file_name, int swap_fd, const char *pkgname, const char *instruction_set, - bool vm_safe_mode, bool debuggable, bool post_bootcomplete) + bool vm_safe_mode, bool debuggable, bool post_bootcomplete, bool use_jit) { static const unsigned int MAX_INSTRUCTION_SET_LEN = 7; @@ -807,7 +807,6 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, (strcmp(vold_decrypt, "trigger_restart_min_framework") == 0 || (strcmp(vold_decrypt, "1") == 0))); - bool use_jit = check_boolean_property("debug.usejit"); bool generate_debug_info = check_boolean_property("debug.generate-debug-info"); static const char* DEX2OAT_BIN = "/system/bin/dex2oat"; @@ -861,6 +860,8 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, } } + // use the JIT if either it's specified as a dexopt flag or if the property is set + use_jit = use_jit || check_boolean_property("debug.usejit"); if (have_dex2oat_Xms_flag) { sprintf(dex2oat_Xms_arg, "-Xms%s", dex2oat_Xms_flag); } @@ -1081,9 +1082,8 @@ static void SetDex2OatAndPatchOatScheduling(bool set_to_bg) { } } -int dexopt(const char *apk_path, uid_t uid, bool is_public, - const char *pkgname, const char *instruction_set, int dexopt_needed, - bool vm_safe_mode, bool debuggable, const char* oat_dir, bool boot_complete) +int dexopt(const char *apk_path, uid_t uid, const char *pkgname, const char *instruction_set, + int dexopt_needed, const char* oat_dir, int dexopt_flags) { struct utimbuf ut; struct stat input_stat; @@ -1092,6 +1092,15 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *input_file; char in_odex_path[PKG_PATH_MAX]; int res, input_fd=-1, out_fd=-1, swap_fd=-1; + bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0; + bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0; + bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0; + bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0; + bool use_jit = (dexopt_flags & DEXOPT_USEJIT) != 0; + + if ((dexopt_flags & DEXOPT_MASK) != 0) { + LOG_FATAL("dexopt flags contains unknown fields\n"); + } // Early best-effort check whether we can fit the the path into our buffers. // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run @@ -1231,7 +1240,7 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, input_file_name++; } run_dex2oat(input_fd, out_fd, input_file_name, out_path, swap_fd, pkgname, - instruction_set, vm_safe_mode, debuggable, boot_complete); + instruction_set, vm_safe_mode, debuggable, boot_complete, use_jit); } else { ALOGE("Invalid dexopt needed: %d\n", dexopt_needed); exit(73); diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp index f67e8384d2..7a161504ec 100644 --- a/cmds/installd/installd.cpp +++ b/cmds/installd/installd.cpp @@ -47,10 +47,9 @@ static int do_install(char **arg, char reply[REPLY_MAX] __unused) static int do_dexopt(char **arg, char reply[REPLY_MAX] __unused) { - /* apk_path, uid, is_public, pkgname, instruction_set, - * dexopt_needed, vm_safe_mode, debuggable, oat_dir, boot_complete */ - return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], atoi(arg[5]), - atoi(arg[6]), atoi(arg[7]), arg[8], atoi(arg[9])); + /* apk_path, uid, pkgname, instruction_set, dexopt_needed, oat_dir, dexopt_flags */ + return dexopt(arg[0], atoi(arg[1]), arg[2], arg[3], atoi(arg[4]), + arg[5], atoi(arg[6])); } static int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] __unused) @@ -194,7 +193,7 @@ struct cmdinfo { struct cmdinfo cmds[] = { { "ping", 0, do_ping }, { "install", 5, do_install }, - { "dexopt", 10, do_dexopt }, + { "dexopt", 7, do_dexopt }, { "markbootcomplete", 1, do_mark_boot_complete }, { "movedex", 3, do_move_dex }, { "rmdex", 2, do_rm_dex }, diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index 24b9084656..df13fe4e72 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -90,6 +90,24 @@ #define DEXOPT_PATCHOAT_NEEDED 2 #define DEXOPT_SELF_PATCHOAT_NEEDED 3 +/**************************************************************************** + * IMPORTANT: These values are passed from Java code. Keep them in sync with + * frameworks/base/services/core/java/com/android/server/pm/Installer.java + ***************************************************************************/ +constexpr int DEXOPT_PUBLIC = 1 << 1; +constexpr int DEXOPT_SAFEMODE = 1 << 2; +constexpr int DEXOPT_DEBUGGABLE = 1 << 3; +constexpr int DEXOPT_BOOTCOMPLETE = 1 << 4; +constexpr int DEXOPT_USEJIT = 1 << 5; + +/* all known values for dexopt flags */ +constexpr int DEXOPT_MASK = + DEXOPT_PUBLIC + | DEXOPT_SAFEMODE + | DEXOPT_DEBUGGABLE + | DEXOPT_BOOTCOMPLETE + | DEXOPT_USEJIT; + #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) /* data structures */ @@ -241,9 +259,8 @@ int get_size(const char *uuid, const char *pkgname, int userid, const char *instruction_set, int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize); int free_cache(const char *uuid, int64_t free_size); -int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName, - const char *instruction_set, int dexopt_needed, bool vm_safe_mode, - bool debuggable, const char* oat_dir, bool boot_complete); +int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *instruction_set, + int dexopt_needed, const char* oat_dir, int dexopt_flags); int mark_boot_complete(const char *instruction_set); int movefiles(); int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId); diff --git a/cmds/installd/installd.rc b/cmds/installd/installd.rc new file mode 100644 index 0000000000..5e4c925d2b --- /dev/null +++ b/cmds/installd/installd.rc @@ -0,0 +1,3 @@ +service installd /system/bin/installd + class main + socket installd stream 600 system system diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp index 7db3fb90c9..e58391fb04 100644 --- a/cmds/installd/utils.cpp +++ b/cmds/installd/utils.cpp @@ -256,7 +256,7 @@ static int _delete_dir_contents(DIR *d, if ((name[1] == '.') && (name[2] == 0)) continue; } - subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); + subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); if (subfd < 0) { ALOGE("Couldn't openat %s: %s\n", name, strerror(errno)); result = -1; @@ -316,7 +316,7 @@ int delete_dir_contents_fd(int dfd, const char *name) int fd, res; DIR *d; - fd = openat(dfd, name, O_RDONLY | O_DIRECTORY); + fd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); if (fd < 0) { ALOGE("Couldn't openat %s: %s\n", name, strerror(errno)); return -1; @@ -656,7 +656,7 @@ static int _add_cache_files(cache_t *cache, cache_dir_t *parentDir, const char * if ((name[1] == '.') && (name[2] == 0)) continue; } - subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); + subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); if (subfd < 0) { ALOGE("Couldn't openat %s: %s\n", name, strerror(errno)); continue; diff --git a/cmds/servicemanager/Android.mk b/cmds/servicemanager/Android.mk index 155cfc503e..7ee0dd184e 100644 --- a/cmds/servicemanager/Android.mk +++ b/cmds/servicemanager/Android.mk @@ -22,4 +22,5 @@ LOCAL_SHARED_LIBRARIES := liblog libselinux LOCAL_SRC_FILES := service_manager.c binder.c LOCAL_CFLAGS += $(svc_c_flags) LOCAL_MODULE := servicemanager +LOCAL_INIT_RC := servicemanager.rc include $(BUILD_EXECUTABLE) diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c index 7fa9a39f79..8596f962bd 100644 --- a/cmds/servicemanager/service_manager.c +++ b/cmds/servicemanager/service_manager.c @@ -23,6 +23,12 @@ #include <cutils/log.h> #endif +struct audit_data { + pid_t pid; + uid_t uid; + const char *name; +}; + const char *str8(const uint16_t *x, size_t x_len) { static char buf[128]; @@ -56,34 +62,39 @@ static int selinux_enabled; static char *service_manager_context; static struct selabel_handle* sehandle; -static bool check_mac_perms(pid_t spid, const char *tctx, const char *perm, const char *name) +static bool check_mac_perms(pid_t spid, uid_t uid, const char *tctx, const char *perm, const char *name) { char *sctx = NULL; const char *class = "service_manager"; bool allowed; + struct audit_data ad; if (getpidcon(spid, &sctx) < 0) { ALOGE("SELinux: getpidcon(pid=%d) failed to retrieve pid context.\n", spid); return false; } - int result = selinux_check_access(sctx, tctx, class, perm, (void *) name); + ad.pid = spid; + ad.uid = uid; + ad.name = name; + + int result = selinux_check_access(sctx, tctx, class, perm, (void *) &ad); allowed = (result == 0); freecon(sctx); return allowed; } -static bool check_mac_perms_from_getcon(pid_t spid, const char *perm) +static bool check_mac_perms_from_getcon(pid_t spid, uid_t uid, const char *perm) { if (selinux_enabled <= 0) { return true; } - return check_mac_perms(spid, service_manager_context, perm, NULL); + return check_mac_perms(spid, uid, service_manager_context, perm, NULL); } -static bool check_mac_perms_from_lookup(pid_t spid, const char *perm, const char *name) +static bool check_mac_perms_from_lookup(pid_t spid, uid_t uid, const char *perm, const char *name) { bool allowed; char *tctx = NULL; @@ -102,27 +113,27 @@ static bool check_mac_perms_from_lookup(pid_t spid, const char *perm, const char return false; } - allowed = check_mac_perms(spid, tctx, perm, name); + allowed = check_mac_perms(spid, uid, tctx, perm, name); freecon(tctx); return allowed; } -static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid) +static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid) { const char *perm = "add"; - return check_mac_perms_from_lookup(spid, perm, str8(name, name_len)) ? 1 : 0; + return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0; } -static int svc_can_list(pid_t spid) +static int svc_can_list(pid_t spid, uid_t uid) { const char *perm = "list"; - return check_mac_perms_from_getcon(spid, perm) ? 1 : 0; + return check_mac_perms_from_getcon(spid, uid, perm) ? 1 : 0; } -static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid) +static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid) { const char *perm = "find"; - return check_mac_perms_from_lookup(spid, perm, str8(name, name_len)) ? 1 : 0; + return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0; } struct svcinfo @@ -184,7 +195,7 @@ uint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, } } - if (!svc_can_find(s, len, spid)) { + if (!svc_can_find(s, len, spid, uid)) { return 0; } @@ -204,7 +215,7 @@ int do_add_service(struct binder_state *bs, if (!handle || (len == 0) || (len > 127)) return -1; - if (!svc_can_register(s, len, spid)) { + if (!svc_can_register(s, len, spid, uid)) { ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n", str8(s, len), handle, uid); return -1; @@ -314,7 +325,7 @@ int svcmgr_handler(struct binder_state *bs, case SVC_MGR_LIST_SERVICES: { uint32_t n = bio_get_uint32(msg); - if (!svc_can_list(txn->sender_pid)) { + if (!svc_can_list(txn->sender_pid, txn->sender_euid)) { ALOGE("list_service() uid=%d - PERMISSION DENIED\n", txn->sender_euid); return -1; @@ -340,7 +351,14 @@ int svcmgr_handler(struct binder_state *bs, static int audit_callback(void *data, security_class_t cls, char *buf, size_t len) { - snprintf(buf, len, "service=%s", !data ? "NULL" : (char *)data); + struct audit_data *ad = (struct audit_data *)data; + + if (!ad || !ad->name) { + ALOGE("No service manager audit data"); + return 0; + } + + snprintf(buf, len, "service=%s pid=%d uid=%d", ad->name, ad->pid, ad->uid); return 0; } diff --git a/cmds/servicemanager/servicemanager.rc b/cmds/servicemanager/servicemanager.rc new file mode 100644 index 0000000000..e73516dbbd --- /dev/null +++ b/cmds/servicemanager/servicemanager.rc @@ -0,0 +1,10 @@ +service servicemanager /system/bin/servicemanager + class core + user system + group system + critical + onrestart restart healthd + onrestart restart zygote + onrestart restart media + onrestart restart surfaceflinger + onrestart restart drm diff --git a/include/android/sensor.h b/include/android/sensor.h index 73928ea76f..9472ad6eee 100644 --- a/include/android/sensor.h +++ b/include/android/sensor.h @@ -59,7 +59,7 @@ extern "C" { /** * Sensor types. - * (keep in sync with hardware/sensor.h) + * (keep in sync with hardware/sensors.h) */ enum { /** @@ -69,7 +69,7 @@ enum { * All values are in SI units (m/s^2) and measure the acceleration of the * device minus the force of gravity. */ - ASENSOR_TYPE_ACCELEROMETER = 1, + ASENSOR_TYPE_ACCELEROMETER = 1, /** * {@link ASENSOR_TYPE_MAGNETIC_FIELD} * reporting-mode: continuous @@ -77,7 +77,7 @@ enum { * All values are in micro-Tesla (uT) and measure the geomagnetic * field in the X, Y and Z axis. */ - ASENSOR_TYPE_MAGNETIC_FIELD = 2, + ASENSOR_TYPE_MAGNETIC_FIELD = 2, /** * {@link ASENSOR_TYPE_GYROSCOPE} * reporting-mode: continuous @@ -85,14 +85,14 @@ enum { * All values are in radians/second and measure the rate of rotation * around the X, Y and Z axis. */ - ASENSOR_TYPE_GYROSCOPE = 4, + ASENSOR_TYPE_GYROSCOPE = 4, /** * {@link ASENSOR_TYPE_LIGHT} * reporting-mode: on-change * * The light sensor value is returned in SI lux units. */ - ASENSOR_TYPE_LIGHT = 5, + ASENSOR_TYPE_LIGHT = 5, /** * {@link ASENSOR_TYPE_PROXIMITY} * reporting-mode: on-change @@ -103,7 +103,15 @@ enum { * SENSOR_FLAG_WAKE_UP. * The value corresponds to the distance to the nearest object in centimeters. */ - ASENSOR_TYPE_PROXIMITY = 8 + ASENSOR_TYPE_PROXIMITY = 8, + /** + * {@link ASENSOR_TYPE_LINEAR_ACCELERATION} + * reporting-mode: continuous + * + * All values are in SI units (m/s^2) and measure the acceleration of the + * device not including the force of gravity. + */ + ASENSOR_TYPE_LINEAR_ACCELERATION = 10 }; /** diff --git a/include/batteryservice/BatteryService.h b/include/batteryservice/BatteryService.h index f0a2790a93..9a8e2f7017 100644 --- a/include/batteryservice/BatteryService.h +++ b/include/batteryservice/BatteryService.h @@ -64,6 +64,9 @@ struct BatteryProperties { int batteryLevel; int batteryVoltage; int batteryTemperature; + int batteryCurrent; + int batteryCycleCount; + int batteryFullCharge; String8 batteryTechnology; status_t writeToParcel(Parcel* parcel) const; diff --git a/include/binder/Binder.h b/include/binder/Binder.h index 86628a03d3..f849fd4327 100644 --- a/include/binder/Binder.h +++ b/include/binder/Binder.h @@ -17,7 +17,7 @@ #ifndef ANDROID_BINDER_H #define ANDROID_BINDER_H -#include <stdatomic.h> +#include <atomic> #include <stdint.h> #include <binder/IBinder.h> @@ -71,7 +71,7 @@ private: class Extras; - atomic_uintptr_t mExtras; // should be atomic<Extras *> + std::atomic<Extras*> mExtras; void* mReserved0; }; @@ -95,7 +95,7 @@ private: IBinder* const mRemote; RefBase::weakref_type* mRefs; - volatile int32_t mState; + std::atomic<int32_t> mState; }; }; // namespace android diff --git a/include/binder/IServiceManager.h b/include/binder/IServiceManager.h index 2c297d64fb..7ccd9fefd3 100644 --- a/include/binder/IServiceManager.h +++ b/include/binder/IServiceManager.h @@ -81,20 +81,6 @@ bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid); bool checkPermission(const String16& permission, pid_t pid, uid_t uid); - -// ---------------------------------------------------------------------- - -class BnServiceManager : public BnInterface<IServiceManager> -{ -public: - virtual status_t onTransact( uint32_t code, - const Parcel& data, - Parcel* reply, - uint32_t flags = 0); -}; - -// ---------------------------------------------------------------------- - }; // namespace android #endif // ANDROID_ISERVICE_MANAGER_H diff --git a/include/input/Input.h b/include/input/Input.h index 92b3d36955..aca811273f 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -139,7 +139,7 @@ struct AInputDevice { namespace android { -#ifdef HAVE_ANDROID_OS +#ifdef __ANDROID__ class Parcel; #endif @@ -234,7 +234,7 @@ struct PointerCoords { return getAxisValue(AMOTION_EVENT_AXIS_Y); } -#ifdef HAVE_ANDROID_OS +#ifdef __ANDROID__ status_t readFromParcel(Parcel* parcel); status_t writeToParcel(Parcel* parcel) const; #endif @@ -572,7 +572,7 @@ public: // Matrix is in row-major form and compatible with SkMatrix. void transform(const float matrix[9]); -#ifdef HAVE_ANDROID_OS +#ifdef __ANDROID__ status_t readFromParcel(Parcel* parcel); status_t writeToParcel(Parcel* parcel) const; #endif diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index 3f0914b67e..eb5840ebfc 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -19,7 +19,7 @@ #include <stdint.h> -#if HAVE_ANDROID_OS +#ifdef __ANDROID__ #include <binder/IBinder.h> #endif @@ -129,7 +129,7 @@ public: void tryRemapKey(int32_t scanCode, int32_t metaState, int32_t* outKeyCode, int32_t* outMetaState) const; -#if HAVE_ANDROID_OS +#ifdef __ANDROID__ /* Reads a key map from a parcel. */ static sp<KeyCharacterMap> readFromParcel(Parcel* parcel); diff --git a/include/powermanager/IPowerManager.h b/include/powermanager/IPowerManager.h index 91ecc5aa31..461fad7515 100644 --- a/include/powermanager/IPowerManager.h +++ b/include/powermanager/IPowerManager.h @@ -25,12 +25,35 @@ namespace android { // ---------------------------------------------------------------------------- -// must be kept in sync with interface defined in IPowerManager.aidl class IPowerManager : public IInterface { public: + // These transaction IDs must be kept in sync with the method order from + // IPowerManager.aidl. + enum { + ACQUIRE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION, + ACQUIRE_WAKE_LOCK_UID = IBinder::FIRST_CALL_TRANSACTION + 1, + RELEASE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION + 2, + UPDATE_WAKE_LOCK_UIDS = IBinder::FIRST_CALL_TRANSACTION + 3, + POWER_HINT = IBinder::FIRST_CALL_TRANSACTION + 4, + UPDATE_WAKE_LOCK_SOURCE = IBinder::FIRST_CALL_TRANSACTION + 5, + IS_WAKE_LOCK_LEVEL_SUPPORTED = IBinder::FIRST_CALL_TRANSACTION + 6, + USER_ACTIVITY = IBinder::FIRST_CALL_TRANSACTION + 7, + WAKE_UP = IBinder::FIRST_CALL_TRANSACTION + 8, + GO_TO_SLEEP = IBinder::FIRST_CALL_TRANSACTION + 9, + NAP = IBinder::FIRST_CALL_TRANSACTION + 10, + IS_INTERACTIVE = IBinder::FIRST_CALL_TRANSACTION + 11, + IS_POWER_SAVE_MODE = IBinder::FIRST_CALL_TRANSACTION + 12, + SET_POWER_SAVE_MODE = IBinder::FIRST_CALL_TRANSACTION + 13, + REBOOT = IBinder::FIRST_CALL_TRANSACTION + 14, + SHUTDOWN = IBinder::FIRST_CALL_TRANSACTION + 15, + CRASH = IBinder::FIRST_CALL_TRANSACTION + 16, + }; + DECLARE_META_INTERFACE(PowerManager); + // The parcels created by these methods must be kept in sync with the + // corresponding methods from IPowerManager.aidl. // FIXME remove the bool isOneWay parameters as they are not oneway in the .aidl virtual status_t acquireWakeLock(int flags, const sp<IBinder>& lock, const String16& tag, const String16& packageName, bool isOneWay = false) = 0; @@ -39,8 +62,11 @@ public: virtual status_t releaseWakeLock(const sp<IBinder>& lock, int flags, bool isOneWay = false) = 0; virtual status_t updateWakeLockUids(const sp<IBinder>& lock, int len, const int *uids, bool isOneWay = false) = 0; - // oneway in the .aidl virtual status_t powerHint(int hintId, int data) = 0; + virtual status_t goToSleep(int64_t event_time_ms, int reason, int flags) = 0; + virtual status_t reboot(bool confirm, const String16& reason, bool wait) = 0; + virtual status_t shutdown(bool confirm, const String16& reason, bool wait) = 0; + virtual status_t crash(const String16& message) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/ui/Region.h b/include/ui/Region.h index 2a1491837d..810f09860d 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -28,7 +28,6 @@ namespace android { // --------------------------------------------------------------------------- -class SharedBuffer; class String8; // --------------------------------------------------------------------------- @@ -130,11 +129,6 @@ public: // Region object. Rect const* getArray(size_t* count) const; - // returns a SharedBuffer as well as the number of rects. - // ownership is transfered to the caller. - // the caller must call SharedBuffer::release() to free the memory. - SharedBuffer const* getSharedBuffer(size_t* count) const; - /* no user serviceable parts here... */ // add a rectangle to the internal list. This rectangle must diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk index d5860ef6ca..ce29ea6818 100644 --- a/libs/binder/Android.mk +++ b/libs/binder/Android.mk @@ -43,6 +43,9 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libbinder LOCAL_SHARED_LIBRARIES := liblog libcutils libutils + +LOCAL_CLANG := true +LOCAL_SANITIZE := integer LOCAL_SRC_FILES := $(sources) ifneq ($(TARGET_USES_64_BIT_BINDER),true) ifneq ($(TARGET_IS_64_BIT),true) diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp index 9d200fb219..e39093d52e 100644 --- a/libs/binder/Binder.cpp +++ b/libs/binder/Binder.cpp @@ -16,7 +16,7 @@ #include <binder/Binder.h> -#include <stdatomic.h> +#include <atomic> #include <utils/misc.h> #include <binder/BpBinder.h> #include <binder/IInterface.h> @@ -70,9 +70,8 @@ public: // --------------------------------------------------------------------------- -BBinder::BBinder() +BBinder::BBinder() : mExtras(nullptr) { - atomic_init(&mExtras, static_cast<uintptr_t>(0)); } bool BBinder::isBinderAlive() const @@ -139,19 +138,16 @@ void BBinder::attachObject( const void* objectID, void* object, void* cleanupCookie, object_cleanup_func func) { - Extras* e = reinterpret_cast<Extras*>( - atomic_load_explicit(&mExtras, memory_order_acquire)); + Extras* e = mExtras.load(std::memory_order_acquire); if (!e) { e = new Extras; - uintptr_t expected = 0; - if (!atomic_compare_exchange_strong_explicit( - &mExtras, &expected, - reinterpret_cast<uintptr_t>(e), - memory_order_release, - memory_order_acquire)) { + Extras* expected = nullptr; + if (!mExtras.compare_exchange_strong(expected, e, + std::memory_order_release, + std::memory_order_acquire)) { delete e; - e = reinterpret_cast<Extras*>(expected); // Filled in by CAS + e = expected; // Filled in by CAS } if (e == 0) return; // out of memory } @@ -160,18 +156,9 @@ void BBinder::attachObject( e->mObjects.attach(objectID, object, cleanupCookie, func); } -// The C11 standard doesn't allow atomic loads from const fields, -// though C++11 does. Fudge it until standards get straightened out. -static inline uintptr_t load_const_atomic(const atomic_uintptr_t* p, - memory_order mo) { - atomic_uintptr_t* non_const_p = const_cast<atomic_uintptr_t*>(p); - return atomic_load_explicit(non_const_p, mo); -} - void* BBinder::findObject(const void* objectID) const { - Extras* e = reinterpret_cast<Extras*>( - load_const_atomic(&mExtras, memory_order_acquire)); + Extras* e = mExtras.load(std::memory_order_acquire); if (!e) return NULL; AutoMutex _l(e->mLock); @@ -180,8 +167,7 @@ void* BBinder::findObject(const void* objectID) const void BBinder::detachObject(const void* objectID) { - Extras* e = reinterpret_cast<Extras*>( - atomic_load_explicit(&mExtras, memory_order_acquire)); + Extras* e = mExtras.load(std::memory_order_acquire); if (!e) return; AutoMutex _l(e->mLock); @@ -195,8 +181,7 @@ BBinder* BBinder::localBinder() BBinder::~BBinder() { - Extras* e = reinterpret_cast<Extras*>( - atomic_load_explicit(&mExtras, memory_order_relaxed)); + Extras* e = mExtras.load(std::memory_order_relaxed); if (e) delete e; } @@ -252,7 +237,7 @@ BpRefBase::BpRefBase(const sp<IBinder>& o) BpRefBase::~BpRefBase() { if (mRemote) { - if (!(mState&kRemoteAcquired)) { + if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) { mRemote->decStrong(this); } mRefs->decWeak(this); @@ -261,7 +246,7 @@ BpRefBase::~BpRefBase() void BpRefBase::onFirstRef() { - android_atomic_or(kRemoteAcquired, &mState); + mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed); } void BpRefBase::onLastStrongRef(const void* /*id*/) diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index ef88181d6d..a237684783 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -852,7 +852,7 @@ status_t IPCThreadState::talkWithDriver(bool doReceive) IF_LOG_COMMANDS() { alog << "About to read/write, write size = " << mOut.dataSize() << endl; } -#if defined(HAVE_ANDROID_OS) +#if defined(__ANDROID__) if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) err = NO_ERROR; else @@ -1158,7 +1158,7 @@ void IPCThreadState::threadDestructor(void *st) IPCThreadState* const self = static_cast<IPCThreadState*>(st); if (self) { self->flushCommands(); -#if defined(HAVE_ANDROID_OS) +#if defined(__ANDROID__) if (self->mProcess->mDriverFD > 0) { ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0); } diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 3c716df177..134aadc6c9 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -184,48 +184,4 @@ public: IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager"); -// ---------------------------------------------------------------------- - -status_t BnServiceManager::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - //printf("ServiceManager received: "); data.print(); - switch(code) { - case GET_SERVICE_TRANSACTION: { - CHECK_INTERFACE(IServiceManager, data, reply); - String16 which = data.readString16(); - sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which); - reply->writeStrongBinder(b); - return NO_ERROR; - } break; - case CHECK_SERVICE_TRANSACTION: { - CHECK_INTERFACE(IServiceManager, data, reply); - String16 which = data.readString16(); - sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which); - reply->writeStrongBinder(b); - return NO_ERROR; - } break; - case ADD_SERVICE_TRANSACTION: { - CHECK_INTERFACE(IServiceManager, data, reply); - String16 which = data.readString16(); - sp<IBinder> b = data.readStrongBinder(); - status_t err = addService(which, b); - reply->writeInt32(err); - return NO_ERROR; - } break; - case LIST_SERVICES_TRANSACTION: { - CHECK_INTERFACE(IServiceManager, data, reply); - Vector<String16> list = listServices(); - const size_t N = list.size(); - reply->writeInt32(N); - for (size_t i=0; i<N; i++) { - reply->writeString16(list[i]); - } - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - }; // namespace android diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 7a4ddc43a5..45191f5bd9 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -1645,8 +1645,14 @@ void Parcel::freeDataNoInit() if (mData) { LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity); pthread_mutex_lock(&gParcelGlobalAllocSizeLock); - gParcelGlobalAllocSize -= mDataCapacity; - gParcelGlobalAllocCount--; + if (mDataCapacity <= gParcelGlobalAllocSize) { + gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity; + } else { + gParcelGlobalAllocSize = 0; + } + if (gParcelGlobalAllocCount > 0) { + gParcelGlobalAllocCount--; + } pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); free(mData); } @@ -1825,6 +1831,7 @@ status_t Parcel::continueWrite(size_t desired) pthread_mutex_lock(&gParcelGlobalAllocSizeLock); gParcelGlobalAllocSize += desired; gParcelGlobalAllocSize -= mDataCapacity; + gParcelGlobalAllocCount++; pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); mData = data; mDataCapacity = desired; diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index 016d3c54b0..821ab6cb9b 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -350,10 +350,6 @@ ProcessState::ProcessState() , mThreadPoolSeq(1) { if (mDriverFD >= 0) { - // XXX Ideally, there should be a specific define for whether we - // have mmap (or whether we could possibly have the kernel module - // availabla). -#if !defined(HAVE_WIN32_IPC) // mmap the binder, providing a chunk of virtual address space to receive transactions. mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { @@ -362,9 +358,6 @@ ProcessState::ProcessState() close(mDriverFD); mDriverFD = -1; } -#else - mDriverFD = -1; -#endif } LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating."); diff --git a/libs/binder/tests/Android.mk b/libs/binder/tests/Android.mk index 36687296fb..a40523d4b3 100644 --- a/libs/binder/tests/Android.mk +++ b/libs/binder/tests/Android.mk @@ -32,3 +32,11 @@ LOCAL_MODULE := binderLibTest LOCAL_SRC_FILES := binderLibTest.cpp LOCAL_SHARED_LIBRARIES := libbinder libutils include $(BUILD_NATIVE_TEST) + +include $(CLEAR_VARS) +LOCAL_MODULE := binderThroughputTest +LOCAL_SRC_FILES := binderThroughputTest.cpp +LOCAL_SHARED_LIBRARIES := libbinder libutils +LOCAL_CLANG := true +LOCAL_CFLAGS += -g -Wall -Werror -std=c++11 -Wno-missing-field-initializers -Wno-sign-compare -O3 +include $(BUILD_NATIVE_TEST) diff --git a/libs/binder/tests/binderThroughputTest.cpp b/libs/binder/tests/binderThroughputTest.cpp new file mode 100644 index 0000000000..71b96d4947 --- /dev/null +++ b/libs/binder/tests/binderThroughputTest.cpp @@ -0,0 +1,317 @@ +#include <binder/Binder.h> +#include <binder/IBinder.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <string> +#include <cstring> +#include <cstdlib> +#include <cstdio> + +#include <iostream> +#include <vector> +#include <tuple> + +#include <unistd.h> +#include <sys/wait.h> + +using namespace std; +using namespace android; + +enum BinderWorkerServiceCode { + BINDER_NOP = IBinder::FIRST_CALL_TRANSACTION, +}; + +#define ASSERT_TRUE(cond) \ +do { \ + if (!(cond)) {\ + cerr << __func__ << ":" << __LINE__ << " condition:" << #cond << " failed\n" << endl; \ + exit(EXIT_FAILURE); \ + } \ +} while (0) + +class BinderWorkerService : public BBinder +{ +public: + BinderWorkerService() {} + ~BinderWorkerService() {} + virtual status_t onTransact(uint32_t code, + const Parcel& data, Parcel* reply, + uint32_t flags = 0) { + (void)flags; + (void)data; + (void)reply; + switch (code) { + case BINDER_NOP: + return NO_ERROR; + default: + return UNKNOWN_TRANSACTION; + }; + } +}; + +class Pipe { + int m_readFd; + int m_writeFd; + Pipe(int readFd, int writeFd) : m_readFd{readFd}, m_writeFd{writeFd} {} + Pipe(const Pipe &) = delete; + Pipe& operator=(const Pipe &) = delete; + Pipe& operator=(const Pipe &&) = delete; +public: + Pipe(Pipe&& rval) noexcept { + m_readFd = rval.m_readFd; + m_writeFd = rval.m_writeFd; + rval.m_readFd = 0; + rval.m_writeFd = 0; + } + ~Pipe() { + if (m_readFd) + close(m_readFd); + if (m_writeFd) + close(m_writeFd); + } + void signal() { + bool val = true; + int error = write(m_writeFd, &val, sizeof(val)); + ASSERT_TRUE(error >= 0); + }; + void wait() { + bool val = false; + int error = read(m_readFd, &val, sizeof(val)); + ASSERT_TRUE(error >= 0); + } + template <typename T> void send(const T& v) { + int error = write(m_writeFd, &v, sizeof(T)); + ASSERT_TRUE(error >= 0); + } + template <typename T> void recv(T& v) { + int error = read(m_readFd, &v, sizeof(T)); + ASSERT_TRUE(error >= 0); + } + static tuple<Pipe, Pipe> createPipePair() { + int a[2]; + int b[2]; + + int error1 = pipe(a); + int error2 = pipe(b); + ASSERT_TRUE(error1 >= 0); + ASSERT_TRUE(error2 >= 0); + + return make_tuple(Pipe(a[0], b[1]), Pipe(b[0], a[1])); + } +}; + +static const uint32_t num_buckets = 128; +static const uint64_t max_time_bucket = 50ull * 1000000; +static const uint64_t time_per_bucket = max_time_bucket / num_buckets; +static constexpr float time_per_bucket_ms = time_per_bucket / 1.0E6; + +struct ProcResults { + uint64_t m_best = max_time_bucket; + uint64_t m_worst = 0; + uint32_t m_buckets[num_buckets] = {0}; + uint64_t m_transactions = 0; + uint64_t m_total_time = 0; + + void add_time(uint64_t time) { + m_buckets[min(time, max_time_bucket-1) / time_per_bucket] += 1; + m_best = min(time, m_best); + m_worst = max(time, m_worst); + m_transactions += 1; + m_total_time += time; + } + static ProcResults combine(const ProcResults& a, const ProcResults& b) { + ProcResults ret; + for (int i = 0; i < num_buckets; i++) { + ret.m_buckets[i] = a.m_buckets[i] + b.m_buckets[i]; + } + ret.m_worst = max(a.m_worst, b.m_worst); + ret.m_best = min(a.m_best, b.m_best); + ret.m_transactions = a.m_transactions + b.m_transactions; + ret.m_total_time = a.m_total_time + b.m_total_time; + return ret; + } + void dump() { + double best = (double)m_best / 1.0E6; + double worst = (double)m_worst / 1.0E6; + double average = (double)m_total_time / m_transactions / 1.0E6; + cout << "average:" << average << "ms worst:" << worst << "ms best:" << best << "ms" << endl; + + uint64_t cur_total = 0; + for (int i = 0; i < num_buckets; i++) { + float cur_time = time_per_bucket_ms * i + 0.5f * time_per_bucket_ms; + if ((cur_total < 0.5f * m_transactions) && (cur_total + m_buckets[i] >= 0.5f * m_transactions)) { + cout << "50%: " << cur_time << " "; + } + if ((cur_total < 0.9f * m_transactions) && (cur_total + m_buckets[i] >= 0.9f * m_transactions)) { + cout << "90%: " << cur_time << " "; + } + if ((cur_total < 0.95f * m_transactions) && (cur_total + m_buckets[i] >= 0.95f * m_transactions)) { + cout << "95%: " << cur_time << " "; + } + if ((cur_total < 0.99f * m_transactions) && (cur_total + m_buckets[i] >= 0.99f * m_transactions)) { + cout << "99%: " << cur_time << " "; + } + cur_total += m_buckets[i]; + } + cout << endl; + + } +}; + +String16 generateServiceName(int num) +{ + char num_str[32]; + snprintf(num_str, sizeof(num_str), "%d", num); + String16 serviceName = String16("binderWorker") + String16(num_str); + return serviceName; +} + +void worker_fx( + int num, + int worker_count, + int iterations, + Pipe p) +{ + // Create BinderWorkerService and for go. + ProcessState::self()->startThreadPool(); + sp<IServiceManager> serviceMgr = defaultServiceManager(); + sp<BinderWorkerService> service = new BinderWorkerService; + serviceMgr->addService(generateServiceName(num), service); + + srand(num); + p.signal(); + p.wait(); + + // Get references to other binder services. + cout << "Created BinderWorker" << num << endl; + (void)worker_count; + vector<sp<IBinder> > workers; + for (int i = 0; i < worker_count; i++) { + if (num == i) + continue; + workers.push_back(serviceMgr->getService(generateServiceName(i))); + } + + // Run the benchmark. + ProcResults results; + chrono::time_point<chrono::high_resolution_clock> start, end; + for (int i = 0; i < iterations; i++) { + int target = rand() % workers.size(); + Parcel data, reply; + start = chrono::high_resolution_clock::now(); + status_t ret = workers[target]->transact(BINDER_NOP, data, &reply); + end = chrono::high_resolution_clock::now(); + + uint64_t cur_time = uint64_t(chrono::duration_cast<chrono::nanoseconds>(end - start).count()); + results.add_time(cur_time); + + if (ret != NO_ERROR) { + cout << "thread " << num << " failed " << ret << "i : " << i << endl; + exit(EXIT_FAILURE); + } + } + // Signal completion to master and wait. + p.signal(); + p.wait(); + + // Send results to master and wait for go to exit. + p.send(results); + p.wait(); + + exit(EXIT_SUCCESS); +} + +Pipe make_worker(int num, int iterations, int worker_count) +{ + auto pipe_pair = Pipe::createPipePair(); + pid_t pid = fork(); + if (pid) { + /* parent */ + return move(get<0>(pipe_pair)); + } else { + /* child */ + worker_fx(num, worker_count, iterations, move(get<1>(pipe_pair))); + /* never get here */ + return move(get<0>(pipe_pair)); + } + +} + +void wait_all(vector<Pipe>& v) +{ + for (int i = 0; i < v.size(); i++) { + v[i].wait(); + } +} + +void signal_all(vector<Pipe>& v) +{ + for (int i = 0; i < v.size(); i++) { + v[i].signal(); + } +} + +int main(int argc, char *argv[]) +{ + int workers = 2; + int iterations = 10000; + (void)argc; + (void)argv; + vector<Pipe> pipes; + + // Parse arguments. + for (int i = 1; i < argc; i++) { + if (string(argv[i]) == "-w") { + workers = atoi(argv[i+1]); + i++; + continue; + } + if (string(argv[i]) == "-i") { + iterations = atoi(argv[i+1]); + i++; + continue; + } + } + + // Create all the workers and wait for them to spawn. + for (int i = 0; i < workers; i++) { + pipes.push_back(make_worker(i, iterations, workers)); + } + wait_all(pipes); + + + // Run the workers and wait for completion. + chrono::time_point<chrono::high_resolution_clock> start, end; + cout << "waiting for workers to complete" << endl; + start = chrono::high_resolution_clock::now(); + signal_all(pipes); + wait_all(pipes); + end = chrono::high_resolution_clock::now(); + + // Calculate overall throughput. + double iterations_per_sec = double(iterations * workers) / (chrono::duration_cast<chrono::nanoseconds>(end - start).count() / 1.0E9); + cout << "iterations per sec: " << iterations_per_sec << endl; + + // Collect all results from the workers. + cout << "collecting results" << endl; + signal_all(pipes); + ProcResults tot_results; + for (int i = 0; i < workers; i++) { + ProcResults tmp_results; + pipes[i].recv(tmp_results); + tot_results = ProcResults::combine(tot_results, tmp_results); + } + tot_results.dump(); + + // Kill all the workers. + cout << "killing workers" << endl; + signal_all(pipes); + for (int i = 0; i < workers; i++) { + int status; + wait(&status); + if (status != 0) { + cout << "nonzero child status" << status << endl; + } + } + return 0; +} diff --git a/libs/input/Android.mk b/libs/input/Android.mk index 944ac7f653..746de66d62 100644 --- a/libs/input/Android.mk +++ b/libs/input/Android.mk @@ -56,6 +56,9 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= $(deviceSources) +LOCAL_CLANG := true +LOCAL_SANITIZE := integer + LOCAL_SHARED_LIBRARIES := \ liblog \ libcutils \ diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index b64cb2ca9d..a6246636a3 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -23,7 +23,7 @@ #include <input/Input.h> #include <input/InputEventLabels.h> -#ifdef HAVE_ANDROID_OS +#ifdef __ANDROID__ #include <binder/Parcel.h> #endif @@ -144,7 +144,7 @@ void PointerCoords::applyOffset(float xOffset, float yOffset) { setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset); } -#ifdef HAVE_ANDROID_OS +#ifdef __ANDROID__ status_t PointerCoords::readFromParcel(Parcel* parcel) { bits = parcel->readInt64(); @@ -420,7 +420,7 @@ void MotionEvent::transform(const float matrix[9]) { } } -#ifdef HAVE_ANDROID_OS +#ifdef __ANDROID__ status_t MotionEvent::readFromParcel(Parcel* parcel) { size_t pointerCount = parcel->readInt32(); size_t sampleCount = parcel->readInt32(); @@ -457,7 +457,8 @@ status_t MotionEvent::readFromParcel(Parcel* parcel) { properties.toolType = parcel->readInt32(); } - while (sampleCount-- > 0) { + while (sampleCount > 0) { + sampleCount--; mSampleEventTimes.push(parcel->readInt64()); for (size_t i = 0; i < pointerCount; i++) { mSamplePointerCoords.push(); diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 7f83da523f..2dff4e0918 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -516,7 +516,8 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory, status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) { status_t result; - for (size_t i = mBatches.size(); i-- > 0; ) { + for (size_t i = mBatches.size(); i > 0; ) { + i--; Batch& batch = mBatches.editItemAt(i); if (frameTime < 0) { result = consumeSamples(factory, batch, batch.samples.size(), @@ -826,7 +827,8 @@ status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) { uint32_t currentSeq = seq; uint32_t chainSeqs[seqChainCount]; size_t chainIndex = 0; - for (size_t i = seqChainCount; i-- > 0; ) { + for (size_t i = seqChainCount; i > 0; ) { + i--; const SeqChain& seqChain = mSeqChains.itemAt(i); if (seqChain.seq == currentSeq) { currentSeq = seqChain.chain; @@ -835,7 +837,8 @@ status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) { } } status_t status = OK; - while (!status && chainIndex-- > 0) { + while (!status && chainIndex > 0) { + chainIndex--; status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled); } if (status) { @@ -845,7 +848,10 @@ status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) { seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq; seqChain.chain = chainSeqs[chainIndex]; mSeqChains.push(seqChain); - } while (chainIndex-- > 0); + if (chainIndex != 0) { + chainIndex--; + } + } while (chainIndex > 0); return status; } } diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index df3f0dd1da..dd01a934ba 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -19,7 +19,7 @@ #include <stdlib.h> #include <string.h> -#if HAVE_ANDROID_OS +#ifdef __ANDROID__ #include <binder/Parcel.h> #endif @@ -599,7 +599,7 @@ void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents, } } -#if HAVE_ANDROID_OS +#ifdef __ANDROID__ sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) { sp<KeyCharacterMap> map = new KeyCharacterMap(); map->mType = parcel->readInt32(); diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp index 6c70c3c9eb..7f6b1576cf 100644 --- a/libs/input/VelocityTracker.cpp +++ b/libs/input/VelocityTracker.cpp @@ -46,7 +46,8 @@ static const nsecs_t ASSUME_POINTER_STOPPED_TIME = 40 * NANOS_PER_MS; static float vectorDot(const float* a, const float* b, uint32_t m) { float r = 0; - while (m--) { + while (m) { + m--; r += *(a++) * *(b++); } return r; @@ -54,7 +55,8 @@ static float vectorDot(const float* a, const float* b, uint32_t m) { static float vectorNorm(const float* a, uint32_t m) { float r = 0; - while (m--) { + while (m) { + m--; float t = *(a++); r += t * t; } @@ -511,7 +513,8 @@ static bool solveLeastSquares(const float* x, const float* y, for (uint32_t h = 0; h < m; h++) { wy[h] = y[h] * w[h]; } - for (uint32_t i = n; i-- != 0; ) { + for (uint32_t i = n; i != 0; ) { + i--; outB[i] = vectorDot(&q[i][0], wy, m); for (uint32_t j = n - 1; j > i; j--) { outB[i] -= r[i][j] * outB[j]; diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index 1ce8626522..54ff741a4e 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -17,6 +17,7 @@ include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_CPPFLAGS := -std=c++1y -Weverything -Werror +LOCAL_SANITIZE := integer # The static constructors and destructors in this library have not been noted to # introduce significant overheads diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 3810da4049..a3558bd5c2 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -835,18 +835,6 @@ Rect const* Region::getArray(size_t* count) const { return begin(); } -SharedBuffer const* Region::getSharedBuffer(size_t* count) const { - // We can get to the SharedBuffer of a Vector<Rect> because Rect has - // a trivial destructor. - SharedBuffer const* sb = SharedBuffer::bufferFromData(mStorage.array()); - if (count) { - size_t numRects = isRect() ? 1 : mStorage.size() - 1; - count[0] = numRects; - } - sb->acquire(); - return sb; -} - // ---------------------------------------------------------------------------- void Region::dump(String8& out, const char* what, uint32_t /* flags */) const diff --git a/opengl/libagl/context.h b/opengl/libagl/context.h index c599a55aaf..d23f43568e 100644 --- a/opengl/libagl/context.h +++ b/opengl/libagl/context.h @@ -21,7 +21,7 @@ #include <stddef.h> #include <sys/types.h> #include <pthread.h> -#ifdef HAVE_ANDROID_OS +#ifdef __ANDROID__ #include <bionic_tls.h> #endif @@ -579,7 +579,7 @@ private: // state // ---------------------------------------------------------------------------- -#ifdef HAVE_ANDROID_OS +#ifdef __ANDROID__ // We have a dedicated TLS slot in bionic inline void setGlThreadSpecific(ogles_context_t *value) { __get_tls()[TLS_SLOT_OPENGL] = value; diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 593d0c2d05..7560d8fdf0 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -64,7 +64,7 @@ const unsigned int NUM_DISPLAYS = 1; static pthread_mutex_t gInitMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t gErrorKeyMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t gEGLErrorKey = -1; -#ifndef HAVE_ANDROID_OS +#ifndef __ANDROID__ namespace gl { pthread_key_t gGLKey = -1; }; // namespace gl @@ -1373,7 +1373,7 @@ static EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config, int32_t w = 0; int32_t h = 0; - while (attrib_list[0]) { + while (attrib_list[0] != EGL_NONE) { if (attrib_list[0] == EGL_WIDTH) w = attrib_list[1]; if (attrib_list[0] == EGL_HEIGHT) h = attrib_list[1]; attrib_list+=2; @@ -1403,7 +1403,7 @@ using namespace android; EGLDisplay eglGetDisplay(NativeDisplayType display) { -#ifndef HAVE_ANDROID_OS +#ifndef __ANDROID__ // this just needs to be done once if (gGLKey == -1) { pthread_mutex_lock(&gInitMutex); diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index 18ad3003e1..7fb0f77d1e 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -59,6 +59,11 @@ ifneq ($(MAX_EGL_CACHE_SIZE),) LOCAL_CFLAGS += -DMAX_EGL_CACHE_SIZE=$(MAX_EGL_CACHE_SIZE) endif +ifneq ($(filter address,$(SANITIZE_TARGET)),) + LOCAL_CFLAGS_32 += -DEGL_WRAPPER_DIR=\"/$(TARGET_COPY_OUT_DATA)/lib\" + LOCAL_CFLAGS_64 += -DEGL_WRAPPER_DIR=\"/$(TARGET_COPY_OUT_DATA)/lib64\" +endif + LOCAL_REQUIRED_MODULES := $(egl.cfg_config_module) egl.cfg_config_module := @@ -139,6 +144,7 @@ LOCAL_SRC_FILES:= \ # LOCAL_MODULE:= libETC1 +LOCAL_MODULE_HOST_OS := darwin linux windows include $(BUILD_HOST_STATIC_LIBRARY) diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index 1fcc048b28..8df9af3e44 100644 --- a/opengl/libs/EGL/Loader.cpp +++ b/opengl/libs/EGL/Loader.cpp @@ -167,6 +167,14 @@ static void* load_wrapper(const char* path) { return so; } +#ifndef EGL_WRAPPER_DIR +#if defined(__LP64__) +#define EGL_WRAPPER_DIR "/system/lib64" +#else +#define EGL_WRAPPER_DIR "/system/lib" +#endif +#endif + void* Loader::open(egl_connection_t* cnx) { void* dso; @@ -187,15 +195,10 @@ void* Loader::open(egl_connection_t* cnx) LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation"); -#if defined(__LP64__) - cnx->libEgl = load_wrapper("/system/lib64/libEGL.so"); - cnx->libGles2 = load_wrapper("/system/lib64/libGLESv2.so"); - cnx->libGles1 = load_wrapper("/system/lib64/libGLESv1_CM.so"); -#else - cnx->libEgl = load_wrapper("/system/lib/libEGL.so"); - cnx->libGles2 = load_wrapper("/system/lib/libGLESv2.so"); - cnx->libGles1 = load_wrapper("/system/lib/libGLESv1_CM.so"); -#endif + cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so"); + cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so"); + cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so"); + LOG_ALWAYS_FATAL_IF(!cnx->libEgl, "couldn't load system EGL wrapper libraries"); diff --git a/opengl/tests/gl_perfapp/jni/gl_code.cpp b/opengl/tests/gl_perfapp/jni/gl_code.cpp index 2f0418373a..378c8e88db 100644 --- a/opengl/tests/gl_perfapp/jni/gl_code.cpp +++ b/opengl/tests/gl_perfapp/jni/gl_code.cpp @@ -26,8 +26,6 @@ uint32_t h; // The stateClock starts at zero and increments by 1 every time we draw a frame. It is used to control which phase of the test we are in. int stateClock; -const int doLoopStates = 2; -const int doSingleTestStates = 2; bool done; // Saves the parameters of the test (so we can print them out when we finish the timing.) diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java index 1bed05bb63..5a412bf85f 100644 --- a/opengl/tools/glgen/src/JniCodeEmitter.java +++ b/opengl/tools/glgen/src/JniCodeEmitter.java @@ -673,7 +673,7 @@ public class JniCodeEmitter { "\";"); cStream.println(); - cStream.println("static JNINativeMethod methods[] = {"); + cStream.println("static const JNINativeMethod methods[] = {"); cStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },"); diff --git a/services/powermanager/Android.mk b/services/powermanager/Android.mk index 7b24c65554..4deb115eee 100644 --- a/services/powermanager/Android.mk +++ b/services/powermanager/Android.mk @@ -14,4 +14,6 @@ LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../../include + include $(BUILD_SHARED_LIBRARY) diff --git a/services/powermanager/IPowerManager.cpp b/services/powermanager/IPowerManager.cpp index ec864ee504..bff871916f 100644 --- a/services/powermanager/IPowerManager.cpp +++ b/services/powermanager/IPowerManager.cpp @@ -27,15 +27,6 @@ namespace android { -// must be kept in sync with IPowerManager.aidl -enum { - ACQUIRE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION, - ACQUIRE_WAKE_LOCK_UID = IBinder::FIRST_CALL_TRANSACTION + 1, - RELEASE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION + 2, - UPDATE_WAKE_LOCK_UIDS = IBinder::FIRST_CALL_TRANSACTION + 3, - POWER_HINT = IBinder::FIRST_CALL_TRANSACTION + 4, -}; - class BpPowerManager : public BpInterface<IPowerManager> { public: @@ -104,6 +95,44 @@ public: // This FLAG_ONEWAY is in the .aidl, so there is no way to disable it return remote()->transact(POWER_HINT, data, &reply, IBinder::FLAG_ONEWAY); } + + virtual status_t goToSleep(int64_t event_time_ms, int reason, int flags) + { + Parcel data, reply; + data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor()); + data.writeInt64(event_time_ms); + data.writeInt32(reason); + data.writeInt32(flags); + return remote()->transact(GO_TO_SLEEP, data, &reply, 0); + } + + virtual status_t reboot(bool confirm, const String16& reason, bool wait) + { + Parcel data, reply; + data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor()); + data.writeInt32(confirm); + data.writeString16(reason); + data.writeInt32(wait); + return remote()->transact(REBOOT, data, &reply, 0); + } + + virtual status_t shutdown(bool confirm, const String16& reason, bool wait) + { + Parcel data, reply; + data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor()); + data.writeInt32(confirm); + data.writeString16(reason); + data.writeInt32(wait); + return remote()->transact(SHUTDOWN, data, &reply, 0); + } + + virtual status_t crash(const String16& message) + { + Parcel data, reply; + data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor()); + data.writeString16(message); + return remote()->transact(CRASH, data, &reply, 0); + } }; IMPLEMENT_META_INTERFACE(PowerManager, "android.os.IPowerManager"); diff --git a/services/sensorservice/BatteryService.cpp b/services/sensorservice/BatteryService.cpp index cb962a6349..81f32cdc58 100644 --- a/services/sensorservice/BatteryService.cpp +++ b/services/sensorservice/BatteryService.cpp @@ -83,7 +83,7 @@ void BatteryService::cleanupImpl(uid_t uid) { if (mBatteryStatService != 0) { Mutex::Autolock _l(mActivationsLock); int64_t identity = IPCThreadState::self()->clearCallingIdentity(); - for (ssize_t i=0 ; i<mActivations.size() ; i++) { + for (size_t i=0 ; i<mActivations.size() ; i++) { const Info& info(mActivations[i]); if (info.uid == uid) { mBatteryStatService->noteStopSensor(info.uid, info.handle); diff --git a/services/sensorservice/GravitySensor.cpp b/services/sensorservice/GravitySensor.cpp index 3cb3745202..61118bc54a 100644 --- a/services/sensorservice/GravitySensor.cpp +++ b/services/sensorservice/GravitySensor.cpp @@ -44,7 +44,6 @@ GravitySensor::GravitySensor(sensor_t const* list, size_t count) bool GravitySensor::process(sensors_event_t* outEvent, const sensors_event_t& event) { - const static double NS2S = 1.0 / 1000000000.0; if (event.type == SENSOR_TYPE_ACCELEROMETER) { vec3_t g; if (!mSensorFusion.hasEstimate()) diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp index dd1bccfbec..40d596f36b 100644 --- a/services/sensorservice/SensorDevice.cpp +++ b/services/sensorservice/SensorDevice.cpp @@ -388,7 +388,7 @@ void SensorDevice::disableAllSensors() { status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) { ALOGD_IF(DEBUG_CONNECTIONS, - "sensor_event handle=%d ts=%lld data=%.2f, %.2f, %.2f %.2f %.2f %.2f", + "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f", injected_sensor_event->sensor, injected_sensor_event->timestamp, injected_sensor_event->data[0], injected_sensor_event->data[1], injected_sensor_event->data[2], diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 40b21a96a0..1a486a34c8 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -118,7 +118,7 @@ void SensorService::onFirstRef() // it's safe to instantiate the SensorFusion object here // (it wants to be instantiated after h/w sensors have been // registered) - const SensorFusion& fusion(SensorFusion::getInstance()); + SensorFusion::getInstance(); // build the sensor list returned to users mUserSensorList = mSensorList; @@ -381,7 +381,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) mActiveSensors.valueAt(i)->getNumConnections()); } - result.appendFormat("Socket Buffer size = %d events\n", + result.appendFormat("Socket Buffer size = %zd events\n", mSocketBufferSize/sizeof(sensors_event_t)); result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held"); @@ -1104,7 +1104,7 @@ bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, AppOpsManager appOps; if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName) != AppOpsManager::MODE_ALLOWED) { - ALOGE("%s a sensor (%s) without enabled required app op: %D", + ALOGE("%s a sensor (%s) without enabled required app op: %d", operation, sensor.getName().string(), opCode); return false; } @@ -1307,13 +1307,13 @@ void SensorService::CircularBuffer::printBuffer(String8& result) const { } result.appendFormat("%d) ", eventNum++); if (mSensorType == SENSOR_TYPE_STEP_COUNTER) { - result.appendFormat("%llu,", mTrimmedSensorEventArr[i]->mStepCounter); + result.appendFormat("%" PRIu64 ",", mTrimmedSensorEventArr[i]->mStepCounter); } else { for (int j = 0; j < numData; ++j) { result.appendFormat("%5.1f,", mTrimmedSensorEventArr[i]->mData[j]); } } - result.appendFormat("%lld %02d:%02d:%02d ", mTrimmedSensorEventArr[i]->mTimestamp, + result.appendFormat("%" PRId64 " %02d:%02d:%02d ", mTrimmedSensorEventArr[i]->mTimestamp, mTrimmedSensorEventArr[i]->mHour, mTrimmedSensorEventArr[i]->mMin, mTrimmedSensorEventArr[i]->mSec); i = (i + 1) % mBufSize; diff --git a/services/sensorservice/main_sensorservice.cpp b/services/sensorservice/main_sensorservice.cpp index 0a96f42973..01bb0e781e 100644 --- a/services/sensorservice/main_sensorservice.cpp +++ b/services/sensorservice/main_sensorservice.cpp @@ -20,6 +20,7 @@ using namespace android; int main(int /*argc*/, char** /*argv*/) { + signal(SIGPIPE, SIG_IGN); SensorService::publishAndJoinThreadPool(); return 0; } diff --git a/services/sensorservice/vec.h b/services/sensorservice/vec.h index 24f30ff436..a142bad3a1 100644 --- a/services/sensorservice/vec.h +++ b/services/sensorservice/vec.h @@ -37,7 +37,7 @@ template <typename TYPE, size_t SIZE> class vec; template <typename TYPE, size_t SIZE> -class vbase; +struct vbase; namespace helpers { diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 1eb23616c3..17ca10e9b8 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -122,6 +122,8 @@ LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--e LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CPPFLAGS := -std=c++11 +LOCAL_INIT_RC := surfaceflinger.rc + LOCAL_SRC_FILES := \ main_surfaceflinger.cpp diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 0859149156..d37fcb2b8a 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -1036,12 +1036,10 @@ public: } } virtual void setVisibleRegionScreen(const Region& reg) { - // Region::getSharedBuffer creates a reference to the underlying - // SharedBuffer of this Region, this reference is freed - // in onDisplayed() hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen; - SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects); - visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data()); + mVisibleRegion = reg; + visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>( + mVisibleRegion.getArray(&visibleRegion.numRects)); } virtual void setSurfaceDamage(const Region& reg) { if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) { @@ -1055,8 +1053,9 @@ public: surfaceDamage.rects = NULL; return; } - SharedBuffer const* sb = reg.getSharedBuffer(&surfaceDamage.numRects); - surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>(sb->data()); + mSurfaceDamage = reg; + surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>( + mSurfaceDamage.getArray(&surfaceDamage.numRects)); } virtual void setSidebandStream(const sp<NativeHandle>& stream) { ALOG_ASSERT(stream->handle() != NULL); @@ -1078,29 +1077,15 @@ public: } } virtual void onDisplayed() { - hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen; - SharedBuffer const* sb = SharedBuffer::bufferFromData(visibleRegion.rects); - if (sb) { - sb->release(); - // not technically needed but safer - visibleRegion.numRects = 0; - visibleRegion.rects = NULL; - } - getLayer()->acquireFenceFd = -1; - - if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) { - return; - } - - hwc_region_t& surfaceDamage = getLayer()->surfaceDamage; - sb = SharedBuffer::bufferFromData(surfaceDamage.rects); - if (sb) { - sb->release(); - surfaceDamage.numRects = 0; - surfaceDamage.rects = NULL; - } } + +protected: + // We need to hold "copies" of these for memory management purposes. The + // actual hwc_layer_1_t holds pointers to the memory within. Vector<> + // internally doesn't copy the memory unless one of the copies is modified. + Region mVisibleRegion; + Region mSurfaceDamage; }; /* diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp index a74bc4cd91..ca81aaa734 100644 --- a/services/surfaceflinger/main_surfaceflinger.cpp +++ b/services/surfaceflinger/main_surfaceflinger.cpp @@ -26,6 +26,7 @@ using namespace android; int main(int, char**) { + signal(SIGPIPE, SIG_IGN); // When SF is launched in its own process, limit the number of // binder threads to 4. ProcessState::self()->setThreadPoolMaxThreadCount(4); diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc new file mode 100644 index 0000000000..59a43e2190 --- /dev/null +++ b/services/surfaceflinger/surfaceflinger.rc @@ -0,0 +1,6 @@ +service surfaceflinger /system/bin/surfaceflinger + class core + user system + group graphics drmrpc + onrestart restart zygote + writepid /dev/cpuset/system-background/tasks |