Merge changes from topic "am-04c3ade2997f463f99e7d6e99506ddc2" into qt-r1-dev-plus-aosp

* changes:
  Merge changes from topic "b_132890298" into qt-dev am: f581d1b92f am: d0151ddb4a
  Add command line utilites to set the reason field in incident report header am: 5dfe3dfeb8 am: 0661c595dd
  Add ProtoOutputStream.serializeToVector am: dcd64522f4 am: de7a0a3362
This commit is contained in:
Android Build Merger (Role)
2019-05-22 13:34:48 +00:00
committed by Android (Google) Code Review
6 changed files with 104 additions and 8 deletions

View File

@@ -30,7 +30,7 @@ cc_binary {
],
static_libs: [
"libplatformprotos",
"libprotoutil",
],
cflags: [

View File

@@ -21,6 +21,7 @@
#include <android/os/BnIncidentReportStatusListener.h>
#include <android/os/IIncidentManager.h>
#include <android/os/IncidentReportArgs.h>
#include <android/util/ProtoOutputStream.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <utils/Looper.h>
@@ -36,6 +37,9 @@ using namespace android;
using namespace android::base;
using namespace android::binder;
using namespace android::os;
using android::util::FIELD_COUNT_SINGLE;
using android::util::FIELD_TYPE_STRING;
using android::util::ProtoOutputStream;
// ================================================================================
class StatusListener : public BnIncidentReportStatusListener {
@@ -129,11 +133,11 @@ static void section_list(FILE* out) {
static IncidentSection const*
find_section(const char* name)
{
size_t low = 0;
size_t high = INCIDENT_SECTION_COUNT - 1;
ssize_t low = 0;
ssize_t high = INCIDENT_SECTION_COUNT - 1;
while (low <= high) {
size_t mid = (low + high) >> 1;
ssize_t mid = (low + high) / 2;
IncidentSection const* section = INCIDENT_SECTIONS + mid;
int cmp = strcmp(section->name, name);
@@ -208,6 +212,7 @@ usage(FILE* out)
fprintf(out, "and one of these destinations:\n");
fprintf(out, " -b (default) print the report to stdout (in proto format)\n");
fprintf(out, " -d send the report into dropbox\n");
fprintf(out, " -r REASON human readable description of why the report is taken.\n");
fprintf(out, " -s PKG/CLS send broadcast to the broadcast receiver.\n");
fprintf(out, "\n");
fprintf(out, " SECTION the field numbers of the incident report fields to include\n");
@@ -221,11 +226,12 @@ main(int argc, char** argv)
IncidentReportArgs args;
enum { DEST_UNSET, DEST_DROPBOX, DEST_STDOUT, DEST_BROADCAST } destination = DEST_UNSET;
int privacyPolicy = PRIVACY_POLICY_AUTOMATIC;
string reason;
string receiverArg;
// Parse the args
int opt;
while ((opt = getopt(argc, argv, "bhdlp:s:")) != -1) {
while ((opt = getopt(argc, argv, "bhdlp:r:s:")) != -1) {
switch (opt) {
case 'h':
usage(stdout);
@@ -250,6 +256,13 @@ main(int argc, char** argv)
case 'p':
privacyPolicy = get_privacy_policy(optarg);
break;
case 'r':
if (reason.size() > 0) {
usage(stderr);
return 1;
}
reason = optarg;
break;
case 's':
if (destination != DEST_UNSET) {
usage(stderr);
@@ -291,6 +304,7 @@ main(int argc, char** argv)
} else {
IncidentSection const* ic = find_section(arg);
if (ic == NULL) {
ALOGD("Invalid section: %s\n", arg);
fprintf(stderr, "Invalid section: %s\n", arg);
return 1;
}
@@ -301,6 +315,14 @@ main(int argc, char** argv)
}
args.setPrivacyPolicy(privacyPolicy);
if (reason.size() > 0) {
ProtoOutputStream proto;
proto.write(/* reason field id */ 2 | FIELD_TYPE_STRING | FIELD_COUNT_SINGLE, reason);
vector<uint8_t> header;
proto.serializeToVector(&header);
args.addHeader(header);
}
// Start the thread pool.
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();

View File

@@ -19,6 +19,7 @@
#include <cstdint>
#include <string>
#include <vector>
#include <android/util/EncodedBuffer.h>
@@ -124,6 +125,7 @@ public:
sp<ProtoReader> data(); // Get the reader apis of the data.
bool flush(int fd); // Flush data directly to a file descriptor.
bool serializeToString(std::string* out); // Serializes the proto to a string.
bool serializeToVector(std::vector<uint8_t>* out); // Serializes the proto to a vector<uint8_t>.
/**
* Clears the ProtoOutputStream so the buffer can be reused instead of deallocation/allocation again.

View File

@@ -454,7 +454,6 @@ ProtoOutputStream::serializeToString(std::string* out)
if (out == nullptr) return false;
if (!compact()) return false;
sp<ProtoReader> reader = mBuffer->read();
out->reserve(reader->size());
while (reader->hasNext()) {
@@ -465,6 +464,23 @@ ProtoOutputStream::serializeToString(std::string* out)
return true;
}
bool
ProtoOutputStream::serializeToVector(std::vector<uint8_t>* out)
{
if (out == nullptr) return false;
if (!compact()) return false;
sp<ProtoReader> reader = mBuffer->read();
out->reserve(reader->size());
while (reader->hasNext()) {
const uint8_t* buf = reader->readBuffer();
size_t size = reader->currentToRead();
out->insert(out->end(), buf, buf + size);
reader->move(size);
}
return true;
}
sp<ProtoReader>
ProtoOutputStream::data()
{

View File

@@ -132,6 +132,53 @@ TEST(ProtoOutputStreamTest, SerializeToStringPrimitives) {
EXPECT_EQ(primitives.val_enum(), PrimitiveProto_Count_TWO);
}
TEST(ProtoOutputStreamTest, SerializeToVectorPrimitives) {
std::string s = "hello";
const char b[5] = { 'a', 'p', 'p', 'l', 'e' };
ProtoOutputStream proto;
EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | PrimitiveProto::kValInt32FieldNumber, 123));
EXPECT_TRUE(proto.write(FIELD_TYPE_INT64 | PrimitiveProto::kValInt64FieldNumber, -1LL));
EXPECT_TRUE(proto.write(FIELD_TYPE_FLOAT | PrimitiveProto::kValFloatFieldNumber, -23.5f));
EXPECT_TRUE(proto.write(FIELD_TYPE_DOUBLE | PrimitiveProto::kValDoubleFieldNumber, 324.5));
EXPECT_TRUE(proto.write(FIELD_TYPE_UINT32 | PrimitiveProto::kValUint32FieldNumber, 3424));
EXPECT_TRUE(proto.write(FIELD_TYPE_UINT64 | PrimitiveProto::kValUint64FieldNumber, 57LL));
EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED32 | PrimitiveProto::kValFixed32FieldNumber, -20));
EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED64 | PrimitiveProto::kValFixed64FieldNumber, -37LL));
EXPECT_TRUE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, true));
EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | PrimitiveProto::kValStringFieldNumber, s));
EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | PrimitiveProto::kValBytesFieldNumber, b, 5));
EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED32 | PrimitiveProto::kValSfixed32FieldNumber, 63));
EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED64 | PrimitiveProto::kValSfixed64FieldNumber, -54));
EXPECT_TRUE(proto.write(FIELD_TYPE_SINT32 | PrimitiveProto::kValSint32FieldNumber, -533));
EXPECT_TRUE(proto.write(FIELD_TYPE_SINT64 | PrimitiveProto::kValSint64FieldNumber, -61224762453LL));
EXPECT_TRUE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 2));
PrimitiveProto primitives;
std::vector<uint8_t> vec;
ASSERT_TRUE(proto.serializeToVector(&vec));
std::string serialized(vec.data(), vec.data() + vec.size());
ASSERT_TRUE(primitives.ParseFromString(serialized));
EXPECT_EQ(primitives.val_int32(), 123);
EXPECT_EQ(primitives.val_int64(), -1);
EXPECT_EQ(primitives.val_float(), -23.5f);
EXPECT_EQ(primitives.val_double(), 324.5f);
EXPECT_EQ(primitives.val_uint32(), 3424);
EXPECT_EQ(primitives.val_uint64(), 57);
EXPECT_EQ(primitives.val_fixed32(), -20);
EXPECT_EQ(primitives.val_fixed64(), -37);
EXPECT_EQ(primitives.val_bool(), true);
EXPECT_THAT(primitives.val_string(), StrEq(s.c_str()));
EXPECT_THAT(primitives.val_bytes(), StrEq("apple"));
EXPECT_EQ(primitives.val_sfixed32(), 63);
EXPECT_EQ(primitives.val_sfixed64(), -54);
EXPECT_EQ(primitives.val_sint32(), -533);
EXPECT_EQ(primitives.val_sint64(), -61224762453LL);
EXPECT_EQ(primitives.val_enum(), PrimitiveProto_Count_TWO);
}
TEST(ProtoOutputStreamTest, Complex) {
std::string name1 = "cat";
std::string name2 = "dog";

View File

@@ -292,6 +292,7 @@ usage(FILE* out)
fprintf(out, "Take an incident report over adb (which must be in the PATH).\n");
fprintf(out, " -b output the incident report raw protobuf format\n");
fprintf(out, " -o OUTPUT the output file. OUTPUT may be '-' or omitted to use stdout\n");
fprintf(out, " -r REASON human readable description of why the report is taken.\n");
fprintf(out, " -s SERIAL sent to adb to choose which device, instead of $ANDROID_SERIAL\n");
fprintf(out, " -t output the incident report in pretty-printed text format\n");
fprintf(out, "\n");
@@ -307,13 +308,14 @@ main(int argc, char** argv)
enum { OUTPUT_TEXT, OUTPUT_PROTO } outputFormat = OUTPUT_TEXT;
const char* inFilename = NULL;
const char* outFilename = NULL;
const char* reason = NULL;
const char* adbSerial = NULL;
pid_t childPid = -1;
vector<string> sections;
const char* privacy = NULL;
int opt;
while ((opt = getopt(argc, argv, "bhi:o:s:twp:")) != -1) {
while ((opt = getopt(argc, argv, "bhi:o:r:s:twp:")) != -1) {
switch (opt) {
case 'b':
outputFormat = OUTPUT_PROTO;
@@ -324,6 +326,9 @@ main(int argc, char** argv)
case 'o':
outFilename = optarg;
break;
case 'r':
reason = optarg;
break;
case 's':
adbSerial = optarg;
break;
@@ -376,7 +381,7 @@ main(int argc, char** argv)
dup2(pfd[1], STDOUT_FILENO);
close(pfd[0]);
close(pfd[1]);
char const** args = (char const**)malloc(sizeof(char*) * (8 + sections.size()));
char const** args = (char const**)malloc(sizeof(char*) * (10 + sections.size()));
int argpos = 0;
args[argpos++] = "adb";
if (adbSerial != NULL) {
@@ -389,6 +394,10 @@ main(int argc, char** argv)
args[argpos++] = "-p";
args[argpos++] = privacy;
}
if (reason != NULL) {
args[argpos++] = "-r";
args[argpos++] = reason;
}
for (vector<string>::const_iterator it=sections.begin(); it!=sections.end(); it++) {
args[argpos++] = it->c_str();
}