/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.notification.zen; import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.provider.Contacts; import android.view.View; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.widget.RadioButtonPreference; import java.util.ArrayList; import java.util.List; /** * Common preference controller functionality shared by * ZenModePriorityMessagesPreferenceController and ZenModePriorityCallsPreferenceController. * * This includes the options to choose the priority senders that are allowed to bypass DND for * calls or messages. This can be one of four values: starred contacts, all contacts, anyone, or * no one. */ public class ZenModePrioritySendersPreferenceController extends AbstractZenModePreferenceController { @VisibleForTesting static final String KEY_ANY = "senders_anyone"; @VisibleForTesting static final String KEY_CONTACTS = "senders_contacts"; @VisibleForTesting static final String KEY_STARRED = "senders_starred_contacts"; @VisibleForTesting static final String KEY_NONE = "senders_none"; private static final Intent ALL_CONTACTS_INTENT = new Intent(Contacts.Intents.UI.LIST_DEFAULT); private static final Intent STARRED_CONTACTS_INTENT = new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION); private static final Intent FALLBACK_INTENT = new Intent(Intent.ACTION_MAIN); private final PackageManager mPackageManager; private final boolean mIsMessages; // if this is false, then this preference is for calls private PreferenceCategory mPreferenceCategory; private List mRadioButtonPreferences = new ArrayList<>(); public ZenModePrioritySendersPreferenceController(Context context, String key, Lifecycle lifecycle, boolean isMessages) { super(context, key, lifecycle); mIsMessages = isMessages; mPackageManager = mContext.getPackageManager(); if (!FALLBACK_INTENT.hasCategory(Intent.CATEGORY_APP_CONTACTS)) { FALLBACK_INTENT.addCategory(Intent.CATEGORY_APP_CONTACTS); } } @Override public void displayPreference(PreferenceScreen screen) { mPreferenceCategory = screen.findPreference(getPreferenceKey()); if (mPreferenceCategory.findPreference(KEY_ANY) == null) { makeRadioPreference(KEY_STARRED, com.android.settings.R.string.zen_mode_from_starred); makeRadioPreference(KEY_CONTACTS, com.android.settings.R.string.zen_mode_from_contacts); makeRadioPreference(KEY_ANY, com.android.settings.R.string.zen_mode_from_anyone); makeRadioPreference(KEY_NONE, mIsMessages ? com.android.settings.R.string.zen_mode_none_messages : com.android.settings.R.string.zen_mode_none_calls); updateSummaries(); } super.displayPreference(screen); } @Override public boolean isAvailable() { return true; } @Override public String getPreferenceKey() { return KEY; } @Override public void updateState(Preference preference) { final int currSetting = getPrioritySenders(); for (RadioButtonPreference pref : mRadioButtonPreferences) { pref.setChecked(keyToSetting(pref.getKey()) == currSetting); } } @Override public void onResume() { super.onResume(); updateSummaries(); } private void updateSummaries() { for (RadioButtonPreference pref : mRadioButtonPreferences) { pref.setSummary(getSummary(pref.getKey())); } } private static int keyToSetting(String key) { switch (key) { case KEY_STARRED: return NotificationManager.Policy.PRIORITY_SENDERS_STARRED; case KEY_CONTACTS: return NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS; case KEY_ANY: return NotificationManager.Policy.PRIORITY_SENDERS_ANY; case KEY_NONE: default: return ZenModeBackend.SOURCE_NONE; } } private String getSummary(String key) { switch (key) { case KEY_STARRED: return mBackend.getStarredContactsSummary(mContext); case KEY_CONTACTS: return mBackend.getContactsNumberSummary(mContext); case KEY_ANY: return mContext.getResources().getString(mIsMessages ? R.string.zen_mode_all_messages_summary : R.string.zen_mode_all_calls_summary); case KEY_NONE: default: return null; } } private int getPrioritySenders() { if (mIsMessages) { return mBackend.getPriorityMessageSenders(); } else { return mBackend.getPriorityCallSenders(); } } private RadioButtonPreference makeRadioPreference(String key, int titleId) { final RadioButtonPreference pref = new RadioButtonPreference(mPreferenceCategory.getContext()); pref.setKey(key); pref.setTitle(titleId); pref.setOnClickListener(mRadioButtonClickListener); View.OnClickListener widgetClickListener = getWidgetClickListener(key); if (widgetClickListener != null) { pref.setExtraWidgetOnClickListener(widgetClickListener); } mPreferenceCategory.addPreference(pref); mRadioButtonPreferences.add(pref); return pref; } private RadioButtonPreference.OnClickListener mRadioButtonClickListener = new RadioButtonPreference.OnClickListener() { @Override public void onRadioButtonClicked(RadioButtonPreference preference) { int selectedSetting = keyToSetting(preference.getKey()); if (selectedSetting != getPrioritySenders()) { mBackend.saveSenders( mIsMessages ? PRIORITY_CATEGORY_MESSAGES : PRIORITY_CATEGORY_CALLS, selectedSetting); } } }; private View.OnClickListener getWidgetClickListener(String key) { if (!KEY_CONTACTS.equals(key) && !KEY_STARRED.equals(key)) { return null; } if (KEY_STARRED.equals(key) && !isStarredIntentValid()) { return null; } if (KEY_CONTACTS.equals(key) && !isContactsIntentValid()) { return null; } return new View.OnClickListener() { @Override public void onClick(View v) { if (KEY_STARRED.equals(key) && STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { mContext.startActivity(STARRED_CONTACTS_INTENT); } else if (KEY_CONTACTS.equals(key) && ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null) { mContext.startActivity(ALL_CONTACTS_INTENT); } else { mContext.startActivity(FALLBACK_INTENT); } } }; } private boolean isStarredIntentValid() { return STARRED_CONTACTS_INTENT.resolveActivity(mPackageManager) != null || FALLBACK_INTENT.resolveActivity(mPackageManager) != null; } private boolean isContactsIntentValid() { return ALL_CONTACTS_INTENT.resolveActivity(mPackageManager) != null || FALLBACK_INTENT.resolveActivity(mPackageManager) != null; } }