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.app;
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.TransitionManager;
31 import android.util.AttributeSet;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.ImageView;
35 import android.widget.TextView;
36 
37 import androidx.preference.Preference;
38 import androidx.preference.PreferenceViewHolder;
39 
40 import com.android.settings.R;
41 import com.android.settings.Utils;
42 
43 public class ImportancePreference extends Preference {
44 
45     private boolean mIsConfigurable = true;
46     private int mImportance;
47     private boolean mDisplayInStatusBar;
48     private boolean mDisplayOnLockscreen;
49     private View mSilenceButton;
50     private View mAlertButton;
51     private Context mContext;
52     Drawable selectedBackground;
53     Drawable unselectedBackground;
54     private static final int BUTTON_ANIM_TIME_MS = 100;
55     private static final boolean SHOW_BUTTON_SUMMARY = false;
56 
ImportancePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)57     public ImportancePreference(Context context, AttributeSet attrs,
58             int defStyleAttr, int defStyleRes) {
59         super(context, attrs, defStyleAttr, defStyleRes);
60         init(context);
61     }
62 
ImportancePreference(Context context, AttributeSet attrs, int defStyleAttr)63     public ImportancePreference(Context context, AttributeSet attrs, int defStyleAttr) {
64         super(context, attrs, defStyleAttr);
65         init(context);
66     }
67 
ImportancePreference(Context context, AttributeSet attrs)68     public ImportancePreference(Context context, AttributeSet attrs) {
69         super(context, attrs);
70         init(context);
71     }
72 
ImportancePreference(Context context)73     public ImportancePreference(Context context) {
74         super(context);
75         init(context);
76     }
77 
init(Context context)78     private void init(Context context) {
79         mContext = context;
80         selectedBackground = mContext.getDrawable(
81                 R.drawable.notification_importance_button_background_selected);
82         unselectedBackground = mContext.getDrawable(
83                 R.drawable.notification_importance_button_background_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 
getSelectedColor()157     private ColorStateList getSelectedColor() {
158         return Utils.getColorAttr(getContext(),
159                 R.attr.notification_importance_button_foreground_color_selected);
160     }
161 
getUnselectedColor()162     private ColorStateList getUnselectedColor() {
163         return Utils.getColorAttr(getContext(),
164                 R.attr.notification_importance_button_foreground_color_unselected);
165     }
166 
setImportanceSummary(ViewGroup parent, int importance, boolean fromUser)167     void setImportanceSummary(ViewGroup parent, int importance, boolean fromUser) {
168         if (fromUser) {
169             AutoTransition transition = new AutoTransition();
170             transition.setDuration(BUTTON_ANIM_TIME_MS);
171             TransitionManager.beginDelayedTransition(parent, transition);
172         }
173 
174         ColorStateList colorSelected = getSelectedColor();
175         ColorStateList colorUnselected = getUnselectedColor();
176 
177         if (importance >= IMPORTANCE_DEFAULT) {
178             parent.findViewById(R.id.silence_summary).setVisibility(GONE);
179             ((ImageView) parent.findViewById(R.id.silence_icon)).setImageTintList(colorUnselected);
180             ((TextView) parent.findViewById(R.id.silence_label)).setTextColor(colorUnselected);
181 
182             ((ImageView) parent.findViewById(R.id.alert_icon)).setImageTintList(colorSelected);
183             ((TextView) parent.findViewById(R.id.alert_label)).setTextColor(colorSelected);
184 
185             parent.findViewById(R.id.alert_summary).setVisibility(VISIBLE);
186         } else {
187             parent.findViewById(R.id.alert_summary).setVisibility(GONE);
188             ((ImageView) parent.findViewById(R.id.alert_icon)).setImageTintList(colorUnselected);
189             ((TextView) parent.findViewById(R.id.alert_label)).setTextColor(colorUnselected);
190 
191             ((ImageView) parent.findViewById(R.id.silence_icon)).setImageTintList(colorSelected);
192             ((TextView) parent.findViewById(R.id.silence_label)).setTextColor(colorSelected);
193             parent.findViewById(R.id.silence_summary).setVisibility(VISIBLE);
194         }
195     }
196 }
197