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 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 59 private static final Intent STARRED_CONTACTS_INTENT = 60 new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION) 61 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 62 private static final Intent FALLBACK_INTENT = new Intent(Intent.ACTION_MAIN) 63 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 64 65 private final PackageManager mPackageManager; 66 private final boolean mIsMessages; // if this is false, then this preference is for calls 67 68 private PreferenceCategory mPreferenceCategory; 69 private List<RadioButtonPreference> mRadioButtonPreferences = new ArrayList<>(); 70 ZenModePrioritySendersPreferenceController(Context context, String key, Lifecycle lifecycle, boolean isMessages)71 public ZenModePrioritySendersPreferenceController(Context context, String key, 72 Lifecycle lifecycle, boolean isMessages) { 73 super(context, key, lifecycle); 74 mIsMessages = isMessages; 75 76 mPackageManager = mContext.getPackageManager(); 77 if (!FALLBACK_INTENT.hasCategory(Intent.CATEGORY_APP_CONTACTS)) { 78 FALLBACK_INTENT.addCategory(Intent.CATEGORY_APP_CONTACTS); 79 } 80 } 81 82 @Override displayPreference(PreferenceScreen screen)83 public void displayPreference(PreferenceScreen screen) { 84 mPreferenceCategory = screen.findPreference(getPreferenceKey()); 85 if (mPreferenceCategory.findPreference(KEY_ANY) == null) { 86 makeRadioPreference(KEY_STARRED, 87 com.android.settings.R.string.zen_mode_from_starred); 88 makeRadioPreference(KEY_CONTACTS, 89 com.android.settings.R.string.zen_mode_from_contacts); 90 makeRadioPreference(KEY_ANY, 91 com.android.settings.R.string.zen_mode_from_anyone); 92 makeRadioPreference(KEY_NONE, 93 mIsMessages 94 ? com.android.settings.R.string.zen_mode_none_messages 95 : com.android.settings.R.string.zen_mode_none_calls); 96 updateSummaries(); 97 } 98 99 super.displayPreference(screen); 100 } 101 102 @Override isAvailable()103 public boolean isAvailable() { 104 return true; 105 } 106 107 @Override getPreferenceKey()108 public String getPreferenceKey() { 109 return KEY; 110 } 111 112 @Override updateState(Preference preference)113 public void updateState(Preference preference) { 114 final int currSetting = getPrioritySenders(); 115 116 for (RadioButtonPreference pref : mRadioButtonPreferences) { 117 pref.setChecked(keyToSetting(pref.getKey()) == currSetting); 118 } 119 } 120 121 @Override onResume()122 public void onResume() { 123 super.onResume(); 124 updateSummaries(); 125 } 126 updateSummaries()127 private void updateSummaries() { 128 for (RadioButtonPreference pref : mRadioButtonPreferences) { 129 pref.setSummary(getSummary(pref.getKey())); 130 } 131 } 132 keyToSetting(String key)133 private static int keyToSetting(String key) { 134 switch (key) { 135 case KEY_STARRED: 136 return NotificationManager.Policy.PRIORITY_SENDERS_STARRED; 137 case KEY_CONTACTS: 138 return NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS; 139 case KEY_ANY: 140 return NotificationManager.Policy.PRIORITY_SENDERS_ANY; 141 case KEY_NONE: 142 default: 143 return ZenModeBackend.SOURCE_NONE; 144 } 145 } 146 getSummary(String key)147 private String getSummary(String key) { 148 switch (key) { 149 case KEY_STARRED: 150 return mBackend.getStarredContactsSummary(mContext); 151 case KEY_CONTACTS: 152 return mBackend.getContactsNumberSummary(mContext); 153 case KEY_ANY: 154 return mContext.getResources().getString(mIsMessages 155 ? R.string.zen_mode_all_messages_summary 156 : R.string.zen_mode_all_calls_summary); 157 case KEY_NONE: 158 default: 159 return null; 160 } 161 } 162 getPrioritySenders()163 private int getPrioritySenders() { 164 if (mIsMessages) { 165 return mBackend.getPriorityMessageSenders(); 166 } else { 167 return mBackend.getPriorityCallSenders(); 168 } 169 } 170 makeRadioPreference(String key, int titleId)171 private RadioButtonPreference makeRadioPreference(String key, int titleId) { 172 final RadioButtonPreference pref = 173 new RadioButtonPreference(mPreferenceCategory.getContext()); 174 pref.setKey(key); 175 pref.setTitle(titleId); 176 pref.setOnClickListener(mRadioButtonClickListener); 177 178 View.OnClickListener widgetClickListener = getWidgetClickListener(key); 179 if (widgetClickListener != null) { 180 pref.setExtraWidgetOnClickListener(widgetClickListener); 181 } 182 183 mPreferenceCategory.addPreference(pref); 184 mRadioButtonPreferences.add(pref); 185 return pref; 186 } 187 188 private RadioButtonPreference.OnClickListener mRadioButtonClickListener = 189 new RadioButtonPreference.OnClickListener() { 190 @Override 191 public void onRadioButtonClicked(RadioButtonPreference preference) { 192 int selectedSetting = keyToSetting(preference.getKey()); 193 if (selectedSetting != getPrioritySenders()) { 194 mBackend.saveSenders( 195 mIsMessages ? PRIORITY_CATEGORY_MESSAGES : PRIORITY_CATEGORY_CALLS, 196 selectedSetting); 197 } 198 } 199 }; 200 getWidgetClickListener(String key)201 private View.OnClickListener getWidgetClickListener(String key) { 202 if (!KEY_CONTACTS.equals(key) && !KEY_STARRED.equals(key)) { 203 return null; 204 } 205 206 if (KEY_STARRED.equals(key) && !isStarredIntentValid()) { 207 return null; 208 } 209 210 if (KEY_CONTACTS.equals(key) && !isContactsIntentValid()) { 211 return null; 212 } 213 214 return new View.OnClickListener() { 215 @Override 216 public void onClick(View v) { 217 if (KEY_STARRED.equals(key) 218 && STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { 219 mContext.startActivity(STARRED_CONTACTS_INTENT); 220 } else if (KEY_CONTACTS.equals(key) 221 && ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { 222 mContext.startActivity(ALL_CONTACTS_INTENT); 223 } else { 224 mContext.startActivity(FALLBACK_INTENT); 225 } 226 } 227 }; 228 } 229 230 private boolean isStarredIntentValid() { 231 return STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null 232 || FALLBACK_INTENT.resolveActivity(mPackageManager) != null; 233 } 234 235 private boolean isContactsIntentValid() { 236 return ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null 237 || FALLBACK_INTENT.resolveActivity(mPackageManager) != null; 238 } 239 } 240