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 #pragma once
17 
18 #include <aidl/android/hardware/vibrator/BnVibrator.h>
19 #include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
20 #include <android-base/stringprintf.h>
21 #include <hardware/hardware.h>
22 #include <hardware/vibrator.h>
23 #include <linux/input.h>
24 
25 #include <iomanip>
26 #include <iostream>
27 #include <sstream>
28 #include <string>
29 #include <typeinfo>
30 #include <vector>
31 
32 #include "DspMemChunk.h"
33 
34 /* Macros to expand argument (x) into pair("x", x) for nicer tracing logs
35  * Easily extendible past 7 elements
36  */
37 #define WITH_NAME(a) std::make_pair(#a, a)
38 
39 #define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)
40 #define VA_NUM_ARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, N, ...) N
41 
42 #define CONCAT_IMPL(x, y) x##y
43 #define MACRO_CONCAT(x, y) CONCAT_IMPL(x, y)
44 
45 #define PREPEND_EACH_ARG_WITH_NAME_1(a) WITH_NAME(a)
46 #define PREPEND_EACH_ARG_WITH_NAME_2(a, ...) WITH_NAME(a), PREPEND_EACH_ARG_WITH_NAME_1(__VA_ARGS__)
47 #define PREPEND_EACH_ARG_WITH_NAME_3(a, ...) WITH_NAME(a), PREPEND_EACH_ARG_WITH_NAME_2(__VA_ARGS__)
48 #define PREPEND_EACH_ARG_WITH_NAME_4(a, ...) WITH_NAME(a), PREPEND_EACH_ARG_WITH_NAME_3(__VA_ARGS__)
49 #define PREPEND_EACH_ARG_WITH_NAME_5(a, ...) WITH_NAME(a), PREPEND_EACH_ARG_WITH_NAME_4(__VA_ARGS__)
50 #define PREPEND_EACH_ARG_WITH_NAME_6(a, ...) WITH_NAME(a), PREPEND_EACH_ARG_WITH_NAME_5(__VA_ARGS__)
51 #define PREPEND_EACH_ARG_WITH_NAME_7(a, ...) WITH_NAME(a), PREPEND_EACH_ARG_WITH_NAME_6(__VA_ARGS__)
52 #define PREPEND_EACH_ARG_WITH_NAME(...) \
53     MACRO_CONCAT(PREPEND_EACH_ARG_WITH_NAME_, VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
54 
55 namespace aidl {
56 namespace android {
57 namespace hardware {
58 namespace vibrator {
59 
60 using ::android::base::StringPrintf;
61 
62 /* Supported typenames */
63 
64 // Fallback to typeid
65 template <typename T>
66 struct TypeName {
GetTypeName67     static const char *Get() { return "<unknown>"; }
68 };
69 
70 // Helper Macro
71 #define SUPPORT_TYPENAME(T)        \
72     template <>                    \
73     struct TypeName<T> {           \
74         static const char *Get() { \
75             return #T;             \
76         }                          \
77     }
78 
79 SUPPORT_TYPENAME(bool);
80 
81 SUPPORT_TYPENAME(int8_t);
82 SUPPORT_TYPENAME(int16_t);
83 SUPPORT_TYPENAME(int32_t);
84 SUPPORT_TYPENAME(uint8_t);
85 SUPPORT_TYPENAME(uint16_t);
86 SUPPORT_TYPENAME(uint32_t);
87 
88 SUPPORT_TYPENAME(int8_t *);
89 SUPPORT_TYPENAME(int16_t *);
90 SUPPORT_TYPENAME(int32_t *);
91 SUPPORT_TYPENAME(uint8_t *);
92 SUPPORT_TYPENAME(uint16_t *);
93 SUPPORT_TYPENAME(uint32_t *);
94 
95 SUPPORT_TYPENAME(const int16_t *);
96 SUPPORT_TYPENAME(const int32_t *);
97 SUPPORT_TYPENAME(const uint16_t *);
98 SUPPORT_TYPENAME(const uint32_t *);
99 
100 SUPPORT_TYPENAME(float);
101 SUPPORT_TYPENAME(float *);
102 SUPPORT_TYPENAME(const float *);
103 
104 SUPPORT_TYPENAME(std::string);
105 SUPPORT_TYPENAME(const std::string &);
106 SUPPORT_TYPENAME(const char **);
107 
108 SUPPORT_TYPENAME(std::vector<ff_effect> *);
109 SUPPORT_TYPENAME(const ff_effect *);
110 SUPPORT_TYPENAME(ff_effect);
111 SUPPORT_TYPENAME(ff_effect *);
112 
113 SUPPORT_TYPENAME(Effect);
114 SUPPORT_TYPENAME(EffectStrength);
115 SUPPORT_TYPENAME(std::vector<Effect> *);
116 
117 SUPPORT_TYPENAME(const std::vector<PrimitivePwle> &);
118 SUPPORT_TYPENAME(const std::vector<PrimitivePwle>);
119 SUPPORT_TYPENAME(std::vector<PrimitivePwle> &);
120 SUPPORT_TYPENAME(std::vector<PrimitivePwle>);
121 
122 SUPPORT_TYPENAME(const std::shared_ptr<IVibratorCallback> &&);
123 SUPPORT_TYPENAME(const std::shared_ptr<IVibratorCallback> &);
124 SUPPORT_TYPENAME(const std::shared_ptr<IVibratorCallback>);
125 SUPPORT_TYPENAME(std::shared_ptr<IVibratorCallback> &&);
126 SUPPORT_TYPENAME(std::shared_ptr<IVibratorCallback> &);
127 SUPPORT_TYPENAME(std::shared_ptr<IVibratorCallback>);
128 
129 SUPPORT_TYPENAME(std::vector<CompositePrimitive> *);
130 SUPPORT_TYPENAME(CompositePrimitive);
131 
132 SUPPORT_TYPENAME(const std::vector<CompositeEffect> &);
133 SUPPORT_TYPENAME(const std::vector<CompositeEffect>);
134 SUPPORT_TYPENAME(std::vector<CompositeEffect> &);
135 SUPPORT_TYPENAME(std::vector<CompositeEffect>);
136 
137 SUPPORT_TYPENAME(std::vector<Braking> *);
138 SUPPORT_TYPENAME(struct pcm **);
139 SUPPORT_TYPENAME(const DspMemChunk *);
140 SUPPORT_TYPENAME(DspMemChunk *);
141 
142 /* Support printing */
143 
144 template <typename T>
145 std::ostream &operator<<(std::ostream &out, const std::vector<T> &arg) {
146     out << "{";
147     for (size_t i = 0; i < arg.size(); i++) {
148         out << arg[i];
149         if (i != arg.size() - 1) {
150             out << ", ";
151         }
152     }
153     out << "}";
154     return out;
155 }
156 
157 std::ostream &operator<<(std::ostream &out, const std::shared_ptr<IVibratorCallback> arg);
158 std::ostream &operator<<(std::ostream &out, const ff_effect *arg);
159 std::ostream &operator<<(std::ostream &out, const ff_effect &arg);
160 std::ostream &operator<<(std::ostream &out, const CompositePrimitive &arg);
161 std::ostream &operator<<(std::ostream &out, const Braking &arg);
162 std::ostream &operator<<(std::ostream &out, const PrimitivePwle &arg);
163 std::ostream &operator<<(std::ostream &out, const CompositeEffect &arg);
164 std::ostream &operator<<(std::ostream &out, const DspMemChunk *arg);
165 std::ostream &operator<<(std::ostream &out, Effect arg);
166 std::ostream &operator<<(std::ostream &out, EffectStrength arg);
167 
168 /* Tracing classes */
169 
170 class Trace {
171   public:
172     static void debug(int fd);
depth()173     static int depth() { return mDepth; }
enter()174     static void enter() { mDepth++; }
exit()175     static void exit() { mDepth--; }
push(const std::string & t)176     static void push(const std::string &t) { mTrace.push_back(t); }
pop()177     static void pop() { mTrace.pop_back(); }
save()178     static void save() {
179         std::vector<std::string> temp;
180         std::swap(mTrace, temp);
181         mPreviousTraces.push_back(std::move(temp));
182     }
183 
184   private:
185     static int mDepth;
186     static std::vector<std::string> mTrace;
187     static std::vector<std::vector<std::string>> mPreviousTraces;
188 };
189 
190 class FunctionTrace : public Trace {
191   public:
192     FunctionTrace(const char *funcName);
193     FunctionTrace(const char *className, const char *funcName);
194     ~FunctionTrace();
195 
196     template <typename T>
addParameter(std::pair<const char *,T> t)197     void addParameter(std::pair<const char *, T> t) {
198         std::stringstream fmt;
199         fmt << TypeName<T>::Get() << " " << t.first << ":" << t.second;
200         mParameters.push_back(fmt.str());
201     }
202 
203     template <typename T, typename... Ts>
addParameter(std::pair<const char *,T> t,Ts...ts)204     void addParameter(std::pair<const char *, T> t, Ts... ts) {
205         addParameter(t);
206         addParameter(ts...);
207     }
208 
addParameter()209     void addParameter() { return; }
210 
211     void save();
212 
213   private:
214     std::string mClassName;
215     std::string mFuncName;
216     std::vector<std::string> mParameters;
217 };
218 
219 class EffectTrace : public Trace {
220   public:
221     EffectTrace(uint16_t index, float scale, int32_t duration, const DspMemChunk *ch);
222     void save();
223 
224   private:
225     std::string mDescription;
226 };
227 
228 }  // namespace vibrator
229 }  // namespace hardware
230 }  // namespace android
231 }  // namespace aidl
232