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