Skip to content

Commit 2cd8035

Browse files
author
Ahmad Khalil
committed
Add adaptive haptics scaling to external vibrations
We've converted HapticScale into a struct which includes both scale level and adaptive haptics scale. The adaptive haptics scale is now included in the process of scaling vibrations. Bug: 305957324 Test: N/A Change-Id: Ic46f11812e2599da6ec7f8363932a0d9368e7157
1 parent f8680e6 commit 2cd8035

4 files changed

Lines changed: 104 additions & 50 deletions

File tree

libs/vibrator/ExternalVibration.cpp

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <vibrator/ExternalVibration.h>
1818
#include <vibrator/ExternalVibrationUtils.h>
1919

20-
#include <android/os/IExternalVibratorService.h>
20+
#include <android/os/ExternalVibrationScale.h>
2121
#include <binder/Parcel.h>
2222
#include <log/log.h>
2323
#include <utils/Errors.h>
@@ -65,24 +65,36 @@ inline bool ExternalVibration::operator==(const ExternalVibration& rhs) const {
6565
return mToken == rhs.mToken;
6666
}
6767

68-
os::HapticScale ExternalVibration::externalVibrationScaleToHapticScale(int externalVibrationScale) {
69-
switch (externalVibrationScale) {
70-
case IExternalVibratorService::SCALE_MUTE:
71-
return os::HapticScale::MUTE;
72-
case IExternalVibratorService::SCALE_VERY_LOW:
73-
return os::HapticScale::VERY_LOW;
74-
case IExternalVibratorService::SCALE_LOW:
75-
return os::HapticScale::LOW;
76-
case IExternalVibratorService::SCALE_NONE:
77-
return os::HapticScale::NONE;
78-
case IExternalVibratorService::SCALE_HIGH:
79-
return os::HapticScale::HIGH;
80-
case IExternalVibratorService::SCALE_VERY_HIGH:
81-
return os::HapticScale::VERY_HIGH;
68+
os::HapticScale ExternalVibration::externalVibrationScaleToHapticScale(
69+
os::ExternalVibrationScale externalVibrationScale) {
70+
os::HapticLevel scaleLevel = os::HapticLevel::NONE;
71+
72+
switch (externalVibrationScale.scaleLevel) {
73+
case os::ExternalVibrationScale::ScaleLevel::SCALE_MUTE:
74+
scaleLevel = os::HapticLevel::MUTE;
75+
break;
76+
case os::ExternalVibrationScale::ScaleLevel::SCALE_VERY_LOW:
77+
scaleLevel = os::HapticLevel::VERY_LOW;
78+
break;
79+
case os::ExternalVibrationScale::ScaleLevel::SCALE_LOW:
80+
scaleLevel = os::HapticLevel::LOW;
81+
break;
82+
case os::ExternalVibrationScale::ScaleLevel::SCALE_NONE:
83+
scaleLevel = os::HapticLevel::NONE;
84+
break;
85+
case os::ExternalVibrationScale::ScaleLevel::SCALE_HIGH:
86+
scaleLevel = os::HapticLevel::HIGH;
87+
break;
88+
case os::ExternalVibrationScale::ScaleLevel::SCALE_VERY_HIGH:
89+
scaleLevel = os::HapticLevel::VERY_HIGH;
90+
break;
8291
default:
83-
ALOGE("Unknown ExternalVibrationScale %d, not applying scaling", externalVibrationScale);
84-
return os::HapticScale::NONE;
85-
}
92+
ALOGE("Unknown ExternalVibrationScale %d, not applying scaling",
93+
externalVibrationScale.scaleLevel);
94+
}
95+
96+
return {/*level=*/scaleLevel, /*adaptiveScaleFactor=*/
97+
externalVibrationScale.adaptiveHapticsScale};
8698
}
8799

88100
} // namespace os

libs/vibrator/ExternalVibrationUtils.cpp

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,50 +26,59 @@ static constexpr float HAPTIC_SCALE_VERY_LOW_RATIO = 2.0f / 3.0f;
2626
static constexpr float HAPTIC_SCALE_LOW_RATIO = 3.0f / 4.0f;
2727
static constexpr float HAPTIC_MAX_AMPLITUDE_FLOAT = 1.0f;
2828

29-
float getHapticScaleGamma(HapticScale scale) {
30-
switch (scale) {
31-
case HapticScale::VERY_LOW:
29+
float getHapticScaleGamma(HapticLevel level) {
30+
switch (level) {
31+
case HapticLevel::VERY_LOW:
3232
return 2.0f;
33-
case HapticScale::LOW:
33+
case HapticLevel::LOW:
3434
return 1.5f;
35-
case HapticScale::HIGH:
35+
case HapticLevel::HIGH:
3636
return 0.5f;
37-
case HapticScale::VERY_HIGH:
37+
case HapticLevel::VERY_HIGH:
3838
return 0.25f;
3939
default:
4040
return 1.0f;
4141
}
4242
}
4343

44-
float getHapticMaxAmplitudeRatio(HapticScale scale) {
45-
switch (scale) {
46-
case HapticScale::VERY_LOW:
44+
float getHapticMaxAmplitudeRatio(HapticLevel level) {
45+
switch (level) {
46+
case HapticLevel::VERY_LOW:
4747
return HAPTIC_SCALE_VERY_LOW_RATIO;
48-
case HapticScale::LOW:
48+
case HapticLevel::LOW:
4949
return HAPTIC_SCALE_LOW_RATIO;
50-
case HapticScale::NONE:
51-
case HapticScale::HIGH:
52-
case HapticScale::VERY_HIGH:
50+
case HapticLevel::NONE:
51+
case HapticLevel::HIGH:
52+
case HapticLevel::VERY_HIGH:
5353
return 1.0f;
5454
default:
5555
return 0.0f;
5656
}
5757
}
5858

5959
void applyHapticScale(float* buffer, size_t length, HapticScale scale) {
60-
if (scale == HapticScale::MUTE) {
60+
if (scale.isScaleMute()) {
6161
memset(buffer, 0, length * sizeof(float));
6262
return;
6363
}
64-
if (scale == HapticScale::NONE) {
64+
if (scale.isScaleNone()) {
6565
return;
6666
}
67-
float gamma = getHapticScaleGamma(scale);
68-
float maxAmplitudeRatio = getHapticMaxAmplitudeRatio(scale);
67+
HapticLevel hapticLevel = scale.getLevel();
68+
float adaptiveScaleFactor = scale.getAdaptiveScaleFactor();
69+
float gamma = getHapticScaleGamma(hapticLevel);
70+
float maxAmplitudeRatio = getHapticMaxAmplitudeRatio(hapticLevel);
71+
6972
for (size_t i = 0; i < length; i++) {
70-
float sign = buffer[i] >= 0 ? 1.0 : -1.0;
71-
buffer[i] = powf(fabsf(buffer[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma)
72-
* maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * sign;
73+
if (hapticLevel != HapticLevel::NONE) {
74+
float sign = buffer[i] >= 0 ? 1.0 : -1.0;
75+
buffer[i] = powf(fabsf(buffer[i] / HAPTIC_MAX_AMPLITUDE_FLOAT), gamma)
76+
* maxAmplitudeRatio * HAPTIC_MAX_AMPLITUDE_FLOAT * sign;
77+
}
78+
79+
if (adaptiveScaleFactor != 1.0f) {
80+
buffer[i] *= adaptiveScaleFactor;
81+
}
7382
}
7483
}
7584

@@ -89,13 +98,13 @@ void clipHapticData(float* buffer, size_t length, float limit) {
8998
} // namespace
9099

91100
bool isValidHapticScale(HapticScale scale) {
92-
switch (scale) {
93-
case HapticScale::MUTE:
94-
case HapticScale::VERY_LOW:
95-
case HapticScale::LOW:
96-
case HapticScale::NONE:
97-
case HapticScale::HIGH:
98-
case HapticScale::VERY_HIGH:
101+
switch (scale.getLevel()) {
102+
case HapticLevel::MUTE:
103+
case HapticLevel::VERY_LOW:
104+
case HapticLevel::LOW:
105+
case HapticLevel::NONE:
106+
case HapticLevel::HIGH:
107+
case HapticLevel::VERY_HIGH:
99108
return true;
100109
}
101110
return false;

libs/vibrator/include/vibrator/ExternalVibration.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <system/audio.h>
2525
#include <utils/RefBase.h>
2626
#include <vibrator/ExternalVibrationUtils.h>
27+
#include <android/os/ExternalVibrationScale.h>
2728

2829
namespace android {
2930
namespace os {
@@ -45,10 +46,11 @@ public :
4546
audio_attributes_t getAudioAttributes() const { return mAttrs; }
4647
sp<IExternalVibrationController> getController() { return mController; }
4748

48-
/* Converts the scale from non-public ExternalVibrationService into the HapticScale
49+
/* Converts the scale from non-public ExternalVibrationService into the HapticScaleLevel
4950
* used by the utils.
5051
*/
51-
static os::HapticScale externalVibrationScaleToHapticScale(int externalVibrationScale);
52+
static os::HapticScale externalVibrationScaleToHapticScale(
53+
os::ExternalVibrationScale externalVibrationScale);
5254

5355
private:
5456
int32_t mUid;

libs/vibrator/include/vibrator/ExternalVibrationUtils.h

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
namespace android::os {
2121

22-
enum class HapticScale {
22+
enum class HapticLevel {
2323
MUTE = -100,
2424
VERY_LOW = -2,
2525
LOW = -1,
@@ -28,10 +28,41 @@ enum class HapticScale {
2828
VERY_HIGH = 2,
2929
};
3030

31+
class HapticScale {
32+
private:
33+
HapticLevel mLevel = HapticLevel::NONE;
34+
float mAdaptiveScaleFactor = 1.0f;
35+
36+
public:
37+
constexpr HapticScale(HapticLevel level, float adaptiveScaleFactor)
38+
: mLevel(level), mAdaptiveScaleFactor(adaptiveScaleFactor) {}
39+
constexpr HapticScale(HapticLevel level) : mLevel(level) {}
40+
constexpr HapticScale() {}
41+
42+
HapticLevel getLevel() const { return mLevel; }
43+
float getAdaptiveScaleFactor() const { return mAdaptiveScaleFactor; }
44+
45+
bool operator==(const HapticScale& other) const {
46+
return mLevel == other.mLevel && mAdaptiveScaleFactor == other.mAdaptiveScaleFactor;
47+
}
48+
49+
bool isScaleNone() const {
50+
return mLevel == HapticLevel::NONE && mAdaptiveScaleFactor == 1.0f;
51+
}
52+
53+
bool isScaleMute() const {
54+
return mLevel == HapticLevel::MUTE;
55+
}
56+
57+
static HapticScale mute() {
58+
return {/*level=*/os::HapticLevel::MUTE};
59+
}
60+
};
61+
3162
bool isValidHapticScale(HapticScale scale);
3263

33-
/* Scales the haptic data in given buffer using the selected HapticScale and ensuring no absolute
34-
* value will be larger than the absolute of given limit.
64+
/* Scales the haptic data in given buffer using the selected HapticScaleLevel and ensuring no
65+
* absolute value will be larger than the absolute of given limit.
3566
* The limit will be ignored if it is NaN or zero.
3667
*/
3768
void scaleHapticData(float* buffer, size_t length, HapticScale scale, float limit);

0 commit comments

Comments
 (0)