1 /* 2 * Copyright (C) 2022 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 17 package android.os.vibrator; 18 19 import static android.os.VibrationAttributes.USAGE_ACCESSIBILITY; 20 import static android.os.VibrationAttributes.USAGE_ALARM; 21 import static android.os.VibrationAttributes.USAGE_COMMUNICATION_REQUEST; 22 import static android.os.VibrationAttributes.USAGE_HARDWARE_FEEDBACK; 23 import static android.os.VibrationAttributes.USAGE_MEDIA; 24 import static android.os.VibrationAttributes.USAGE_NOTIFICATION; 25 import static android.os.VibrationAttributes.USAGE_PHYSICAL_EMULATION; 26 import static android.os.VibrationAttributes.USAGE_RINGTONE; 27 import static android.os.VibrationAttributes.USAGE_TOUCH; 28 import static android.os.VibrationAttributes.USAGE_UNKNOWN; 29 30 import android.annotation.Nullable; 31 import android.content.res.Resources; 32 import android.os.VibrationAttributes; 33 import android.os.Vibrator; 34 import android.os.Vibrator.VibrationIntensity; 35 36 /** 37 * List of device-specific internal vibration configuration loaded from platform config.xml. 38 * 39 * <p>This should not be public, but some individual values are exposed by {@link Vibrator} by 40 * hidden methods, made available to Settings, SysUI and other platform client code. They can also 41 * be individually exposed with the necessary permissions by the {@link Vibrator} service. 42 * 43 * @hide 44 */ 45 public class VibrationConfig { 46 47 // TODO(b/191150049): move these to vibrator static config file 48 private final float mHapticChannelMaxVibrationAmplitude; 49 private final int mRampStepDurationMs; 50 private final int mRampDownDurationMs; 51 52 @VibrationIntensity 53 private final int mDefaultAlarmVibrationIntensity; 54 @VibrationIntensity 55 private final int mDefaultHapticFeedbackIntensity; 56 @VibrationIntensity 57 private final int mDefaultMediaVibrationIntensity; 58 @VibrationIntensity 59 private final int mDefaultNotificationVibrationIntensity; 60 @VibrationIntensity 61 private final int mDefaultRingVibrationIntensity; 62 63 /** @hide */ VibrationConfig(@ullable Resources resources)64 public VibrationConfig(@Nullable Resources resources) { 65 mHapticChannelMaxVibrationAmplitude = loadFloat(resources, 66 com.android.internal.R.dimen.config_hapticChannelMaxVibrationAmplitude, 0); 67 mRampDownDurationMs = loadInteger(resources, 68 com.android.internal.R.integer.config_vibrationWaveformRampDownDuration, 0); 69 mRampStepDurationMs = loadInteger(resources, 70 com.android.internal.R.integer.config_vibrationWaveformRampStepDuration, 0); 71 72 mDefaultAlarmVibrationIntensity = loadDefaultIntensity(resources, 73 com.android.internal.R.integer.config_defaultAlarmVibrationIntensity); 74 mDefaultHapticFeedbackIntensity = loadDefaultIntensity(resources, 75 com.android.internal.R.integer.config_defaultHapticFeedbackIntensity); 76 mDefaultMediaVibrationIntensity = loadDefaultIntensity(resources, 77 com.android.internal.R.integer.config_defaultMediaVibrationIntensity); 78 mDefaultNotificationVibrationIntensity = loadDefaultIntensity(resources, 79 com.android.internal.R.integer.config_defaultNotificationVibrationIntensity); 80 mDefaultRingVibrationIntensity = loadDefaultIntensity(resources, 81 com.android.internal.R.integer.config_defaultRingVibrationIntensity); 82 } 83 84 @VibrationIntensity loadDefaultIntensity(@ullable Resources res, int resId)85 private static int loadDefaultIntensity(@Nullable Resources res, int resId) { 86 int defaultIntensity = Vibrator.VIBRATION_INTENSITY_MEDIUM; 87 int value = loadInteger(res, resId, defaultIntensity); 88 if (value < Vibrator.VIBRATION_INTENSITY_OFF || value > Vibrator.VIBRATION_INTENSITY_HIGH) { 89 return defaultIntensity; 90 } 91 return value; 92 } 93 loadFloat(@ullable Resources res, int resId, float defaultValue)94 private static float loadFloat(@Nullable Resources res, int resId, float defaultValue) { 95 return res != null ? res.getFloat(resId) : defaultValue; 96 } 97 loadInteger(@ullable Resources res, int resId, int defaultValue)98 private static int loadInteger(@Nullable Resources res, int resId, int defaultValue) { 99 return res != null ? res.getInteger(resId) : defaultValue; 100 } 101 102 /** 103 * Return the maximum amplitude the vibrator can play using the audio haptic channels. 104 * 105 * @return a positive value representing the maximum absolute value the device can play signals 106 * from audio haptic channels, or {@link Float#NaN NaN} if it's unknown. 107 */ getHapticChannelMaximumAmplitude()108 public float getHapticChannelMaximumAmplitude() { 109 if (mHapticChannelMaxVibrationAmplitude <= 0) { 110 return Float.NaN; 111 } 112 return mHapticChannelMaxVibrationAmplitude; 113 } 114 115 /** 116 * The duration, in milliseconds, that should be applied to the ramp to turn off the vibrator 117 * when a vibration is cancelled or finished at non-zero amplitude. 118 */ getRampDownDurationMs()119 public int getRampDownDurationMs() { 120 if (mRampDownDurationMs < 0) { 121 return 0; 122 } 123 return mRampDownDurationMs; 124 } 125 126 /** 127 * The duration, in milliseconds, that should be applied to convert vibration effect's 128 * {@link android.os.vibrator.RampSegment} to a {@link android.os.vibrator.StepSegment} on 129 * devices without PWLE support. 130 */ getRampStepDurationMs()131 public int getRampStepDurationMs() { 132 if (mRampStepDurationMs < 0) { 133 return 0; 134 } 135 return mRampStepDurationMs; 136 } 137 138 /** Get the default vibration intensity for given usage. */ 139 @VibrationIntensity getDefaultVibrationIntensity(@ibrationAttributes.Usage int usage)140 public int getDefaultVibrationIntensity(@VibrationAttributes.Usage int usage) { 141 switch (usage) { 142 case USAGE_ALARM: 143 return mDefaultAlarmVibrationIntensity; 144 case USAGE_NOTIFICATION: 145 case USAGE_COMMUNICATION_REQUEST: 146 return mDefaultNotificationVibrationIntensity; 147 case USAGE_RINGTONE: 148 return mDefaultRingVibrationIntensity; 149 case USAGE_TOUCH: 150 case USAGE_HARDWARE_FEEDBACK: 151 case USAGE_PHYSICAL_EMULATION: 152 case USAGE_ACCESSIBILITY: 153 return mDefaultHapticFeedbackIntensity; 154 case USAGE_MEDIA: 155 case USAGE_UNKNOWN: 156 // fall through 157 default: 158 return mDefaultMediaVibrationIntensity; 159 } 160 } 161 162 @Override toString()163 public String toString() { 164 return "VibrationConfig{" 165 + "mHapticChannelMaxVibrationAmplitude=" + mHapticChannelMaxVibrationAmplitude 166 + ", mRampStepDurationMs=" + mRampStepDurationMs 167 + ", mRampDownDurationMs=" + mRampDownDurationMs 168 + ", mDefaultAlarmIntensity=" + mDefaultAlarmVibrationIntensity 169 + ", mDefaultHapticFeedbackIntensity=" + mDefaultHapticFeedbackIntensity 170 + ", mDefaultMediaIntensity=" + mDefaultMediaVibrationIntensity 171 + ", mDefaultNotificationIntensity=" + mDefaultNotificationVibrationIntensity 172 + ", mDefaultRingIntensity=" + mDefaultRingVibrationIntensity 173 + "}"; 174 } 175 } 176