xref: /aosp_15_r20/external/libchrome-gestures/src/interpreter.cc (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
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