Merge changes from topic 'a11yModal'
* changes: Javadoc and AudioManager update for A11Y stream Conditional behavior for a11y stream volume
This commit is contained in:
committed by
Android (Google) Code Review
commit
1c94fdc469
@@ -801,8 +801,8 @@ public class AudioManager {
|
||||
* management of audio settings or the main telephony application.
|
||||
*
|
||||
* @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL},
|
||||
* {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC} or
|
||||
* {@link #STREAM_ALARM}
|
||||
* {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC},
|
||||
* {@link #STREAM_ALARM} or {@link #STREAM_ACCESSIBILITY}.
|
||||
* @param direction The direction to adjust the volume. One of
|
||||
* {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
|
||||
* {@link #ADJUST_SAME}.
|
||||
@@ -3195,7 +3195,8 @@ public class AudioManager {
|
||||
* {@link #STREAM_MUSIC},
|
||||
* {@link #STREAM_ALARM},
|
||||
* {@link #STREAM_NOTIFICATION},
|
||||
* {@link #STREAM_DTMF}.
|
||||
* {@link #STREAM_DTMF},
|
||||
* {@link #STREAM_ACCESSIBILITY}.
|
||||
*
|
||||
* @return The bit-mask "or" of audio output device codes for all enabled devices on this
|
||||
* stream. Zero or more of
|
||||
@@ -3238,6 +3239,7 @@ public class AudioManager {
|
||||
case STREAM_ALARM:
|
||||
case STREAM_NOTIFICATION:
|
||||
case STREAM_DTMF:
|
||||
case STREAM_ACCESSIBILITY:
|
||||
return AudioSystem.getDevicesForStream(streamType);
|
||||
default:
|
||||
return 0;
|
||||
|
||||
@@ -32,4 +32,11 @@ oneway interface IVolumeController {
|
||||
void setLayoutDirection(int layoutDirection);
|
||||
|
||||
void dismiss();
|
||||
|
||||
/**
|
||||
* Change the a11y mode.
|
||||
* @param a11yMode one of {@link VolumePolicy#A11Y_MODE_MEDIA_A11Y_VOLUME},
|
||||
* {@link VolumePolicy#A11Y_MODE_INDEPENDENT_A11Y_VOLUME}
|
||||
*/
|
||||
void setA11yMode(int mode);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,17 @@ import java.util.Objects;
|
||||
public final class VolumePolicy implements Parcelable {
|
||||
public static final VolumePolicy DEFAULT = new VolumePolicy(false, false, true, 400);
|
||||
|
||||
/**
|
||||
* Accessibility volume policy where the STREAM_MUSIC volume (i.e. media volume) affects
|
||||
* the STREAM_ACCESSIBILITY volume, and vice-versa.
|
||||
*/
|
||||
public static final int A11Y_MODE_MEDIA_A11Y_VOLUME = 0;
|
||||
/**
|
||||
* Accessibility volume policy where the STREAM_ACCESSIBILITY volume is independent from
|
||||
* any other volume.
|
||||
*/
|
||||
public static final int A11Y_MODE_INDEPENDENT_A11Y_VOLUME = 1;
|
||||
|
||||
/** Allow volume adjustments lower from vibrate to enter ringer mode = silent */
|
||||
public final boolean volumeDownToEnterSilent;
|
||||
|
||||
|
||||
@@ -1120,6 +1120,7 @@
|
||||
<item></item> <!-- STREAM_SYSTEM_ENFORCED -->
|
||||
<item></item> <!-- STREAM_DTMF -->
|
||||
<item></item> <!-- STREAM_TTS -->
|
||||
<item>Accessibility</item> <!-- STREAM_ACCESSIBILITY -->
|
||||
</string-array>
|
||||
|
||||
<string name="volume_stream_muted" translatable="false">%s silent</string>
|
||||
|
||||
@@ -78,6 +78,7 @@ public class VolumeDialogController {
|
||||
AudioSystem.STREAM_SYSTEM_ENFORCED,
|
||||
AudioSystem.STREAM_TTS,
|
||||
AudioSystem.STREAM_VOICE_CALL,
|
||||
AudioSystem.STREAM_ACCESSIBILITY,
|
||||
};
|
||||
|
||||
private final HandlerThread mWorkerThread;
|
||||
@@ -562,6 +563,22 @@ public class VolumeDialogController {
|
||||
.sendToTarget();
|
||||
mWorker.sendEmptyMessage(W.DISMISS_REQUESTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setA11yMode(int mode) {
|
||||
if (D.BUG) Log.d(TAG, "setA11yMode to " + mode);
|
||||
if (mDestroyed) return;
|
||||
switch (mode) {
|
||||
case VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME:
|
||||
// "legacy" mode
|
||||
break;
|
||||
case VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME:
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Invalid accessibility mode " + mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class W extends Handler {
|
||||
|
||||
@@ -139,7 +139,9 @@ import java.util.Objects;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class AudioService extends IAudioService.Stub {
|
||||
public class AudioService extends IAudioService.Stub
|
||||
implements AccessibilityManager.TouchExplorationStateChangeListener,
|
||||
AccessibilityManager.AccessibilityStateChangeListener{
|
||||
|
||||
private static final String TAG = "AudioService";
|
||||
|
||||
@@ -775,7 +777,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
TAG,
|
||||
SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);
|
||||
|
||||
StreamOverride.init(mContext);
|
||||
initA11yMonitoring(mContext);
|
||||
mControllerService.init();
|
||||
onIndicateSystemReady();
|
||||
}
|
||||
@@ -972,6 +974,8 @@ public class AudioService extends IAudioService.Stub {
|
||||
|
||||
private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
|
||||
int dtmfStreamAlias;
|
||||
final int a11yStreamAlias = sIndependentA11yVolume ?
|
||||
AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC;
|
||||
|
||||
if (mIsSingleVolume) {
|
||||
mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION;
|
||||
@@ -1000,9 +1004,13 @@ public class AudioService extends IAudioService.Stub {
|
||||
}
|
||||
|
||||
mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
|
||||
mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
|
||||
|
||||
if (updateVolumes) {
|
||||
mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
|
||||
caller);
|
||||
mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
|
||||
mStreamStates[a11yStreamAlias], caller);
|
||||
// apply stream mute states according to new value of mRingerModeAffectedStreams
|
||||
setRingerModeInt(getRingerModeInternal(), false);
|
||||
sendMsg(mAudioHandler,
|
||||
@@ -1011,6 +1019,12 @@ public class AudioService extends IAudioService.Stub {
|
||||
0,
|
||||
0,
|
||||
mStreamStates[AudioSystem.STREAM_DTMF], 0);
|
||||
sendMsg(mAudioHandler,
|
||||
MSG_SET_ALL_VOLUMES,
|
||||
SENDMSG_QUEUE,
|
||||
0,
|
||||
0,
|
||||
mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1536,6 +1550,10 @@ public class AudioService extends IAudioService.Stub {
|
||||
|
||||
private void setStreamVolume(int streamType, int index, int flags, String callingPackage,
|
||||
String caller, int uid) {
|
||||
if (DEBUG_VOL) {
|
||||
Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
|
||||
+ ", calling=" + callingPackage + ")");
|
||||
}
|
||||
if (mUseFixedVolume) {
|
||||
return;
|
||||
}
|
||||
@@ -3639,7 +3657,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
return AudioSystem.STREAM_VOICE_CALL;
|
||||
}
|
||||
} else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
|
||||
if (isAfMusicActiveRecently(StreamOverride.sDelayMs)) {
|
||||
if (isAfMusicActiveRecently(sStreamOverrideDelayMs)) {
|
||||
if (DEBUG_VOL)
|
||||
Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active");
|
||||
return AudioSystem.STREAM_MUSIC;
|
||||
@@ -3665,13 +3683,13 @@ public class AudioService extends IAudioService.Stub {
|
||||
return AudioSystem.STREAM_VOICE_CALL;
|
||||
}
|
||||
} else if (AudioSystem.isStreamActive(AudioSystem.STREAM_NOTIFICATION,
|
||||
StreamOverride.sDelayMs) ||
|
||||
sStreamOverrideDelayMs) ||
|
||||
AudioSystem.isStreamActive(AudioSystem.STREAM_RING,
|
||||
StreamOverride.sDelayMs)) {
|
||||
sStreamOverrideDelayMs)) {
|
||||
if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
|
||||
return AudioSystem.STREAM_NOTIFICATION;
|
||||
} else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
|
||||
if (isAfMusicActiveRecently(StreamOverride.sDelayMs)) {
|
||||
if (isAfMusicActiveRecently(sStreamOverrideDelayMs)) {
|
||||
if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: forcing STREAM_MUSIC");
|
||||
return AudioSystem.STREAM_MUSIC;
|
||||
} else {
|
||||
@@ -5861,44 +5879,67 @@ public class AudioService extends IAudioService.Stub {
|
||||
}
|
||||
|
||||
//==========================================================================================
|
||||
// Accessibility: taking touch exploration into account for selecting the default
|
||||
// Accessibility
|
||||
|
||||
private void initA11yMonitoring(Context ctxt) {
|
||||
AccessibilityManager accessibilityManager =
|
||||
(AccessibilityManager) ctxt.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
|
||||
updateA11yVolumeAlias(accessibilityManager.isEnabled());
|
||||
accessibilityManager.addTouchExplorationStateChangeListener(this);
|
||||
accessibilityManager.addAccessibilityStateChangeListener(this);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// A11y: taking touch exploration into account for selecting the default
|
||||
// stream override timeout when adjusting volume
|
||||
//==========================================================================================
|
||||
private static class StreamOverride
|
||||
implements AccessibilityManager.TouchExplorationStateChangeListener {
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
// AudioService.getActiveStreamType() will return:
|
||||
// - STREAM_NOTIFICATION on tablets during this period after a notification stopped
|
||||
// - STREAM_MUSIC on phones during this period after music or talkback/voice search prompt
|
||||
// stopped
|
||||
private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
|
||||
private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
|
||||
// AudioService.getActiveStreamType() will return:
|
||||
// - STREAM_NOTIFICATION on tablets during this period after a notification stopped
|
||||
// - STREAM_MUSIC on phones during this period after music or talkback/voice search prompt
|
||||
// stopped
|
||||
private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
|
||||
private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
|
||||
|
||||
static int sDelayMs;
|
||||
private static int sStreamOverrideDelayMs;
|
||||
|
||||
static void init(Context ctxt) {
|
||||
AccessibilityManager accessibilityManager =
|
||||
(AccessibilityManager) ctxt.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
updateDefaultStreamOverrideDelay(
|
||||
accessibilityManager.isTouchExplorationEnabled());
|
||||
accessibilityManager.addTouchExplorationStateChangeListener(
|
||||
new StreamOverride());
|
||||
@Override
|
||||
public void onTouchExplorationStateChanged(boolean enabled) {
|
||||
updateDefaultStreamOverrideDelay(enabled);
|
||||
}
|
||||
|
||||
private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) {
|
||||
if (touchExploreEnabled) {
|
||||
sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS;
|
||||
} else {
|
||||
sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS;
|
||||
}
|
||||
if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled
|
||||
+ " stream override delay is now " + sStreamOverrideDelayMs + " ms");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTouchExplorationStateChanged(boolean enabled) {
|
||||
updateDefaultStreamOverrideDelay(enabled);
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
// A11y: taking a11y state into account for the handling of a11y prompts volume
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
private static void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) {
|
||||
if (touchExploreEnabled) {
|
||||
sDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS;
|
||||
} else {
|
||||
sDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS;
|
||||
}
|
||||
if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled
|
||||
+ " stream override delay is now " + sDelayMs + " ms");
|
||||
}
|
||||
private static boolean sIndependentA11yVolume = false;
|
||||
|
||||
@Override
|
||||
public void onAccessibilityStateChanged(boolean enabled) {
|
||||
updateA11yVolumeAlias(enabled);
|
||||
}
|
||||
|
||||
private void updateA11yVolumeAlias(boolean a11Enabled) {
|
||||
if (DEBUG_VOL) Log.d(TAG, "Accessibility mode changed to " + a11Enabled);
|
||||
// a11y has its own volume stream when a11y service is enabled
|
||||
sIndependentA11yVolume = a11Enabled;
|
||||
// update the volume mapping scheme
|
||||
updateStreamVolumeAlias(true /*updateVolumes*/, TAG);
|
||||
// update the volume controller behavior
|
||||
mVolumeController.setA11yMode(sIndependentA11yVolume ?
|
||||
VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
|
||||
VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
|
||||
}
|
||||
|
||||
//==========================================================================================
|
||||
@@ -6178,6 +6219,16 @@ public class AudioService extends IAudioService.Stub {
|
||||
Log.w(TAG, "Error calling dismiss", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setA11yMode(int a11yMode) {
|
||||
if (mController == null)
|
||||
return;
|
||||
try {
|
||||
mController.setA11yMode(a11yMode);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Error calling setA11Mode", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user