summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/atrace/atrace.rc2
-rw-r--r--cmds/dumpstate/dumpstate.cpp287
-rw-r--r--cmds/dumpstate/dumpstate.rc8
-rw-r--r--cmds/dumpstate/utils.cpp3
-rw-r--r--include/gui/GraphicsEnv.h59
-rw-r--r--libs/gui/Android.mk2
-rw-r--r--libs/gui/GLConsumer.cpp11
-rw-r--r--libs/gui/GraphicsEnv.cpp81
-rw-r--r--opengl/libs/EGL/Loader.cpp96
-rw-r--r--opengl/libs/EGL/Loader.h7
-rw-r--r--opengl/libs/EGL/eglApi.cpp7
-rw-r--r--opengl/libs/EGL/egl_display.cpp3
-rw-r--r--opengl/specs/EGL_ANDROID_create_native_client_buffer.txt11
-rw-r--r--services/sensorservice/BatteryService.cpp24
-rw-r--r--services/sensorservice/BatteryService.h1
-rw-r--r--services/sensorservice/SensorService.cpp11
-rw-r--r--services/surfaceflinger/Layer.cpp1
-rw-r--r--vulkan/libvulkan/Android.mk2
-rw-r--r--vulkan/libvulkan/driver.cpp70
-rw-r--r--vulkan/libvulkan/swapchain.cpp2
20 files changed, 557 insertions, 131 deletions
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index e3cc9da5f3..747cc69282 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -1,6 +1,6 @@
## Permissions to allow system-wide tracing to the kernel trace buffer.
##
-on fs
+on post-fs
# Allow writing to the kernel trace log.
chmod 0222 /sys/kernel/debug/tracing/trace_marker
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 60460e0122..0929d9b9e9 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -34,8 +34,9 @@
#include <sys/wait.h>
#include <unistd.h>
-#include <android-base/stringprintf.h>
#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <cutils/properties.h>
#include "private/android_filesystem_config.h"
@@ -385,6 +386,83 @@ static void dump_raft() {
}
}
+/**
+ * Finds the last modified file in the directory dir whose name starts with file_prefix
+ * Function returns empty string when it does not find a file
+ */
+static std::string get_last_modified_file_matching_prefix(const std::string& dir,
+ const std::string& file_prefix) {
+ std::unique_ptr<DIR, decltype(&closedir)> d(opendir(dir.c_str()), closedir);
+ if (d == nullptr) {
+ MYLOGD("Error %d opening %s\n", errno, dir.c_str());
+ return "";
+ }
+
+ // Find the newest file matching the file_prefix in dir
+ struct dirent *de;
+ time_t last_modified = 0;
+ std::string last_modified_file = "";
+ struct stat s;
+
+ while ((de = readdir(d.get()))) {
+ std::string file = std::string(de->d_name);
+ if (!file_prefix.empty()) {
+ if (!android::base::StartsWith(file, file_prefix.c_str())) continue;
+ }
+ file = dir + "/" + file;
+ int ret = stat(file.c_str(), &s);
+
+ if ((ret == 0) && (s.st_mtime > last_modified)) {
+ last_modified_file = file;
+ last_modified = s.st_mtime;
+ }
+ }
+
+ return last_modified_file;
+}
+
+void dump_modem_logs() {
+ DurationReporter duration_reporter("dump_modem_logs");
+ if (is_user_build()) {
+ return;
+ }
+
+ if (!is_zipping()) {
+ MYLOGD("Not dumping modem logs. dumpstate is not generating a zipping bugreport\n");
+ return;
+ }
+
+ char property[PROPERTY_VALUE_MAX];
+ property_get("ro.radio.log_prefix", property, "");
+ std::string file_prefix = std::string(property);
+ if(file_prefix.empty()) {
+ MYLOGD("No modem log : file_prefix is empty\n");
+ return;
+ }
+
+ MYLOGD("dump_modem_logs: directory is %s and file_prefix is %s\n",
+ bugreport_dir.c_str(), file_prefix.c_str());
+
+ std::string modem_log_file =
+ get_last_modified_file_matching_prefix(bugreport_dir, file_prefix);
+
+ struct stat s;
+ if (modem_log_file.empty() || stat(modem_log_file.c_str(), &s) != 0) {
+ MYLOGD("Modem log %s does not exist\n", modem_log_file.c_str());
+ return;
+ }
+
+ std::string filename = basename(modem_log_file.c_str());
+ if (!add_zip_entry(filename, modem_log_file)) {
+ MYLOGE("Unable to add modem log %s to zip file\n", modem_log_file.c_str());
+ } else {
+ MYLOGD("Modem Log %s is added to zip\n", modem_log_file.c_str());
+ if (remove(modem_log_file.c_str())) {
+ MYLOGE("Error removing modem log %s\n", modem_log_file.c_str());
+ }
+ }
+}
+
static bool skip_not_stat(const char *path) {
static const char stat[] = "/stat";
size_t len = strlen(path);
@@ -830,9 +908,63 @@ static void dump_iptables() {
run_command("IP6TABLES RAW", 10, "ip6tables", "-t", "raw", "-L", "-nvx", NULL);
}
+static void do_kmsg() {
+ struct stat st;
+ if (!stat(PSTORE_LAST_KMSG, &st)) {
+ /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */
+ dump_file("LAST KMSG", PSTORE_LAST_KMSG);
+ } else if (!stat(ALT_PSTORE_LAST_KMSG, &st)) {
+ dump_file("LAST KMSG", ALT_PSTORE_LAST_KMSG);
+ } else {
+ /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
+ dump_file("LAST KMSG", "/proc/last_kmsg");
+ }
+}
+
+static void do_logcat() {
+ unsigned long timeout;
+ // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
+ // calculate timeout
+ timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash");
+ if (timeout < 20000) {
+ timeout = 20000;
+ }
+ 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",
+ "-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",
+ "-v", "printable",
+ "-d",
+ "*:v", NULL);
+
+ run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL);
+
+ /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */
+ run_command("LAST LOGCAT", 10, "logcat", "-L",
+ "-b", "all",
+ "-v", "threadtime",
+ "-v", "printable",
+ "-d",
+ "*:v", NULL);
+}
+
static void dumpstate(const std::string& screenshot_path, const std::string& version) {
DurationReporter duration_reporter("DUMPSTATE");
- unsigned long timeout;
dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
run_command("UPTIME", 10, "uptime", NULL);
@@ -867,42 +999,16 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver
for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
for_each_pid(show_showtime, "PROCESS TIMES (pid cmd user system iowait+percentage)");
+ /* Dump Bluetooth HCI logs */
+ add_dir("/data/misc/bluetooth/logs", true);
+
if (!screenshot_path.empty()) {
MYLOGI("taking late screenshot\n");
take_screenshot(screenshot_path);
MYLOGI("wrote screenshot: %s\n", screenshot_path.c_str());
}
- // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
- // calculate timeout
- timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash");
- if (timeout < 20000) {
- timeout = 20000;
- }
- 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",
- "-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",
- "-v", "printable",
- "-d",
- "*:v", NULL);
-
- run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL);
+ do_logcat();
/* show the traces we collected in main(), if that was done */
if (dump_traces_path != NULL) {
@@ -970,23 +1076,7 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver
dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats");
- if (!stat(PSTORE_LAST_KMSG, &st)) {
- /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */
- dump_file("LAST KMSG", PSTORE_LAST_KMSG);
- } else if (!stat(ALT_PSTORE_LAST_KMSG, &st)) {
- dump_file("LAST KMSG", ALT_PSTORE_LAST_KMSG);
- } else {
- /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
- dump_file("LAST KMSG", "/proc/last_kmsg");
- }
-
- /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */
- run_command("LAST LOGCAT", 10, "logcat", "-L",
- "-b", "all",
- "-v", "threadtime",
- "-v", "printable",
- "-d",
- "*:v", NULL);
+ do_kmsg();
/* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
@@ -1119,6 +1209,10 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver
run_command("APP PROVIDERS", 30, "dumpsys", "-t", "30", "activity", "provider", "all", NULL);
+ // dump_modem_logs adds the modem logs if available to the bugreport.
+ // Do this at the end to allow for sufficient time for the modem logs to be
+ // collected.
+ dump_modem_logs();
printf("========================================================\n");
printf("== Final progress (pid %d): %d/%d (originally %d)\n",
@@ -1130,14 +1224,15 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver
static void usage() {
fprintf(stderr,
- "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file [-d] [-p] "
- "[-z]] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]\n"
+ "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-t]"
+ "[-z] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]\n"
" -h: display this help message\n"
" -b: play sound file instead of vibrate, at beginning of job\n"
" -e: play sound file instead of vibrate, at end of job\n"
" -o: write to file (instead of stdout)\n"
" -d: append date to filename (requires -o)\n"
" -p: capture screenshot to filename.png (requires -o)\n"
+ " -t: only captures telephony sections\n"
" -z: generate zipped file (requires -o)\n"
" -s: write output to control socket (for init)\n"
" -S: write file location to control socket (for init; requires -o and -z)"
@@ -1234,6 +1329,8 @@ int main(int argc, char *argv[]) {
int do_broadcast = 0;
int do_early_screenshot = 0;
int is_remote_mode = 0;
+ bool telephony_only = false;
+
std::string version = VERSION_DEFAULT;
now = time(NULL);
@@ -1274,9 +1371,10 @@ int main(int argc, char *argv[]) {
format_args(argc, const_cast<const char **>(argv), &args);
MYLOGD("Dumpstate command line: %s\n", args.c_str());
int c;
- while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) {
+ while ((c = getopt(argc, argv, "dho:svqzptPBRSV:")) != -1) {
switch (c) {
case 'd': do_add_date = 1; break;
+ case 't': telephony_only = true; break;
case 'z': do_zip_file = 1; break;
case 'o': use_outfile = optarg; break;
case 's': use_socket = 1; break;
@@ -1373,6 +1471,9 @@ int main(int argc, char *argv[]) {
char build_id[PROPERTY_VALUE_MAX];
property_get("ro.build.id", build_id, "UNKNOWN_BUILD");
base_name = base_name + "-" + build_id;
+ if (telephony_only) {
+ base_name = base_name + "-telephony";
+ }
if (do_fb) {
// TODO: if dumpstate was an object, the paths could be internal variables and then
// we could have a function to calculate the derived values, such as:
@@ -1482,48 +1583,60 @@ int main(int argc, char *argv[]) {
// duration is logged into MYLOG instead.
print_header(version);
- // Dumps systrace right away, otherwise it will be filled with unnecessary events.
- // First try to dump anrd trace if the daemon is running. Otherwise, dump
- // the raw trace.
- if (!dump_anrd_trace()) {
- dump_systrace();
- }
-
- // TODO: Drop root user and move into dumpstate() once b/28633932 is fixed.
- dump_raft();
-
- // Invoking the following dumpsys calls before dump_traces() to try and
- // keep the system stats as close to its initial state as possible.
- run_command_as_shell("DUMPSYS MEMINFO", 30, "dumpsys", "-t", "30", "meminfo", "-a", NULL);
- run_command_as_shell("DUMPSYS CPUINFO", 10, "dumpsys", "-t", "10", "cpuinfo", "-a", NULL);
+ if (telephony_only) {
+ dump_iptables();
+ if (!drop_root_user()) {
+ return -1;
+ }
+ do_dmesg();
+ do_logcat();
+ do_kmsg();
+ dumpstate_board();
+ dump_modem_logs();
+ } else {
+ // Dumps systrace right away, otherwise it will be filled with unnecessary events.
+ // First try to dump anrd trace if the daemon is running. Otherwise, dump
+ // the raw trace.
+ if (!dump_anrd_trace()) {
+ dump_systrace();
+ }
- /* collect stack traces from Dalvik and native processes (needs root) */
- dump_traces_path = dump_traces();
+ // TODO: Drop root user and move into dumpstate() once b/28633932 is fixed.
+ dump_raft();
+
+ // Invoking the following dumpsys calls before dump_traces() to try and
+ // keep the system stats as close to its initial state as possible.
+ run_command_as_shell("DUMPSYS MEMINFO", 30, "dumpsys", "-t", "30", "meminfo", "-a", NULL);
+ run_command_as_shell("DUMPSYS CPUINFO", 10, "dumpsys", "-t", "10", "cpuinfo", "-a", NULL);
+
+ /* collect stack traces from Dalvik and native processes (needs root) */
+ dump_traces_path = dump_traces();
+
+ /* Run some operations that require root. */
+ get_tombstone_fds(tombstone_data);
+ add_dir(RECOVERY_DIR, true);
+ add_dir(RECOVERY_DATA_DIR, true);
+ add_dir(LOGPERSIST_DATA_DIR, false);
+ if (!is_user_build()) {
+ add_dir(PROFILE_DATA_DIR_CUR, true);
+ add_dir(PROFILE_DATA_DIR_REF, true);
+ }
+ add_mountinfo();
+ dump_iptables();
- /* Run some operations that require root. */
- get_tombstone_fds(tombstone_data);
- add_dir(RECOVERY_DIR, true);
- add_dir(RECOVERY_DATA_DIR, true);
- add_dir(LOGPERSIST_DATA_DIR, false);
- if (!is_user_build()) {
- add_dir(PROFILE_DATA_DIR_CUR, true);
- add_dir(PROFILE_DATA_DIR_REF, true);
- }
- add_mountinfo();
- dump_iptables();
+ // Capture any IPSec policies in play. No keys are exposed here.
+ run_command("IP XFRM POLICY", 10, "ip", "xfrm", "policy", nullptr);
- // Capture any IPSec policies in play. No keys are exposed here.
- run_command("IP XFRM POLICY", 10, "ip", "xfrm", "policy", nullptr);
+ // Run ss as root so we can see socket marks.
+ run_command("DETAILED SOCKET STATE", 10, "ss", "-eionptu", NULL);
- // Run ss as root so we can see socket marks.
- run_command("DETAILED SOCKET STATE", 10, "ss", "-eionptu", NULL);
+ if (!drop_root_user()) {
+ return -1;
+ }
- if (!drop_root_user()) {
- return -1;
+ dumpstate(do_early_screenshot ? "": screenshot_path, version);
}
- dumpstate(do_early_screenshot ? "": screenshot_path, version);
-
/* close output if needed */
if (is_redirecting) {
fclose(stdout);
diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc
index 3448e91088..336db9fcd1 100644
--- a/cmds/dumpstate/dumpstate.rc
+++ b/cmds/dumpstate/dumpstate.rc
@@ -46,3 +46,11 @@ service bugreportwear /system/bin/dumpstate -d -B -P -p -z \
class main
disabled
oneshot
+
+# bugreportelefony is a lightweight version of bugreport that only includes a few, urgent
+# sections used to report telephony bugs.
+service bugreportelefony /system/bin/dumpstate -t -d -B -z \
+ -o /data/user_de/0/com.android.shell/files/bugreports/bugreport
+ class main
+ disabled
+ oneshot
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index fd6413d562..af6c6660c4 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -828,7 +828,8 @@ bool drop_root_user() {
}
gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW,
- AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC };
+ AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC,
+ AID_BLUETOOTH };
if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
MYLOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
return false;
diff --git a/include/gui/GraphicsEnv.h b/include/gui/GraphicsEnv.h
new file mode 100644
index 0000000000..4c7366f094
--- /dev/null
+++ b/include/gui/GraphicsEnv.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_GUI_GRAPHICS_ENV_H
+#define ANDROID_GUI_GRAPHICS_ENV_H 1
+
+#include <string>
+
+struct android_namespace_t;
+
+namespace android {
+
+class GraphicsEnv {
+public:
+ static GraphicsEnv& getInstance();
+
+ // Set a search path for loading graphics drivers. The path is a list of
+ // directories separated by ':'. A directory can be contained in a zip file
+ // (drivers must be stored uncompressed and page aligned); such elements
+ // in the search path must have a '!' after the zip filename, e.g.
+ // /data/app/com.example.driver/base.apk!/lib/arm64-v8a
+ void setDriverPath(const std::string path);
+ android_namespace_t* getDriverNamespace();
+
+private:
+ GraphicsEnv() = default;
+ std::string mDriverPath;
+ android_namespace_t* mDriverNamespace = nullptr;
+};
+
+} // namespace android
+
+/* FIXME
+ * Export an un-mangled function that just does
+ * return android::GraphicsEnv::getInstance().getDriverNamespace();
+ * This allows libEGL to get the function pointer via dlsym, since it can't
+ * directly link against libgui. In a future release, we'll fix this so that
+ * libgui does not depend on graphics API libraries, and libEGL can link
+ * against it. The current dependencies from libgui -> libEGL are:
+ * - the GLConsumer class, which should be moved to its own library
+ * - the EGLsyncKHR synchronization in BufferQueue, which is deprecated and
+ * will be removed soon.
+ */
+extern "C" android_namespace_t* android_getDriverNamespace();
+
+#endif // ANDROID_GUI_GRAPHICS_ENV_H
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index 46feb1cc36..9e2fc2b040 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -54,6 +54,7 @@ LOCAL_SRC_FILES := \
DisplayEventReceiver.cpp \
GLConsumer.cpp \
GraphicBufferAlloc.cpp \
+ GraphicsEnv.cpp \
GuiConfig.cpp \
IDisplayEventConnection.cpp \
IGraphicBufferAlloc.cpp \
@@ -75,6 +76,7 @@ LOCAL_SRC_FILES := \
SyncFeatures.cpp \
LOCAL_SHARED_LIBRARIES := \
+ libnativeloader \
libbinder \
libcutils \
libEGL \
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index aa0db4506c..10e999c228 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -1228,14 +1228,19 @@ EGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy,
EGL_NONE,
};
if (!crop.isValid()) {
- // No crop rect to set, so terminate the attrib array before the crop.
- attrs[2] = EGL_NONE;
+ // No crop rect to set, so leave the crop out of the attrib array. Make
+ // sure to propagate the protected content attrs if they are set.
+ attrs[2] = attrs[10];
+ attrs[3] = attrs[11];
+ attrs[4] = EGL_NONE;
} else if (!isEglImageCroppable(crop)) {
// The crop rect is not at the origin, so we can't set the crop on the
// EGLImage because that's not allowed by the EGL_ANDROID_image_crop
// extension. In the future we can add a layered extension that
// removes this restriction if there is hardware that can support it.
- attrs[2] = EGL_NONE;
+ attrs[2] = attrs[10];
+ attrs[3] = attrs[11];
+ attrs[4] = EGL_NONE;
}
eglInitialize(dpy, 0, 0);
EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
diff --git a/libs/gui/GraphicsEnv.cpp b/libs/gui/GraphicsEnv.cpp
new file mode 100644
index 0000000000..68f0f988e2
--- /dev/null
+++ b/libs/gui/GraphicsEnv.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 1
+#define LOG_TAG "GraphicsEnv"
+#include <gui/GraphicsEnv.h>
+
+#include <mutex>
+
+#include <log/log.h>
+#include <nativeloader/dlext_namespaces.h>
+
+namespace android {
+
+/*static*/ GraphicsEnv& GraphicsEnv::getInstance() {
+ static GraphicsEnv env;
+ return env;
+}
+
+void GraphicsEnv::setDriverPath(const std::string path) {
+ if (!mDriverPath.empty()) {
+ ALOGV("ignoring attempt to change driver path from '%s' to '%s'",
+ mDriverPath.c_str(), path.c_str());
+ return;
+ }
+ ALOGV("setting driver path to '%s'", path.c_str());
+ mDriverPath = path;
+}
+
+android_namespace_t* GraphicsEnv::getDriverNamespace() {
+ static std::once_flag once;
+ std::call_once(once, [this]() {
+ // TODO; In the next version of Android, all graphics drivers will be
+ // loaded into a custom namespace. To minimize risk for this release,
+ // only updated drivers use a custom namespace.
+ //
+ // Additionally, the custom namespace will be
+ // ANDROID_NAMESPACE_TYPE_ISOLATED, and will only have access to a
+ // subset of the system.
+ if (mDriverPath.empty())
+ return;
+
+ char defaultPath[PATH_MAX];
+ android_get_LD_LIBRARY_PATH(defaultPath, sizeof(defaultPath));
+ size_t defaultPathLen = strlen(defaultPath);
+
+ std::string path;
+ path.reserve(mDriverPath.size() + 1 + defaultPathLen);
+ path.append(mDriverPath);
+ path.push_back(':');
+ path.append(defaultPath, defaultPathLen);
+
+ mDriverNamespace = android_create_namespace(
+ "gfx driver",
+ nullptr, // ld_library_path
+ path.c_str(), // default_library_path
+ ANDROID_NAMESPACE_TYPE_SHARED,
+ nullptr, // permitted_when_isolated_path
+ nullptr); // parent
+ });
+ return mDriverNamespace;
+}
+
+} // namespace android
+
+extern "C" android_namespace_t* android_getDriverNamespace() {
+ return android::GraphicsEnv::getInstance().getDriverNamespace();
+}
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 49f501d3a6..ca5e6e8180 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -14,6 +14,10 @@
** limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <array>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
@@ -23,8 +27,10 @@
#include <limits.h>
#include <dirent.h>
+#include <android/dlext.h>
#include <cutils/log.h>
#include <cutils/properties.h>
+#include <utils/Trace.h>
#include <EGL/egl.h>
@@ -114,6 +120,11 @@ static char const * getProcessCmdline() {
return NULL;
}
+static void* do_dlopen(const char* path, int mode) {
+ ATRACE_CALL();
+ return dlopen(path, mode);
+}
+
// ----------------------------------------------------------------------------
Loader::driver_t::driver_t(void* gles)
@@ -154,14 +165,30 @@ status_t Loader::driver_t::set(void* hnd, int32_t api)
// ----------------------------------------------------------------------------
Loader::Loader()
- : getProcAddress(NULL) {
+ : getProcAddress(NULL),
+ mLibGui(nullptr),
+ mGetDriverNamespace(nullptr)
+{
+ // FIXME: See note in GraphicsEnv.h about android_getDriverNamespace().
+ // libgui should already be loaded in any process that uses libEGL, but
+ // if for some reason it isn't, then we're not going to get a driver
+ // namespace anyway, so don't force it to be loaded.
+ mLibGui = dlopen("libgui.so", RTLD_NOLOAD | RTLD_LOCAL | RTLD_LAZY);
+ if (!mLibGui) {
+ ALOGD("failed to load libgui: %s", dlerror());
+ return;
+ }
+ mGetDriverNamespace = reinterpret_cast<decltype(mGetDriverNamespace)>(
+ dlsym(mLibGui, "android_getDriverNamespace"));
}
Loader::~Loader() {
+ if (mLibGui)
+ dlclose(mLibGui);
}
static void* load_wrapper(const char* path) {
- void* so = dlopen(path, RTLD_NOW | RTLD_LOCAL);
+ void* so = do_dlopen(path, RTLD_NOW | RTLD_LOCAL);
ALOGE_IF(!so, "dlopen(\"%s\") failed: %s", path, dlerror());
return so;
}
@@ -208,6 +235,8 @@ static void setEmulatorGlesValue(void) {
void* Loader::open(egl_connection_t* cnx)
{
+ ATRACE_CALL();
+
void* dso;
driver_t* hnd = 0;
@@ -253,6 +282,8 @@ void Loader::init_api(void* dso,
__eglMustCastToProperFunctionPointerType* curr,
getProcAddressType getProcAddress)
{
+ ATRACE_CALL();
+
const ssize_t SIZE = 256;
char scrap[SIZE];
while (*api) {
@@ -304,9 +335,8 @@ void Loader::init_api(void* dso,
}
}
-void *Loader::load_driver(const char* kind,
- egl_connection_t* cnx, uint32_t mask)
-{
+static void* load_system_driver(const char* kind) {
+ ATRACE_CALL();
class MatchFile {
public:
static String8 find(const char* kind) {
@@ -422,7 +452,7 @@ void *Loader::load_driver(const char* kind,
}
const char* const driver_absolute_path = absolutePath.string();
- void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
+ void* dso = do_dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
if (dso == 0) {
const char* err = dlerror();
ALOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown");
@@ -431,11 +461,63 @@ void *Loader::load_driver(const char* kind,
ALOGD("loaded %s", driver_absolute_path);
+ return dso;
+}
+
+static void* do_android_dlopen_ext(const char* path, int mode, const android_dlextinfo* info) {
+ ATRACE_CALL();
+ return android_dlopen_ext(path, mode, info);
+}
+
+static const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
+ "ro.hardware.egl",
+ "ro.board.platform",
+}};
+
+static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
+ ATRACE_CALL();
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE,
+ .library_namespace = ns,
+ };
+ void* so = nullptr;
+ char prop[PROPERTY_VALUE_MAX + 1];
+ for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
+ if (property_get(key, prop, nullptr) > 0) {
+ String8 name;
+ name.appendFormat("lib%s_%s.so", kind, prop);
+ so = do_android_dlopen_ext(name.string(), RTLD_LOCAL | RTLD_NOW,
+ &dlextinfo);
+ if (so)
+ return so;
+ }
+ }
+ return nullptr;
+}
+
+void *Loader::load_driver(const char* kind,
+ egl_connection_t* cnx, uint32_t mask)
+{
+ ATRACE_CALL();
+
+ void* dso = nullptr;
+ if (mGetDriverNamespace) {
+ android_namespace_t* ns = mGetDriverNamespace();
+ if (ns) {
+ dso = load_updated_driver(kind, ns);
+ }
+ }
+ if (!dso) {
+ dso = load_system_driver(kind);
+ if (!dso)
+ return NULL;
+ }
+
if (mask & EGL) {
getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
ALOGE_IF(!getProcAddress,
- "can't find eglGetProcAddress() in %s", driver_absolute_path);
+ "can't find eglGetProcAddress() in EGL driver library");
egl_t* egl = &cnx->egl;
__eglMustCastToProperFunctionPointerType* curr =
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index 8cefe32764..04a8e413ad 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -25,6 +25,8 @@
#include <utils/Singleton.h>
#include <utils/String8.h>
+#include <gui/GraphicsEnv.h>
+
#include <EGL/egl.h>
// ----------------------------------------------------------------------------
@@ -53,7 +55,10 @@ class Loader : public Singleton<Loader>
};
getProcAddressType getProcAddress;
-
+
+ void* mLibGui;
+ decltype(android_getDriverNamespace)* mGetDriverNamespace;
+
public:
~Loader();
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index f41e6e2311..436ea30800 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -272,6 +272,7 @@ static inline EGLContext getContext() { return egl_tls_t::getContext(); }
EGLDisplay eglGetDisplay(EGLNativeDisplayType display)
{
+ ATRACE_CALL();
clearError();
uintptr_t index = reinterpret_cast<uintptr_t>(display);
@@ -1848,12 +1849,6 @@ EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
if (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID) {
usage |= GRALLOC_USAGE_HW_TEXTURE;
}
- // The buffer must be used for either a texture or a
- // renderbuffer.
- if ((value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID) &&
- (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)) {
- return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
- }
break;
default:
return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 1e39aae40d..acd70d19b4 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -15,6 +15,7 @@
*/
#define __STDC_LIMIT_MACROS 1
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <string.h>
@@ -26,6 +27,7 @@
#include "egl_tls.h"
#include "Loader.h"
#include <cutils/properties.h>
+#include <utils/Trace.h>
// ----------------------------------------------------------------------------
namespace android {
@@ -103,6 +105,7 @@ EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
Mutex::Autolock _l(lock);
+ ATRACE_CALL();
// get our driver loader
Loader& loader(Loader::getInstance());
diff --git a/opengl/specs/EGL_ANDROID_create_native_client_buffer.txt b/opengl/specs/EGL_ANDROID_create_native_client_buffer.txt
index a6fae80d7d..51c6c61782 100644
--- a/opengl/specs/EGL_ANDROID_create_native_client_buffer.txt
+++ b/opengl/specs/EGL_ANDROID_create_native_client_buffer.txt
@@ -124,12 +124,10 @@ Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors)
desirable) do not route the entire composition to the external sink.
EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID: The buffer will be
- used to create a renderbuffer. This flag must not be set if
- EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID is set.
+ used to create a color-renderable texture.
EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID: The buffer will be used to
- create a texture. This flag must not be set if
- EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID is set.
+ create a filterable texture.
Errors
@@ -149,11 +147,6 @@ Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors)
with the value of EGL_FORMAT, the error EGL_BAD_PARAMETER is
Generated.
- * If both the EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID and
- EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID are set in the value of
- EGL_NATIVE_BUFFER_USAGE_ANDROID, the error EGL_BAD_PARAMETER is
- Generated."
-
Issues
1. Should this extension define what combinations of formats and usage flags
diff --git a/services/sensorservice/BatteryService.cpp b/services/sensorservice/BatteryService.cpp
index 81f32cdc58..452c8c64b0 100644
--- a/services/sensorservice/BatteryService.cpp
+++ b/services/sensorservice/BatteryService.cpp
@@ -30,12 +30,7 @@
namespace android {
// ---------------------------------------------------------------------------
-BatteryService::BatteryService() {
- const sp<IServiceManager> sm(defaultServiceManager());
- if (sm != NULL) {
- const String16 name("batterystats");
- mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
- }
+BatteryService::BatteryService() : mBatteryStatService(nullptr) {
}
bool BatteryService::addSensor(uid_t uid, int handle) {
@@ -61,7 +56,7 @@ bool BatteryService::removeSensor(uid_t uid, int handle) {
void BatteryService::enableSensorImpl(uid_t uid, int handle) {
- if (mBatteryStatService != 0) {
+ if (checkService()) {
if (addSensor(uid, handle)) {
int64_t identity = IPCThreadState::self()->clearCallingIdentity();
mBatteryStatService->noteStartSensor(uid, handle);
@@ -70,7 +65,7 @@ void BatteryService::enableSensorImpl(uid_t uid, int handle) {
}
}
void BatteryService::disableSensorImpl(uid_t uid, int handle) {
- if (mBatteryStatService != 0) {
+ if (checkService()) {
if (removeSensor(uid, handle)) {
int64_t identity = IPCThreadState::self()->clearCallingIdentity();
mBatteryStatService->noteStopSensor(uid, handle);
@@ -80,7 +75,7 @@ void BatteryService::disableSensorImpl(uid_t uid, int handle) {
}
void BatteryService::cleanupImpl(uid_t uid) {
- if (mBatteryStatService != 0) {
+ if (checkService()) {
Mutex::Autolock _l(mActivationsLock);
int64_t identity = IPCThreadState::self()->clearCallingIdentity();
for (size_t i=0 ; i<mActivations.size() ; i++) {
@@ -95,6 +90,17 @@ void BatteryService::cleanupImpl(uid_t uid) {
}
}
+bool BatteryService::checkService() {
+ if (mBatteryStatService == nullptr) {
+ const sp<IServiceManager> sm(defaultServiceManager());
+ if (sm != NULL) {
+ const String16 name("batterystats");
+ mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
+ }
+ }
+ return mBatteryStatService != nullptr;
+}
+
ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
// ---------------------------------------------------------------------------
diff --git a/services/sensorservice/BatteryService.h b/services/sensorservice/BatteryService.h
index 08ba857518..43a750c6c2 100644
--- a/services/sensorservice/BatteryService.h
+++ b/services/sensorservice/BatteryService.h
@@ -49,6 +49,7 @@ class BatteryService : public Singleton<BatteryService> {
SortedVector<Info> mActivations;
bool addSensor(uid_t uid, int handle);
bool removeSensor(uid_t uid, int handle);
+ bool checkService();
public:
static void enableSensor(uid_t uid, int handle) {
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 614a9b11b9..99da2c4974 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -868,7 +868,7 @@ void SensorService::makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) co
}
}
-Vector<Sensor> SensorService::getSensorList(const String16& /* opPackageName */) {
+Vector<Sensor> SensorService::getSensorList(const String16& opPackageName) {
char value[PROPERTY_VALUE_MAX];
property_get("debug.sensors", value, "0");
const Vector<Sensor>& initialSensorList = (atoi(value)) ?
@@ -876,7 +876,14 @@ Vector<Sensor> SensorService::getSensorList(const String16& /* opPackageName */)
Vector<Sensor> accessibleSensorList;
for (size_t i = 0; i < initialSensorList.size(); i++) {
Sensor sensor = initialSensorList[i];
- accessibleSensorList.add(sensor);
+ if (canAccessSensor(sensor, "getSensorList", opPackageName)) {
+ accessibleSensorList.add(sensor);
+ } else {
+ ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
+ sensor.getName().string(),
+ sensor.getRequiredPermission().string(),
+ sensor.getRequiredAppOp());
+ }
}
makeUuidsIntoIdsForSensorList(accessibleSensorList);
return accessibleSensorList;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index dfece935b1..3ffa6554ad 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1364,6 +1364,7 @@ void Layer::pushPendingState() {
// Wake us up to check if the frame has been received
setTransactionFlags(eTransactionNeeded);
+ mFlinger->setTransactionFlags(eTraversalNeeded);
}
mPendingStates.push_back(mCurrentState);
}
diff --git a/vulkan/libvulkan/Android.mk b/vulkan/libvulkan/Android.mk
index d2e28ff665..b7d6791a4e 100644
--- a/vulkan/libvulkan/Android.mk
+++ b/vulkan/libvulkan/Android.mk
@@ -51,7 +51,7 @@ LOCAL_SRC_FILES := \
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_STATIC_LIBRARIES := libziparchive
-LOCAL_SHARED_LIBRARIES := libhardware libsync libbase liblog libutils libcutils libz
+LOCAL_SHARED_LIBRARIES := libgui libhardware libsync libbase liblog libutils libcutils libz
LOCAL_MODULE := libvulkan
include $(BUILD_SHARED_LIBRARY)
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 25552724d5..741a0ce15c 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -18,10 +18,15 @@
#include <string.h>
#include <algorithm>
#include <array>
+#include <dlfcn.h>
#include <new>
#include <malloc.h>
#include <sys/prctl.h>
+#include <android/dlext.h>
+#include <cutils/properties.h>
+#include <gui/GraphicsEnv.h>
+
#include "driver.h"
#include "stubhal.h"
@@ -123,17 +128,74 @@ class CreateInfoWrapper {
Hal Hal::hal_;
+void* LoadLibrary(const android_dlextinfo& dlextinfo,
+ const char* subname,
+ int subname_len) {
+ const char kLibFormat[] = "vulkan.%*s.so";
+ char* name = static_cast<char*>(
+ alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
+ sprintf(name, kLibFormat, subname_len, subname);
+ return android_dlopen_ext(name, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+}
+
+const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
+ "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID,
+ "ro.board.platform",
+}};
+
+int LoadUpdatedDriver(const hw_module_t** module) {
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE,
+ .library_namespace = android::GraphicsEnv::getInstance().getDriverNamespace(),
+ };
+ if (!dlextinfo.library_namespace)
+ return -ENOENT;
+
+ void* so = nullptr;
+ char prop[PROPERTY_VALUE_MAX];
+ for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
+ int prop_len = property_get(key, prop, nullptr);
+ if (prop_len > 0) {
+ so = LoadLibrary(dlextinfo, prop, prop_len);
+ if (so)
+ break;
+ }
+ }
+ if (!so)
+ return -ENOENT;
+
+ hw_module_t* hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
+ if (!hmi) {
+ ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
+ dlclose(so);
+ return -EINVAL;
+ }
+ if (strcmp(hmi->id, HWVULKAN_HARDWARE_MODULE_ID) != 0) {
+ ALOGE("HAL id '%s' != '%s'", hmi->id, HWVULKAN_HARDWARE_MODULE_ID);
+ dlclose(so);
+ return -EINVAL;
+ }
+ hmi->dso = so;
+ *module = hmi;
+ ALOGD("loaded updated driver");
+ return 0;
+}
+
bool Hal::Open() {
ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
// Use a stub device unless we successfully open a real HAL device.
hal_.dev_ = &stubhal::kDevice;
- const hwvulkan_module_t* module;
- int result =
- hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module));
+ int result;
+ const hwvulkan_module_t* module = nullptr;
+
+ result = LoadUpdatedDriver(reinterpret_cast<const hw_module_t**>(&module));
+ if (result == -ENOENT) {
+ result = hw_get_module(HWVULKAN_HARDWARE_MODULE_ID, reinterpret_cast<const hw_module_t**>(&module));
+ }
if (result != 0) {
- ALOGI("no Vulkan HAL present, using stub HAL");
+ ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
return true;
}
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index adc7d5cf1c..03d37fa895 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -719,6 +719,8 @@ void DestroySwapchainKHR(VkDevice device,
const VkAllocationCallbacks* allocator) {
const auto& dispatch = GetData(device).driver;
Swapchain* swapchain = SwapchainFromHandle(swapchain_handle);
+ if (!swapchain)
+ return;
bool active = swapchain->surface.swapchain_handle == swapchain_handle;
ANativeWindow* window = active ? swapchain->surface.window.get() : nullptr;