• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "Trace.h"
18 
19 #include <aidl/android/hardware/vibrator/BnVibrator.h>
20 #include <log/log.h>
21 
22 namespace aidl {
23 namespace android {
24 namespace hardware {
25 namespace vibrator {
26 
27 enum WaveformIndex : uint16_t {
28     /* Physical waveform */
29     WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0,
30     WAVEFORM_RESERVED_INDEX_1 = 1,
31     WAVEFORM_CLICK_INDEX = 2,
32     WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX = 3,
33     WAVEFORM_THUD_INDEX = 4,
34     WAVEFORM_SPIN_INDEX = 5,
35     WAVEFORM_QUICK_RISE_INDEX = 6,
36     WAVEFORM_SLOW_RISE_INDEX = 7,
37     WAVEFORM_QUICK_FALL_INDEX = 8,
38     WAVEFORM_LIGHT_TICK_INDEX = 9,
39     WAVEFORM_LOW_TICK_INDEX = 10,
40     WAVEFORM_RESERVED_MFG_1,
41     WAVEFORM_RESERVED_MFG_2,
42     WAVEFORM_RESERVED_MFG_3,
43     WAVEFORM_MAX_PHYSICAL_INDEX,
44     /* OWT waveform */
45     WAVEFORM_COMPOSE = WAVEFORM_MAX_PHYSICAL_INDEX,
46     WAVEFORM_PWLE,
47     /*
48      * Refer to <linux/input.h>, the WAVEFORM_MAX_INDEX must not exceed 96.
49      * #define FF_GAIN          0x60  // 96 in decimal
50      * #define FF_MAX_EFFECTS   FF_GAIN
51      */
52     WAVEFORM_MAX_INDEX,
53 };
54 
55 /* Support printing */
56 
operator <<(std::ostream & out,std::shared_ptr<IVibratorCallback> arg)57 std::ostream &operator<<(std::ostream &out, std::shared_ptr<IVibratorCallback> arg) {
58     return out << arg->descriptor << "()";
59 }
60 
operator <<(std::ostream & out,const ff_effect * arg)61 std::ostream &operator<<(std::ostream &out, const ff_effect *arg) {
62     if (arg == nullptr) {
63         return out;
64     }
65 
66     return out << StringPrintf("%p", arg).c_str();
67 }
68 
operator <<(std::ostream & out,const ff_effect & arg)69 std::ostream &operator<<(std::ostream &out, const ff_effect &arg) {
70     out << "(";
71     out << "FF_PERIODIC, " << arg.id << ", " << arg.replay.length << "ms, "
72         << arg.u.periodic.custom_len << " bytes";
73     out << ")";
74     return out;
75 }
76 
operator <<(std::ostream & out,const CompositePrimitive & arg)77 std::ostream &operator<<(std::ostream &out, const CompositePrimitive &arg) {
78     return out << toString(arg).c_str();
79 }
80 
operator <<(std::ostream & out,const Braking & arg)81 std::ostream &operator<<(std::ostream &out, const Braking &arg) {
82     return out << toString(arg).c_str();
83 }
84 
operator <<(std::ostream & out,const PrimitivePwle & arg)85 std::ostream &operator<<(std::ostream &out, const PrimitivePwle &arg) {
86     out << "(";
87     switch (arg.getTag()) {
88         case PrimitivePwle::active: {
89             auto active = arg.get<PrimitivePwle::active>();
90             out << std::fixed << std::setprecision(2) << active.startAmplitude << ", "
91                 << active.startFrequency << "Hz, " << active.endAmplitude << ", "
92                 << active.endFrequency << "Hz, " << active.duration << "ms";
93             break;
94         }
95         case PrimitivePwle::braking: {
96             out << "Deprecated!";
97             break;
98         }
99     }
100     out << ")";
101     return out;
102 }
103 
operator <<(std::ostream & out,const CompositeEffect & arg)104 std::ostream &operator<<(std::ostream &out, const CompositeEffect &arg) {
105     out << "(" << arg.delayMs << "ms, " << toString(arg.primitive) << ", " << arg.scale << ")";
106     return out;
107 }
108 
operator <<(std::ostream & out,const DspMemChunk * arg)109 std::ostream &operator<<(std::ostream &out, const DspMemChunk *arg) {
110     if (arg == nullptr) {
111         return out << "NULL";
112     }
113 
114     out << "(";
115     if (arg->type() == 14) {
116         out << "WAVEFORM_COMPOSE, ";
117     } else if (arg->type() == 15) {
118         out << "WAVEFORM_PWLE, ";
119     }
120     out << arg->size() << " bytes";
121     out << ")";
122     return out;
123 }
124 
operator <<(std::ostream & out,Effect arg)125 std::ostream &operator<<(std::ostream &out, Effect arg) {
126     return out << toString(arg).c_str();
127 }
128 
operator <<(std::ostream & out,EffectStrength arg)129 std::ostream &operator<<(std::ostream &out, EffectStrength arg) {
130     return out << toString(arg).c_str();
131 }
132 
133 /* Trace Interface */
134 
135 int Trace::mDepth = -1;
136 std::vector<std::string> Trace::mTrace = {};
137 std::vector<std::vector<std::string>> Trace::mPreviousTraces = {};
138 
debug(int fd)139 void Trace::debug(int fd) {
140     std::vector<std::string> tTrace;
141     std::swap(mTrace, tTrace);
142 
143     std::vector<std::vector<std::string>> tPreviousTraces;
144     std::swap(mPreviousTraces, tPreviousTraces);
145 
146     dprintf(fd, "\nCurrent Trace:\n");
147     for (auto line : tTrace) {
148         dprintf(fd, "%s\n", line.c_str());
149     }
150 
151     if (tPreviousTraces.size() > 0) {
152         for (auto i = tPreviousTraces.size(); i--;) {
153             dprintf(fd, "\nPrevious Trace #%zu:\n", i);
154             for (auto line : tPreviousTraces[i]) {
155                 dprintf(fd, "%s\n", line.c_str());
156             }
157         }
158     }
159 }
160 
161 /* FunctionTrace Interface */
162 
FunctionTrace(const char * funcName)163 FunctionTrace::FunctionTrace(const char *funcName) : mClassName(""), mFuncName(funcName) {
164     Trace::enter();
165 }
166 
FunctionTrace(const char * className,const char * funcName)167 FunctionTrace::FunctionTrace(const char *className, const char *funcName)
168     : mClassName(className), mFuncName(funcName) {
169     Trace::enter();
170 }
171 
~FunctionTrace()172 FunctionTrace::~FunctionTrace() {
173     Trace::exit();
174 }
175 
save()176 void FunctionTrace::save() {
177     std::stringstream fmt;
178     int d = Trace::depth();
179     for (int i = 0; i < d; i++) {
180         fmt << "   ";
181     }
182 
183     if (mClassName != "") {
184         fmt << mClassName << "::";
185     }
186     fmt << mFuncName << "(";
187 
188     for (auto param : mParameters) {
189         fmt << param;
190         if (param != mParameters.back()) {
191             fmt << ", ";
192         }
193     }
194 
195     fmt << ")";
196 
197     std::string fmtOut = fmt.str();
198     ALOGI("%s", fmtOut.c_str());
199     Trace::push(fmtOut);
200 }
201 
202 /* Effect Trace Implementation */
203 
EffectTrace(uint16_t index,float scale,int32_t duration,const DspMemChunk * ch)204 EffectTrace::EffectTrace(uint16_t index, float scale, int32_t duration, const DspMemChunk *ch) {
205     std::stringstream fmt;
206     fmt << "Effect(";
207     switch (index) {
208         case WAVEFORM_LONG_VIBRATION_EFFECT_INDEX:
209             fmt << "LONG_VIBRATION, " << scale << ", " << duration << ")";
210             break;
211         case WAVEFORM_CLICK_INDEX:
212             fmt << "CLICK, " << scale << ")";
213             break;
214         case WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX:
215             fmt << "SHORT_VIBRATION, " << scale << ", " << duration << ")";
216             break;
217         case WAVEFORM_THUD_INDEX:
218         case WAVEFORM_SPIN_INDEX:
219         case WAVEFORM_QUICK_RISE_INDEX:
220         case WAVEFORM_SLOW_RISE_INDEX:
221         case WAVEFORM_QUICK_FALL_INDEX:
222             break;
223         case WAVEFORM_LIGHT_TICK_INDEX:
224             fmt << "LIGHT_TICK, " << scale << ")";
225             break;
226         case WAVEFORM_LOW_TICK_INDEX:
227             break;
228         case WAVEFORM_COMPOSE:
229             fmt << "COMPOSITE, " << ch->size() << " bytes)";
230             break;
231         case WAVEFORM_PWLE:
232             fmt << "PWLE, " << ch->size() << " bytes)";
233             break;
234         default:
235             break;
236     }
237     mDescription = fmt.str();
238 }
239 
save()240 void EffectTrace::save() {
241     std::stringstream fmt;
242     for (int i = 0; i < depth(); i++) {
243         fmt << "   ";
244     }
245     fmt << mDescription;
246 
247     std::string fmtOut = fmt.str();
248     ALOGI("%s", fmtOut.c_str());
249     Trace::push(fmtOut);
250     Trace::save();
251 }
252 
253 }  // namespace vibrator
254 }  // namespace hardware
255 }  // namespace android
256 }  // namespace aidl
257