1 /* 2 * Copyright (C) 2008 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.view; 18 19 import android.annotation.IntDef; 20 import android.media.AudioManager; 21 22 import com.android.internal.annotations.VisibleForTesting; 23 import com.android.internal.annotations.VisibleForTesting.Visibility; 24 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 import java.util.Random; 28 29 /** 30 * Constants to be used to play sound effects via {@link View#playSoundEffect(int)} 31 */ 32 public class SoundEffectConstants { 33 SoundEffectConstants()34 private SoundEffectConstants() {} 35 private static final Random NAVIGATION_REPEAT_RANDOMIZER = new Random(); 36 private static int sLastNavigationRepeatSoundEffectId = -1; 37 38 public static final int CLICK = 0; 39 40 /** Effect id for a navigation left */ 41 public static final int NAVIGATION_LEFT = 1; 42 /** Effect id for a navigation up */ 43 public static final int NAVIGATION_UP = 2; 44 /** Effect id for a navigation right */ 45 public static final int NAVIGATION_RIGHT = 3; 46 /** Effect id for a navigation down */ 47 public static final int NAVIGATION_DOWN = 4; 48 /** Effect id for a repeatedly triggered navigation left, e.g. due to long pressing a button */ 49 public static final int NAVIGATION_REPEAT_LEFT = 5; 50 /** Effect id for a repeatedly triggered navigation up, e.g. due to long pressing a button */ 51 public static final int NAVIGATION_REPEAT_UP = 6; 52 /** Effect id for a repeatedly triggered navigation right, e.g. due to long pressing a button */ 53 public static final int NAVIGATION_REPEAT_RIGHT = 7; 54 /** Effect id for a repeatedly triggered navigation down, e.g. due to long pressing a button */ 55 public static final int NAVIGATION_REPEAT_DOWN = 8; 56 57 /** @hide */ 58 @IntDef(value = { 59 CLICK, 60 NAVIGATION_LEFT, 61 NAVIGATION_UP, 62 NAVIGATION_RIGHT, 63 NAVIGATION_DOWN, 64 NAVIGATION_REPEAT_LEFT, 65 NAVIGATION_REPEAT_UP, 66 NAVIGATION_REPEAT_RIGHT, 67 NAVIGATION_REPEAT_DOWN 68 }) 69 @Retention(RetentionPolicy.SOURCE) 70 public @interface SoundEffect {} 71 72 /** @hide */ 73 @IntDef(prefix = { "NAVIGATION_" }, value = { 74 NAVIGATION_LEFT, 75 NAVIGATION_UP, 76 NAVIGATION_RIGHT, 77 NAVIGATION_DOWN, 78 NAVIGATION_REPEAT_LEFT, 79 NAVIGATION_REPEAT_UP, 80 NAVIGATION_REPEAT_RIGHT, 81 NAVIGATION_REPEAT_DOWN 82 }) 83 @Retention(RetentionPolicy.SOURCE) 84 public @interface NavigationSoundEffect {} 85 86 /** 87 * Get the sonification constant for the focus directions. 88 * @param direction The direction of the focus. 89 * @return The appropriate sonification constant. 90 * @throws {@link IllegalArgumentException} when the passed direction is not one of the 91 * documented values. 92 */ getContantForFocusDirection(@iew.FocusDirection int direction)93 public static int getContantForFocusDirection(@View.FocusDirection int direction) { 94 switch (direction) { 95 case View.FOCUS_RIGHT: 96 return SoundEffectConstants.NAVIGATION_RIGHT; 97 case View.FOCUS_FORWARD: 98 case View.FOCUS_DOWN: 99 return SoundEffectConstants.NAVIGATION_DOWN; 100 case View.FOCUS_LEFT: 101 return SoundEffectConstants.NAVIGATION_LEFT; 102 case View.FOCUS_BACKWARD: 103 case View.FOCUS_UP: 104 return SoundEffectConstants.NAVIGATION_UP; 105 } 106 throw new IllegalArgumentException("direction must be one of " 107 + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, FOCUS_BACKWARD}."); 108 } 109 110 /** 111 * Get the sonification constant for the focus directions 112 * @param direction The direction of the focus. 113 * @param repeating True if the user long-presses a direction 114 * @return The appropriate sonification constant 115 * @throws IllegalArgumentException when the passed direction is not one of the 116 * documented values. 117 */ getConstantForFocusDirection( @iew.FocusDirection int direction, boolean repeating)118 public static @NavigationSoundEffect int getConstantForFocusDirection( 119 @View.FocusDirection int direction, boolean repeating) { 120 if (repeating) { 121 switch (direction) { 122 case View.FOCUS_RIGHT: 123 return SoundEffectConstants.NAVIGATION_REPEAT_RIGHT; 124 case View.FOCUS_FORWARD: 125 case View.FOCUS_DOWN: 126 return SoundEffectConstants.NAVIGATION_REPEAT_DOWN; 127 case View.FOCUS_LEFT: 128 return SoundEffectConstants.NAVIGATION_REPEAT_LEFT; 129 case View.FOCUS_BACKWARD: 130 case View.FOCUS_UP: 131 return SoundEffectConstants.NAVIGATION_REPEAT_UP; 132 } 133 throw new IllegalArgumentException("direction must be one of {FOCUS_UP, FOCUS_DOWN, " 134 + "FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, FOCUS_BACKWARD}."); 135 } else { 136 return getContantForFocusDirection(direction); 137 } 138 } 139 140 /** 141 * @param effectId any of the effect ids defined in {@link SoundEffectConstants} 142 * @return true if the given effect id is a navigation repeat one 143 * @hide 144 */ 145 @VisibleForTesting(visibility = Visibility.PACKAGE) isNavigationRepeat(@avigationSoundEffect int effectId)146 public static boolean isNavigationRepeat(@NavigationSoundEffect int effectId) { 147 return effectId == SoundEffectConstants.NAVIGATION_REPEAT_DOWN 148 || effectId == SoundEffectConstants.NAVIGATION_REPEAT_LEFT 149 || effectId == SoundEffectConstants.NAVIGATION_REPEAT_RIGHT 150 || effectId == SoundEffectConstants.NAVIGATION_REPEAT_UP; 151 } 152 153 /** 154 * @return The next navigation repeat sound effect id, chosen at random in a non-repeating 155 * fashion 156 * @hide 157 */ 158 @VisibleForTesting(visibility = Visibility.PACKAGE) nextNavigationRepeatSoundEffectId()159 public static int nextNavigationRepeatSoundEffectId() { 160 int next = NAVIGATION_REPEAT_RANDOMIZER.nextInt( 161 AudioManager.NUM_NAVIGATION_REPEAT_SOUND_EFFECTS - 1); 162 if (next >= sLastNavigationRepeatSoundEffectId) { 163 next++; 164 } 165 sLastNavigationRepeatSoundEffectId = next; 166 return AudioManager.getNthNavigationRepeatSoundEffect(next); 167 } 168 } 169