Merge "libutils: Clarify Condition::signal wakes up exactly one thread"
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 8557bcf..98a2af4 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -343,7 +343,7 @@
/* Add an entry to the fstab, and return 0 on success or -1 on error */
int fs_mgr_add_entry(struct fstab *fstab,
const char *mount_point, const char *fs_type,
- const char *blk_device, long long length)
+ const char *blk_device)
{
struct fstab_rec *new_fstab_recs;
int n = fstab->num_entries;
diff --git a/fs_mgr/fs_mgr_main.c b/fs_mgr/fs_mgr_main.c
index 4bde4a1..e5a00d5 100644
--- a/fs_mgr/fs_mgr_main.c
+++ b/fs_mgr/fs_mgr_main.c
@@ -80,10 +80,10 @@
int a_flag=0;
int u_flag=0;
int n_flag=0;
- char *n_name;
- char *n_blk_dev;
- char *fstab_file;
- struct fstab *fstab;
+ char *n_name=NULL;
+ char *n_blk_dev=NULL;
+ char *fstab_file=NULL;
+ struct fstab *fstab=NULL;
klog_init();
klog_set_level(6);
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 0f90c32..835cf64 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -57,7 +57,7 @@
char *real_blk_device, int size);
int fs_mgr_add_entry(struct fstab *fstab,
const char *mount_point, const char *fs_type,
- const char *blk_device, long long length);
+ const char *blk_device);
struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path);
int fs_mgr_is_voldmanaged(struct fstab_rec *fstab);
int fs_mgr_is_nonremovable(struct fstab_rec *fstab);
diff --git a/healthd/healthd_board_default.cpp b/healthd/healthd_board_default.cpp
index b2bb516..ed4ddb4 100644
--- a/healthd/healthd_board_default.cpp
+++ b/healthd/healthd_board_default.cpp
@@ -16,13 +16,13 @@
#include <healthd.h>
-void healthd_board_init(struct healthd_config *config)
+void healthd_board_init(struct healthd_config*)
{
// use defaults
}
-int healthd_board_battery_update(struct android::BatteryProperties *props)
+int healthd_board_battery_update(struct android::BatteryProperties*)
{
// return 0 to log periodic polled battery status to kernel log
return 0;
diff --git a/include/cutils/properties.h b/include/cutils/properties.h
index 2c70165..798db8b 100644
--- a/include/cutils/properties.h
+++ b/include/cutils/properties.h
@@ -20,6 +20,7 @@
#include <sys/cdefs.h>
#include <stddef.h>
#include <sys/system_properties.h>
+#include <stdint.h>
#ifdef __cplusplus
extern "C" {
@@ -44,6 +45,64 @@
*/
int property_get(const char *key, char *value, const char *default_value);
+/* property_get_bool: returns the value of key coerced into a
+** boolean. If the property is not set, then the default value is returned.
+**
+* The following is considered to be true (1):
+** "1", "true", "y", "yes", "on"
+**
+** The following is considered to be false (0):
+** "0", "false", "n", "no", "off"
+**
+** The conversion is whitespace-sensitive (e.g. " off" will not be false).
+**
+** If no property with this key is set (or the key is NULL) or the boolean
+** conversion fails, the default value is returned.
+**/
+int8_t property_get_bool(const char *key, int8_t default_value);
+
+/* property_get_int64: returns the value of key truncated and coerced into a
+** int64_t. If the property is not set, then the default value is used.
+**
+** The numeric conversion is identical to strtoimax with the base inferred:
+** - All digits up to the first non-digit characters are read
+** - The longest consecutive prefix of digits is converted to a long
+**
+** Valid strings of digits are:
+** - An optional sign character + or -
+** - An optional prefix indicating the base (otherwise base 10 is assumed)
+** -- 0 prefix is octal
+** -- 0x / 0X prefix is hex
+**
+** Leading/trailing whitespace is ignored. Overflow/underflow will cause
+** numeric conversion to fail.
+**
+** If no property with this key is set (or the key is NULL) or the numeric
+** conversion fails, the default value is returned.
+**/
+int64_t property_get_int64(const char *key, int64_t default_value);
+
+/* property_get_int32: returns the value of key truncated and coerced into an
+** int32_t. If the property is not set, then the default value is used.
+**
+** The numeric conversion is identical to strtoimax with the base inferred:
+** - All digits up to the first non-digit characters are read
+** - The longest consecutive prefix of digits is converted to a long
+**
+** Valid strings of digits are:
+** - An optional sign character + or -
+** - An optional prefix indicating the base (otherwise base 10 is assumed)
+** -- 0 prefix is octal
+** -- 0x / 0X prefix is hex
+**
+** Leading/trailing whitespace is ignored. Overflow/underflow will cause
+** numeric conversion to fail.
+**
+** If no property with this key is set (or the key is NULL) or the numeric
+** conversion fails, the default value is returned.
+**/
+int32_t property_get_int32(const char *key, int32_t default_value);
+
/* property_set: returns 0 on success, < 0 on failure
*/
int property_set(const char *key, const char *value);
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 512184b..baa012d 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -253,6 +253,7 @@
{ 00750, AID_ROOT, AID_ROOT, 0, "system/bin/install-recovery.sh" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" },
{ 00755, AID_ROOT, AID_ROOT, 0, "system/lib/valgrind/*" },
+ { 00755, AID_ROOT, AID_ROOT, 0, "system/lib64/valgrind/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/vendor/bin/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" },
diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h
index f1d68a0..8c61293 100644
--- a/include/utils/BitSet.h
+++ b/include/utils/BitSet.h
@@ -75,19 +75,19 @@
// Result is undefined if all bits are unmarked.
inline uint32_t firstMarkedBit() const { return firstMarkedBit(value); }
- static uint32_t firstMarkedBit(uint32_t value) { return __builtin_clzl(value); }
+ static uint32_t firstMarkedBit(uint32_t value) { return clz_checked(value); }
// Finds the first unmarked bit in the set.
// Result is undefined if all bits are marked.
inline uint32_t firstUnmarkedBit() const { return firstUnmarkedBit(value); }
- static inline uint32_t firstUnmarkedBit(uint32_t value) { return __builtin_clzl(~ value); }
+ static inline uint32_t firstUnmarkedBit(uint32_t value) { return clz_checked(~ value); }
// Finds the last marked bit in the set.
// Result is undefined if all bits are unmarked.
inline uint32_t lastMarkedBit() const { return lastMarkedBit(value); }
- static inline uint32_t lastMarkedBit(uint32_t value) { return 31 - __builtin_ctzl(value); }
+ static inline uint32_t lastMarkedBit(uint32_t value) { return 31 - ctz_checked(value); }
// Finds the first marked bit in the set and clears it. Returns the bit index.
// Result is undefined if all bits are unmarked.
@@ -145,6 +145,25 @@
value |= other.value;
return *this;
}
+
+private:
+ // We use these helpers as the signature of __builtin_c{l,t}z has "unsigned int" for the
+ // input, which is only guaranteed to be 16b, not 32. The compiler should optimize this away.
+ static inline uint32_t clz_checked(uint32_t value) {
+ if (sizeof(unsigned int) == sizeof(uint32_t)) {
+ return __builtin_clz(value);
+ } else {
+ return __builtin_clzl(value);
+ }
+ }
+
+ static inline uint32_t ctz_checked(uint32_t value) {
+ if (sizeof(unsigned int) == sizeof(uint32_t)) {
+ return __builtin_ctz(value);
+ } else {
+ return __builtin_ctzl(value);
+ }
+ }
};
ANDROID_BASIC_TYPES_TRAITS(BitSet32)
diff --git a/include/utils/LruCache.h b/include/utils/LruCache.h
index fa8f03f..f615a32 100644
--- a/include/utils/LruCache.h
+++ b/include/utils/LruCache.h
@@ -48,6 +48,7 @@
bool remove(const TKey& key);
bool removeOldest();
void clear();
+ const TValue& peekOldestValue();
class Iterator {
public:
@@ -180,6 +181,14 @@
}
template <typename TKey, typename TValue>
+const TValue& LruCache<TKey, TValue>::peekOldestValue() {
+ if (mOldest) {
+ return mOldest->value;
+ }
+ return mNullValue;
+}
+
+template <typename TKey, typename TValue>
void LruCache<TKey, TValue>::clear() {
if (mListener) {
for (Entry* p = mOldest; p != NULL; p = p->child) {
diff --git a/libbacktrace/UnwindCurrent.cpp b/libbacktrace/UnwindCurrent.cpp
index 034b73c..67d372a 100755
--- a/libbacktrace/UnwindCurrent.cpp
+++ b/libbacktrace/UnwindCurrent.cpp
@@ -42,7 +42,7 @@
BACK_LOGW("unw_getcontext failed %d", ret);
return false;
}
- return UnwindFromContext(num_ignore_frames, true);
+ return UnwindFromContext(num_ignore_frames, false);
}
std::string UnwindCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
@@ -57,12 +57,14 @@
return "";
}
-bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, bool resolve) {
+bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, bool within_handler) {
// The cursor structure is pretty large, do not put it on the stack.
unw_cursor_t* cursor = new unw_cursor_t;
int ret = unw_init_local(cursor, &context_);
if (ret < 0) {
- BACK_LOGW("unw_init_local failed %d", ret);
+ if (!within_handler) {
+ BACK_LOGW("unw_init_local failed %d", ret);
+ }
delete cursor;
return false;
}
@@ -74,13 +76,17 @@
unw_word_t pc;
ret = unw_get_reg(cursor, UNW_REG_IP, &pc);
if (ret < 0) {
- BACK_LOGW("Failed to read IP %d", ret);
+ if (!within_handler) {
+ BACK_LOGW("Failed to read IP %d", ret);
+ }
break;
}
unw_word_t sp;
ret = unw_get_reg(cursor, UNW_REG_SP, &sp);
if (ret < 0) {
- BACK_LOGW("Failed to read SP %d", ret);
+ if (!within_handler) {
+ BACK_LOGW("Failed to read SP %d", ret);
+ }
break;
}
@@ -98,7 +104,7 @@
prev->stack_size = frame->sp - prev->sp;
}
- if (resolve) {
+ if (!within_handler) {
frame->func_name = GetFunctionName(frame->pc, &frame->func_offset);
frame->map = FindMap(frame->pc);
} else {
@@ -154,7 +160,7 @@
void UnwindThread::ThreadUnwind(
siginfo_t* /*siginfo*/, void* sigcontext, size_t num_ignore_frames) {
ExtractContext(sigcontext);
- UnwindFromContext(num_ignore_frames, false);
+ UnwindFromContext(num_ignore_frames, true);
}
//-------------------------------------------------------------------------
diff --git a/libbacktrace/UnwindCurrent.h b/libbacktrace/UnwindCurrent.h
index acce110..41080c7 100644
--- a/libbacktrace/UnwindCurrent.h
+++ b/libbacktrace/UnwindCurrent.h
@@ -34,7 +34,7 @@
virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset);
- bool UnwindFromContext(size_t num_ignore_frames, bool resolve);
+ bool UnwindFromContext(size_t num_ignore_frames, bool within_handler);
void ExtractContext(void* sigcontext);
diff --git a/libcutils/properties.c b/libcutils/properties.c
index 28d8b2f..bfbd1b8 100644
--- a/libcutils/properties.c
+++ b/libcutils/properties.c
@@ -15,17 +15,94 @@
*/
#define LOG_TAG "properties"
+// #define LOG_NDEBUG 0
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <unistd.h>
#include <cutils/sockets.h>
#include <errno.h>
#include <assert.h>
#include <cutils/properties.h>
+#include <stdbool.h>
+#include <inttypes.h>
#include "loghack.h"
+int8_t property_get_bool(const char *key, int8_t default_value) {
+ if (!key) {
+ return default_value;
+ }
+
+ int8_t result = default_value;
+ char buf[PROPERTY_VALUE_MAX] = {'\0',};
+
+ int len = property_get(key, buf, "");
+ if (len == 1) {
+ char ch = buf[0];
+ if (ch == '0' || ch == 'n') {
+ result = false;
+ } else if (ch == '1' || ch == 'y') {
+ result = true;
+ }
+ } else if (len > 1) {
+ if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) {
+ result = false;
+ } else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) {
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+// Convert string property to int (default if fails); return default value if out of bounds
+static intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,
+ intmax_t default_value) {
+ if (!key) {
+ return default_value;
+ }
+
+ intmax_t result = default_value;
+ char buf[PROPERTY_VALUE_MAX] = {'\0',};
+ char *end = NULL;
+
+ int len = property_get(key, buf, "");
+ if (len > 0) {
+ int tmp = errno;
+ errno = 0;
+
+ // Infer base automatically
+ result = strtoimax(buf, &end, /*base*/0);
+ if ((result == INTMAX_MIN || result == INTMAX_MAX) && errno == ERANGE) {
+ // Over or underflow
+ result = default_value;
+ ALOGV("%s(%s,%lld) - overflow", __FUNCTION__, key, default_value);
+ } else if (result < lower_bound || result > upper_bound) {
+ // Out of range of requested bounds
+ result = default_value;
+ ALOGV("%s(%s,%lld) - out of range", __FUNCTION__, key, default_value);
+ } else if (end == buf) {
+ // Numeric conversion failed
+ result = default_value;
+ ALOGV("%s(%s,%lld) - numeric conversion failed", __FUNCTION__, key, default_value);
+ }
+
+ errno = tmp;
+ }
+
+ return result;
+}
+
+int64_t property_get_int64(const char *key, int64_t default_value) {
+ return (int64_t)property_get_imax(key, INT64_MIN, INT64_MAX, default_value);
+}
+
+int32_t property_get_int32(const char *key, int32_t default_value) {
+ return (int32_t)property_get_imax(key, INT32_MIN, INT32_MAX, default_value);
+}
+
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
@@ -44,10 +121,13 @@
if(len > 0) {
return len;
}
-
if(default_value) {
len = strlen(default_value);
- memcpy(value, default_value, len + 1);
+ if (len >= PROPERTY_VALUE_MAX) {
+ len = PROPERTY_VALUE_MAX - 1;
+ }
+ memcpy(value, default_value, len);
+ value[len] = '\0';
}
return len;
}
diff --git a/libcutils/tests/Android.mk b/libcutils/tests/Android.mk
new file mode 100644
index 0000000..e9d3ed7
--- /dev/null
+++ b/libcutils/tests/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2014 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+test_src_files := \
+ PropertiesTest.cpp \
+
+shared_libraries := \
+ libutils
+
+static_libraries := \
+ libcutils
+
+LOCAL_SHARED_LIBRARIES := $(shared_libraries)
+LOCAL_STATIC_LIBRARIES := $(static_libraries)
+LOCAL_SRC_FILES := $(test_src_files)
+LOCAL_MODULE := libcutils_test
+include $(BUILD_NATIVE_TEST)
diff --git a/libcutils/tests/PropertiesTest.cpp b/libcutils/tests/PropertiesTest.cpp
new file mode 100644
index 0000000..659821c
--- /dev/null
+++ b/libcutils/tests/PropertiesTest.cpp
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Properties_test"
+#include <utils/Log.h>
+#include <gtest/gtest.h>
+
+#include <cutils/properties.h>
+#include <limits.h>
+#include <string>
+#include <sstream>
+#include <iostream>
+
+namespace android {
+
+#define STRINGIFY_INNER(x) #x
+#define STRINGIFY(x) STRINGIFY_INNER(x)
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
+#define ASSERT_OK(x) ASSERT_EQ(0, (x))
+#define EXPECT_OK(x) EXPECT_EQ(0, (x))
+
+#define PROPERTY_TEST_KEY "libcutils.test.key"
+#define PROPERTY_TEST_VALUE_DEFAULT "<<<default_value>>>"
+
+template <typename T>
+static std::string HexString(T value) {
+ std::stringstream ss;
+ ss << "0x" << std::hex << std::uppercase << value;
+ return ss.str();
+}
+
+template <typename T>
+static ::testing::AssertionResult AssertEqualHex(const char *mExpr,
+ const char *nExpr,
+ T m,
+ T n) {
+ if (m == n) {
+ return ::testing::AssertionSuccess();
+ }
+
+ return ::testing::AssertionFailure()
+ << mExpr << " and " << nExpr << " (expected: " << HexString(m) <<
+ ", actual: " << HexString(n) << ") are not equal";
+}
+
+class PropertiesTest : public testing::Test {
+public:
+ PropertiesTest() : mValue() {}
+protected:
+ virtual void SetUp() {
+ EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));
+ }
+
+ virtual void TearDown() {
+ EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));
+ }
+
+ char mValue[PROPERTY_VALUE_MAX];
+
+ template <typename T>
+ static std::string ToString(T value) {
+ std::stringstream ss;
+ ss << value;
+
+ return ss.str();
+ }
+
+ // Return length of property read; value is written into mValue
+ int SetAndGetProperty(const char* value, const char* defaultValue = PROPERTY_TEST_VALUE_DEFAULT) {
+ EXPECT_OK(property_set(PROPERTY_TEST_KEY, value)) << "value: '" << value << "'";
+ return property_get(PROPERTY_TEST_KEY, mValue, defaultValue);
+ }
+
+ void ResetValue(unsigned char c = 0xFF) {
+ for (size_t i = 0; i < ARRAY_SIZE(mValue); ++i) {
+ mValue[i] = (char) c;
+ }
+ }
+};
+
+TEST_F(PropertiesTest, SetString) {
+
+ // Null key -> unsuccessful set
+ {
+ // Null key -> fails
+ EXPECT_GT(0, property_set(/*key*/NULL, PROPERTY_TEST_VALUE_DEFAULT));
+ }
+
+ // Null value -> returns default value
+ {
+ // Null value -> OK , and it clears the value
+ EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));
+ ResetValue();
+
+ // Since the value is null, default value will be returned
+ int len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
+ EXPECT_EQ(strlen(PROPERTY_TEST_VALUE_DEFAULT), len);
+ EXPECT_STREQ(PROPERTY_TEST_VALUE_DEFAULT, mValue);
+ }
+
+ // Trivial case => get returns what was set
+ {
+ int len = SetAndGetProperty("hello_world");
+ EXPECT_EQ(strlen("hello_world"), len) << "hello_world key";
+ EXPECT_STREQ("hello_world", mValue);
+ ResetValue();
+ }
+
+ // Set to empty string => get returns default always
+ {
+ const char* EMPTY_STRING_DEFAULT = "EMPTY_STRING";
+ int len = SetAndGetProperty("", EMPTY_STRING_DEFAULT);
+ EXPECT_EQ(strlen(EMPTY_STRING_DEFAULT), len) << "empty key";
+ EXPECT_STREQ(EMPTY_STRING_DEFAULT, mValue);
+ ResetValue();
+ }
+
+ // Set to max length => get returns what was set
+ {
+ std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a');
+
+ int len = SetAndGetProperty(maxLengthString.c_str());
+ EXPECT_EQ(PROPERTY_VALUE_MAX-1, len) << "max length key";
+ EXPECT_STREQ(maxLengthString.c_str(), mValue);
+ ResetValue();
+ }
+
+ // Set to max length + 1 => set fails
+ {
+ const char* VALID_TEST_VALUE = "VALID_VALUE";
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, VALID_TEST_VALUE));
+
+ std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');
+
+ // Expect that the value set fails since it's too long
+ EXPECT_GT(0, property_set(PROPERTY_TEST_KEY, oneLongerString.c_str()));
+ int len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
+
+ EXPECT_EQ(strlen(VALID_TEST_VALUE), len) << "set should've failed";
+ EXPECT_STREQ(VALID_TEST_VALUE, mValue);
+ ResetValue();
+ }
+}
+
+TEST_F(PropertiesTest, GetString) {
+
+ // Try to use a default value that's too long => set fails
+ {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
+
+ std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a');
+ std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');
+
+ // Expect that the value is truncated since it's too long (by 1)
+ int len = property_get(PROPERTY_TEST_KEY, mValue, oneLongerString.c_str());
+ EXPECT_EQ(PROPERTY_VALUE_MAX-1, len);
+ EXPECT_STREQ(maxLengthString.c_str(), mValue);
+ ResetValue();
+ }
+}
+
+TEST_F(PropertiesTest, GetBool) {
+ /**
+ * TRUE
+ */
+ const char *valuesTrue[] = { "1", "true", "y", "yes", "on", };
+ for (size_t i = 0; i < ARRAY_SIZE(valuesTrue); ++i) {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesTrue[i]));
+ bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false);
+ EXPECT_TRUE(val) << "Property should've been TRUE for value: '" << valuesTrue[i] << "'";
+ }
+
+ /**
+ * FALSE
+ */
+ const char *valuesFalse[] = { "0", "false", "n", "no", "off", };
+ for (size_t i = 0; i < ARRAY_SIZE(valuesFalse); ++i) {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesFalse[i]));
+ bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true);
+ EXPECT_FALSE(val) << "Property shoud've been FALSE For string value: '" << valuesFalse[i] << "'";
+ }
+
+ /**
+ * NEITHER
+ */
+ const char *valuesNeither[] = { "x0", "x1", "2", "-2", "True", "False", "garbage", "", " ",
+ "+1", " 1 ", " true", " true ", " y ", " yes", "yes ",
+ "+0", "-0", "00", " 00 ", " false", "false ",
+ };
+ for (size_t i = 0; i < ARRAY_SIZE(valuesNeither); ++i) {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesNeither[i]));
+
+ // The default value should always be used
+ bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true);
+ EXPECT_TRUE(val) << "Property should've been NEITHER (true) for string value: '" << valuesNeither[i] << "'";
+
+ val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false);
+ EXPECT_FALSE(val) << "Property should've been NEITHER (false) for string value: '" << valuesNeither[i] << "'";
+ }
+}
+
+TEST_F(PropertiesTest, GetInt64) {
+ const int64_t DEFAULT_VALUE = INT64_C(0xDEADBEEFBEEFDEAD);
+
+ const std::string longMaxString = ToString(INT64_MAX);
+ const std::string longStringOverflow = longMaxString + "0";
+
+ const std::string longMinString = ToString(INT64_MIN);
+ const std::string longStringUnderflow = longMinString + "0";
+
+ const char* setValues[] = {
+ // base 10
+ "1", "2", "12345", "-1", "-2", "-12345",
+ // base 16
+ "0xFF", "0x0FF", "0xC0FFEE",
+ // base 8
+ "0", "01234", "07",
+ // corner cases
+ " 2", "2 ", "+0", "-0", " +0 ", longMaxString.c_str(), longMinString.c_str(),
+ // failing cases
+ NULL, "", " ", " ", "hello", " true ", "y",
+ longStringOverflow.c_str(), longStringUnderflow.c_str(),
+ };
+
+ int64_t getValues[] = {
+ // base 10
+ 1, 2, 12345, -1, -2, -12345,
+ // base 16
+ 0xFF, 0x0FF, 0xC0FFEE,
+ // base 8
+ 0, 01234, 07,
+ // corner cases
+ 2, 2, 0, 0, 0, INT64_MAX, INT64_MIN,
+ // failing cases
+ DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE,
+ DEFAULT_VALUE, DEFAULT_VALUE,
+ };
+
+ ASSERT_EQ(ARRAY_SIZE(setValues), ARRAY_SIZE(getValues));
+
+ for (size_t i = 0; i < ARRAY_SIZE(setValues); ++i) {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, setValues[i]));
+
+ int64_t val = property_get_int64(PROPERTY_TEST_KEY, DEFAULT_VALUE);
+ EXPECT_PRED_FORMAT2(AssertEqualHex, getValues[i], val) << "Property was set to '" << setValues[i] << "'";
+ }
+}
+
+TEST_F(PropertiesTest, GetInt32) {
+ const int32_t DEFAULT_VALUE = INT32_C(0xDEADBEEF);
+
+ const std::string intMaxString = ToString(INT32_MAX);
+ const std::string intStringOverflow = intMaxString + "0";
+
+ const std::string intMinString = ToString(INT32_MIN);
+ const std::string intStringUnderflow = intMinString + "0";
+
+ const char* setValues[] = {
+ // base 10
+ "1", "2", "12345", "-1", "-2", "-12345",
+ // base 16
+ "0xFF", "0x0FF", "0xC0FFEE", "0Xf00",
+ // base 8
+ "0", "01234", "07",
+ // corner cases
+ " 2", "2 ", "+0", "-0", " +0 ", intMaxString.c_str(), intMinString.c_str(),
+ // failing cases
+ NULL, "", " ", " ", "hello", " true ", "y",
+ intStringOverflow.c_str(), intStringUnderflow.c_str(),
+ };
+
+ int32_t getValues[] = {
+ // base 10
+ 1, 2, 12345, -1, -2, -12345,
+ // base 16
+ 0xFF, 0x0FF, 0xC0FFEE, 0Xf00,
+ // base 8
+ 0, 01234, 07,
+ // corner cases
+ 2, 2, 0, 0, 0, INT32_MAX, INT32_MIN,
+ // failing cases
+ DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE,
+ DEFAULT_VALUE, DEFAULT_VALUE,
+ };
+
+ ASSERT_EQ(ARRAY_SIZE(setValues), ARRAY_SIZE(getValues));
+
+ for (size_t i = 0; i < ARRAY_SIZE(setValues); ++i) {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, setValues[i]));
+
+ int32_t val = property_get_int32(PROPERTY_TEST_KEY, DEFAULT_VALUE);
+ EXPECT_PRED_FORMAT2(AssertEqualHex, getValues[i], val) << "Property was set to '" << setValues[i] << "'";
+ }
+}
+
+} // namespace android
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index d726f2d..24ae738 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -484,7 +484,7 @@
EXPECT_EQ(true, matches);
- EXPECT_LE(sizeof(max_payload_buf), max_len);
+ EXPECT_LE(sizeof(max_payload_buf), static_cast<size_t>(max_len));
android_logger_list_close(logger_list);
}
diff --git a/libpixelflinger/codeflinger/disassem.c b/libpixelflinger/codeflinger/disassem.c
index aeb8034..39dd614 100644
--- a/libpixelflinger/codeflinger/disassem.c
+++ b/libpixelflinger/codeflinger/disassem.c
@@ -301,19 +301,14 @@
static void disassemble_printaddr(u_int address);
u_int
-disasm(const disasm_interface_t *di, u_int loc, int altfmt)
+disasm(const disasm_interface_t *di, u_int loc, int __unused altfmt)
{
const struct arm32_insn *i_ptr = &arm32_i[0];
-
- u_int insn;
- int matchp;
+ u_int insn = di->di_readword(loc);
+ int matchp = 0;
int branch;
char* f_ptr;
- int fmt;
-
- fmt = 0;
- matchp = 0;
- insn = di->di_readword(loc);
+ int fmt = 0;
/* di->di_printf("loc=%08x insn=%08x : ", loc, insn);*/
@@ -670,7 +665,7 @@
}
static void
-disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn, u_int loc)
+disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn, u_int __unused loc)
{
if (((insn >> 8) & 0xf) == 1)
di->di_printf("f%d, ", (insn >> 12) & 0x07);
diff --git a/libpixelflinger/codeflinger/disassem.h b/libpixelflinger/codeflinger/disassem.h
index 02747cd..c7c60b6 100644
--- a/libpixelflinger/codeflinger/disassem.h
+++ b/libpixelflinger/codeflinger/disassem.h
@@ -49,8 +49,8 @@
typedef struct {
u_int (*di_readword)(u_int);
- void (*di_printaddr)(u_int);
- void (*di_printf)(const char *, ...);
+ void (*di_printaddr)(u_int);
+ int (*di_printf)(const char *, ...);
} disasm_interface_t;
/* Prototypes for callable functions */
diff --git a/libsuspend/autosuspend_earlysuspend.c b/libsuspend/autosuspend_earlysuspend.c
index 1df8c6a..2bece4c 100644
--- a/libsuspend/autosuspend_earlysuspend.c
+++ b/libsuspend/autosuspend_earlysuspend.c
@@ -75,13 +75,8 @@
return err < 0 ? err : 0;
}
-static void *earlysuspend_thread_func(void *arg)
+static void *earlysuspend_thread_func(void __unused *arg)
{
- char buf[80];
- char wakeup_count[20];
- int wakeup_count_len;
- int ret;
-
while (1) {
if (wait_for_fb_sleep()) {
ALOGE("Failed reading wait_for_fb_sleep, exiting earlysuspend thread\n");
diff --git a/libutils/Timers.cpp b/libutils/Timers.cpp
index 5293cd2..a431e92 100644
--- a/libutils/Timers.cpp
+++ b/libutils/Timers.cpp
@@ -34,7 +34,7 @@
nsecs_t systemTime(int clock)
{
-#if defined(HAVE_POSIX_CLOCKS)
+#if defined(HAVE_ANDROID_OS)
static const clockid_t clocks[] = {
CLOCK_REALTIME,
CLOCK_MONOTONIC,
@@ -47,7 +47,9 @@
clock_gettime(clocks[clock], &t);
return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
#else
- // we don't support the clocks here.
+ // Clock support varies widely across hosts. Mac OS doesn't support
+ // posix clocks, older glibcs don't support CLOCK_BOOTTIME and Windows
+ // is windows.
struct timeval t;
t.tv_sec = t.tv_usec = 0;
gettimeofday(&t, NULL);
diff --git a/libutils/tests/BasicHashtable_test.cpp b/libutils/tests/BasicHashtable_test.cpp
index 7dcf750..a61b1e1 100644
--- a/libutils/tests/BasicHashtable_test.cpp
+++ b/libutils/tests/BasicHashtable_test.cpp
@@ -397,7 +397,7 @@
const SimpleEntry& entry = h.entryAt(index);
ASSERT_GE(entry.key, 0);
ASSERT_LT(entry.key, N);
- ASSERT_EQ(false, set[entry.key]);
+ ASSERT_FALSE(set[entry.key]);
ASSERT_EQ(entry.key * 10, entry.value);
set[entry.key] = true;
diff --git a/libutils/tests/LruCache_test.cpp b/libutils/tests/LruCache_test.cpp
index e573952..bcbea32 100644
--- a/libutils/tests/LruCache_test.cpp
+++ b/libutils/tests/LruCache_test.cpp
@@ -184,7 +184,7 @@
for (size_t i = 0; i < kNumKeys; i++) {
strings[i] = (char *)malloc(16);
- sprintf(strings[i], "%d", i);
+ sprintf(strings[i], "%zu", i);
}
srandom(12345);
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 00a60bd..ca97208 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -230,12 +230,16 @@
" 'events' or 'all'. Multiple -b parameters are allowed and\n"
" results are interleaved. The default is -b main -b system.\n"
" -B output the log in binary.\n"
- " -S output statistics.\n");
-
- fprintf(stderr, " -G <count> set size of log's ring buffer and exit\n"
- " -p output prune white and ~black list\n"
- " -P '<list> ...' set prune white and ~black list; UID, /PID or !(worst UID)\n"
- " default is ~!, prune worst UID.\n");
+ " -S output statistics.\n"
+ " -G <size> set size of log ring buffer, may suffix with K or M.\n"
+ " -p print prune white and ~black list. Service is specified as\n"
+ " UID, UID/PID or /PID. Weighed for quicker pruning if prefix\n"
+ " with ~, otherwise weighed for longevity if unadorned. All\n"
+ " other pruning activity is oldest first. Special case ~!\n"
+ " represents an automatic quicker pruning for the noisiest\n"
+ " UID as determined by the current statistics.\n"
+ " -P '<list> ...' set prune white and ~black list, using same format as\n"
+ " printed above. Must be quoted.\n");
fprintf(stderr,"\nfilterspecs are a series of \n"
" <tag>[:priority]\n\n"
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 79e33ef..d9e4d1c 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -557,7 +557,7 @@
# encryption) or trigger_restart_min_framework (other encryption)
# One shot invocation to encrypt unencrypted volumes
-service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace
+service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default
disabled
oneshot
# vold will set vold.decrypt to trigger_restart_framework (default
diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc
new file mode 100644
index 0000000..3d60a31
--- /dev/null
+++ b/rootdir/init.zygote32_64.rc
@@ -0,0 +1,12 @@
+service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
+ class main
+ socket zygote stream 660 root system
+ onrestart write /sys/android_power/request_state wake
+ onrestart write /sys/power/state on
+ onrestart restart media
+ onrestart restart netd
+
+service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
+ class main
+ socket zygote_secondary stream 660 root system
+ onrestart restart zygote
diff --git a/toolbox/syren.c b/toolbox/syren.c
index 06e329e..47c2460 100644
--- a/toolbox/syren.c
+++ b/toolbox/syren.c
@@ -123,7 +123,11 @@
r = find_reg(argv[2]);
if (r == NULL) {
- strcpy(name, argv[2]);
+ if(strlen(argv[2]) >= sizeof(name)){
+ fprintf(stderr, "REGNAME too long\n");
+ return 0;
+ }
+ strlcpy(name, argv[2], sizeof(name));
char *addr_str = strchr(argv[2], ':');
if (addr_str == NULL)
return usage();
@@ -131,7 +135,7 @@
sio.page = strtoul(argv[2], 0, 0);
sio.addr = strtoul(addr_str, 0, 0);
} else {
- strcpy(name, r->name);
+ strlcpy(name, r->name, sizeof(name));
sio.page = r->page;
sio.addr = r->addr;
}