1 /* 2 * Copyright (C) 2020 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.zen; 18 19 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; 20 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES; 21 22 import android.app.NotificationManager; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.pm.PackageManager; 26 import android.provider.Contacts; 27 import android.view.View; 28 29 import androidx.annotation.VisibleForTesting; 30 import androidx.preference.Preference; 31 import androidx.preference.PreferenceCategory; 32 import androidx.preference.PreferenceScreen; 33 34 import com.android.settings.R; 35 import com.android.settingslib.core.lifecycle.Lifecycle; 36 import com.android.settingslib.widget.RadioButtonPreference; 37 38 import java.util.ArrayList; 39 import java.util.List; 40 41 /** 42 * Common preference controller functionality shared by 43 * ZenModePriorityMessagesPreferenceController and ZenModePriorityCallsPreferenceController. 44 * 45 * This includes the options to choose the priority senders that are allowed to bypass DND for 46 * calls or messages. This can be one of four values: starred contacts, all contacts, anyone, or 47 * no one. 48 */ 49 public class ZenModePrioritySendersPreferenceController 50 extends AbstractZenModePreferenceController { 51 @VisibleForTesting static final String KEY_ANY = "senders_anyone"; 52 @VisibleForTesting static final String KEY_CONTACTS = "senders_contacts"; 53 @VisibleForTesting static final String KEY_STARRED = "senders_starred_contacts"; 54 @VisibleForTesting static final String KEY_NONE = "senders_none"; 55 56 private static final Intent ALL_CONTACTS_INTENT = 57 new Intent(Contacts.Intents.UI.LIST_DEFAULT); 58 private static final Intent STARRED_CONTACTS_INTENT = 59 new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION); 60 private static final Intent FALLBACK_INTENT = new Intent(Intent.ACTION_MAIN); 61 62 private final PackageManager mPackageManager; 63 private final boolean mIsMessages; // if this is false, then this preference is for calls 64 65 private PreferenceCategory mPreferenceCategory; 66 private List<RadioButtonPreference> mRadioButtonPreferences = new ArrayList<>(); 67 ZenModePrioritySendersPreferenceController(Context context, String key, Lifecycle lifecycle, boolean isMessages)68 public ZenModePrioritySendersPreferenceController(Context context, String key, 69 Lifecycle lifecycle, boolean isMessages) { 70 super(context, key, lifecycle); 71 mIsMessages = isMessages; 72 73 mPackageManager = mContext.getPackageManager(); 74 if (!FALLBACK_INTENT.hasCategory(Intent.CATEGORY_APP_CONTACTS)) { 75 FALLBACK_INTENT.addCategory(Intent.CATEGORY_APP_CONTACTS); 76 } 77 } 78 79 @Override displayPreference(PreferenceScreen screen)80 public void displayPreference(PreferenceScreen screen) { 81 mPreferenceCategory = screen.findPreference(getPreferenceKey()); 82 if (mPreferenceCategory.findPreference(KEY_ANY) == null) { 83 makeRadioPreference(KEY_STARRED, 84 com.android.settings.R.string.zen_mode_from_starred); 85 makeRadioPreference(KEY_CONTACTS, 86 com.android.settings.R.string.zen_mode_from_contacts); 87 makeRadioPreference(KEY_ANY, 88 com.android.settings.R.string.zen_mode_from_anyone); 89 makeRadioPreference(KEY_NONE, 90 mIsMessages 91 ? com.android.settings.R.string.zen_mode_none_messages 92 : com.android.settings.R.string.zen_mode_none_calls); 93 updateSummaries(); 94 } 95 96 super.displayPreference(screen); 97 } 98 99 @Override isAvailable()100 public boolean isAvailable() { 101 return true; 102 } 103 104 @Override getPreferenceKey()105 public String getPreferenceKey() { 106 return KEY; 107 } 108 109 @Override updateState(Preference preference)110 public void updateState(Preference preference) { 111 final int currSetting = getPrioritySenders(); 112 113 for (RadioButtonPreference pref : mRadioButtonPreferences) { 114 pref.setChecked(keyToSetting(pref.getKey()) == currSetting); 115 } 116 } 117 118 @Override onResume()119 public void onResume() { 120 super.onResume(); 121 updateSummaries(); 122 } 123 updateSummaries()124 private void updateSummaries() { 125 for (RadioButtonPreference pref : mRadioButtonPreferences) { 126 pref.setSummary(getSummary(pref.getKey())); 127 } 128 } 129 keyToSetting(String key)130 private static int keyToSetting(String key) { 131 switch (key) { 132 case KEY_STARRED: 133 return NotificationManager.Policy.PRIORITY_SENDERS_STARRED; 134 case KEY_CONTACTS: 135 return NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS; 136 case KEY_ANY: 137 return NotificationManager.Policy.PRIORITY_SENDERS_ANY; 138 case KEY_NONE: 139 default: 140 return ZenModeBackend.SOURCE_NONE; 141 } 142 } 143 getSummary(String key)144 private String getSummary(String key) { 145 switch (key) { 146 case KEY_STARRED: 147 return mBackend.getStarredContactsSummary(mContext); 148 case KEY_CONTACTS: 149 return mBackend.getContactsNumberSummary(mContext); 150 case KEY_ANY: 151 return mContext.getResources().getString(mIsMessages 152 ? R.string.zen_mode_all_messages_summary 153 : R.string.zen_mode_all_calls_summary); 154 case KEY_NONE: 155 default: 156 return null; 157 } 158 } 159 getPrioritySenders()160 private int getPrioritySenders() { 161 if (mIsMessages) { 162 return mBackend.getPriorityMessageSenders(); 163 } else { 164 return mBackend.getPriorityCallSenders(); 165 } 166 } 167 makeRadioPreference(String key, int titleId)168 private RadioButtonPreference makeRadioPreference(String key, int titleId) { 169 final RadioButtonPreference pref = 170 new RadioButtonPreference(mPreferenceCategory.getContext()); 171 pref.setKey(key); 172 pref.setTitle(titleId); 173 pref.setOnClickListener(mRadioButtonClickListener); 174 175 View.OnClickListener widgetClickListener = getWidgetClickListener(key); 176 if (widgetClickListener != null) { 177 pref.setExtraWidgetOnClickListener(widgetClickListener); 178 } 179 180 mPreferenceCategory.addPreference(pref); 181 mRadioButtonPreferences.add(pref); 182 return pref; 183 } 184 185 private RadioButtonPreference.OnClickListener mRadioButtonClickListener = 186 new RadioButtonPreference.OnClickListener() { 187 @Override 188 public void onRadioButtonClicked(RadioButtonPreference preference) { 189 int selectedSetting = keyToSetting(preference.getKey()); 190 if (selectedSetting != getPrioritySenders()) { 191 mBackend.saveSenders( 192 mIsMessages ? PRIORITY_CATEGORY_MESSAGES : PRIORITY_CATEGORY_CALLS, 193 selectedSetting); 194 } 195 } 196 }; 197 getWidgetClickListener(String key)198 private View.OnClickListener getWidgetClickListener(String key) { 199 if (!KEY_CONTACTS.equals(key) && !KEY_STARRED.equals(key)) { 200 return null; 201 } 202 203 if (KEY_STARRED.equals(key) && !isStarredIntentValid()) { 204 return null; 205 } 206 207 if (KEY_CONTACTS.equals(key) && !isContactsIntentValid()) { 208 return null; 209 } 210 211 return new View.OnClickListener() { 212 @Override 213 public void onClick(View v) { 214 if (KEY_STARRED.equals(key) 215 && STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { 216 mContext.startActivity(STARRED_CONTACTS_INTENT); 217 } else if (KEY_CONTACTS.equals(key) 218 && ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { 219 mContext.startActivity(ALL_CONTACTS_INTENT); 220 } else { 221 mContext.startActivity(FALLBACK_INTENT); 222 } 223 } 224 }; 225 } 226 227 private boolean isStarredIntentValid() { 228 return STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null 229 || FALLBACK_INTENT.resolveActivity(mPackageManager) != null; 230 } 231 232 private boolean isContactsIntentValid() { 233 return ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null 234 || FALLBACK_INTENT.resolveActivity(mPackageManager) != null; 235 } 236 } 237