Home | History | Annotate | Download | only in preference
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      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
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     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.
     15  */
     16 
     17 package android.preference;
     18 
     19 import android.annotation.UnsupportedAppUsage;
     20 import android.app.Dialog;
     21 import android.content.Context;
     22 import android.content.res.TypedArray;
     23 import android.os.Parcel;
     24 import android.os.Parcelable;
     25 import android.util.AttributeSet;
     26 import android.view.KeyEvent;
     27 import android.view.View;
     28 import android.widget.SeekBar;
     29 
     30 import com.android.internal.R;
     31 
     32 /**
     33  * @hide
     34  *
     35  * @deprecated Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
     36  *      <a href="{@docRoot}reference/androidx/preference/package-summary.html">
     37  *      Preference Library</a> for consistent behavior across all devices. For more information on
     38  *      using the AndroidX Preference Library see
     39  *      <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.
     40  */
     41 @Deprecated
     42 public class VolumePreference extends SeekBarDialogPreference implements
     43         PreferenceManager.OnActivityStopListener, View.OnKeyListener, SeekBarVolumizer.Callback {
     44     @UnsupportedAppUsage
     45     private int mStreamType;
     46 
     47     /** May be null if the dialog isn't visible. */
     48     private SeekBarVolumizer mSeekBarVolumizer;
     49 
     50     public VolumePreference(
     51             Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
     52         super(context, attrs, defStyleAttr, defStyleRes);
     53 
     54         final TypedArray a = context.obtainStyledAttributes(attrs,
     55                 R.styleable.VolumePreference, defStyleAttr, defStyleRes);
     56         mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0);
     57         a.recycle();
     58     }
     59 
     60     public VolumePreference(Context context, AttributeSet attrs, int defStyleAttr) {
     61         this(context, attrs, defStyleAttr, 0);
     62     }
     63 
     64     @UnsupportedAppUsage
     65     public VolumePreference(Context context, AttributeSet attrs) {
     66         this(context, attrs, R.attr.seekBarDialogPreferenceStyle);
     67     }
     68 
     69     public VolumePreference(Context context) {
     70         this(context, null);
     71     }
     72 
     73     public void setStreamType(int streamType) {
     74         mStreamType = streamType;
     75     }
     76 
     77     @Override
     78     protected void onBindDialogView(View view) {
     79         super.onBindDialogView(view);
     80 
     81         final SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekbar);
     82         mSeekBarVolumizer = new SeekBarVolumizer(getContext(), mStreamType, null, this);
     83         mSeekBarVolumizer.start();
     84         mSeekBarVolumizer.setSeekBar(seekBar);
     85 
     86         getPreferenceManager().registerOnActivityStopListener(this);
     87 
     88         // grab focus and key events so that pressing the volume buttons in the
     89         // dialog doesn't also show the normal volume adjust toast.
     90         view.setOnKeyListener(this);
     91         view.setFocusableInTouchMode(true);
     92         view.requestFocus();
     93     }
     94 
     95     public boolean onKey(View v, int keyCode, KeyEvent event) {
     96         // If key arrives immediately after the activity has been cleaned up.
     97         if (mSeekBarVolumizer == null) return true;
     98         boolean isdown = (event.getAction() == KeyEvent.ACTION_DOWN);
     99         switch (keyCode) {
    100             case KeyEvent.KEYCODE_VOLUME_DOWN:
    101                 if (isdown) {
    102                     mSeekBarVolumizer.changeVolumeBy(-1);
    103                 }
    104                 return true;
    105             case KeyEvent.KEYCODE_VOLUME_UP:
    106                 if (isdown) {
    107                     mSeekBarVolumizer.changeVolumeBy(1);
    108                 }
    109                 return true;
    110             case KeyEvent.KEYCODE_VOLUME_MUTE:
    111                 if (isdown) {
    112                     mSeekBarVolumizer.muteVolume();
    113                 }
    114                 return true;
    115             default:
    116                 return false;
    117         }
    118     }
    119 
    120     @Override
    121     protected void onDialogClosed(boolean positiveResult) {
    122         super.onDialogClosed(positiveResult);
    123 
    124         if (!positiveResult && mSeekBarVolumizer != null) {
    125             mSeekBarVolumizer.revertVolume();
    126         }
    127 
    128         cleanup();
    129     }
    130 
    131     public void onActivityStop() {
    132         if (mSeekBarVolumizer != null) {
    133             mSeekBarVolumizer.stopSample();
    134         }
    135     }
    136 
    137     /**
    138      * Do clean up.  This can be called multiple times!
    139      */
    140     private void cleanup() {
    141        getPreferenceManager().unregisterOnActivityStopListener(this);
    142 
    143        if (mSeekBarVolumizer != null) {
    144            final Dialog dialog = getDialog();
    145            if (dialog != null && dialog.isShowing()) {
    146                final View view = dialog.getWindow().getDecorView().findViewById(R.id.seekbar);
    147                if (view != null) {
    148                    view.setOnKeyListener(null);
    149                }
    150 
    151                // Stopped while dialog was showing, revert changes
    152                mSeekBarVolumizer.revertVolume();
    153            }
    154 
    155            mSeekBarVolumizer.stop();
    156            mSeekBarVolumizer = null;
    157        }
    158 
    159     }
    160 
    161     @Override
    162     public void onSampleStarting(SeekBarVolumizer volumizer) {
    163         if (mSeekBarVolumizer != null && volumizer != mSeekBarVolumizer) {
    164             mSeekBarVolumizer.stopSample();
    165         }
    166     }
    167 
    168     @Override
    169     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
    170         // noop
    171     }
    172 
    173     @Override
    174     public void onMuted(boolean muted, boolean zenMuted) {
    175         // noop
    176     }
    177 
    178     @Override
    179     protected Parcelable onSaveInstanceState() {
    180         final Parcelable superState = super.onSaveInstanceState();
    181         if (isPersistent()) {
    182             // No need to save instance state since it's persistent
    183             return superState;
    184         }
    185 
    186         final SavedState myState = new SavedState(superState);
    187         if (mSeekBarVolumizer != null) {
    188             mSeekBarVolumizer.onSaveInstanceState(myState.getVolumeStore());
    189         }
    190         return myState;
    191     }
    192 
    193     @Override
    194     protected void onRestoreInstanceState(Parcelable state) {
    195         if (state == null || !state.getClass().equals(SavedState.class)) {
    196             // Didn't save state for us in onSaveInstanceState
    197             super.onRestoreInstanceState(state);
    198             return;
    199         }
    200 
    201         SavedState myState = (SavedState) state;
    202         super.onRestoreInstanceState(myState.getSuperState());
    203         if (mSeekBarVolumizer != null) {
    204             mSeekBarVolumizer.onRestoreInstanceState(myState.getVolumeStore());
    205         }
    206     }
    207 
    208     public static class VolumeStore {
    209         @UnsupportedAppUsage
    210         public int volume = -1;
    211         @UnsupportedAppUsage
    212         public int originalVolume = -1;
    213     }
    214 
    215     private static class SavedState extends BaseSavedState {
    216         VolumeStore mVolumeStore = new VolumeStore();
    217 
    218         public SavedState(Parcel source) {
    219             super(source);
    220             mVolumeStore.volume = source.readInt();
    221             mVolumeStore.originalVolume = source.readInt();
    222         }
    223 
    224         @Override
    225         public void writeToParcel(Parcel dest, int flags) {
    226             super.writeToParcel(dest, flags);
    227             dest.writeInt(mVolumeStore.volume);
    228             dest.writeInt(mVolumeStore.originalVolume);
    229         }
    230 
    231         VolumeStore getVolumeStore() {
    232             return mVolumeStore;
    233         }
    234 
    235         public SavedState(Parcelable superState) {
    236             super(superState);
    237         }
    238 
    239         public static final @android.annotation.NonNull Parcelable.Creator<SavedState> CREATOR =
    240                 new Parcelable.Creator<SavedState>() {
    241             public SavedState createFromParcel(Parcel in) {
    242                 return new SavedState(in);
    243             }
    244 
    245             public SavedState[] newArray(int size) {
    246                 return new SavedState[size];
    247             }
    248         };
    249     }
    250 }
    251