1 /*
2  * Copyright (C) 2019 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 static android.app.NotificationManager.IMPORTANCE_DEFAULT;
20 import static android.app.NotificationManager.IMPORTANCE_HIGH;
21 import static android.app.NotificationManager.IMPORTANCE_LOW;
22 import static android.app.NotificationManager.IMPORTANCE_MIN;
23 import static android.view.View.GONE;
24 import static android.view.View.VISIBLE;
25 
26 import android.content.Context;
27 import android.content.res.ColorStateList;
28 import android.graphics.drawable.Drawable;
29 import android.transition.AutoTransition;
30 import android.transition.Transition;
31 import android.transition.TransitionManager;
32 import android.util.AttributeSet;
33 import android.view.View;
34 import android.view.ViewGroup;
35 import android.widget.Button;
36 import android.widget.ImageView;
37 import android.widget.TextView;
38 
39 import com.android.settings.Utils;
40 import com.android.settingslib.R;
41 
42 import androidx.preference.Preference;
43 import androidx.preference.PreferenceViewHolder;
44 
45 public class ImportancePreference extends Preference {
46 
47     private boolean mIsConfigurable = true;
48     private int mImportance;
49     private boolean mDisplayInStatusBar;
50     private boolean mDisplayOnLockscreen;
51     private View mSilenceButton;
52     private View mAlertButton;
53     private Context mContext;
54     Drawable selectedBackground;
55     Drawable unselectedBackground;
56     private static final int BUTTON_ANIM_TIME_MS = 100;
57     private static final boolean SHOW_BUTTON_SUMMARY = false;
58 
ImportancePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)59     public ImportancePreference(Context context, AttributeSet attrs,
60             int defStyleAttr, int defStyleRes) {
61         super(context, attrs, defStyleAttr, defStyleRes);
62         init(context);
63     }
64 
ImportancePreference(Context context, AttributeSet attrs, int defStyleAttr)65     public ImportancePreference(Context context, AttributeSet attrs, int defStyleAttr) {
66         super(context, attrs, defStyleAttr);
67         init(context);
68     }
69 
ImportancePreference(Context context, AttributeSet attrs)70     public ImportancePreference(Context context, AttributeSet attrs) {
71         super(context, attrs);
72         init(context);
73     }
74 
ImportancePreference(Context context)75     public ImportancePreference(Context context) {
76         super(context);
77         init(context);
78     }
79 
init(Context context)80     private void init(Context context) {
81         mContext = context;
82         selectedBackground = mContext.getDrawable(R.drawable.button_border_selected);
83         unselectedBackground = mContext.getDrawable(R.drawable.button_border_unselected);
84         setLayoutResource(R.layout.notif_importance_preference);
85     }
86 
setImportance(int importance)87     public void setImportance(int importance) {
88         mImportance = importance;
89     }
90 
setConfigurable(boolean configurable)91     public void setConfigurable(boolean configurable) {
92         mIsConfigurable = configurable;
93     }
94 
setDisplayInStatusBar(boolean display)95     public void setDisplayInStatusBar(boolean display) {
96         mDisplayInStatusBar = display;
97     }
98 
setDisplayOnLockscreen(boolean display)99     public void setDisplayOnLockscreen(boolean display) {
100         mDisplayOnLockscreen = display;
101     }
102 
103     @Override
onBindViewHolder(final PreferenceViewHolder holder)104     public void onBindViewHolder(final PreferenceViewHolder holder) {
105         super.onBindViewHolder(holder);
106         holder.itemView.setClickable(false);
107 
108         mSilenceButton = holder.findViewById(R.id.silence);
109         mAlertButton = holder.findViewById(R.id.alert);
110 
111         if (!mIsConfigurable) {
112             mSilenceButton.setEnabled(false);
113             mAlertButton.setEnabled(false);
114         }
115 
116         setImportanceSummary((ViewGroup) holder.itemView, mImportance, false);
117         switch (mImportance) {
118             case IMPORTANCE_MIN:
119             case IMPORTANCE_LOW:
120                 mAlertButton.setBackground(unselectedBackground);
121                 mSilenceButton.setBackground(selectedBackground);
122                 mSilenceButton.setSelected(true);
123                 break;
124             case IMPORTANCE_HIGH:
125             default:
126                 mSilenceButton.setBackground(unselectedBackground);
127                 mAlertButton.setBackground(selectedBackground);
128                 mAlertButton.setSelected(true);
129                 break;
130         }
131 
132         mSilenceButton.setOnClickListener(v -> {
133             callChangeListener(IMPORTANCE_LOW);
134             mAlertButton.setBackground(unselectedBackground);
135             mSilenceButton.setBackground(selectedBackground);
136             setImportanceSummary((ViewGroup) holder.itemView, IMPORTANCE_LOW, true);
137             // a11y service won't always read the newly appearing text in the right order if the
138             // selection happens too soon (readback happens on a different thread as layout). post
139             // the selection to make that conflict less likely
140             holder.itemView.post(() -> {
141                 mAlertButton.setSelected(false);
142                 mSilenceButton.setSelected(true);
143             });
144         });
145         mAlertButton.setOnClickListener(v -> {
146             callChangeListener(IMPORTANCE_DEFAULT);
147             mSilenceButton.setBackground(unselectedBackground);
148             mAlertButton.setBackground(selectedBackground);
149             setImportanceSummary((ViewGroup) holder.itemView, IMPORTANCE_DEFAULT, true);
150             holder.itemView.post(() -> {
151                 mSilenceButton.setSelected(false);
152                 mAlertButton.setSelected(true);
153             });
154         });
155     }
156 
getAccentTint()157     private ColorStateList getAccentTint() {
158         return Utils.getColorAccent(getContext());
159     }
160 
getRegularTint()161     private ColorStateList getRegularTint() {
162         return Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary);
163     }
164 
setImportanceSummary(ViewGroup parent, int importance, boolean fromUser)165     void setImportanceSummary(ViewGroup parent, int importance, boolean fromUser) {
166         if (fromUser) {
167             AutoTransition transition = new AutoTransition();
168             transition.setDuration(BUTTON_ANIM_TIME_MS);
169             TransitionManager.beginDelayedTransition(parent, transition);
170         }
171 
172         ColorStateList colorAccent = getAccentTint();
173         ColorStateList colorNormal = getRegularTint();
174 
175         if (importance >= IMPORTANCE_DEFAULT) {
176             parent.findViewById(R.id.silence_summary).setVisibility(GONE);
177             ((ImageView) parent.findViewById(R.id.silence_icon)).setImageTintList(colorNormal);
178             ((TextView) parent.findViewById(R.id.silence_label)).setTextColor(colorNormal);
179 
180             ((ImageView) parent.findViewById(R.id.alert_icon)).setImageTintList(colorAccent);
181             ((TextView) parent.findViewById(R.id.alert_label)).setTextColor(colorAccent);
182 
183             parent.findViewById(R.id.alert_summary).setVisibility(VISIBLE);
184         } else {
185             parent.findViewById(R.id.alert_summary).setVisibility(GONE);
186             ((ImageView) parent.findViewById(R.id.alert_icon)).setImageTintList(colorNormal);
187             ((TextView) parent.findViewById(R.id.alert_label)).setTextColor(colorNormal);
188 
189             ((ImageView) parent.findViewById(R.id.silence_icon)).setImageTintList(colorAccent);
190             ((TextView) parent.findViewById(R.id.silence_label)).setTextColor(colorAccent);
191             parent.findViewById(R.id.silence_summary).setVisibility(VISIBLE);
192         }
193     }
194 }
195