• 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 #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