diff options
author | 2018-02-01 15:17:04 -0800 | |
---|---|---|
committer | 2018-02-15 16:53:22 -0800 | |
commit | b592e3bc3169e39bd6b0bfce9f788631d5d22acd (patch) | |
tree | e760b9120e2a44654e0f8850e421d5d65116bcb9 | |
parent | 5f8b250f1a2dc69eac726d4011d66322f8f192f7 (diff) |
This cl formats incidentd and makes it easier for debugging.
Bug: 72755317
Test: clang-format -type=file -i <files>
Change-Id: Ide91227f26c6b1db6d2e5fe8117ca5cc4cf77fd3
27 files changed, 716 insertions, 736 deletions
diff --git a/cmds/incidentd/.clang-format b/cmds/incidentd/.clang-format new file mode 100644 index 000000000000..6fa5b474b715 --- /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 23cd2af512b5..d2d24c89449a 100644 --- a/cmds/incidentd/Android.mk +++ b/cmds/incidentd/Android.mk @@ -32,7 +32,7 @@ LOCAL_SRC_FILES := \ 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 @@ LOCAL_SRC_FILES := \ 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 71c6deb18aac..1730a6401254 100644 --- a/cmds/incidentd/README.md +++ b/cmds/incidentd/README.md @@ -20,4 +20,8 @@ Run the test via AndroidTest.xml ``` 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 0fff4e6dc4a0..883924c83d82 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 @@ FdBuffer::read(int fd, int64_t timeout) 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 @@ FdBuffer::read(int fd, int64_t timeout) 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 @@ FdBuffer::read(int fd, int64_t timeout) 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 @@ FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeou 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 @@ FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeou // 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 @@ FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeou 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 @@ FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeou } 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 @@ FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeou } 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 @@ FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeou 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 @@ FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeou 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 48dc855e71b2..5bfa0938f5e8 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 @@ using namespace std; /** * 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 @@ public: * * 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 @@ private: 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 654036ec6ab7..9ae624094dca 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 @@ enum { 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 @@ checkIncidentPermissions(const IncidentReportArgs& args) // 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 @@ checkIncidentPermissions(const IncidentReportArgs& args) 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 @@ ReportRequestQueue::getNextRequest() } } - // ================================================================================ 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 @@ ReportHandler::handleMessage(const Message& message) } } -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 @@ ReportHandler::run_report() } } -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 @@ ReportHandler::send_backlog_to_dropbox() // ================================================================================ 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 @@ IncidentService::reportIncident(const IncidentReportArgs& args) 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 @@ IncidentService::reportIncidentToStream(const IncidentReportArgs& args, 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 @@ IncidentService::systemRunning() 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 d6f33dfb1a86..3c665076bebc 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 android::os; using namespace std; // ================================================================================ -class ReportRequestQueue : public virtual RefBase -{ +class ReportRequestQueue : public virtual RefBase { public: ReportRequestQueue(); virtual ~ReportRequestQueue(); @@ -46,10 +46,8 @@ private: 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 @@ private: void send_backlog_to_dropbox(); }; - // ================================================================================ class IncidentService : public BnIncidentManager { public: @@ -99,14 +96,29 @@ public: 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/io_util.cpp b/cmds/incidentd/src/Log.h index 90f543e30ff7..46efbd1fb7d0 100644 --- a/cmds/incidentd/src/io_util.cpp +++ b/cmds/incidentd/src/Log.h @@ -14,33 +14,21 @@ * 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(); } +/* + * 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. + */ -bool Fpipe::close() { return !(::close(mFds[0]) || ::close(mFds[1])); } +#pragma once -bool Fpipe::init() { return pipe(mFds) != -1; } +#define LOG_TAG "incidentd" +#define DEBUG false -int Fpipe::readFd() const { return mFds[0]; } +#include <log/log.h> -int Fpipe::writeFd() const { return mFds[1]; } +// 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 c5078f0f7909..c42a87b64a73 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 @@ const Privacy* lookup(const Privacy* p, uint32_t fieldId) 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 ce1b8e96529c..6b6de9cd9823 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 @@ public: 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 f53befefab93..e4128f4217d1 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 @@ PrivacyBuffer::writeFieldOrSkip(uint32_t fieldTag, bool skip) 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 @@ PrivacyBuffer::writeFieldOrSkip(uint32_t fieldTag, bool skip) * 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::stripField(const Privacy* parentPolicy, const PrivacySpec& spec) // ================================================================================ 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 c9ca9a752c9c..92e1a2572465 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 @@ using namespace android::util; * 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 @@ private: 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 06baebaf3a4c..c0b53586a8ce 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 @@ static const char* INCIDENT_DIRECTORY = "/data/misc/incidents/"; // ================================================================================ 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 @@ ReportRequestSet::setMainDest(int dest) } } -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 @@ ReportRequestSet::sectionStats(int id) { // ================================================================================ 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 @@ Reporter::Reporter(const char* directory) 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 @@ Reporter::runReport() 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 @@ Reporter::runReport() } // 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 @@ Reporter::runReport() // 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 @@ Reporter::runReport() 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 @@ DONE: } // 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 @@ DONE: // 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 @@ DONE: /** * 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 @@ Reporter::create_file(int* fd) 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 @@ Reporter::upload_backlog() return REPORT_FINISHED; } - diff --git a/cmds/incidentd/src/Reporter.h b/cmds/incidentd/src/Reporter.h index 6058068be331..0f3f22172452 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 android::os; 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 @@ private: }; // ================================================================================ -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 @@ private: 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 3c76298c284c..2e4e980278f9 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_HEADER = 1; 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 @@ fork_execute_incident_helper(const int id, const char* name, Fpipe& p2cPipe, Fpi 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 @@ fork_execute_incident_helper(const int id, const char* name, Fpipe& p2cPipe, Fpi // ================================================================================ 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 @@ static status_t wait_child(pid_t pid) { 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 @@ static status_t wait_child(pid_t pid) { 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 @@ write_report_requests(const int id, const FdBuffer& buffer, ReportRequestSet* re 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 @@ write_report_requests(const int id, const FdBuffer& buffer, ReportRequestSet* re 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 @@ DONE: } // ================================================================================ -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 @@ HeaderSection::Execute(ReportRequestSet* requests) const 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 @@ FileSection::Execute(ReportRequestSet* requests) const // 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 @@ FileSection::Execute(ReportRequestSet* requests) const } // ================================================================================ -struct WorkerThreadData : public virtual RefBase -{ +struct WorkerThreadData : public virtual RefBase { const WorkerThreadSection* section; int fds[2]; @@ -362,31 +330,19 @@ struct WorkerThreadData : public virtual RefBase }; 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 @@ worker_thread_func(void* cookie) 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 @@ WorkerThreadSection::Execute(ReportRequestSet* requests) const 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 @@ WorkerThreadSection::Execute(ReportRequestSet* requests) const 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 @@ WorkerThreadSection::Execute(ReportRequestSet* requests) const // 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 @@ WorkerThreadSection::Execute(ReportRequestSet* requests) const } // ================================================================================ -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 @@ CommandSection::init(const char* command, va_list args) 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 @@ CommandSection::Execute(ReportRequestSet* requests) const 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 @@ CommandSection::Execute(ReportRequestSet* requests) const 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 @@ CommandSection::Execute(ReportRequestSet* requests) const // ================================================================================ DumpsysSection::DumpsysSection(int id, const char* service, ...) - :WorkerThreadSection(id), - mService(service) -{ + : WorkerThreadSection(id), mService(service) { name = "dumpsys "; name += service; @@ -637,13 +583,9 @@ DumpsysSection::DumpsysSection(int id, const char* service, ...) 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 @@ DumpsysSection::BlockingCall(int pipeWriteFd) const // 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 @@ static inline int32_t get4LE(uint8_t const* src) { 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 @@ LogSection::BlockingCall(int pipeWriteFd) const 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 @@ LogSection::BlockingCall(int pipeWriteFd) const 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 @@ LogSection::BlockingCall(int pipeWriteFd) const 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 @@ LogSection::BlockingCall(int pipeWriteFd) const 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 80cc033d5ca0..d6446810c40f 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 @@ public: /** * Section that generates incident headers. */ -class HeaderSection : public Section -{ +class HeaderSection : public Section { public: HeaderSection(); virtual ~HeaderSection(); @@ -61,8 +60,7 @@ public: /** * Section that generates incident metadata. */ -class MetadataSection : public Section -{ +class MetadataSection : public Section { public: MetadataSection(); virtual ~MetadataSection(); @@ -73,8 +71,7 @@ public: /** * 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 @@ public: 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 @@ public: /** * 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 @@ private: /** * 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 @@ private: /** * 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 @@ private: 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 000000000000..2415860572fb --- /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 index 320dd6c386d2..09aa0404277a 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 @@ public: 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/main.cpp b/cmds/incidentd/src/main.cpp index 3a7511d43048..38b7449403fe 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 20111d8ae89a..b71c066201c4 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 @@ create_directory(const char* directory) 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 @@ done: 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 @@ clean_directory(const char* directory, off_t maxSize, size_t maxCount) 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 @@ clean_directory(const char* directory, off_t maxSize, size_t maxCount) 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 bed4f869cfe4..2a3cf4c0f701 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 <utils/Errors.h> - #include <sys/types.h> +#include <utils/Errors.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 ddc0505df331..697e66f9cf40 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 Privacy** PRIVACY_POLICY_LIST; 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 3fd2ed82a26e..956c8d39346a 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 @@ public: } 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 @@ TEST_F(FdBufferTest, ReadAndIterate) { 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 @@ TEST_F(FdBufferTest, ReadTimeout) { if (pid == 0) { close(c2pPipe.readFd()); - while(true) { + while (true) { write(c2pPipe.writeFd(), "poo", 3); sleep(1); } @@ -130,7 +129,7 @@ TEST_F(FdBufferTest, ReadTimeout) { 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 @@ TEST_F(FdBufferTest, ReadInStreamAndWrite) { 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 @@ TEST_F(FdBufferTest, ReadInStreamAndWriteAllAtOnce) { 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 @@ TEST_F(FdBufferTest, ReadInStreamEmpty) { 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, ReadInStreamEmpty) { 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 @@ TEST_F(FdBufferTest, ReadInStreamMoreThan4MB) { 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 @@ TEST_F(FdBufferTest, ReadInStreamTimeOut) { 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 c7bfe5555743..7ea9bbfcd8c7 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 OTHER_TYPE = 1; 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 @@ public: } } - 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 @@ public: } 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 @@ public: } 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, StripLengthDelimitedField_Message) { 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, ClearAndStrip) { 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, BadDataInFdBuffer) { 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 @@ TEST_F(PrivacyBufferTest, SelfRecursionMessage) { 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, SelfRecursionMessage) { 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 a1e3c3430595..bd359ac9516c 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 namespace std; using ::testing::StrEq; using ::testing::Test; -class TestListener : public IIncidentReportStatusListener -{ +class TestListener : public IIncidentReportStatusListener { public: int startInvoked; int finishInvoked; @@ -44,8 +41,8 @@ public: 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 @@ public: }; 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 @@ TEST_F(ReporterTest, RunReportWithHeaders) { 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 @@ TEST_F(ReporterTest, RunReportToGivenDirectory) { 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 5752a670c6a2..a1f4fdc77300 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 REVERSE_PARSER = 1; 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 @@ using ::testing::internal::GetCapturedStdout; // 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 @@ TEST(SectionTest, HeaderSection) { 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 @@ TEST(SectionTest, TestMultipleRequests) { 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 @@ TEST(SectionTest, TestMultipleRequestsBySpec) { 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 @@ TEST(SectionTest, TestMultipleRequestsBySpec) { 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 1d6213fd19b3..bd2d15cc38be 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); |