• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 #include "VtsProfilingInterface.h"
17 
18 #include <cutils/properties.h>
19 #include <fstream>
20 #include <string>
21 
22 #include <android-base/logging.h>
23 #include <google/protobuf/text_format.h>
24 
25 #include "test/vts/proto/VtsDriverControlMessage.pb.h"
26 #include "test/vts/proto/VtsProfilingMessage.pb.h"
27 
28 using namespace std;
29 
30 namespace android {
31 namespace vts {
32 
33 const int VtsProfilingInterface::kProfilingPointEntry = 1;
34 const int VtsProfilingInterface::kProfilingPointCallback = 2;
35 const int VtsProfilingInterface::kProfilingPointExit = 3;
36 
VtsProfilingInterface(const string & trace_file_path)37 VtsProfilingInterface::VtsProfilingInterface(const string& trace_file_path)
38     : trace_file_path_(trace_file_path),
39       trace_output_(nullptr),
40       initialized_(false) {
41 }
42 
~VtsProfilingInterface()43 VtsProfilingInterface::~VtsProfilingInterface() {
44   if (trace_output_) {
45     trace_output_.close();
46   }
47 }
48 
NanoTime()49 static int64_t NanoTime() {
50   std::chrono::nanoseconds duration(
51       std::chrono::steady_clock::now().time_since_epoch());
52   return static_cast<int64_t>(duration.count());
53 }
54 
getInstance(const string & trace_file_path)55 VtsProfilingInterface& VtsProfilingInterface::getInstance(
56     const string& trace_file_path) {
57   static VtsProfilingInterface instance(trace_file_path);
58   return instance;
59 }
60 
Init()61 void VtsProfilingInterface::Init() {
62   if (initialized_) return;
63 
64   // Attach device info and timestamp for the trace file.
65   char build_number[PROPERTY_VALUE_MAX];
66   char device_id[PROPERTY_VALUE_MAX];
67   char product_name[PROPERTY_VALUE_MAX];
68   property_get("ro.build.version.incremental", build_number, "unknown_build");
69   property_get("ro.serialno", device_id, "unknown_device");
70   property_get("ro.build.product", product_name, "unknown_product");
71 
72   string file_path = trace_file_path_ + "_" + string(product_name) + "_"
73       + string(device_id) + "_" + string(build_number) + "_"
74       + to_string(NanoTime()) + ".vts.trace";
75 
76   LOG(INFO) << "Creating new profiler instance with file path: " << file_path;
77   trace_output_ = std::ofstream(file_path, std::fstream::out);
78   if (!trace_output_) {
79     LOG(ERROR) << "Can not open trace file: " << file_path << ": "
80                << std::strerror(errno);
81     initialized_ = false;
82     return;
83   }
84   initialized_ = true;
85 }
86 
AddTraceEvent(android::hardware::details::HidlInstrumentor::InstrumentationEvent event,const char * package,const char * version,const char * interface,const FunctionSpecificationMessage & message)87 bool VtsProfilingInterface::AddTraceEvent(
88     android::hardware::details::HidlInstrumentor::InstrumentationEvent event,
89     const char* package, const char* version, const char* interface,
90     const FunctionSpecificationMessage& message) {
91   if (!initialized_) {
92     LOG(ERROR) << "Profiler not initialized. ";
93     return false;
94   }
95   if (stop_trace_recording_)
96     return true;
97 
98   // Build the VTSProfilingRecord and print it to string.
99   VtsProfilingRecord record;
100   record.set_timestamp(NanoTime());
101   record.set_event((InstrumentationEventType)static_cast<int>(event));
102   record.set_package(package);
103   record.set_version(stof(version));
104   record.set_interface(interface);
105   *record.mutable_func_msg() = message;
106   string record_str;
107   if (!google::protobuf::TextFormat::PrintToString(record, &record_str)) {
108     LOG(ERROR) << "Can't print the message";
109     return false;
110   }
111 
112   // Write the record string to trace file.
113   mutex_.lock();
114   if ((static_cast<std::string::size_type>(trace_output_.tellp())
115        + record_str.size()) > kTraceFileSizeLimit
116       && (static_cast<std::string::size_type>(trace_output_.tellp())
117           + record_str.size()) >= record_str.size()) {
118     LOG(WARNING) << "Trace file too big, stop recording the trace";
119     trace_output_.close();
120     stop_trace_recording_ = true;
121   }
122   if (!stop_trace_recording_) {
123     trace_output_ << record_str << "\n";
124     trace_output_.flush();
125   }
126   mutex_.unlock();
127 
128   return true;
129 }
130 
131 }  // namespace vts
132 }  // namespace android
133