Merge "healthd: Correct the scaling factor for maxVoltage and maxCurrent." into nyc-dev
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 37d1146..ff4eb22 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -157,7 +157,7 @@
" (-r: replace existing application)\n"
" (-t: allow test packages)\n"
" (-s: install application on sdcard)\n"
- " (-d: allow version code downgrade)\n"
+ " (-d: allow version code downgrade (debuggable packages only))\n"
" (-g: grant all runtime permissions)\n"
" adb install-multiple [-lrtsdpg] <file...>\n"
" - push this package file to the device and install it\n"
@@ -165,7 +165,7 @@
" (-r: replace existing application)\n"
" (-t: allow test packages)\n"
" (-s: install application on sdcard)\n"
- " (-d: allow version code downgrade)\n"
+ " (-d: allow version code downgrade (debuggable packages only))\n"
" (-p: partial application install)\n"
" (-g: grant all runtime permissions)\n"
" adb uninstall [-k] <package> - remove this app package from the device\n"
diff --git a/base/include/base/unique_fd.h b/base/include/base/unique_fd.h
new file mode 100644
index 0000000..4117775
--- /dev/null
+++ b/base/include/base/unique_fd.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 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_BASE_UNIQUE_FD_H
+#define ANDROID_BASE_UNIQUE_FD_H
+
+#include <unistd.h>
+
+#include <base/macros.h>
+
+/* Container for a file descriptor that automatically closes the descriptor as
+ * it goes out of scope.
+ *
+ * unique_fd ufd(open("/some/path", "r"));
+ *
+ * if (ufd.get() < 0) // invalid descriptor
+ * return error;
+ *
+ * // Do something useful
+ *
+ * return 0; // descriptor is closed here
+ */
+namespace android {
+namespace base {
+
+class unique_fd final {
+ public:
+ unique_fd() : value_(-1) {}
+
+ explicit unique_fd(int value) : value_(value) {}
+ ~unique_fd() { clear(); }
+
+ unique_fd(unique_fd&& other) : value_(other.release()) {}
+ unique_fd& operator = (unique_fd&& s) {
+ reset(s.release());
+ return *this;
+ }
+
+ void reset(int new_value) {
+ if (value_ >= 0)
+ close(value_);
+ value_ = new_value;
+ }
+
+ void clear() {
+ reset(-1);
+ }
+
+ int get() const { return value_; }
+
+ int release() {
+ int ret = value_;
+ value_ = -1;
+ return ret;
+ }
+
+ private:
+ int value_;
+
+ DISALLOW_COPY_AND_ASSIGN(unique_fd);
+};
+
+} // namespace base
+} // namespace android
+
+#endif // ANDROID_BASE_UNIQUE_FD_H
diff --git a/include/log/log.h b/include/log/log.h
index 6ad6f0a..e606a84 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -589,6 +589,8 @@
int android_log_write_int32(android_log_context ctx, int32_t value);
int android_log_write_int64(android_log_context ctx, int64_t value);
int android_log_write_string8(android_log_context ctx, const char *value);
+int android_log_write_string8_len(android_log_context ctx,
+ const char *value, size_t maxlen);
int android_log_write_float32(android_log_context ctx, float value);
/* Submit the composed list context to the specified logger id */
diff --git a/include/system/graphics.h b/include/system/graphics.h
index e255614..880cb9f 100644
--- a/include/system/graphics.h
+++ b/include/system/graphics.h
@@ -927,9 +927,9 @@
* The values are encoded using the full range ([0,255] for 8-bit) for all
* components.
*/
- HAL_DATASPACE_SRGB_LINEAR_LEGACY = 0x200,
+ HAL_DATASPACE_SRGB_LINEAR = 0x200, // deprecated, use HAL_DATASPACE_V0_SRGB_LINEAR
- HAL_DATASPACE_SRGB_LINEAR = HAL_DATASPACE_STANDARD_BT709 |
+ HAL_DATASPACE_V0_SRGB_LINEAR = HAL_DATASPACE_STANDARD_BT709 |
HAL_DATASPACE_TRANSFER_LINEAR | HAL_DATASPACE_RANGE_FULL,
@@ -946,9 +946,9 @@
*
* Use full range and BT.709 standard.
*/
- HAL_DATASPACE_SRGB_LEGACY = 0x201,
+ HAL_DATASPACE_SRGB = 0x201, // deprecated, use HAL_DATASPACE_V0_SRGB
- HAL_DATASPACE_SRGB = HAL_DATASPACE_STANDARD_BT709 |
+ HAL_DATASPACE_V0_SRGB = HAL_DATASPACE_STANDARD_BT709 |
HAL_DATASPACE_TRANSFER_SRGB | HAL_DATASPACE_RANGE_FULL,
@@ -970,9 +970,9 @@
*
* Use full range, BT.601 transfer and BT.601_625 standard.
*/
- HAL_DATASPACE_JFIF_LEGACY = 0x101,
+ HAL_DATASPACE_JFIF = 0x101, // deprecated, use HAL_DATASPACE_V0_JFIF
- HAL_DATASPACE_JFIF = HAL_DATASPACE_STANDARD_BT601_625 |
+ HAL_DATASPACE_V0_JFIF = HAL_DATASPACE_STANDARD_BT601_625 |
HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_FULL,
/*
@@ -982,9 +982,9 @@
*
* Use limited range, BT.601 transfer and BT.601_625 standard.
*/
- HAL_DATASPACE_BT601_625_LEGACY = 0x102,
+ HAL_DATASPACE_BT601_625 = 0x102, // deprecated, use HAL_DATASPACE_V0_BT601_625
- HAL_DATASPACE_BT601_625 = HAL_DATASPACE_STANDARD_BT601_625 |
+ HAL_DATASPACE_V0_BT601_625 = HAL_DATASPACE_STANDARD_BT601_625 |
HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_LIMITED,
@@ -995,9 +995,9 @@
*
* Use limited range, BT.601 transfer and BT.601_525 standard.
*/
- HAL_DATASPACE_BT601_525_LEGACY = 0x103,
+ HAL_DATASPACE_BT601_525 = 0x103, // deprecated, use HAL_DATASPACE_V0_BT601_525
- HAL_DATASPACE_BT601_525 = HAL_DATASPACE_STANDARD_BT601_525 |
+ HAL_DATASPACE_V0_BT601_525 = HAL_DATASPACE_STANDARD_BT601_525 |
HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_LIMITED,
/*
@@ -1007,9 +1007,9 @@
*
* Use limited range, BT.709 transfer and BT.709 standard.
*/
- HAL_DATASPACE_BT709_LEGACY = 0x104,
+ HAL_DATASPACE_BT709 = 0x104, // deprecated, use HAL_DATASPACE_V0_BT709
- HAL_DATASPACE_BT709 = HAL_DATASPACE_STANDARD_BT709 |
+ HAL_DATASPACE_V0_BT709 = HAL_DATASPACE_STANDARD_BT709 |
HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_LIMITED,
/*
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index 54d1122..1a26695 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -138,9 +138,9 @@
ta_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
#ifdef USE_SCHEDBOOST
- filename = "/sys/fs/cgroup/stune/foreground/tasks";
+ filename = "/dev/stune/foreground/tasks";
fg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
- filename = "/sys/fs/cgroup/stune/tasks";
+ filename = "/dev/stune/tasks";
bg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
#endif
}
@@ -266,8 +266,8 @@
policy = _policy(policy);
pthread_once(&the_once, __initialize);
- int fd;
- int boost_fd;
+ int fd = -1;
+ int boost_fd = -1;
switch (policy) {
case SP_BACKGROUND:
fd = bg_cpuset_fd;
diff --git a/libcutils/tests/Android.mk b/libcutils/tests/Android.mk
index 4da5ed6..52cf5f4 100644
--- a/libcutils/tests/Android.mk
+++ b/libcutils/tests/Android.mk
@@ -23,8 +23,9 @@
test_target_only_src_files := \
MemsetTest.cpp \
PropertiesTest.cpp \
+ trace-dev_test.cpp \
-test_libraries := libcutils liblog
+test_libraries := libcutils liblog libbase
#
diff --git a/libcutils/tests/trace-dev_test.cpp b/libcutils/tests/trace-dev_test.cpp
new file mode 100644
index 0000000..edf981b
--- /dev/null
+++ b/libcutils/tests/trace-dev_test.cpp
@@ -0,0 +1,295 @@
+/*
+ * 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 <sys/types.h>
+#include <unistd.h>
+
+#include <memory>
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
+#include <gtest/gtest.h>
+
+#include "../trace-dev.c"
+
+class TraceDevTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ lseek(tmp_file_.fd, 0, SEEK_SET);
+ atrace_marker_fd = tmp_file_.fd;
+ }
+
+ void TearDown() override {
+ atrace_marker_fd = -1;
+ }
+
+ TemporaryFile tmp_file_;
+
+ static std::string MakeName(size_t length) {
+ std::string name;
+ for (size_t i = 0; i < length; i++) {
+ name += '0' + (i % 10);
+ }
+ return name;
+ }
+};
+
+TEST_F(TraceDevTest, atrace_begin_body_normal) {
+ atrace_begin_body("fake_name");
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("B|%d|fake_name", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_begin_body_exact) {
+ std::string expected = android::base::StringPrintf("B|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1);
+ atrace_begin_body(name.c_str());
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name;
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_begin_body(name.c_str());
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_begin_body_truncated) {
+ std::string expected = android::base::StringPrintf("B|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_begin_body(name.c_str());
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 1;
+ expected += android::base::StringPrintf("%.*s", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_begin_body_normal) {
+ atrace_async_begin_body("fake_name", 12345);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("S|%d|fake_name|12345", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_begin_body_exact) {
+ std::string expected = android::base::StringPrintf("S|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
+ atrace_async_begin_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name + "|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_async_begin_body(name.c_str(), 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_begin_body_truncated) {
+ std::string expected = android::base::StringPrintf("S|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_begin_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
+ expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_end_body_normal) {
+ atrace_async_end_body("fake_name", 12345);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("F|%d|fake_name|12345", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_end_body_exact) {
+ std::string expected = android::base::StringPrintf("F|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
+ atrace_async_end_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name + "|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_async_end_body(name.c_str(), 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_end_body_truncated) {
+ std::string expected = android::base::StringPrintf("F|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_end_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
+ expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int_body_normal) {
+ atrace_int_body("fake_name", 12345);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("C|%d|fake_name|12345", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int_body_exact) {
+ std::string expected = android::base::StringPrintf("C|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
+ atrace_int_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name + "|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_int_body(name.c_str(), 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int_body_truncated) {
+ std::string expected = android::base::StringPrintf("C|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_int_body(name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
+ expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int64_body_normal) {
+ atrace_int64_body("fake_name", 17179869183L);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("C|%d|fake_name|17179869183", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int64_body_exact) {
+ std::string expected = android::base::StringPrintf("C|%d|", getpid());
+ std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 13);
+ atrace_int64_body(name.c_str(), 17179869183L);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += name + "|17179869183";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the exact same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_int64_body(name.c_str(), 17179869183L);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_int64_body_truncated) {
+ std::string expected = android::base::StringPrintf("C|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_int64_body(name.c_str(), 17179869183L);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 13;
+ expected += android::base::StringPrintf("%.*s|17179869183", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
diff --git a/libcutils/trace-dev.c b/libcutils/trace-dev.c
index f025256..5df1c5a 100644
--- a/libcutils/trace-dev.c
+++ b/libcutils/trace-dev.c
@@ -194,49 +194,47 @@
void atrace_begin_body(const char* name)
{
char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "B|%d|%s", getpid(), name);
+ int len = snprintf(buf, sizeof(buf), "B|%d|%s", getpid(), name);
+ if (len >= (int) sizeof(buf)) {
+ ALOGW("Truncated name in %s: %s\n", __FUNCTION__, name);
+ len = sizeof(buf) - 1;
+ }
write(atrace_marker_fd, buf, len);
}
+#define WRITE_MSG(format_begin, format_end, pid, name, value) { \
+ char buf[ATRACE_MESSAGE_LENGTH]; \
+ int len = snprintf(buf, sizeof(buf), format_begin "%s" format_end, pid, \
+ name, value); \
+ if (len >= (int) sizeof(buf)) { \
+ /* Given the sizeof(buf), and all of the current format buffers, \
+ * it is impossible for name_len to be < 0 if len >= sizeof(buf). */ \
+ int name_len = strlen(name) - (len - sizeof(buf)) - 1; \
+ /* Truncate the name to make the message fit. */ \
+ ALOGW("Truncated name in %s: %s\n", __FUNCTION__, name); \
+ len = snprintf(buf, sizeof(buf), format_begin "%.*s" format_end, pid, \
+ name_len, name, value); \
+ } \
+ write(atrace_marker_fd, buf, len); \
+}
void atrace_async_begin_body(const char* name, int32_t cookie)
{
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "S|%d|%s|%" PRId32,
- getpid(), name, cookie);
- write(atrace_marker_fd, buf, len);
+ WRITE_MSG("S|%d|", "|%" PRId32, getpid(), name, cookie);
}
void atrace_async_end_body(const char* name, int32_t cookie)
{
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "F|%d|%s|%" PRId32,
- getpid(), name, cookie);
- write(atrace_marker_fd, buf, len);
+ WRITE_MSG("F|%d|", "|%" PRId32, getpid(), name, cookie);
}
void atrace_int_body(const char* name, int32_t value)
{
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%" PRId32,
- getpid(), name, value);
- write(atrace_marker_fd, buf, len);
+ WRITE_MSG("C|%d|", "|%" PRId32, getpid(), name, value);
}
void atrace_int64_body(const char* name, int64_t value)
{
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%" PRId64,
- getpid(), name, value);
- write(atrace_marker_fd, buf, len);
+ WRITE_MSG("C|%d|", "|%" PRId64, getpid(), name, value);
}
diff --git a/liblog/Android.mk b/liblog/Android.mk
index c7b76d8..dd5b518 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -24,11 +24,10 @@
# so make sure we do not regret hard-coding it as follows:
liblog_cflags := -DLIBLOG_LOG_TAG=1005
-liblog_host_sources := logd_write.c log_event_write.c fake_log_device.c event.logtags
-liblog_target_sources := logd_write.c log_event_write.c event_tag_map.c log_time.cpp log_is_loggable.c
-liblog_target_sources += logprint.c
-liblog_target_sources += log_read.c
-liblog_target_sources += log_event_list.c
+liblog_sources := logd_write.c log_event_list.c log_event_write.c
+liblog_host_sources := $(liblog_sources) fake_log_device.c event.logtags
+liblog_target_sources := $(liblog_sources) event_tag_map.c
+liblog_target_sources += log_time.cpp log_is_loggable.c logprint.c log_read.c
# Shared and static library for host
# ========================================================
diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c
index 50a27c0..2213f21 100644
--- a/liblog/log_event_list.c
+++ b/liblog/log_event_list.c
@@ -195,9 +195,10 @@
return 0;
}
-int android_log_write_string8(android_log_context ctx, const char *value) {
+int android_log_write_string8_len(android_log_context ctx,
+ const char *value, size_t maxlen) {
size_t needed;
- int32_t len;
+ ssize_t len;
android_log_context_internal *context;
context = (android_log_context_internal *)ctx;
@@ -208,13 +209,13 @@
return -EIO;
}
if (!value) {
- return -EINVAL;
+ value = "";
}
- len = strlen(value);
- needed = sizeof(uint8_t) + sizeof(len) + len;
+ len = strnlen(value, maxlen);
+ needed = sizeof(uint8_t) + sizeof(int32_t) + len;
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
/* Truncate string for delivery */
- len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(len);
+ len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);
if (len <= 0) {
context->overflow = true;
return -EIO;
@@ -223,9 +224,15 @@
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_STRING;
copy4LE(&context->storage[context->pos + 1], len);
- memcpy(&context->storage[context->pos + 5], value, len);
+ if (len) {
+ memcpy(&context->storage[context->pos + 5], value, len);
+ }
context->pos += needed;
- return 0;
+ return len;
+}
+
+int android_log_write_string8(android_log_context ctx, const char *value) {
+ return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);
}
int android_log_write_float32(android_log_context ctx, float value) {
diff --git a/liblog/log_event_write.c b/liblog/log_event_write.c
index 0bc42d5..ad42edd 100644
--- a/liblog/log_event_write.c
+++ b/liblog/log_event_write.c
@@ -15,74 +15,33 @@
*/
#include <errno.h>
-#include <string.h>
#include <log/log.h>
-#include <log/logger.h>
-#define MAX_EVENT_PAYLOAD 512
#define MAX_SUBTAG_LEN 32
-static inline void copy4LE(uint8_t *buf, size_t pos, int val)
+int __android_log_error_write(int tag, const char *subTag, int32_t uid,
+ const char *data, uint32_t dataLen)
{
- buf[pos] = val & 0xFF;
- buf[pos+1] = (val >> 8) & 0xFF;
- buf[pos+2] = (val >> 16) & 0xFF;
- buf[pos+3] = (val >> 24) & 0xFF;
-}
+ int ret = -EINVAL;
-int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data,
- uint32_t dataLen)
-{
- uint8_t buf[MAX_EVENT_PAYLOAD];
- size_t pos = 0;
- uint32_t subTagLen = 0;
- uint32_t roomLeftForData = 0;
+ if (subTag && (data || !dataLen)) {
+ android_log_context ctx = create_android_logger(tag);
- if ((subTag == NULL) || ((data == NULL) && (dataLen != 0))) return -EINVAL;
-
- subTagLen = strlen(subTag);
-
- // Truncate subtags that are too long.
- subTagLen = subTagLen > MAX_SUBTAG_LEN ? MAX_SUBTAG_LEN : subTagLen;
-
- // Truncate dataLen if it is too long.
- roomLeftForData = MAX_EVENT_PAYLOAD -
- (1 + // EVENT_TYPE_LIST
- 1 + // Number of elements in list
- 1 + // EVENT_TYPE_STRING
- sizeof(subTagLen) +
- subTagLen +
- 1 + // EVENT_TYPE_INT
- sizeof(uid) +
- 1 + // EVENT_TYPE_STRING
- sizeof(dataLen));
- dataLen = dataLen > roomLeftForData ? roomLeftForData : dataLen;
-
- buf[pos++] = EVENT_TYPE_LIST;
- buf[pos++] = 3; // Number of elements in the list (subTag, uid, data)
-
- // Write sub tag.
- buf[pos++] = EVENT_TYPE_STRING;
- copy4LE(buf, pos, subTagLen);
- pos += 4;
- memcpy(&buf[pos], subTag, subTagLen);
- pos += subTagLen;
-
- // Write UID.
- buf[pos++] = EVENT_TYPE_INT;
- copy4LE(buf, pos, uid);
- pos += 4;
-
- // Write data.
- buf[pos++] = EVENT_TYPE_STRING;
- copy4LE(buf, pos, dataLen);
- pos += 4;
- if (dataLen != 0)
- {
- memcpy(&buf[pos], data, dataLen);
- pos += dataLen;
+ ret = -ENOMEM;
+ if (ctx) {
+ ret = android_log_write_string8_len(ctx, subTag, MAX_SUBTAG_LEN);
+ if (ret >= 0) {
+ ret = android_log_write_int32(ctx, uid);
+ if (ret >= 0) {
+ ret = android_log_write_string8_len(ctx, data, dataLen);
+ if (ret >= 0) {
+ ret = android_log_write_list(ctx, LOG_ID_EVENTS);
+ }
+ }
+ }
+ android_log_destroy(&ctx);
+ }
}
-
- return __android_log_bwrite(tag, buf, pos);
+ return ret;
}
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 65d1456..3da4815 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -1368,7 +1368,7 @@
const int TAG = 123456782;
const char SUBTAG[] = "test-subtag";
const int UID = -1;
- const int DATA_LEN = SIZEOF_MAX_PAYLOAD_BUF;
+ const int DATA_LEN = sizeof(max_payload_buf);
struct logger_list *logger_list;
pid_t pid = getpid();
@@ -1439,9 +1439,9 @@
}
eventData += dataLen;
- // 4 bytes for the tag, and 512 bytes for the log since the
- // max_payload_buf should be truncated.
- ASSERT_EQ(4 + 512, eventData - original);
+ // 4 bytes for the tag, and max_payload_buf should be truncated.
+ ASSERT_LE(4 + 512, eventData - original); // worst expectations
+ ASSERT_GT(4 + DATA_LEN, eventData - original); // must be truncated
++count;
}
@@ -2054,6 +2054,30 @@
return "[1,[2,[3,[4,[5,[6]]]]]]";
}
+static const char *event_test_android_log_error_write(uint32_t tag, size_t &expected_len) {
+ EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, "dlroW olleH", 11));
+
+ expected_len = sizeof(uint32_t) +
+ sizeof(uint8_t) + sizeof(uint8_t) +
+ sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
+ sizeof(uint8_t) + sizeof(uint32_t) +
+ sizeof(uint8_t) + sizeof(uint32_t) + sizeof("dlroW olleH") - 1;
+
+ return "[Hello World,42,dlroW olleH]";
+}
+
+static const char *event_test_android_log_error_write_null(uint32_t tag, size_t &expected_len) {
+ EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, NULL, 0));
+
+ expected_len = sizeof(uint32_t) +
+ sizeof(uint8_t) + sizeof(uint8_t) +
+ sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
+ sizeof(uint8_t) + sizeof(uint32_t) +
+ sizeof(uint8_t) + sizeof(uint32_t) + sizeof("") - 1;
+
+ return "[Hello World,42,]";
+}
+
// make sure all user buffers are flushed
static void print_barrier() {
std::cout.flush();
@@ -2172,6 +2196,14 @@
create_android_logger(event_test_7_level_suffix);
}
+TEST(liblog, create_android_logger_android_log_error_write) {
+ create_android_logger(event_test_android_log_error_write);
+}
+
+TEST(liblog, create_android_logger_android_log_error_write_null) {
+ create_android_logger(event_test_android_log_error_write_null);
+}
+
TEST(liblog, create_android_logger_overflow) {
android_log_context ctx;
diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h
index 5644aa6..b16c0e6 100644
--- a/libnativeloader/include/nativeloader/native_loader.h
+++ b/libnativeloader/include/nativeloader/native_loader.h
@@ -29,9 +29,19 @@
void PreloadPublicNativeLibraries();
__attribute__((visibility("default")))
-void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
- jobject class_loader, bool is_shared, jstring library_path,
- jstring permitted_path);
+jstring CreateClassLoaderNamespace(JNIEnv* env,
+ int32_t target_sdk_version,
+ jobject class_loader,
+ bool is_shared,
+ jstring library_path,
+ jstring permitted_path);
+
+__attribute__((visibility("default")))
+void* OpenNativeLibrary(JNIEnv* env,
+ int32_t target_sdk_version,
+ const char* path,
+ jobject class_loader,
+ jstring library_path);
#if defined(__ANDROID__)
// Look up linker namespace by class_loader. Returns nullptr if
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index b763631..837924b 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -21,6 +21,7 @@
#ifdef __ANDROID__
#include <android/dlext.h>
#include "cutils/properties.h"
+#include "log/log.h"
#endif
#include <algorithm>
@@ -61,11 +62,12 @@
public:
LibraryNamespaces() : initialized_(false) { }
- android_namespace_t* GetOrCreate(JNIEnv* env, jobject class_loader,
- bool is_shared,
- jstring java_library_path,
- jstring java_permitted_path,
- int32_t target_sdk_version) {
+ android_namespace_t* Create(JNIEnv* env,
+ jobject class_loader,
+ bool is_shared,
+ jstring java_library_path,
+ jstring java_permitted_path,
+ int32_t target_sdk_version) {
ScopedUtfChars library_path(env, java_library_path);
std::string permitted_path;
@@ -82,9 +84,7 @@
android_namespace_t* ns = FindNamespaceByClassLoader(env, class_loader);
- if (ns != nullptr) {
- return ns;
- }
+ LOG_FATAL_IF(ns != nullptr, "There is already a namespace associated with this classloader");
uint64_t namespace_type = ANDROID_NAMESPACE_TYPE_ISOLATED;
if (is_shared) {
@@ -99,7 +99,9 @@
permitted_path.c_str() :
nullptr);
- namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns));
+ if (ns != nullptr) {
+ namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns));
+ }
return ns;
}
@@ -147,6 +149,10 @@
};
static LibraryNamespaces* g_namespaces = new LibraryNamespaces;
+
+static bool namespaces_enabled(uint32_t target_sdk_version) {
+ return target_sdk_version > 0;
+}
#endif
void PreloadPublicNativeLibraries() {
@@ -156,20 +162,52 @@
}
-void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
- jobject class_loader, bool is_shared, jstring java_library_path,
- jstring java_permitted_path) {
+jstring CreateClassLoaderNamespace(JNIEnv* env,
+ int32_t target_sdk_version,
+ jobject class_loader,
+ bool is_shared,
+ jstring library_path,
+ jstring permitted_path) {
#if defined(__ANDROID__)
- if (target_sdk_version == 0 || class_loader == nullptr) {
+ if (!namespaces_enabled(target_sdk_version)) {
+ return nullptr;
+ }
+
+ android_namespace_t* ns = g_namespaces->Create(env,
+ class_loader,
+ is_shared,
+ library_path,
+ permitted_path,
+ target_sdk_version);
+ if (ns == nullptr) {
+ return env->NewStringUTF(dlerror());
+ }
+#else
+ UNUSED(env, target_sdk_version, class_loader, is_shared,
+ library_path, permitted_path);
+#endif
+ return nullptr;
+}
+
+void* OpenNativeLibrary(JNIEnv* env,
+ int32_t target_sdk_version,
+ const char* path,
+ jobject class_loader,
+ jstring library_path) {
+#if defined(__ANDROID__)
+ if (!namespaces_enabled(target_sdk_version) || class_loader == nullptr) {
return dlopen(path, RTLD_NOW);
}
- android_namespace_t* ns =
- g_namespaces->GetOrCreate(env, class_loader, is_shared,
- java_library_path, java_permitted_path, target_sdk_version);
+ android_namespace_t* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader);
if (ns == nullptr) {
- return nullptr;
+ // This is the case where the classloader was not created by ApplicationLoaders
+ // In this case we create an isolated not-shared namespace for it.
+ ns = g_namespaces->Create(env, class_loader, false, library_path, nullptr, target_sdk_version);
+ if (ns == nullptr) {
+ return nullptr;
+ }
}
android_dlextinfo extinfo;
@@ -178,8 +216,7 @@
return android_dlopen_ext(path, RTLD_NOW, &extinfo);
#else
- UNUSED(env, target_sdk_version, class_loader, is_shared,
- java_library_path, java_permitted_path);
+ UNUSED(env, target_sdk_version, class_loader, library_path);
return dlopen(path, RTLD_NOW);
#endif
}
diff --git a/libutils/Android.mk b/libutils/Android.mk
index 8c4fd15..3584b6a 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -72,7 +72,7 @@
ifeq ($(TARGET_ARCH),mips)
LOCAL_CFLAGS += -DALIGN_DOUBLE
endif
-LOCAL_CFLAGS += -Werror
+LOCAL_CFLAGS += -Werror -fvisibility=protected
LOCAL_STATIC_LIBRARIES := \
libcutils \
diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp
index fd45c4a..6a26d00 100644
--- a/logd/FlushCommand.cpp
+++ b/logd/FlushCommand.cpp
@@ -16,7 +16,10 @@
#include <stdlib.h>
+#include <private/android_filesystem_config.h>
+
#include "FlushCommand.h"
+#include "LogBuffer.h"
#include "LogBufferElement.h"
#include "LogCommand.h"
#include "LogReader.h"
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index fffc9ba..230dd11 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -20,10 +20,13 @@
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/prctl.h>
#include <sys/uio.h>
#include <syslog.h>
+#include <string>
+
#include <cutils/properties.h>
#include <log/logger.h>
#include <private/android_filesystem_config.h>
@@ -31,7 +34,9 @@
#include "libaudit.h"
#include "LogAudit.h"
+#include "LogBuffer.h"
#include "LogKlog.h"
+#include "LogReader.h"
#ifndef AUDITD_ENFORCE_INTEGRITY
#define AUDITD_ENFORCE_INTEGRITY false
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index 455ed58..3a84541 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -18,7 +18,10 @@
#define _LOGD_LOG_AUDIT_H__
#include <sysutils/SocketListener.h>
-#include "LogReader.h"
+
+#include "LogBuffer.h"
+
+class LogReader;
class LogAudit : public SocketListener {
LogBuffer *logbuf;
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index fde9ad7..eb5194c 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -25,9 +25,11 @@
#include <log/logger.h>
#include <private/android_logger.h>
+#include "LogBuffer.h"
#include "LogBufferElement.h"
#include "LogCommand.h"
#include "LogReader.h"
+#include "LogUtils.h"
const uint64_t LogBufferElement::FLUSH_ERROR(0);
atomic_int_fast64_t LogBufferElement::sequence(1);
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 9690489..ac2b128 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -20,13 +20,16 @@
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/prctl.h>
#include <sys/uio.h>
#include <syslog.h>
#include <log/logger.h>
+#include "LogBuffer.h"
#include "LogKlog.h"
+#include "LogReader.h"
#define KMSG_PRIORITY(PRI) \
'<', \
diff --git a/logd/LogKlog.h b/logd/LogKlog.h
index 3c8cc87..ee73b71 100644
--- a/logd/LogKlog.h
+++ b/logd/LogKlog.h
@@ -19,10 +19,12 @@
#include <sysutils/SocketListener.h>
#include <log/log_read.h>
-#include "LogReader.h"
char *log_strntok_r(char *s, size_t *len, char **saveptr, size_t *sublen);
+class LogBuffer;
+class LogReader;
+
class LogKlog : public SocketListener {
LogBuffer *logbuf;
LogReader *reader;
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index 846dd7c..39dd227 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -27,6 +27,7 @@
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
+#include "LogBuffer.h"
#include "LogListener.h"
#include "LogUtils.h"
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 667a3f2..2c07984 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -18,11 +18,15 @@
#include <poll.h>
#include <sys/prctl.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <cutils/sockets.h>
-#include "LogReader.h"
#include "FlushCommand.h"
+#include "LogBuffer.h"
+#include "LogBufferElement.h"
+#include "LogReader.h"
+#include "LogUtils.h"
LogReader::LogReader(LogBuffer *logbuf) :
SocketListener(getLogSocket(), true),
@@ -176,6 +180,11 @@
}
FlushCommand command(*this, nonBlock, tail, logMask, pid, sequence, timeout);
+
+ // Set acceptable upper limit to wait for slow reader processing b/27242723
+ struct timeval t = { LOGD_SNDTIMEO, 0 };
+ setsockopt(cli->getSocket(), SOL_SOCKET, SO_SNDTIMEO, (const char *)&t, sizeof(t));
+
command.runSocketCommand(cli);
return true;
}
diff --git a/logd/LogReader.h b/logd/LogReader.h
index 91559a3..98674b8 100644
--- a/logd/LogReader.h
+++ b/logd/LogReader.h
@@ -18,8 +18,10 @@
#define _LOGD_LOG_WRITER_H__
#include <sysutils/SocketListener.h>
-#include "LogBuffer.h"
-#include "LogTimes.h"
+
+#define LOGD_SNDTIMEO 32
+
+class LogBuffer;
class LogReader : public SocketListener {
LogBuffer &mLogbuf;
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index 1117088..f5969df 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -27,6 +27,7 @@
#include <log/log.h>
class LogReader;
+class LogBufferElement;
class LogTimeEntry {
static pthread_mutex_t timesLock;
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index de19790..2014374 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -30,6 +30,8 @@
#include <log/log.h>
#include <log/logger.h>
+#include "../LogReader.h" // pickup LOGD_SNDTIMEO
+
/*
* returns statistics
*/
@@ -253,6 +255,9 @@
fprintf(stderr, "lid=crash ");
break;
case 5:
+ fprintf(stderr, "lid=security ");
+ break;
+ case 6:
fprintf(stderr, "lid=kernel ");
break;
default:
@@ -710,3 +715,56 @@
EXPECT_TRUE(content_timeout);
EXPECT_NE(0U, alarm_timeout);
}
+
+// b/27242723 confirmed fixed
+TEST(logd, SNDTIMEO) {
+ static const unsigned sndtimeo = LOGD_SNDTIMEO; // <sigh> it has to be done!
+ static const unsigned sleep_time = sndtimeo + 3;
+ static const unsigned alarm_time = sleep_time + 5;
+
+ int fd;
+
+ ASSERT_TRUE((fd = socket_local_client("logdr",
+ ANDROID_SOCKET_NAMESPACE_RESERVED,
+ SOCK_SEQPACKET)) > 0);
+
+ struct sigaction ignore, old_sigaction;
+ memset(&ignore, 0, sizeof(ignore));
+ ignore.sa_handler = caught_signal;
+ sigemptyset(&ignore.sa_mask);
+ sigaction(SIGALRM, &ignore, &old_sigaction);
+ unsigned int old_alarm = alarm(alarm_time);
+
+ static const char ask[] = "stream lids=0,1,2,3,4,5,6"; // all sources
+ bool reader_requested = write(fd, ask, sizeof(ask)) == sizeof(ask);
+ EXPECT_TRUE(reader_requested);
+
+ log_msg msg;
+ bool read_one = recv(fd, msg.buf, sizeof(msg), 0) > 0;
+
+ EXPECT_TRUE(read_one);
+ if (read_one) {
+ dump_log_msg("user", &msg, 3, -1);
+ }
+
+ fprintf (stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo);
+ sleep(sleep_time);
+
+ // flush will block if we did not trigger. if it did, last entry returns 0
+ int recv_ret;
+ do {
+ recv_ret = recv(fd, msg.buf, sizeof(msg), 0);
+ } while (recv_ret > 0);
+ int save_errno = (recv_ret < 0) ? errno : 0;
+
+ EXPECT_NE(0U, alarm(old_alarm));
+ sigaction(SIGALRM, &old_sigaction, NULL);
+
+ EXPECT_EQ(0, recv_ret);
+ if (recv_ret > 0) {
+ dump_log_msg("user", &msg, 3, -1);
+ }
+ EXPECT_EQ(0, save_errno);
+
+ close(fd);
+}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 3c88d31..3428417 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -44,15 +44,15 @@
mkdir /acct/uid
# Create energy-aware scheduler tuning nodes
- mkdir /sys/fs/cgroup/stune
- mount cgroup none /sys/fs/cgroup/stune schedtune
- mkdir /sys/fs/cgroup/stune/foreground
- chown system system /sys/fs/cgroup/stune
- chown system system /sys/fs/cgroup/stune/foreground
- chown system system /sys/fs/cgroup/stune/tasks
- chown system system /sys/fs/cgroup/stune/foreground/tasks
- chmod 0664 /sys/fs/cgroup/stune/tasks
- chmod 0664 /sys/fs/cgroup/stune/foreground/tasks
+ mkdir /dev/stune
+ mount cgroup none /dev/stune schedtune
+ mkdir /dev/stune/foreground
+ chown system system /dev/stune
+ chown system system /dev/stune/foreground
+ chown system system /dev/stune/tasks
+ chown system system /dev/stune/foreground/tasks
+ chmod 0664 /dev/stune/tasks
+ chmod 0664 /dev/stune/foreground/tasks
# Mount staging areas for devices managed by vold
# See storage config details at http://source.android.com/tech/storage/
diff --git a/rootdir/init.zygote32.rc b/rootdir/init.zygote32.rc
index 1b1d747..22b9d6b 100644
--- a/rootdir/init.zygote32.rc
+++ b/rootdir/init.zygote32.rc
@@ -7,4 +7,4 @@
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
- writepid /dev/cpuset/foreground/tasks /sys/fs/cgroup/stune/foreground/tasks
+ writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc
index 04b8854..555eda4 100644
--- a/rootdir/init.zygote32_64.rc
+++ b/rootdir/init.zygote32_64.rc
@@ -13,4 +13,4 @@
class main
socket zygote_secondary stream 660 root system
onrestart restart zygote
- writepid /dev/cpuset/foreground/tasks /sys/fs/cgroup/stune/foreground/tasks
+ writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
diff --git a/rootdir/init.zygote64.rc b/rootdir/init.zygote64.rc
index 21ff647..297468c 100644
--- a/rootdir/init.zygote64.rc
+++ b/rootdir/init.zygote64.rc
@@ -7,4 +7,4 @@
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
- writepid /dev/cpuset/foreground/tasks /sys/fs/cgroup/stune/foreground/tasks
+ writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
index 257ae19..46f9f02 100644
--- a/rootdir/init.zygote64_32.rc
+++ b/rootdir/init.zygote64_32.rc
@@ -13,4 +13,4 @@
class main
socket zygote_secondary stream 660 root system
onrestart restart zygote
- writepid /dev/cpuset/foreground/tasks /sys/fs/cgroup/stune/foreground/tasks
+ writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks