nanotool: add support for log events

Change-Id: I2d8484847055bfbf3a40c945a867a64b71867313
diff --git a/util/nanotool/Android.mk b/util/nanotool/Android.mk
index bbbdd3c..fdd0295 100644
--- a/util/nanotool/Android.mk
+++ b/util/nanotool/Android.mk
@@ -26,6 +26,7 @@
     calibrationfile.cpp \
     contexthub.cpp \
     log.cpp \
+    logevent.cpp \
     nanomessage.cpp \
     nanotool.cpp \
     resetreasonevent.cpp \
diff --git a/util/nanotool/logevent.cpp b/util/nanotool/logevent.cpp
new file mode 100644
index 0000000..7389e4b
--- /dev/null
+++ b/util/nanotool/logevent.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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 "log.h"
+#include "logevent.h"
+
+namespace android {
+
+/* LogEvent *******************************************************************/
+
+std::unique_ptr<LogEvent> LogEvent::FromBytes(
+        const std::vector<uint8_t>& buffer) {
+    auto event = std::unique_ptr<LogEvent>(new LogEvent());
+    event->Populate(buffer);
+
+    return event;
+}
+
+std::string LogEvent::GetMessage() const {
+    constexpr size_t kHeaderSize = sizeof(uint32_t) // Message type.
+        + sizeof(char) // Log level.
+        + sizeof(char); // Beginning of log message.
+
+    if (event_data.size() < kHeaderSize) {
+        LOGW("Invalid/short LogEvent event of size %zu", event_data.size());
+        return std::string();
+    } else {
+        const char *message = reinterpret_cast<const char *>(
+            event_data.data() + sizeof(uint32_t));
+        return std::string(message);
+    }
+}
+
+}  // namespace android
diff --git a/util/nanotool/logevent.h b/util/nanotool/logevent.h
new file mode 100644
index 0000000..04864af
--- /dev/null
+++ b/util/nanotool/logevent.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef LOG_EVENT_H_
+#define LOG_EVENT_H_
+
+#include "nanomessage.h"
+
+namespace android {
+
+class LogEvent : public ReadEventResponse {
+  public:
+    /*
+     * Constructs and populates a LogEvent instance. Returns nullptr if
+     * the packet is malformed. The rest of the methods in this class are not
+     * guaranteed to be safe unless the object is constructed from this
+     * function.
+     */
+    static std::unique_ptr<LogEvent> FromBytes(
+        const std::vector<uint8_t>& buffer);
+
+    // Returns a string containing the contents of the log message.
+    std::string GetMessage() const;
+};
+
+}  // namespace android
+
+#endif  // LOG_EVENT_H_
diff --git a/util/nanotool/nanomessage.cpp b/util/nanotool/nanomessage.cpp
index f31cdb3..0f88973 100644
--- a/util/nanotool/nanomessage.cpp
+++ b/util/nanotool/nanomessage.cpp
@@ -21,6 +21,7 @@
 
 #include "apptohostevent.h"
 #include "log.h"
+#include "logevent.h"
 #include "resetreasonevent.h"
 #include "sensorevent.h"
 
@@ -119,6 +120,8 @@
         return AppToHostEvent::FromBytes(buffer);
     } else if (ReadEventResponse::IsResetReasonEvent(event_type)) {
         return ResetReasonEvent::FromBytes(buffer);
+    } else if (ReadEventResponse::IsLogEvent(event_type)) {
+        return LogEvent::FromBytes(buffer);
     } else {
         LOGW("Received unexpected/unsupported event type %u", event_type);
         return nullptr;
@@ -147,6 +150,10 @@
     return ReadEventResponse::IsResetReasonEvent(GetEventType());
 }
 
+bool ReadEventResponse::IsLogEvent() const {
+    return ReadEventResponse::IsLogEvent(GetEventType());
+}
+
 uint32_t ReadEventResponse::GetEventType() const {
     return ReadEventResponse::EventTypeFromBuffer(event_data);
 }
@@ -164,6 +171,10 @@
     return (event_type == static_cast<uint32_t>(EventType::ResetReasonEvent));
 }
 
+bool ReadEventResponse::IsLogEvent(uint32_t event_type) {
+    return (event_type == static_cast<uint32_t>(EventType::LogEvent));
+}
+
 uint32_t ReadEventResponse::EventTypeFromBuffer(const std::vector<uint8_t>& buffer) {
     if (buffer.size() < sizeof(uint32_t)) {
         LOGW("Invalid/short event of size %zu", buffer.size());
diff --git a/util/nanotool/nanomessage.h b/util/nanotool/nanomessage.h
index 8881c17..2276775 100644
--- a/util/nanotool/nanomessage.h
+++ b/util/nanotool/nanomessage.h
@@ -36,6 +36,7 @@
     ConfigureSensor  = 0x00000300,
     AppToHostEvent   = 0x00000401,
     ResetReasonEvent = 0x00000403,
+    LogEvent         = 0x474F4C41,
 };
 
 /*
@@ -140,6 +141,7 @@
     bool IsAppToHostEvent() const;
     bool IsSensorEvent() const;
     bool IsResetReasonEvent() const;
+    bool IsLogEvent() const;
     uint32_t GetEventType() const;
 
     // Event data associated with this response.
@@ -150,6 +152,7 @@
     static bool IsAppToHostEvent(uint32_t event_type);
     static bool IsSensorEvent(uint32_t event_type);
     static bool IsResetReasonEvent(uint32_t event_type);
+    static bool IsLogEvent(uint32_t event_type);
 };
 
 /*
diff --git a/util/nanotool/resetreasonevent.h b/util/nanotool/resetreasonevent.h
index 48c9e67..d5e58eb 100644
--- a/util/nanotool/resetreasonevent.h
+++ b/util/nanotool/resetreasonevent.h
@@ -17,7 +17,6 @@
 #ifndef RESET_REASON_EVENT_H_
 #define RESET_REASON_EVENT_H_
 
-#include "contexthub.h"
 #include "nanomessage.h"
 
 namespace android {