1 /* 2 * Copyright (C) 2023 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 com.android.internal.vibrator.persistence; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.os.VibrationEffect; 23 import android.os.VibrationEffect.Composition.PrimitiveType; 24 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 import java.util.Locale; 28 29 /** 30 * Constants used for vibration XML serialization and parsing. 31 * 32 * @hide 33 */ 34 public final class XmlConstants { 35 36 public static final String NAMESPACE = null; 37 38 public static final String TAG_VIBRATION_EFFECT = "vibration-effect"; 39 public static final String TAG_VIBRATION_SELECT = "vibration-select"; 40 41 public static final String TAG_PREDEFINED_EFFECT = "predefined-effect"; 42 public static final String TAG_PRIMITIVE_EFFECT = "primitive-effect"; 43 public static final String TAG_WAVEFORM_EFFECT = "waveform-effect"; 44 public static final String TAG_WAVEFORM_ENTRY = "waveform-entry"; 45 public static final String TAG_REPEATING = "repeating"; 46 47 public static final String ATTRIBUTE_NAME = "name"; 48 public static final String ATTRIBUTE_FALLBACK = "fallback"; 49 public static final String ATTRIBUTE_DURATION_MS = "durationMs"; 50 public static final String ATTRIBUTE_AMPLITUDE = "amplitude"; 51 public static final String ATTRIBUTE_SCALE = "scale"; 52 public static final String ATTRIBUTE_DELAY_MS = "delayMs"; 53 54 public static final String VALUE_AMPLITUDE_DEFAULT = "default"; 55 56 /** 57 * Allow {@link VibrationEffect} hidden APIs to be used during parsing/serializing. 58 * 59 * <p>Use the schema at services/core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd. 60 */ 61 public static final int FLAG_ALLOW_HIDDEN_APIS = 1 << 0; 62 63 /** @hide */ 64 @IntDef(prefix = { "FLAG_" }, flag = true, value = { 65 FLAG_ALLOW_HIDDEN_APIS 66 }) 67 @Retention(RetentionPolicy.SOURCE) 68 public @interface Flags {} 69 70 /** Represent supported values for attribute name in {@link #TAG_PRIMITIVE_EFFECT} */ 71 public enum PrimitiveEffectName { 72 LOW_TICK(VibrationEffect.Composition.PRIMITIVE_LOW_TICK), 73 TICK(VibrationEffect.Composition.PRIMITIVE_TICK), 74 CLICK(VibrationEffect.Composition.PRIMITIVE_CLICK), 75 SLOW_RISE(VibrationEffect.Composition.PRIMITIVE_SLOW_RISE), 76 QUICK_RISE(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE), 77 QUICK_FALL(VibrationEffect.Composition.PRIMITIVE_QUICK_FALL), 78 SPIN(VibrationEffect.Composition.PRIMITIVE_SPIN), 79 THUD(VibrationEffect.Composition.PRIMITIVE_THUD); 80 81 @PrimitiveType private final int mPrimitiveId; 82 PrimitiveEffectName(@rimitiveType int id)83 PrimitiveEffectName(@PrimitiveType int id) { 84 mPrimitiveId = id; 85 } 86 87 /** 88 * Return the {@link PrimitiveEffectName} that represents given primitive id, or null if 89 * none of the available names maps to the given id. 90 */ 91 @Nullable findById(int primitiveId)92 public static PrimitiveEffectName findById(int primitiveId) { 93 for (PrimitiveEffectName name : PrimitiveEffectName.values()) { 94 if (name.mPrimitiveId == primitiveId) { 95 return name; 96 } 97 } 98 return null; 99 } 100 101 /** 102 * Return the {@link PrimitiveEffectName} that represents given primitive name, or null if 103 * none of the available names maps to the given name. 104 */ 105 @Nullable findByName(@onNull String primitiveName)106 public static PrimitiveEffectName findByName(@NonNull String primitiveName) { 107 try { 108 return PrimitiveEffectName.valueOf(primitiveName.toUpperCase(Locale.ROOT)); 109 } catch (IllegalArgumentException e) { 110 return null; 111 } 112 } 113 114 @PrimitiveType getPrimitiveId()115 public int getPrimitiveId() { 116 return mPrimitiveId; 117 } 118 119 @Override toString()120 public String toString() { 121 return name().toLowerCase(Locale.ROOT); 122 } 123 } 124 125 /** Represent supported values for attribute name in {@link #TAG_PREDEFINED_EFFECT} */ 126 public enum PredefinedEffectName { 127 // Public effects 128 TICK(VibrationEffect.EFFECT_TICK, true), 129 CLICK(VibrationEffect.EFFECT_CLICK, true), 130 HEAVY_CLICK(VibrationEffect.EFFECT_HEAVY_CLICK, true), 131 DOUBLE_CLICK(VibrationEffect.EFFECT_DOUBLE_CLICK, true), 132 133 // Hidden effects 134 TEXTURE_TICK(VibrationEffect.EFFECT_TEXTURE_TICK, false), 135 THUD(VibrationEffect.EFFECT_THUD, false), 136 POP(VibrationEffect.EFFECT_POP, false), 137 RINGTONE_1(VibrationEffect.RINGTONES[0], false), 138 RINGTONE_2(VibrationEffect.RINGTONES[1], false), 139 RINGTONE_3(VibrationEffect.RINGTONES[2], false), 140 RINGTONE_4(VibrationEffect.RINGTONES[3], false), 141 RINGTONE_5(VibrationEffect.RINGTONES[4], false), 142 RINGTONE_6(VibrationEffect.RINGTONES[5], false), 143 RINGTONE_7(VibrationEffect.RINGTONES[6], false), 144 RINGTONE_8(VibrationEffect.RINGTONES[7], false), 145 RINGTONE_9(VibrationEffect.RINGTONES[8], false), 146 RINGTONE_10(VibrationEffect.RINGTONES[9], false), 147 RINGTONE_11(VibrationEffect.RINGTONES[10], false), 148 RINGTONE_12(VibrationEffect.RINGTONES[11], false), 149 RINGTONE_13(VibrationEffect.RINGTONES[12], false), 150 RINGTONE_14(VibrationEffect.RINGTONES[13], false), 151 RINGTONE_15(VibrationEffect.RINGTONES[14], false); 152 153 private final int mEffectId; 154 private final boolean mIsPublic; 155 PredefinedEffectName(int id, boolean isPublic)156 PredefinedEffectName(int id, boolean isPublic) { 157 mEffectId = id; 158 mIsPublic = isPublic; 159 } 160 161 /** 162 * Return the {@link PredefinedEffectName} that represents given effect id, or null if 163 * none of the available names maps to the given id. 164 */ 165 @Nullable findById(int effectId, @XmlConstants.Flags int flags)166 public static PredefinedEffectName findById(int effectId, @XmlConstants.Flags int flags) { 167 boolean allowHidden = (flags & XmlConstants.FLAG_ALLOW_HIDDEN_APIS) != 0; 168 for (PredefinedEffectName name : PredefinedEffectName.values()) { 169 if (name.mEffectId == effectId) { 170 return (name.mIsPublic || allowHidden) ? name : null; 171 } 172 } 173 return null; 174 } 175 176 /** 177 * Return the {@link PredefinedEffectName} that represents given effect name, or null if 178 * none of the available names maps to the given name. 179 */ 180 @Nullable findByName(@onNull String effectName, @XmlConstants.Flags int flags)181 public static PredefinedEffectName findByName(@NonNull String effectName, 182 @XmlConstants.Flags int flags) { 183 boolean allowHidden = (flags & XmlConstants.FLAG_ALLOW_HIDDEN_APIS) != 0; 184 try { 185 PredefinedEffectName name = PredefinedEffectName.valueOf( 186 effectName.toUpperCase(Locale.ROOT)); 187 return (name.mIsPublic || allowHidden) ? name : null; 188 } catch (IllegalArgumentException e) { 189 return null; 190 } 191 } 192 getEffectId()193 public int getEffectId() { 194 return mEffectId; 195 } 196 197 @Override toString()198 public String toString() { 199 return name().toLowerCase(Locale.ROOT); 200 } 201 } 202 } 203