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.settings.notification;
18 
19 import com.android.settings.R;
20 import com.android.settings.SeekBarPreference;
21 
22 import android.content.Context;
23 import android.content.res.ColorStateList;
24 import android.content.res.TypedArray;
25 import android.graphics.drawable.Drawable;
26 import android.os.Handler;
27 import android.service.notification.NotificationListenerService;
28 import android.support.v7.preference.PreferenceViewHolder;
29 import android.util.AttributeSet;
30 import android.view.View;
31 import android.widget.ImageView;
32 import android.widget.SeekBar;
33 import android.widget.TextView;
34 
35 /**
36  * A slider preference that controls notification importance.
37  **/
38 public class ImportanceSeekBarPreference extends SeekBarPreference implements
39         SeekBar.OnSeekBarChangeListener {
40     private static final String TAG = "ImportanceSeekBarPref";
41 
42     private Callback mCallback;
43     private int mMinProgress;
44     private TextView mSummaryTextView;
45     private String mSummary;
46     private SeekBar mSeekBar;
47     private ColorStateList mActiveSliderTint;
48     private ColorStateList mInactiveSliderTint;
49     private float mActiveSliderAlpha = 1.0f;
50     private float mInactiveSliderAlpha;
51     private boolean mAutoOn;
52     private Handler mHandler;
53 
ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)54     public ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr,
55             int defStyleRes) {
56         super(context, attrs, defStyleAttr, defStyleRes);
57         setLayoutResource(R.layout.preference_importance_slider);
58         mActiveSliderTint = ColorStateList.valueOf(
59                 context.getColor(R.color.importance_slider_color));
60         mInactiveSliderTint = ColorStateList.valueOf(
61                 context.getColor(R.color.importance_disabled_slider_color));
62         mHandler = new Handler();
63         final TypedArray ta =
64                 context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Theme, 0, 0);
65         mInactiveSliderAlpha =
66                 ta.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f);
67         ta.recycle();
68     }
69 
ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr)70     public ImportanceSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
71         this(context, attrs, defStyleAttr, 0);
72     }
73 
ImportanceSeekBarPreference(Context context, AttributeSet attrs)74     public ImportanceSeekBarPreference(Context context, AttributeSet attrs) {
75         this(context, attrs, 0);
76     }
77 
ImportanceSeekBarPreference(Context context)78     public ImportanceSeekBarPreference(Context context) {
79         this(context, null);
80     }
81 
setCallback(Callback callback)82     public void setCallback(Callback callback) {
83         mCallback = callback;
84     }
85 
setMinimumProgress(int minProgress)86     public void setMinimumProgress(int minProgress) {
87         mMinProgress = minProgress;
88         notifyChanged();
89     }
90 
91     @Override
setProgress(int progress)92     public void setProgress(int progress) {
93         mSummary = getProgressSummary(progress);
94         super.setProgress(progress);
95     }
96 
setAutoOn(boolean autoOn)97     public void setAutoOn(boolean autoOn) {
98         mAutoOn = autoOn;
99         notifyChanged();
100     }
101 
102     @Override
onBindViewHolder(PreferenceViewHolder view)103     public void onBindViewHolder(PreferenceViewHolder view) {
104         super.onBindViewHolder(view);
105         mSummaryTextView = (TextView) view.findViewById(com.android.internal.R.id.summary);
106         mSeekBar = (SeekBar) view.findViewById(
107                 com.android.internal.R.id.seekbar);
108 
109         final ImageView autoButton = (ImageView) view.findViewById(R.id.auto_importance);
110         applyAutoUi(autoButton);
111         autoButton.setOnClickListener(new View.OnClickListener() {
112             @Override
113             public void onClick(View v) {
114                 applyAuto(autoButton);
115             }
116         });
117     }
118 
applyAuto(ImageView autoButton)119     private void applyAuto(ImageView autoButton) {
120         mAutoOn = !mAutoOn;
121         if (!mAutoOn) {
122             setProgress(NotificationListenerService.Ranking.IMPORTANCE_DEFAULT);
123             mCallback.onImportanceChanged(
124                     NotificationListenerService.Ranking.IMPORTANCE_DEFAULT, true);
125         } else {
126             mCallback.onImportanceChanged(
127                     NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED, true);
128         }
129         applyAutoUi(autoButton);
130     }
131 
applyAutoUi(ImageView autoButton)132     private void applyAutoUi(ImageView autoButton) {
133         mSeekBar.setEnabled(!mAutoOn);
134 
135         final float alpha = mAutoOn ? mInactiveSliderAlpha : mActiveSliderAlpha;
136         final ColorStateList starTint = mAutoOn ?  mActiveSliderTint : mInactiveSliderTint;
137         Drawable icon = autoButton.getDrawable().mutate();
138         icon.setTintList(starTint);
139         autoButton.setImageDrawable(icon);
140         mSeekBar.setAlpha(alpha);
141 
142         if (mAutoOn) {
143             setProgress(NotificationListenerService.Ranking.IMPORTANCE_DEFAULT);
144             mSummary = getProgressSummary(
145                     NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED);
146         }
147         mSummaryTextView.setText(mSummary);
148     }
149 
150     @Override
getSummary()151     public CharSequence getSummary() {
152         return mSummary;
153     }
154 
155     @Override
onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch)156     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
157         super.onProgressChanged(seekBar, progress, fromTouch);
158         if (progress < mMinProgress) {
159             seekBar.setProgress(mMinProgress);
160             progress = mMinProgress;
161         }
162         if (mSummaryTextView != null) {
163             mSummary = getProgressSummary(progress);
164             mSummaryTextView.setText(mSummary);
165         }
166         mCallback.onImportanceChanged(progress, fromTouch);
167     }
168 
getProgressSummary(int progress)169     private String getProgressSummary(int progress) {
170         switch (progress) {
171             case NotificationListenerService.Ranking.IMPORTANCE_NONE:
172                 return getContext().getString(R.string.notification_importance_blocked);
173             case NotificationListenerService.Ranking.IMPORTANCE_MIN:
174                 return getContext().getString(R.string.notification_importance_min);
175             case NotificationListenerService.Ranking.IMPORTANCE_LOW:
176                 return getContext().getString(R.string.notification_importance_low);
177             case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT:
178                 return getContext().getString(R.string.notification_importance_default);
179             case NotificationListenerService.Ranking.IMPORTANCE_HIGH:
180                 return getContext().getString(R.string.notification_importance_high);
181             case NotificationListenerService.Ranking.IMPORTANCE_MAX:
182                 return getContext().getString(R.string.notification_importance_max);
183             default:
184                 return getContext().getString(R.string.notification_importance_unspecified);
185         }
186     }
187 
188     @Override
notifyChanged()189     protected void notifyChanged() {
190         mHandler.post(mNotifyChanged);
191     }
192 
postNotifyChanged()193     private void postNotifyChanged() {
194         super.notifyChanged();
195     }
196 
197     private final Runnable mNotifyChanged = new Runnable() {
198         @Override
199         public void run() {
200             postNotifyChanged();
201         }
202     };
203 
204     public interface Callback {
onImportanceChanged(int progress, boolean fromTouch)205         void onImportanceChanged(int progress, boolean fromTouch);
206     }
207 }
208