diff options
| -rw-r--r-- | core/java/android/view/VolumePanel.java | 504 | ||||
| -rw-r--r-- | core/res/res/drawable-hdpi/ic_sysbar_quicksettings.png | bin | 0 -> 773 bytes | |||
| -rw-r--r-- | core/res/res/drawable-mdpi/ic_sysbar_quicksettings.png | bin | 0 -> 653 bytes | |||
| -rw-r--r-- | core/res/res/layout/volume_adjust.xml | 68 | ||||
| -rw-r--r-- | core/res/res/layout/volume_adjust_item.xml | 45 | ||||
| -rw-r--r-- | core/res/res/values/styles.xml | 5 | ||||
| -rw-r--r-- | core/res/res/values/themes.xml | 5 |
7 files changed, 478 insertions, 149 deletions
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java index e447dbb8a5f2..bb5774f31417 100644 --- a/core/java/android/view/VolumePanel.java +++ b/core/java/android/view/VolumePanel.java @@ -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 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 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; 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,33 +451,40 @@ 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 (max != mLevel.getMax()) { - mLevel.setMax(max); + if (!mDialog.isShowing()) { + mDialog.setContentView(mView); + // Showing dialog - use collapsed state + collapse(); + mDialog.show(); } - 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 && @@ -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 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 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 ringer icon visible with an icon that is chosen - * based on the current ringer mode. + * Switch between icons because Bluetooth music is same as music volume, but with + * different icons. */ - 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(); + } } diff --git a/core/res/res/drawable-hdpi/ic_sysbar_quicksettings.png b/core/res/res/drawable-hdpi/ic_sysbar_quicksettings.png Binary files differnew file mode 100644 index 000000000000..47b4ba23f7a5 --- /dev/null +++ b/core/res/res/drawable-hdpi/ic_sysbar_quicksettings.png diff --git a/core/res/res/drawable-mdpi/ic_sysbar_quicksettings.png b/core/res/res/drawable-mdpi/ic_sysbar_quicksettings.png Binary files differnew file mode 100644 index 000000000000..792810427f92 --- /dev/null +++ b/core/res/res/drawable-mdpi/ic_sysbar_quicksettings.png diff --git a/core/res/res/layout/volume_adjust.xml b/core/res/res/layout/volume_adjust.xml index 18da85f93d9a..b0ca3e8e71ff 100644 --- a/core/res/res/layout/volume_adjust.xml +++ b/core/res/res/layout/volume_adjust.xml @@ -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"> - - <ImageView - android:id="@+id/other_stream_icon" + 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:layout_marginRight="16dip" /> + android:orientation="vertical" + > + <!-- Sliders go here --> + </LinearLayout> - <TextView + <ImageView + android:id="@+id/expand_button_divider" + android:src="?attr/dividerVertical" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:id="@+id/message" - android:textAppearance="?android:attr/textAppearanceMedium" /> + 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_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> diff --git a/core/res/res/layout/volume_adjust_item.xml b/core/res/res/layout/volume_adjust_item.xml new file mode 100644 index 000000000000..e841d878af0c --- /dev/null +++ b/core/res/res/layout/volume_adjust_item.xml @@ -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> + + diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index e2751bd59029..5700641f3986 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -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"> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 38b068e25c95..6d5b4822b1dc 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -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> |