Merge changes from topic "am-04c3ade2997f463f99e7d6e99506ddc2" into qt-r1-dev-plus-aosp
* changes: Merge changes from topic "b_132890298" into qt-dev am:f581d1b92fam:d0151ddb4aAdd command line utilites to set the reason field in incident report header am:5dfe3dfeb8am:0661c595ddAdd ProtoOutputStream.serializeToVector am:dcd64522f4am:de7a0a3362
This commit is contained in:
committed by
Android (Google) Code Review
commit
8b584bda41
@@ -30,7 +30,7 @@ cc_binary {
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
"libplatformprotos",
|
||||
"libprotoutil",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user