• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AlarmVolumePreference(Context context, AttributeSet attrs)50     public AlarmVolumePreference(Context context, AttributeSet attrs) {
51         super(context, attrs);
52     }
53 
54     @Override
onBindViewHolder(PreferenceViewHolder holder)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 
onSeekbarChanged()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 
doesDoNotDisturbAllowAlarmPlayback()129     private boolean doesDoNotDisturbAllowAlarmPlayback() {
130         return !Utils.isNOrLater() || doesDoNotDisturbAllowAlarmPlaybackNPlus();
131     }
132 
133     @TargetApi(Build.VERSION_CODES.N)
doesDoNotDisturbAllowAlarmPlaybackNPlus()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 }