Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2015 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 com.android.deskclock.settings;
     18 
     19 import android.annotation.TargetApi;
     20 import android.app.NotificationManager;
     21 import android.content.Context;
     22 import android.database.ContentObserver;
     23 import android.media.AudioManager;
     24 import android.os.Build;
     25 import android.provider.Settings;
     26 import android.support.v7.preference.Preference;
     27 import android.support.v7.preference.PreferenceViewHolder;
     28 import android.util.AttributeSet;
     29 import android.view.View;
     30 import android.widget.ImageView;
     31 import android.widget.SeekBar;
     32 
     33 import com.android.deskclock.R;
     34 import com.android.deskclock.RingtonePreviewKlaxon;
     35 import com.android.deskclock.Utils;
     36 import com.android.deskclock.data.DataModel;
     37 
     38 import static android.content.Context.AUDIO_SERVICE;
     39 import static android.content.Context.NOTIFICATION_SERVICE;
     40 import static android.media.AudioManager.STREAM_ALARM;
     41 
     42 public class AlarmVolumePreference extends Preference {
     43 
     44     private static final long ALARM_PREVIEW_DURATION_MS = 2000;
     45 
     46     private SeekBar mSeekbar;
     47     private ImageView mAlarmIcon;
     48     private boolean mPreviewPlaying;
     49 
     50     public AlarmVolumePreference(Context context, AttributeSet attrs) {
     51         super(context, attrs);
     52     }
     53 
     54     @Override
     55     public void onBindViewHolder(PreferenceViewHolder holder) {
     56         super.onBindViewHolder(holder);
     57 
     58         final Context context = getContext();
     59         final AudioManager audioManager = (AudioManager) context.getSystemService(AUDIO_SERVICE);
     60 
     61         // Disable click feedback for this preference.
     62         holder.itemView.setClickable(false);
     63 
     64         mSeekbar = (SeekBar) holder.findViewById(R.id.alarm_volume_slider);
     65         mSeekbar.setMax(audioManager.getStreamMaxVolume(STREAM_ALARM));
     66         mSeekbar.setProgress(audioManager.getStreamVolume(STREAM_ALARM));
     67         mAlarmIcon = (ImageView) holder.findViewById(R.id.alarm_icon);
     68         onSeekbarChanged();
     69 
     70         final ContentObserver volumeObserver = new ContentObserver(mSeekbar.getHandler()) {
     71             @Override
     72             public void onChange(boolean selfChange) {
     73                 // Volume was changed elsewhere, update our slider.
     74                 mSeekbar.setProgress(audioManager.getStreamVolume(STREAM_ALARM));
     75             }
     76         };
     77 
     78         mSeekbar.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
     79             @Override
     80             public void onViewAttachedToWindow(View v) {
     81                 context.getContentResolver().registerContentObserver(Settings.System.CONTENT_URI,
     82                         true, volumeObserver);
     83             }
     84 
     85             @Override
     86             public void onViewDetachedFromWindow(View v) {
     87                 context.getContentResolver().unregisterContentObserver(volumeObserver);
     88             }
     89         });
     90 
     91         mSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
     92             @Override
     93             public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
     94                 if (fromUser) {
     95                     audioManager.setStreamVolume(STREAM_ALARM, progress, 0);
     96                 }
     97                 onSeekbarChanged();
     98             }
     99 
    100             @Override
    101             public void onStartTrackingTouch(SeekBar seekBar) {
    102             }
    103 
    104             @Override
    105             public void onStopTrackingTouch(SeekBar seekBar) {
    106                 if (!mPreviewPlaying && seekBar.getProgress() != 0) {
    107                     // If we are not currently playing and progress is set to non-zero, start.
    108                     RingtonePreviewKlaxon.start(
    109                             context, DataModel.getDataModel().getDefaultAlarmRingtoneUri());
    110                     mPreviewPlaying = true;
    111                     seekBar.postDelayed(new Runnable() {
    112                         @Override
    113                         public void run() {
    114                             RingtonePreviewKlaxon.stop(context);
    115                             mPreviewPlaying = false;
    116                         }
    117                     }, ALARM_PREVIEW_DURATION_MS);
    118                 }
    119             }
    120         });
    121     }
    122 
    123     private void onSeekbarChanged() {
    124         mSeekbar.setEnabled(doesDoNotDisturbAllowAlarmPlayback());
    125         mAlarmIcon.setImageResource(mSeekbar.getProgress() == 0 ?
    126                 R.drawable.ic_alarm_off_24dp : R.drawable.ic_alarm_small);
    127     }
    128 
    129     private boolean doesDoNotDisturbAllowAlarmPlayback() {
    130         return !Utils.isNOrLater() || doesDoNotDisturbAllowAlarmPlaybackNPlus();
    131     }
    132 
    133     @TargetApi(Build.VERSION_CODES.N)
    134     private boolean doesDoNotDisturbAllowAlarmPlaybackNPlus() {
    135         final NotificationManager notificationManager = (NotificationManager)
    136                 getContext().getSystemService(NOTIFICATION_SERVICE);
    137         return notificationManager.getCurrentInterruptionFilter() !=
    138                 NotificationManager.INTERRUPTION_FILTER_NONE;
    139     }
    140 }