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