This cl formats incidentd and makes it easier for debugging.
Bug: 72755317
Test: clang-format -type=file -i <files>
Change-Id: Ide91227f26c6b1db6d2e5fe8117ca5cc4cf77fd3
diff --git a/cmds/incidentd/.clang-format b/cmds/incidentd/.clang-format
new file mode 100644
index 0000000..6fa5b47
--- /dev/null
+++ b/cmds/incidentd/.clang-format
@@ -0,0 +1,17 @@
+BasedOnStyle: Google
+AllowShortIfStatementsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: true
+AllowShortLoopsOnASingleLine: true
+BinPackArguments: true
+BinPackParameters: true
+ColumnLimit: 100
+CommentPragmas: NOLINT:.*
+ContinuationIndentWidth: 8
+DerivePointerAlignment: false
+IndentWidth: 4
+PointerAlignment: Left
+TabWidth: 4
+AccessModifierOffset: -4
+IncludeCategories:
+ - Regex: '^"Log\.h"'
+ Priority: -1
diff --git a/cmds/incidentd/Android.mk b/cmds/incidentd/Android.mk
index 23cd2af..d2d24c8 100644
--- a/cmds/incidentd/Android.mk
+++ b/cmds/incidentd/Android.mk
@@ -32,7 +32,7 @@
src/Privacy.cpp \
src/Reporter.cpp \
src/Section.cpp \
- src/io_util.cpp \
+ src/incidentd_util.cpp \
src/main.cpp \
src/report_directory.cpp
@@ -116,7 +116,7 @@
src/Privacy.cpp \
src/Reporter.cpp \
src/Section.cpp \
- src/io_util.cpp \
+ src/incidentd_util.cpp \
src/report_directory.cpp \
tests/section_list.cpp \
tests/PrivacyBuffer_test.cpp \
diff --git a/cmds/incidentd/README.md b/cmds/incidentd/README.md
index 71c6deb..1730a640 100644
--- a/cmds/incidentd/README.md
+++ b/cmds/incidentd/README.md
@@ -20,4 +20,8 @@
```
root$ atest incidentd_test
-```
\ No newline at end of file
+```
+
+Use clang-format to style the file
+
+clang-format -style=file -i <file list>
\ No newline at end of file
diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp
index 0fff4e6..883924c8 100644
--- a/cmds/incidentd/src/FdBuffer.cpp
+++ b/cmds/incidentd/src/FdBuffer.cpp
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#define LOG_TAG "incidentd"
+#include "Log.h"
#include "FdBuffer.h"
@@ -26,30 +25,16 @@
#include <unistd.h>
#include <wait.h>
-const bool DEBUG = false;
-const ssize_t BUFFER_SIZE = 16 * 1024; // 16 KB
-const ssize_t MAX_BUFFER_COUNT = 256; // 4 MB max
+const ssize_t BUFFER_SIZE = 16 * 1024; // 16 KB
+const ssize_t MAX_BUFFER_COUNT = 256; // 4 MB max
FdBuffer::FdBuffer()
- :mBuffer(BUFFER_SIZE),
- mStartTime(-1),
- mFinishTime(-1),
- mTimedOut(false),
- mTruncated(false)
-{
-}
+ : mBuffer(BUFFER_SIZE), mStartTime(-1), mFinishTime(-1), mTimedOut(false), mTruncated(false) {}
-FdBuffer::~FdBuffer()
-{
-}
+FdBuffer::~FdBuffer() {}
-status_t
-FdBuffer::read(int fd, int64_t timeout)
-{
- struct pollfd pfds = {
- .fd = fd,
- .events = POLLIN
- };
+status_t FdBuffer::read(int fd, int64_t timeout) {
+ struct pollfd pfds = {.fd = fd, .events = POLLIN};
mStartTime = uptimeMillis();
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
@@ -63,22 +48,22 @@
int64_t remainingTime = (mStartTime + timeout) - uptimeMillis();
if (remainingTime <= 0) {
- if (DEBUG) ALOGD("timed out due to long read");
+ VLOG("timed out due to long read");
mTimedOut = true;
break;
}
int count = poll(&pfds, 1, remainingTime);
if (count == 0) {
- if (DEBUG) ALOGD("timed out due to block calling poll");
+ VLOG("timed out due to block calling poll");
mTimedOut = true;
break;
} else if (count < 0) {
- if (DEBUG) ALOGD("poll failed: %s", strerror(errno));
+ VLOG("poll failed: %s", strerror(errno));
return -errno;
} else {
if ((pfds.revents & POLLERR) != 0) {
- if (DEBUG) ALOGD("return event has error %s", strerror(errno));
+ VLOG("return event has error %s", strerror(errno));
return errno != 0 ? -errno : UNKNOWN_ERROR;
} else {
ssize_t amt = ::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite());
@@ -86,7 +71,7 @@
if (errno == EAGAIN || errno == EWOULDBLOCK) {
continue;
} else {
- if (DEBUG) ALOGD("Fail to read %d: %s", fd, strerror(errno));
+ VLOG("Fail to read %d: %s", fd, strerror(errno));
return -errno;
}
} else if (amt == 0) {
@@ -100,13 +85,12 @@
return NO_ERROR;
}
-status_t
-FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeoutMs, const bool isSysfs)
-{
+status_t FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeoutMs,
+ const bool isSysfs) {
struct pollfd pfds[] = {
- { .fd = fd, .events = POLLIN },
- { .fd = toFd, .events = POLLOUT },
- { .fd = fromFd, .events = POLLIN },
+ {.fd = fd, .events = POLLIN},
+ {.fd = toFd, .events = POLLOUT},
+ {.fd = fromFd, .events = POLLIN},
};
mStartTime = uptimeMillis();
@@ -131,7 +115,7 @@
int64_t remainingTime = (mStartTime + timeoutMs) - uptimeMillis();
if (remainingTime <= 0) {
- if (DEBUG) ALOGD("timed out due to long read");
+ VLOG("timed out due to long read");
mTimedOut = true;
break;
}
@@ -139,11 +123,11 @@
// wait for any pfds to be ready to perform IO
int count = poll(pfds, 3, remainingTime);
if (count == 0) {
- if (DEBUG) ALOGD("timed out due to block calling poll");
+ VLOG("timed out due to block calling poll");
mTimedOut = true;
break;
} else if (count < 0) {
- if (DEBUG) ALOGD("Fail to poll: %s", strerror(errno));
+ VLOG("Fail to poll: %s", strerror(errno));
return -errno;
}
@@ -151,10 +135,10 @@
for (int i = 0; i < 3; ++i) {
if ((pfds[i].revents & POLLERR) != 0) {
if (i == 0 && isSysfs) {
- if (DEBUG) ALOGD("fd %d is sysfs, ignore its POLLERR return value", fd);
+ VLOG("fd %d is sysfs, ignore its POLLERR return value", fd);
continue;
}
- if (DEBUG) ALOGD("fd[%d]=%d returns error events: %s", i, fd, strerror(errno));
+ VLOG("fd[%d]=%d returns error events: %s", i, fd, strerror(errno));
return errno != 0 ? -errno : UNKNOWN_ERROR;
}
}
@@ -169,9 +153,9 @@
}
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
- if (DEBUG) ALOGD("Fail to read fd %d: %s", fd, strerror(errno));
+ VLOG("Fail to read fd %d: %s", fd, strerror(errno));
return -errno;
- } // otherwise just continue
+ } // otherwise just continue
} else if (amt == 0) { // reach EOF so don't have to poll pfds[0].
::close(pfds[0].fd);
pfds[0].fd = -1;
@@ -191,9 +175,9 @@
}
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
- if (DEBUG) ALOGD("Fail to write toFd %d: %s", toFd, strerror(errno));
+ VLOG("Fail to write toFd %d: %s", toFd, strerror(errno));
return -errno;
- } // otherwise just continue
+ } // otherwise just continue
} else {
wpos += amt;
cirSize -= amt;
@@ -218,9 +202,9 @@
ssize_t amt = ::read(fromFd, mBuffer.writeBuffer(), mBuffer.currentToWrite());
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
- if (DEBUG) ALOGD("Fail to read fromFd %d: %s", fromFd, strerror(errno));
+ VLOG("Fail to read fromFd %d: %s", fromFd, strerror(errno));
return -errno;
- } // otherwise just continue
+ } // otherwise just continue
} else if (amt == 0) {
break;
} else {
@@ -232,14 +216,6 @@
return NO_ERROR;
}
-size_t
-FdBuffer::size() const
-{
- return mBuffer.size();
-}
+size_t FdBuffer::size() const { return mBuffer.size(); }
-EncodedBuffer::iterator
-FdBuffer::data() const
-{
- return mBuffer.begin();
-}
+EncodedBuffer::iterator FdBuffer::data() const { return mBuffer.begin(); }
diff --git a/cmds/incidentd/src/FdBuffer.h b/cmds/incidentd/src/FdBuffer.h
index 48dc855..5bfa093 100644
--- a/cmds/incidentd/src/FdBuffer.h
+++ b/cmds/incidentd/src/FdBuffer.h
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#pragma once
#ifndef FD_BUFFER_H
#define FD_BUFFER_H
@@ -27,8 +28,7 @@
/**
* Reads a file into a buffer, and then writes that data to an FdSet.
*/
-class FdBuffer
-{
+class FdBuffer {
public:
FdBuffer();
~FdBuffer();
@@ -50,7 +50,8 @@
*
* Poll will return POLLERR if fd is from sysfs, handle this edge case.
*/
- status_t readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeoutMs, const bool isSysfs=false);
+ status_t readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeoutMs,
+ const bool isSysfs = false);
/**
* Whether we timed out.
@@ -90,4 +91,4 @@
bool mTruncated;
};
-#endif // FD_BUFFER_H
+#endif // FD_BUFFER_H
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index 654036e..9ae6240 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -13,15 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#define LOG_TAG "incidentd"
+#include "Log.h"
#include "IncidentService.h"
+#include "FdBuffer.h"
+#include "PrivacyBuffer.h"
#include "Reporter.h"
+#include "incidentd_util.h"
+#include "section_list.h"
#include <binder/IPCThreadState.h>
+#include <binder/IResultReceiver.h>
#include <binder/IServiceManager.h>
+#include <binder/IShellCallback.h>
#include <cutils/log.h>
#include <private/android_filesystem_config.h>
#include <utils/Looper.h>
@@ -29,11 +34,9 @@
#include <unistd.h>
using namespace android;
+using namespace android::base;
-enum {
- WHAT_RUN_REPORT = 1,
- WHAT_SEND_BACKLOG_TO_DROPBOX = 2
-};
+enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
//#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL * 60 * 5)
#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
@@ -42,9 +45,7 @@
String16 const DUMP_PERMISSION("android.permission.DUMP");
String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
-static Status
-checkIncidentPermissions(const IncidentReportArgs& args)
-{
+static Status checkIncidentPermissions(const IncidentReportArgs& args) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
pid_t callingPid = IPCThreadState::self()->getCallingPid();
if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
@@ -55,14 +56,16 @@
// checking calling permission.
if (!checkCallingPermission(DUMP_PERMISSION)) {
ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
- callingPid, callingUid);
- return Status::fromExceptionCode(Status::EX_SECURITY,
+ callingPid, callingUid);
+ return Status::fromExceptionCode(
+ Status::EX_SECURITY,
"Calling process does not have permission: android.permission.DUMP");
}
if (!checkCallingPermission(USAGE_STATS_PERMISSION)) {
ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS",
- callingPid, callingUid);
- return Status::fromExceptionCode(Status::EX_SECURITY,
+ callingPid, callingUid);
+ return Status::fromExceptionCode(
+ Status::EX_SECURITY,
"Calling process does not have permission: android.permission.USAGE_STATS");
}
@@ -71,40 +74,34 @@
case DEST_LOCAL:
if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
- callingPid, callingUid);
- return Status::fromExceptionCode(Status::EX_SECURITY,
- "Calling process does not have permission to get local data.");
+ callingPid, callingUid);
+ return Status::fromExceptionCode(
+ Status::EX_SECURITY,
+ "Calling process does not have permission to get local data.");
}
case DEST_EXPLICIT:
- if (callingUid != AID_SHELL && callingUid != AID_ROOT &&
- callingUid != AID_STATSD && callingUid != AID_SYSTEM) {
+ if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
+ callingUid != AID_SYSTEM) {
ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
- callingPid, callingUid);
- return Status::fromExceptionCode(Status::EX_SECURITY,
- "Calling process does not have permission to get explicit data.");
+ callingPid, callingUid);
+ return Status::fromExceptionCode(
+ Status::EX_SECURITY,
+ "Calling process does not have permission to get explicit data.");
}
}
return Status::ok();
}
// ================================================================================
-ReportRequestQueue::ReportRequestQueue()
-{
-}
+ReportRequestQueue::ReportRequestQueue() {}
-ReportRequestQueue::~ReportRequestQueue()
-{
-}
+ReportRequestQueue::~ReportRequestQueue() {}
-void
-ReportRequestQueue::addRequest(const sp<ReportRequest>& request)
-{
+void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
unique_lock<mutex> lock(mLock);
mQueue.push_back(request);
}
-sp<ReportRequest>
-ReportRequestQueue::getNextRequest()
-{
+sp<ReportRequest> ReportRequestQueue::getNextRequest() {
unique_lock<mutex> lock(mLock);
if (mQueue.empty()) {
return NULL;
@@ -115,22 +112,13 @@
}
}
-
// ================================================================================
ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue)
- :mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
- mHandlerLooper(handlerLooper),
- mQueue(queue)
-{
-}
+ : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS), mHandlerLooper(handlerLooper), mQueue(queue) {}
-ReportHandler::~ReportHandler()
-{
-}
+ReportHandler::~ReportHandler() {}
-void
-ReportHandler::handleMessage(const Message& message)
-{
+void ReportHandler::handleMessage(const Message& message) {
switch (message.what) {
case WHAT_RUN_REPORT:
run_report();
@@ -141,33 +129,24 @@
}
}
-void
-ReportHandler::scheduleRunReport(const sp<ReportRequest>& request)
-{
+void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
mQueue->addRequest(request);
mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
}
-void
-ReportHandler::scheduleSendBacklogToDropbox()
-{
+void ReportHandler::scheduleSendBacklogToDropbox() {
unique_lock<mutex> lock(mLock);
mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
schedule_send_backlog_to_dropbox_locked();
}
-void
-ReportHandler::schedule_send_backlog_to_dropbox_locked()
-{
+void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
- mHandlerLooper->sendMessageDelayed(mBacklogDelay, this,
- Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
+ mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
}
-void
-ReportHandler::run_report()
-{
+void ReportHandler::run_report() {
sp<Reporter> reporter = new Reporter();
// Merge all of the requests into one that has all of the
@@ -190,15 +169,13 @@
}
}
-void
-ReportHandler::send_backlog_to_dropbox()
-{
+void ReportHandler::send_backlog_to_dropbox() {
if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
// There was a failure. Exponential backoff.
unique_lock<mutex> lock(mLock);
mBacklogDelay *= 2;
ALOGI("Error sending to dropbox. Trying again in %lld minutes",
- (mBacklogDelay / (1000000000LL * 60)));
+ (mBacklogDelay / (1000000000LL * 60)));
schedule_send_backlog_to_dropbox_locked();
} else {
mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
@@ -207,18 +184,13 @@
// ================================================================================
IncidentService::IncidentService(const sp<Looper>& handlerLooper)
- :mQueue(new ReportRequestQueue())
-{
+ : mQueue(new ReportRequestQueue()) {
mHandler = new ReportHandler(handlerLooper, mQueue);
}
-IncidentService::~IncidentService()
-{
-}
+IncidentService::~IncidentService() {}
-Status
-IncidentService::reportIncident(const IncidentReportArgs& args)
-{
+Status IncidentService::reportIncident(const IncidentReportArgs& args) {
ALOGI("reportIncident");
Status status = checkIncidentPermissions(args);
@@ -231,10 +203,9 @@
return Status::ok();
}
-Status
-IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
- const sp<IIncidentReportStatusListener>& listener, const unique_fd& stream)
-{
+Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
+ const sp<IIncidentReportStatusListener>& listener,
+ const unique_fd& stream) {
ALOGI("reportIncidentToStream");
Status status = checkIncidentPermissions(args);
@@ -252,12 +223,10 @@
return Status::ok();
}
-Status
-IncidentService::systemRunning()
-{
+Status IncidentService::systemRunning() {
if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
return Status::fromExceptionCode(Status::EX_SECURITY,
- "Only system uid can call systemRunning");
+ "Only system uid can call systemRunning");
}
// When system_server is up and running, schedule the dropbox task to run.
@@ -266,3 +235,120 @@
return Status::ok();
}
+/**
+ * Implement our own because the default binder implementation isn't
+ * properly handling SHELL_COMMAND_TRANSACTION.
+ */
+status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags) {
+ status_t err;
+
+ switch (code) {
+ case SHELL_COMMAND_TRANSACTION: {
+ int in = data.readFileDescriptor();
+ int out = data.readFileDescriptor();
+ int err = data.readFileDescriptor();
+ int argc = data.readInt32();
+ Vector<String8> args;
+ for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
+ args.add(String8(data.readString16()));
+ }
+ sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
+ sp<IResultReceiver> resultReceiver =
+ IResultReceiver::asInterface(data.readStrongBinder());
+
+ FILE* fin = fdopen(in, "r");
+ FILE* fout = fdopen(out, "w");
+ FILE* ferr = fdopen(err, "w");
+
+ if (fin == NULL || fout == NULL || ferr == NULL) {
+ resultReceiver->send(NO_MEMORY);
+ } else {
+ err = command(fin, fout, ferr, args);
+ resultReceiver->send(err);
+ }
+
+ if (fin != NULL) {
+ fflush(fin);
+ fclose(fin);
+ }
+ if (fout != NULL) {
+ fflush(fout);
+ fclose(fout);
+ }
+ if (fout != NULL) {
+ fflush(ferr);
+ fclose(ferr);
+ }
+
+ return NO_ERROR;
+ }
+ default: { return BnIncidentManager::onTransact(code, data, reply, flags); }
+ }
+}
+
+status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
+ const int argCount = args.size();
+
+ if (argCount >= 1) {
+ if (!args[0].compare(String8("privacy"))) {
+ return cmd_privacy(in, out, err, args);
+ }
+ }
+ return cmd_help(out);
+}
+
+status_t IncidentService::cmd_help(FILE* out) {
+ fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
+ fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
+ fprintf(out, " Prints/parses for the section id.\n");
+ return NO_ERROR;
+}
+
+static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
+ if (p == NULL) return;
+ fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
+ if (p->children == NULL) return;
+ for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
+ printPrivacy(p->children[i], out, indent + " ");
+ }
+}
+
+status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
+ const int argCount = args.size();
+ if (argCount >= 3) {
+ String8 opt = args[1];
+ int sectionId = atoi(args[2].string());
+
+ const Privacy* p = get_privacy_of_section(sectionId);
+ if (p == NULL) {
+ fprintf(err, "Can't find section id %d\n", sectionId);
+ return NO_ERROR;
+ }
+ fprintf(err, "Get privacy for %d\n", sectionId);
+ if (opt == "print") {
+ printPrivacy(p, out, String8(""));
+ } else if (opt == "parse") {
+ FdBuffer buf;
+ status_t error = buf.read(fileno(in), 60000);
+ if (error != NO_ERROR) {
+ fprintf(err, "Error reading from stdin\n");
+ return error;
+ }
+ fprintf(err, "Read %zu bytes\n", buf.size());
+ auto data = buf.data();
+ PrivacyBuffer pBuf(p, data);
+
+ PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
+ error = pBuf.strip(spec);
+ if (error != NO_ERROR) {
+ fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
+ return error;
+ }
+ return pBuf.flush(fileno(out));
+ }
+ } else {
+ return cmd_help(out);
+ }
+ return NO_ERROR;
+}
diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h
index d6f33df..3c66507 100644
--- a/cmds/incidentd/src/IncidentService.h
+++ b/cmds/incidentd/src/IncidentService.h
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#pragma once
#ifndef INCIDENT_SERVICE_H
#define INCIDENT_SERVICE_H
@@ -32,8 +33,7 @@
using namespace std;
// ================================================================================
-class ReportRequestQueue : public virtual RefBase
-{
+class ReportRequestQueue : public virtual RefBase {
public:
ReportRequestQueue();
virtual ~ReportRequestQueue();
@@ -46,10 +46,8 @@
deque<sp<ReportRequest> > mQueue;
};
-
// ================================================================================
-class ReportHandler : public MessageHandler
-{
+class ReportHandler : public MessageHandler {
public:
ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue);
virtual ~ReportHandler();
@@ -89,7 +87,6 @@
void send_backlog_to_dropbox();
};
-
// ================================================================================
class IncidentService : public BnIncidentManager {
public:
@@ -99,14 +96,29 @@
virtual Status reportIncident(const IncidentReportArgs& args);
virtual Status reportIncidentToStream(const IncidentReportArgs& args,
- const sp<IIncidentReportStatusListener>& listener, const unique_fd& stream);
+ const sp<IIncidentReportStatusListener>& listener,
+ const unique_fd& stream);
virtual Status systemRunning();
+ // Implement commands for debugging purpose.
+ virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags) override;
+ virtual status_t command(FILE* in, FILE* out, FILE* err, Vector<String8>& args);
+
private:
sp<ReportRequestQueue> mQueue;
sp<ReportHandler> mHandler;
+
+ /**
+ * Commands print out help.
+ */
+ status_t cmd_help(FILE* out);
+
+ /**
+ * Commands related to privacy filtering.
+ */
+ status_t cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args);
};
-
-#endif // INCIDENT_SERVICE_H
+#endif // INCIDENT_SERVICE_H
diff --git a/cmds/incidentd/src/Log.h b/cmds/incidentd/src/Log.h
new file mode 100644
index 0000000..46efbd1
--- /dev/null
+++ b/cmds/incidentd/src/Log.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/*
+ * This file must be included at the top of the file. Other header files
+ * occasionally include log.h, and if LOG_TAG isn't set when that happens
+ * we'll get a preprocesser error when we try to define it here.
+ */
+
+#pragma once
+
+#define LOG_TAG "incidentd"
+#define DEBUG false
+
+#include <log/log.h>
+
+// Use the local value to turn on/off debug logs instead of using log.tag.properties.
+// The advantage is that in production compiler can remove the logging code if the local
+// DEBUG/VERBOSE is false.
+#define VLOG(...) \
+ if (DEBUG) ALOGD(__VA_ARGS__);
\ No newline at end of file
diff --git a/cmds/incidentd/src/Privacy.cpp b/cmds/incidentd/src/Privacy.cpp
index c5078f0..c42a87b 100644
--- a/cmds/incidentd/src/Privacy.cpp
+++ b/cmds/incidentd/src/Privacy.cpp
@@ -21,10 +21,9 @@
uint64_t encode_field_id(const Privacy* p) { return (uint64_t)p->type << 32 | p->field_id; }
-const Privacy* lookup(const Privacy* p, uint32_t fieldId)
-{
+const Privacy* lookup(const Privacy* p, uint32_t fieldId) {
if (p->children == NULL) return NULL;
- for (int i=0; p->children[i] != NULL; i++) { // NULL-terminated.
+ for (int i = 0; p->children[i] != NULL; i++) { // NULL-terminated.
if (p->children[i]->field_id == fieldId) return p->children[i];
// Incident section gen tool guarantees field ids in ascending order.
if (p->children[i]->field_id > fieldId) return NULL;
@@ -32,41 +31,31 @@
return NULL;
}
-static bool allowDest(const uint8_t dest, const uint8_t policy)
-{
+static bool allowDest(const uint8_t dest, const uint8_t policy) {
switch (policy) {
- case android::os::DEST_LOCAL:
- return dest == android::os::DEST_LOCAL;
- case android::os::DEST_EXPLICIT:
- case DEST_UNSET:
- return dest == android::os::DEST_LOCAL ||
- dest == android::os::DEST_EXPLICIT ||
- dest == DEST_UNSET;
- case android::os::DEST_AUTOMATIC:
- return true;
- default:
- return false;
+ case android::os::DEST_LOCAL:
+ return dest == android::os::DEST_LOCAL;
+ case android::os::DEST_EXPLICIT:
+ case DEST_UNSET:
+ return dest == android::os::DEST_LOCAL || dest == android::os::DEST_EXPLICIT ||
+ dest == DEST_UNSET;
+ case android::os::DEST_AUTOMATIC:
+ return true;
+ default:
+ return false;
}
}
-bool
-PrivacySpec::operator<(const PrivacySpec& other) const
-{
- return dest < other.dest;
-}
+bool PrivacySpec::operator<(const PrivacySpec& other) const { return dest < other.dest; }
-bool
-PrivacySpec::CheckPremission(const Privacy* privacy, const uint8_t defaultDest) const
-{
+bool PrivacySpec::CheckPremission(const Privacy* privacy, const uint8_t defaultDest) const {
uint8_t policy = privacy != NULL ? privacy->dest : defaultDest;
return allowDest(dest, policy);
}
-bool
-PrivacySpec::RequireAll() const { return dest == android::os::DEST_LOCAL; }
+bool PrivacySpec::RequireAll() const { return dest == android::os::DEST_LOCAL; }
-PrivacySpec PrivacySpec::new_spec(int dest)
-{
+PrivacySpec PrivacySpec::new_spec(int dest) {
switch (dest) {
case android::os::DEST_AUTOMATIC:
case android::os::DEST_EXPLICIT:
diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h
index ce1b8e9..6b6de9c 100644
--- a/cmds/incidentd/src/Privacy.h
+++ b/cmds/incidentd/src/Privacy.h
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#pragma once
#ifndef PRIVACY_H
#define PRIVACY_H
@@ -20,7 +21,7 @@
#include <stdint.h>
// This is the default value of DEST enum, sync with privacy.proto
-const uint8_t DEST_UNSET = 255; // DEST_UNSET is not exposed to libincident
+const uint8_t DEST_UNSET = 255; // DEST_UNSET is not exposed to libincident
const uint8_t DEST_DEFAULT_VALUE = DEST_UNSET;
/*
@@ -68,15 +69,17 @@
bool operator<(const PrivacySpec& other) const;
// check permission of a policy, if returns true, don't strip the data.
- bool CheckPremission(const Privacy* privacy, const uint8_t defaultDest = DEST_DEFAULT_VALUE) const;
+ bool CheckPremission(const Privacy* privacy,
+ const uint8_t defaultDest = DEST_DEFAULT_VALUE) const;
// if returns true, no data need to be stripped.
bool RequireAll() const;
// Constructs spec using static methods below.
static PrivacySpec new_spec(int dest);
+
private:
PrivacySpec(uint8_t dest) : dest(dest) {}
};
-#endif // PRIVACY_H
+#endif // PRIVACY_H
diff --git a/cmds/incidentd/src/PrivacyBuffer.cpp b/cmds/incidentd/src/PrivacyBuffer.cpp
index f53befe..e4128f4 100644
--- a/cmds/incidentd/src/PrivacyBuffer.cpp
+++ b/cmds/incidentd/src/PrivacyBuffer.cpp
@@ -13,29 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#define LOG_TAG "incidentd"
+#include "Log.h"
#include "PrivacyBuffer.h"
-#include "io_util.h"
+#include "incidentd_util.h"
+#include <android-base/file.h>
#include <android/util/protobuf.h>
#include <cutils/log.h>
using namespace android::util;
-const bool DEBUG = false;
-
/**
* Write the field to buf based on the wire type, iterator will point to next field.
* If skip is set to true, no data will be written to buf. Return number of bytes written.
*/
-void
-PrivacyBuffer::writeFieldOrSkip(uint32_t fieldTag, bool skip)
-{
- if (DEBUG) ALOGD("%s field %d (wiretype = %d)", skip ? "skip" : "write",
- read_field_id(fieldTag), read_wire_type(fieldTag));
-
+void PrivacyBuffer::writeFieldOrSkip(uint32_t fieldTag, bool skip) {
uint8_t wireType = read_wire_type(fieldTag);
size_t bytesToWrite = 0;
uint32_t varint = 0;
@@ -54,18 +47,17 @@
break;
case WIRE_TYPE_LENGTH_DELIMITED:
bytesToWrite = mData.readRawVarint();
- if(!skip) mProto.writeLengthDelimitedHeader(read_field_id(fieldTag), bytesToWrite);
+ if (!skip) mProto.writeLengthDelimitedHeader(read_field_id(fieldTag), bytesToWrite);
break;
case WIRE_TYPE_FIXED32:
if (!skip) mProto.writeRawVarint(fieldTag);
bytesToWrite = 4;
break;
}
- if (DEBUG) ALOGD("%s %d bytes of data", skip ? "skip" : "write", (int)bytesToWrite);
if (skip) {
mData.rp()->move(bytesToWrite);
} else {
- for (size_t i=0; i<bytesToWrite; i++) {
+ for (size_t i = 0; i < bytesToWrite; i++) {
mProto.writeRawByte(mData.next());
}
}
@@ -78,28 +70,29 @@
* The iterator must point to the head of a protobuf formatted field for successful operation.
* After exit with NO_ERROR, iterator points to the next protobuf field's head.
*/
-status_t
-PrivacyBuffer::stripField(const Privacy* parentPolicy, const PrivacySpec& spec)
-{
+status_t PrivacyBuffer::stripField(const Privacy* parentPolicy, const PrivacySpec& spec,
+ int depth /* use as a counter for this recusive method. */) {
if (!mData.hasNext() || parentPolicy == NULL) return BAD_VALUE;
uint32_t fieldTag = mData.readRawVarint();
- const Privacy* policy = lookup(parentPolicy, read_field_id(fieldTag));
+ uint32_t fieldId = read_field_id(fieldTag);
+ const Privacy* policy = lookup(parentPolicy, fieldId);
+ VLOG("[Depth %2d]Try to strip id %d, wiretype %d", depth, fieldId, read_wire_type(fieldTag));
if (policy == NULL || policy->children == NULL) {
- if (DEBUG) ALOGD("Not a message field %d: dest(%d)", read_field_id(fieldTag),
- policy != NULL ? policy->dest : parentPolicy->dest);
-
bool skip = !spec.CheckPremission(policy, parentPolicy->dest);
// iterator will point to head of next field
+ size_t currentAt = mData.rp()->pos();
writeFieldOrSkip(fieldTag, skip);
+ VLOG("[Depth %2d]Field %d %ss %d bytes", depth, fieldId, skip ? "skip" : "write",
+ (int)(get_varint_size(fieldTag) + mData.rp()->pos() - currentAt));
return NO_ERROR;
}
// current field is message type and its sub-fields have extra privacy policies
uint32_t msgSize = mData.readRawVarint();
- EncodedBuffer::Pointer start = mData.rp()->copy();
+ size_t start = mData.rp()->pos();
long long token = mProto.start(encode_field_id(policy));
- while (mData.rp()->pos() - start.pos() != msgSize) {
- status_t err = stripField(policy, spec);
+ while (mData.rp()->pos() - start != msgSize) {
+ status_t err = stripField(policy, spec, depth + 1);
if (err != NO_ERROR) return err;
}
mProto.end(token);
@@ -108,53 +101,39 @@
// ================================================================================
PrivacyBuffer::PrivacyBuffer(const Privacy* policy, EncodedBuffer::iterator& data)
- :mPolicy(policy),
- mData(data),
- mProto(),
- mSize(0)
-{
-}
+ : mPolicy(policy), mData(data), mProto(), mSize(0) {}
-PrivacyBuffer::~PrivacyBuffer()
-{
-}
+PrivacyBuffer::~PrivacyBuffer() {}
-status_t
-PrivacyBuffer::strip(const PrivacySpec& spec)
-{
- if (DEBUG) ALOGD("Strip with spec %d", spec.dest);
+status_t PrivacyBuffer::strip(const PrivacySpec& spec) {
+ VLOG("Strip with spec %d", spec.dest);
// optimization when no strip happens
if (mPolicy == NULL || mPolicy->children == NULL || spec.RequireAll()) {
if (spec.CheckPremission(mPolicy)) mSize = mData.size();
return NO_ERROR;
}
while (mData.hasNext()) {
- status_t err = stripField(mPolicy, spec);
+ status_t err = stripField(mPolicy, spec, 0);
if (err != NO_ERROR) return err;
}
if (mData.bytesRead() != mData.size()) return BAD_VALUE;
mSize = mProto.size();
- mData.rp()->rewind(); // rewind the read pointer back to beginning after the strip.
+ mData.rp()->rewind(); // rewind the read pointer back to beginning after the strip.
return NO_ERROR;
}
-void
-PrivacyBuffer::clear()
-{
+void PrivacyBuffer::clear() {
mSize = 0;
mProto.clear();
}
-size_t
-PrivacyBuffer::size() const { return mSize; }
+size_t PrivacyBuffer::size() const { return mSize; }
-status_t
-PrivacyBuffer::flush(int fd)
-{
+status_t PrivacyBuffer::flush(int fd) {
status_t err = NO_ERROR;
EncodedBuffer::iterator iter = size() == mData.size() ? mData : mProto.data();
while (iter.readBuffer() != NULL) {
- err = write_all(fd, iter.readBuffer(), iter.currentToRead());
+ err = WriteFully(fd, iter.readBuffer(), iter.currentToRead()) ? NO_ERROR : -errno;
iter.rp()->move(iter.currentToRead());
if (err != NO_ERROR) return err;
}
diff --git a/cmds/incidentd/src/PrivacyBuffer.h b/cmds/incidentd/src/PrivacyBuffer.h
index c9ca9a7..92e1a25 100644
--- a/cmds/incidentd/src/PrivacyBuffer.h
+++ b/cmds/incidentd/src/PrivacyBuffer.h
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#pragma once
#ifndef PRIVACY_BUFFER_H
#define PRIVACY_BUFFER_H
@@ -31,14 +32,14 @@
* PrivacyBuffer holds the original protobuf data and strips PII-sensitive fields
* based on the request and holds stripped data in its own buffer for output.
*/
-class PrivacyBuffer
-{
+class PrivacyBuffer {
public:
PrivacyBuffer(const Privacy* policy, EncodedBuffer::iterator& data);
~PrivacyBuffer();
/**
- * Strip based on the request and hold data in its own buffer. Return NO_ERROR if strip succeeds.
+ * Strip based on the request and hold data in its own buffer. Return NO_ERROR if strip
+ * succeeds.
*/
status_t strip(const PrivacySpec& spec);
@@ -64,8 +65,8 @@
ProtoOutputStream mProto;
size_t mSize;
- status_t stripField(const Privacy* parentPolicy, const PrivacySpec& spec);
+ status_t stripField(const Privacy* parentPolicy, const PrivacySpec& spec, int depth);
void writeFieldOrSkip(uint32_t fieldTag, bool skip);
};
-#endif // PRIVACY_BUFFER_H
\ No newline at end of file
+#endif // PRIVACY_BUFFER_H
\ No newline at end of file
diff --git a/cmds/incidentd/src/Reporter.cpp b/cmds/incidentd/src/Reporter.cpp
index 06baeba..c0b5358 100644
--- a/cmds/incidentd/src/Reporter.cpp
+++ b/cmds/incidentd/src/Reporter.cpp
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#define LOG_TAG "incidentd"
+#include "Log.h"
#include "Reporter.h"
@@ -26,11 +25,11 @@
#include <private/android_filesystem_config.h>
#include <utils/SystemClock.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <dirent.h>
-#include <fcntl.h>
#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
/**
* The directory where the incident reports are stored.
@@ -39,62 +38,37 @@
// ================================================================================
ReportRequest::ReportRequest(const IncidentReportArgs& a,
- const sp<IIncidentReportStatusListener> &l, int f)
- :args(a),
- listener(l),
- fd(f),
- err(NO_ERROR)
-{
-}
+ const sp<IIncidentReportStatusListener>& l, int f)
+ : args(a), listener(l), fd(f), err(NO_ERROR) {}
-ReportRequest::~ReportRequest()
-{
+ReportRequest::~ReportRequest() {
if (fd >= 0) {
// clean up the opened file descriptor
close(fd);
}
}
-bool
-ReportRequest::ok()
-{
- return fd >= 0 && err == NO_ERROR;
-}
+bool ReportRequest::ok() { return fd >= 0 && err == NO_ERROR; }
// ================================================================================
ReportRequestSet::ReportRequestSet()
- :mRequests(),
- mSections(),
- mMainFd(-1),
- mMainDest(-1),
- mMetadata(),
- mSectionStats()
-{
-}
+ : mRequests(), mSections(), mMainFd(-1), mMainDest(-1), mMetadata(), mSectionStats() {}
-ReportRequestSet::~ReportRequestSet()
-{
-}
+ReportRequestSet::~ReportRequestSet() {}
// TODO: dedup on exact same args and fd, report the status back to listener!
-void
-ReportRequestSet::add(const sp<ReportRequest>& request)
-{
+void ReportRequestSet::add(const sp<ReportRequest>& request) {
mRequests.push_back(request);
mSections.merge(request->args);
mMetadata.set_request_size(mMetadata.request_size() + 1);
}
-void
-ReportRequestSet::setMainFd(int fd)
-{
+void ReportRequestSet::setMainFd(int fd) {
mMainFd = fd;
mMetadata.set_use_dropbox(fd > 0);
}
-void
-ReportRequestSet::setMainDest(int dest)
-{
+void ReportRequestSet::setMainDest(int dest) {
mMainDest = dest;
PrivacySpec spec = PrivacySpec::new_spec(dest);
switch (spec.dest) {
@@ -110,13 +84,9 @@
}
}
-bool
-ReportRequestSet::containsSection(int id) {
- return mSections.containsSection(id);
-}
+bool ReportRequestSet::containsSection(int id) { return mSections.containsSection(id); }
-IncidentMetadata::SectionStats*
-ReportRequestSet::sectionStats(int id) {
+IncidentMetadata::SectionStats* ReportRequestSet::sectionStats(int id) {
if (mSectionStats.find(id) == mSectionStats.end()) {
auto stats = mMetadata.add_sections();
stats->set_id(id);
@@ -128,9 +98,7 @@
// ================================================================================
Reporter::Reporter() : Reporter(INCIDENT_DIRECTORY) { isTest = false; };
-Reporter::Reporter(const char* directory)
- :batch()
-{
+Reporter::Reporter(const char* directory) : batch() {
char buf[100];
// TODO: Make the max size smaller for user builds.
@@ -148,13 +116,9 @@
mFilename = mIncidentDirectory + buf;
}
-Reporter::~Reporter()
-{
-}
+Reporter::~Reporter() {}
-Reporter::run_report_status_t
-Reporter::runReport()
-{
+Reporter::run_report_status_t Reporter::runReport() {
status_t err = NO_ERROR;
bool needMainFd = false;
int mainFd = -1;
@@ -163,7 +127,7 @@
MetadataSection metadataSection;
// See if we need the main file
- for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) {
+ for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
if ((*it)->fd < 0 && mainFd < 0) {
needMainFd = true;
mainDest = (*it)->args.dest();
@@ -194,7 +158,7 @@
}
// Tell everyone that we're starting.
- for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) {
+ for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
if ((*it)->listener != NULL) {
(*it)->listener->onReportStarted();
}
@@ -205,15 +169,14 @@
// For each of the report fields, see if we need it, and if so, execute the command
// and report to those that care that we're doing it.
- for (const Section** section=SECTION_LIST; *section; section++) {
+ for (const Section** section = SECTION_LIST; *section; section++) {
const int id = (*section)->id;
if (this->batch.containsSection(id)) {
ALOGD("Taking incident report section %d '%s'", id, (*section)->name.string());
- // Notify listener of starting.
- for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) {
+ for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
if ((*it)->listener != NULL && (*it)->args.containsSection(id)) {
- (*it)->listener->onReportSectionStatus(id,
- IIncidentReportStatusListener::STATUS_STARTING);
+ (*it)->listener->onReportSectionStatus(
+ id, IIncidentReportStatusListener::STATUS_STARTING);
}
}
@@ -227,15 +190,15 @@
stats->set_exec_duration_ms(endTime - startTime);
if (err != NO_ERROR) {
ALOGW("Incident section %s (%d) failed: %s. Stopping report.",
- (*section)->name.string(), id, strerror(-err));
+ (*section)->name.string(), id, strerror(-err));
goto DONE;
}
- // Notify listener of ending.
- for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) {
+ // Notify listener of starting
+ for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
if ((*it)->listener != NULL && (*it)->args.containsSection(id)) {
- (*it)->listener->onReportSectionStatus(id,
- IIncidentReportStatusListener::STATUS_FINISHED);
+ (*it)->listener->onReportSectionStatus(
+ id, IIncidentReportStatusListener::STATUS_FINISHED);
}
}
ALOGD("Finish incident report section %d '%s'", id, (*section)->name.string());
@@ -252,7 +215,7 @@
}
// Tell everyone that we're done.
- for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) {
+ for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
if ((*it)->listener != NULL) {
if (err == NO_ERROR) {
(*it)->listener->onReportFinished();
@@ -274,7 +237,7 @@
// If the status was ok, delete the file. If not, leave it around until the next
// boot or the next checkin. If the directory gets too big older files will
// be rotated out.
- if(!isTest) unlink(mFilename.c_str());
+ if (!isTest) unlink(mFilename.c_str());
}
return REPORT_FINISHED;
@@ -283,9 +246,7 @@
/**
* Create our output file and set the access permissions to -rw-rw----
*/
-status_t
-Reporter::create_file(int* fd)
-{
+status_t Reporter::create_file(int* fd) {
const char* filename = mFilename.c_str();
*fd = open(filename, O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC, 0660);
@@ -307,9 +268,7 @@
return NO_ERROR;
}
-Reporter::run_report_status_t
-Reporter::upload_backlog()
-{
+Reporter::run_report_status_t Reporter::upload_backlog() {
DIR* dir;
struct dirent* entry;
struct stat st;
@@ -360,4 +319,3 @@
return REPORT_FINISHED;
}
-
diff --git a/cmds/incidentd/src/Reporter.h b/cmds/incidentd/src/Reporter.h
index 6058068..0f3f221 100644
--- a/cmds/incidentd/src/Reporter.h
+++ b/cmds/incidentd/src/Reporter.h
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#pragma once
#ifndef REPORTER_H
#define REPORTER_H
@@ -33,23 +34,21 @@
using namespace std;
// ================================================================================
-struct ReportRequest : public virtual RefBase
-{
+struct ReportRequest : public virtual RefBase {
IncidentReportArgs args;
sp<IIncidentReportStatusListener> listener;
int fd;
status_t err;
- ReportRequest(const IncidentReportArgs& args,
- const sp<IIncidentReportStatusListener> &listener, int fd);
+ ReportRequest(const IncidentReportArgs& args, const sp<IIncidentReportStatusListener>& listener,
+ int fd);
virtual ~ReportRequest();
- bool ok(); // returns true if the request is ok for write.
+ bool ok(); // returns true if the request is ok for write.
};
// ================================================================================
-class ReportRequestSet
-{
+class ReportRequestSet {
public:
ReportRequestSet();
~ReportRequestSet();
@@ -81,18 +80,14 @@
};
// ================================================================================
-class Reporter : public virtual RefBase
-{
+class Reporter : public virtual RefBase {
public:
- enum run_report_status_t {
- REPORT_FINISHED = 0,
- REPORT_NEEDS_DROPBOX = 1
- };
+ enum run_report_status_t { REPORT_FINISHED = 0, REPORT_NEEDS_DROPBOX = 1 };
ReportRequestSet batch;
- Reporter(); // PROD must use this constructor.
- Reporter(const char* directory); // For testing purpose only.
+ Reporter(); // PROD must use this constructor.
+ Reporter(const char* directory); // For testing purpose only.
virtual ~Reporter();
// Run the report as described in the batch and args parameters.
@@ -110,8 +105,7 @@
status_t create_file(int* fd);
- bool isTest = true; // default to true for testing
+ bool isTest = true; // default to true for testing
};
-
-#endif // REPORTER_H
+#endif // REPORTER_H
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 3c76298..2e4e980 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#define LOG_TAG "incidentd"
+#include "Log.h"
#include "Section.h"
@@ -26,20 +25,21 @@
#include <memory>
#include <mutex>
+#include <android-base/file.h>
#include <android/util/protobuf.h>
#include <binder/IServiceManager.h>
#include <log/log_event_list.h>
-#include <log/logprint.h>
#include <log/log_read.h>
+#include <log/logprint.h>
#include <private/android_logger.h>
#include "FdBuffer.h"
-#include "frameworks/base/core/proto/android/util/log.proto.h"
-#include "io_util.h"
#include "Privacy.h"
#include "PrivacyBuffer.h"
-#include "section_list.h"
+#include "frameworks/base/core/proto/android/util/log.proto.h"
+#include "incidentd_util.h"
+using namespace android::base;
using namespace android::util;
using namespace std;
@@ -48,21 +48,18 @@
const int FIELD_ID_INCIDENT_METADATA = 2;
// incident section parameters
-const int WAIT_MAX = 5;
+const int WAIT_MAX = 5;
const struct timespec WAIT_INTERVAL_NS = {0, 200 * 1000 * 1000};
const char INCIDENT_HELPER[] = "/system/bin/incident_helper";
-static pid_t
-fork_execute_incident_helper(const int id, const char* name, Fpipe& p2cPipe, Fpipe& c2pPipe)
-{
- const char* ihArgs[] { INCIDENT_HELPER, "-s", String8::format("%d", id).string(), NULL };
+static pid_t fork_execute_incident_helper(const int id, const char* name, Fpipe& p2cPipe,
+ Fpipe& c2pPipe) {
+ const char* ihArgs[]{INCIDENT_HELPER, "-s", String8::format("%d", id).string(), NULL};
// fork used in multithreaded environment, avoid adding unnecessary code in child process
pid_t pid = fork();
if (pid == 0) {
- if (TEMP_FAILURE_RETRY(dup2(p2cPipe.readFd(), STDIN_FILENO)) != 0
- || !p2cPipe.close()
- || TEMP_FAILURE_RETRY(dup2(c2pPipe.writeFd(), STDOUT_FILENO)) != 1
- || !c2pPipe.close()) {
+ if (TEMP_FAILURE_RETRY(dup2(p2cPipe.readFd(), STDIN_FILENO)) != 0 || !p2cPipe.close() ||
+ TEMP_FAILURE_RETRY(dup2(c2pPipe.writeFd(), STDOUT_FILENO)) != 1 || !c2pPipe.close()) {
ALOGW("%s can't setup stdin and stdout for incident helper", name);
_exit(EXIT_FAILURE);
}
@@ -73,7 +70,7 @@
execv(INCIDENT_HELPER, const_cast<char**>(ihArgs));
ALOGW("%s failed in incident helper process: %s", name, strerror(errno));
- _exit(EXIT_FAILURE); // always exits with failure if any
+ _exit(EXIT_FAILURE); // always exits with failure if any
}
// close the fds used in incident helper
close(p2cPipe.readFd());
@@ -84,18 +81,18 @@
// ================================================================================
static status_t statusCode(int status) {
if (WIFSIGNALED(status)) {
- ALOGD("return by signal: %s", strerror(WTERMSIG(status)));
- return -WTERMSIG(status);
+ VLOG("return by signal: %s", strerror(WTERMSIG(status)));
+ return -WTERMSIG(status);
} else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
- ALOGD("return by exit: %s", strerror(WEXITSTATUS(status)));
- return -WEXITSTATUS(status);
+ VLOG("return by exit: %s", strerror(WEXITSTATUS(status)));
+ return -WEXITSTATUS(status);
}
return NO_ERROR;
}
static status_t kill_child(pid_t pid) {
int status;
- ALOGD("try to kill child process %d", pid);
+ VLOG("try to kill child process %d", pid);
kill(pid, SIGKILL);
if (waitpid(pid, &status, 0) == -1) return -1;
return statusCode(status);
@@ -105,7 +102,7 @@
int status;
bool died = false;
// wait for child to report status up to 1 seconds
- for(int loop = 0; !died && loop < WAIT_MAX; loop++) {
+ for (int loop = 0; !died && loop < WAIT_MAX; loop++) {
if (waitpid(pid, &status, WNOHANG) == pid) died = true;
// sleep for 0.2 second
nanosleep(&WAIT_INTERVAL_NS, NULL);
@@ -114,38 +111,14 @@
return statusCode(status);
}
// ================================================================================
-static const Privacy*
-get_privacy_of_section(int id)
-{
- int l = 0;
- int r = PRIVACY_POLICY_COUNT - 1;
- while (l <= r) {
- int mid = (l + r) >> 1;
- const Privacy* p = PRIVACY_POLICY_LIST[mid];
-
- if (p->field_id < (uint32_t)id) {
- l = mid + 1;
- } else if (p->field_id > (uint32_t)id) {
- r = mid - 1;
- } else {
- return p;
- }
- }
- return NULL;
-}
-
-// ================================================================================
-static status_t
-write_section_header(int fd, int sectionId, size_t size)
-{
+static status_t write_section_header(int fd, int sectionId, size_t size) {
uint8_t buf[20];
- uint8_t *p = write_length_delimited_tag_header(buf, sectionId, size);
- return write_all(fd, buf, p-buf);
+ uint8_t* p = write_length_delimited_tag_header(buf, sectionId, size);
+ return WriteFully(fd, buf, p - buf) ? NO_ERROR : -errno;
}
-static status_t
-write_report_requests(const int id, const FdBuffer& buffer, ReportRequestSet* requests)
-{
+static status_t write_report_requests(const int id, const FdBuffer& buffer,
+ ReportRequestSet* requests) {
status_t err = -EBADF;
EncodedBuffer::iterator data = buffer.data();
PrivacyBuffer privacyBuffer(get_privacy_of_section(id), data);
@@ -171,18 +144,24 @@
for (auto mit = requestsBySpec.begin(); mit != requestsBySpec.end(); mit++) {
PrivacySpec spec = mit->first;
err = privacyBuffer.strip(spec);
- if (err != NO_ERROR) return err; // it means the privacyBuffer data is corrupted.
+ if (err != NO_ERROR) return err; // it means the privacyBuffer data is corrupted.
if (privacyBuffer.size() == 0) continue;
for (auto it = mit->second.begin(); it != mit->second.end(); it++) {
sp<ReportRequest> request = *it;
err = write_section_header(request->fd, id, privacyBuffer.size());
- if (err != NO_ERROR) { request->err = err; continue; }
+ if (err != NO_ERROR) {
+ request->err = err;
+ continue;
+ }
err = privacyBuffer.flush(request->fd);
- if (err != NO_ERROR) { request->err = err; continue; }
+ if (err != NO_ERROR) {
+ request->err = err;
+ continue;
+ }
writeable++;
- ALOGD("Section %d flushed %zu bytes to fd %d with spec %d", id,
- privacyBuffer.size(), request->fd, spec.dest);
+ VLOG("Section %d flushed %zu bytes to fd %d with spec %d", id, privacyBuffer.size(),
+ request->fd, spec.dest);
}
privacyBuffer.clear();
}
@@ -191,16 +170,22 @@
if (requests->mainFd() >= 0) {
PrivacySpec spec = PrivacySpec::new_spec(requests->mainDest());
err = privacyBuffer.strip(spec);
- if (err != NO_ERROR) return err; // the buffer data is corrupted.
+ if (err != NO_ERROR) return err; // the buffer data is corrupted.
if (privacyBuffer.size() == 0) goto DONE;
err = write_section_header(requests->mainFd(), id, privacyBuffer.size());
- if (err != NO_ERROR) { requests->setMainFd(-1); goto DONE; }
+ if (err != NO_ERROR) {
+ requests->setMainFd(-1);
+ goto DONE;
+ }
err = privacyBuffer.flush(requests->mainFd());
- if (err != NO_ERROR) { requests->setMainFd(-1); goto DONE; }
+ if (err != NO_ERROR) {
+ requests->setMainFd(-1);
+ goto DONE;
+ }
writeable++;
- ALOGD("Section %d flushed %zu bytes to dropbox %d with spec %d", id,
- privacyBuffer.size(), requests->mainFd(), spec.dest);
+ VLOG("Section %d flushed %zu bytes to dropbox %d with spec %d", id, privacyBuffer.size(),
+ requests->mainFd(), spec.dest);
stats->set_report_size_bytes(privacyBuffer.size());
}
@@ -210,40 +195,28 @@
}
// ================================================================================
-Section::Section(int i, const int64_t timeoutMs)
- :id(i),
- timeoutMs(timeoutMs)
-{
-}
+Section::Section(int i, const int64_t timeoutMs) : id(i), timeoutMs(timeoutMs) {}
-Section::~Section()
-{
-}
+Section::~Section() {}
// ================================================================================
-HeaderSection::HeaderSection()
- :Section(FIELD_ID_INCIDENT_HEADER, 0)
-{
-}
+HeaderSection::HeaderSection() : Section(FIELD_ID_INCIDENT_HEADER, 0) {}
-HeaderSection::~HeaderSection()
-{
-}
+HeaderSection::~HeaderSection() {}
-status_t
-HeaderSection::Execute(ReportRequestSet* requests) const
-{
- for (ReportRequestSet::iterator it=requests->begin(); it!=requests->end(); it++) {
+status_t HeaderSection::Execute(ReportRequestSet* requests) const {
+ for (ReportRequestSet::iterator it = requests->begin(); it != requests->end(); it++) {
const sp<ReportRequest> request = *it;
const vector<vector<uint8_t>>& headers = request->args.headers();
- for (vector<vector<uint8_t>>::const_iterator buf=headers.begin(); buf!=headers.end(); buf++) {
+ for (vector<vector<uint8_t>>::const_iterator buf = headers.begin(); buf != headers.end();
+ buf++) {
if (buf->empty()) continue;
// So the idea is only requests with negative fd are written to dropbox file.
int fd = request->fd >= 0 ? request->fd : requests->mainFd();
write_section_header(fd, id, buf->size());
- write_all(fd, (uint8_t const*)buf->data(), buf->size());
+ WriteFully(fd, (uint8_t const*)buf->data(), buf->size());
// If there was an error now, there will be an error later and we will remove
// it from the list then.
}
@@ -251,54 +224,49 @@
return NO_ERROR;
}
// ================================================================================
-MetadataSection::MetadataSection()
- :Section(FIELD_ID_INCIDENT_METADATA, 0)
-{
-}
+MetadataSection::MetadataSection() : Section(FIELD_ID_INCIDENT_METADATA, 0) {}
-MetadataSection::~MetadataSection()
-{
-}
+MetadataSection::~MetadataSection() {}
-status_t
-MetadataSection::Execute(ReportRequestSet* requests) const
-{
+status_t MetadataSection::Execute(ReportRequestSet* requests) const {
std::string metadataBuf;
requests->metadata().SerializeToString(&metadataBuf);
- for (ReportRequestSet::iterator it=requests->begin(); it!=requests->end(); it++) {
+ for (ReportRequestSet::iterator it = requests->begin(); it != requests->end(); it++) {
const sp<ReportRequest> request = *it;
if (metadataBuf.empty() || request->fd < 0 || request->err != NO_ERROR) {
continue;
}
write_section_header(request->fd, id, metadataBuf.size());
- write_all(request->fd, (uint8_t const*)metadataBuf.data(), metadataBuf.size());
+ if (!WriteFully(request->fd, (uint8_t const*)metadataBuf.data(), metadataBuf.size())) {
+ ALOGW("Failed to write metadata to fd %d", request->fd);
+ // we don't fail if we can't write to a single request's fd.
+ }
}
if (requests->mainFd() >= 0 && !metadataBuf.empty()) {
write_section_header(requests->mainFd(), id, metadataBuf.size());
- write_all(requests->mainFd(), (uint8_t const*)metadataBuf.data(), metadataBuf.size());
+ if (!WriteFully(requests->mainFd(), (uint8_t const*)metadataBuf.data(), metadataBuf.size())) {
+ ALOGW("Failed to write metadata to dropbox fd %d", requests->mainFd());
+ return -1;
+ }
}
return NO_ERROR;
}
// ================================================================================
FileSection::FileSection(int id, const char* filename, const int64_t timeoutMs)
- :Section(id, timeoutMs),
- mFilename(filename)
-{
+ : Section(id, timeoutMs), mFilename(filename) {
name = filename;
mIsSysfs = strncmp(filename, "/sys/", 5) == 0;
}
FileSection::~FileSection() {}
-status_t
-FileSection::Execute(ReportRequestSet* requests) const
-{
+status_t FileSection::Execute(ReportRequestSet* requests) const {
// read from mFilename first, make sure the file is available
// add O_CLOEXEC to make sure it is closed when exec incident helper
int fd = open(mFilename, O_RDONLY | O_CLOEXEC);
if (fd == -1) {
- ALOGW("FileSection '%s' failed to open file", this->name.string());
- return -errno;
+ ALOGW("FileSection '%s' failed to open file", this->name.string());
+ return -errno;
}
FdBuffer buffer;
@@ -318,22 +286,23 @@
// parent process
status_t readStatus = buffer.readProcessedDataInStream(fd, p2cPipe.writeFd(), c2pPipe.readFd(),
- this->timeoutMs, mIsSysfs);
+ this->timeoutMs, mIsSysfs);
if (readStatus != NO_ERROR || buffer.timedOut()) {
ALOGW("FileSection '%s' failed to read data from incident helper: %s, timedout: %s",
- this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
+ this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
kill_child(pid);
return readStatus;
}
status_t ihStatus = wait_child(pid);
if (ihStatus != NO_ERROR) {
- ALOGW("FileSection '%s' abnormal child process: %s", this->name.string(), strerror(-ihStatus));
+ ALOGW("FileSection '%s' abnormal child process: %s", this->name.string(),
+ strerror(-ihStatus));
return ihStatus;
}
- ALOGD("FileSection '%s' wrote %zd bytes in %d ms", this->name.string(), buffer.size(),
- (int)buffer.durationMs());
+ VLOG("FileSection '%s' wrote %zd bytes in %d ms", this->name.string(), buffer.size(),
+ (int)buffer.durationMs());
status_t err = write_report_requests(this->id, buffer, requests);
if (err != NO_ERROR) {
ALOGW("FileSection '%s' failed writing: %s", this->name.string(), strerror(-err));
@@ -344,8 +313,7 @@
}
// ================================================================================
-struct WorkerThreadData : public virtual RefBase
-{
+struct WorkerThreadData : public virtual RefBase {
const WorkerThreadSection* section;
int fds[2];
@@ -362,31 +330,19 @@
};
WorkerThreadData::WorkerThreadData(const WorkerThreadSection* sec)
- :section(sec),
- workerDone(false),
- workerError(NO_ERROR)
-{
+ : section(sec), workerDone(false), workerError(NO_ERROR) {
fds[0] = -1;
fds[1] = -1;
}
-WorkerThreadData::~WorkerThreadData()
-{
-}
+WorkerThreadData::~WorkerThreadData() {}
// ================================================================================
-WorkerThreadSection::WorkerThreadSection(int id)
- :Section(id)
-{
-}
+WorkerThreadSection::WorkerThreadSection(int id) : Section(id) {}
-WorkerThreadSection::~WorkerThreadSection()
-{
-}
+WorkerThreadSection::~WorkerThreadSection() {}
-static void*
-worker_thread_func(void* cookie)
-{
+static void* worker_thread_func(void* cookie) {
WorkerThreadData* data = (WorkerThreadData*)cookie;
status_t err = data->section->BlockingCall(data->writeFd());
@@ -402,9 +358,7 @@
return NULL;
}
-status_t
-WorkerThreadSection::Execute(ReportRequestSet* requests) const
-{
+status_t WorkerThreadSection::Execute(ReportRequestSet* requests) const {
status_t err = NO_ERROR;
pthread_t thread;
pthread_attr_t attr;
@@ -447,7 +401,7 @@
if (err != NO_ERROR) {
// TODO: Log this error into the incident report.
ALOGW("WorkerThreadSection '%s' reader failed with error '%s'", this->name.string(),
- strerror(-err));
+ strerror(-err));
}
// Done with the read fd. The worker thread closes the write one so
@@ -466,7 +420,7 @@
err = data->workerError;
// TODO: Log this error into the incident report.
ALOGW("WorkerThreadSection '%s' worker failed with error '%s'", this->name.string(),
- strerror(-err));
+ strerror(-err));
}
}
}
@@ -484,13 +438,13 @@
// just exit with a log messasge.
if (err != NO_ERROR) {
ALOGW("WorkerThreadSection '%s' failed with error '%s'", this->name.string(),
- strerror(-err));
+ strerror(-err));
return NO_ERROR;
}
// Write the data that was collected
- ALOGD("WorkerThreadSection '%s' wrote %zd bytes in %d ms", name.string(), buffer.size(),
- (int)buffer.durationMs());
+ VLOG("WorkerThreadSection '%s' wrote %zd bytes in %d ms", name.string(), buffer.size(),
+ (int)buffer.durationMs());
err = write_report_requests(this->id, buffer, requests);
if (err != NO_ERROR) {
ALOGW("WorkerThreadSection '%s' failed writing: '%s'", this->name.string(), strerror(-err));
@@ -501,14 +455,12 @@
}
// ================================================================================
-void
-CommandSection::init(const char* command, va_list args)
-{
+void CommandSection::init(const char* command, va_list args) {
va_list copied_args;
int numOfArgs = 0;
va_copy(copied_args, args);
- while(va_arg(copied_args, const char*) != NULL) {
+ while (va_arg(copied_args, const char*) != NULL) {
numOfArgs++;
}
va_end(copied_args);
@@ -518,41 +470,33 @@
mCommand[0] = command;
name = command;
- for (int i=0; i<numOfArgs; i++) {
+ for (int i = 0; i < numOfArgs; i++) {
const char* arg = va_arg(args, const char*);
- mCommand[i+1] = arg;
+ mCommand[i + 1] = arg;
name += " ";
name += arg;
}
- mCommand[numOfArgs+1] = NULL;
+ mCommand[numOfArgs + 1] = NULL;
}
CommandSection::CommandSection(int id, const int64_t timeoutMs, const char* command, ...)
- :Section(id, timeoutMs)
-{
+ : Section(id, timeoutMs) {
va_list args;
va_start(args, command);
init(command, args);
va_end(args);
}
-CommandSection::CommandSection(int id, const char* command, ...)
- :Section(id)
-{
+CommandSection::CommandSection(int id, const char* command, ...) : Section(id) {
va_list args;
va_start(args, command);
init(command, args);
va_end(args);
}
-CommandSection::~CommandSection()
-{
- free(mCommand);
-}
+CommandSection::~CommandSection() { free(mCommand); }
-status_t
-CommandSection::Execute(ReportRequestSet* requests) const
-{
+status_t CommandSection::Execute(ReportRequestSet* requests) const {
FdBuffer buffer;
Fpipe cmdPipe;
Fpipe ihPipe;
@@ -571,13 +515,15 @@
if (cmdPid == 0) {
// replace command's stdout with ihPipe's write Fd
if (dup2(cmdPipe.writeFd(), STDOUT_FILENO) != 1 || !ihPipe.close() || !cmdPipe.close()) {
- ALOGW("CommandSection '%s' failed to set up stdout: %s", this->name.string(), strerror(errno));
+ ALOGW("CommandSection '%s' failed to set up stdout: %s", this->name.string(),
+ strerror(errno));
_exit(EXIT_FAILURE);
}
- execvp(this->mCommand[0], (char *const *) this->mCommand);
- int err = errno; // record command error code
- ALOGW("CommandSection '%s' failed in executing command: %s", this->name.string(), strerror(errno));
- _exit(err); // exit with command error code
+ execvp(this->mCommand[0], (char* const*)this->mCommand);
+ int err = errno; // record command error code
+ ALOGW("CommandSection '%s' failed in executing command: %s", this->name.string(),
+ strerror(errno));
+ _exit(err); // exit with command error code
}
pid_t ihPid = fork_execute_incident_helper(this->id, this->name.string(), cmdPipe, ihPipe);
if (ihPid == -1) {
@@ -589,24 +535,26 @@
status_t readStatus = buffer.read(ihPipe.readFd(), this->timeoutMs);
if (readStatus != NO_ERROR || buffer.timedOut()) {
ALOGW("CommandSection '%s' failed to read data from incident helper: %s, timedout: %s",
- this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
+ this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
kill_child(cmdPid);
kill_child(ihPid);
return readStatus;
}
- // TODO: wait for command here has one trade-off: the failed status of command won't be detected until
+ // TODO: wait for command here has one trade-off: the failed status of command won't be detected
+ // until
// buffer timeout, but it has advatage on starting the data stream earlier.
status_t cmdStatus = wait_child(cmdPid);
- status_t ihStatus = wait_child(ihPid);
+ status_t ihStatus = wait_child(ihPid);
if (cmdStatus != NO_ERROR || ihStatus != NO_ERROR) {
- ALOGW("CommandSection '%s' abnormal child processes, return status: command: %s, incident helper: %s",
- this->name.string(), strerror(-cmdStatus), strerror(-ihStatus));
+ ALOGW("CommandSection '%s' abnormal child processes, return status: command: %s, incident "
+ "helper: %s",
+ this->name.string(), strerror(-cmdStatus), strerror(-ihStatus));
return cmdStatus != NO_ERROR ? cmdStatus : ihStatus;
}
- ALOGD("CommandSection '%s' wrote %zd bytes in %d ms", this->name.string(), buffer.size(),
- (int)buffer.durationMs());
+ VLOG("CommandSection '%s' wrote %zd bytes in %d ms", this->name.string(), buffer.size(),
+ (int)buffer.durationMs());
status_t err = write_report_requests(this->id, buffer, requests);
if (err != NO_ERROR) {
ALOGW("CommandSection '%s' failed writing: %s", this->name.string(), strerror(-err));
@@ -617,9 +565,7 @@
// ================================================================================
DumpsysSection::DumpsysSection(int id, const char* service, ...)
- :WorkerThreadSection(id),
- mService(service)
-{
+ : WorkerThreadSection(id), mService(service) {
name = "dumpsys ";
name += service;
@@ -637,13 +583,9 @@
va_end(args);
}
-DumpsysSection::~DumpsysSection()
-{
-}
+DumpsysSection::~DumpsysSection() {}
-status_t
-DumpsysSection::BlockingCall(int pipeWriteFd) const
-{
+status_t DumpsysSection::BlockingCall(int pipeWriteFd) const {
// checkService won't wait for the service to show up like getService will.
sp<IBinder> service = defaultServiceManager()->checkService(mService);
@@ -667,30 +609,23 @@
// initialization only once in Section.cpp.
map<log_id_t, log_time> LogSection::gLastLogsRetrieved;
-LogSection::LogSection(int id, log_id_t logID)
- :WorkerThreadSection(id),
- mLogID(logID)
-{
+LogSection::LogSection(int id, log_id_t logID) : WorkerThreadSection(id), mLogID(logID) {
name += "logcat ";
name += android_log_id_to_name(logID);
switch (logID) {
- case LOG_ID_EVENTS:
- case LOG_ID_STATS:
- case LOG_ID_SECURITY:
- mBinary = true;
- break;
- default:
- mBinary = false;
+ case LOG_ID_EVENTS:
+ case LOG_ID_STATS:
+ case LOG_ID_SECURITY:
+ mBinary = true;
+ break;
+ default:
+ mBinary = false;
}
}
-LogSection::~LogSection()
-{
-}
+LogSection::~LogSection() {}
-static size_t
-trimTail(char const* buf, size_t len)
-{
+static size_t trimTail(char const* buf, size_t len) {
while (len > 0) {
char c = buf[len - 1];
if (c == '\0' || c == ' ' || c == '\n' || c == '\r' || c == ':') {
@@ -706,17 +641,15 @@
return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
}
-status_t
-LogSection::BlockingCall(int pipeWriteFd) const
-{
+status_t LogSection::BlockingCall(int pipeWriteFd) const {
status_t err = NO_ERROR;
// Open log buffer and getting logs since last retrieved time if any.
unique_ptr<logger_list, void (*)(logger_list*)> loggers(
- gLastLogsRetrieved.find(mLogID) == gLastLogsRetrieved.end() ?
- android_logger_list_alloc(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, 0) :
- android_logger_list_alloc_time(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
- gLastLogsRetrieved[mLogID], 0),
- android_logger_list_free);
+ gLastLogsRetrieved.find(mLogID) == gLastLogsRetrieved.end()
+ ? android_logger_list_alloc(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, 0)
+ : android_logger_list_alloc_time(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
+ gLastLogsRetrieved[mLogID], 0),
+ android_logger_list_free);
if (android_logger_open(loggers.get(), mLogID) == NULL) {
ALOGW("LogSection %s: Can't get logger.", this->name.string());
@@ -727,7 +660,7 @@
log_time lastTimestamp(0);
ProtoOutputStream proto;
- while (true) { // keeps reading until logd buffer is fully read.
+ while (true) { // keeps reading until logd buffer is fully read.
status_t err = android_logger_list_read(loggers.get(), &msg);
// err = 0 - no content, unexpected connection drop or EOF.
// err = +ive number - size of retrieved data from logger
@@ -742,7 +675,8 @@
if (mBinary) {
// remove the first uint32 which is tag's index in event log tags
android_log_context context = create_android_log_parser(msg.msg() + sizeof(uint32_t),
- msg.len() - sizeof(uint32_t));;
+ msg.len() - sizeof(uint32_t));
+ ;
android_log_list_element elem;
lastTimestamp.tv_sec = msg.entry_v1.sec;
@@ -752,38 +686,46 @@
long long token = proto.start(LogProto::BINARY_LOGS);
proto.write(BinaryLogEntry::SEC, msg.entry_v1.sec);
proto.write(BinaryLogEntry::NANOSEC, msg.entry_v1.nsec);
- proto.write(BinaryLogEntry::UID, (int) msg.entry_v4.uid);
+ proto.write(BinaryLogEntry::UID, (int)msg.entry_v4.uid);
proto.write(BinaryLogEntry::PID, msg.entry_v1.pid);
proto.write(BinaryLogEntry::TID, msg.entry_v1.tid);
- proto.write(BinaryLogEntry::TAG_INDEX, get4LE(reinterpret_cast<uint8_t const*>(msg.msg())));
+ proto.write(BinaryLogEntry::TAG_INDEX,
+ get4LE(reinterpret_cast<uint8_t const*>(msg.msg())));
do {
elem = android_log_read_next(context);
long long elemToken = proto.start(BinaryLogEntry::ELEMS);
switch (elem.type) {
case EVENT_TYPE_INT:
- proto.write(BinaryLogEntry::Elem::TYPE, BinaryLogEntry::Elem::EVENT_TYPE_INT);
- proto.write(BinaryLogEntry::Elem::VAL_INT32, (int) elem.data.int32);
+ proto.write(BinaryLogEntry::Elem::TYPE,
+ BinaryLogEntry::Elem::EVENT_TYPE_INT);
+ proto.write(BinaryLogEntry::Elem::VAL_INT32, (int)elem.data.int32);
break;
case EVENT_TYPE_LONG:
- proto.write(BinaryLogEntry::Elem::TYPE, BinaryLogEntry::Elem::EVENT_TYPE_LONG);
- proto.write(BinaryLogEntry::Elem::VAL_INT64, (long long) elem.data.int64);
+ proto.write(BinaryLogEntry::Elem::TYPE,
+ BinaryLogEntry::Elem::EVENT_TYPE_LONG);
+ proto.write(BinaryLogEntry::Elem::VAL_INT64, (long long)elem.data.int64);
break;
case EVENT_TYPE_STRING:
- proto.write(BinaryLogEntry::Elem::TYPE, BinaryLogEntry::Elem::EVENT_TYPE_STRING);
+ proto.write(BinaryLogEntry::Elem::TYPE,
+ BinaryLogEntry::Elem::EVENT_TYPE_STRING);
proto.write(BinaryLogEntry::Elem::VAL_STRING, elem.data.string, elem.len);
break;
case EVENT_TYPE_FLOAT:
- proto.write(BinaryLogEntry::Elem::TYPE, BinaryLogEntry::Elem::EVENT_TYPE_FLOAT);
+ proto.write(BinaryLogEntry::Elem::TYPE,
+ BinaryLogEntry::Elem::EVENT_TYPE_FLOAT);
proto.write(BinaryLogEntry::Elem::VAL_FLOAT, elem.data.float32);
break;
case EVENT_TYPE_LIST:
- proto.write(BinaryLogEntry::Elem::TYPE, BinaryLogEntry::Elem::EVENT_TYPE_LIST);
+ proto.write(BinaryLogEntry::Elem::TYPE,
+ BinaryLogEntry::Elem::EVENT_TYPE_LIST);
break;
case EVENT_TYPE_LIST_STOP:
- proto.write(BinaryLogEntry::Elem::TYPE, BinaryLogEntry::Elem::EVENT_TYPE_LIST_STOP);
+ proto.write(BinaryLogEntry::Elem::TYPE,
+ BinaryLogEntry::Elem::EVENT_TYPE_LIST_STOP);
break;
case EVENT_TYPE_UNKNOWN:
- proto.write(BinaryLogEntry::Elem::TYPE, BinaryLogEntry::Elem::EVENT_TYPE_UNKNOWN);
+ proto.write(BinaryLogEntry::Elem::TYPE,
+ BinaryLogEntry::Elem::EVENT_TYPE_UNKNOWN);
break;
}
proto.end(elemToken);
@@ -811,7 +753,8 @@
proto.write(TextLogEntry::PID, entry.pid);
proto.write(TextLogEntry::TID, entry.tid);
proto.write(TextLogEntry::TAG, entry.tag, trimTail(entry.tag, entry.tagLen));
- proto.write(TextLogEntry::LOG, entry.message, trimTail(entry.message, entry.messageLen));
+ proto.write(TextLogEntry::LOG, entry.message,
+ trimTail(entry.message, entry.messageLen));
proto.end(token);
}
}
diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h
index 80cc033..d644681 100644
--- a/cmds/incidentd/src/Section.h
+++ b/cmds/incidentd/src/Section.h
@@ -13,31 +13,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#pragma once
#ifndef SECTIONS_H
#define SECTIONS_H
#include "Reporter.h"
-#include <map>
#include <stdarg.h>
+#include <map>
-#include <utils/String8.h>
#include <utils/String16.h>
+#include <utils/String8.h>
#include <utils/Vector.h>
using namespace android;
-const int64_t REMOTE_CALL_TIMEOUT_MS = 10 * 1000; // 10 seconds
+const int64_t REMOTE_CALL_TIMEOUT_MS = 10 * 1000; // 10 seconds
/**
* Base class for sections
*/
-class Section
-{
+class Section {
public:
const int id;
- const int64_t timeoutMs; // each section must have a timeout
+ const int64_t timeoutMs; // each section must have a timeout
String8 name;
Section(int id, const int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS);
@@ -49,8 +49,7 @@
/**
* Section that generates incident headers.
*/
-class HeaderSection : public Section
-{
+class HeaderSection : public Section {
public:
HeaderSection();
virtual ~HeaderSection();
@@ -61,8 +60,7 @@
/**
* Section that generates incident metadata.
*/
-class MetadataSection : public Section
-{
+class MetadataSection : public Section {
public:
MetadataSection();
virtual ~MetadataSection();
@@ -73,8 +71,7 @@
/**
* Section that reads in a file.
*/
-class FileSection : public Section
-{
+class FileSection : public Section {
public:
FileSection(int id, const char* filename, const int64_t timeoutMs = 5000 /* 5 seconds */);
virtual ~FileSection();
@@ -83,14 +80,13 @@
private:
const char* mFilename;
- bool mIsSysfs; // sysfs files are pollable but return POLLERR by default, handle it separately
+ bool mIsSysfs; // sysfs files are pollable but return POLLERR by default, handle it separately
};
/**
* Base class for sections that call a command that might need a timeout.
*/
-class WorkerThreadSection : public Section
-{
+class WorkerThreadSection : public Section {
public:
WorkerThreadSection(int id);
virtual ~WorkerThreadSection();
@@ -103,8 +99,7 @@
/**
* Section that forks and execs a command, and puts stdout as the section.
*/
-class CommandSection : public Section
-{
+class CommandSection : public Section {
public:
CommandSection(int id, const int64_t timeoutMs, const char* command, ...);
@@ -123,8 +118,7 @@
/**
* Section that calls dumpsys on a system service.
*/
-class DumpsysSection : public WorkerThreadSection
-{
+class DumpsysSection : public WorkerThreadSection {
public:
DumpsysSection(int id, const char* service, ...);
virtual ~DumpsysSection();
@@ -139,8 +133,7 @@
/**
* Section that reads from logd.
*/
-class LogSection : public WorkerThreadSection
-{
+class LogSection : public WorkerThreadSection {
// global last log retrieved timestamp for each log_id_t.
static map<log_id_t, log_time> gLastLogsRetrieved;
@@ -155,5 +148,4 @@
bool mBinary;
};
-#endif // SECTIONS_H
-
+#endif // SECTIONS_H
diff --git a/cmds/incidentd/src/incidentd_util.cpp b/cmds/incidentd/src/incidentd_util.cpp
new file mode 100644
index 0000000..2415860
--- /dev/null
+++ b/cmds/incidentd/src/incidentd_util.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 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 "incidentd_util.h"
+
+#include "section_list.h"
+
+const Privacy* get_privacy_of_section(int id) {
+ int l = 0;
+ int r = PRIVACY_POLICY_COUNT - 1;
+ while (l <= r) {
+ int mid = (l + r) >> 1;
+ const Privacy* p = PRIVACY_POLICY_LIST[mid];
+
+ if (p->field_id < (uint32_t)id) {
+ l = mid + 1;
+ } else if (p->field_id > (uint32_t)id) {
+ r = mid - 1;
+ } else {
+ return p;
+ }
+ }
+ return NULL;
+}
+
+// ================================================================================
+Fpipe::Fpipe() : mRead(), mWrite() {}
+
+Fpipe::~Fpipe() { close(); }
+
+bool Fpipe::close() {
+ mRead.reset();
+ mWrite.reset();
+ return true;
+}
+
+bool Fpipe::init() { return Pipe(&mRead, &mWrite); }
+
+int Fpipe::readFd() const { return mRead.get(); }
+
+int Fpipe::writeFd() const { return mWrite.get(); }
\ No newline at end of file
diff --git a/cmds/incidentd/src/io_util.h b/cmds/incidentd/src/incidentd_util.h
similarity index 74%
rename from cmds/incidentd/src/io_util.h
rename to cmds/incidentd/src/incidentd_util.h
index 320dd6c..09aa040 100644
--- a/cmds/incidentd/src/io_util.h
+++ b/cmds/incidentd/src/incidentd_util.h
@@ -13,16 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#pragma once
-#ifndef IO_UTIL_H
-#define IO_UTIL_H
+#ifndef INCIDENTD_UTIL_H
+#define INCIDENTD_UTIL_H
-#include <stdint.h>
-#include <utils/Errors.h>
+#include <android-base/unique_fd.h>
-using namespace android;
+#include "Privacy.h"
-status_t write_all(int fd, uint8_t const* buf, size_t size);
+using namespace android::base;
+
+const Privacy* get_privacy_of_section(int id);
class Fpipe {
public:
@@ -35,7 +37,8 @@
int writeFd() const;
private:
- int mFds[2];
+ unique_fd mRead;
+ unique_fd mWrite;
};
-#endif // IO_UTIL_H
\ No newline at end of file
+#endif // INCIDENTD_UTIL_H
\ No newline at end of file
diff --git a/cmds/incidentd/src/io_util.cpp b/cmds/incidentd/src/io_util.cpp
deleted file mode 100644
index 90f543e..0000000
--- a/cmds/incidentd/src/io_util.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 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 "incidentd"
-
-#include "io_util.h"
-
-#include <unistd.h>
-
-status_t write_all(int fd, uint8_t const* buf, size_t size)
-{
- while (size > 0) {
- ssize_t amt = TEMP_FAILURE_RETRY(::write(fd, buf, size));
- if (amt < 0) {
- return -errno;
- }
- size -= amt;
- buf += amt;
- }
- return NO_ERROR;
-}
-
-Fpipe::Fpipe() {}
-
-Fpipe::~Fpipe() { close(); }
-
-bool Fpipe::close() { return !(::close(mFds[0]) || ::close(mFds[1])); }
-
-bool Fpipe::init() { return pipe(mFds) != -1; }
-
-int Fpipe::readFd() const { return mFds[0]; }
-
-int Fpipe::writeFd() const { return mFds[1]; }
diff --git a/cmds/incidentd/src/main.cpp b/cmds/incidentd/src/main.cpp
index 3a7511d..38b7449 100644
--- a/cmds/incidentd/src/main.cpp
+++ b/cmds/incidentd/src/main.cpp
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#define LOG_TAG "incidentd"
+#include "Log.h"
#include "IncidentService.h"
@@ -23,25 +22,22 @@
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/Status.h>
-#include <cutils/log.h>
#include <utils/Looper.h>
#include <utils/StrongPointer.h>
-#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/types.h>
using namespace android;
// ================================================================================
-int
-main(int /*argc*/, char** /*argv*/)
-{
+int main(int /*argc*/, char** /*argv*/) {
// Set up the looper
sp<Looper> looper(Looper::prepare(0 /* opts */));
// Set up the binder
sp<ProcessState> ps(ProcessState::self());
- ps->setThreadPoolMaxThreadCount(1); // everything is oneway, let it queue and save ram
+ ps->setThreadPoolMaxThreadCount(1); // everything is oneway, let it queue and save ram
ps->startThreadPool();
ps->giveThreadPoolName();
IPCThreadState::self()->disableBackgroundScheduling(true);
diff --git a/cmds/incidentd/src/report_directory.cpp b/cmds/incidentd/src/report_directory.cpp
index 20111d8..b71c066 100644
--- a/cmds/incidentd/src/report_directory.cpp
+++ b/cmds/incidentd/src/report_directory.cpp
@@ -13,19 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#define LOG_TAG "incidentd"
+#include "Log.h"
#include "report_directory.h"
-#include <cutils/log.h>
#include <private/android_filesystem_config.h>
#include <utils/String8.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <dirent.h>
#include <libgen.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
#include <vector>
@@ -33,9 +31,7 @@
using namespace android;
using namespace std;
-status_t
-create_directory(const char* directory)
-{
+status_t create_directory(const char* directory) {
struct stat st;
status_t err = NO_ERROR;
char* dir = strdup(directory);
@@ -75,14 +71,14 @@
goto done;
}
if ((st.st_mode & 0777) != 0770) {
- ALOGE("No incident reports today. Mode is %0o on report directory %s",
- st.st_mode, directory);
+ ALOGE("No incident reports today. Mode is %0o on report directory %s", st.st_mode,
+ directory);
err = BAD_VALUE;
goto done;
}
if (st.st_uid != AID_INCIDENTD || st.st_gid != AID_INCIDENTD) {
ALOGE("No incident reports today. Owner is %d and group is %d on report directory %s",
- st.st_uid, st.st_gid, directory);
+ st.st_uid, st.st_gid, directory);
err = BAD_VALUE;
goto done;
}
@@ -92,20 +88,17 @@
return err;
}
-static bool
-stat_mtime_cmp(const pair<String8,struct stat>& a, const pair<String8,struct stat>& b)
-{
+static bool stat_mtime_cmp(const pair<String8, struct stat>& a,
+ const pair<String8, struct stat>& b) {
return a.second.st_mtime < b.second.st_mtime;
}
-void
-clean_directory(const char* directory, off_t maxSize, size_t maxCount)
-{
+void clean_directory(const char* directory, off_t maxSize, size_t maxCount) {
DIR* dir;
struct dirent* entry;
struct stat st;
- vector<pair<String8,struct stat>> files;
+ vector<pair<String8, struct stat>> files;
if ((dir = opendir(directory)) == NULL) {
ALOGE("Couldn't open incident directory: %s", directory);
@@ -131,7 +124,7 @@
if (!S_ISREG(st.st_mode)) {
continue;
}
- files.push_back(pair<String8,struct stat>(filename, st));
+ files.push_back(pair<String8, struct stat>(filename, st));
totalSize += st.st_size;
totalCount++;
@@ -148,8 +141,8 @@
sort(files.begin(), files.end(), stat_mtime_cmp);
// Remove files until we're under our limits.
- for (vector<pair<String8,struct stat>>::iterator it = files.begin();
- it != files.end() && totalSize >= maxSize && totalCount >= maxCount; it++) {
+ for (vector<pair<String8, struct stat>>::iterator it = files.begin();
+ it != files.end() && totalSize >= maxSize && totalCount >= maxCount; it++) {
remove(it->first.string());
totalSize -= it->second.st_size;
totalCount--;
diff --git a/cmds/incidentd/src/report_directory.h b/cmds/incidentd/src/report_directory.h
index bed4f86..2a3cf4c 100644
--- a/cmds/incidentd/src/report_directory.h
+++ b/cmds/incidentd/src/report_directory.h
@@ -13,17 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#pragma once
#ifndef DIRECTORY_CLEANER_H
#define DIRECTORY_CLEANER_H
+#include <sys/types.h>
#include <utils/Errors.h>
-#include <sys/types.h>
-
-using namespace android;
-
-status_t create_directory(const char* directory);
+android::status_t create_directory(const char* directory);
void clean_directory(const char* directory, off_t maxSize, size_t maxCount);
-#endif // DIRECTORY_CLEANER_H
+#endif // DIRECTORY_CLEANER_H
diff --git a/cmds/incidentd/src/section_list.h b/cmds/incidentd/src/section_list.h
index ddc0505..697e66f 100644
--- a/cmds/incidentd/src/section_list.h
+++ b/cmds/incidentd/src/section_list.h
@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#pragma once
#ifndef SECTION_LIST_H
#define SECTION_LIST_H
-#include <log/log_event_list.h> // include log_id_t enums.
+#include <log/log_event_list.h> // include log_id_t enums.
#include "Privacy.h"
#include "Section.h"
@@ -36,5 +37,4 @@
extern const int PRIVACY_POLICY_COUNT;
-#endif // SECTION_LIST_H
-
+#endif // SECTION_LIST_H
diff --git a/cmds/incidentd/tests/FdBuffer_test.cpp b/cmds/incidentd/tests/FdBuffer_test.cpp
index 3fd2ed82..956c8d3 100644
--- a/cmds/incidentd/tests/FdBuffer_test.cpp
+++ b/cmds/incidentd/tests/FdBuffer_test.cpp
@@ -11,11 +11,10 @@
// 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 "incidentd"
+#include "Log.h"
#include "FdBuffer.h"
-#include "io_util.h"
+#include "incidentd_util.h"
#include <android-base/file.h>
#include <android-base/test_utils.h>
@@ -48,7 +47,7 @@
}
void AssertBufferContent(const char* expected) {
- int i=0;
+ int i = 0;
EncodedBuffer::iterator it = buffer.data();
while (it.hasNext()) {
ASSERT_EQ(it.next(), expected[i++]);
@@ -100,7 +99,7 @@
ASSERT_TRUE(WriteStringToFile(testdata, tf.path));
ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, READ_TIMEOUT));
- int i=0;
+ int i = 0;
EncodedBuffer::iterator it = buffer.data();
while (it.hasNext()) {
EXPECT_EQ(it.next(), (uint8_t)testdata[i++]);
@@ -118,7 +117,7 @@
if (pid == 0) {
close(c2pPipe.readFd());
- while(true) {
+ while (true) {
write(c2pPipe.writeFd(), "poo", 3);
sleep(1);
}
@@ -130,7 +129,7 @@
ASSERT_EQ(NO_ERROR, status);
EXPECT_TRUE(buffer.timedOut());
- kill(pid, SIGKILL); // reap the child process
+ kill(pid, SIGKILL); // reap the child process
}
}
@@ -155,8 +154,8 @@
close(p2cPipe.readFd());
close(c2pPipe.writeFd());
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd,
- p2cPipe.writeFd(), c2pPipe.readFd(), READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd, p2cPipe.writeFd(),
+ c2pPipe.readFd(), READ_TIMEOUT));
AssertBufferReadSuccessful(HEAD.size() + testdata.size());
AssertBufferContent(expected.c_str());
wait(&pid);
@@ -187,8 +186,8 @@
close(p2cPipe.readFd());
close(c2pPipe.writeFd());
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd,
- p2cPipe.writeFd(), c2pPipe.readFd(), READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd, p2cPipe.writeFd(),
+ c2pPipe.readFd(), READ_TIMEOUT));
AssertBufferReadSuccessful(HEAD.size() + testdata.size());
AssertBufferContent(expected.c_str());
wait(&pid);
@@ -212,8 +211,8 @@
close(p2cPipe.readFd());
close(c2pPipe.writeFd());
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd,
- p2cPipe.writeFd(), c2pPipe.readFd(), READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd, p2cPipe.writeFd(),
+ c2pPipe.readFd(), READ_TIMEOUT));
AssertBufferReadSuccessful(0);
AssertBufferContent("");
wait(&pid);
@@ -222,7 +221,7 @@
TEST_F(FdBufferTest, ReadInStreamMoreThan4MB) {
const std::string testFile = kTestDataPath + "morethan4MB.txt";
- size_t fourMB = (size_t) 4 * 1024 * 1024;
+ size_t fourMB = (size_t)4 * 1024 * 1024;
int fd = open(testFile.c_str(), O_RDONLY | O_CLOEXEC);
ASSERT_NE(fd, -1);
int pid = fork();
@@ -239,8 +238,8 @@
close(p2cPipe.readFd());
close(c2pPipe.writeFd());
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(fd,
- p2cPipe.writeFd(), c2pPipe.readFd(), READ_TIMEOUT));
+ ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(fd, p2cPipe.writeFd(),
+ c2pPipe.readFd(), READ_TIMEOUT));
EXPECT_EQ(buffer.size(), fourMB);
EXPECT_FALSE(buffer.timedOut());
EXPECT_TRUE(buffer.truncated());
@@ -276,9 +275,9 @@
close(p2cPipe.readFd());
close(c2pPipe.writeFd());
- ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd,
- p2cPipe.writeFd(), c2pPipe.readFd(), QUICK_TIMEOUT_MS));
+ ASSERT_EQ(NO_ERROR, buffer.readProcessedDataInStream(tf.fd, p2cPipe.writeFd(),
+ c2pPipe.readFd(), QUICK_TIMEOUT_MS));
EXPECT_TRUE(buffer.timedOut());
- kill(pid, SIGKILL); // reap the child process
+ kill(pid, SIGKILL); // reap the child process
}
}
diff --git a/cmds/incidentd/tests/PrivacyBuffer_test.cpp b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
index c7bfe55..7ea9bbf 100644
--- a/cmds/incidentd/tests/PrivacyBuffer_test.cpp
+++ b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
@@ -11,8 +11,7 @@
// 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 "incidentd"
+#include "Log.h"
#include "FdBuffer.h"
#include "PrivacyBuffer.h"
@@ -37,13 +36,12 @@
const uint8_t STRING_TYPE = 9;
const uint8_t MESSAGE_TYPE = 11;
const string STRING_FIELD_0 = "\x02\viamtestdata";
-const string VARINT_FIELD_1 = "\x08\x96\x01"; // 150
+const string VARINT_FIELD_1 = "\x08\x96\x01"; // 150
const string STRING_FIELD_2 = "\x12\vwhatthefuck";
-const string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff"; // -1
-const string FIX32_FIELD_4 = "\x25\xff\xff\xff\xff"; // -1
+const string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff"; // -1
+const string FIX32_FIELD_4 = "\x25\xff\xff\xff\xff"; // -1
const string MESSAGE_FIELD_5 = "\x2a\x10" + VARINT_FIELD_1 + STRING_FIELD_2;
-
class PrivacyBufferTest : public Test {
public:
virtual ~PrivacyBufferTest() {
@@ -55,9 +53,7 @@
}
}
- virtual void SetUp() override {
- ASSERT_NE(tf.fd, -1);
- }
+ virtual void SetUp() override { ASSERT_NE(tf.fd, -1); }
void writeToFdBuffer(string str) {
ASSERT_TRUE(WriteStringToFile(str, tf.path));
@@ -81,11 +77,11 @@
}
void assertStripByFields(uint8_t dest, string expected, int size, Privacy* privacy, ...) {
- Privacy* list[size+1];
+ Privacy* list[size + 1];
list[0] = privacy;
va_list args;
va_start(args, privacy);
- for (int i=1; i<size; i++) {
+ for (int i = 1; i < size; i++) {
Privacy* p = va_arg(args, Privacy*);
list[i] = p;
}
@@ -115,13 +111,14 @@
}
FdBuffer buffer;
+
private:
TemporaryFile tf;
// Littering this code with unique_ptr (or similar) is ugly, so we just
// mass-free everything after the test completes.
- std::vector<Privacy *> privacies;
+ std::vector<Privacy*> privacies;
- Privacy *new_uninit_privacy() {
+ Privacy* new_uninit_privacy() {
Privacy* p = new Privacy;
privacies.push_back(p);
return p;
@@ -165,63 +162,69 @@
TEST_F(PrivacyBufferTest, NoStripVarintField) {
writeToFdBuffer(VARINT_FIELD_1);
- assertStripByFields(DEST_EXPLICIT, VARINT_FIELD_1, 1, create_privacy(1, OTHER_TYPE, DEST_AUTOMATIC));
+ assertStripByFields(DEST_EXPLICIT, VARINT_FIELD_1, 1,
+ create_privacy(1, OTHER_TYPE, DEST_AUTOMATIC));
}
TEST_F(PrivacyBufferTest, NoStripLengthDelimitedField_String) {
writeToFdBuffer(STRING_FIELD_2);
- assertStripByFields(DEST_EXPLICIT, STRING_FIELD_2, 1, create_privacy(2, STRING_TYPE, DEST_AUTOMATIC));
+ assertStripByFields(DEST_EXPLICIT, STRING_FIELD_2, 1,
+ create_privacy(2, STRING_TYPE, DEST_AUTOMATIC));
}
TEST_F(PrivacyBufferTest, NoStripFixed64Field) {
writeToFdBuffer(FIX64_FIELD_3);
- assertStripByFields(DEST_EXPLICIT, FIX64_FIELD_3, 1, create_privacy(3, OTHER_TYPE, DEST_AUTOMATIC));
+ assertStripByFields(DEST_EXPLICIT, FIX64_FIELD_3, 1,
+ create_privacy(3, OTHER_TYPE, DEST_AUTOMATIC));
}
TEST_F(PrivacyBufferTest, NoStripFixed32Field) {
writeToFdBuffer(FIX32_FIELD_4);
- assertStripByFields(DEST_EXPLICIT, FIX32_FIELD_4, 1, create_privacy(4, OTHER_TYPE, DEST_AUTOMATIC));
+ assertStripByFields(DEST_EXPLICIT, FIX32_FIELD_4, 1,
+ create_privacy(4, OTHER_TYPE, DEST_AUTOMATIC));
}
TEST_F(PrivacyBufferTest, NoStripLengthDelimitedField_Message) {
writeToFdBuffer(MESSAGE_FIELD_5);
- assertStripByFields(DEST_EXPLICIT, MESSAGE_FIELD_5, 1, create_privacy(5, MESSAGE_TYPE, DEST_AUTOMATIC));
+ assertStripByFields(DEST_EXPLICIT, MESSAGE_FIELD_5, 1,
+ create_privacy(5, MESSAGE_TYPE, DEST_AUTOMATIC));
}
TEST_F(PrivacyBufferTest, StripVarintAndString) {
- writeToFdBuffer(STRING_FIELD_0 + VARINT_FIELD_1 + STRING_FIELD_2
- + FIX64_FIELD_3 + FIX32_FIELD_4);
+ writeToFdBuffer(STRING_FIELD_0 + VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3 +
+ FIX32_FIELD_4);
string expected = STRING_FIELD_0 + FIX64_FIELD_3 + FIX32_FIELD_4;
- assertStripByFields(DEST_EXPLICIT, expected, 2,
- create_privacy(1, OTHER_TYPE, DEST_LOCAL), create_privacy(2, STRING_TYPE, DEST_LOCAL));
+ assertStripByFields(DEST_EXPLICIT, expected, 2, create_privacy(1, OTHER_TYPE, DEST_LOCAL),
+ create_privacy(2, STRING_TYPE, DEST_LOCAL));
}
TEST_F(PrivacyBufferTest, StripVarintAndFixed64) {
- writeToFdBuffer(STRING_FIELD_0 + VARINT_FIELD_1 + STRING_FIELD_2
- + FIX64_FIELD_3 + FIX32_FIELD_4);
+ writeToFdBuffer(STRING_FIELD_0 + VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3 +
+ FIX32_FIELD_4);
string expected = STRING_FIELD_0 + STRING_FIELD_2 + FIX32_FIELD_4;
- assertStripByFields(DEST_EXPLICIT, expected, 2,
- create_privacy(1, OTHER_TYPE, DEST_LOCAL), create_privacy(3, OTHER_TYPE, DEST_LOCAL));
+ assertStripByFields(DEST_EXPLICIT, expected, 2, create_privacy(1, OTHER_TYPE, DEST_LOCAL),
+ create_privacy(3, OTHER_TYPE, DEST_LOCAL));
}
TEST_F(PrivacyBufferTest, StripVarintInNestedMessage) {
writeToFdBuffer(STRING_FIELD_0 + MESSAGE_FIELD_5);
- Privacy* list[] = { create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL };
+ Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
string expected = STRING_FIELD_0 + "\x2a\xd" + STRING_FIELD_2;
assertStripByFields(DEST_EXPLICIT, expected, 1, create_message_privacy(5, list));
}
TEST_F(PrivacyBufferTest, StripFix64AndVarintInNestedMessage) {
writeToFdBuffer(STRING_FIELD_0 + FIX64_FIELD_3 + MESSAGE_FIELD_5);
- Privacy* list[] = { create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL };
+ Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
string expected = STRING_FIELD_0 + "\x2a\xd" + STRING_FIELD_2;
- assertStripByFields(DEST_EXPLICIT, expected, 2, create_privacy(3, OTHER_TYPE, DEST_LOCAL), create_message_privacy(5, list));
+ assertStripByFields(DEST_EXPLICIT, expected, 2, create_privacy(3, OTHER_TYPE, DEST_LOCAL),
+ create_message_privacy(5, list));
}
TEST_F(PrivacyBufferTest, ClearAndStrip) {
string data = STRING_FIELD_0 + VARINT_FIELD_1;
writeToFdBuffer(data);
- Privacy* list[] = { create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL };
+ Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
EncodedBuffer::iterator bufData = buffer.data();
PrivacyBuffer privacyBuf(create_message_privacy(300, list), bufData);
PrivacySpec spec1 = PrivacySpec::new_spec(DEST_EXPLICIT);
@@ -235,7 +238,7 @@
TEST_F(PrivacyBufferTest, BadDataInFdBuffer) {
writeToFdBuffer("iambaddata");
- Privacy* list[] = { create_privacy(4, OTHER_TYPE, DEST_AUTOMATIC), NULL };
+ Privacy* list[] = {create_privacy(4, OTHER_TYPE, DEST_AUTOMATIC), NULL};
EncodedBuffer::iterator bufData = buffer.data();
PrivacyBuffer privacyBuf(create_message_privacy(300, list), bufData);
PrivacySpec spec;
@@ -244,8 +247,8 @@
TEST_F(PrivacyBufferTest, BadDataInNestedMessage) {
writeToFdBuffer(STRING_FIELD_0 + MESSAGE_FIELD_5 + "aoeoe");
- Privacy* list[] = { create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL };
- Privacy* field5[] = { create_message_privacy(5, list), NULL };
+ Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
+ Privacy* field5[] = {create_message_privacy(5, list), NULL};
EncodedBuffer::iterator bufData = buffer.data();
PrivacyBuffer privacyBuf(create_message_privacy(300, field5), bufData);
PrivacySpec spec;
@@ -256,7 +259,7 @@
string input = "\x2a\"" + VARINT_FIELD_1 + STRING_FIELD_2 + MESSAGE_FIELD_5;
writeToFdBuffer(input);
Privacy* field5 = create_message_privacy(5, NULL);
- Privacy* list[] = { create_privacy(1, OTHER_TYPE, DEST_LOCAL), field5, NULL };
+ Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), field5, NULL};
field5->children = list;
string expected = "\x2a\x1c" + STRING_FIELD_2 + "\x2a\xd" + STRING_FIELD_2;
assertStrip(DEST_EXPLICIT, expected, field5);
@@ -264,7 +267,7 @@
TEST_F(PrivacyBufferTest, AutoMessage) {
writeToFdBuffer(STRING_FIELD_2 + MESSAGE_FIELD_5);
- Privacy* list[] = { create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL };
+ Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
Privacy* autoMsg = create_privacy(5, MESSAGE_TYPE, DEST_AUTOMATIC);
autoMsg->children = list;
string expected = "\x2a\xd" + STRING_FIELD_2;
diff --git a/cmds/incidentd/tests/Reporter_test.cpp b/cmds/incidentd/tests/Reporter_test.cpp
index a1e3c34..bd359ac 100644
--- a/cmds/incidentd/tests/Reporter_test.cpp
+++ b/cmds/incidentd/tests/Reporter_test.cpp
@@ -11,8 +11,7 @@
// 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 "incidentd"
+#include "Log.h"
#include "Reporter.h"
@@ -26,7 +25,6 @@
#include <gtest/gtest.h>
#include <string.h>
-
using namespace android;
using namespace android::base;
using namespace android::binder;
@@ -35,8 +33,7 @@
using ::testing::StrEq;
using ::testing::Test;
-class TestListener : public IIncidentReportStatusListener
-{
+class TestListener : public IIncidentReportStatusListener {
public:
int startInvoked;
int finishInvoked;
@@ -44,8 +41,8 @@
map<int, int> startSections;
map<int, int> finishSections;
- TestListener() : startInvoked(0), finishInvoked(0), failedInvoked(0) {};
- virtual ~TestListener() {};
+ TestListener() : startInvoked(0), finishInvoked(0), failedInvoked(0){};
+ virtual ~TestListener(){};
virtual Status onReportStarted() {
startInvoked++;
@@ -53,16 +50,14 @@
};
virtual Status onReportSectionStatus(int section, int status) {
switch (status) {
- case IIncidentReportStatusListener::STATUS_STARTING:
- if (startSections.count(section) == 0)
- startSections[section] = 0;
- startSections[section] = startSections[section] + 1;
- break;
- case IIncidentReportStatusListener::STATUS_FINISHED:
- if (finishSections.count(section) == 0)
- finishSections[section] = 0;
- finishSections[section] = finishSections[section] + 1;
- break;
+ case IIncidentReportStatusListener::STATUS_STARTING:
+ if (startSections.count(section) == 0) startSections[section] = 0;
+ startSections[section] = startSections[section] + 1;
+ break;
+ case IIncidentReportStatusListener::STATUS_FINISHED:
+ if (finishSections.count(section) == 0) finishSections[section] = 0;
+ finishSections[section] = finishSections[section] + 1;
+ break;
}
return Status::ok();
};
@@ -156,7 +151,8 @@
string result;
ReadFileToString(tf.path, &result);
- EXPECT_THAT(result, StrEq("\n\x2" "\b\f"));
+ EXPECT_THAT(result, StrEq("\n\x2"
+ "\b\f"));
EXPECT_EQ(l->startInvoked, 2);
EXPECT_EQ(l->finishInvoked, 2);
@@ -178,7 +174,11 @@
ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport());
vector<string> results = InspectFiles();
ASSERT_EQ((int)results.size(), 1);
- EXPECT_EQ(results[0], "\n\x2" "\b\f\n\x6" "\x12\x4" "abcd");
+ EXPECT_EQ(results[0],
+ "\n\x2"
+ "\b\f\n\x6"
+ "\x12\x4"
+ "abcd");
}
TEST_F(ReporterTest, ReportMetadata) {
diff --git a/cmds/incidentd/tests/Section_test.cpp b/cmds/incidentd/tests/Section_test.cpp
index 5752a67..a1f4fdc 100644
--- a/cmds/incidentd/tests/Section_test.cpp
+++ b/cmds/incidentd/tests/Section_test.cpp
@@ -11,8 +11,7 @@
// 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 "incidentd"
+#include "Log.h"
#include "Section.h"
@@ -30,9 +29,9 @@
const int QUICK_TIMEOUT_MS = 100;
-const string VARINT_FIELD_1 = "\x08\x96\x01"; // 150
+const string VARINT_FIELD_1 = "\x08\x96\x01"; // 150
const string STRING_FIELD_2 = "\x12\vwhatthefuck";
-const string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff"; // -1
+const string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff"; // -1
using namespace android::base;
using namespace android::binder;
@@ -44,11 +43,10 @@
// NOTICE: this test requires /system/bin/incident_helper is installed.
-class SimpleListener : public IIncidentReportStatusListener
-{
+class SimpleListener : public IIncidentReportStatusListener {
public:
- SimpleListener() {};
- virtual ~SimpleListener() {};
+ SimpleListener(){};
+ virtual ~SimpleListener(){};
virtual Status onReportStarted() { return Status::ok(); };
virtual Status onReportSectionStatus(int /*section*/, int /*status*/) { return Status::ok(); };
@@ -84,7 +82,9 @@
string content;
CaptureStdout();
ASSERT_EQ(NO_ERROR, hs.Execute(&requests));
- EXPECT_THAT(GetCapturedStdout(), StrEq("\n\x5" "\x12\x3" "axe\n\x05\x12\x03pup"));
+ EXPECT_THAT(GetCapturedStdout(), StrEq("\n\x5"
+ "\x12\x3"
+ "axe\n\x05\x12\x03pup"));
EXPECT_TRUE(ReadFileToString(output2.path, &content));
EXPECT_THAT(content, StrEq("\n\x05\x12\x03pup"));
@@ -271,12 +271,12 @@
string content, expect;
expect = VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3;
- char c = (char) expect.size();
+ char c = (char)expect.size();
EXPECT_TRUE(ReadFileToString(output1.path, &content));
EXPECT_THAT(content, StrEq(string("\x02") + c + expect));
expect = STRING_FIELD_2 + FIX64_FIELD_3;
- c = (char) expect.size();
+ c = (char)expect.size();
EXPECT_TRUE(ReadFileToString(output2.path, &content));
EXPECT_THAT(content, StrEq(string("\x02") + c + expect));
@@ -315,7 +315,7 @@
string content, expect;
expect = STRING_FIELD_2 + FIX64_FIELD_3;
- char c = (char) expect.size();
+ char c = (char)expect.size();
// output1 and output2 are the same
EXPECT_TRUE(ReadFileToString(output1.path, &content));
@@ -324,7 +324,7 @@
EXPECT_THAT(content, StrEq(string("\x02") + c + expect));
// output3 has only auto field
- c = (char) STRING_FIELD_2.size();
+ c = (char)STRING_FIELD_2.size();
EXPECT_TRUE(ReadFileToString(output3.path, &content));
EXPECT_THAT(content, StrEq(string("\x02") + c + STRING_FIELD_2));
}
\ No newline at end of file
diff --git a/cmds/incidentd/tests/section_list.cpp b/cmds/incidentd/tests/section_list.cpp
index 1d6213f..bd2d15c 100644
--- a/cmds/incidentd/tests/section_list.cpp
+++ b/cmds/incidentd/tests/section_list.cpp
@@ -1,25 +1,17 @@
// This file is a dummy section_list.cpp used for test only.
#include "section_list.h"
-const Section* SECTION_LIST[] = {
- NULL
-};
+const Section* SECTION_LIST[] = {NULL};
-Privacy sub_field_1 { 1, 1, NULL, DEST_LOCAL, NULL };
-Privacy sub_field_2 { 2, 9, NULL, DEST_AUTOMATIC, NULL };
+Privacy sub_field_1{1, 1, NULL, DEST_LOCAL, NULL};
+Privacy sub_field_2{2, 9, NULL, DEST_AUTOMATIC, NULL};
-Privacy* list[] = {
- &sub_field_1,
- &sub_field_2,
- NULL };
+Privacy* list[] = {&sub_field_1, &sub_field_2, NULL};
-Privacy field_0 { 0, 11, list, DEST_EXPLICIT, NULL };
-Privacy field_1 { 1, 9, NULL, DEST_AUTOMATIC, NULL };
+Privacy field_0{0, 11, list, DEST_EXPLICIT, NULL};
+Privacy field_1{1, 9, NULL, DEST_AUTOMATIC, NULL};
-Privacy* final_list[] = {
- &field_0,
- &field_1
-};
+Privacy* final_list[] = {&field_0, &field_1};
const Privacy** PRIVACY_POLICY_LIST = const_cast<const Privacy**>(final_list);