• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "clearcutserializer.h"
18 
19 #include "tuningfork/protobuf_nano_util.h"
20 #include "nano/tuningfork_clearcut_log.pb.h"
21 
22 namespace tuningfork {
23 
writeCountArray(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)24 bool ClearcutSerializer::writeCountArray(pb_ostream_t *stream, const pb_field_t *field,
25                                        void *const *arg) {
26     const Histogram* h = static_cast<Histogram*>(*arg);
27     if(!pb_encode_tag(stream, PB_WT_STRING, logs_proto_tuningfork_TuningForkHistogram_counts_tag))
28         return false;
29     // Get the length of the data
30     pb_ostream_t sizing_stream = PB_OSTREAM_SIZING;
31     for (int i = 0; i < h->num_buckets_; ++i)
32         pb_encode_varint(&sizing_stream, h->buckets_[i]);
33     // Encode the length of the packed array in bytes
34     if (!pb_encode_varint(stream, sizing_stream.bytes_written))
35         return false;
36     // Encode each item, without the type, since it's packed
37     for (int i = 0; i < h->num_buckets_; ++i) {
38         if(!pb_encode_varint(stream, h->buckets_[i]))
39             return false;
40     }
41     return true;
42 }
writeCpuFreqs(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)43 bool ClearcutSerializer::writeCpuFreqs(pb_ostream_t *stream, const pb_field_t *field,
44                                          void *const *arg) {
45     std::vector<uint64_t>* v = static_cast<std::vector<uint64_t>*>(*arg);
46     // Encode each item
47     for (int i = 0; i < v->size(); ++i) {
48         pb_encode_tag_for_field(stream, field);
49         pb_encode_varint(stream, (*v)[i]);
50     }
51     return true;
52 }
53 
Fill(const Histogram & h,ClearcutHistogram & ch)54 void ClearcutSerializer::Fill(const Histogram& h, ClearcutHistogram& ch) {
55      ch.counts.funcs.encode = writeCountArray;
56      ch.counts.arg = (void*)(&h);
57 }
58 
writeAnnotation(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)59 bool ClearcutSerializer::writeAnnotation(pb_ostream_t* stream, const pb_field_t *field,
60                                          void *const *arg) {
61     const Prong* p = static_cast<const Prong*>(*arg);
62     if(p->annotation_.size()>0) {
63         pb_encode_tag_for_field(stream, field);
64         pb_encode_string(stream, &p->annotation_[0], p->annotation_.size());
65     }
66     return true;
67 }
Fill(const Prong & p,ClearcutHistogram & h)68 void ClearcutSerializer::Fill(const Prong& p, ClearcutHistogram& h) {
69     h.has_instrument_id = true;
70     h.instrument_id = p.instrumentation_key_;
71     h.annotation.funcs.encode = writeAnnotation;
72     h.annotation.arg = (void*)(&p);
73     Fill(p.histogram_, h);
74 }
Fill(const ExtraUploadInfo & tdi,DeviceInfo & di)75 void ClearcutSerializer::Fill(const ExtraUploadInfo& tdi, DeviceInfo& di) {
76     di.has_total_memory_bytes = true;
77     di.total_memory_bytes = tdi.total_memory_bytes;
78     di.has_gl_es_version = true;
79     di.gl_es_version = tdi.gl_es_version;
80     di.build_fingerprint.funcs.encode = writeString;
81     di.build_fingerprint.arg = (void*)&tdi.build_fingerprint;
82     di.build_version_sdk.funcs.encode = writeString;
83     di.build_version_sdk.arg = (void*)&tdi.build_version_sdk;
84     di.cpu_max_freq_hz.funcs.encode = writeCpuFreqs;
85     di.cpu_max_freq_hz.arg = (void*)&tdi.cpu_max_freq_hz;
86 }
writeHistograms(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)87 bool ClearcutSerializer::writeHistograms(pb_ostream_t* stream, const pb_field_t *field,
88                                          void *const *arg) {
89     const ProngCache* pc =static_cast<const ProngCache*>(*arg);
90     for (auto &p: pc->prongs_) {
91         if (p->histogram_.Count() > 0) {
92             ClearcutHistogram h;
93             Fill(*p, h);
94             pb_encode_tag_for_field(stream, field);
95             // Get size, then fill object
96             pb_ostream_t sizing_stream = PB_OSTREAM_SIZING;
97             pb_encode(&sizing_stream, logs_proto_tuningfork_TuningForkHistogram_fields, &h);
98             pb_encode_varint(stream, sizing_stream.bytes_written);
99             pb_encode(stream, logs_proto_tuningfork_TuningForkHistogram_fields, &h);
100         }
101     }
102     return true;
103 }
writeDeviceInfo(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)104 bool ClearcutSerializer::writeDeviceInfo(pb_ostream_t* stream, const pb_field_t *field,
105                                          void *const *arg) {
106     const ExtraUploadInfo* tdi =static_cast<const ExtraUploadInfo*>(*arg);
107     DeviceInfo di;
108     Fill(*tdi, di);
109     pb_encode_tag_for_field(stream, field);
110     // Get size, then fill object
111     pb_ostream_t sizing_stream = PB_OSTREAM_SIZING;
112     pb_encode(&sizing_stream, logs_proto_tuningfork_DeviceInfo_fields, &di);
113     pb_encode_varint(stream, sizing_stream.bytes_written);
114     pb_encode(stream, logs_proto_tuningfork_DeviceInfo_fields, &di);
115     return true;
116 }
117 
writeString(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)118 bool ClearcutSerializer::writeString(pb_ostream_t* stream, const pb_field_t *field,
119                                            void *const *arg) {
120 
121     const std::string* str = static_cast<std::string*>(*arg);
122     if(!pb_encode_tag_for_field(stream, field)) return false;
123     return pb_encode_string(stream, (uint8_t*) str->data(), str->size());
124 }
125 
FillExtras(const ExtraUploadInfo & info,TuningForkLogEvent & evt)126 void ClearcutSerializer::FillExtras(const ExtraUploadInfo& info,
127                                     TuningForkLogEvent& evt) {
128     evt.experiment_id.funcs.encode = writeString;
129     evt.experiment_id.arg = (void*)&info.experiment_id;
130     evt.session_id.funcs.encode = writeString;
131     evt.session_id.arg = (void*)&info.session_id;
132     evt.apk_package_name.funcs.encode = writeString;
133     evt.apk_package_name.arg = (void*)&info.apk_package_name;
134     evt.has_apk_version_code = true;
135     evt.apk_version_code = info.apk_version_code;
136     evt.has_tuningfork_version = true;
137     evt.tuningfork_version = info.tuningfork_version;
138 }
139 
FillHistograms(const ProngCache & pc,TuningForkLogEvent & evt)140 void ClearcutSerializer::FillHistograms(const ProngCache& pc, TuningForkLogEvent &evt) {
141     evt.histograms.funcs.encode = writeHistograms;
142     evt.histograms.arg = (void*)&pc;
143 }
144 
writeFidelityParams(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)145 bool ClearcutSerializer::writeFidelityParams(pb_ostream_t* stream, const pb_field_t *field,
146                                              void *const *arg) {
147     const ProtobufSerialization* fp = static_cast<const ProtobufSerialization*>(*arg);
148     if(fp->size()>0) {
149         pb_encode_tag_for_field(stream, field);
150         pb_encode_string(stream, &(*fp)[0], fp->size());
151     }
152     return true;
153 }
SerializeEvent(const ProngCache & pc,const ProtobufSerialization & fidelity_params,const ExtraUploadInfo & device_info,ProtobufSerialization & evt_ser)154 void ClearcutSerializer::SerializeEvent(const ProngCache& pc,
155                                         const ProtobufSerialization& fidelity_params,
156                                         const ExtraUploadInfo& device_info,
157                                         ProtobufSerialization& evt_ser) {
158     TuningForkLogEvent evt = logs_proto_tuningfork_TuningForkLogEvent_init_default;
159     evt.fidelityparams.funcs.encode = writeFidelityParams;
160     evt.fidelityparams.arg = (void*)&fidelity_params;
161     FillHistograms(pc,evt);
162     evt.has_device_info = true;
163     Fill(device_info, evt.device_info);
164     FillExtras(device_info, evt);
165     VectorStream str {&evt_ser, 0};
166     pb_ostream_t stream = {VectorStream::Write, &str, SIZE_MAX, 0};
167     pb_encode(&stream, logs_proto_tuningfork_TuningForkLogEvent_fields, &evt);
168 }
169 
170 } // namespace tuningfork
171