Skip to content

Commit

Permalink
add local log buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
cinit committed Jan 2, 2022
1 parent 5b6f60a commit 3207fda
Show file tree
Hide file tree
Showing 34 changed files with 745 additions and 42 deletions.

This file was deleted.

12 changes: 0 additions & 12 deletions app/src/main/aidl/cc/ioctl/nfcdevicehost/ipc/IRemoteRuntime.aidl

This file was deleted.

5 changes: 5 additions & 0 deletions app/src/main/cpp/libnciclient/NciHostDaemonProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,8 @@ TypedLpcResult<bool> NciHostDaemonProxy::isNfcDiscoverySoundDisabled() {
TypedLpcResult<bool> NciHostDaemonProxy::setNfcDiscoverySoundDisabled(bool disable) {
return invokeRemoteProcedure<bool, const bool &>(Ids::setNfcDiscoverySoundDisabled, disable);
}

TypedLpcResult<std::vector<LogEntryRecord>> NciHostDaemonProxy::getLogsPartial(uint32_t startIndex, uint32_t count) {
return invokeRemoteProcedure<std::vector<LogEntryRecord>, const uint32_t &, const uint32_t &>(
Ids::getLogsPartial, startIndex, count);
}
2 changes: 2 additions & 0 deletions app/src/main/cpp/libnciclient/NciHostDaemonProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class NciHostDaemonProxy : public INciHostDaemon, public BaseIpcProxy {
TypedLpcResult<bool> isNfcDiscoverySoundDisabled() override;

TypedLpcResult<bool> setNfcDiscoverySoundDisabled(bool disable) override;

TypedLpcResult<std::vector<LogEntryRecord>> getLogsPartial(uint32_t startIndex, uint32_t count) override;
};

}
Expand Down
51 changes: 51 additions & 0 deletions app/src/main/cpp/libnciclient/ipc_handle_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "ipc_handle_jni.h"
#include "IpcConnector.h"
#include "../rpcprotocol/log/Log.h"
#include "../rpcprotocol/log/LogEntryRecord.h"
#include "NciClientImpl.h"
#include "rpcprotocol/INciHostDaemon.h"

Expand Down Expand Up @@ -43,6 +44,19 @@ static inline jstring getJStringOrNull(JNIEnv *env, const std::string &str) {
return str.empty() ? nullptr : getJString(env, str);
}

static jobject getJLogEntryRecordObject(JNIEnv *env, const LogEntryRecord &log) {
jclass clazz = env->FindClass("cc/ioctl/nfcdevicehost/ipc/daemon/INciHostDaemon$LogEntryRecord");
jmethodID constructor = env->GetMethodID(clazz, "<init>", "(IJILjava/lang/String;Ljava/lang/String;)V");
jint jlevel = static_cast<jint>(log.level);
jstring tag = getJString(env, log.tag);
jstring message = getJString(env, log.message);
jobject obj = env->NewObject(clazz, constructor, jint(log.id), jlong(log.timestamp), jlevel, tag, message);
env->DeleteLocalRef(tag);
env->DeleteLocalRef(message);
env->DeleteLocalRef(clazz);
return obj;
}

template<class T>
bool jniThrowLpcResultErrorOrException(JNIEnv *env, const TypedLpcResult<T> &result) {
if (uint32_t err = result.getError(); err != 0) {
Expand Down Expand Up @@ -945,3 +959,40 @@ Java_cc_ioctl_nfcdevicehost_ipc_daemon_internal_NciHostDaemonProxy_setNfcDiscove
return 0;
}
}

/*
* Class: cc_ioctl_nfcdevicehost_ipc_daemon_internal_NciHostDaemonProxy
* Method: getLogsPartial
* Signature: (II)[Lcc/ioctl/nfcdevicehost/ipc/daemon/INciHostDaemon/LogEntryRecord;
*/
extern "C" [[maybe_unused]] JNIEXPORT jobjectArray JNICALL
Java_cc_ioctl_nfcdevicehost_ipc_daemon_internal_NciHostDaemonProxy_getLogsPartial
(JNIEnv *env, jobject, jint start, jint count) {
IpcConnector &connector = IpcConnector::getInstance();
INciHostDaemon *proxy = connector.getNciDaemon();
if (proxy == nullptr) {
env->ThrowNew(env->FindClass("java/lang/IllegalStateException"),
"attempt to transact while proxy object not available");
return nullptr;
} else {
if (auto lpcResult = proxy->getLogsPartial(uint32_t(start), uint32_t(count));
!jniThrowLpcResultErrorOrException(env, lpcResult)) {
std::vector<LogEntryRecord> r;
if (lpcResult.getResult(&r)) {
jclass clazzArray = env->FindClass(
"cc/ioctl/nfcdevicehost/ipc/daemon/INciHostDaemon$LogEntryRecord");
jobjectArray result = env->NewObjectArray(jint(r.size()), clazzArray, nullptr);
for (int i = 0; i < r.size(); ++i) {
jobject obj = getJLogEntryRecordObject(env, r[i]);
env->SetObjectArrayElement(result, i, obj);
}
return result;
} else {
env->ThrowNew(env->FindClass("java/lang/RuntimeException"),
"error while read data from LpcResult");
return nullptr;
}
}
return nullptr;
}
}
16 changes: 8 additions & 8 deletions app/src/main/cpp/libnciclient/ipc_handle_jni.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/src/main/cpp/ncihostd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ project(ncihostd)

set(CMAKE_CXX_STANDARD 17)

add_executable(ncihostd startup/startup.c startup/daemon.cpp ipc/IpcStateController.cpp
add_executable(ncihostd startup/startup.c startup/daemon.cpp ipc/IpcStateController.cpp ipc/logbuffer/LocalLogBuffer.cpp
service/front/NciHostDaemonImpl.cpp service/front/NciClientProxy.cpp service/HwServiceStatus.cpp
elfsym/ElfView.cpp elfsym/ProcessView.cpp inject/Injector.cpp inject/arch/ptrace_inject_utils.cpp
inject/arch/ptrace_inject_arm_impl.cpp inject/arch/ptrace_inject_x86_impl.cpp inject/SysServicePatch.cpp
Expand Down
74 changes: 74 additions & 0 deletions app/src/main/cpp/ncihostd/ipc/logbuffer/LocalLogBuffer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// Created by kinit on 2022-01-02.
//

#include "LocalLogBuffer.h"

using namespace logbuffer;

LocalLogBuffer &LocalLogBuffer::getInstance() {
static LocalLogBuffer gwInstance;
return gwInstance;
}

void LocalLogBuffer::append(const LogEntryRecord &entry) {
LogEntryRecord log = entry;
// fill in the sequence number
log.id = mSequenceNumber++;
std::scoped_lock lock(mMutex);
mLogRecords.push_back(log);
// drop the oldest log records if the buffer is full
if (mLogRecords.size() > MAX_LOG_ENTRIES) {
mLogRecords.pop_front();
}
}

std::vector<LogEntryRecord> LocalLogBuffer::getAllLogs() {
std::scoped_lock lock(mMutex);
std::vector<LogEntryRecord> logs;
logs.reserve(mLogRecords.size());
for (const auto &log: mLogRecords) {
logs.push_back(log);
}
return logs;
}

std::vector<LogEntryRecord> LocalLogBuffer::getLogsPartial(uint32_t start, uint32_t count) {
std::scoped_lock lock(mMutex);
if (mLogRecords.empty()) {
return {};
}
std::vector<LogEntryRecord> logs;
// iterate the log records
auto it = mLogRecords.cbegin();
while (it != mLogRecords.cend()) {
if (auto &log = *it; log.id >= start) {
// found the start index
if (logs.size() >= count) {
break;
}
// add the log to the result list
logs.push_back(log);
}
it++;
}
return logs;
}

size_t LocalLogBuffer::getLogCount() const {
return mLogRecords.size();
}

void LocalLogBuffer::clear() noexcept {
std::scoped_lock lock(mMutex);
mLogRecords.clear();
}

uint32_t LocalLogBuffer::getFirstLogEntryIndex() noexcept {
std::scoped_lock lock(mMutex);
if (mLogRecords.empty()) {
return 0;
} else {
return mLogRecords.front().id;
}
}
51 changes: 51 additions & 0 deletions app/src/main/cpp/ncihostd/ipc/logbuffer/LocalLogBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// Created by kinit on 2022-01-02.
//

#ifndef NCI_HOST_NATIVES_LOCALLOGBUFFER_H
#define NCI_HOST_NATIVES_LOCALLOGBUFFER_H

#include <cstdint>
#include <vector>
#include <deque>
#include <mutex>
#include <atomic>

#include "rpcprotocol/log/LogEntryRecord.h"

namespace logbuffer {

class LocalLogBuffer {
private:
constexpr static size_t MAX_LOG_ENTRIES = 4096;

LocalLogBuffer() = default;

public:
LocalLogBuffer(const LocalLogBuffer &) = delete;

LocalLogBuffer &operator=(const LocalLogBuffer &) = delete;

[[nodiscard]] static LocalLogBuffer &getInstance();

void append(const LogEntryRecord &entry);

[[nodiscard]] std::vector<LogEntryRecord> getAllLogs();

[[nodiscard]] std::vector<LogEntryRecord> getLogsPartial(uint32_t start, uint32_t count);

[[nodiscard]] uint32_t getFirstLogEntryIndex() noexcept;

[[nodiscard]] size_t getLogCount() const;

void clear() noexcept;

private:
std::deque<LogEntryRecord> mLogRecords;
std::mutex mMutex;
std::atomic_uint32_t mSequenceNumber = 1;
};

}

#endif //NCI_HOST_NATIVES_LOCALLOGBUFFER_H
13 changes: 13 additions & 0 deletions app/src/main/cpp/ncihostd/service/front/NciHostDaemonImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "rpcprotocol/utils/auto_close_fd.h"
#include "rpcprotocol/utils/SELinux.h"
#include "rpcprotocol/log/Log.h"
#include "ncihostd/ipc/logbuffer/LocalLogBuffer.h"
#include "rpcprotocol/protocol/LpcArgListExtractor.h"
#include "rpcprotocol/utils/ProcessUtils.h"

Expand Down Expand Up @@ -141,6 +142,12 @@ bool NciHostDaemonImpl::dispatchLpcInvocation([[maybe_unused]] const IpcTransact
}));
return true;
}
case Ids::getLogsPartial: {
result = R::invoke(this, args, R::is(+[](T *p, uint32_t start, uint32_t length) {
return p->getLogsPartial(start, length);
}));
return true;
}
default:
return false;
}
Expand Down Expand Up @@ -485,3 +492,9 @@ TypedLpcResult<bool> NciHostDaemonImpl::setNfcDiscoverySoundDisabled(bool disabl
auto &androidNfcService = androidsvc::AndroidNfcService::getInstance();
return {androidNfcService.setNfcDiscoverySoundDisabled(disable)};
}

TypedLpcResult<std::vector<LogEntryRecord>> NciHostDaemonImpl::getLogsPartial(uint32_t startIndex, uint32_t count) {
auto &logBuffer = logbuffer::LocalLogBuffer::getInstance();
auto logs = logBuffer.getLogsPartial(startIndex, count);
return {logs};
}
2 changes: 2 additions & 0 deletions app/src/main/cpp/ncihostd/service/front/NciHostDaemonImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class NciHostDaemonImpl : public INciHostDaemon, public BaseIpcObject {

TypedLpcResult<bool> setNfcDiscoverySoundDisabled(bool disable) override;

TypedLpcResult<std::vector<LogEntryRecord>> getLogsPartial(uint32_t startIndex, uint32_t count) override;

private:
std::mutex mEventMutex;
std::deque<std::tuple<halpatch::IoSyscallEvent, std::vector<uint8_t>>> mHistoryIoEvents;
Expand Down
16 changes: 15 additions & 1 deletion app/src/main/cpp/ncihostd/startup/daemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "daemon.h"
#include "../ipc/IpcStateController.h"
#include "rpcprotocol/log/Log.h"
#include "../ipc/logbuffer/LocalLogBuffer.h"
#include "rpcprotocol/protocol/rpc_struct.h"
#include "rpcprotocol/protocol/IpcTransactor.h"

Expand Down Expand Up @@ -156,8 +157,19 @@ bool doConnect(const IpcSocketMeta &target, int uid) {

timespec gStartTime;

void log_to_local_log_buffer(Log::Level level, const char *tag, const char *msg) {
timespec systime = {};
clock_gettime(CLOCK_REALTIME, &systime);
uint64_t timestampMs = uint64_t(systime.tv_sec) * 1000LL + uint64_t(systime.tv_nsec) / 1000000LL;
auto &logBuffer = logbuffer::LocalLogBuffer::getInstance();
// leave id as 0, it will be filled in by the log buffer
LogEntryRecord log = LogEntryRecord(0, timestampMs, level, tag, msg);
logBuffer.append(log);
}

void log_print_handler(Log::Level level, const char *tag, const char *msg) {
timespec systime;
log_to_local_log_buffer(level, tag, msg);
timespec systime = {};
clock_gettime(CLOCK_MONOTONIC, &systime);
uint64_t dsec = systime.tv_sec - gStartTime.tv_sec;
double reltime = double(dsec) + double(int64_t(systime.tv_nsec) - int64_t(gStartTime.tv_sec)) / 1000000000.0;
Expand Down Expand Up @@ -228,6 +240,8 @@ extern "C" void startDaemon(int uid, const char *ipcFilePath, int daemonize) {
printf("startup_do_daemonize error: %d", err);
exit(-1);
}
// set the log handler
Log::setLogHandler(&log_to_local_log_buffer);
} else {
// do not daemonize, just use stdout as log output
Log::setLogHandler(&log_print_handler);
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/cpp/rpcprotocol/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ add_library(rpcprotocol STATIC
protocol/RemoteException.cpp utils/SharedBuffer.cpp protocol/IpcTransactor.cpp protocol/LpcResult.cpp
protocol/BaseIpcObject.cpp protocol/BaseIpcProxy.cpp INciHostDaemon.cpp
log/Log.cpp utils/io_utils.cpp utils/Uuid.cpp utils/SignalHandler.cpp utils/FileMemMap.cpp utils/TextUtils.cpp
log/SessionLog.h log/DefaultSessionLogImpl.cpp)
log/SessionLog.h log/DefaultSessionLogImpl.cpp log/LogEntryRecord.cpp)

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
SET(CLANG_CXX_EXTRA_OPT "-Werror=unknown-warning-option -Werror=format-invalid-specifier -Werror=call-to-pure-virtual-from-ctor-dtor")
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/cpp/rpcprotocol/INciHostDaemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <vector>

#include "../libbasehalpatch/ipc/daemon_ipc_struct.h"
#include "log/LogEntryRecord.h"
#include "protocol/ArgList.h"
#include "protocol/LpcResult.h"

Expand Down Expand Up @@ -112,6 +113,9 @@ class INciHostDaemon {
[[nodiscard]]
virtual TypedLpcResult<bool> setNfcDiscoverySoundDisabled(bool disable) = 0;

[[nodiscard]]
virtual TypedLpcResult<std::vector<LogEntryRecord>> getLogsPartial(uint32_t startIndex, uint32_t count) = 0;

class TransactionIds {
public:
static constexpr uint32_t getVersionName = 1;
Expand All @@ -131,6 +135,7 @@ class INciHostDaemon {
static constexpr uint32_t connectToAndroidNfcService = 20;
static constexpr uint32_t isNfcDiscoverySoundDisabled = 21;
static constexpr uint32_t setNfcDiscoverySoundDisabled = 22;
static constexpr uint32_t getLogsPartial = 23;
};
};

Expand Down
Loading

0 comments on commit 3207fda

Please sign in to comment.