Merge "Expanded volume panel with sliders and mute buttons." into honeycomb
This commit is contained in:
committed by
Android (Google) Code Review
commit
823fbbbab5
@@ -16,10 +16,17 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.bluetooth.HeadsetBase;
|
||||
import com.android.internal.R;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioService;
|
||||
import android.media.AudioSystem;
|
||||
@@ -29,12 +36,16 @@ import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Vibrator;
|
||||
import android.util.Config;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Handle the volume up and down keys.
|
||||
@@ -43,7 +54,7 @@ import android.widget.Toast;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class VolumePanel extends Handler
|
||||
public class VolumePanel extends Handler implements OnSeekBarChangeListener, View.OnClickListener
|
||||
{
|
||||
private static final String TAG = "VolumePanel";
|
||||
private static boolean LOGD = false;
|
||||
@@ -68,62 +79,255 @@ public class VolumePanel extends Handler
|
||||
private static final int BEEP_DURATION = 150;
|
||||
private static final int MAX_VOLUME = 100;
|
||||
private static final int FREE_DELAY = 10000;
|
||||
private static final int TIMEOUT_DELAY = 3000;
|
||||
|
||||
private static final int MSG_VOLUME_CHANGED = 0;
|
||||
private static final int MSG_FREE_RESOURCES = 1;
|
||||
private static final int MSG_PLAY_SOUND = 2;
|
||||
private static final int MSG_STOP_SOUNDS = 3;
|
||||
private static final int MSG_VIBRATE = 4;
|
||||
private static final int MSG_TIMEOUT = 5;
|
||||
private static final int MSG_RINGER_MODE_CHANGED = 6;
|
||||
|
||||
private static final int RINGTONE_VOLUME_TEXT = com.android.internal.R.string.volume_ringtone;
|
||||
private static final int MUSIC_VOLUME_TEXT = com.android.internal.R.string.volume_music;
|
||||
private static final int INCALL_VOLUME_TEXT = com.android.internal.R.string.volume_call;
|
||||
private static final int ALARM_VOLUME_TEXT = com.android.internal.R.string.volume_alarm;
|
||||
private static final int UNKNOWN_VOLUME_TEXT = com.android.internal.R.string.volume_unknown;
|
||||
private static final int NOTIFICATION_VOLUME_TEXT =
|
||||
com.android.internal.R.string.volume_notification;
|
||||
private static final int BLUETOOTH_INCALL_VOLUME_TEXT =
|
||||
com.android.internal.R.string.volume_bluetooth_call;
|
||||
// private static final int RINGTONE_VOLUME_TEXT = com.android.internal.R.string.volume_ringtone;
|
||||
// private static final int MUSIC_VOLUME_TEXT = com.android.internal.R.string.volume_music;
|
||||
// private static final int INCALL_VOLUME_TEXT = com.android.internal.R.string.volume_call;
|
||||
// private static final int ALARM_VOLUME_TEXT = com.android.internal.R.string.volume_alarm;
|
||||
// private static final int UNKNOWN_VOLUME_TEXT = com.android.internal.R.string.volume_unknown;
|
||||
// private static final int NOTIFICATION_VOLUME_TEXT =
|
||||
// com.android.internal.R.string.volume_notification;
|
||||
// private static final int BLUETOOTH_INCALL_VOLUME_TEXT =
|
||||
// com.android.internal.R.string.volume_bluetooth_call;
|
||||
|
||||
protected Context mContext;
|
||||
private AudioManager mAudioManager;
|
||||
protected AudioService mAudioService;
|
||||
private boolean mRingIsSilent;
|
||||
|
||||
private final Toast mToast;
|
||||
/** Dialog containing all the sliders */
|
||||
private final Dialog mDialog;
|
||||
/** Dialog's content view */
|
||||
private final View mView;
|
||||
private final TextView mMessage;
|
||||
private final TextView mAdditionalMessage;
|
||||
private final ImageView mSmallStreamIcon;
|
||||
private final ImageView mLargeStreamIcon;
|
||||
private final ProgressBar mLevel;
|
||||
// private final TextView mMessage;
|
||||
// private final TextView mAdditionalMessage;
|
||||
// private final ImageView mSmallStreamIcon;
|
||||
// private final ImageView mLargeStreamIcon;
|
||||
// private final ProgressBar mLevel;
|
||||
|
||||
/** Contains the sliders and their touchable icons */
|
||||
private final ViewGroup mSliderGroup;
|
||||
/** The button that expands the dialog to show all sliders */
|
||||
private final View mMoreButton;
|
||||
/** Dummy divider icon that needs to vanish with the more button */
|
||||
private final View mDivider;
|
||||
|
||||
/** Currently active stream that shows up at the top of the list of sliders */
|
||||
private int mActiveStreamType = -1;
|
||||
/** All the slider controls mapped by stream type */
|
||||
private HashMap<Integer,StreamControl> mStreamControls;
|
||||
|
||||
// List of stream types and their order
|
||||
// RING and VOICE_CALL are hidden unless explicitly requested
|
||||
private static final int [] STREAM_TYPES = {
|
||||
AudioManager.STREAM_RING,
|
||||
AudioManager.STREAM_VOICE_CALL,
|
||||
AudioManager.STREAM_MUSIC,
|
||||
AudioManager.STREAM_NOTIFICATION
|
||||
};
|
||||
|
||||
// These icons need to correspond to the ones above.
|
||||
private static final int [] STREAM_ICONS_NORMAL = {
|
||||
R.drawable.ic_audio_phone,
|
||||
R.drawable.ic_audio_phone,
|
||||
R.drawable.ic_audio_vol,
|
||||
R.drawable.ic_audio_notification,
|
||||
};
|
||||
|
||||
// These icons need to correspond to the ones above.
|
||||
private static final int [] STREAM_ICONS_MUTED = {
|
||||
R.drawable.ic_audio_phone,
|
||||
R.drawable.ic_audio_phone,
|
||||
R.drawable.ic_audio_vol_mute,
|
||||
R.drawable.ic_audio_notification_mute,
|
||||
};
|
||||
|
||||
/** Object that contains data for each slider */
|
||||
private class StreamControl {
|
||||
int streamType;
|
||||
ViewGroup group;
|
||||
ImageView icon;
|
||||
SeekBar seekbarView;
|
||||
int iconRes;
|
||||
int iconMuteRes;
|
||||
}
|
||||
|
||||
// Synchronize when accessing this
|
||||
private ToneGenerator mToneGenerators[];
|
||||
private Vibrator mVibrator;
|
||||
|
||||
public VolumePanel(Context context, AudioService volumeService) {
|
||||
public VolumePanel(final Context context, AudioService volumeService) {
|
||||
mContext = context;
|
||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
mAudioService = volumeService;
|
||||
mToast = new Toast(context);
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) context
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
View view = mView = inflater.inflate(com.android.internal.R.layout.volume_adjust, null);
|
||||
mMessage = (TextView) view.findViewById(com.android.internal.R.id.message);
|
||||
mAdditionalMessage =
|
||||
(TextView) view.findViewById(com.android.internal.R.id.additional_message);
|
||||
mSmallStreamIcon = (ImageView) view.findViewById(com.android.internal.R.id.other_stream_icon);
|
||||
mLargeStreamIcon = (ImageView) view.findViewById(com.android.internal.R.id.ringer_stream_icon);
|
||||
mLevel = (ProgressBar) view.findViewById(com.android.internal.R.id.level);
|
||||
View view = mView = inflater.inflate(R.layout.volume_adjust, null);
|
||||
mView.setOnTouchListener(new View.OnTouchListener() {
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
resetTimeout();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
mSliderGroup = (ViewGroup) mView.findViewById(R.id.slider_group);
|
||||
mMoreButton = (ImageView) mView.findViewById(R.id.expand_button);
|
||||
mMoreButton.setOnClickListener(this);
|
||||
mDivider = (ImageView) mView.findViewById(R.id.expand_button_divider);
|
||||
|
||||
mDialog = new Dialog(context, R.style.Theme_Panel_Volume);
|
||||
mDialog.setTitle("Volume control"); // No need to localize
|
||||
mDialog.setContentView(mView);
|
||||
mDialog.setOnDismissListener(new OnDismissListener() {
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
mActiveStreamType = -1;
|
||||
}
|
||||
});
|
||||
// Change some window properties
|
||||
Window window = mDialog.getWindow();
|
||||
window.setGravity(Gravity.TOP);
|
||||
WindowManager.LayoutParams lp = window.getAttributes();
|
||||
lp.token = null;
|
||||
lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
|
||||
window.setAttributes(lp);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
|
||||
|
||||
// mMessage = (TextView) view.findViewById(com.android.internal.R.id.message);
|
||||
// mAdditionalMessage =
|
||||
// (TextView) view.findViewById(com.android.internal.R.id.additional_message);
|
||||
// mSmallStreamIcon = (ImageView) view.findViewById(com.android.internal.R.id.other_stream_icon);
|
||||
// mLargeStreamIcon = (ImageView) view.findViewById(com.android.internal.R.id.ringer_stream_icon);
|
||||
// mLevel = (ProgressBar) view.findViewById(com.android.internal.R.id.level);
|
||||
|
||||
mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
|
||||
mVibrator = new Vibrator();
|
||||
|
||||
listenToRingerMode();
|
||||
}
|
||||
|
||||
private void listenToRingerMode() {
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
|
||||
mContext.registerReceiver(new BroadcastReceiver() {
|
||||
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
|
||||
removeMessages(MSG_RINGER_MODE_CHANGED);
|
||||
sendMessage(obtainMessage(MSG_RINGER_MODE_CHANGED));
|
||||
}
|
||||
}
|
||||
}, filter);
|
||||
}
|
||||
|
||||
private boolean isMuted(int streamType) {
|
||||
return mAudioManager.isStreamMute(streamType);
|
||||
}
|
||||
|
||||
private void createSliders() {
|
||||
LayoutInflater inflater = (LayoutInflater) mContext
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mStreamControls = new HashMap<Integer,StreamControl>(STREAM_TYPES.length);
|
||||
for (int i = 0; i < STREAM_TYPES.length; i++) {
|
||||
StreamControl sc = new StreamControl();
|
||||
sc.streamType = STREAM_TYPES[i];
|
||||
sc.group = (ViewGroup) inflater.inflate(R.layout.volume_adjust_item, null);
|
||||
sc.group.setTag(sc);
|
||||
sc.icon = (ImageView) sc.group.findViewById(R.id.stream_icon);
|
||||
sc.icon.setOnClickListener(this);
|
||||
sc.icon.setTag(sc);
|
||||
sc.iconRes = STREAM_ICONS_NORMAL[i];
|
||||
sc.iconMuteRes = STREAM_ICONS_MUTED[i];
|
||||
sc.icon.setImageResource(sc.iconRes);
|
||||
sc.seekbarView = (SeekBar) sc.group.findViewById(R.id.seekbar);
|
||||
sc.seekbarView.setMax(mAudioManager.getStreamMaxVolume(STREAM_TYPES[i]));
|
||||
sc.seekbarView.setOnSeekBarChangeListener(this);
|
||||
sc.seekbarView.setTag(sc);
|
||||
mStreamControls.put(STREAM_TYPES[i], sc);
|
||||
}
|
||||
}
|
||||
|
||||
private void reorderSliders(int activeStreamType) {
|
||||
mSliderGroup.removeAllViews();
|
||||
|
||||
StreamControl active = mStreamControls.get(activeStreamType);
|
||||
if (active == null) {
|
||||
Log.e("VolumePanel", "Missing stream type! - " + activeStreamType);
|
||||
mActiveStreamType = -1;
|
||||
} else {
|
||||
mSliderGroup.addView(active.group);
|
||||
mActiveStreamType = activeStreamType;
|
||||
active.group.setVisibility(View.VISIBLE);
|
||||
updateSlider(active);
|
||||
}
|
||||
|
||||
for (int i = 0; i < STREAM_TYPES.length; i++) {
|
||||
// Skip the phone specific ones and the active one
|
||||
final int streamType = STREAM_TYPES[i];
|
||||
if (streamType == AudioManager.STREAM_RING
|
||||
|| streamType == AudioManager.STREAM_VOICE_CALL
|
||||
|| streamType == activeStreamType) {
|
||||
continue;
|
||||
}
|
||||
StreamControl sc = mStreamControls.get(streamType);
|
||||
mSliderGroup.addView(sc.group);
|
||||
updateSlider(sc);
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the mute and progress state of a slider */
|
||||
private void updateSlider(StreamControl sc) {
|
||||
sc.seekbarView.setProgress(mAudioManager.getLastAudibleStreamVolume(sc.streamType));
|
||||
final boolean muted = isMuted(sc.streamType);
|
||||
sc.icon.setImageResource(muted ? sc.iconMuteRes : sc.iconRes);
|
||||
sc.seekbarView.setEnabled(!muted);
|
||||
}
|
||||
|
||||
private boolean isExpanded() {
|
||||
return mMoreButton.getVisibility() != View.VISIBLE;
|
||||
}
|
||||
|
||||
private void expand() {
|
||||
final int count = mSliderGroup.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
mSliderGroup.getChildAt(i).setVisibility(View.VISIBLE);
|
||||
}
|
||||
mMoreButton.setVisibility(View.INVISIBLE);
|
||||
mDivider.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
private void collapse() {
|
||||
mMoreButton.setVisibility(View.VISIBLE);
|
||||
mDivider.setVisibility(View.VISIBLE);
|
||||
final int count = mSliderGroup.getChildCount();
|
||||
for (int i = 1; i < count; i++) {
|
||||
mSliderGroup.getChildAt(i).setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStates() {
|
||||
final int count = mSliderGroup.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
StreamControl sc = (StreamControl) mSliderGroup.getChildAt(i).getTag();
|
||||
updateSlider(sc);
|
||||
}
|
||||
}
|
||||
|
||||
public void postVolumeChanged(int streamType, int flags) {
|
||||
if (hasMessages(MSG_VOLUME_CHANGED)) return;
|
||||
if (mStreamControls == null) {
|
||||
createSliders();
|
||||
}
|
||||
removeMessages(MSG_FREE_RESOURCES);
|
||||
obtainMessage(MSG_VOLUME_CHANGED, streamType, flags).sendToTarget();
|
||||
}
|
||||
@@ -137,6 +341,10 @@ public class VolumePanel extends Handler
|
||||
|
||||
if (LOGD) Log.d(TAG, "onVolumeChanged(streamType: " + streamType + ", flags: " + flags + ")");
|
||||
|
||||
if (mActiveStreamType == -1) {
|
||||
reorderSliders(streamType);
|
||||
}
|
||||
|
||||
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
|
||||
onShowVolumeChanged(streamType, flags);
|
||||
}
|
||||
@@ -154,12 +362,14 @@ public class VolumePanel extends Handler
|
||||
|
||||
removeMessages(MSG_FREE_RESOURCES);
|
||||
sendMessageDelayed(obtainMessage(MSG_FREE_RESOURCES), FREE_DELAY);
|
||||
|
||||
resetTimeout();
|
||||
}
|
||||
|
||||
protected void onShowVolumeChanged(int streamType, int flags) {
|
||||
int index = mAudioService.getStreamVolume(streamType);
|
||||
int message = UNKNOWN_VOLUME_TEXT;
|
||||
int additionalMessage = 0;
|
||||
// int message = UNKNOWN_VOLUME_TEXT;
|
||||
// int additionalMessage = 0;
|
||||
mRingIsSilent = false;
|
||||
|
||||
if (LOGD) {
|
||||
@@ -168,31 +378,35 @@ public class VolumePanel extends Handler
|
||||
}
|
||||
|
||||
// get max volume for progress bar
|
||||
|
||||
int max = mAudioService.getStreamMaxVolume(streamType);
|
||||
|
||||
switch (streamType) {
|
||||
|
||||
case AudioManager.STREAM_RING: {
|
||||
setRingerIcon();
|
||||
message = RINGTONE_VOLUME_TEXT;
|
||||
// setRingerIcon();
|
||||
// message = RINGTONE_VOLUME_TEXT;
|
||||
Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
|
||||
mContext, RingtoneManager.TYPE_RINGTONE);
|
||||
if (ringuri == null) {
|
||||
additionalMessage =
|
||||
com.android.internal.R.string.volume_music_hint_silent_ringtone_selected;
|
||||
// additionalMessage =
|
||||
// com.android.internal.R.string.volume_music_hint_silent_ringtone_selected;
|
||||
mRingIsSilent = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AudioManager.STREAM_MUSIC: {
|
||||
message = MUSIC_VOLUME_TEXT;
|
||||
// message = MUSIC_VOLUME_TEXT;
|
||||
// Special case for when Bluetooth is active for music
|
||||
if (mAudioManager.isBluetoothA2dpOn()) {
|
||||
additionalMessage =
|
||||
com.android.internal.R.string.volume_music_hint_playing_through_bluetooth;
|
||||
setLargeIcon(com.android.internal.R.drawable.ic_volume_bluetooth_ad2p);
|
||||
// additionalMessage =
|
||||
// com.android.internal.R.string.volume_music_hint_playing_through_bluetooth;
|
||||
// setLargeIcon(com.android.internal.R.drawable.ic_volume_bluetooth_ad2p);
|
||||
setMusicIcon(R.drawable.ic_audio_bt, R.drawable.ic_audio_bt_mute);
|
||||
} else {
|
||||
setSmallIcon(index);
|
||||
setMusicIcon(R.drawable.ic_audio_vol, R.drawable.ic_audio_vol_mute);
|
||||
// setSmallIcon(index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -205,25 +419,25 @@ public class VolumePanel extends Handler
|
||||
*/
|
||||
index++;
|
||||
max++;
|
||||
message = INCALL_VOLUME_TEXT;
|
||||
setSmallIcon(index);
|
||||
// message = INCALL_VOLUME_TEXT;
|
||||
// setSmallIcon(index);
|
||||
break;
|
||||
}
|
||||
|
||||
case AudioManager.STREAM_ALARM: {
|
||||
message = ALARM_VOLUME_TEXT;
|
||||
setSmallIcon(index);
|
||||
// message = ALARM_VOLUME_TEXT;
|
||||
// setSmallIcon(index);
|
||||
break;
|
||||
}
|
||||
|
||||
case AudioManager.STREAM_NOTIFICATION: {
|
||||
message = NOTIFICATION_VOLUME_TEXT;
|
||||
setSmallIcon(index);
|
||||
// message = NOTIFICATION_VOLUME_TEXT;
|
||||
// setSmallIcon(index);
|
||||
Uri ringuri = RingtoneManager.getActualDefaultRingtoneUri(
|
||||
mContext, RingtoneManager.TYPE_NOTIFICATION);
|
||||
if (ringuri == null) {
|
||||
additionalMessage =
|
||||
com.android.internal.R.string.volume_music_hint_silent_ringtone_selected;
|
||||
// additionalMessage =
|
||||
// com.android.internal.R.string.volume_music_hint_silent_ringtone_selected;
|
||||
mRingIsSilent = true;
|
||||
}
|
||||
break;
|
||||
@@ -237,34 +451,41 @@ public class VolumePanel extends Handler
|
||||
*/
|
||||
index++;
|
||||
max++;
|
||||
message = BLUETOOTH_INCALL_VOLUME_TEXT;
|
||||
setLargeIcon(com.android.internal.R.drawable.ic_volume_bluetooth_in_call);
|
||||
// message = BLUETOOTH_INCALL_VOLUME_TEXT;
|
||||
// setLargeIcon(com.android.internal.R.drawable.ic_volume_bluetooth_in_call);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String messageString = Resources.getSystem().getString(message);
|
||||
if (!mMessage.getText().equals(messageString)) {
|
||||
mMessage.setText(messageString);
|
||||
// String messageString = Resources.getSystem().getString(message);
|
||||
// if (!mMessage.getText().equals(messageString)) {
|
||||
// mMessage.setText(messageString);
|
||||
// }
|
||||
//
|
||||
// if (additionalMessage == 0) {
|
||||
// mAdditionalMessage.setVisibility(View.GONE);
|
||||
// } else {
|
||||
// mAdditionalMessage.setVisibility(View.VISIBLE);
|
||||
// mAdditionalMessage.setText(Resources.getSystem().getString(additionalMessage));
|
||||
// }
|
||||
|
||||
// if (max != mLevel.getMax()) {
|
||||
// mLevel.setMax(max);
|
||||
// }
|
||||
// mLevel.setProgress(index);
|
||||
|
||||
StreamControl sc = mStreamControls.get(streamType);
|
||||
if (sc != null) {
|
||||
sc.seekbarView.setProgress(index);
|
||||
}
|
||||
|
||||
if (additionalMessage == 0) {
|
||||
mAdditionalMessage.setVisibility(View.GONE);
|
||||
} else {
|
||||
mAdditionalMessage.setVisibility(View.VISIBLE);
|
||||
mAdditionalMessage.setText(Resources.getSystem().getString(additionalMessage));
|
||||
if (!mDialog.isShowing()) {
|
||||
mDialog.setContentView(mView);
|
||||
// Showing dialog - use collapsed state
|
||||
collapse();
|
||||
mDialog.show();
|
||||
}
|
||||
|
||||
if (max != mLevel.getMax()) {
|
||||
mLevel.setMax(max);
|
||||
}
|
||||
mLevel.setProgress(index);
|
||||
|
||||
mToast.setView(mView);
|
||||
mToast.setDuration(Toast.LENGTH_SHORT);
|
||||
mToast.setGravity(Gravity.TOP, 0, 0);
|
||||
mToast.show();
|
||||
|
||||
// Do a little vibrate if applicable (only when going into vibrate mode)
|
||||
if ((flags & AudioManager.FLAG_VIBRATE) != 0 &&
|
||||
mAudioService.isStreamAffectedByRingerMode(streamType) &&
|
||||
@@ -333,59 +554,72 @@ public class VolumePanel extends Handler
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the small icon visible, and hides the large icon.
|
||||
*
|
||||
* @param index The volume index, where 0 means muted.
|
||||
*/
|
||||
private void setSmallIcon(int index) {
|
||||
mLargeStreamIcon.setVisibility(View.GONE);
|
||||
mSmallStreamIcon.setVisibility(View.VISIBLE);
|
||||
|
||||
mSmallStreamIcon.setImageResource(index == 0
|
||||
? com.android.internal.R.drawable.ic_volume_off_small
|
||||
: com.android.internal.R.drawable.ic_volume_small);
|
||||
}
|
||||
// /**
|
||||
// * Makes the small icon visible, and hides the large icon.
|
||||
// *
|
||||
// * @param index The volume index, where 0 means muted.
|
||||
// */
|
||||
// private void setSmallIcon(int index) {
|
||||
// mLargeStreamIcon.setVisibility(View.GONE);
|
||||
// mSmallStreamIcon.setVisibility(View.VISIBLE);
|
||||
//
|
||||
// mSmallStreamIcon.setImageResource(index == 0
|
||||
// ? com.android.internal.R.drawable.ic_volume_off_small
|
||||
// : com.android.internal.R.drawable.ic_volume_small);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Makes the large image view visible with the given icon.
|
||||
// *
|
||||
// * @param resId The icon to display.
|
||||
// */
|
||||
// private void setLargeIcon(int resId) {
|
||||
// mSmallStreamIcon.setVisibility(View.GONE);
|
||||
// mLargeStreamIcon.setVisibility(View.VISIBLE);
|
||||
// mLargeStreamIcon.setImageResource(resId);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Makes the ringer icon visible with an icon that is chosen
|
||||
// * based on the current ringer mode.
|
||||
// */
|
||||
// private void setRingerIcon() {
|
||||
// mSmallStreamIcon.setVisibility(View.GONE);
|
||||
// mLargeStreamIcon.setVisibility(View.VISIBLE);
|
||||
//
|
||||
// int ringerMode = mAudioService.getRingerMode();
|
||||
// int icon;
|
||||
//
|
||||
// if (LOGD) Log.d(TAG, "setRingerIcon(), ringerMode: " + ringerMode);
|
||||
//
|
||||
// if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
|
||||
// icon = com.android.internal.R.drawable.ic_volume_off;
|
||||
// } else if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
// icon = com.android.internal.R.drawable.ic_vibrate;
|
||||
// } else {
|
||||
// icon = com.android.internal.R.drawable.ic_volume;
|
||||
// }
|
||||
// mLargeStreamIcon.setImageResource(icon);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Makes the large image view visible with the given icon.
|
||||
*
|
||||
* @param resId The icon to display.
|
||||
* Switch between icons because Bluetooth music is same as music volume, but with
|
||||
* different icons.
|
||||
*/
|
||||
private void setLargeIcon(int resId) {
|
||||
mSmallStreamIcon.setVisibility(View.GONE);
|
||||
mLargeStreamIcon.setVisibility(View.VISIBLE);
|
||||
mLargeStreamIcon.setImageResource(resId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the ringer icon visible with an icon that is chosen
|
||||
* based on the current ringer mode.
|
||||
*/
|
||||
private void setRingerIcon() {
|
||||
mSmallStreamIcon.setVisibility(View.GONE);
|
||||
mLargeStreamIcon.setVisibility(View.VISIBLE);
|
||||
|
||||
int ringerMode = mAudioService.getRingerMode();
|
||||
int icon;
|
||||
|
||||
if (LOGD) Log.d(TAG, "setRingerIcon(), ringerMode: " + ringerMode);
|
||||
|
||||
if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
|
||||
icon = com.android.internal.R.drawable.ic_volume_off;
|
||||
} else if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
icon = com.android.internal.R.drawable.ic_vibrate;
|
||||
} else {
|
||||
icon = com.android.internal.R.drawable.ic_volume;
|
||||
private void setMusicIcon(int resId, int resMuteId) {
|
||||
StreamControl sc = mStreamControls.get(AudioManager.STREAM_MUSIC);
|
||||
if (sc != null) {
|
||||
sc.iconRes = resId;
|
||||
sc.iconMuteRes = resMuteId;
|
||||
sc.icon.setImageResource(isMuted(sc.streamType) ? sc.iconMuteRes : sc.iconRes);
|
||||
}
|
||||
mLargeStreamIcon.setImageResource(icon);
|
||||
}
|
||||
|
||||
protected void onFreeResources() {
|
||||
// We'll keep the views, just ditch the cached drawable and hence
|
||||
// bitmaps
|
||||
mSmallStreamIcon.setImageDrawable(null);
|
||||
mLargeStreamIcon.setImageDrawable(null);
|
||||
// mSmallStreamIcon.setImageDrawable(null);
|
||||
// mLargeStreamIcon.setImageDrawable(null);
|
||||
|
||||
synchronized (this) {
|
||||
for (int i = mToneGenerators.length - 1; i >= 0; i--) {
|
||||
@@ -426,7 +660,55 @@ public class VolumePanel extends Handler
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_TIMEOUT: {
|
||||
if (mDialog.isShowing()) {
|
||||
mDialog.dismiss();
|
||||
mActiveStreamType = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSG_RINGER_MODE_CHANGED: {
|
||||
if (mDialog.isShowing()) {
|
||||
updateStates();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetTimeout() {
|
||||
removeMessages(MSG_TIMEOUT);
|
||||
sendMessageDelayed(obtainMessage(MSG_TIMEOUT), TIMEOUT_DELAY);
|
||||
}
|
||||
|
||||
public void onProgressChanged(SeekBar seekBar, int progress,
|
||||
boolean fromUser) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
resetTimeout();
|
||||
}
|
||||
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
if (v == mMoreButton) {
|
||||
expand();
|
||||
} else if (v.getTag() instanceof StreamControl) {
|
||||
StreamControl sc = (StreamControl) v.getTag();
|
||||
mAudioManager.setRingerMode(mAudioManager.isSilentMode()
|
||||
? AudioManager.RINGER_MODE_NORMAL : AudioManager.RINGER_MODE_SILENT);
|
||||
// Expand the dialog if it hasn't been expanded yet.
|
||||
if (!isExpanded()) expand();
|
||||
}
|
||||
resetTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
BIN
core/res/res/drawable-hdpi/ic_sysbar_quicksettings.png
Normal file
BIN
core/res/res/drawable-hdpi/ic_sysbar_quicksettings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 773 B |
BIN
core/res/res/drawable-mdpi/ic_sysbar_quicksettings.png
Normal file
BIN
core/res/res/drawable-mdpi/ic_sysbar_quicksettings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 653 B |
@@ -17,56 +17,48 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:drawable/dialog_full_holo_dark"
|
||||
android:gravity="left">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="416dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingTop="16dip"
|
||||
android:paddingRight="16dip"
|
||||
android:paddingBottom="8dip"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dip"
|
||||
android:gravity="left">
|
||||
|
||||
android:layout_marginTop="80dip"
|
||||
android:background="@android:drawable/dialog_full_holo_dark"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/slider_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<!-- Sliders go here -->
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/other_stream_icon"
|
||||
android:id="@+id/expand_button_divider"
|
||||
android:src="?attr/dividerVertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dip"
|
||||
android:scaleType="fitXY"
|
||||
android:layout_gravity="top"
|
||||
android:layout_marginTop="16dip"
|
||||
android:layout_marginBottom="16dip"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/expand_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="16dip" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/message"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
android:layout_gravity="top"
|
||||
android:padding="16dip"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:src="@drawable/ic_sysbar_quicksettings"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/additional_message"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ringer_stream_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="14dip" />
|
||||
|
||||
<ProgressBar
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:id="@+id/level"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
|
||||
45
core/res/res/layout/volume_adjust_item.xml
Normal file
45
core/res/res/layout/volume_adjust_item.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="80dip"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="8dip"
|
||||
android:layout_marginBottom="8dip"
|
||||
android:gravity="left|center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/stream_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dip"
|
||||
android:layout_marginLeft="8dip"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
/>
|
||||
|
||||
<SeekBar
|
||||
style="?android:attr/seekBarStyle"
|
||||
android:id="@+id/seekbar"
|
||||
android:layout_width="300dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dip"
|
||||
android:layout_marginLeft="8dip"
|
||||
android:layout_marginRight="8dip" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -208,6 +208,11 @@
|
||||
<item name="windowExitAnimation">@anim/fade_out</item>
|
||||
</style>
|
||||
|
||||
<!-- Window animations used for volume panel. -->
|
||||
<style name="Animation.VolumePanel">
|
||||
<item name="windowEnterAnimation">@null</item>
|
||||
<item name="windowExitAnimation">@anim/fade_out</item>
|
||||
</style>
|
||||
<!-- Status Bar Styles -->
|
||||
|
||||
<style name="TextAppearance.StatusBar">
|
||||
|
||||
@@ -730,6 +730,11 @@
|
||||
<item name="android:windowCloseOnTouchOutside">false</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Panel.Volume">
|
||||
<item name="android:windowAnimationStyle">@android:style/Animation.VolumePanel</item>
|
||||
<item name="android:windowCloseOnTouchOutside">true</item>
|
||||
</style>
|
||||
|
||||
<!-- Default theme with an Action Bar. -->
|
||||
<style name="Theme.WithActionBar">
|
||||
<item name="android:windowActionBar">true</item>
|
||||
|
||||
Reference in New Issue
Block a user