11754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato/* 21754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Copyright (C) 2016 The Android Open Source Project 31754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * 41754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 51754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * you may not use this file except in compliance with the License. 61754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * You may obtain a copy of the License at 71754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * 81754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * http://www.apache.org/licenses/LICENSE-2.0 91754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * 101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Unless required by applicable law or agreed to in writing, software 111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * See the License for the specific language governing permissions and 141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * limitations under the License. 151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato */ 161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "generic_message.h" 181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "printer.h" 191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 207669012623a18855913c84ec0690066fbfd823eaJoe Onorato#include <frameworks/base/core/proto/android/os/incident.pb.h> 211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <google/protobuf/wire_format.h> 221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <google/protobuf/io/coded_stream.h> 231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <google/protobuf/io/zero_copy_stream_impl.h> 241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <sys/types.h> 261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <sys/stat.h> 271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <sys/wait.h> 281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <errno.h> 291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <fcntl.h> 301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <stdio.h> 311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <string.h> 321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <unistd.h> 331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratousing namespace android::os; 351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratousing namespace google::protobuf; 361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratousing namespace google::protobuf::io; 371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratousing namespace google::protobuf::internal; 381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic bool read_message(CodedInputStream* in, Descriptor const* descriptor, 401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato GenericMessage* message); 411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic void print_message(Out* out, Descriptor const* descriptor, GenericMessage const* message); 421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================ 441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic bool 451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoread_length_delimited(CodedInputStream* in, uint32 fieldId, Descriptor const* descriptor, 461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato GenericMessage* message) 471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint32 size; 491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (!in->ReadVarint32(&size)) { 501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return false; 511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato FieldDescriptor const* field = descriptor->FindFieldByNumber(fieldId); 541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (field != NULL) { 551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int type = field->type(); 561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (type == FieldDescriptor::TYPE_MESSAGE) { 571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato GenericMessage* child = message->addMessage(fieldId); 581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato CodedInputStream::Limit limit = in->PushLimit(size); 601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato bool rv = read_message(in, field->message_type(), child); 611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato in->PopLimit(limit); 621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return rv; 631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else if (type == FieldDescriptor::TYPE_STRING) { 641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // TODO: do a version of readstring that just pumps the data 651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // rather than allocating a string which we don't care about. 661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato string str; 671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (in->ReadString(&str, size)) { 681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato message->addString(fieldId, str); 691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return true; 701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return false; 721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else if (type == FieldDescriptor::TYPE_BYTES) { 741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // TODO: Save bytes field. 751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return in->Skip(size); 761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return in->Skip(size); 791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================ 821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic bool 831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoread_message(CodedInputStream* in, Descriptor const* descriptor, GenericMessage* message) 841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint32 value32; 861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint64 value64; 871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato while (true) { 891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint32 tag = in->ReadTag(); 901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (tag == 0) { 911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return true; 921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int fieldId = WireFormatLite::GetTagFieldNumber(tag); 941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato switch (WireFormatLite::GetTagWireType(tag)) { 951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case WireFormatLite::WIRETYPE_VARINT: 961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (in->ReadVarint64(&value64)) { 971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato message->addInt64(fieldId, value64); 981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 1001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return false; 1011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case WireFormatLite::WIRETYPE_FIXED64: 1031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (in->ReadLittleEndian64(&value64)) { 1041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato message->addInt64(fieldId, value64); 1051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 1071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return false; 1081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: 1101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (!read_length_delimited(in, fieldId, descriptor, message)) { 1111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return false; 1121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case WireFormatLite::WIRETYPE_FIXED32: 1151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (in->ReadLittleEndian32(&value32)) { 1161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato message->addInt32(fieldId, value32); 1171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 1191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return false; 1201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato default: 1221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "bad tag: 0x%x (%d) at index %d\n", tag, tag, 1231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato in->CurrentPosition()); 1241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return false; 1251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 1281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================ 1301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic void 1311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoprint_value(Out* out, FieldDescriptor const* field, GenericMessage::Node const& node) 1321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 1331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint32_t val32; 1341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato FieldDescriptor::Type type = field->type(); 1351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato switch (node.type) { 1371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case GenericMessage::TYPE_VALUE32: 1381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato switch (type) { 1391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_FIXED32: 1401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%u", node.value32); 1411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_SFIXED32: 1431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%d", node.value32); 1441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_FLOAT: 1461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%f", *(float*)&node.value32); 1471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato default: 1491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("(unexpected value %d (0x%x)", node.value32, node.value32); 1501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case GenericMessage::TYPE_VALUE64: 1541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato switch (type) { 1551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_FIXED64: 1561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_SFIXED64: 1571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_DOUBLE: 1581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%f", *(double*)&node.value64); 1591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_SINT32: 1611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_INT32: 1621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato val32 = (uint32_t)node.value32; 1631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%d", val32); 1641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_INT64: 1661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_UINT32: 1671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato val32 = (uint32_t)node.value32; 1681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%u", val32); 1691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_UINT64: 1711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_SINT64: 1721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_BOOL: 1731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (node.value64) { 1741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("true"); 1751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 1761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("false"); 1771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_ENUM: 1801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato default: 1811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("(unexpected value %ld (0x%x))", node.value64, node.value64); 1821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case GenericMessage::TYPE_MESSAGE: 1861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato print_message(out, field->message_type(), node.message); 1871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case GenericMessage::TYPE_STRING: 1891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // TODO: custom format for multi-line strings. 1901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%s", node.str->c_str()); 1911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case GenericMessage::TYPE_DATA: 1931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("<bytes>"); 1941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 1971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic void 1991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoprint_message(Out* out, Descriptor const* descriptor, GenericMessage const* message) 2001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 2011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%s {\n", descriptor->name().c_str()); 2021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->indent(); 2031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int const N = descriptor->field_count(); 2051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (int i=0; i<N; i++) { 2061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato FieldDescriptor const* field = descriptor->field(i); 2071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int fieldId = field->number(); 2091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato bool repeated = field->label() == FieldDescriptor::LABEL_REPEATED; 2101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato FieldDescriptor::Type type = field->type(); 2111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato GenericMessage::const_iterator_pair it = message->find(fieldId); 2121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%s=", field->name().c_str()); 2141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (repeated) { 2151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (it.first != it.second) { 2161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("["); 2171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (type == FieldDescriptor::TYPE_MESSAGE 2181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato || type == FieldDescriptor::TYPE_STRING 2191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato || type == FieldDescriptor::TYPE_BYTES) { 2201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("\n"); 2211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->indent(); 2231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (GenericMessage::const_iterator_pair it = message->find(fieldId); 2251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato it.first != it.second; it.first++) { 2261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato print_value(out, field, it.first->second); 2271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (type == FieldDescriptor::TYPE_MESSAGE 2281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato || type == FieldDescriptor::TYPE_STRING 2291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato || type == FieldDescriptor::TYPE_BYTES) { 2301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("\n"); 2311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->dedent(); 2351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("]"); 2361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 2371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("[]"); 2381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 2401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (it.first != it.second) { 2411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato print_value(out, field, it.first->second); 2421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 2431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato switch (type) { 2441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_BOOL: 2451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("false"); 2461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 2471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_STRING: 2481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_MESSAGE: 2491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf(""); 2501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 2511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case FieldDescriptor::TYPE_ENUM: 2521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("%s", field->default_value_enum()->name().c_str()); 2531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 2541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato default: 2551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("0"); 2561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 2571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("\n"); 2611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->dedent(); 2631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out->printf("}"); 2641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 2651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================ 2671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic uint8_t* 2681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratowrite_raw_varint(uint8_t* buf, uint32_t val) 2691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 2701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint8_t* p = buf; 2711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato while (true) { 2721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if ((val & ~0x7F) == 0) { 2731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *p++ = (uint8_t)val; 2741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return p; 2751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 2761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *p++ = (uint8_t)((val & 0x7F) | 0x80); 2771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato val >>= 7; 2781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 2811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic int 2831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratowrite_all(int fd, uint8_t const* buf, size_t size) 2841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 2851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato while (size > 0) { 2861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ssize_t amt = ::write(fd, buf, size); 2871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (amt < 0) { 2881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return errno; 2891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato size -= amt; 2911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato buf += amt; 2921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 0; 2941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 2951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic int 2971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoadb_incident_workaround(const char* adbSerial, const vector<string>& sections) 2981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 2991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato const int maxAllowedSize = 20 * 1024 * 1024; // 20MB 3001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint8_t* buffer = (uint8_t*)malloc(maxAllowedSize); 3011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (vector<string>::const_iterator it=sections.begin(); it!=sections.end(); it++) { 3031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato Descriptor const* descriptor = IncidentProto::descriptor(); 3041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato FieldDescriptor const* field; 3051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Get the name and field id. 3071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato string name = *it; 3081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato char* end; 3091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int id = strtol(name.c_str(), &end, 0); 3101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (*end == '\0') { 3111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // If it's an id, find out the string. 3121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato field = descriptor->FindFieldByNumber(id); 3131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (field == NULL) { 3141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "Unable to find field number: %d\n", id); 3151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 3161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato name = field->name(); 3181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 3191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // If it's a string, find out the id. 3201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato field = descriptor->FindFieldByName(name); 3211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (field == NULL) { 3221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "Unable to find field: %s\n", name.c_str()); 3231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 3241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato id = field->number(); 3261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int pfd[2]; 3291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (pipe(pfd) != 0) { 3301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "pipe failed: %s\n", strerror(errno)); 3311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 3321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato pid_t pid = fork(); 3351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (pid == -1) { 3361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "fork failed: %s\n", strerror(errno)); 3371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 3381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else if (pid == 0) { 3391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // child 3401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato dup2(pfd[1], STDOUT_FILENO); 3411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato close(pfd[0]); 3421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato close(pfd[1]); 3431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato char const** args = (char const**)malloc(sizeof(char*) * 8); 3451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int argpos = 0; 3461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = "adb"; 3471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (adbSerial != NULL) { 3481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = "-s"; 3491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = adbSerial; 3501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = "shell"; 3521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = "dumpsys"; 3531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = name.c_str(); 3541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = "--proto"; 3551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = NULL; 3561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato execvp(args[0], (char*const*)args); 3571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "execvp failed: %s\n", strerror(errno)); 35889547ce0178d5b5b66badc5a422cdbecc9ddac34Yunlian Jiang free(args); 3591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 3601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 3611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // parent 3621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato close(pfd[1]); 3631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato size_t size = 0; 3651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato while (size < maxAllowedSize) { 3661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ssize_t amt = read(pfd[0], buffer + size, maxAllowedSize - size); 3671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (amt == 0) { 3681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 3691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else if (amt == -1) { 3701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "read error: %s\n", strerror(errno)); 3711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 3721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato size += amt; 3741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int status; 3771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato do { 3781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato waitpid(pid, &status, 0); 3791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } while (!WIFEXITED(status)); 3801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (WEXITSTATUS(status) != 0) { 3811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return WEXITSTATUS(status); 3821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (size > 0) { 3851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint8_t header[20]; 3861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint8_t* p = write_raw_varint(header, (id << 3) | 2); 3871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato p = write_raw_varint(p, size); 3881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int err = write_all(STDOUT_FILENO, header, p-header); 3891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (err != 0) { 3901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "write error: %s\n", strerror(err)); 3911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 3921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato err = write_all(STDOUT_FILENO, buffer, size); 3941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (err != 0) { 3951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "write error: %s\n", strerror(err)); 3961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 3971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 4001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato close(pfd[0]); 4011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 4021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 4031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 40489547ce0178d5b5b66badc5a422cdbecc9ddac34Yunlian Jiang free(buffer); 4051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 0; 4061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 4071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 4081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================ 4091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic void 4101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratousage(FILE* out) 4111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 4121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "usage: incident_report -i INPUT [-o OUTPUT]\n"); 4131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "\n"); 4141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "Pretty-prints an incident report protobuf file.\n"); 4151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, " -i INPUT the input file. INPUT may be '-' to use stdin\n"); 4161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, " -o OUTPUT the output file. OUTPUT may be '-' or omitted to use stdout\n"); 4171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "\n"); 4181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "\n"); 4191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "usage: incident_report [-o OUTPUT] [-t|b] [-s SERIAL] [SECTION...]\n"); 4201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "\n"); 4211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "Take an incident report over adb (which must be in the PATH).\n"); 4221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, " -b output the incident report raw protobuf format\n"); 4231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, " -o OUTPUT the output file. OUTPUT may be '-' or omitted to use stdout\n"); 4241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, " -s SERIAL sent to adb to choose which device, instead of $ANDROID_SERIAL\n"); 4251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, " -t output the incident report in pretty-printed text format\n"); 4261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "\n"); 4271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, " SECTION which bugreport sections to print, either the int code of the\n"); 4281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, " section in the Incident proto or the field name. If ommited,\n"); 4291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, " the report will contain all fields\n"); 4301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(out, "\n"); 4311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 4321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 4331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoint 4341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratomain(int argc, char** argv) 4351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 4361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato enum { OUTPUT_TEXT, OUTPUT_PROTO } outputFormat = OUTPUT_TEXT; 4371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato const char* inFilename = NULL; 4381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato const char* outFilename = NULL; 4391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato const char* adbSerial = NULL; 4401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato bool adbIncidentWorkaround = true; 4411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato pid_t childPid = -1; 4421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato vector<string> sections; 4431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 4441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int opt; 4451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato while ((opt = getopt(argc, argv, "bhi:o:s:tw")) != -1) { 4461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato switch (opt) { 4471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case 'b': 4481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato outputFormat = OUTPUT_PROTO; 4491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 4501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case 'i': 4511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato inFilename = optarg; 4521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 4531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case 'o': 4541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato outFilename = optarg; 4551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 4561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case 's': 4571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato adbSerial = optarg; 4581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 4591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case 't': 4601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato outputFormat = OUTPUT_TEXT; 4611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 4621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case 'h': 4631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato usage(stdout); 4641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 0; 4651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato case 'w': 4661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato adbIncidentWorkaround = false; 4671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 4681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato default: 4691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato usage(stderr); 4701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 4711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 4721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 4731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 4741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato while (optind < argc) { 4751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato sections.push_back(argv[optind++]); 4761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 4771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 4781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int inFd; 4791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (inFilename != NULL) { 4801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // translate-only mode - oepn the file or use stdin. 4811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (strcmp("-", inFilename) == 0) { 4821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato inFd = STDIN_FILENO; 4831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 4841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato inFd = open(inFilename, O_RDONLY | O_CLOEXEC); 4851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (inFd < 0) { 4861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "unable to open file for read (%s): %s\n", strerror(errno), 4871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato inFilename); 4881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 4891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 4901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 4911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 4921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // pipe mode - run adb shell incident ... 4931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int pfd[2]; 4941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (pipe(pfd) != 0) { 4951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "pipe failed: %s\n", strerror(errno)); 4961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 4971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 4981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 4991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato childPid = fork(); 5001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (childPid == -1) { 5011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "fork failed: %s\n", strerror(errno)); 5021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 5031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else if (childPid == 0) { 5041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato dup2(pfd[1], STDOUT_FILENO); 5051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato close(pfd[0]); 5061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato close(pfd[1]); 5071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // child 5081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (adbIncidentWorkaround) { 5091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // TODO: Until the device side incident command is checked in, 5101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // the incident_report builds the outer Incident proto by hand 5111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // from individual adb shell dumpsys <service> --proto calls, 5121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // with a maximum allowed output size. 5131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return adb_incident_workaround(adbSerial, sections); 5141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 5161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // TODO: This is what the real implementation will be... 5171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato char const** args = (char const**)malloc(sizeof(char*) * (6 + sections.size())); 5181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int argpos = 0; 5191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = "adb"; 5201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (adbSerial != NULL) { 5211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = "-s"; 5221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = adbSerial; 5231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = "shell"; 5251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = "incident"; 5261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (vector<string>::const_iterator it=sections.begin(); it!=sections.end(); it++) { 5271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = it->c_str(); 5281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato args[argpos++] = NULL; 5301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato execvp(args[0], (char*const*)args); 5311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "execvp failed: %s\n", strerror(errno)); 5321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 0; 5331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 5341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // parent 5351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato inFd = pfd[0]; 5361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato close(pfd[1]); 5371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 5401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int outFd; 5411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (outFilename == NULL || strcmp("-", outFilename) == 0) { 5421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato outFd = STDOUT_FILENO; 5431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 5441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato outFd = open(outFilename, O_CREAT | O_RDWR, 0666); 5451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (outFd < 0) { 5461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "unable to open file for write: %s\n", outFilename); 5471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 5481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 5511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato GenericMessage message; 5521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 5531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato Descriptor const* descriptor = IncidentProto::descriptor(); 5541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato FileInputStream infile(inFd); 5551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato CodedInputStream in(&infile); 5561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 5571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (!read_message(&in, descriptor, &message)) { 5581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fprintf(stderr, "unable to read incident\n"); 5591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 1; 5601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 5621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato Out out(outFd); 5631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 5641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato print_message(&out, descriptor, &message); 5651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato out.printf("\n"); 5661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 5671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (childPid != -1) { 5681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int status; 5691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato do { 5701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato waitpid(childPid, &status, 0); 5711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } while (!WIFEXITED(status)); 5721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (WEXITSTATUS(status) != 0) { 5731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return WEXITSTATUS(status); 5741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 5761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 5771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return 0; 5781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 579