VolumePanel: Add support for master volume
Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
committed by
Mike Lockwood
parent
8517e46f3d
commit
8dc1dabd25
@@ -92,6 +92,9 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
private static final int MSG_TIMEOUT = 5;
|
||||
private static final int MSG_RINGER_MODE_CHANGED = 6;
|
||||
|
||||
// Pseudo stream type for master volume
|
||||
private static final int STREAM_MASTER = -1;
|
||||
|
||||
protected Context mContext;
|
||||
private AudioManager mAudioManager;
|
||||
protected AudioService mAudioService;
|
||||
@@ -148,7 +151,13 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
R.string.volume_icon_description_notification,
|
||||
R.drawable.ic_audio_notification,
|
||||
R.drawable.ic_audio_notification_mute,
|
||||
true);
|
||||
true),
|
||||
// for now, use media resources for master volume
|
||||
MasterStream(STREAM_MASTER,
|
||||
R.string.volume_icon_description_media,
|
||||
R.drawable.ic_audio_vol,
|
||||
R.drawable.ic_audio_vol_mute,
|
||||
false);
|
||||
|
||||
int streamType;
|
||||
int descRes;
|
||||
@@ -173,7 +182,8 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
StreamResources.VoiceStream,
|
||||
StreamResources.MediaStream,
|
||||
StreamResources.NotificationStream,
|
||||
StreamResources.AlarmStream
|
||||
StreamResources.AlarmStream,
|
||||
StreamResources.MasterStream
|
||||
};
|
||||
|
||||
/** Object that contains data for each slider */
|
||||
@@ -195,6 +205,16 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
mAudioService = volumeService;
|
||||
|
||||
// For now, only show master volume if master volume is supported
|
||||
boolean useMasterVolume = context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_useMasterVolume);
|
||||
if (useMasterVolume) {
|
||||
for (int i = 0; i < STREAMS.length; i++) {
|
||||
StreamResources streamRes = STREAMS[i];
|
||||
streamRes.show = (streamRes.streamType == STREAM_MASTER);
|
||||
}
|
||||
}
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
View view = mView = inflater.inflate(R.layout.volume_adjust, null);
|
||||
@@ -245,7 +265,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
mVibrator = new Vibrator();
|
||||
|
||||
mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
|
||||
mShowCombinedVolumes = !mVoiceCapable;
|
||||
mShowCombinedVolumes = !mVoiceCapable && !useMasterVolume;
|
||||
// If we don't want to show multiple volumes, hide the settings button and divider
|
||||
if (!mShowCombinedVolumes) {
|
||||
mMoreButton.setVisibility(View.GONE);
|
||||
@@ -274,7 +294,49 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
}
|
||||
|
||||
private boolean isMuted(int streamType) {
|
||||
return mAudioManager.isStreamMute(streamType);
|
||||
if (streamType == STREAM_MASTER) {
|
||||
// master volume mute not yet supported
|
||||
return false;
|
||||
} else {
|
||||
return mAudioService.isStreamMute(streamType);
|
||||
}
|
||||
}
|
||||
|
||||
private int getStreamMaxVolume(int streamType) {
|
||||
// master volume is 0.0f - 1.0f, but we will use 0 - 100 internally
|
||||
if (streamType == STREAM_MASTER) {
|
||||
return 100;
|
||||
} else {
|
||||
return mAudioService.getStreamMaxVolume(streamType);
|
||||
}
|
||||
}
|
||||
|
||||
private int getStreamVolume(int streamType) {
|
||||
// master volume is 0.0f - 1.0f, but we will use 0 - 100 internally
|
||||
if (streamType == STREAM_MASTER) {
|
||||
return Math.round(mAudioService.getMasterVolume() * 100);
|
||||
} else {
|
||||
return mAudioService.getStreamVolume(streamType);
|
||||
}
|
||||
}
|
||||
|
||||
private void setStreamVolume(int streamType, int index, int flags) {
|
||||
// master volume is 0.0f - 1.0f, but we will use 0 - 100 internally
|
||||
if (streamType == STREAM_MASTER) {
|
||||
mAudioService.setMasterVolume((float)index / 100.0f);
|
||||
} else {
|
||||
mAudioService.setStreamVolume(streamType, index, flags);
|
||||
}
|
||||
}
|
||||
|
||||
private int getLastAudibleStreamVolume(int streamType) {
|
||||
// master volume is 0.0f - 1.0f, but we will use 0 - 100 internally
|
||||
if (streamType == STREAM_MASTER) {
|
||||
// master volume mute not yet supported
|
||||
return getStreamVolume(STREAM_MASTER);
|
||||
} else {
|
||||
return mAudioService.getLastAudibleStreamVolume(streamType);
|
||||
}
|
||||
}
|
||||
|
||||
private void createSliders() {
|
||||
@@ -301,7 +363,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
sc.seekbarView = (SeekBar) sc.group.findViewById(R.id.seekbar);
|
||||
int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO ||
|
||||
streamType == AudioSystem.STREAM_VOICE_CALL) ? 1 : 0;
|
||||
sc.seekbarView.setMax(mAudioManager.getStreamMaxVolume(streamType) + plusOne);
|
||||
sc.seekbarView.setMax(getStreamMaxVolume(streamType) + plusOne);
|
||||
sc.seekbarView.setOnSeekBarChangeListener(this);
|
||||
sc.seekbarView.setTag(sc);
|
||||
mStreamControls.put(streamType, sc);
|
||||
@@ -342,7 +404,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
|
||||
/** Update the mute and progress state of a slider */
|
||||
private void updateSlider(StreamControl sc) {
|
||||
sc.seekbarView.setProgress(mAudioManager.getLastAudibleStreamVolume(sc.streamType));
|
||||
sc.seekbarView.setProgress(getLastAudibleStreamVolume(sc.streamType));
|
||||
final boolean muted = isMuted(sc.streamType);
|
||||
sc.icon.setImageResource(muted ? sc.iconMuteRes : sc.iconRes);
|
||||
if (sc.streamType == AudioManager.STREAM_RING && muted
|
||||
@@ -390,6 +452,10 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
obtainMessage(MSG_VOLUME_CHANGED, streamType, flags).sendToTarget();
|
||||
}
|
||||
|
||||
public void postMasterVolumeChanged(int flags) {
|
||||
postVolumeChanged(STREAM_MASTER, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this if you have other work to do when the volume changes (for
|
||||
* example, vibrating, playing a sound, etc.). Make sure to call through to
|
||||
@@ -424,9 +490,9 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
}
|
||||
|
||||
protected void onShowVolumeChanged(int streamType, int flags) {
|
||||
int index = mAudioService.isStreamMute(streamType) ?
|
||||
mAudioService.getLastAudibleStreamVolume(streamType)
|
||||
: mAudioService.getStreamVolume(streamType);
|
||||
int index = isMuted(streamType) ?
|
||||
getLastAudibleStreamVolume(streamType)
|
||||
: getStreamVolume(streamType);
|
||||
|
||||
mRingIsSilent = false;
|
||||
|
||||
@@ -437,7 +503,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
|
||||
// get max volume for progress bar
|
||||
|
||||
int max = mAudioService.getStreamMaxVolume(streamType);
|
||||
int max = getStreamMaxVolume(streamType);
|
||||
|
||||
switch (streamType) {
|
||||
|
||||
@@ -571,6 +637,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
* Lock on this VolumePanel instance as long as you use the returned ToneGenerator.
|
||||
*/
|
||||
private ToneGenerator getOrCreateToneGenerator(int streamType) {
|
||||
if (streamType == STREAM_MASTER) return null;
|
||||
synchronized (this) {
|
||||
if (mToneGenerators[streamType] == null) {
|
||||
try {
|
||||
@@ -671,8 +738,8 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
|
||||
final Object tag = seekBar.getTag();
|
||||
if (fromUser && tag instanceof StreamControl) {
|
||||
StreamControl sc = (StreamControl) tag;
|
||||
if (mAudioManager.getStreamVolume(sc.streamType) != progress) {
|
||||
mAudioManager.setStreamVolume(sc.streamType, progress, 0);
|
||||
if (getStreamVolume(sc.streamType) != progress) {
|
||||
setStreamVolume(sc.streamType, progress, 0);
|
||||
}
|
||||
}
|
||||
resetTimeout();
|
||||
|
||||
@@ -386,7 +386,7 @@ public class AudioManager {
|
||||
* since the last volume key up, so cancel any sounds.
|
||||
*/
|
||||
if (mUseMasterVolume) {
|
||||
adjustMasterVolume(ADJUST_SAME);
|
||||
adjustMasterVolume(ADJUST_SAME, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
|
||||
} else {
|
||||
adjustSuggestedStreamVolume(ADJUST_SAME,
|
||||
stream, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
|
||||
@@ -410,7 +410,8 @@ public class AudioManager {
|
||||
adjustMasterVolume(
|
||||
keyCode == KeyEvent.KEYCODE_VOLUME_UP
|
||||
? ADJUST_RAISE
|
||||
: ADJUST_LOWER);
|
||||
: ADJUST_LOWER,
|
||||
flags);
|
||||
} else {
|
||||
if (mVolumeControlStream != -1) {
|
||||
stream = mVolumeControlStream;
|
||||
@@ -443,7 +444,7 @@ public class AudioManager {
|
||||
*/
|
||||
if (mUseMasterVolume) {
|
||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
|
||||
adjustMasterVolume(ADJUST_SAME);
|
||||
adjustMasterVolume(ADJUST_SAME, FLAG_PLAY_SOUND);
|
||||
}
|
||||
} else {
|
||||
int flags = FLAG_PLAY_SOUND;
|
||||
@@ -549,11 +550,12 @@ public class AudioManager {
|
||||
* @param direction The direction to adjust the volume. One of
|
||||
* {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
|
||||
* {@link #ADJUST_SAME}.
|
||||
* @param flags One or more flags.
|
||||
*/
|
||||
private void adjustMasterVolume(int direction) {
|
||||
private void adjustMasterVolume(int direction, int flags) {
|
||||
IAudioService service = getService();
|
||||
try {
|
||||
service.adjustMasterVolume(direction);
|
||||
service.adjustMasterVolume(direction, flags);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Dead object in adjustMasterVolume", e);
|
||||
}
|
||||
|
||||
@@ -615,7 +615,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
}
|
||||
|
||||
/** @see AudioManager#adjustMasterVolume(int) */
|
||||
public void adjustMasterVolume(int direction) {
|
||||
public void adjustMasterVolume(int direction, int flags) {
|
||||
ensureValidDirection(direction);
|
||||
|
||||
float volume = AudioSystem.getMasterVolume();
|
||||
@@ -631,6 +631,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
long origCallerIdentityToken = Binder.clearCallingIdentity();
|
||||
Settings.System.putFloat(mContentResolver, Settings.System.VOLUME_MASTER, volume);
|
||||
Binder.restoreCallingIdentity(origCallerIdentityToken);
|
||||
mVolumePanel.postMasterVolumeChanged(flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -764,6 +765,14 @@ public class AudioService extends IAudioService.Stub {
|
||||
return (mStreamStates[streamType].getIndex(device, false /* lastAudible */) + 5) / 10;
|
||||
}
|
||||
|
||||
public float getMasterVolume() {
|
||||
return AudioSystem.getMasterVolume();
|
||||
}
|
||||
|
||||
public void setMasterVolume(float volume) {
|
||||
AudioSystem.setMasterVolume(volume);
|
||||
}
|
||||
|
||||
/** @see AudioManager#getStreamMaxVolume(int) */
|
||||
public int getStreamMaxVolume(int streamType) {
|
||||
ensureValidStreamType(streamType);
|
||||
|
||||
@@ -33,7 +33,7 @@ interface IAudioService {
|
||||
|
||||
void adjustStreamVolume(int streamType, int direction, int flags);
|
||||
|
||||
void adjustMasterVolume(int direction);
|
||||
void adjustMasterVolume(int direction, int flags);
|
||||
|
||||
void setStreamVolume(int streamType, int index, int flags);
|
||||
|
||||
@@ -44,7 +44,9 @@ interface IAudioService {
|
||||
boolean isStreamMute(int streamType);
|
||||
|
||||
int getStreamVolume(int streamType);
|
||||
|
||||
|
||||
float getMasterVolume();
|
||||
|
||||
int getStreamMaxVolume(int streamType);
|
||||
|
||||
int getLastAudibleStreamVolume(int streamType);
|
||||
|
||||
Reference in New Issue
Block a user