2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.settings;
19 import android.app.Dialog;
20 import android.content.Context;
21 import android.media.AudioManager;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.preference.VolumePreference;
25 import android.provider.Settings;
26 import android.util.AttributeSet;
27 import android.view.View;
28 import android.widget.CheckBox;
29 import android.widget.CompoundButton;
30 import android.widget.SeekBar;
31 import android.widget.TextView;
34 * Special preference type that allows configuration of both the ring volume and
35 * notification volume.
37 public class RingerVolumePreference extends VolumePreference implements
38 CheckBox.OnCheckedChangeListener {
39 private static final String TAG = "RingerVolumePreference";
41 private CheckBox mNotificationsUseRingVolumeCheckbox;
42 private SeekBarVolumizer [] mSeekBarVolumizer;
43 private static final int[] SEEKBAR_ID = new int[] {
44 R.id.notification_volume_seekbar,
45 R.id.media_volume_seekbar,
46 R.id.alarm_volume_seekbar
48 private static final int[] SEEKBAR_TYPE = new int[] {
49 AudioManager.STREAM_NOTIFICATION,
50 AudioManager.STREAM_MUSIC,
51 AudioManager.STREAM_ALARM
53 //private SeekBarVolumizer mNotificationSeekBarVolumizer;
54 private TextView mNotificationVolumeTitle;
56 public RingerVolumePreference(Context context, AttributeSet attrs) {
57 super(context, attrs);
59 // The always visible seekbar is for ring volume
60 setStreamType(AudioManager.STREAM_RING);
62 setDialogLayoutResource(R.layout.preference_dialog_ringervolume);
63 setDialogIcon(R.drawable.ic_settings_sound);
65 mSeekBarVolumizer = new SeekBarVolumizer[SEEKBAR_ID.length];
69 protected void onBindDialogView(View view) {
70 super.onBindDialogView(view);
72 for (int i = 0; i < SEEKBAR_ID.length; i++) {
73 SeekBar seekBar = (SeekBar) view.findViewById(SEEKBAR_ID[i]);
74 mSeekBarVolumizer[i] = new SeekBarVolumizer(getContext(), seekBar,
78 mNotificationVolumeTitle = (TextView) view.findViewById(R.id.notification_volume_title);
79 mNotificationsUseRingVolumeCheckbox =
80 (CheckBox) view.findViewById(R.id.same_notification_volume);
81 mNotificationsUseRingVolumeCheckbox.setOnCheckedChangeListener(this);
82 mNotificationsUseRingVolumeCheckbox.setChecked(Settings.System.getInt(
83 getContext().getContentResolver(),
84 Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1) == 1);
85 setNotificationVolumeVisibility(!mNotificationsUseRingVolumeCheckbox.isChecked());
89 protected void onDialogClosed(boolean positiveResult) {
90 super.onDialogClosed(positiveResult);
92 if (!positiveResult) {
93 for (SeekBarVolumizer vol : mSeekBarVolumizer) {
94 if (vol != null) vol.revertVolume();
101 public void onActivityStop() {
102 super.onActivityStop();
106 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
107 setNotificationVolumeVisibility(!isChecked);
109 Settings.System.putInt(getContext().getContentResolver(),
110 Settings.System.NOTIFICATIONS_USE_RING_VOLUME, isChecked ? 1 : 0);
113 // The user wants the notification to be same as ring, so do a
114 // one-time sync right now
115 AudioManager audioManager = (AudioManager) getContext()
116 .getSystemService(Context.AUDIO_SERVICE);
117 audioManager.setStreamVolume(AudioManager.STREAM_NOTIFICATION,
118 audioManager.getStreamVolume(AudioManager.STREAM_RING), 0);
123 protected void onSampleStarting(SeekBarVolumizer volumizer) {
124 super.onSampleStarting(volumizer);
125 for (SeekBarVolumizer vol : mSeekBarVolumizer) {
126 if (vol != null && vol != volumizer) vol.stopSample();
130 private void setNotificationVolumeVisibility(boolean visible) {
131 if (mSeekBarVolumizer[0] != null) {
132 mSeekBarVolumizer[0].getSeekBar().setVisibility(
133 visible ? View.VISIBLE : View.GONE);
135 mNotificationVolumeTitle.setVisibility(visible ? View.VISIBLE : View.GONE);
138 private void cleanup() {
139 for (int i = 0; i < SEEKBAR_ID.length; i++) {
140 if (mSeekBarVolumizer[i] != null) {
141 Dialog dialog = getDialog();
142 if (dialog != null && dialog.isShowing()) {
143 // Stopped while dialog was showing, revert changes
144 mSeekBarVolumizer[i].revertVolume();
146 mSeekBarVolumizer[i].stop();
147 mSeekBarVolumizer[i] = null;
153 protected Parcelable onSaveInstanceState() {
154 final Parcelable superState = super.onSaveInstanceState();
155 if (isPersistent()) {
156 // No need to save instance state since it's persistent
160 final SavedState myState = new SavedState(superState);
161 VolumeStore[] volumeStore = myState.getVolumeStore(SEEKBAR_ID.length);
162 for (int i = 0; i < SEEKBAR_ID.length; i++) {
163 SeekBarVolumizer vol = mSeekBarVolumizer[i];
165 vol.onSaveInstanceState(volumeStore[i]);
172 protected void onRestoreInstanceState(Parcelable state) {
173 if (state == null || !state.getClass().equals(SavedState.class)) {
174 // Didn't save state for us in onSaveInstanceState
175 super.onRestoreInstanceState(state);
179 SavedState myState = (SavedState) state;
180 super.onRestoreInstanceState(myState.getSuperState());
181 VolumeStore[] volumeStore = myState.getVolumeStore(SEEKBAR_ID.length);
182 for (int i = 0; i < SEEKBAR_ID.length; i++) {
183 SeekBarVolumizer vol = mSeekBarVolumizer[i];
185 vol.onRestoreInstanceState(volumeStore[i]);
190 private static class SavedState extends BaseSavedState {
191 VolumeStore [] mVolumeStore;
193 public SavedState(Parcel source) {
195 mVolumeStore = new VolumeStore[SEEKBAR_ID.length];
196 for (int i = 0; i < SEEKBAR_ID.length; i++) {
197 mVolumeStore[i] = new VolumeStore();
198 mVolumeStore[i].volume = source.readInt();
199 mVolumeStore[i].originalVolume = source.readInt();
204 public void writeToParcel(Parcel dest, int flags) {
205 super.writeToParcel(dest, flags);
206 for (int i = 0; i < SEEKBAR_ID.length; i++) {
207 dest.writeInt(mVolumeStore[i].volume);
208 dest.writeInt(mVolumeStore[i].originalVolume);
212 VolumeStore[] getVolumeStore(int count) {
213 if (mVolumeStore == null || mVolumeStore.length != count) {
214 mVolumeStore = new VolumeStore[count];
215 for (int i = 0; i < count; i++) {
216 mVolumeStore[i] = new VolumeStore();
222 public SavedState(Parcelable superState) {
226 public static final Parcelable.Creator<SavedState> CREATOR =
227 new Parcelable.Creator<SavedState>() {
228 public SavedState createFromParcel(Parcel in) {
229 return new SavedState(in);
232 public SavedState[] newArray(int size) {
233 return new SavedState[size];