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.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