1 // Copyright 2012 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "include/interpreter.h"
6
7 #include <cxxabi.h>
8 #include <string>
9
10 #include <json/value.h>
11 #include <json/writer.h>
12
13 #include "include/activity_log.h"
14 #include "include/finger_metrics.h"
15 #include "include/gestures.h"
16 #include "include/logging.h"
17 #include "include/tracer.h"
18
19 using std::string;
20
21 namespace gestures {
22
23 using EventDebug = ActivityLog::EventDebug;
24
Interpreter(PropRegistry * prop_reg,Tracer * tracer,bool force_log_creation)25 Interpreter::Interpreter(PropRegistry* prop_reg,
26 Tracer* tracer,
27 bool force_log_creation)
28 : requires_metrics_(false),
29 initialized_(false),
30 name_(nullptr),
31 tracer_(tracer) {
32 #ifdef DEEP_LOGS
33 bool logging_enabled = true;
34 #else
35 bool logging_enabled = force_log_creation;
36 #endif
37 if (logging_enabled)
38 log_.reset(new ActivityLog(prop_reg));
39 }
40
~Interpreter()41 Interpreter::~Interpreter() {
42 if (name_)
43 free(const_cast<char*>(name_));
44 }
45
Trace(const char * message,const char * name)46 void Interpreter::Trace(const char* message, const char* name) {
47 if (tracer_)
48 tracer_->Trace(message, name);
49 }
50
SyncInterpret(HardwareState & hwstate,stime_t * timeout)51 void Interpreter::SyncInterpret(HardwareState& hwstate,
52 stime_t* timeout) {
53 AssertWithReturn(initialized_);
54 if (EventLoggingIsEnabled()) {
55 Trace("log: start: ", "LogHardwareState");
56 log_->LogHardwareState(hwstate);
57 Trace("log: end: ", "LogHardwareState");
58 }
59 if (own_metrics_)
60 own_metrics_->Update(hwstate);
61
62 Trace("SyncInterpret: start: ", name());
63 SyncInterpretImpl(hwstate, timeout);
64 Trace("SyncInterpret: end: ", name());
65 LogOutputs(nullptr, timeout, "SyncLogOutputs");
66 }
67
HandleTimer(stime_t now,stime_t * timeout)68 void Interpreter::HandleTimer(stime_t now, stime_t* timeout) {
69 AssertWithReturn(initialized_);
70 if (EventLoggingIsEnabled()) {
71 Trace("log: start: ", "LogTimerCallback");
72 log_->LogTimerCallback(now);
73 Trace("log: end: ", "LogTimerCallback");
74 }
75 Trace("HandleTimer: start: ", name());
76 HandleTimerImpl(now, timeout);
77 Trace("HandleTimer: end: ", name());
78 LogOutputs(nullptr, timeout, "TimerLogOutputs");
79 }
80
ProduceGesture(const Gesture & gesture)81 void Interpreter::ProduceGesture(const Gesture& gesture) {
82 AssertWithReturn(initialized_);
83 LogOutputs(&gesture, nullptr, "ProduceGesture");
84 consumer_->ConsumeGesture(gesture);
85 }
86
Initialize(const HardwareProperties * hwprops,Metrics * metrics,MetricsProperties * mprops,GestureConsumer * consumer)87 void Interpreter::Initialize(const HardwareProperties* hwprops,
88 Metrics* metrics,
89 MetricsProperties* mprops,
90 GestureConsumer* consumer) {
91 if (log_.get() && hwprops) {
92 Trace("log: start: ", "SetHardwareProperties");
93 log_->SetHardwareProperties(*hwprops);
94 Trace("log: end: ", "SetHardwareProperties");
95 }
96
97 metrics_ = metrics;
98 if (requires_metrics_ && metrics == nullptr) {
99 own_metrics_.reset(new Metrics(mprops));
100 metrics_ = own_metrics_.get();
101 }
102
103 hwprops_ = hwprops;
104 consumer_ = consumer;
105 initialized_ = true;
106 }
107
EncodeCommonInfo()108 Json::Value Interpreter::EncodeCommonInfo() {
109 Json::Value root = log_.get() ?
110 log_->EncodeCommonInfo() : Json::Value(Json::objectValue);
111 root[ActivityLog::kKeyInterpreterName] = Json::Value(string(name()));
112 return root;
113 }
114
Encode()115 std::string Interpreter::Encode() {
116 Json::Value root = EncodeCommonInfo();
117 if (log_.get())
118 log_->AddEncodeInfo(&root);
119
120 std::string out = root.toStyledString();
121 return out;
122 }
123
InitName()124 void Interpreter::InitName() {
125 if (!name_) {
126 int status;
127 char* full_name = abi::__cxa_demangle(typeid(*this).name(), 0, 0, &status);
128 if (full_name == nullptr) {
129 if (status == -1)
130 Err("Memory allocation failed");
131 else if (status == -2)
132 Err("Mangled_name is not a valid name");
133 else if (status == -3)
134 Err("One of the arguments is invalid");
135 return;
136 }
137 // the return value of abi::__cxa_demangle(...) is gestures::XXXInterpreter
138 char* last_colon = strrchr(full_name, ':');
139 char* class_name;
140 if (last_colon)
141 class_name = last_colon + 1;
142 else
143 class_name = full_name;
144 name_ = strdup(class_name);
145 free(full_name);
146 }
147 }
148
EventLoggingIsEnabled()149 bool Interpreter::EventLoggingIsEnabled() {
150 return enable_event_logging_ && log_.get();
151 }
152
SetEventLoggingEnabled(bool enabled)153 void Interpreter::SetEventLoggingEnabled(bool enabled) {
154 // TODO(b/185844310): log an event when touch logging is enabled or disabled.
155 enable_event_logging_ = enabled;
156 }
157
EventDebugLoggingIsEnabled(ActivityLog::EventDebug event)158 bool Interpreter::EventDebugLoggingIsEnabled(ActivityLog::EventDebug event) {
159 return EventLoggingIsEnabled() &&
160 (enable_event_debug_logging_ & (1 << static_cast<int>(event)));
161 }
162
GetEventDebugLoggingEnabled()163 uint32_t Interpreter::GetEventDebugLoggingEnabled() {
164 return enable_event_debug_logging_;
165 }
166
SetEventDebugLoggingEnabled(uint32_t enabled)167 void Interpreter::SetEventDebugLoggingEnabled(uint32_t enabled) {
168 enable_event_debug_logging_ = enabled;
169 }
170
EventDebugLoggingDisable(ActivityLog::EventDebug event)171 void Interpreter::EventDebugLoggingDisable(ActivityLog::EventDebug event) {
172 enable_event_debug_logging_ &= ~(1 << static_cast<int>(event));
173 }
174
EventDebugLoggingEnable(ActivityLog::EventDebug event)175 void Interpreter::EventDebugLoggingEnable(ActivityLog::EventDebug event) {
176 enable_event_debug_logging_ |= (1 << static_cast<int>(event));
177 }
178
LogOutputs(const Gesture * result,stime_t * timeout,const char * action)179 void Interpreter::LogOutputs(const Gesture* result,
180 stime_t* timeout,
181 const char* action) {
182 if (!EventLoggingIsEnabled())
183 return;
184 Trace("log: start: ", action);
185 if (result)
186 log_->LogGesture(*result);
187 if (timeout && *timeout >= 0.0)
188 log_->LogCallbackRequest(*timeout);
189 Trace("log: end: ", action);
190 }
191
LogGestureConsume(const std::string & name,const Gesture & gesture)192 void Interpreter::LogGestureConsume(
193 const std::string& name, const Gesture& gesture) {
194 if (EventDebugLoggingIsEnabled(EventDebug::Gesture))
195 log_->LogGestureConsume(name, gesture);
196 }
197
LogGestureProduce(const std::string & name,const Gesture & gesture)198 void Interpreter::LogGestureProduce(
199 const std::string& name, const Gesture& gesture) {
200 if (EventDebugLoggingIsEnabled(EventDebug::Gesture))
201 log_->LogGestureProduce(name, gesture);
202 }
203
LogHardwareStatePre(const std::string & name,const HardwareState & hwstate)204 void Interpreter::LogHardwareStatePre(
205 const std::string& name, const HardwareState& hwstate) {
206 if (EventDebugLoggingIsEnabled(EventDebug::HardwareState))
207 log_->LogHardwareStatePre(name, hwstate);
208 }
209
LogHardwareStatePost(const std::string & name,const HardwareState & hwstate)210 void Interpreter::LogHardwareStatePost(
211 const std::string& name, const HardwareState& hwstate) {
212 if (EventDebugLoggingIsEnabled(EventDebug::HardwareState))
213 log_->LogHardwareStatePost(name, hwstate);
214 }
215
LogHandleTimerPre(const std::string & name,stime_t now,const stime_t * timeout)216 void Interpreter::LogHandleTimerPre(
217 const std::string& name, stime_t now, const stime_t* timeout) {
218 if (EventDebugLoggingIsEnabled(EventDebug::HandleTimer))
219 log_->LogHandleTimerPre(name, now, timeout);
220 }
221
LogHandleTimerPost(const std::string & name,stime_t now,const stime_t * timeout)222 void Interpreter::LogHandleTimerPost(
223 const std::string& name, stime_t now, const stime_t* timeout) {
224 if (EventDebugLoggingIsEnabled(EventDebug::HandleTimer))
225 log_->LogHandleTimerPost(name, now, timeout);
226 }
227
228 } // namespace gestures
229