Loading core/api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -48034,10 +48034,15 @@ package android.view { } public class SoundEffectConstants { method public static int getConstantForFocusDirection(int, boolean); method public static int getContantForFocusDirection(int); field public static final int CLICK = 0; // 0x0 field public static final int NAVIGATION_DOWN = 4; // 0x4 field public static final int NAVIGATION_LEFT = 1; // 0x1 field public static final int NAVIGATION_REPEAT_DOWN = 8; // 0x8 field public static final int NAVIGATION_REPEAT_LEFT = 5; // 0x5 field public static final int NAVIGATION_REPEAT_RIGHT = 7; // 0x7 field public static final int NAVIGATION_REPEAT_UP = 6; // 0x6 field public static final int NAVIGATION_RIGHT = 3; // 0x3 field public static final int NAVIGATION_UP = 2; // 0x2 } core/java/android/view/SoundEffectConstants.java +80 −2 Original line number Diff line number Diff line Loading @@ -16,12 +16,21 @@ package android.view; import android.media.AudioManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; import java.util.Random; /** * Constants to be used to play sound effects via {@link View#playSoundEffect(int)} */ public class SoundEffectConstants { private SoundEffectConstants() {} private static final Random NAVIGATION_REPEAT_RANDOMIZER = new Random(); private static int sLastNavigationRepeatSoundEffectId = -1; public static final int CLICK = 0; Loading @@ -29,6 +38,14 @@ public class SoundEffectConstants { public static final int NAVIGATION_UP = 2; public static final int NAVIGATION_RIGHT = 3; public static final int NAVIGATION_DOWN = 4; /** Sound effect for a repeatedly triggered navigation, e.g. due to long pressing a button */ public static final int NAVIGATION_REPEAT_LEFT = 5; /** @see #NAVIGATION_REPEAT_LEFT */ public static final int NAVIGATION_REPEAT_UP = 6; /** @see #NAVIGATION_REPEAT_LEFT */ public static final int NAVIGATION_REPEAT_RIGHT = 7; /** @see #NAVIGATION_REPEAT_LEFT */ public static final int NAVIGATION_REPEAT_DOWN = 8; /** * Get the sonification constant for the focus directions. Loading @@ -40,7 +57,7 @@ public class SoundEffectConstants { * @throws {@link IllegalArgumentException} when the passed direction is not one of the * documented values. */ public static int getContantForFocusDirection(int direction) { public static int getContantForFocusDirection(@View.FocusDirection int direction) { switch (direction) { case View.FOCUS_RIGHT: return SoundEffectConstants.NAVIGATION_RIGHT; Loading @@ -56,4 +73,65 @@ public class SoundEffectConstants { throw new IllegalArgumentException("direction must be one of " + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, FOCUS_BACKWARD}."); } /** * Get the sonification constant for the focus directions * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN}, * {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT}, {@link View#FOCUS_FORWARD} * or {@link View#FOCUS_BACKWARD} * @param repeating True if the user long-presses a direction * @return The appropriate sonification constant * @throws IllegalArgumentException when the passed direction is not one of the * documented values. */ public static int getConstantForFocusDirection(@View.FocusDirection int direction, boolean repeating) { if (repeating) { switch (direction) { case View.FOCUS_RIGHT: return SoundEffectConstants.NAVIGATION_REPEAT_RIGHT; case View.FOCUS_FORWARD: case View.FOCUS_DOWN: return SoundEffectConstants.NAVIGATION_REPEAT_DOWN; case View.FOCUS_LEFT: return SoundEffectConstants.NAVIGATION_REPEAT_LEFT; case View.FOCUS_BACKWARD: case View.FOCUS_UP: return SoundEffectConstants.NAVIGATION_REPEAT_UP; } throw new IllegalArgumentException("direction must be one of {FOCUS_UP, FOCUS_DOWN, " + "FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, FOCUS_BACKWARD}."); } else { return getContantForFocusDirection(direction); } } /** * @param effectId any of the effect ids defined in {@link SoundEffectConstants} * @return true if the given effect id is a navigation repeat one * @hide */ @VisibleForTesting(visibility = Visibility.PACKAGE) public static boolean isNavigationRepeat(int effectId) { return effectId == SoundEffectConstants.NAVIGATION_REPEAT_DOWN || effectId == SoundEffectConstants.NAVIGATION_REPEAT_LEFT || effectId == SoundEffectConstants.NAVIGATION_REPEAT_RIGHT || effectId == SoundEffectConstants.NAVIGATION_REPEAT_UP; } /** * @return The next navigation repeat sound effect id, chosen at random in a non-repeating * fashion * @hide */ @VisibleForTesting(visibility = Visibility.PACKAGE) public static int nextNavigationRepeatSoundEffectId() { int next = NAVIGATION_REPEAT_RANDOMIZER.nextInt( AudioManager.NUM_NAVIGATION_REPEAT_SOUND_EFFECTS - 1); if (next >= sLastNavigationRepeatSoundEffectId) { next++; } sLastNavigationRepeatSoundEffectId = next; return AudioManager.getNthNavigationRepeatSoundEffect(next); } } core/java/android/view/ViewRootImpl.java +19 −2 Original line number Diff line number Diff line Loading @@ -323,6 +323,8 @@ public final class ViewRootImpl implements ViewParent, private boolean mForceDisableBLAST; private boolean mEnableTripleBuffering; private boolean mFastScrollSoundEffectsEnabled; /** * Signals that compatibility booleans have been initialized according to * target SDK versions. Loading Loading @@ -813,6 +815,8 @@ public final class ViewRootImpl implements ViewParent, loadSystemProperties(); mImeFocusController = new ImeFocusController(this); AudioManager audioManager = mContext.getSystemService(AudioManager.class); mFastScrollSoundEffectsEnabled = audioManager.areNavigationRepeatSoundEffectsEnabled(); } public static void addFirstDrawHandler(Runnable callback) { Loading Loading @@ -6081,8 +6085,10 @@ public final class ViewRootImpl implements ViewParent, v, mTempRect); } if (v.requestFocus(direction, mTempRect)) { playSoundEffect(SoundEffectConstants .getContantForFocusDirection(direction)); boolean isFastScrolling = event.getRepeatCount() > 0; playSoundEffect( SoundEffectConstants.getConstantForFocusDirection(direction, isFastScrolling)); return true; } } Loading Loading @@ -7743,20 +7749,31 @@ public final class ViewRootImpl implements ViewParent, try { final AudioManager audioManager = getAudioManager(); if (mFastScrollSoundEffectsEnabled && SoundEffectConstants.isNavigationRepeat(effectId)) { audioManager.playSoundEffect( SoundEffectConstants.nextNavigationRepeatSoundEffectId()); return; } switch (effectId) { case SoundEffectConstants.CLICK: audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); return; case SoundEffectConstants.NAVIGATION_DOWN: case SoundEffectConstants.NAVIGATION_REPEAT_DOWN: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN); return; case SoundEffectConstants.NAVIGATION_LEFT: case SoundEffectConstants.NAVIGATION_REPEAT_LEFT: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT); return; case SoundEffectConstants.NAVIGATION_RIGHT: case SoundEffectConstants.NAVIGATION_REPEAT_RIGHT: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT); return; case SoundEffectConstants.NAVIGATION_UP: case SoundEffectConstants.NAVIGATION_REPEAT_UP: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP); return; default: Loading core/tests/coretests/src/android/view/SoundEffectConstantsTest.java 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import org.junit.Test; import org.junit.runner.RunWith; /** * Tests for {@link SoundEffectConstants} * * Build/Install/Run: * atest FrameworksCoreTests:SoundEffectConstantsTest */ @SmallTest @RunWith(AndroidJUnit4.class) public class SoundEffectConstantsTest { @Test public void testIsNavigationRepeat() { assertTrue(SoundEffectConstants.isNavigationRepeat( SoundEffectConstants.NAVIGATION_REPEAT_RIGHT)); assertTrue(SoundEffectConstants.isNavigationRepeat( SoundEffectConstants.NAVIGATION_REPEAT_LEFT)); assertTrue( SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_REPEAT_UP)); assertTrue(SoundEffectConstants.isNavigationRepeat( SoundEffectConstants.NAVIGATION_REPEAT_DOWN)); assertFalse(SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_RIGHT)); assertFalse(SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_LEFT)); assertFalse(SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_UP)); assertFalse(SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_DOWN)); assertFalse(SoundEffectConstants.isNavigationRepeat(-1)); } } Loading
core/api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -48034,10 +48034,15 @@ package android.view { } public class SoundEffectConstants { method public static int getConstantForFocusDirection(int, boolean); method public static int getContantForFocusDirection(int); field public static final int CLICK = 0; // 0x0 field public static final int NAVIGATION_DOWN = 4; // 0x4 field public static final int NAVIGATION_LEFT = 1; // 0x1 field public static final int NAVIGATION_REPEAT_DOWN = 8; // 0x8 field public static final int NAVIGATION_REPEAT_LEFT = 5; // 0x5 field public static final int NAVIGATION_REPEAT_RIGHT = 7; // 0x7 field public static final int NAVIGATION_REPEAT_UP = 6; // 0x6 field public static final int NAVIGATION_RIGHT = 3; // 0x3 field public static final int NAVIGATION_UP = 2; // 0x2 }
core/java/android/view/SoundEffectConstants.java +80 −2 Original line number Diff line number Diff line Loading @@ -16,12 +16,21 @@ package android.view; import android.media.AudioManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; import java.util.Random; /** * Constants to be used to play sound effects via {@link View#playSoundEffect(int)} */ public class SoundEffectConstants { private SoundEffectConstants() {} private static final Random NAVIGATION_REPEAT_RANDOMIZER = new Random(); private static int sLastNavigationRepeatSoundEffectId = -1; public static final int CLICK = 0; Loading @@ -29,6 +38,14 @@ public class SoundEffectConstants { public static final int NAVIGATION_UP = 2; public static final int NAVIGATION_RIGHT = 3; public static final int NAVIGATION_DOWN = 4; /** Sound effect for a repeatedly triggered navigation, e.g. due to long pressing a button */ public static final int NAVIGATION_REPEAT_LEFT = 5; /** @see #NAVIGATION_REPEAT_LEFT */ public static final int NAVIGATION_REPEAT_UP = 6; /** @see #NAVIGATION_REPEAT_LEFT */ public static final int NAVIGATION_REPEAT_RIGHT = 7; /** @see #NAVIGATION_REPEAT_LEFT */ public static final int NAVIGATION_REPEAT_DOWN = 8; /** * Get the sonification constant for the focus directions. Loading @@ -40,7 +57,7 @@ public class SoundEffectConstants { * @throws {@link IllegalArgumentException} when the passed direction is not one of the * documented values. */ public static int getContantForFocusDirection(int direction) { public static int getContantForFocusDirection(@View.FocusDirection int direction) { switch (direction) { case View.FOCUS_RIGHT: return SoundEffectConstants.NAVIGATION_RIGHT; Loading @@ -56,4 +73,65 @@ public class SoundEffectConstants { throw new IllegalArgumentException("direction must be one of " + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, FOCUS_BACKWARD}."); } /** * Get the sonification constant for the focus directions * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN}, * {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT}, {@link View#FOCUS_FORWARD} * or {@link View#FOCUS_BACKWARD} * @param repeating True if the user long-presses a direction * @return The appropriate sonification constant * @throws IllegalArgumentException when the passed direction is not one of the * documented values. */ public static int getConstantForFocusDirection(@View.FocusDirection int direction, boolean repeating) { if (repeating) { switch (direction) { case View.FOCUS_RIGHT: return SoundEffectConstants.NAVIGATION_REPEAT_RIGHT; case View.FOCUS_FORWARD: case View.FOCUS_DOWN: return SoundEffectConstants.NAVIGATION_REPEAT_DOWN; case View.FOCUS_LEFT: return SoundEffectConstants.NAVIGATION_REPEAT_LEFT; case View.FOCUS_BACKWARD: case View.FOCUS_UP: return SoundEffectConstants.NAVIGATION_REPEAT_UP; } throw new IllegalArgumentException("direction must be one of {FOCUS_UP, FOCUS_DOWN, " + "FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, FOCUS_BACKWARD}."); } else { return getContantForFocusDirection(direction); } } /** * @param effectId any of the effect ids defined in {@link SoundEffectConstants} * @return true if the given effect id is a navigation repeat one * @hide */ @VisibleForTesting(visibility = Visibility.PACKAGE) public static boolean isNavigationRepeat(int effectId) { return effectId == SoundEffectConstants.NAVIGATION_REPEAT_DOWN || effectId == SoundEffectConstants.NAVIGATION_REPEAT_LEFT || effectId == SoundEffectConstants.NAVIGATION_REPEAT_RIGHT || effectId == SoundEffectConstants.NAVIGATION_REPEAT_UP; } /** * @return The next navigation repeat sound effect id, chosen at random in a non-repeating * fashion * @hide */ @VisibleForTesting(visibility = Visibility.PACKAGE) public static int nextNavigationRepeatSoundEffectId() { int next = NAVIGATION_REPEAT_RANDOMIZER.nextInt( AudioManager.NUM_NAVIGATION_REPEAT_SOUND_EFFECTS - 1); if (next >= sLastNavigationRepeatSoundEffectId) { next++; } sLastNavigationRepeatSoundEffectId = next; return AudioManager.getNthNavigationRepeatSoundEffect(next); } }
core/java/android/view/ViewRootImpl.java +19 −2 Original line number Diff line number Diff line Loading @@ -323,6 +323,8 @@ public final class ViewRootImpl implements ViewParent, private boolean mForceDisableBLAST; private boolean mEnableTripleBuffering; private boolean mFastScrollSoundEffectsEnabled; /** * Signals that compatibility booleans have been initialized according to * target SDK versions. Loading Loading @@ -813,6 +815,8 @@ public final class ViewRootImpl implements ViewParent, loadSystemProperties(); mImeFocusController = new ImeFocusController(this); AudioManager audioManager = mContext.getSystemService(AudioManager.class); mFastScrollSoundEffectsEnabled = audioManager.areNavigationRepeatSoundEffectsEnabled(); } public static void addFirstDrawHandler(Runnable callback) { Loading Loading @@ -6081,8 +6085,10 @@ public final class ViewRootImpl implements ViewParent, v, mTempRect); } if (v.requestFocus(direction, mTempRect)) { playSoundEffect(SoundEffectConstants .getContantForFocusDirection(direction)); boolean isFastScrolling = event.getRepeatCount() > 0; playSoundEffect( SoundEffectConstants.getConstantForFocusDirection(direction, isFastScrolling)); return true; } } Loading Loading @@ -7743,20 +7749,31 @@ public final class ViewRootImpl implements ViewParent, try { final AudioManager audioManager = getAudioManager(); if (mFastScrollSoundEffectsEnabled && SoundEffectConstants.isNavigationRepeat(effectId)) { audioManager.playSoundEffect( SoundEffectConstants.nextNavigationRepeatSoundEffectId()); return; } switch (effectId) { case SoundEffectConstants.CLICK: audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); return; case SoundEffectConstants.NAVIGATION_DOWN: case SoundEffectConstants.NAVIGATION_REPEAT_DOWN: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN); return; case SoundEffectConstants.NAVIGATION_LEFT: case SoundEffectConstants.NAVIGATION_REPEAT_LEFT: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT); return; case SoundEffectConstants.NAVIGATION_RIGHT: case SoundEffectConstants.NAVIGATION_REPEAT_RIGHT: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT); return; case SoundEffectConstants.NAVIGATION_UP: case SoundEffectConstants.NAVIGATION_REPEAT_UP: audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP); return; default: Loading
core/tests/coretests/src/android/view/SoundEffectConstantsTest.java 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import org.junit.Test; import org.junit.runner.RunWith; /** * Tests for {@link SoundEffectConstants} * * Build/Install/Run: * atest FrameworksCoreTests:SoundEffectConstantsTest */ @SmallTest @RunWith(AndroidJUnit4.class) public class SoundEffectConstantsTest { @Test public void testIsNavigationRepeat() { assertTrue(SoundEffectConstants.isNavigationRepeat( SoundEffectConstants.NAVIGATION_REPEAT_RIGHT)); assertTrue(SoundEffectConstants.isNavigationRepeat( SoundEffectConstants.NAVIGATION_REPEAT_LEFT)); assertTrue( SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_REPEAT_UP)); assertTrue(SoundEffectConstants.isNavigationRepeat( SoundEffectConstants.NAVIGATION_REPEAT_DOWN)); assertFalse(SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_RIGHT)); assertFalse(SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_LEFT)); assertFalse(SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_UP)); assertFalse(SoundEffectConstants.isNavigationRepeat(SoundEffectConstants.NAVIGATION_DOWN)); assertFalse(SoundEffectConstants.isNavigationRepeat(-1)); } }