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