summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/incident/main.cpp21
-rw-r--r--cmds/incidentd/src/EncodedBuffer.cpp4
-rw-r--r--cmds/incidentd/src/FdBuffer.cpp59
-rw-r--r--cmds/incidentd/src/FdBuffer.h29
-rw-r--r--cmds/incidentd/src/Privacy.cpp11
-rw-r--r--cmds/incidentd/src/Privacy.h3
-rw-r--r--cmds/incidentd/src/Section.cpp50
-rw-r--r--cmds/incidentd/tests/Reporter_test.cpp3
-rw-r--r--cmds/incidentd/tests/Section_test.cpp130
-rw-r--r--core/java/android/os/IncidentReportArgs.java16
-rw-r--r--libs/incident/include/android/os/IncidentReportArgs.h6
-rw-r--r--libs/incident/src/IncidentReportArgs.cpp24
12 files changed, 312 insertions, 44 deletions
diff --git a/cmds/incident/main.cpp b/cmds/incident/main.cpp
index 47f1db89e1cb..519852dbe88b 100644
--- a/cmds/incident/main.cpp
+++ b/cmds/incident/main.cpp
@@ -25,6 +25,7 @@
#include <binder/IServiceManager.h>
#include <utils/Looper.h>
+#include <cstring>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
@@ -144,6 +145,16 @@ find_section(const char* name)
}
// ================================================================================
+static int
+get_dest(const char* arg)
+{
+ if (strcmp(arg, "LOCAL") == 0) return 0;
+ if (strcmp(arg, "EXPLICIT") == 0) return 1;
+ if (strcmp(arg, "AUTOMATIC") == 0) return 2;
+ return -1; // return the default value
+}
+
+// ================================================================================
static void
usage(FILE* out)
{
@@ -155,6 +166,7 @@ usage(FILE* out)
fprintf(out, " -b (default) print the report to stdout (in proto format)\n");
fprintf(out, " -d send the report into dropbox\n");
fprintf(out, " -l list available sections\n");
+ fprintf(out, " -p privacy spec, LOCAL, EXPLICIT or AUTOMATIC\n");
fprintf(out, "\n");
fprintf(out, " SECTION the field numbers of the incident report fields to include\n");
fprintf(out, "\n");
@@ -166,10 +178,11 @@ main(int argc, char** argv)
Status status;
IncidentReportArgs args;
enum { DEST_DROPBOX, DEST_STDOUT } destination = DEST_STDOUT;
+ int dest = -1; // default
// Parse the args
int opt;
- while ((opt = getopt(argc, argv, "bhdl")) != -1) {
+ while ((opt = getopt(argc, argv, "bhdlp:")) != -1) {
switch (opt) {
case 'h':
usage(stdout);
@@ -183,6 +196,9 @@ main(int argc, char** argv)
case 'd':
destination = DEST_DROPBOX;
break;
+ case 'p':
+ dest = get_dest(optarg);
+ break;
default:
usage(stderr);
return 1;
@@ -210,8 +226,7 @@ main(int argc, char** argv)
}
}
}
-
-
+ args.setDest(dest);
// Start the thread pool.
sp<ProcessState> ps(ProcessState::self());
diff --git a/cmds/incidentd/src/EncodedBuffer.cpp b/cmds/incidentd/src/EncodedBuffer.cpp
index d1872f96b9df..3d20548f18b7 100644
--- a/cmds/incidentd/src/EncodedBuffer.cpp
+++ b/cmds/incidentd/src/EncodedBuffer.cpp
@@ -70,7 +70,6 @@ write_field_or_skip(FdBuffer::iterator &iterator, vector<uint8_t> &buf, uint8_t
if (skip) {
iterator += bytesToWrite;
} else {
- buf.reserve(bytesToWrite);
for (size_t i=0; i<bytesToWrite; i++) {
buf.push_back(*iterator);
iterator++;
@@ -192,4 +191,5 @@ EncodedBuffer::flush(int fd)
if (err != NO_ERROR) return err;
}
return NO_ERROR;
-} \ No newline at end of file
+}
+
diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp
index 23a611acd494..bb399b57b8cd 100644
--- a/cmds/incidentd/src/FdBuffer.cpp
+++ b/cmds/incidentd/src/FdBuffer.cpp
@@ -259,6 +259,12 @@ FdBuffer::flush(int fd) const
}
FdBuffer::iterator
+FdBuffer::begin() const
+{
+ return iterator(*this, 0, 0);
+}
+
+FdBuffer::iterator
FdBuffer::end() const
{
if (mBuffers.empty() || mCurrentWritten < 0) return begin();
@@ -268,6 +274,17 @@ FdBuffer::end() const
return FdBuffer::iterator(*this, mBuffers.size() - 1, mCurrentWritten);
}
+// ===============================================================================
+FdBuffer::iterator::iterator(const FdBuffer& buffer, ssize_t index, ssize_t offset)
+ : mFdBuffer(buffer),
+ mIndex(index),
+ mOffset(offset)
+{
+}
+
+FdBuffer::iterator&
+FdBuffer::iterator::operator=(iterator& other) const { return other; }
+
FdBuffer::iterator&
FdBuffer::iterator::operator+(size_t offset)
{
@@ -280,8 +297,50 @@ FdBuffer::iterator::operator+(size_t offset)
return *this;
}
+FdBuffer::iterator&
+FdBuffer::iterator::operator+=(size_t offset) { return *this + offset; }
+
+FdBuffer::iterator&
+FdBuffer::iterator::operator++() { return *this + 1; }
+
+FdBuffer::iterator
+FdBuffer::iterator::operator++(int) { return *this + 1; }
+
+bool
+FdBuffer::iterator::operator==(iterator other) const
+{
+ return mIndex == other.mIndex && mOffset == other.mOffset;
+}
+
+bool
+FdBuffer::iterator::operator!=(iterator other) const { return !(*this == other); }
+
+int
+FdBuffer::iterator::operator-(iterator other) const
+{
+ return (int)bytesRead() - (int)other.bytesRead();
+}
+
+FdBuffer::iterator::reference
+FdBuffer::iterator::operator*() const
+{
+ return mFdBuffer.mBuffers[mIndex][mOffset];
+}
+
+FdBuffer::iterator
+FdBuffer::iterator::snapshot() const
+{
+ return FdBuffer::iterator(mFdBuffer, mIndex, mOffset);
+}
+
size_t
FdBuffer::iterator::bytesRead() const
{
return mIndex * BUFFER_SIZE + mOffset;
}
+
+bool
+FdBuffer::iterator::outOfBound() const
+{
+ return bytesRead() > mFdBuffer.size();
+}
diff --git a/cmds/incidentd/src/FdBuffer.h b/cmds/incidentd/src/FdBuffer.h
index 4c4823e5a4d8..dfe39c62de42 100644
--- a/cmds/incidentd/src/FdBuffer.h
+++ b/cmds/incidentd/src/FdBuffer.h
@@ -87,32 +87,29 @@ public:
friend class iterator;
class iterator : public std::iterator<std::random_access_iterator_tag, uint8_t> {
public:
- iterator(const FdBuffer& buffer, ssize_t index, ssize_t offset)
- : mFdBuffer(buffer), mIndex(index), mOffset(offset) {}
- iterator& operator=(iterator& other) const { return other; }
- iterator& operator+(size_t offset); // this is implemented in .cpp
- iterator& operator+=(size_t offset) { return *this + offset; }
- iterator& operator++() { return *this + 1; }
- iterator operator++(int) { return *this + 1; }
- bool operator==(iterator other) const {
- return mIndex == other.mIndex && mOffset == other.mOffset;
- }
- bool operator!=(iterator other) const { return !(*this == other); }
- int operator-(iterator other) const { return (int)bytesRead() - (int)other.bytesRead(); }
- reference operator*() const { return mFdBuffer.mBuffers[mIndex][mOffset]; }
+ iterator(const FdBuffer& buffer, ssize_t index, ssize_t offset);
+ iterator& operator=(iterator& other) const;
+ iterator& operator+(size_t offset);
+ iterator& operator+=(size_t offset);
+ iterator& operator++();
+ iterator operator++(int);
+ bool operator==(iterator other) const;
+ bool operator!=(iterator other) const;
+ int operator-(iterator other) const;
+ reference operator*() const;
// return the snapshot of the current iterator
- iterator snapshot() const { return iterator(mFdBuffer, mIndex, mOffset); }
+ iterator snapshot() const;
// how many bytes are read
size_t bytesRead() const;
// random access could make the iterator out of bound
- bool outOfBound() const { return bytesRead() > mFdBuffer.size(); }
+ bool outOfBound() const;
private:
const FdBuffer& mFdBuffer;
size_t mIndex;
size_t mOffset;
};
- iterator begin() const { return iterator(*this, 0, 0); }
+ iterator begin() const;
iterator end() const;
private:
diff --git a/cmds/incidentd/src/Privacy.cpp b/cmds/incidentd/src/Privacy.cpp
index a790efa2f611..dbab5480e698 100644
--- a/cmds/incidentd/src/Privacy.cpp
+++ b/cmds/incidentd/src/Privacy.cpp
@@ -88,6 +88,12 @@ static bool allowDest(const uint8_t dest, const uint8_t policy)
}
bool
+PrivacySpec::operator<(const PrivacySpec& other) const
+{
+ return dest < other.dest;
+}
+
+bool
PrivacySpec::CheckPremission(const Privacy* privacy) const
{
uint8_t policy = privacy == NULL ? DEST_DEFAULT_VALUE : privacy->dest;
@@ -97,4 +103,9 @@ PrivacySpec::CheckPremission(const Privacy* privacy) const
bool
PrivacySpec::RequireAll() const { return dest == DEST_LOCAL; }
+PrivacySpec new_spec_from_args(int dest) {
+ if (dest < 0) return PrivacySpec();
+ return PrivacySpec(dest);
+}
+
PrivacySpec get_default_dropbox_spec() { return PrivacySpec(DEST_AUTOMATIC); } \ No newline at end of file
diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h
index 53b0325b15f4..c56ba9b8e3fe 100644
--- a/cmds/incidentd/src/Privacy.h
+++ b/cmds/incidentd/src/Privacy.h
@@ -58,10 +58,13 @@ public:
PrivacySpec() : dest(DEST_DEFAULT_VALUE) {}
PrivacySpec(uint8_t dest) : dest(dest) {}
+ bool operator<(const PrivacySpec& other) const;
+
bool CheckPremission(const Privacy* privacy) const;
bool RequireAll() const;
};
+PrivacySpec new_spec_from_args(int dest);
PrivacySpec get_default_dropbox_spec();
#endif // PRIVACY_H
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index a04804c8c770..08959263838d 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -27,6 +27,7 @@
#include <private/android_filesystem_config.h>
#include <binder/IServiceManager.h>
+#include <map>
#include <mutex>
#include <wait.h>
#include <unistd.h>
@@ -109,20 +110,16 @@ GetPrivacyOfSection(int id)
}
static status_t
-WriteToRequest(const int id, const int fd, EncodedBuffer& buffer, const PrivacySpec& spec)
+WriteToRequest(const int id, const int fd, EncodedBuffer& buffer)
{
- if (fd < 0) return EBADF;
+ if (buffer.size() == 0) return NO_ERROR;
+
status_t err = NO_ERROR;
uint8_t buf[20];
-
- buffer.clear(); // clear before strip
- err = buffer.strip(spec); // TODO: don't have to strip again if the spec is the same.
- if (err != NO_ERROR || buffer.size() == 0) return err;
uint8_t *p = write_length_delimited_tag_header(buf, id, buffer.size());
err = write_all(fd, buf, p-buf);
if (err == NO_ERROR) {
err = buffer.flush(fd);
- ALOGD("Section %d flushed %zu bytes to fd %d with spec %d", id, buffer.size(), fd, spec.dest);
}
return err;
}
@@ -130,25 +127,46 @@ WriteToRequest(const int id, const int fd, EncodedBuffer& buffer, const PrivacyS
static status_t
WriteToReportRequests(const int id, const FdBuffer& buffer, ReportRequestSet* requests)
{
- status_t err = EBADF;
+ status_t err = -EBADF;
EncodedBuffer encodedBuffer(buffer, GetPrivacyOfSection(id));
int writeable = 0;
- // The streaming ones
+ // The streaming ones, group requests by spec in order to save unnecessary strip operations
+ map<PrivacySpec, vector<sp<ReportRequest>>> requestsBySpec;
for (ReportRequestSet::iterator it = requests->begin(); it != requests->end(); it++) {
sp<ReportRequest> request = *it;
- PrivacySpec spec; // TODO: this should be derived from each request.
- err = WriteToRequest(id, request->fd, encodedBuffer, spec);
- if (err != NO_ERROR) {
- request->err = err;
- } else {
- writeable++;
+ if (!request->args.containsSection(id) || request->fd < 0 || request->err != NO_ERROR) {
+ continue; // skip invalid request
+ }
+ PrivacySpec spec = new_spec_from_args(request->args.dest());
+ requestsBySpec[spec].push_back(request);
+ }
+
+ for (map<PrivacySpec, vector<sp<ReportRequest>>>::iterator mit = requestsBySpec.begin(); mit != requestsBySpec.end(); mit++) {
+ PrivacySpec spec = mit->first;
+ err = encodedBuffer.strip(spec);
+ if (err != NO_ERROR) return err; // it means the encodedBuffer data is corrupted.
+ if (encodedBuffer.size() == 0) continue;
+
+ for (vector<sp<ReportRequest>>::iterator it = mit->second.begin(); it != mit->second.end(); it++) {
+ sp<ReportRequest> request = *it;
+ err = WriteToRequest(id, request->fd, encodedBuffer);
+ if (err != NO_ERROR) {
+ request->err = err;
+ } else {
+ writeable++;
+ }
+ ALOGD("Section %d flushed %zu bytes to fd %d with spec %d", id, encodedBuffer.size(), request->fd, spec.dest);
}
+ encodedBuffer.clear();
}
// The dropbox file
if (requests->mainFd() >= 0) {
- err = WriteToRequest(id, requests->mainFd(), encodedBuffer, get_default_dropbox_spec());
+ err = encodedBuffer.strip(get_default_dropbox_spec());
+ if (err != NO_ERROR) return err; // the buffer data is corrupted.
+
+ err = WriteToRequest(id, requests->mainFd(), encodedBuffer);
if (err != NO_ERROR) {
requests->setMainFd(-1);
} else {
diff --git a/cmds/incidentd/tests/Reporter_test.cpp b/cmds/incidentd/tests/Reporter_test.cpp
index 3c1b44b6a515..5d074bcb0e4c 100644
--- a/cmds/incidentd/tests/Reporter_test.cpp
+++ b/cmds/incidentd/tests/Reporter_test.cpp
@@ -76,8 +76,7 @@ public:
};
protected:
- IBinder* onAsBinder() override { return nullptr; };
-
+ virtual IBinder* onAsBinder() override { return nullptr; };
};
class ReporterTest : public Test {
diff --git a/cmds/incidentd/tests/Section_test.cpp b/cmds/incidentd/tests/Section_test.cpp
index ab0f05498232..f2aee8fa2bb0 100644
--- a/cmds/incidentd/tests/Section_test.cpp
+++ b/cmds/incidentd/tests/Section_test.cpp
@@ -33,11 +33,27 @@ const string STRING_FIELD_2 = "\x12\vwhatthefuck";
const string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff"; // -1
using namespace android::base;
+using namespace android::binder;
using namespace std;
using ::testing::StrEq;
using ::testing::internal::CaptureStdout;
using ::testing::internal::GetCapturedStdout;
+class SimpleListener : public IIncidentReportStatusListener
+{
+public:
+ SimpleListener() {};
+ virtual ~SimpleListener() {};
+
+ virtual Status onReportStarted() { return Status::ok(); };
+ virtual Status onReportSectionStatus(int /*section*/, int /*status*/) { return Status::ok(); };
+ virtual Status onReportFinished() { return Status::ok(); };
+ virtual Status onReportFailed() { return Status::ok(); };
+
+protected:
+ virtual IBinder* onAsBinder() override { return nullptr; };
+};
+
// NOTICE: this test requires /system/bin/incident_helper is installed.
TEST(SectionTest, FileSection) {
TemporaryFile tf;
@@ -126,4 +142,118 @@ TEST(SectionTest, TestFilterPiiTaggedFields) {
CaptureStdout();
ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
EXPECT_THAT(GetCapturedStdout(), StrEq("\x02\r" + STRING_FIELD_2));
+}
+
+TEST(SectionTest, TestBadFdRequest) {
+ TemporaryFile input;
+ FileSection fs(NOOP_PARSER, input.path);
+ ReportRequestSet requests;
+ ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, input.path, false));
+
+ IncidentReportArgs args;
+ args.setAll(true);
+ args.setDest(0);
+ sp<ReportRequest> badFdRequest = new ReportRequest(args, new SimpleListener(), 1234567);
+ requests.add(badFdRequest);
+ requests.setMainFd(STDOUT_FILENO);
+
+ CaptureStdout();
+ ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
+ EXPECT_THAT(GetCapturedStdout(), StrEq("\x02\r" + STRING_FIELD_2));
+ EXPECT_EQ(badFdRequest->err, -EBADF);
+}
+
+TEST(SectionTest, TestBadRequests) {
+ TemporaryFile input;
+ FileSection fs(NOOP_PARSER, input.path);
+ ReportRequestSet requests;
+ ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, input.path, false));
+
+ IncidentReportArgs args;
+ args.setAll(true);
+ args.setDest(0);
+ requests.add(new ReportRequest(args, new SimpleListener(), -1));
+ EXPECT_EQ(fs.Execute(&requests), -EBADF);
+}
+
+TEST(SectionTest, TestMultipleRequests) {
+ TemporaryFile input, output1, output2, output3;
+ FileSection fs(NOOP_PARSER, input.path);
+ ReportRequestSet requests;
+
+ ASSERT_TRUE(input.fd != -1);
+ ASSERT_TRUE(output1.fd != -1);
+ ASSERT_TRUE(output2.fd != -1);
+ ASSERT_TRUE(output3.fd != -1);
+ ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, input.path, false));
+
+ IncidentReportArgs args1, args2, args3;
+ args1.setAll(true);
+ args1.setDest(0); // LOCAL
+ args2.setAll(true); // default to explicit
+ sp<SimpleListener> l = new SimpleListener();
+ requests.add(new ReportRequest(args1, l, output1.fd));
+ requests.add(new ReportRequest(args2, l, output2.fd));
+ requests.add(new ReportRequest(args3, l, output3.fd));
+ requests.setMainFd(STDOUT_FILENO);
+
+ CaptureStdout();
+ ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
+ EXPECT_THAT(GetCapturedStdout(), StrEq("\x02\r" + STRING_FIELD_2));
+
+ string content, expect;
+ expect = VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3;
+ 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();
+ EXPECT_TRUE(ReadFileToString(output2.path, &content));
+ EXPECT_THAT(content, StrEq(string("\x02") + c + expect));
+
+ // because args3 doesn't set section, so it should receive nothing
+ EXPECT_TRUE(ReadFileToString(output3.path, &content));
+ EXPECT_THAT(content, StrEq(""));
+}
+
+TEST(SectionTest, TestMultipleRequestsBySpec) {
+ TemporaryFile input, output1, output2, output3;
+ FileSection fs(NOOP_PARSER, input.path);
+ ReportRequestSet requests;
+
+ ASSERT_TRUE(input.fd != -1);
+ ASSERT_TRUE(output1.fd != -1);
+ ASSERT_TRUE(output2.fd != -1);
+ ASSERT_TRUE(output3.fd != -1);
+
+ ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, input.path, false));
+
+ IncidentReportArgs args1, args2, args3, args4;
+ args1.setAll(true);
+ args2.setAll(true);
+ args4.setAll(true);
+ sp<SimpleListener> l = new SimpleListener();
+ requests.add(new ReportRequest(args1, l, output1.fd));
+ requests.add(new ReportRequest(args2, l, output2.fd));
+ requests.add(new ReportRequest(args3, l, output3.fd));
+ requests.setMainFd(STDOUT_FILENO);
+
+ CaptureStdout();
+ ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
+ EXPECT_THAT(GetCapturedStdout(), StrEq("\x02\r" + STRING_FIELD_2));
+
+ string content, expect;
+ expect = STRING_FIELD_2 + FIX64_FIELD_3;
+ char c = (char) expect.size();
+
+ // output1 and output2 are the same
+ EXPECT_TRUE(ReadFileToString(output1.path, &content));
+ EXPECT_THAT(content, StrEq(string("\x02") + c + expect));
+ EXPECT_TRUE(ReadFileToString(output2.path, &content));
+ EXPECT_THAT(content, StrEq(string("\x02") + c + expect));
+
+ // because args3 doesn't set section, so it should receive nothing
+ EXPECT_TRUE(ReadFileToString(output3.path, &content));
+ EXPECT_THAT(content, StrEq(""));
} \ No newline at end of file
diff --git a/core/java/android/os/IncidentReportArgs.java b/core/java/android/os/IncidentReportArgs.java
index abb316171309..fd0ebcfea080 100644
--- a/core/java/android/os/IncidentReportArgs.java
+++ b/core/java/android/os/IncidentReportArgs.java
@@ -35,6 +35,7 @@ public final class IncidentReportArgs implements Parcelable {
private final IntArray mSections = new IntArray();
private final ArrayList<byte[]> mHeaders = new ArrayList<byte[]>();
private boolean mAll;
+ private int mDest;
/**
* Construct an incident report args with no fields.
@@ -69,6 +70,8 @@ public final class IncidentReportArgs implements Parcelable {
for (int i=0; i<N; i++) {
out.writeByteArray(mHeaders.get(i));
}
+
+ out.writeInt(mDest);
}
public void readFromParcel(Parcel in) {
@@ -85,6 +88,8 @@ public final class IncidentReportArgs implements Parcelable {
for (int i=0; i<N; i++) {
mHeaders.add(in.createByteArray());
}
+
+ mDest = in.readInt();
}
public static final Parcelable.Creator<IncidentReportArgs> CREATOR
@@ -118,7 +123,8 @@ public final class IncidentReportArgs implements Parcelable {
}
sb.append(", ");
sb.append(mHeaders.size());
- sb.append(" headers)");
+ sb.append(" headers), ");
+ sb.append("Dest enum value: ").append(mDest);
return sb.toString();
}
@@ -133,6 +139,14 @@ public final class IncidentReportArgs implements Parcelable {
}
/**
+ * Set this incident report privacy policy spec.
+ * @hide
+ */
+ public void setPrivacyPolicy(int dest) {
+ mDest = dest;
+ }
+
+ /**
* Add this section to the incident report. Skip if the input is smaller than 2 since section
* id are only valid for positive integer as Protobuf field id. Here 1 is reserved for Header.
*/
diff --git a/libs/incident/include/android/os/IncidentReportArgs.h b/libs/incident/include/android/os/IncidentReportArgs.h
index 956ef6c39b99..da8098970962 100644
--- a/libs/incident/include/android/os/IncidentReportArgs.h
+++ b/libs/incident/include/android/os/IncidentReportArgs.h
@@ -39,12 +39,13 @@ public:
virtual status_t readFromParcel(const Parcel* in);
void setAll(bool all);
+ void setDest(int dest);
void addSection(int section);
void addHeader(const vector<int8_t>& header);
- inline bool all() const { return mAll; };
+ inline bool all() const { return mAll; }
bool containsSection(int section) const;
-
+ inline int dest() const { return mDest; }
inline const set<int>& sections() const { return mSections; }
inline const vector<vector<int8_t>>& headers() const { return mHeaders; }
@@ -54,6 +55,7 @@ private:
set<int> mSections;
vector<vector<int8_t>> mHeaders;
bool mAll;
+ int mDest;
};
}
diff --git a/libs/incident/src/IncidentReportArgs.cpp b/libs/incident/src/IncidentReportArgs.cpp
index f60490911aed..e62872238387 100644
--- a/libs/incident/src/IncidentReportArgs.cpp
+++ b/libs/incident/src/IncidentReportArgs.cpp
@@ -25,14 +25,16 @@ namespace os {
IncidentReportArgs::IncidentReportArgs()
:mSections(),
- mAll(false)
+ mAll(false),
+ mDest(-1)
{
}
IncidentReportArgs::IncidentReportArgs(const IncidentReportArgs& that)
:mSections(that.mSections),
mHeaders(that.mHeaders),
- mAll(that.mAll)
+ mAll(that.mAll),
+ mDest(that.mDest)
{
}
@@ -74,6 +76,11 @@ IncidentReportArgs::writeToParcel(Parcel* out) const
}
}
+ err = out->writeInt32(mDest);
+ if (err != NO_ERROR) {
+ return err;
+ }
+
return NO_ERROR;
}
@@ -120,6 +127,13 @@ IncidentReportArgs::readFromParcel(const Parcel* in)
}
}
+ int32_t dest;
+ err = in->readInt32(&dest);
+ if (err != NO_ERROR) {
+ return err;
+ }
+ mDest = dest;
+
return OK;
}
@@ -133,6 +147,12 @@ IncidentReportArgs::setAll(bool all)
}
void
+IncidentReportArgs::setDest(int dest)
+{
+ mDest = dest;
+}
+
+void
IncidentReportArgs::addSection(int section)
{
if (!mAll) {