Merge "Add support for navigation repeat sound effects" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
daeb58b574
@@ -48034,10 +48034,15 @@ package android.view {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class SoundEffectConstants {
|
public class SoundEffectConstants {
|
||||||
|
method public static int getConstantForFocusDirection(int, boolean);
|
||||||
method public static int getContantForFocusDirection(int);
|
method public static int getContantForFocusDirection(int);
|
||||||
field public static final int CLICK = 0; // 0x0
|
field public static final int CLICK = 0; // 0x0
|
||||||
field public static final int NAVIGATION_DOWN = 4; // 0x4
|
field public static final int NAVIGATION_DOWN = 4; // 0x4
|
||||||
field public static final int NAVIGATION_LEFT = 1; // 0x1
|
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_RIGHT = 3; // 0x3
|
||||||
field public static final int NAVIGATION_UP = 2; // 0x2
|
field public static final int NAVIGATION_UP = 2; // 0x2
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,21 @@
|
|||||||
|
|
||||||
package android.view;
|
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)}
|
* Constants to be used to play sound effects via {@link View#playSoundEffect(int)}
|
||||||
*/
|
*/
|
||||||
public class SoundEffectConstants {
|
public class SoundEffectConstants {
|
||||||
|
|
||||||
private SoundEffectConstants() {}
|
private SoundEffectConstants() {}
|
||||||
|
private static final Random NAVIGATION_REPEAT_RANDOMIZER = new Random();
|
||||||
|
private static int sLastNavigationRepeatSoundEffectId = -1;
|
||||||
|
|
||||||
public static final int CLICK = 0;
|
public static final int CLICK = 0;
|
||||||
|
|
||||||
@@ -29,6 +38,14 @@ public class SoundEffectConstants {
|
|||||||
public static final int NAVIGATION_UP = 2;
|
public static final int NAVIGATION_UP = 2;
|
||||||
public static final int NAVIGATION_RIGHT = 3;
|
public static final int NAVIGATION_RIGHT = 3;
|
||||||
public static final int NAVIGATION_DOWN = 4;
|
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.
|
* Get the sonification constant for the focus directions.
|
||||||
@@ -40,7 +57,7 @@ public class SoundEffectConstants {
|
|||||||
* @throws {@link IllegalArgumentException} when the passed direction is not one of the
|
* @throws {@link IllegalArgumentException} when the passed direction is not one of the
|
||||||
* documented values.
|
* documented values.
|
||||||
*/
|
*/
|
||||||
public static int getContantForFocusDirection(int direction) {
|
public static int getContantForFocusDirection(@View.FocusDirection int direction) {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case View.FOCUS_RIGHT:
|
case View.FOCUS_RIGHT:
|
||||||
return SoundEffectConstants.NAVIGATION_RIGHT;
|
return SoundEffectConstants.NAVIGATION_RIGHT;
|
||||||
@@ -56,4 +73,65 @@ public class SoundEffectConstants {
|
|||||||
throw new IllegalArgumentException("direction must be one of "
|
throw new IllegalArgumentException("direction must be one of "
|
||||||
+ "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, FOCUS_BACKWARD}.");
|
+ "{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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -323,6 +323,8 @@ public final class ViewRootImpl implements ViewParent,
|
|||||||
private boolean mForceDisableBLAST;
|
private boolean mForceDisableBLAST;
|
||||||
private boolean mEnableTripleBuffering;
|
private boolean mEnableTripleBuffering;
|
||||||
|
|
||||||
|
private boolean mFastScrollSoundEffectsEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals that compatibility booleans have been initialized according to
|
* Signals that compatibility booleans have been initialized according to
|
||||||
* target SDK versions.
|
* target SDK versions.
|
||||||
@@ -813,6 +815,8 @@ public final class ViewRootImpl implements ViewParent,
|
|||||||
|
|
||||||
loadSystemProperties();
|
loadSystemProperties();
|
||||||
mImeFocusController = new ImeFocusController(this);
|
mImeFocusController = new ImeFocusController(this);
|
||||||
|
AudioManager audioManager = mContext.getSystemService(AudioManager.class);
|
||||||
|
mFastScrollSoundEffectsEnabled = audioManager.areNavigationRepeatSoundEffectsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addFirstDrawHandler(Runnable callback) {
|
public static void addFirstDrawHandler(Runnable callback) {
|
||||||
@@ -6081,8 +6085,10 @@ public final class ViewRootImpl implements ViewParent,
|
|||||||
v, mTempRect);
|
v, mTempRect);
|
||||||
}
|
}
|
||||||
if (v.requestFocus(direction, mTempRect)) {
|
if (v.requestFocus(direction, mTempRect)) {
|
||||||
playSoundEffect(SoundEffectConstants
|
boolean isFastScrolling = event.getRepeatCount() > 0;
|
||||||
.getContantForFocusDirection(direction));
|
playSoundEffect(
|
||||||
|
SoundEffectConstants.getConstantForFocusDirection(direction,
|
||||||
|
isFastScrolling));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7743,20 +7749,31 @@ public final class ViewRootImpl implements ViewParent,
|
|||||||
try {
|
try {
|
||||||
final AudioManager audioManager = getAudioManager();
|
final AudioManager audioManager = getAudioManager();
|
||||||
|
|
||||||
|
if (mFastScrollSoundEffectsEnabled
|
||||||
|
&& SoundEffectConstants.isNavigationRepeat(effectId)) {
|
||||||
|
audioManager.playSoundEffect(
|
||||||
|
SoundEffectConstants.nextNavigationRepeatSoundEffectId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (effectId) {
|
switch (effectId) {
|
||||||
case SoundEffectConstants.CLICK:
|
case SoundEffectConstants.CLICK:
|
||||||
audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);
|
audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);
|
||||||
return;
|
return;
|
||||||
case SoundEffectConstants.NAVIGATION_DOWN:
|
case SoundEffectConstants.NAVIGATION_DOWN:
|
||||||
|
case SoundEffectConstants.NAVIGATION_REPEAT_DOWN:
|
||||||
audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN);
|
audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN);
|
||||||
return;
|
return;
|
||||||
case SoundEffectConstants.NAVIGATION_LEFT:
|
case SoundEffectConstants.NAVIGATION_LEFT:
|
||||||
|
case SoundEffectConstants.NAVIGATION_REPEAT_LEFT:
|
||||||
audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT);
|
audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT);
|
||||||
return;
|
return;
|
||||||
case SoundEffectConstants.NAVIGATION_RIGHT:
|
case SoundEffectConstants.NAVIGATION_RIGHT:
|
||||||
|
case SoundEffectConstants.NAVIGATION_REPEAT_RIGHT:
|
||||||
audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT);
|
audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT);
|
||||||
return;
|
return;
|
||||||
case SoundEffectConstants.NAVIGATION_UP:
|
case SoundEffectConstants.NAVIGATION_UP:
|
||||||
|
case SoundEffectConstants.NAVIGATION_REPEAT_UP:
|
||||||
audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP);
|
audioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user