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