Merge "Add timeout to usb_device_control_transfer call in usbhost code."
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp
index c348dd5..9b59d05 100644
--- a/adb/bugreport.cpp
+++ b/adb/bugreport.cpp
@@ -237,8 +237,7 @@
// Uses a default value until device provides the proper name
dest_file = "bugreport.zip";
} else {
- if (!android::base::EndsWith(dest_file, ".zip")) {
- // TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
+ if (!android::base::EndsWithIgnoreCase(dest_file, ".zip")) {
dest_file += ".zip";
}
}
diff --git a/base/include/android-base/strings.h b/base/include/android-base/strings.h
index 69781cd..b8a9289 100644
--- a/base/include/android-base/strings.h
+++ b/base/include/android-base/strings.h
@@ -58,9 +58,11 @@
// Tests whether 's' starts with 'prefix'.
bool StartsWith(const std::string& s, const char* prefix);
+bool StartsWithIgnoreCase(const std::string& s, const char* prefix);
// Tests whether 's' ends with 'suffix'.
bool EndsWith(const std::string& s, const char* suffix);
+bool EndsWithIgnoreCase(const std::string& s, const char* suffix);
} // namespace base
} // namespace android
diff --git a/base/strings.cpp b/base/strings.cpp
index b8775df..7a94ad7 100644
--- a/base/strings.cpp
+++ b/base/strings.cpp
@@ -87,17 +87,29 @@
template std::string Join(const std::vector<const char*>&, const std::string&);
bool StartsWith(const std::string& s, const char* prefix) {
- return s.compare(0, strlen(prefix), prefix) == 0;
+ return strncmp(s.c_str(), prefix, strlen(prefix)) == 0;
}
-bool EndsWith(const std::string& s, const char* suffix) {
+bool StartsWithIgnoreCase(const std::string& s, const char* prefix) {
+ return strncasecmp(s.c_str(), prefix, strlen(prefix)) == 0;
+}
+
+static bool EndsWith(const std::string& s, const char* suffix, bool case_sensitive) {
size_t suffix_length = strlen(suffix);
size_t string_length = s.size();
if (suffix_length > string_length) {
return false;
}
size_t offset = string_length - suffix_length;
- return s.compare(offset, suffix_length, suffix) == 0;
+ return (case_sensitive ? strncmp : strncasecmp)(s.c_str() + offset, suffix, suffix_length) == 0;
+}
+
+bool EndsWith(const std::string& s, const char* suffix) {
+ return EndsWith(s, suffix, true);
+}
+
+bool EndsWithIgnoreCase(const std::string& s, const char* suffix) {
+ return EndsWith(s, suffix, false);
}
} // namespace base
diff --git a/base/strings_test.cpp b/base/strings_test.cpp
index 30ae29e..5fb21dd 100644
--- a/base/strings_test.cpp
+++ b/base/strings_test.cpp
@@ -134,44 +134,113 @@
"2,1" == android::base::Join(list, ','));
}
-TEST(strings, startswith_empty) {
+TEST(strings, StartsWith_empty) {
ASSERT_FALSE(android::base::StartsWith("", "foo"));
ASSERT_TRUE(android::base::StartsWith("", ""));
}
-TEST(strings, startswith_simple) {
+TEST(strings, StartsWithIgnoreCase_empty) {
+ ASSERT_FALSE(android::base::StartsWithIgnoreCase("", "foo"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("", ""));
+}
+
+TEST(strings, StartsWith_simple) {
ASSERT_TRUE(android::base::StartsWith("foo", ""));
ASSERT_TRUE(android::base::StartsWith("foo", "f"));
ASSERT_TRUE(android::base::StartsWith("foo", "fo"));
ASSERT_TRUE(android::base::StartsWith("foo", "foo"));
}
-TEST(strings, startswith_prefix_too_long) {
+TEST(strings, StartsWithIgnoreCase_simple) {
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", ""));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "f"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "F"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "fo"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "fO"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "Fo"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "FO"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "foo"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "foO"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "fOo"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "fOO"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "Foo"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "FoO"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "FOo"));
+ ASSERT_TRUE(android::base::StartsWithIgnoreCase("foo", "FOO"));
+}
+
+TEST(strings, StartsWith_prefix_too_long) {
ASSERT_FALSE(android::base::StartsWith("foo", "foobar"));
}
-TEST(strings, startswith_contains_prefix) {
+TEST(strings, StartsWithIgnoreCase_prefix_too_long) {
+ ASSERT_FALSE(android::base::StartsWithIgnoreCase("foo", "foobar"));
+ ASSERT_FALSE(android::base::StartsWithIgnoreCase("foo", "FOOBAR"));
+}
+
+TEST(strings, StartsWith_contains_prefix) {
ASSERT_FALSE(android::base::StartsWith("foobar", "oba"));
ASSERT_FALSE(android::base::StartsWith("foobar", "bar"));
}
-TEST(strings, endswith_empty) {
+TEST(strings, StartsWithIgnoreCase_contains_prefix) {
+ ASSERT_FALSE(android::base::StartsWithIgnoreCase("foobar", "oba"));
+ ASSERT_FALSE(android::base::StartsWithIgnoreCase("foobar", "OBA"));
+ ASSERT_FALSE(android::base::StartsWithIgnoreCase("foobar", "bar"));
+ ASSERT_FALSE(android::base::StartsWithIgnoreCase("foobar", "BAR"));
+}
+
+TEST(strings, EndsWith_empty) {
ASSERT_FALSE(android::base::EndsWith("", "foo"));
ASSERT_TRUE(android::base::EndsWith("", ""));
}
-TEST(strings, endswith_simple) {
+TEST(strings, EndsWithIgnoreCase_empty) {
+ ASSERT_FALSE(android::base::EndsWithIgnoreCase("", "foo"));
+ ASSERT_FALSE(android::base::EndsWithIgnoreCase("", "FOO"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("", ""));
+}
+
+TEST(strings, EndsWith_simple) {
ASSERT_TRUE(android::base::EndsWith("foo", ""));
ASSERT_TRUE(android::base::EndsWith("foo", "o"));
ASSERT_TRUE(android::base::EndsWith("foo", "oo"));
ASSERT_TRUE(android::base::EndsWith("foo", "foo"));
}
-TEST(strings, endswith_prefix_too_long) {
+TEST(strings, EndsWithIgnoreCase_simple) {
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", ""));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "o"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "O"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "oo"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "oO"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "Oo"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "OO"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "foo"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "foO"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "fOo"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "fOO"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "Foo"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "FoO"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "FOo"));
+ ASSERT_TRUE(android::base::EndsWithIgnoreCase("foo", "FOO"));
+}
+
+TEST(strings, EndsWith_prefix_too_long) {
ASSERT_FALSE(android::base::EndsWith("foo", "foobar"));
}
-TEST(strings, endswith_contains_prefix) {
+TEST(strings, EndsWithIgnoreCase_prefix_too_long) {
+ ASSERT_FALSE(android::base::EndsWithIgnoreCase("foo", "foobar"));
+ ASSERT_FALSE(android::base::EndsWithIgnoreCase("foo", "FOOBAR"));
+}
+
+TEST(strings, EndsWith_contains_prefix) {
ASSERT_FALSE(android::base::EndsWith("foobar", "oba"));
ASSERT_FALSE(android::base::EndsWith("foobar", "foo"));
}
+
+TEST(strings, EndsWithIgnoreCase_contains_prefix) {
+ ASSERT_FALSE(android::base::EndsWithIgnoreCase("foobar", "OBA"));
+ ASSERT_FALSE(android::base::EndsWithIgnoreCase("foobar", "FOO"));
+}
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 4e62d74..293e78a 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -151,7 +151,7 @@
CAP_MASK_LONG(CAP_NET_RAW), "system/bin/hostapd" },
/* Support wifi_hal_legacy administering a network interface. */
- { 00755, AID_WIFI, AID_WIFI, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/hw/wifi_hal_legacy" },
+ { 00755, AID_WIFI, AID_WIFI, CAP_MASK_LONG(CAP_NET_ADMIN) | CAP_MASK_LONG(CAP_NET_RAW), "system/bin/hw/android.hardware.wifi@1.0-service" },
{ 00750, AID_ROOT, AID_ROOT, 0, "system/bin/uncrypt" },
{ 00750, AID_ROOT, AID_ROOT, 0, "system/bin/install-recovery.sh" },
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 5cab7a8..a009433 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+// for manual checking of stale entries during LogBuffer::erase()
+//#define DEBUG_CHECK_FOR_STALE_ENTRIES
#include <ctype.h>
#include <errno.h>
@@ -256,6 +258,11 @@
log_id_for_each(i) {
doSetLast |= setLast[i] = mLastSet[i] && (it == mLast[i]);
}
+#ifdef DEBUG_CHECK_FOR_STALE_ENTRIES
+ LogBufferElementCollection::iterator bad = it;
+ int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ?
+ element->getTag() : element->getUid();
+#endif
it = mLogElements.erase(it);
if (doSetLast) {
log_id_for_each(i) {
@@ -269,6 +276,27 @@
}
}
}
+#ifdef DEBUG_CHECK_FOR_STALE_ENTRIES
+ log_id_for_each(i) {
+ for(auto b : mLastWorst[i]) {
+ if (bad == b.second) {
+ android::prdebug("stale mLastWorst[%d] key=%d mykey=%d\n",
+ i, b.first, key);
+ }
+ }
+ for(auto b : mLastWorstPidOfSystem[i]) {
+ if (bad == b.second) {
+ android::prdebug("stale mLastWorstPidOfSystem[%d] pid=%d\n",
+ i, b.first);
+ }
+ }
+ if (mLastSet[i] && (bad == mLast[i])) {
+ android::prdebug("stale mLast[%d]\n", i);
+ mLastSet[i] = false;
+ mLast[i] = mLogElements.begin();
+ }
+ }
+#endif
if (coalesce) {
stats.erase(element);
} else {
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index a939002..f5c60c7 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -36,29 +36,24 @@
LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime,
uid_t uid, pid_t pid, pid_t tid,
const char *msg, unsigned short len) :
- mLogId(log_id),
mUid(uid),
mPid(pid),
mTid(tid),
- mMsgLen(len),
mSequence(sequence.fetch_add(1, memory_order_relaxed)),
- mRealTime(realtime) {
+ mRealTime(realtime),
+ mMsgLen(len),
+ mLogId(log_id) {
mMsg = new char[len];
memcpy(mMsg, msg, len);
+ mTag = (isBinary() && (mMsgLen >= sizeof(uint32_t))) ?
+ le32toh(reinterpret_cast<android_event_header_t *>(mMsg)->tag) :
+ 0;
}
LogBufferElement::~LogBufferElement() {
delete [] mMsg;
}
-uint32_t LogBufferElement::getTag() const {
- if (((mLogId != LOG_ID_EVENTS) && (mLogId != LOG_ID_SECURITY)) ||
- !mMsg || (mMsgLen < sizeof(uint32_t))) {
- return 0;
- }
- return le32toh(reinterpret_cast<android_event_header_t *>(mMsg)->tag);
-}
-
// caller must own and free character string
char *android::tidToName(pid_t tid) {
char *retval = NULL;
@@ -164,7 +159,7 @@
size_t hdrLen;
// LOG_ID_SECURITY not strictly needed since spam filter not activated,
// but required for accuracy.
- if ((mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY)) {
+ if (isBinary()) {
hdrLen = sizeof(android_log_event_string_t);
} else {
hdrLen = 1 + sizeof(tag);
@@ -178,7 +173,7 @@
}
size_t retval = hdrLen + len;
- if ((mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY)) {
+ if (isBinary()) {
android_log_event_string_t *event =
reinterpret_cast<android_log_event_string_t *>(buffer);
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h
index 2c7fd44..fb7fbed 100644
--- a/logd/LogBufferElement.h
+++ b/logd/LogBufferElement.h
@@ -36,33 +36,40 @@
friend LogBuffer;
- const log_id_t mLogId;
- const uid_t mUid;
- const pid_t mPid;
- const pid_t mTid;
- char *mMsg;
- union {
- const unsigned short mMsgLen; // mMSg != NULL
- unsigned short mDropped; // mMsg == NULL
- };
+ // sized to match reality of incoming log packets
+ uint32_t mTag; // only valid for isBinary()
+ const uint32_t mUid;
+ const uint32_t mPid;
+ const uint32_t mTid;
const uint64_t mSequence;
log_time mRealTime;
+ char *mMsg;
+ union {
+ const uint16_t mMsgLen; // mMSg != NULL
+ uint16_t mDropped; // mMsg == NULL
+ };
+ const uint8_t mLogId;
+
static atomic_int_fast64_t sequence;
// assumption: mMsg == NULL
size_t populateDroppedMessage(char *&buffer,
LogBuffer *parent);
-
public:
LogBufferElement(log_id_t log_id, log_time realtime,
uid_t uid, pid_t pid, pid_t tid,
const char *msg, unsigned short len);
virtual ~LogBufferElement();
- log_id_t getLogId() const { return mLogId; }
+ bool isBinary(void) const {
+ return (mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY);
+ }
+
+ log_id_t getLogId() const { return static_cast<log_id_t>(mLogId); }
uid_t getUid(void) const { return mUid; }
pid_t getPid(void) const { return mPid; }
pid_t getTid(void) const { return mTid; }
+ uint32_t getTag() const { return mTag; }
unsigned short getDropped(void) const { return mMsg ? 0 : mDropped; }
unsigned short setDropped(unsigned short value) {
if (mMsg) {
@@ -76,8 +83,6 @@
static uint64_t getCurrentSequence(void) { return sequence.load(memory_order_relaxed); }
log_time getRealTime(void) const { return mRealTime; }
- uint32_t getTag(void) const;
-
static const uint64_t FLUSH_ERROR;
uint64_t flushTo(SocketClient *writer, LogBuffer *parent, bool privileged);
};