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 <log/log.h> 19 #include <utils/Trace.h> 20 21 #include <algorithm> 22 #include <chrono> 23 #include <mutex> 24 25 #include "Vibrator.h" 26 27 constexpr int32_t DURATION_BUCKET_WIDTH = 50; 28 constexpr int32_t DURATION_50MS_BUCKET_COUNT = 20; 29 constexpr int32_t DURATION_BUCKET_COUNT = DURATION_50MS_BUCKET_COUNT + 1; 30 constexpr uint32_t MAX_TIME_MS = UINT16_MAX; 31 32 namespace aidl { 33 namespace android { 34 namespace hardware { 35 namespace vibrator { 36 37 enum EffectLatency : uint16_t { 38 kPrebakedEffectLatency = 0, 39 kCompositionEffectLatency, 40 kPwleEffectLatency, 41 42 kEffectLatencyCount 43 }; 44 45 enum VibratorError : uint16_t { 46 kInitError = 0, 47 kHwApiError, 48 kHwCalError, 49 kComposeFailError, 50 kAlsaFailError, 51 kAsyncFailError, 52 kBadTimeoutError, 53 kBadAmplitudeError, 54 kBadEffectError, 55 kBadEffectStrengthError, 56 kBadPrimitiveError, 57 kBadCompositeError, 58 kPwleConstructionFailError, 59 kUnsupportedOpError, 60 61 kVibratorErrorCount 62 }; 63 64 class StatsApi : public Vibrator::StatsApi { 65 private: 66 static constexpr uint32_t BASE_CONTINUOUS_EFFECT_OFFSET = 32768; 67 enum WaveformIndex : uint16_t { 68 /* Physical waveform */ 69 WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0, 70 WAVEFORM_RESERVED_INDEX_1 = 1, 71 WAVEFORM_CLICK_INDEX = 2, 72 WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX = 3, 73 WAVEFORM_THUD_INDEX = 4, 74 WAVEFORM_SPIN_INDEX = 5, 75 WAVEFORM_QUICK_RISE_INDEX = 6, 76 WAVEFORM_SLOW_RISE_INDEX = 7, 77 WAVEFORM_QUICK_FALL_INDEX = 8, 78 WAVEFORM_LIGHT_TICK_INDEX = 9, 79 WAVEFORM_LOW_TICK_INDEX = 10, 80 WAVEFORM_RESERVED_MFG_1, 81 WAVEFORM_RESERVED_MFG_2, 82 WAVEFORM_RESERVED_MFG_3, 83 WAVEFORM_MAX_PHYSICAL_INDEX, 84 /* OWT waveform */ 85 WAVEFORM_COMPOSE = WAVEFORM_MAX_PHYSICAL_INDEX, 86 WAVEFORM_PWLE, 87 /* 88 * Refer to <linux/input.h>, the WAVEFORM_MAX_INDEX must not exceed 96. 89 * #define FF_GAIN 0x60 // 96 in decimal 90 * #define FF_MAX_EFFECTS FF_GAIN 91 */ 92 WAVEFORM_MAX_INDEX, 93 }; 94 95 public: StatsApi()96 StatsApi() { 97 mWaveformCounts = std::vector<int32_t>(WAVEFORM_MAX_INDEX, 0); 98 mDurationCounts = std::vector<int32_t>(DURATION_BUCKET_COUNT, 0); 99 mMinLatencies = std::vector<int32_t>(kEffectLatencyCount, 0); 100 mMaxLatencies = std::vector<int32_t>(kEffectLatencyCount, 0); 101 mLatencyTotals = std::vector<int32_t>(kEffectLatencyCount, 0); 102 mLatencyCounts = std::vector<int32_t>(kEffectLatencyCount, 0); 103 mErrorCounts = std::vector<int32_t>(kVibratorErrorCount, 0); 104 } 105 logPrimitive(uint16_t effectIndex)106 bool logPrimitive(uint16_t effectIndex) override { 107 if (effectIndex >= WAVEFORM_MAX_PHYSICAL_INDEX || 108 effectIndex == WAVEFORM_LONG_VIBRATION_EFFECT_INDEX || 109 effectIndex == WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX) { 110 ALOGE("Invalid waveform index for logging primitive: %d", effectIndex); 111 return false; 112 } 113 114 { 115 std::scoped_lock<std::mutex> lock(mDataAccess); 116 mWaveformCounts[effectIndex]++; 117 } 118 119 return true; 120 } 121 logWaveform(uint16_t effectIndex,int32_t duration)122 bool logWaveform(uint16_t effectIndex, int32_t duration) override { 123 if (effectIndex != WAVEFORM_LONG_VIBRATION_EFFECT_INDEX && 124 effectIndex != WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX + BASE_CONTINUOUS_EFFECT_OFFSET) { 125 ALOGE("Invalid waveform index for logging waveform: %d", effectIndex); 126 return false; 127 } else if (effectIndex == 128 WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX + BASE_CONTINUOUS_EFFECT_OFFSET) { 129 effectIndex = WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX; 130 } 131 132 if (duration > MAX_TIME_MS || duration < 0) { 133 ALOGE("Invalid waveform duration for logging waveform: %d", duration); 134 return false; 135 } 136 137 { 138 std::scoped_lock<std::mutex> lock(mDataAccess); 139 mWaveformCounts[effectIndex]++; 140 if (duration < DURATION_BUCKET_WIDTH * DURATION_50MS_BUCKET_COUNT) { 141 mDurationCounts[duration / DURATION_BUCKET_WIDTH]++; 142 } else { 143 mDurationCounts[DURATION_50MS_BUCKET_COUNT]++; 144 } 145 } 146 147 return true; 148 } 149 logError(uint16_t errorIndex)150 bool logError(uint16_t errorIndex) override { 151 if (errorIndex >= kVibratorErrorCount) { 152 ALOGE("Invalid index for logging error: %d", errorIndex); 153 return false; 154 } 155 156 { 157 std::scoped_lock<std::mutex> lock(mDataAccess); 158 mErrorCounts[errorIndex]++; 159 } 160 161 return true; 162 } 163 logLatencyStart(uint16_t latencyIndex)164 bool logLatencyStart(uint16_t latencyIndex) override { 165 if (latencyIndex >= kEffectLatencyCount) { 166 ALOGE("Invalid index for measuring latency: %d", latencyIndex); 167 return false; 168 } 169 170 mCurrentLatencyStart = std::chrono::steady_clock::now(); 171 mCurrentLatencyIndex = latencyIndex; 172 173 return true; 174 } 175 logLatencyEnd()176 bool logLatencyEnd() override { 177 if (mCurrentLatencyIndex >= kEffectLatencyCount) { 178 return false; 179 } 180 181 int32_t latency = (std::chrono::duration_cast<std::chrono::milliseconds>( 182 std::chrono::steady_clock::now() - mCurrentLatencyStart)) 183 .count(); 184 185 { 186 std::scoped_lock<std::mutex> lock(mDataAccess); 187 if (latency < mMinLatencies[mCurrentLatencyIndex] || 188 mMinLatencies[mCurrentLatencyIndex] == 0) { 189 mMinLatencies[mCurrentLatencyIndex] = latency; 190 } 191 if (latency > mMaxLatencies[mCurrentLatencyIndex]) { 192 mMinLatencies[mCurrentLatencyIndex] = latency; 193 } 194 mLatencyTotals[mCurrentLatencyIndex] += latency; 195 mLatencyCounts[mCurrentLatencyIndex]++; 196 } 197 198 mCurrentLatencyIndex = kEffectLatencyCount; 199 return true; 200 } 201 debug(int fd)202 void debug(int fd) override { (void)fd; } 203 204 private: 205 uint16_t mCurrentLatencyIndex; 206 std::chrono::time_point<std::chrono::steady_clock> mCurrentLatencyStart; 207 std::vector<int32_t> mWaveformCounts; 208 std::vector<int32_t> mDurationCounts; 209 std::vector<int32_t> mMinLatencies; 210 std::vector<int32_t> mMaxLatencies; 211 std::vector<int32_t> mLatencyTotals; 212 std::vector<int32_t> mLatencyCounts; 213 std::vector<int32_t> mErrorCounts; 214 std::mutex mDataAccess; 215 }; 216 217 } // namespace vibrator 218 } // namespace hardware 219 } // namespace android 220 } // namespace aidl 221