Merge "Revert "Delete HWC1""
diff --git a/Android.bp b/Android.bp
index f5620f8..086a2c6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -8,6 +8,7 @@
subdirs = [
"cmds/*",
"libs/*",
- "opengl/*",
+ "opengl",
"services/*",
+ "vulkan",
]
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index 44a994c..695e464 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -1,30 +1,100 @@
LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
+# ================#
+# Common settings #
+# ================#
+# ZipArchive support, the order matters here to get all symbols.
+COMMON_ZIP_LIBRARIES := libziparchive libz libcrypto_static
-ifdef BOARD_WLAN_DEVICE
-LOCAL_CFLAGS := -DFWDUMP_$(BOARD_WLAN_DEVICE)
-endif
-
-LOCAL_SRC_FILES := \
- dumpstate.cpp \
+# TODO: ideally the tests should depend on a shared dumpstate library, but currently libdumpstate
+# is used to define the device-specific HAL library. Instead, both dumpstate and dumpstate_test
+# shares a lot of common settings
+COMMON_LOCAL_CFLAGS := \
+ -Wall -Werror -Wno-missing-field-initializers -Wno-unused-variable -Wunused-parameter
+COMMON_SRC_FILES := \
utils.cpp
-
-LOCAL_MODULE := dumpstate
-
-LOCAL_SHARED_LIBRARIES := \
+COMMON_SHARED_LIBRARIES := \
libbase \
libcutils \
libhardware_legacy \
liblog \
libselinux
-# ZipArchive support, the order matters here to get all symbols.
-ZIP_LIBRARIES := libziparchive libz libcrypto_static
+# ==========#
+# dumpstate #
+# ==========#
+include $(CLEAR_VARS)
-LOCAL_STATIC_LIBRARIES := $(ZIP_LIBRARIES)
+ifdef BOARD_WLAN_DEVICE
+LOCAL_CFLAGS := -DFWDUMP_$(BOARD_WLAN_DEVICE)
+endif
+
+LOCAL_SRC_FILES := $(COMMON_SRC_FILES) \
+ dumpstate.cpp
+
+LOCAL_MODULE := dumpstate
+
+LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES)
+
+LOCAL_STATIC_LIBRARIES := $(COMMON_ZIP_LIBRARIES)
+
LOCAL_HAL_STATIC_LIBRARIES := libdumpstate
-LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
+
+LOCAL_CFLAGS += $(COMMON_LOCAL_CFLAGS)
+
LOCAL_INIT_RC := dumpstate.rc
include $(BUILD_EXECUTABLE)
+
+# ===============#
+# dumpstate_test #
+# ===============#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := dumpstate_test
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := $(COMMON_LOCAL_CFLAGS)
+
+LOCAL_SRC_FILES := $(COMMON_SRC_FILES) \
+ tests/dumpstate_test.cpp
+
+LOCAL_STATIC_LIBRARIES := $(COMMON_ZIP_LIBRARIES) \
+ libgmock
+
+LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES)
+
+include $(BUILD_NATIVE_TEST)
+
+# =======================#
+# dumpstate_test_fixture #
+# =======================#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := dumpstate_test_fixture
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := $(COMMON_LOCAL_CFLAGS)
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+LOCAL_SRC_FILES := \
+ tests/dumpstate_test_fixture.cpp
+
+dist_zip_root := $(TARGET_OUT_DATA)
+dumpstate_tests_subpath_from_data := nativetest/dumpstate_test_fixture
+dumpstate_tests_root_in_device := /data/$(dumpstate_tests_subpath_from_data)
+dumpstate_tests_root_for_test_zip := $(dist_zip_root)/$(dumpstate_tests_subpath_from_data)
+testdata_files := $(call find-subdir-files, testdata/*)
+
+GEN := $(addprefix $(dumpstate_tests_root_for_test_zip)/, $(testdata_files))
+$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
+$(GEN): PRIVATE_CUSTOM_TOOL = cp $< $@
+$(GEN): $(dumpstate_tests_root_for_test_zip)/testdata/% : $(LOCAL_PATH)/testdata/%
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+LOCAL_PICKUP_FILES := $(dist_zip_root)
+
+include $(BUILD_NATIVE_TEST)
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index f3e68b3..32dbf8d 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -52,8 +52,6 @@
#include <openssl/sha.h>
-using android::base::StringPrintf;
-
/* read before root is shed */
static char cmdline_buf[16384] = "(unknown)";
static const char *dump_traces_path = NULL;
@@ -62,7 +60,6 @@
static std::string args;
// TODO: variables below should be part of dumpstate object
-static std::string buildType;
static time_t now;
static std::unique_ptr<ZipWriter> zip_writer;
static std::set<std::string> mount_points;
@@ -127,14 +124,6 @@
static constexpr char PROPERTY_EXTRA_OPTIONS[] = "dumpstate.options";
static constexpr char PROPERTY_LAST_ID[] = "dumpstate.last_id";
-bool Dumpstate::IsUserBuild() {
- return "user" == buildType;
-}
-
-bool Dumpstate::IsDryRun() {
- return dryRun_;
-}
-
/* gets the tombstone data, according to the bugreport type: if zipped, gets all tombstones;
* otherwise, gets just those modified in the last half an hour. */
static void get_tombstone_fds(tombstone_data_t data[NUM_TOMBSTONES]) {
@@ -155,7 +144,7 @@
}
// for_each_pid() callback to get mount info about a process.
-void do_mountinfo(int pid, const char *name) {
+void do_mountinfo(int pid, const char* name __attribute__((unused))) {
char path[PATH_MAX];
// Gets the the content of the /proc/PID/ns/mnt link, so only unique mount points
@@ -426,7 +415,7 @@
return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */
}
-static bool skip_none(const char *path) {
+static bool skip_none(const char* path __attribute__((unused))) {
return false;
}
@@ -704,7 +693,6 @@
build = android::base::GetProperty("ro.build.display.id", "(unknown)");
fingerprint = android::base::GetProperty("ro.build.fingerprint", "(unknown)");
- buildType = android::base::GetProperty("ro.build.type", "(unknown)");
radio = android::base::GetProperty("gsm.version.baseband", "(unknown)");
bootloader = android::base::GetProperty("ro.bootloader", "(unknown)");
network = android::base::GetProperty("gsm.operator.alpha", "(unknown)");
@@ -727,7 +715,7 @@
printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
printf("Bugreport format version: %s\n", version.c_str());
printf("Dumpstate info: id=%lu pid=%d dryRun=%d args=%s extraOptions=%s\n", ds.id_, getpid(),
- ds.dryRun_, args.c_str(), extraOptions.c_str());
+ ds.IsDryRun(), args.c_str(), extraOptions.c_str());
printf("\n");
}
@@ -805,7 +793,7 @@
}
/* adds a file to the existing zipped bugreport */
-static int _add_file_from_fd(const char *title, const char *path, int fd) {
+static int _add_file_from_fd(const char* title __attribute__((unused)), const char* path, int fd) {
return add_zip_entry_from_fd(ZIP_ROOT_DIR + path, fd) ? 0 : 1;
}
@@ -853,15 +841,16 @@
static void dump_iptables() {
RunCommand("IPTABLES", {"iptables", "-L", "-nvx"});
RunCommand("IP6TABLES", {"ip6tables", "-L", "-nvx"});
- RunCommand("IPTABLE NAT", {"iptables", "-t", "nat", "-L", "-nvx"});
+ RunCommand("IPTABLES NAT", {"iptables", "-t", "nat", "-L", "-nvx"});
/* no ip6 nat */
- RunCommand("IPTABLE MANGLE", {"iptables", "-t", "mangle", "-L", "-nvx"});
- RunCommand("IP6TABLE MANGLE", {"ip6tables", "-t", "mangle", "-L", "-nvx"});
- RunCommand("IPTABLE RAW", {"iptables", "-t", "raw", "-L", "-nvx"});
- RunCommand("IP6TABLE RAW", {"ip6tables", "-t", "raw", "-L", "-nvx"});
+ RunCommand("IPTABLES MANGLE", {"iptables", "-t", "mangle", "-L", "-nvx"});
+ RunCommand("IP6TABLES MANGLE", {"ip6tables", "-t", "mangle", "-L", "-nvx"});
+ RunCommand("IPTABLES RAW", {"iptables", "-t", "raw", "-L", "-nvx"});
+ RunCommand("IP6TABLES RAW", {"ip6tables", "-t", "raw", "-L", "-nvx"});
}
-static void dumpstate(const std::string& screenshot_path, const std::string& version) {
+static void dumpstate(const std::string& screenshot_path,
+ const std::string& version __attribute__((unused))) {
DurationReporter durationReporter("DUMPSTATE");
unsigned long timeout;
@@ -1193,7 +1182,7 @@
}
}
-static void sig_handler(int signo) {
+static void sig_handler(int signo __attribute__((unused))) {
wake_lock_releaser();
_exit(EXIT_FAILURE);
}
@@ -1319,8 +1308,7 @@
register_sig_handler();
}
- ds.dryRun_ = android::base::GetBoolProperty("dumpstate.dry_run", false);
- if (ds.dryRun_) {
+ if (ds.IsDryRun()) {
MYLOGI("Running on dry-run mode (to disable it, call 'setprop dumpstate.dry_run false')\n");
}
@@ -1620,6 +1608,10 @@
add_mountinfo();
dump_iptables();
+ // Capture any IPSec policies in play. No keys are exposed here.
+ RunCommand("IP XFRM POLICY", {"ip", "xfrm", "policy"},
+ CommandOptions::WithTimeout(10).Build());
+
// Run ss as root so we can see socket marks.
RunCommand("DETAILED SOCKET STATE", {"ss", "-eionptu"}, CommandOptions::WithTimeout(10).Build());
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 70af270..adaf29e 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -37,9 +37,6 @@
#include <string>
#include <vector>
-// TODO: remove once dumpstate_board() devices use CommandOptions
-#define SU_PATH "/system/xbin/su"
-
// Workaround for const char *args[MAX_ARGS_ARRAY_SIZE] variables until they're converted to
// std::vector<std::string>
// TODO: remove once not used
@@ -202,6 +199,8 @@
* that are spread accross utils.cpp and dumpstate.cpp will be moved to it.
*/
class Dumpstate {
+ friend class DumpstateTest;
+
public:
static Dumpstate& GetInstance();
@@ -256,7 +255,13 @@
*/
int DumpFile(const std::string& title, const std::string& path);
- // TODO: fields below should be private once refactor is finished
+ // TODO: members below should be private once refactor is finished
+
+ /*
+ * Updates the overall progress of the bugreport generation by the given weight increment.
+ */
+ void UpdateProgress(int delta);
+
// TODO: initialize fields on constructor
// dumpstate id - unique after each device reboot.
@@ -274,15 +279,19 @@
// When set, defines a socket file-descriptor use to report progress to bugreportz.
int controlSocketFd_ = -1;
- // Whether this is a dry run.
- bool dryRun_;
// Full path of the directory where the bugreport files will be written;
std::string bugreportDir_;
private:
// Used by GetInstance() only.
- Dumpstate();
+ Dumpstate(bool dryRun = false, const std::string& buildType = "user");
+
+ // Whether this is a dry run.
+ bool dryRun_;
+
+ // Build type (such as 'user' or 'eng').
+ std::string buildType_;
};
// for_each_pid_func = void (*)(int, const char*);
@@ -323,9 +332,6 @@
/* sends a broadcast using Activity Manager */
void send_broadcast(const std::string& action, const std::vector<std::string>& args);
-/* updates the overall progress of dumpstate by the given weight increment */
-void update_progress(int weight);
-
/* prints all the system properties */
void print_properties();
diff --git a/cmds/dumpstate/testdata/multiple-lines-with-newline.txt b/cmds/dumpstate/testdata/multiple-lines-with-newline.txt
new file mode 100644
index 0000000..7b7a187
--- /dev/null
+++ b/cmds/dumpstate/testdata/multiple-lines-with-newline.txt
@@ -0,0 +1,3 @@
+I AM LINE1
+I AM LINE2
+I AM LINE3
diff --git a/cmds/dumpstate/testdata/multiple-lines.txt b/cmds/dumpstate/testdata/multiple-lines.txt
new file mode 100644
index 0000000..bead103
--- /dev/null
+++ b/cmds/dumpstate/testdata/multiple-lines.txt
@@ -0,0 +1,3 @@
+I AM LINE1
+I AM LINE2
+I AM LINE3
\ No newline at end of file
diff --git a/cmds/dumpstate/testdata/single-line-with-newline.txt b/cmds/dumpstate/testdata/single-line-with-newline.txt
new file mode 100644
index 0000000..cb48c82
--- /dev/null
+++ b/cmds/dumpstate/testdata/single-line-with-newline.txt
@@ -0,0 +1 @@
+I AM LINE1
diff --git a/cmds/dumpstate/testdata/single-line.txt b/cmds/dumpstate/testdata/single-line.txt
new file mode 100644
index 0000000..2f64046
--- /dev/null
+++ b/cmds/dumpstate/testdata/single-line.txt
@@ -0,0 +1 @@
+I AM LINE1
\ No newline at end of file
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
new file mode 100644
index 0000000..8d70704
--- /dev/null
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dumpstate.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <libgen.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <thread>
+
+#include <android-base/file.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+#define LOG_TAG "dumpstate"
+#include <cutils/log.h>
+
+using ::testing::EndsWith;
+using ::testing::IsEmpty;
+using ::testing::StrEq;
+using ::testing::StartsWith;
+using ::testing::Test;
+using ::testing::internal::CaptureStderr;
+using ::testing::internal::CaptureStdout;
+using ::testing::internal::GetCapturedStderr;
+using ::testing::internal::GetCapturedStdout;
+
+// Not used on test cases yet...
+void dumpstate_board(void) {
+}
+
+class DumpstateTest : public Test {
+ public:
+ void SetUp() {
+ SetDryRun(false);
+ SetBuildType(android::base::GetProperty("ro.build.type", "(unknown)"));
+ ds.updateProgress_ = false;
+ }
+
+ // Runs a command and capture `stdout` and `stderr`.
+ int RunCommand(const std::string& title, const std::vector<std::string>& fullCommand,
+ const CommandOptions& options = CommandOptions::DEFAULT) {
+ CaptureStdout();
+ CaptureStderr();
+ int status = ds.RunCommand(title, fullCommand, options);
+ out = GetCapturedStdout();
+ err = GetCapturedStderr();
+ return status;
+ }
+
+ // Dumps a file and capture `stdout` and `stderr`.
+ int DumpFile(const std::string& title, const std::string& path) {
+ CaptureStdout();
+ CaptureStderr();
+ int status = ds.DumpFile(title, path);
+ out = GetCapturedStdout();
+ err = GetCapturedStderr();
+ return status;
+ }
+
+ void SetDryRun(bool dryRun) {
+ ALOGD("Setting dryRun_ to %s\n", dryRun ? "true" : "false");
+ ds.dryRun_ = dryRun;
+ }
+
+ void SetBuildType(const std::string& buildType) {
+ ALOGD("Setting buildType_ to '%s'\n", buildType.c_str());
+ ds.buildType_ = buildType;
+ }
+
+ bool IsUserBuild() {
+ return "user" == android::base::GetProperty("ro.build.type", "(unknown)");
+ }
+
+ void DropRoot() {
+ drop_root_user();
+ uid_t uid = getuid();
+ ASSERT_EQ(2000, (int)uid);
+ }
+
+ // TODO: remove when progress is set by Binder callbacks.
+ void AssertSystemProperty(const std::string& key, const std::string& expectedValue) {
+ std::string actualValue = android::base::GetProperty(key, "not set");
+ EXPECT_THAT(expectedValue, StrEq(actualValue)) << "invalid value for property " << key;
+ }
+
+ std::string GetProgressMessage(int progress, int weightTotal, int oldWeightTotal = 0) {
+ EXPECT_EQ(progress, ds.progress_) << "invalid progress";
+ EXPECT_EQ(weightTotal, ds.weightTotal_) << "invalid weightTotal";
+
+ AssertSystemProperty(android::base::StringPrintf("dumpstate.%d.progress", getpid()),
+ std::to_string(progress));
+
+ bool maxIncreased = oldWeightTotal > 0;
+
+ std::string adjustmentMessage = "";
+ if (maxIncreased) {
+ AssertSystemProperty(android::base::StringPrintf("dumpstate.%d.max", getpid()),
+ std::to_string(weightTotal));
+ adjustmentMessage = android::base::StringPrintf(
+ "Adjusting total weight from %d to %d\n", oldWeightTotal, weightTotal);
+ }
+
+ return android::base::StringPrintf("%sSetting progress (dumpstate.%d.progress): %d/%d\n",
+ adjustmentMessage.c_str(), getpid(), progress,
+ weightTotal);
+ }
+
+ // `stdout` and `stderr` from the last command ran.
+ std::string out, err;
+
+ std::string testPath = dirname(android::base::GetExecutablePath().c_str());
+ std::string fixturesPath = testPath + "/../dumpstate_test_fixture/";
+ std::string testDataPath = fixturesPath + "/testdata/";
+ std::string simpleCommand = fixturesPath + "dumpstate_test_fixture";
+ std::string echoCommand = "/system/bin/echo";
+
+ Dumpstate& ds = Dumpstate::GetInstance();
+};
+
+TEST_F(DumpstateTest, RunCommandNoArgs) {
+ EXPECT_EQ(-1, RunCommand("", {}));
+}
+
+TEST_F(DumpstateTest, RunCommandNoTitle) {
+ EXPECT_EQ(0, RunCommand("", {simpleCommand}));
+ EXPECT_THAT(out, StrEq("stdout\n"));
+ EXPECT_THAT(err, StrEq("stderr\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandWithTitle) {
+ EXPECT_EQ(0, RunCommand("I AM GROOT", {simpleCommand}));
+ EXPECT_THAT(err, StrEq("stderr\n"));
+ // We don't know the exact duration, so we check the prefix and suffix
+ EXPECT_THAT(out,
+ StartsWith("------ I AM GROOT (" + simpleCommand + ") ------\nstdout\n------"));
+ EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandWithLoggingMessage) {
+ EXPECT_EQ(
+ 0, RunCommand("", {simpleCommand},
+ CommandOptions::WithTimeout(10).Log("COMMAND, Y U NO LOG FIRST?").Build()));
+ EXPECT_THAT(out, StrEq("stdout\n"));
+ EXPECT_THAT(err, StrEq("COMMAND, Y U NO LOG FIRST?stderr\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandRedirectStderr) {
+ EXPECT_EQ(0, RunCommand("", {simpleCommand},
+ CommandOptions::WithTimeout(10).RedirectStderr().Build()));
+ EXPECT_THAT(out, IsEmpty());
+ EXPECT_THAT(err, StrEq("stdout\nstderr\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandWithOneArg) {
+ EXPECT_EQ(0, RunCommand("", {echoCommand, "one"}));
+ EXPECT_THAT(err, IsEmpty());
+ EXPECT_THAT(out, StrEq("one\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandWithMultipleArgs) {
+ EXPECT_EQ(0, RunCommand("", {echoCommand, "one", "is", "the", "loniest", "number"}));
+ EXPECT_THAT(err, IsEmpty());
+ EXPECT_THAT(out, StrEq("one is the loniest number\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandDryRun) {
+ SetDryRun(true);
+ EXPECT_EQ(0, RunCommand("I AM GROOT", {simpleCommand}));
+ // We don't know the exact duration, so we check the prefix and suffix
+ EXPECT_THAT(out, StartsWith("------ I AM GROOT (" + simpleCommand +
+ ") ------\n\t(skipped on dry run)\n------"));
+ EXPECT_THAT(out, EndsWith("s was the duration of 'I AM GROOT' ------\n"));
+ EXPECT_THAT(err, IsEmpty());
+}
+
+TEST_F(DumpstateTest, RunCommandDryRunNoTitle) {
+ SetDryRun(true);
+ EXPECT_EQ(0, RunCommand("", {simpleCommand}));
+ EXPECT_THAT(out, IsEmpty());
+ EXPECT_THAT(err, IsEmpty());
+}
+
+TEST_F(DumpstateTest, RunCommandDryRunAlways) {
+ SetDryRun(true);
+ EXPECT_EQ(0, RunCommand("", {simpleCommand}, CommandOptions::WithTimeout(10).Always().Build()));
+ EXPECT_THAT(out, StrEq("stdout\n"));
+ EXPECT_THAT(err, StrEq("stderr\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandNotFound) {
+ EXPECT_NE(0, RunCommand("", {"/there/cannot/be/such/command"}));
+ EXPECT_THAT(out, StartsWith("*** command '/there/cannot/be/such/command' failed: exit code"));
+ EXPECT_THAT(err, StartsWith("execvp on command '/there/cannot/be/such/command' failed"));
+}
+
+TEST_F(DumpstateTest, RunCommandFails) {
+ EXPECT_EQ(42, RunCommand("", {simpleCommand, "--exit", "42"}));
+ EXPECT_THAT(
+ out, StrEq("stdout\n*** command '" + simpleCommand + " --exit 42' failed: exit code 42\n"));
+ EXPECT_THAT(
+ err, StrEq("stderr\n*** command '" + simpleCommand + " --exit 42' failed: exit code 42\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandCrashes) {
+ EXPECT_NE(0, RunCommand("", {simpleCommand, "--crash"}));
+ // We don't know the exit code, so check just the prefix.
+ EXPECT_THAT(
+ out, StartsWith("stdout\n*** command '" + simpleCommand + " --crash' failed: exit code"));
+ EXPECT_THAT(
+ err, StartsWith("stderr\n*** command '" + simpleCommand + " --crash' failed: exit code"));
+}
+
+TEST_F(DumpstateTest, RunCommandTimesout) {
+ EXPECT_EQ(-1, RunCommand("", {simpleCommand, "--sleep", "2"},
+ CommandOptions::WithTimeout(1).Build()));
+ EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + simpleCommand +
+ " --sleep 2' timed out after 1"));
+ EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + simpleCommand +
+ " --sleep 2' timed out after 1"));
+}
+
+TEST_F(DumpstateTest, RunCommandIsKilled) {
+ CaptureStdout();
+ CaptureStderr();
+
+ std::thread t([=]() {
+ EXPECT_EQ(SIGTERM, ds.RunCommand("", {simpleCommand, "--pid", "--sleep", "20"},
+ CommandOptions::WithTimeout(100).Always().Build()));
+ });
+
+ // Capture pid and pre-sleep output.
+ sleep(1); // Wait a little bit to make sure pid and 1st line were printed.
+ std::string err = GetCapturedStderr();
+ EXPECT_THAT(err, StrEq("sleeping for 20s\n"));
+
+ std::string out = GetCapturedStdout();
+ std::vector<std::string> lines = android::base::Split(out, "\n");
+ ASSERT_EQ(3, (int)lines.size()) << "Invalid lines before sleep: " << out;
+
+ int pid = atoi(lines[0].c_str());
+ EXPECT_THAT(lines[1], StrEq("stdout line1"));
+ EXPECT_THAT(lines[2], IsEmpty()); // \n
+
+ // Then kill the process.
+ CaptureStdout();
+ CaptureStderr();
+ ASSERT_EQ(0, kill(pid, SIGTERM)) << "failed to kill pid " << pid;
+ t.join();
+
+ // Finally, check output after murder.
+ out = GetCapturedStdout();
+ err = GetCapturedStderr();
+
+ EXPECT_THAT(out, StrEq("*** command '" + simpleCommand +
+ " --pid --sleep 20' failed: killed by signal 15\n"));
+ EXPECT_THAT(err, StrEq("*** command '" + simpleCommand +
+ " --pid --sleep 20' failed: killed by signal 15\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandProgress) {
+ ds.updateProgress_ = true;
+ ds.progress_ = 0;
+ ds.weightTotal_ = 30;
+
+ EXPECT_EQ(0, RunCommand("", {simpleCommand}, CommandOptions::WithTimeout(20).Build()));
+ std::string progressMessage = GetProgressMessage(20, 30);
+ EXPECT_THAT(out, StrEq("stdout\n"));
+ EXPECT_THAT(err, StrEq("stderr\n" + progressMessage));
+
+ EXPECT_EQ(0, RunCommand("", {simpleCommand}, CommandOptions::WithTimeout(10).Build()));
+ progressMessage = GetProgressMessage(30, 30);
+ EXPECT_THAT(out, StrEq("stdout\n"));
+ EXPECT_THAT(err, StrEq("stderr\n" + progressMessage));
+
+ // Run a command that will increase maximum timeout.
+ EXPECT_EQ(0, RunCommand("", {simpleCommand}, CommandOptions::WithTimeout(1).Build()));
+ progressMessage = GetProgressMessage(31, 36, 30); // 20% increase
+ EXPECT_THAT(out, StrEq("stdout\n"));
+ EXPECT_THAT(err, StrEq("stderr\n" + progressMessage));
+
+ // Make sure command ran while in dryRun is counted.
+ SetDryRun(true);
+ EXPECT_EQ(0, RunCommand("", {simpleCommand}, CommandOptions::WithTimeout(4).Build()));
+ progressMessage = GetProgressMessage(35, 36);
+ EXPECT_THAT(out, IsEmpty());
+ EXPECT_THAT(err, StrEq(progressMessage));
+}
+
+TEST_F(DumpstateTest, RunCommandDropRoot) {
+ // First check root case - only available when running with 'adb root'.
+ uid_t uid = getuid();
+ if (uid == 0) {
+ EXPECT_EQ(0, RunCommand("", {simpleCommand, "--uid"}));
+ EXPECT_THAT(out, StrEq("0\nstdout\n"));
+ EXPECT_THAT(err, StrEq("stderr\n"));
+ return;
+ }
+ // Then drop root.
+
+ EXPECT_EQ(0, RunCommand("", {simpleCommand, "--uid"},
+ CommandOptions::WithTimeout(1).DropRoot().Build()));
+ EXPECT_THAT(out, StrEq("2000\nstdout\n"));
+ EXPECT_THAT(err, StrEq("drop_root_user(): already running as Shell\nstderr\n"));
+}
+
+TEST_F(DumpstateTest, RunCommandAsRootUserBuild) {
+ if (!IsUserBuild()) {
+ // Emulates user build if necessarily.
+ SetBuildType("user");
+ }
+
+ DropRoot();
+
+ EXPECT_EQ(0, RunCommand("", {simpleCommand}, CommandOptions::WithTimeout(1).AsRoot().Build()));
+
+ // We don't know the exact path of su, so we just check for the 'root ...' commands
+ EXPECT_THAT(out, StartsWith("Skipping"));
+ EXPECT_THAT(out, EndsWith("root " + simpleCommand + "' on user build.\n"));
+ EXPECT_THAT(err, IsEmpty());
+}
+
+TEST_F(DumpstateTest, RunCommandAsRootNonUserBuild) {
+ if (IsUserBuild()) {
+ ALOGI("Skipping RunCommandAsRootNonUserBuild on user builds\n");
+ return;
+ }
+
+ DropRoot();
+
+ EXPECT_EQ(0, RunCommand("", {simpleCommand, "--uid"},
+ CommandOptions::WithTimeout(1).AsRoot().Build()));
+
+ EXPECT_THAT(out, StrEq("0\nstdout\n"));
+ EXPECT_THAT(err, StrEq("stderr\n"));
+}
+
+TEST_F(DumpstateTest, DumpFileNotFoundNoTitle) {
+ EXPECT_EQ(-1, DumpFile("", "/I/cant/believe/I/exist"));
+ EXPECT_THAT(out,
+ StrEq("*** Error dumping /I/cant/believe/I/exist: No such file or directory\n"));
+ EXPECT_THAT(err, IsEmpty());
+}
+
+TEST_F(DumpstateTest, DumpFileNotFoundWithTitle) {
+ EXPECT_EQ(-1, DumpFile("Y U NO EXIST?", "/I/cant/believe/I/exist"));
+ EXPECT_THAT(err, IsEmpty());
+ // We don't know the exact duration, so we check the prefix and suffix
+ EXPECT_THAT(out, StartsWith("*** Error dumping /I/cant/believe/I/exist (Y U NO EXIST?): No "
+ "such file or directory\n"));
+ EXPECT_THAT(out, EndsWith("s was the duration of 'Y U NO EXIST?' ------\n"));
+}
+
+TEST_F(DumpstateTest, DumpFileSingleLine) {
+ EXPECT_EQ(0, DumpFile("", testDataPath + "single-line.txt"));
+ EXPECT_THAT(err, IsEmpty());
+ EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
+}
+
+TEST_F(DumpstateTest, DumpFileSingleLineWithNewLine) {
+ EXPECT_EQ(0, DumpFile("", testDataPath + "single-line-with-newline.txt"));
+ EXPECT_THAT(err, IsEmpty());
+ EXPECT_THAT(out, StrEq("I AM LINE1\n"));
+}
+
+TEST_F(DumpstateTest, DumpFileMultipleLines) {
+ EXPECT_EQ(0, DumpFile("", testDataPath + "multiple-lines.txt"));
+ EXPECT_THAT(err, IsEmpty());
+ EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
+}
+
+TEST_F(DumpstateTest, DumpFileMultipleLinesWithNewLine) {
+ EXPECT_EQ(0, DumpFile("", testDataPath + "multiple-lines-with-newline.txt"));
+ EXPECT_THAT(err, IsEmpty());
+ EXPECT_THAT(out, StrEq("I AM LINE1\nI AM LINE2\nI AM LINE3\n"));
+}
+
+TEST_F(DumpstateTest, DumpFileOnDryRunNoTitle) {
+ SetDryRun(true);
+ EXPECT_EQ(0, DumpFile("", testDataPath + "single-line.txt"));
+ EXPECT_THAT(err, IsEmpty());
+ EXPECT_THAT(out, IsEmpty());
+}
+
+TEST_F(DumpstateTest, DumpFileOnDryRun) {
+ SetDryRun(true);
+ EXPECT_EQ(0, DumpFile("Might as well dump. Dump!", testDataPath + "single-line.txt"));
+ EXPECT_THAT(err, IsEmpty());
+ EXPECT_THAT(out, StartsWith("------ Might as well dump. Dump! (" + testDataPath +
+ "single-line.txt) ------\n\t(skipped on dry run)\n------"));
+ EXPECT_THAT(out, EndsWith("s was the duration of 'Might as well dump. Dump!' ------\n"));
+ EXPECT_THAT(err, IsEmpty());
+}
+
+TEST_F(DumpstateTest, DumpFileUpdateProgress) {
+ ds.updateProgress_ = true;
+ ds.progress_ = 0;
+ ds.weightTotal_ = 30;
+
+ EXPECT_EQ(0, DumpFile("", testDataPath + "single-line.txt"));
+
+ std::string progressMessage = GetProgressMessage(5, 30); // TODO: unhardcode WEIGHT_FILE (5)?
+
+ EXPECT_THAT(err, StrEq(progressMessage));
+ EXPECT_THAT(out, StrEq("I AM LINE1\n")); // dumpstate adds missing newline
+}
diff --git a/cmds/dumpstate/tests/dumpstate_test_fixture.cpp b/cmds/dumpstate/tests/dumpstate_test_fixture.cpp
new file mode 100644
index 0000000..5be4719
--- /dev/null
+++ b/cmds/dumpstate/tests/dumpstate_test_fixture.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define LOG_TAG "dumpstate"
+#include <cutils/log.h>
+
+void PrintDefaultOutput() {
+ fprintf(stdout, "stdout\n");
+ fflush(stdout);
+ fprintf(stderr, "stderr\n");
+ fflush(stderr);
+}
+
+/*
+ * Binary used to on RunCommand tests.
+ *
+ * Usage:
+ *
+ * - Unless stated otherwise this command:
+ *
+ * 1.Prints `stdout\n` on `stdout` and flushes it.
+ * 2.Prints `stderr\n` on `stderr` and flushes it.
+ * 3.Exit with status 0.
+ *
+ * - If 1st argument is '--pid', it first prints its pid on `stdout`.
+ *
+ * - If 1st argument is '--uid', it first prints its uid on `stdout`.
+ *
+ * - If 1st argument is '--crash', it uses ALOGF to crash and returns 666.
+ *
+ * - With argument '--exit' 'CODE', returns CODE;
+ *
+ * - With argument '--sleep 'TIME':
+ *
+ * 1.Prints `stdout line1\n` on `stdout` and `sleeping TIME s\n` on `stderr`
+ * 2.Sleeps for TIME s
+ * 3.Prints `stdout line2\n` on `stdout` and `woke up\n` on `stderr`
+ */
+int main(int argc, char* const argv[]) {
+ if (argc == 2) {
+ if (strcmp(argv[1], "--crash") == 0) {
+ PrintDefaultOutput();
+ LOG_FATAL("D'OH\n");
+ return 666;
+ }
+ }
+ if (argc == 3) {
+ if (strcmp(argv[1], "--exit") == 0) {
+ PrintDefaultOutput();
+ return atoi(argv[2]);
+ }
+ }
+
+ if (argc > 1) {
+ int index = 1;
+
+ // First check arguments that can shift the index.
+ if (strcmp(argv[1], "--pid") == 0) {
+ index++;
+ fprintf(stdout, "%d\n", getpid());
+ fflush(stdout);
+ } else if (strcmp(argv[1], "--uid") == 0) {
+ index++;
+ fprintf(stdout, "%d\n", getuid());
+ fflush(stdout);
+ }
+
+ // Then the "common" arguments, if any.
+ if (argc > index + 1) {
+ if (strcmp(argv[index], "--sleep") == 0) {
+ int napTime = atoi(argv[index + 1]);
+ fprintf(stdout, "stdout line1\n");
+ fflush(stdout);
+ fprintf(stderr, "sleeping for %ds\n", napTime);
+ fflush(stderr);
+ sleep(napTime);
+ fprintf(stdout, "stdout line2\n");
+ fflush(stdout);
+ fprintf(stderr, "woke up\n");
+ fflush(stderr);
+ return 0;
+ }
+ }
+ }
+
+ PrintDefaultOutput();
+ return 0;
+}
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index e29d90d..fc1f721 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -50,6 +50,8 @@
#include "dumpstate.h"
+#define SU_PATH "/system/xbin/su"
+
static const int64_t NANOS_PER_SEC = 1000000000;
static const int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
@@ -60,6 +62,12 @@
const CommandOptions& options = CommandOptions::DEFAULT) {
return ds.RunCommand(title, fullCommand, options);
}
+static bool IsDryRun() {
+ return Dumpstate::GetInstance().IsDryRun();
+}
+static void UpdateProgress(int delta) {
+ ds.UpdateProgress(delta);
+}
/* list of native processes to include in the native dumps */
// This matches the /proc/pid/exe link instead of /proc/pid/cmdline.
@@ -154,11 +162,13 @@
return CommandOptions::CommandOptionsBuilder(timeout);
}
-Dumpstate::Dumpstate() {
+Dumpstate::Dumpstate(bool dryRun, const std::string& buildType)
+ : dryRun_(dryRun), buildType_(buildType) {
}
Dumpstate& Dumpstate::GetInstance() {
- static Dumpstate sSingleton;
+ static Dumpstate sSingleton(android::base::GetBoolProperty("dumpstate.dry_run", false),
+ android::base::GetProperty("ro.build.type", "(unknown)"));
return sSingleton;
}
@@ -190,13 +200,16 @@
return (uint64_t) ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
}
-// TODO: temporary function used during the C++ refactoring
-static bool is_dry_run() {
- return Dumpstate::GetInstance().IsDryRun();
+bool Dumpstate::IsDryRun() {
+ return dryRun_;
+}
+
+bool Dumpstate::IsUserBuild() {
+ return "user" == buildType_;
}
void for_each_userid(void (*func)(int), const char *header) {
- if (is_dry_run()) return;
+ if (IsDryRun()) return;
DIR *d;
struct dirent *de;
@@ -279,7 +292,7 @@
}
void for_each_pid(for_each_pid_func func, const char *header) {
- if (is_dry_run()) return;
+ if (IsDryRun()) return;
__for_each_pid(for_each_pid_helper, header, (void *) func);
}
@@ -333,13 +346,13 @@
}
void for_each_tid(for_each_tid_func func, const char *header) {
- if (is_dry_run()) return;
+ if (IsDryRun()) return;
__for_each_pid(for_each_tid_helper, header, (void *) func);
}
void show_wchan(int pid, int tid, const char *name) {
- if (is_dry_run()) return;
+ if (IsDryRun()) return;
char path[255];
char buffer[255];
@@ -406,7 +419,7 @@
}
void show_showtime(int pid, const char *name) {
- if (is_dry_run()) return;
+ if (IsDryRun()) return;
char path[255];
char buffer[1023];
@@ -474,7 +487,7 @@
DurationReporter duration_reporter(title);
printf("------ %s ------\n", title);
- if (is_dry_run()) return;
+ if (IsDryRun()) return;
/* Get size of kernel buffer */
int size = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
@@ -526,8 +539,8 @@
}
printf(") ------\n");
}
- if (is_dry_run()) {
- update_progress(WEIGHT_FILE);
+ if (IsDryRun()) {
+ UpdateProgress(WEIGHT_FILE);
close(fd);
return 0;
}
@@ -568,7 +581,7 @@
}
}
}
- update_progress(WEIGHT_FILE);
+ UpdateProgress(WEIGHT_FILE);
close(fd);
if (!newline) printf("\n");
@@ -578,11 +591,23 @@
int Dumpstate::DumpFile(const std::string& title, const std::string& path) {
DurationReporter durationReporter(title);
+ if (IsDryRun()) {
+ if (!title.empty()) {
+ printf("------ %s (%s) ------\n", title.c_str(), path.c_str());
+ printf("\t(skipped on dry run)\n");
+ }
+ UpdateProgress(WEIGHT_FILE);
+ return 0;
+ }
+
int fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC));
if (fd < 0) {
int err = errno;
- printf("*** %s: %s\n", path.c_str(), strerror(err));
- if (!title.empty()) printf("\n");
+ if (title.empty()) {
+ printf("*** Error dumping %s: %s\n", path.c_str(), strerror(err));
+ } else {
+ printf("*** Error dumping %s (%s): %s\n", path.c_str(), title.c_str(), strerror(err));
+ }
return -1;
}
return _dump_file_from_fd(title, path.c_str(), fd);
@@ -627,7 +652,7 @@
if (!title.empty()) {
printf("------ %s (%s) ------\n", title.c_str(), dir);
}
- if (is_dry_run()) return 0;
+ if (IsDryRun()) return 0;
if (dir[strlen(dir) - 1] == '/') {
++slash;
@@ -684,7 +709,7 @@
* stuck.
*/
int dump_file_from_fd(const char *title, const char *path, int fd) {
- if (is_dry_run()) return 0;
+ if (IsDryRun()) return 0;
int flags = fcntl(fd, F_GETFL);
if (flags == -1) {
@@ -796,8 +821,11 @@
MYLOGI(loggingMessage.c_str(), commandString.c_str());
}
- if (is_dry_run() && !options.Always()) {
- update_progress(options.Timeout());
+ if (IsDryRun() && !options.Always()) {
+ if (!title.empty()) {
+ printf("\t(skipped on dry run)\n");
+ }
+ UpdateProgress(options.Timeout());
return 0;
}
@@ -861,7 +889,7 @@
if (!silent)
printf("*** command '%s' timed out after %.3fs (killing pid %d)\n", command,
(float)elapsed / NANOS_PER_SEC, pid);
- MYLOGE("command '%s' timed out after %.3fs (killing pid %d)\n", command,
+ MYLOGE("*** command '%s' timed out after %.3fs (killing pid %d)\n", command,
(float)elapsed / NANOS_PER_SEC, pid);
} else {
if (!silent)
@@ -871,9 +899,9 @@
(float)elapsed / NANOS_PER_SEC, pid);
}
kill(pid, SIGTERM);
- if (!waitpid_with_timeout(pid, 5, NULL)) {
+ if (!waitpid_with_timeout(pid, 5, nullptr)) {
kill(pid, SIGKILL);
- if (!waitpid_with_timeout(pid, 5, NULL)) {
+ if (!waitpid_with_timeout(pid, 5, nullptr)) {
if (!silent)
printf("could not kill command '%s' (pid %d) even with SIGKILL.\n", command,
pid);
@@ -884,15 +912,17 @@
}
if (WIFSIGNALED(status)) {
- if (!silent) printf("*** %s: Killed by signal %d\n", command, WTERMSIG(status));
- MYLOGE("*** %s: Killed by signal %d\n", command, WTERMSIG(status));
+ if (!silent)
+ printf("*** command '%s' failed: killed by signal %d\n", command, WTERMSIG(status));
+ MYLOGE("*** command '%s' failed: killed by signal %d\n", command, WTERMSIG(status));
} else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
- if (!silent) printf("*** %s: Exit code %d\n", command, WEXITSTATUS(status));
- MYLOGE("*** %s: Exit code %d\n", command, WEXITSTATUS(status));
+ status = WEXITSTATUS(status);
+ if (!silent) printf("*** command '%s' failed: exit code %d\n", command, status);
+ MYLOGE("*** command '%s' failed: exit code %d\n", command, status);
}
if (weight > 0) {
- update_progress(weight);
+ UpdateProgress(weight);
}
return status;
}
@@ -907,7 +937,7 @@
bool drop_root_user() {
if (getgid() == AID_SHELL && getuid() == AID_SHELL) {
- MYLOGD("drop_root_user(): already running as Shell");
+ MYLOGD("drop_root_user(): already running as Shell\n");
return true;
}
/* ensure we will keep capabilities when we drop root */
@@ -988,7 +1018,7 @@
const char* title = "SYSTEM PROPERTIES";
DurationReporter duration_reporter(title);
printf("------ %s ------\n", title);
- if (is_dry_run()) return;
+ if (IsDryRun()) return;
size_t i;
num_props = 0;
property_list(print_prop, NULL);
@@ -1094,7 +1124,7 @@
/* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
const char *dump_traces() {
DurationReporter duration_reporter("DUMP TRACES", nullptr);
- if (is_dry_run()) return nullptr;
+ if (IsDryRun()) return nullptr;
const char* result = nullptr;
@@ -1246,7 +1276,7 @@
void dump_route_tables() {
DurationReporter duration_reporter("DUMP ROUTE TABLES");
- if (is_dry_run()) return;
+ if (IsDryRun()) return;
const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables";
ds.DumpFile("RT_TABLES", RT_TABLES_PATH);
FILE* fp = fopen(RT_TABLES_PATH, "re");
@@ -1266,21 +1296,21 @@
}
// TODO: make this function thread safe if sections are generated in parallel.
-void update_progress(int delta) {
- if (!ds.updateProgress_) return;
+void Dumpstate::UpdateProgress(int delta) {
+ if (!updateProgress_) return;
- ds.progress_ += delta;
+ progress_ += delta;
char key[PROPERTY_KEY_MAX];
char value[PROPERTY_VALUE_MAX];
// adjusts max on the fly
- if (ds.progress_ > ds.weightTotal_) {
- int newTotal = ds.weightTotal_ * 1.2;
- MYLOGD("Adjusting total weight from %d to %d\n", ds.weightTotal_, newTotal);
- ds.weightTotal_ = newTotal;
+ if (progress_ > weightTotal_) {
+ int newTotal = weightTotal_ * 1.2;
+ MYLOGD("Adjusting total weight from %d to %d\n", weightTotal_, newTotal);
+ weightTotal_ = newTotal;
snprintf(key, sizeof(key), "dumpstate.%d.max", getpid());
- snprintf(value, sizeof(value), "%d", ds.weightTotal_);
+ snprintf(value, sizeof(value), "%d", weightTotal_);
int status = property_set(key, value);
if (status != 0) {
MYLOGE("Could not update max weight by setting system property %s to %s: %d\n",
@@ -1289,20 +1319,20 @@
}
snprintf(key, sizeof(key), "dumpstate.%d.progress", getpid());
- snprintf(value, sizeof(value), "%d", ds.progress_);
+ snprintf(value, sizeof(value), "%d", progress_);
- if (ds.progress_ % 100 == 0) {
+ if (progress_ % 100 == 0) {
// We don't want to spam logcat, so only log multiples of 100.
- MYLOGD("Setting progress (%s): %s/%d\n", key, value, ds.weightTotal_);
+ MYLOGD("Setting progress (%s): %s/%d\n", key, value, weightTotal_);
} else {
// stderr is ignored on normal invocations, but useful when calling /system/bin/dumpstate
// directly for debuggging.
- fprintf(stderr, "Setting progress (%s): %s/%d\n", key, value, ds.weightTotal_);
+ fprintf(stderr, "Setting progress (%s): %s/%d\n", key, value, weightTotal_);
}
- if (ds.controlSocketFd_ >= 0) {
- dprintf(ds.controlSocketFd_, "PROGRESS:%d/%d\n", ds.progress_, ds.weightTotal_);
- fsync(ds.controlSocketFd_);
+ if (controlSocketFd_ >= 0) {
+ dprintf(controlSocketFd_, "PROGRESS:%d/%d\n", progress_, weightTotal_);
+ fsync(controlSocketFd_);
}
int status = property_set(key, value);
diff --git a/cmds/surfacereplayer/replayer/Android.mk b/cmds/surfacereplayer/replayer/Android.mk
index 28d4481..dac4314 100644
--- a/cmds/surfacereplayer/replayer/Android.mk
+++ b/cmds/surfacereplayer/replayer/Android.mk
@@ -35,6 +35,7 @@
libEGL \
libGLESv2 \
libbinder \
+ liblog \
libcutils \
libgui \
libui \
diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h
index 3ab63d0..5232d0f 100644
--- a/include/gui/BufferItem.h
+++ b/include/gui/BufferItem.h
@@ -74,13 +74,7 @@
// to set by queueBuffer each time this slot is queued. This value
// is guaranteed to be monotonically increasing for each newly
// acquired buffer.
- union {
- int64_t mTimestamp;
- struct {
- uint32_t mTimestampLo;
- uint32_t mTimestampHi;
- };
- };
+ int64_t mTimestamp;
// mIsAutoTimestamp indicates whether mTimestamp was generated
// automatically when the buffer was queued.
@@ -92,13 +86,7 @@
android_dataspace mDataSpace;
// mFrameNumber is the number of the queued frame for this slot.
- union {
- uint64_t mFrameNumber;
- struct {
- uint32_t mFrameNumberLo;
- uint32_t mFrameNumberHi;
- };
- };
+ uint64_t mFrameNumber;
// mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
int mSlot;
diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h
index 15b7dbe..b1c730a 100644
--- a/include/gui/BufferQueueCore.h
+++ b/include/gui/BufferQueueCore.h
@@ -185,8 +185,12 @@
// PID of the process which last successfully called connect(...)
pid_t mConnectedPid;
- // mConnectedProducerToken is used to set a binder death notification on
+ // mLinkedToDeath is used to set a binder death notification on
// the producer.
+ sp<IProducerListener> mLinkedToDeath;
+
+ // mConnectedProducerListener is used to handle the onBufferReleased
+ // notification.
sp<IProducerListener> mConnectedProducerListener;
// mSlots is an array of buffer slots that must be mirrored on the producer
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index b3291f4..65dea0d 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -22,7 +22,7 @@
namespace android {
-class BufferSlot;
+struct BufferSlot;
class BufferQueueProducer : public BnGraphicBufferProducer,
private IBinder::DeathRecipient {
diff --git a/include/gui/IProducerListener.h b/include/gui/IProducerListener.h
index 4a5ed46..e808bd3 100644
--- a/include/gui/IProducerListener.h
+++ b/include/gui/IProducerListener.h
@@ -41,6 +41,7 @@
// This is called without any lock held and can be called concurrently by
// multiple threads.
virtual void onBufferReleased() = 0; // Asynchronous
+ virtual bool needsReleaseNotify() = 0;
};
class IProducerListener : public ProducerListener, public IInterface
@@ -54,6 +55,7 @@
public:
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0);
+ virtual bool needsReleaseNotify();
};
class DummyProducerListener : public BnProducerListener
@@ -61,6 +63,7 @@
public:
virtual ~DummyProducerListener();
virtual void onBufferReleased() {}
+ virtual bool needsReleaseNotify() { return false; }
};
} // namespace android
diff --git a/include/gui/OccupancyTracker.h b/include/gui/OccupancyTracker.h
index 1d15e7f..d4de8f2 100644
--- a/include/gui/OccupancyTracker.h
+++ b/include/gui/OccupancyTracker.h
@@ -45,12 +45,12 @@
occupancyAverage(0.0f),
usedThirdBuffer(false) {}
- Segment(nsecs_t totalTime, size_t numFrames, float occupancyAverage,
- bool usedThirdBuffer)
- : totalTime(totalTime),
- numFrames(numFrames),
- occupancyAverage(occupancyAverage),
- usedThirdBuffer(usedThirdBuffer) {}
+ Segment(nsecs_t _totalTime, size_t _numFrames, float _occupancyAverage,
+ bool _usedThirdBuffer)
+ : totalTime(_totalTime),
+ numFrames(_numFrames),
+ occupancyAverage(_occupancyAverage),
+ usedThirdBuffer(_usedThirdBuffer) {}
// Parcelable interface
virtual status_t writeToParcel(Parcel* parcel) const override;
diff --git a/include/ui/Fence.h b/include/ui/Fence.h
index a4c1df7..d45ad76 100644
--- a/include/ui/Fence.h
+++ b/include/ui/Fence.h
@@ -79,6 +79,9 @@
// becomes signaled when both f1 and f2 are signaled (even if f1 or f2 is
// destroyed before it becomes signaled). The name argument specifies the
// human-readable name to associated with the new Fence object.
+ static sp<Fence> merge(const char* name, const sp<Fence>& f1,
+ const sp<Fence>& f2);
+
static sp<Fence> merge(const String8& name, const sp<Fence>& f1,
const sp<Fence>& f2);
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index e354b11..4f77eed 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -46,7 +46,6 @@
"-g",
"-Wall",
"-Werror",
- "-std=c++11",
"-Wno-missing-field-initializers",
"-Wno-sign-compare",
"-O3",
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index f5961cf..71b5cca 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -36,6 +36,9 @@
# Don't warn about struct padding
LOCAL_CPPFLAGS += -Wno-padded
+# android/sensors.h uses nested anonymous unions and anonymous structs
+LOCAL_CPPFLAGS += -Wno-nested-anon-types -Wno-gnu-anonymous-struct
+
LOCAL_CPPFLAGS += -DDEBUG_ONLY_CODE=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)
LOCAL_SRC_FILES := \
diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp
index 2ffeb0d..669124e 100644
--- a/libs/gui/BufferItem.cpp
+++ b/libs/gui/BufferItem.cpp
@@ -23,6 +23,21 @@
namespace android {
+template<typename T>
+static inline constexpr uint32_t low32(const T n) {
+ return static_cast<uint32_t>(static_cast<uint64_t>(n));
+}
+
+template<typename T>
+static inline constexpr uint32_t high32(const T n) {
+ return static_cast<uint32_t>(static_cast<uint64_t>(n)>>32);
+}
+
+template<typename T>
+static inline constexpr T to64(const uint32_t lo, const uint32_t hi) {
+ return static_cast<T>(static_cast<uint64_t>(hi)<<32 | lo);
+}
+
BufferItem::BufferItem() :
mGraphicBuffer(NULL),
mFence(NULL),
@@ -56,12 +71,12 @@
addAligned(size, mCrop);
addAligned(size, mTransform);
addAligned(size, mScalingMode);
- addAligned(size, mTimestampLo);
- addAligned(size, mTimestampHi);
+ addAligned(size, low32(mTimestamp));
+ addAligned(size, high32(mTimestamp));
addAligned(size, mIsAutoTimestamp);
addAligned(size, mDataSpace);
- addAligned(size, mFrameNumberLo);
- addAligned(size, mFrameNumberHi);
+ addAligned(size, low32(mFrameNumber));
+ addAligned(size, high32(mFrameNumber));
addAligned(size, mSlot);
addAligned(size, mIsDroppable);
addAligned(size, mAcquireCalled);
@@ -144,12 +159,12 @@
writeAligned(buffer, size, mCrop);
writeAligned(buffer, size, mTransform);
writeAligned(buffer, size, mScalingMode);
- writeAligned(buffer, size, mTimestampLo);
- writeAligned(buffer, size, mTimestampHi);
+ writeAligned(buffer, size, low32(mTimestamp));
+ writeAligned(buffer, size, high32(mTimestamp));
writeAligned(buffer, size, mIsAutoTimestamp);
writeAligned(buffer, size, mDataSpace);
- writeAligned(buffer, size, mFrameNumberLo);
- writeAligned(buffer, size, mFrameNumberHi);
+ writeAligned(buffer, size, low32(mFrameNumber));
+ writeAligned(buffer, size, high32(mFrameNumber));
writeAligned(buffer, size, mSlot);
writeAligned(buffer, size, mIsDroppable);
writeAligned(buffer, size, mAcquireCalled);
@@ -200,15 +215,20 @@
return NO_MEMORY;
}
+ uint32_t timestampLo = 0, timestampHi = 0;
+ uint32_t frameNumberLo = 0, frameNumberHi = 0;
+
readAligned(buffer, size, mCrop);
readAligned(buffer, size, mTransform);
readAligned(buffer, size, mScalingMode);
- readAligned(buffer, size, mTimestampLo);
- readAligned(buffer, size, mTimestampHi);
+ readAligned(buffer, size, timestampLo);
+ readAligned(buffer, size, timestampHi);
+ mTimestamp = to64<int64_t>(timestampLo, timestampHi);
readAligned(buffer, size, mIsAutoTimestamp);
readAligned(buffer, size, mDataSpace);
- readAligned(buffer, size, mFrameNumberLo);
- readAligned(buffer, size, mFrameNumberHi);
+ readAligned(buffer, size, frameNumberLo);
+ readAligned(buffer, size, frameNumberHi);
+ mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
readAligned(buffer, size, mSlot);
readAligned(buffer, size, mIsDroppable);
readAligned(buffer, size, mAcquireCalled);
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index 13f4e1c..6e6cce2 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -62,6 +62,7 @@
mConsumerListener(),
mConsumerUsageBits(0),
mConnectedApi(NO_CONNECTED_API),
+ mLinkedToDeath(),
mConnectedProducerListener(),
mSlots(),
mQueue(),
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 13166f6..90b4b9d 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1122,18 +1122,22 @@
static_cast<uint32_t>(mCore->mQueue.size()),
mCore->mFrameCounter + 1);
- // Set up a death notification so that we can disconnect
- // automatically if the remote producer dies
- if (listener != NULL &&
- IInterface::asBinder(listener)->remoteBinder() != NULL) {
- status = IInterface::asBinder(listener)->linkToDeath(
- static_cast<IBinder::DeathRecipient*>(this));
- if (status != NO_ERROR) {
- BQ_LOGE("connect: linkToDeath failed: %s (%d)",
- strerror(-status), status);
+ if (listener != NULL) {
+ // Set up a death notification so that we can disconnect
+ // automatically if the remote producer dies
+ if (IInterface::asBinder(listener)->remoteBinder() != NULL) {
+ status = IInterface::asBinder(listener)->linkToDeath(
+ static_cast<IBinder::DeathRecipient*>(this));
+ if (status != NO_ERROR) {
+ BQ_LOGE("connect: linkToDeath failed: %s (%d)",
+ strerror(-status), status);
+ }
+ mCore->mLinkedToDeath = listener;
+ }
+ if (listener->needsReleaseNotify()) {
+ mCore->mConnectedProducerListener = listener;
}
}
- mCore->mConnectedProducerListener = listener;
break;
default:
BQ_LOGE("connect: unknown API %d", api);
@@ -1195,9 +1199,9 @@
mCore->freeAllBuffersLocked();
// Remove our death notification callback if we have one
- if (mCore->mConnectedProducerListener != NULL) {
+ if (mCore->mLinkedToDeath != NULL) {
sp<IBinder> token =
- IInterface::asBinder(mCore->mConnectedProducerListener);
+ IInterface::asBinder(mCore->mLinkedToDeath);
// This can fail if we're here because of the death
// notification, but we just ignore it
token->unlinkToDeath(
@@ -1205,6 +1209,7 @@
}
mCore->mSharedBufferSlot =
BufferQueueCore::INVALID_BUFFER_SLOT;
+ mCore->mLinkedToDeath = NULL;
mCore->mConnectedProducerListener = NULL;
mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
mCore->mConnectedPid = -1;
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 805a10d..5546d54 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -315,9 +315,10 @@
if (!mSlots[slot].mFence.get()) {
mSlots[slot].mFence = fence;
} else {
+ char fenceName[32] = {};
+ snprintf(fenceName, 32, "%.28s:%d", mName.string(), slot);
sp<Fence> mergedFence = Fence::merge(
- String8::format("%.28s:%d", mName.string(), slot),
- mSlots[slot].mFence, fence);
+ fenceName, mSlots[slot].mFence, fence);
if (!mergedFence.get()) {
CB_LOGE("failed to merge release fences");
// synchronization is broken, the best we can do is hope fences
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
index 855a488..62abfa8 100644
--- a/libs/gui/IProducerListener.cpp
+++ b/libs/gui/IProducerListener.cpp
@@ -22,6 +22,7 @@
enum {
ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
+ NEEDS_RELEASE_NOTIFY,
};
class BpProducerListener : public BpInterface<IProducerListener>
@@ -37,6 +38,23 @@
data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
}
+
+ virtual bool needsReleaseNotify() {
+ bool result;
+ Parcel data, reply;
+ data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
+ status_t err = remote()->transact(NEEDS_RELEASE_NOTIFY, data, &reply);
+ if (err != NO_ERROR) {
+ ALOGE("IProducerListener: binder call \'needsReleaseNotify\' failed");
+ return true;
+ }
+ err = reply.readBool(&result);
+ if (err != NO_ERROR) {
+ ALOGE("IProducerListener: malformed binder reply");
+ return true;
+ }
+ return result;
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -52,6 +70,10 @@
CHECK_INTERFACE(IProducerListener, data, reply);
onBufferReleased();
return NO_ERROR;
+ case NEEDS_RELEASE_NOTIFY:
+ CHECK_INTERFACE(IProducerListener, data, reply);
+ reply->writeBool(needsReleaseNotify());
+ return NO_ERROR;
}
return BBinder::onTransact(code, data, reply, flags);
}
@@ -60,4 +82,8 @@
DummyProducerListener::~DummyProducerListener() = default;
+bool BnProducerListener::needsReleaseNotify() {
+ return true;
+}
+
} // namespace android
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index f0b5eda..029a420 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -23,7 +23,6 @@
name: "StructLayout_test",
srcs: ["StructLayout_test.cpp"],
cflags: [
- "-std=c++11",
"-O0",
],
}
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index bf24ffb..7cf8233 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -72,7 +72,7 @@
return err < 0 ? -errno : status_t(NO_ERROR);
}
-sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
+sp<Fence> Fence::merge(const char* name, const sp<Fence>& f1,
const sp<Fence>& f2) {
ATRACE_CALL();
int result;
@@ -80,24 +80,29 @@
// valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so
// that a new fence with the given name is created.
if (f1->isValid() && f2->isValid()) {
- result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd);
+ result = sync_merge(name, f1->mFenceFd, f2->mFenceFd);
} else if (f1->isValid()) {
- result = sync_merge(name.string(), f1->mFenceFd, f1->mFenceFd);
+ result = sync_merge(name, f1->mFenceFd, f1->mFenceFd);
} else if (f2->isValid()) {
- result = sync_merge(name.string(), f2->mFenceFd, f2->mFenceFd);
+ result = sync_merge(name, f2->mFenceFd, f2->mFenceFd);
} else {
return NO_FENCE;
}
if (result == -1) {
status_t err = -errno;
ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
- name.string(), f1->mFenceFd, f2->mFenceFd,
+ name, f1->mFenceFd, f2->mFenceFd,
strerror(-err), err);
return NO_FENCE;
}
return sp<Fence>(new Fence(result));
}
+sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
+ const sp<Fence>& f2) {
+ return merge(name.string(), f1, f2);
+}
+
int Fence::dup() const {
return ::dup(mFenceFd);
}
diff --git a/opengl/Android.bp b/opengl/Android.bp
new file mode 100644
index 0000000..164be20
--- /dev/null
+++ b/opengl/Android.bp
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 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.
+
+ndk_headers {
+ name: "libEGL_headers",
+ from: "include",
+ to: "",
+ srcs: ["include/EGL/**/*.h"],
+}
+
+ndk_headers {
+ name: "libGLESv1_CM_headers",
+ from: "include",
+ to: "",
+ srcs: ["include/GLES/**/*.h"],
+}
+
+ndk_headers {
+ name: "libGLESv2_headers",
+ from: "include",
+ to: "",
+ srcs: ["include/GLES2/**/*.h"],
+}
+
+ndk_headers {
+ name: "libGLESv3_headers",
+ from: "include",
+ to: "",
+ srcs: ["include/GLES3/**/*.h"],
+}
+
+ndk_headers {
+ name: "khr_headers",
+ from: "include",
+ to: "",
+ srcs: ["include/KHR/**/*.h"],
+}
+
+subdirs = [
+ "*",
+]
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index f28d4ff..bdd5152 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -20,3 +20,28 @@
},
},
}
+
+// The headers modules are in frameworks/native/opengl/Android.bp.
+ndk_library {
+ name: "libEGL.ndk",
+ symbol_file: "libEGL.map.txt",
+ first_version: "9",
+}
+
+ndk_library {
+ name: "libGLESv1_CM.ndk",
+ symbol_file: "libGLESv1_CM.map.txt",
+ first_version: "9",
+}
+
+ndk_library {
+ name: "libGLESv2.ndk",
+ symbol_file: "libGLESv2.map.txt",
+ first_version: "9",
+}
+
+ndk_library {
+ name: "libGLESv3.ndk",
+ symbol_file: "libGLESv3.map.txt",
+ first_version: "18",
+}
diff --git a/opengl/libs/libEGL.map.txt b/opengl/libs/libEGL.map.txt
new file mode 100644
index 0000000..c8b83f5
--- /dev/null
+++ b/opengl/libs/libEGL.map.txt
@@ -0,0 +1,67 @@
+LIBEGL {
+ global:
+ eglBindAPI;
+ eglBindTexImage;
+ eglChooseConfig;
+ eglClientWaitSyncKHR; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
+ eglCopyBuffers;
+ eglCreateContext;
+ eglCreateImageKHR;
+ eglCreateNativeClientBufferANDROID; # introduced=24
+ eglCreatePbufferFromClientBuffer;
+ eglCreatePbufferSurface;
+ eglCreatePixmapSurface;
+ eglCreateStreamFromFileDescriptorKHR; # introduced=23
+ eglCreateStreamKHR; # introduced=23
+ eglCreateStreamProducerSurfaceKHR; # introduced=23
+ eglCreateSyncKHR; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
+ eglCreateWindowSurface;
+ eglDestroyContext;
+ eglDestroyImageKHR;
+ eglDestroyStreamKHR; # introduced=23
+ eglDestroySurface;
+ eglDestroySyncKHR; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
+ eglGetConfigAttrib;
+ eglGetConfigs;
+ eglGetCurrentContext;
+ eglGetCurrentDisplay;
+ eglGetCurrentSurface;
+ eglGetDisplay;
+ eglGetError;
+ eglGetProcAddress;
+ eglGetStreamFileDescriptorKHR; # introduced=23
+ eglGetSyncAttribKHR; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
+ eglGetSystemTimeFrequencyNV; # introduced-arm=14 introduced-arm64=21 introduced-mips=14 introduced-mips64=21 introduced-x86=14 introduced-x86_64=21
+ eglGetSystemTimeNV; # introduced-arm=14 introduced-arm64=21 introduced-mips=14 introduced-mips64=21 introduced-x86=14 introduced-x86_64=21
+ eglInitialize;
+ eglLockSurfaceKHR;
+ eglMakeCurrent;
+ eglPresentationTimeANDROID; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
+ eglQueryAPI;
+ eglQueryContext;
+ eglQueryStreamKHR; # introduced=23
+ eglQueryStreamTimeKHR; # introduced=23
+ eglQueryStreamu64KHR; # introduced=23
+ eglQueryString;
+ eglQuerySurface;
+ eglReleaseTexImage;
+ eglReleaseThread;
+ eglSetDamageRegionKHR; # introduced=23
+ eglSignalSyncKHR; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
+ eglStreamAttribKHR; # introduced=23
+ eglStreamConsumerAcquireKHR; # introduced=23
+ eglStreamConsumerGLTextureExternalKHR; # introduced=23
+ eglStreamConsumerReleaseKHR; # introduced=23
+ eglSurfaceAttrib;
+ eglSwapBuffers;
+ eglSwapBuffersWithDamageKHR; # introduced=23
+ eglSwapInterval;
+ eglTerminate;
+ eglUnlockSurfaceKHR;
+ eglWaitClient;
+ eglWaitGL;
+ eglWaitNative;
+ eglWaitSyncKHR; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
+ local:
+ *;
+};
diff --git a/opengl/libs/libGLESv1_CM.map.txt b/opengl/libs/libGLESv1_CM.map.txt
new file mode 100644
index 0000000..8ba91e6
--- /dev/null
+++ b/opengl/libs/libGLESv1_CM.map.txt
@@ -0,0 +1,283 @@
+LIBGLESV1_CM {
+ global:
+ glActiveTexture;
+ glAlphaFunc;
+ glAlphaFuncx;
+ glAlphaFuncxOES;
+ glBindBuffer;
+ glBindFramebufferOES;
+ glBindRenderbufferOES;
+ glBindTexture;
+ glBindVertexArrayOES; # introduced-mips=9 introduced-x86=9
+ glBlendEquationOES;
+ glBlendEquationSeparateOES;
+ glBlendFunc;
+ glBlendFuncSeparateOES;
+ glBufferData;
+ glBufferSubData;
+ glCheckFramebufferStatusOES;
+ glClear;
+ glClearColor;
+ glClearColorx;
+ glClearColorxOES;
+ glClearDepthf;
+ glClearDepthfOES;
+ glClearDepthx;
+ glClearDepthxOES;
+ glClearStencil;
+ glClientActiveTexture;
+ glClipPlanef;
+ glClipPlanefIMG; # introduced-mips=9 introduced-x86=9
+ glClipPlanefOES;
+ glClipPlanex;
+ glClipPlanexIMG; # introduced-mips=9 introduced-x86=9
+ glClipPlanexOES;
+ glColor4f;
+ glColor4ub;
+ glColor4x;
+ glColor4xOES;
+ glColorMask;
+ glColorPointer;
+ glColorPointerBounds;
+ glCompressedTexImage2D;
+ glCompressedTexSubImage2D;
+ glCopyTexImage2D;
+ glCopyTexSubImage2D;
+ glCullFace;
+ glCurrentPaletteMatrixOES;
+ glDeleteBuffers;
+ glDeleteFencesNV; # introduced-mips=9 introduced-x86=9
+ glDeleteFramebuffersOES;
+ glDeleteRenderbuffersOES;
+ glDeleteTextures;
+ glDeleteVertexArraysOES; # introduced-mips=9 introduced-x86=9
+ glDepthFunc;
+ glDepthMask;
+ glDepthRangef;
+ glDepthRangefOES;
+ glDepthRangex;
+ glDepthRangexOES;
+ glDisable;
+ glDisableClientState;
+ glDisableDriverControlQCOM; # introduced-mips=9 introduced-x86=9
+ glDiscardFramebufferEXT; # introduced-mips=9 introduced-x86=9
+ glDrawArrays;
+ glDrawElements;
+ glDrawTexfOES;
+ glDrawTexfvOES;
+ glDrawTexiOES;
+ glDrawTexivOES;
+ glDrawTexsOES;
+ glDrawTexsvOES;
+ glDrawTexxOES;
+ glDrawTexxvOES;
+ glEGLImageTargetRenderbufferStorageOES;
+ glEGLImageTargetTexture2DOES;
+ glEnable;
+ glEnableClientState;
+ glEnableDriverControlQCOM; # introduced-mips=9 introduced-x86=9
+ glEndTilingQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetBufferPointervQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetBuffersQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetFramebuffersQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetProgramBinarySourceQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetProgramsQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetRenderbuffersQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetShadersQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetTexLevelParameterivQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetTexSubImageQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetTexturesQCOM; # introduced-mips=9 introduced-x86=9
+ glExtIsProgramBinaryQCOM; # introduced-mips=9 introduced-x86=9
+ glExtTexObjectStateOverrideiQCOM; # introduced-mips=9 introduced-x86=9
+ glFinish;
+ glFinishFenceNV; # introduced-mips=9 introduced-x86=9
+ glFlush;
+ glFogf;
+ glFogfv;
+ glFogx;
+ glFogxOES;
+ glFogxv;
+ glFogxvOES;
+ glFramebufferRenderbufferOES;
+ glFramebufferTexture2DMultisampleIMG; # introduced-mips=9 introduced-x86=9
+ glFramebufferTexture2DOES;
+ glFrontFace;
+ glFrustumf;
+ glFrustumfOES;
+ glFrustumx;
+ glFrustumxOES;
+ glGenBuffers;
+ glGenFencesNV; # introduced-mips=9 introduced-x86=9
+ glGenFramebuffersOES;
+ glGenRenderbuffersOES;
+ glGenTextures;
+ glGenVertexArraysOES; # introduced-mips=9 introduced-x86=9
+ glGenerateMipmapOES;
+ glGetBooleanv;
+ glGetBufferParameteriv;
+ glGetBufferPointervOES;
+ glGetClipPlanef;
+ glGetClipPlanefOES;
+ glGetClipPlanex;
+ glGetClipPlanexOES;
+ glGetDriverControlStringQCOM; # introduced-mips=9 introduced-x86=9
+ glGetDriverControlsQCOM; # introduced-mips=9 introduced-x86=9
+ glGetError;
+ glGetFenceivNV; # introduced-mips=9 introduced-x86=9
+ glGetFixedv;
+ glGetFixedvOES;
+ glGetFloatv;
+ glGetFramebufferAttachmentParameterivOES;
+ glGetIntegerv;
+ glGetLightfv;
+ glGetLightxv;
+ glGetLightxvOES;
+ glGetMaterialfv;
+ glGetMaterialxv;
+ glGetMaterialxvOES;
+ glGetPointerv;
+ glGetRenderbufferParameterivOES;
+ glGetString;
+ glGetTexEnvfv;
+ glGetTexEnviv;
+ glGetTexEnvxv;
+ glGetTexEnvxvOES;
+ glGetTexGenfvOES;
+ glGetTexGenivOES;
+ glGetTexGenxvOES;
+ glGetTexParameterfv;
+ glGetTexParameteriv;
+ glGetTexParameterxv;
+ glGetTexParameterxvOES;
+ glHint;
+ glIsBuffer;
+ glIsEnabled;
+ glIsFenceNV; # introduced-mips=9 introduced-x86=9
+ glIsFramebufferOES;
+ glIsRenderbufferOES;
+ glIsTexture;
+ glIsVertexArrayOES; # introduced-mips=9 introduced-x86=9
+ glLightModelf;
+ glLightModelfv;
+ glLightModelx;
+ glLightModelxOES;
+ glLightModelxv;
+ glLightModelxvOES;
+ glLightf;
+ glLightfv;
+ glLightx;
+ glLightxOES;
+ glLightxv;
+ glLightxvOES;
+ glLineWidth;
+ glLineWidthx;
+ glLineWidthxOES;
+ glLoadIdentity;
+ glLoadMatrixf;
+ glLoadMatrixx;
+ glLoadMatrixxOES;
+ glLoadPaletteFromModelViewMatrixOES;
+ glLogicOp;
+ glMapBufferOES;
+ glMaterialf;
+ glMaterialfv;
+ glMaterialx;
+ glMaterialxOES;
+ glMaterialxv;
+ glMaterialxvOES;
+ glMatrixIndexPointerOES;
+ glMatrixIndexPointerOESBounds; # introduced-mips=9 introduced-x86=9
+ glMatrixMode;
+ glMultMatrixf;
+ glMultMatrixx;
+ glMultMatrixxOES;
+ glMultiDrawArraysEXT; # introduced-mips=9 introduced-x86=9
+ glMultiDrawElementsEXT; # introduced-mips=9 introduced-x86=9
+ glMultiTexCoord4f;
+ glMultiTexCoord4x;
+ glMultiTexCoord4xOES;
+ glNormal3f;
+ glNormal3x;
+ glNormal3xOES;
+ glNormalPointer;
+ glNormalPointerBounds;
+ glOrthof;
+ glOrthofOES;
+ glOrthox;
+ glOrthoxOES;
+ glPixelStorei;
+ glPointParameterf;
+ glPointParameterfv;
+ glPointParameterx;
+ glPointParameterxOES;
+ glPointParameterxv;
+ glPointParameterxvOES;
+ glPointSize;
+ glPointSizePointerOES;
+ glPointSizePointerOESBounds; # introduced-mips=9 introduced-x86=9
+ glPointSizex;
+ glPointSizexOES;
+ glPolygonOffset;
+ glPolygonOffsetx;
+ glPolygonOffsetxOES;
+ glPopMatrix;
+ glPushMatrix;
+ glQueryMatrixxOES;
+ glReadPixels;
+ glRenderbufferStorageMultisampleIMG; # introduced-mips=9 introduced-x86=9
+ glRenderbufferStorageOES;
+ glRotatef;
+ glRotatex;
+ glRotatexOES;
+ glSampleCoverage;
+ glSampleCoveragex;
+ glSampleCoveragexOES;
+ glScalef;
+ glScalex;
+ glScalexOES;
+ glScissor;
+ glSetFenceNV; # introduced-mips=9 introduced-x86=9
+ glShadeModel;
+ glStartTilingQCOM; # introduced-mips=9 introduced-x86=9
+ glStencilFunc;
+ glStencilMask;
+ glStencilOp;
+ glTestFenceNV; # introduced-mips=9 introduced-x86=9
+ glTexCoordPointer;
+ glTexCoordPointerBounds;
+ glTexEnvf;
+ glTexEnvfv;
+ glTexEnvi;
+ glTexEnviv;
+ glTexEnvx;
+ glTexEnvxOES;
+ glTexEnvxv;
+ glTexEnvxvOES;
+ glTexGenfOES;
+ glTexGenfvOES;
+ glTexGeniOES;
+ glTexGenivOES;
+ glTexGenxOES;
+ glTexGenxvOES;
+ glTexImage2D;
+ glTexParameterf;
+ glTexParameterfv;
+ glTexParameteri;
+ glTexParameteriv;
+ glTexParameterx;
+ glTexParameterxOES;
+ glTexParameterxv;
+ glTexParameterxvOES;
+ glTexSubImage2D;
+ glTranslatef;
+ glTranslatex;
+ glTranslatexOES;
+ glUnmapBufferOES;
+ glVertexPointer;
+ glVertexPointerBounds;
+ glViewport;
+ glWeightPointerOES;
+ glWeightPointerOESBounds; # introduced-mips=9 introduced-x86=9
+ local:
+ *;
+};
diff --git a/opengl/libs/libGLESv2.map.txt b/opengl/libs/libGLESv2.map.txt
new file mode 100644
index 0000000..1b0042a
--- /dev/null
+++ b/opengl/libs/libGLESv2.map.txt
@@ -0,0 +1,207 @@
+LIBGLESV2 {
+ global:
+ glActiveTexture;
+ glAttachShader;
+ glBeginPerfMonitorAMD;
+ glBindAttribLocation;
+ glBindBuffer;
+ glBindFramebuffer;
+ glBindRenderbuffer;
+ glBindTexture;
+ glBindVertexArrayOES; # introduced-mips=9 introduced-x86=9
+ glBlendColor;
+ glBlendEquation;
+ glBlendEquationSeparate;
+ glBlendFunc;
+ glBlendFuncSeparate;
+ glBufferData;
+ glBufferSubData;
+ glCheckFramebufferStatus;
+ glClear;
+ glClearColor;
+ glClearDepthf;
+ glClearStencil;
+ glColorMask;
+ glCompileShader;
+ glCompressedTexImage2D;
+ glCompressedTexImage3DOES;
+ glCompressedTexSubImage2D;
+ glCompressedTexSubImage3DOES;
+ glCopyTexImage2D;
+ glCopyTexSubImage2D;
+ glCopyTexSubImage3DOES;
+ glCoverageMaskNV; # introduced-mips=9 introduced-x86=9
+ glCoverageOperationNV; # introduced-mips=9 introduced-x86=9
+ glCreateProgram;
+ glCreateShader;
+ glCullFace;
+ glDeleteBuffers;
+ glDeleteFencesNV;
+ glDeleteFramebuffers;
+ glDeletePerfMonitorsAMD;
+ glDeleteProgram;
+ glDeleteRenderbuffers;
+ glDeleteShader;
+ glDeleteTextures;
+ glDeleteVertexArraysOES; # introduced-mips=9 introduced-x86=9
+ glDepthFunc;
+ glDepthMask;
+ glDepthRangef;
+ glDetachShader;
+ glDisable;
+ glDisableDriverControlQCOM;
+ glDisableVertexAttribArray;
+ glDiscardFramebufferEXT; # introduced-mips=9 introduced-x86=9
+ glDrawArrays;
+ glDrawElements;
+ glEGLImageTargetRenderbufferStorageOES;
+ glEGLImageTargetTexture2DOES;
+ glEnable;
+ glEnableDriverControlQCOM;
+ glEnableVertexAttribArray;
+ glEndPerfMonitorAMD;
+ glEndTilingQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetBufferPointervQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetBuffersQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetFramebuffersQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetProgramBinarySourceQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetProgramsQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetRenderbuffersQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetShadersQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetTexLevelParameterivQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetTexSubImageQCOM; # introduced-mips=9 introduced-x86=9
+ glExtGetTexturesQCOM; # introduced-mips=9 introduced-x86=9
+ glExtIsProgramBinaryQCOM; # introduced-mips=9 introduced-x86=9
+ glExtTexObjectStateOverrideiQCOM; # introduced-mips=9 introduced-x86=9
+ glFinish;
+ glFinishFenceNV;
+ glFlush;
+ glFramebufferRenderbuffer;
+ glFramebufferTexture2D;
+ glFramebufferTexture2DMultisampleIMG; # introduced-mips=9 introduced-x86=9
+ glFramebufferTexture3DOES;
+ glFrontFace;
+ glGenBuffers;
+ glGenFencesNV;
+ glGenFramebuffers;
+ glGenPerfMonitorsAMD;
+ glGenRenderbuffers;
+ glGenTextures;
+ glGenVertexArraysOES; # introduced-mips=9 introduced-x86=9
+ glGenerateMipmap;
+ glGetActiveAttrib;
+ glGetActiveUniform;
+ glGetAttachedShaders;
+ glGetAttribLocation;
+ glGetBooleanv;
+ glGetBufferParameteriv;
+ glGetBufferPointervOES;
+ glGetDriverControlStringQCOM;
+ glGetDriverControlsQCOM;
+ glGetError;
+ glGetFenceivNV;
+ glGetFloatv;
+ glGetFramebufferAttachmentParameteriv;
+ glGetIntegerv;
+ glGetPerfMonitorCounterDataAMD;
+ glGetPerfMonitorCounterInfoAMD;
+ glGetPerfMonitorCounterStringAMD;
+ glGetPerfMonitorCountersAMD;
+ glGetPerfMonitorGroupStringAMD;
+ glGetPerfMonitorGroupsAMD;
+ glGetProgramBinaryOES;
+ glGetProgramInfoLog;
+ glGetProgramiv;
+ glGetRenderbufferParameteriv;
+ glGetShaderInfoLog;
+ glGetShaderPrecisionFormat;
+ glGetShaderSource;
+ glGetShaderiv;
+ glGetString;
+ glGetTexParameterfv;
+ glGetTexParameteriv;
+ glGetUniformLocation;
+ glGetUniformfv;
+ glGetUniformiv;
+ glGetVertexAttribPointerv;
+ glGetVertexAttribfv;
+ glGetVertexAttribiv;
+ glHint;
+ glIsBuffer;
+ glIsEnabled;
+ glIsFenceNV;
+ glIsFramebuffer;
+ glIsProgram;
+ glIsRenderbuffer;
+ glIsShader;
+ glIsTexture;
+ glIsVertexArrayOES; # introduced-mips=9 introduced-x86=9
+ glLineWidth;
+ glLinkProgram;
+ glMapBufferOES;
+ glMultiDrawArraysEXT; # introduced-mips=9 introduced-x86=9
+ glMultiDrawElementsEXT; # introduced-mips=9 introduced-x86=9
+ glPixelStorei;
+ glPolygonOffset;
+ glProgramBinaryOES;
+ glReadPixels;
+ glReleaseShaderCompiler;
+ glRenderbufferStorage;
+ glRenderbufferStorageMultisampleIMG; # introduced-mips=9 introduced-x86=9
+ glSampleCoverage;
+ glScissor;
+ glSelectPerfMonitorCountersAMD;
+ glSetFenceNV;
+ glShaderBinary;
+ glShaderSource;
+ glStartTilingQCOM; # introduced-mips=9 introduced-x86=9
+ glStencilFunc;
+ glStencilFuncSeparate;
+ glStencilMask;
+ glStencilMaskSeparate;
+ glStencilOp;
+ glStencilOpSeparate;
+ glTestFenceNV;
+ glTexImage2D;
+ glTexImage3DOES;
+ glTexParameterf;
+ glTexParameterfv;
+ glTexParameteri;
+ glTexParameteriv;
+ glTexSubImage2D;
+ glTexSubImage3DOES;
+ glUniform1f;
+ glUniform1fv;
+ glUniform1i;
+ glUniform1iv;
+ glUniform2f;
+ glUniform2fv;
+ glUniform2i;
+ glUniform2iv;
+ glUniform3f;
+ glUniform3fv;
+ glUniform3i;
+ glUniform3iv;
+ glUniform4f;
+ glUniform4fv;
+ glUniform4i;
+ glUniform4iv;
+ glUniformMatrix2fv;
+ glUniformMatrix3fv;
+ glUniformMatrix4fv;
+ glUnmapBufferOES;
+ glUseProgram;
+ glValidateProgram;
+ glVertexAttrib1f;
+ glVertexAttrib1fv;
+ glVertexAttrib2f;
+ glVertexAttrib2fv;
+ glVertexAttrib3f;
+ glVertexAttrib3fv;
+ glVertexAttrib4f;
+ glVertexAttrib4fv;
+ glVertexAttribPointer;
+ glViewport;
+ local:
+ *;
+};
diff --git a/opengl/libs/libGLESv3.map.txt b/opengl/libs/libGLESv3.map.txt
new file mode 100644
index 0000000..21f6cb6
--- /dev/null
+++ b/opengl/libs/libGLESv3.map.txt
@@ -0,0 +1,416 @@
+LIBGLESV3 {
+ global:
+ glActiveShaderProgram; # introduced=21
+ glActiveTexture;
+ glAttachShader;
+ glBeginQuery;
+ glBeginTransformFeedback;
+ glBindAttribLocation;
+ glBindBuffer;
+ glBindBufferBase;
+ glBindBufferRange;
+ glBindFramebuffer;
+ glBindImageTexture; # introduced=21
+ glBindProgramPipeline; # introduced=21
+ glBindRenderbuffer;
+ glBindSampler;
+ glBindTexture;
+ glBindTransformFeedback;
+ glBindVertexArray;
+ glBindVertexArrayOES;
+ glBindVertexBuffer; # introduced=21
+ glBlendBarrier; # introduced=24
+ glBlendBarrierKHR; # introduced=21
+ glBlendColor;
+ glBlendEquation;
+ glBlendEquationSeparate;
+ glBlendEquationSeparatei; # introduced=24
+ glBlendEquationSeparateiEXT; # introduced=21
+ glBlendEquationi; # introduced=24
+ glBlendEquationiEXT; # introduced=21
+ glBlendFunc;
+ glBlendFuncSeparate;
+ glBlendFuncSeparatei; # introduced=24
+ glBlendFuncSeparateiEXT; # introduced=21
+ glBlendFunci; # introduced=24
+ glBlendFunciEXT; # introduced=21
+ glBlitFramebuffer;
+ glBufferData;
+ glBufferSubData;
+ glCheckFramebufferStatus;
+ glClear;
+ glClearBufferfi;
+ glClearBufferfv;
+ glClearBufferiv;
+ glClearBufferuiv;
+ glClearColor;
+ glClearDepthf;
+ glClearStencil;
+ glClientWaitSync;
+ glColorMask;
+ glColorMaski; # introduced=24
+ glColorMaskiEXT; # introduced=21
+ glCompileShader;
+ glCompressedTexImage2D;
+ glCompressedTexImage3D;
+ glCompressedTexImage3DOES;
+ glCompressedTexSubImage2D;
+ glCompressedTexSubImage3D;
+ glCompressedTexSubImage3DOES;
+ glCopyBufferSubData;
+ glCopyImageSubData; # introduced=24
+ glCopyImageSubDataEXT; # introduced=21
+ glCopyTexImage2D;
+ glCopyTexSubImage2D;
+ glCopyTexSubImage3D;
+ glCopyTexSubImage3DOES;
+ glCreateProgram;
+ glCreateShader;
+ glCreateShaderProgramv; # introduced=21
+ glCullFace;
+ glDebugMessageCallback; # introduced=24
+ glDebugMessageCallbackKHR; # introduced=21
+ glDebugMessageControl; # introduced=24
+ glDebugMessageControlKHR; # introduced=21
+ glDebugMessageInsert; # introduced=24
+ glDebugMessageInsertKHR; # introduced=21
+ glDeleteBuffers;
+ glDeleteFramebuffers;
+ glDeleteProgram;
+ glDeleteProgramPipelines; # introduced=21
+ glDeleteQueries;
+ glDeleteRenderbuffers;
+ glDeleteSamplers;
+ glDeleteShader;
+ glDeleteSync;
+ glDeleteTextures;
+ glDeleteTransformFeedbacks;
+ glDeleteVertexArrays;
+ glDeleteVertexArraysOES;
+ glDepthFunc;
+ glDepthMask;
+ glDepthRangef;
+ glDetachShader;
+ glDisable;
+ glDisableVertexAttribArray;
+ glDisablei; # introduced=24
+ glDisableiEXT; # introduced=21
+ glDispatchCompute; # introduced=21
+ glDispatchComputeIndirect; # introduced=21
+ glDrawArrays;
+ glDrawArraysIndirect; # introduced=21
+ glDrawArraysInstanced;
+ glDrawBuffers;
+ glDrawElements;
+ glDrawElementsBaseVertex; # introduced=24
+ glDrawElementsIndirect; # introduced=21
+ glDrawElementsInstanced;
+ glDrawElementsInstancedBaseVertex; # introduced=24
+ glDrawRangeElements;
+ glDrawRangeElementsBaseVertex; # introduced=24
+ glEGLImageTargetRenderbufferStorageOES;
+ glEGLImageTargetTexture2DOES;
+ glEnable;
+ glEnableVertexAttribArray;
+ glEnablei; # introduced=24
+ glEnableiEXT; # introduced=21
+ glEndQuery;
+ glEndTransformFeedback;
+ glFenceSync;
+ glFinish;
+ glFlush;
+ glFlushMappedBufferRange;
+ glFramebufferParameteri; # introduced=21
+ glFramebufferRenderbuffer;
+ glFramebufferTexture; # introduced=24
+ glFramebufferTexture2D;
+ glFramebufferTexture3DOES;
+ glFramebufferTextureEXT; # introduced=21
+ glFramebufferTextureLayer;
+ glFrontFace;
+ glGenBuffers;
+ glGenFramebuffers;
+ glGenProgramPipelines; # introduced=21
+ glGenQueries;
+ glGenRenderbuffers;
+ glGenSamplers;
+ glGenTextures;
+ glGenTransformFeedbacks;
+ glGenVertexArrays;
+ glGenVertexArraysOES;
+ glGenerateMipmap;
+ glGetActiveAttrib;
+ glGetActiveUniform;
+ glGetActiveUniformBlockName;
+ glGetActiveUniformBlockiv;
+ glGetActiveUniformsiv;
+ glGetAttachedShaders;
+ glGetAttribLocation;
+ glGetBooleani_v; # introduced=21
+ glGetBooleanv;
+ glGetBufferParameteri64v;
+ glGetBufferParameteriv;
+ glGetBufferPointerv;
+ glGetBufferPointervOES;
+ glGetDebugMessageLog; # introduced=24
+ glGetDebugMessageLogKHR; # introduced=21
+ glGetError;
+ glGetFloatv;
+ glGetFragDataLocation;
+ glGetFramebufferAttachmentParameteriv;
+ glGetFramebufferParameteriv; # introduced=21
+ glGetGraphicsResetStatus; # introduced=24
+ glGetInteger64i_v;
+ glGetInteger64v;
+ glGetIntegeri_v;
+ glGetIntegerv;
+ glGetInternalformativ;
+ glGetMultisamplefv; # introduced=21
+ glGetObjectLabel; # introduced=24
+ glGetObjectLabelKHR; # introduced=21
+ glGetObjectPtrLabel; # introduced=24
+ glGetObjectPtrLabelKHR; # introduced=21
+ glGetPointerv; # introduced=24
+ glGetPointervKHR; # introduced=21
+ glGetProgramBinary;
+ glGetProgramBinaryOES;
+ glGetProgramInfoLog;
+ glGetProgramInterfaceiv; # introduced=21
+ glGetProgramPipelineInfoLog; # introduced=21
+ glGetProgramPipelineiv; # introduced=21
+ glGetProgramResourceIndex; # introduced=21
+ glGetProgramResourceLocation; # introduced=21
+ glGetProgramResourceName; # introduced=21
+ glGetProgramResourceiv; # introduced=21
+ glGetProgramiv;
+ glGetQueryObjectuiv;
+ glGetQueryiv;
+ glGetRenderbufferParameteriv;
+ glGetSamplerParameterIiv; # introduced=24
+ glGetSamplerParameterIivEXT; # introduced=21
+ glGetSamplerParameterIuiv; # introduced=24
+ glGetSamplerParameterIuivEXT; # introduced=21
+ glGetSamplerParameterfv;
+ glGetSamplerParameteriv;
+ glGetShaderInfoLog;
+ glGetShaderPrecisionFormat;
+ glGetShaderSource;
+ glGetShaderiv;
+ glGetString;
+ glGetStringi;
+ glGetSynciv;
+ glGetTexLevelParameterfv; # introduced=21
+ glGetTexLevelParameteriv; # introduced=21
+ glGetTexParameterIiv; # introduced=24
+ glGetTexParameterIivEXT; # introduced=21
+ glGetTexParameterIuiv; # introduced=24
+ glGetTexParameterIuivEXT; # introduced=21
+ glGetTexParameterfv;
+ glGetTexParameteriv;
+ glGetTransformFeedbackVarying;
+ glGetUniformBlockIndex;
+ glGetUniformIndices;
+ glGetUniformLocation;
+ glGetUniformfv;
+ glGetUniformiv;
+ glGetUniformuiv;
+ glGetVertexAttribIiv;
+ glGetVertexAttribIuiv;
+ glGetVertexAttribPointerv;
+ glGetVertexAttribfv;
+ glGetVertexAttribiv;
+ glGetnUniformfv; # introduced=24
+ glGetnUniformiv; # introduced=24
+ glGetnUniformuiv; # introduced=24
+ glHint;
+ glInvalidateFramebuffer;
+ glInvalidateSubFramebuffer;
+ glIsBuffer;
+ glIsEnabled;
+ glIsEnabledi; # introduced=24
+ glIsEnablediEXT; # introduced=21
+ glIsFramebuffer;
+ glIsProgram;
+ glIsProgramPipeline; # introduced=21
+ glIsQuery;
+ glIsRenderbuffer;
+ glIsSampler;
+ glIsShader;
+ glIsSync;
+ glIsTexture;
+ glIsTransformFeedback;
+ glIsVertexArray;
+ glIsVertexArrayOES;
+ glLineWidth;
+ glLinkProgram;
+ glMapBufferOES;
+ glMapBufferRange;
+ glMemoryBarrier; # introduced=21
+ glMemoryBarrierByRegion; # introduced=21
+ glMinSampleShading; # introduced=24
+ glMinSampleShadingOES; # introduced=21
+ glObjectLabel; # introduced=24
+ glObjectLabelKHR; # introduced=21
+ glObjectPtrLabel; # introduced=24
+ glObjectPtrLabelKHR; # introduced=21
+ glPatchParameteri; # introduced=24
+ glPatchParameteriEXT; # introduced=21
+ glPauseTransformFeedback;
+ glPixelStorei;
+ glPolygonOffset;
+ glPopDebugGroup; # introduced=24
+ glPopDebugGroupKHR; # introduced=21
+ glPrimitiveBoundingBox; # introduced=24
+ glPrimitiveBoundingBoxEXT; # introduced=21
+ glProgramBinary;
+ glProgramBinaryOES;
+ glProgramParameteri;
+ glProgramUniform1f; # introduced=21
+ glProgramUniform1fv; # introduced=21
+ glProgramUniform1i; # introduced=21
+ glProgramUniform1iv; # introduced=21
+ glProgramUniform1ui; # introduced=21
+ glProgramUniform1uiv; # introduced=21
+ glProgramUniform2f; # introduced=21
+ glProgramUniform2fv; # introduced=21
+ glProgramUniform2i; # introduced=21
+ glProgramUniform2iv; # introduced=21
+ glProgramUniform2ui; # introduced=21
+ glProgramUniform2uiv; # introduced=21
+ glProgramUniform3f; # introduced=21
+ glProgramUniform3fv; # introduced=21
+ glProgramUniform3i; # introduced=21
+ glProgramUniform3iv; # introduced=21
+ glProgramUniform3ui; # introduced=21
+ glProgramUniform3uiv; # introduced=21
+ glProgramUniform4f; # introduced=21
+ glProgramUniform4fv; # introduced=21
+ glProgramUniform4i; # introduced=21
+ glProgramUniform4iv; # introduced=21
+ glProgramUniform4ui; # introduced=21
+ glProgramUniform4uiv; # introduced=21
+ glProgramUniformMatrix2fv; # introduced=21
+ glProgramUniformMatrix2x3fv; # introduced=21
+ glProgramUniformMatrix2x4fv; # introduced=21
+ glProgramUniformMatrix3fv; # introduced=21
+ glProgramUniformMatrix3x2fv; # introduced=21
+ glProgramUniformMatrix3x4fv; # introduced=21
+ glProgramUniformMatrix4fv; # introduced=21
+ glProgramUniformMatrix4x2fv; # introduced=21
+ glProgramUniformMatrix4x3fv; # introduced=21
+ glPushDebugGroup; # introduced=24
+ glPushDebugGroupKHR; # introduced=21
+ glReadBuffer;
+ glReadPixels;
+ glReadnPixels; # introduced=24
+ glReleaseShaderCompiler;
+ glRenderbufferStorage;
+ glRenderbufferStorageMultisample;
+ glResumeTransformFeedback;
+ glSampleCoverage;
+ glSampleMaski; # introduced=21
+ glSamplerParameterIiv; # introduced=24
+ glSamplerParameterIivEXT; # introduced=21
+ glSamplerParameterIuiv; # introduced=24
+ glSamplerParameterIuivEXT; # introduced=21
+ glSamplerParameterf;
+ glSamplerParameterfv;
+ glSamplerParameteri;
+ glSamplerParameteriv;
+ glScissor;
+ glShaderBinary;
+ glShaderSource;
+ glStencilFunc;
+ glStencilFuncSeparate;
+ glStencilMask;
+ glStencilMaskSeparate;
+ glStencilOp;
+ glStencilOpSeparate;
+ glTexBuffer; # introduced=24
+ glTexBufferEXT; # introduced=21
+ glTexBufferRange; # introduced=24
+ glTexBufferRangeEXT; # introduced=21
+ glTexImage2D;
+ glTexImage3D;
+ glTexImage3DOES;
+ glTexParameterIiv; # introduced=24
+ glTexParameterIivEXT; # introduced=21
+ glTexParameterIuiv; # introduced=24
+ glTexParameterIuivEXT; # introduced=21
+ glTexParameterf;
+ glTexParameterfv;
+ glTexParameteri;
+ glTexParameteriv;
+ glTexStorage2D;
+ glTexStorage2DMultisample; # introduced=21
+ glTexStorage3D;
+ glTexStorage3DMultisample; # introduced=24
+ glTexStorage3DMultisampleOES; # introduced=21
+ glTexSubImage2D;
+ glTexSubImage3D;
+ glTexSubImage3DOES;
+ glTransformFeedbackVaryings;
+ glUniform1f;
+ glUniform1fv;
+ glUniform1i;
+ glUniform1iv;
+ glUniform1ui;
+ glUniform1uiv;
+ glUniform2f;
+ glUniform2fv;
+ glUniform2i;
+ glUniform2iv;
+ glUniform2ui;
+ glUniform2uiv;
+ glUniform3f;
+ glUniform3fv;
+ glUniform3i;
+ glUniform3iv;
+ glUniform3ui;
+ glUniform3uiv;
+ glUniform4f;
+ glUniform4fv;
+ glUniform4i;
+ glUniform4iv;
+ glUniform4ui;
+ glUniform4uiv;
+ glUniformBlockBinding;
+ glUniformMatrix2fv;
+ glUniformMatrix2x3fv;
+ glUniformMatrix2x4fv;
+ glUniformMatrix3fv;
+ glUniformMatrix3x2fv;
+ glUniformMatrix3x4fv;
+ glUniformMatrix4fv;
+ glUniformMatrix4x2fv;
+ glUniformMatrix4x3fv;
+ glUnmapBuffer;
+ glUnmapBufferOES;
+ glUseProgram;
+ glUseProgramStages; # introduced=21
+ glValidateProgram;
+ glValidateProgramPipeline; # introduced=21
+ glVertexAttrib1f;
+ glVertexAttrib1fv;
+ glVertexAttrib2f;
+ glVertexAttrib2fv;
+ glVertexAttrib3f;
+ glVertexAttrib3fv;
+ glVertexAttrib4f;
+ glVertexAttrib4fv;
+ glVertexAttribBinding; # introduced=21
+ glVertexAttribDivisor;
+ glVertexAttribFormat; # introduced=21
+ glVertexAttribI4i;
+ glVertexAttribI4iv;
+ glVertexAttribI4ui;
+ glVertexAttribI4uiv;
+ glVertexAttribIFormat; # introduced=21
+ glVertexAttribIPointer;
+ glVertexAttribPointer;
+ glVertexBindingDivisor; # introduced=21
+ glViewport;
+ glWaitSync;
+ local:
+ *;
+};
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 39b4528..3253056 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -126,7 +126,6 @@
endif
LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
-LOCAL_CFLAGS += -std=c++14
LOCAL_STATIC_LIBRARIES := libtrace_proto libvkjson
LOCAL_SHARED_LIBRARIES := \
@@ -158,7 +157,6 @@
LOCAL_LDFLAGS_32 := -Wl,--version-script,art/sigchainlib/version-script32.txt -Wl,--export-dynamic
LOCAL_LDFLAGS_64 := -Wl,--version-script,art/sigchainlib/version-script64.txt -Wl,--export-dynamic
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
-LOCAL_CPPFLAGS := -std=c++14
LOCAL_INIT_RC := surfaceflinger.rc
@@ -202,7 +200,6 @@
LOCAL_CLANG := true
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
-LOCAL_CPPFLAGS := -std=c++14
LOCAL_SRC_FILES := \
DdmConnection.cpp
diff --git a/vulkan/Android.bp b/vulkan/Android.bp
new file mode 100644
index 0000000..97d99d0
--- /dev/null
+++ b/vulkan/Android.bp
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 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.
+
+ndk_headers {
+ name: "libvulkan_headers",
+ from: "include",
+ to: "",
+ srcs: ["include/vulkan/**/*.h"],
+}
+
+subdirs = [
+ "libvulkan",
+]
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
new file mode 100644
index 0000000..5e3f4dd
--- /dev/null
+++ b/vulkan/libvulkan/Android.bp
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 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.
+
+// Headers module is in frameworks/native/vulkan/Android.bp.
+ndk_library {
+ name: "libvulkan.ndk",
+ symbol_file: "libvulkan.map.txt",
+ first_version: "24",
+}
diff --git a/vulkan/libvulkan/libvulkan.map.txt b/vulkan/libvulkan/libvulkan.map.txt
new file mode 100644
index 0000000..1745925
--- /dev/null
+++ b/vulkan/libvulkan/libvulkan.map.txt
@@ -0,0 +1,153 @@
+LIBVULKAN {
+ global:
+ vkAcquireNextImageKHR;
+ vkAllocateCommandBuffers;
+ vkAllocateDescriptorSets;
+ vkAllocateMemory;
+ vkBeginCommandBuffer;
+ vkBindBufferMemory;
+ vkBindImageMemory;
+ vkCmdBeginQuery;
+ vkCmdBeginRenderPass;
+ vkCmdBindDescriptorSets;
+ vkCmdBindIndexBuffer;
+ vkCmdBindPipeline;
+ vkCmdBindVertexBuffers;
+ vkCmdBlitImage;
+ vkCmdClearAttachments;
+ vkCmdClearColorImage;
+ vkCmdClearDepthStencilImage;
+ vkCmdCopyBuffer;
+ vkCmdCopyBufferToImage;
+ vkCmdCopyImage;
+ vkCmdCopyImageToBuffer;
+ vkCmdCopyQueryPoolResults;
+ vkCmdDispatch;
+ vkCmdDispatchIndirect;
+ vkCmdDraw;
+ vkCmdDrawIndexed;
+ vkCmdDrawIndexedIndirect;
+ vkCmdDrawIndirect;
+ vkCmdEndQuery;
+ vkCmdEndRenderPass;
+ vkCmdExecuteCommands;
+ vkCmdFillBuffer;
+ vkCmdNextSubpass;
+ vkCmdPipelineBarrier;
+ vkCmdPushConstants;
+ vkCmdResetEvent;
+ vkCmdResetQueryPool;
+ vkCmdResolveImage;
+ vkCmdSetBlendConstants;
+ vkCmdSetDepthBias;
+ vkCmdSetDepthBounds;
+ vkCmdSetEvent;
+ vkCmdSetLineWidth;
+ vkCmdSetScissor;
+ vkCmdSetStencilCompareMask;
+ vkCmdSetStencilReference;
+ vkCmdSetStencilWriteMask;
+ vkCmdSetViewport;
+ vkCmdUpdateBuffer;
+ vkCmdWaitEvents;
+ vkCmdWriteTimestamp;
+ vkCreateAndroidSurfaceKHR;
+ vkCreateBuffer;
+ vkCreateBufferView;
+ vkCreateCommandPool;
+ vkCreateComputePipelines;
+ vkCreateDescriptorPool;
+ vkCreateDescriptorSetLayout;
+ vkCreateDevice;
+ vkCreateEvent;
+ vkCreateFence;
+ vkCreateFramebuffer;
+ vkCreateGraphicsPipelines;
+ vkCreateImage;
+ vkCreateImageView;
+ vkCreateInstance;
+ vkCreatePipelineCache;
+ vkCreatePipelineLayout;
+ vkCreateQueryPool;
+ vkCreateRenderPass;
+ vkCreateSampler;
+ vkCreateSemaphore;
+ vkCreateShaderModule;
+ vkCreateSwapchainKHR;
+ vkDestroyBuffer;
+ vkDestroyBufferView;
+ vkDestroyCommandPool;
+ vkDestroyDescriptorPool;
+ vkDestroyDescriptorSetLayout;
+ vkDestroyDevice;
+ vkDestroyEvent;
+ vkDestroyFence;
+ vkDestroyFramebuffer;
+ vkDestroyImage;
+ vkDestroyImageView;
+ vkDestroyInstance;
+ vkDestroyPipeline;
+ vkDestroyPipelineCache;
+ vkDestroyPipelineLayout;
+ vkDestroyQueryPool;
+ vkDestroyRenderPass;
+ vkDestroySampler;
+ vkDestroySemaphore;
+ vkDestroyShaderModule;
+ vkDestroySurfaceKHR;
+ vkDestroySwapchainKHR;
+ vkDeviceWaitIdle;
+ vkEndCommandBuffer;
+ vkEnumerateDeviceExtensionProperties;
+ vkEnumerateDeviceLayerProperties;
+ vkEnumerateInstanceExtensionProperties;
+ vkEnumerateInstanceLayerProperties;
+ vkEnumeratePhysicalDevices;
+ vkFlushMappedMemoryRanges;
+ vkFreeCommandBuffers;
+ vkFreeDescriptorSets;
+ vkFreeMemory;
+ vkGetBufferMemoryRequirements;
+ vkGetDeviceMemoryCommitment;
+ vkGetDeviceProcAddr;
+ vkGetDeviceQueue;
+ vkGetEventStatus;
+ vkGetFenceStatus;
+ vkGetImageMemoryRequirements;
+ vkGetImageSparseMemoryRequirements;
+ vkGetImageSubresourceLayout;
+ vkGetInstanceProcAddr;
+ vkGetPhysicalDeviceFeatures;
+ vkGetPhysicalDeviceFormatProperties;
+ vkGetPhysicalDeviceImageFormatProperties;
+ vkGetPhysicalDeviceMemoryProperties;
+ vkGetPhysicalDeviceProperties;
+ vkGetPhysicalDeviceQueueFamilyProperties;
+ vkGetPhysicalDeviceSparseImageFormatProperties;
+ vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
+ vkGetPhysicalDeviceSurfaceFormatsKHR;
+ vkGetPhysicalDeviceSurfacePresentModesKHR;
+ vkGetPhysicalDeviceSurfaceSupportKHR;
+ vkGetPipelineCacheData;
+ vkGetQueryPoolResults;
+ vkGetRenderAreaGranularity;
+ vkGetSwapchainImagesKHR;
+ vkInvalidateMappedMemoryRanges;
+ vkMapMemory;
+ vkMergePipelineCaches;
+ vkQueueBindSparse;
+ vkQueuePresentKHR;
+ vkQueueSubmit;
+ vkQueueWaitIdle;
+ vkResetCommandBuffer;
+ vkResetCommandPool;
+ vkResetDescriptorPool;
+ vkResetEvent;
+ vkResetFences;
+ vkSetEvent;
+ vkUnmapMemory;
+ vkUpdateDescriptorSets;
+ vkWaitForFences;
+ local:
+ *;
+};