Show icons for allowed contacts
Test: atest com.android.settings.notification.modes Bug: 346551087 Flag: android.app.modes_ui Change-Id: If2b6b06b4a9c16bdefb03850ad1615e96c601fbd
This commit is contained in:
@@ -20,6 +20,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
@@ -29,11 +36,16 @@ import android.view.Gravity;
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Px;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.Utils;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
class IconUtil {
|
||||
|
||||
static Drawable applyNormalTint(@NonNull Context context, @NonNull Drawable icon) {
|
||||
@@ -87,9 +99,10 @@ class IconUtil {
|
||||
/**
|
||||
* Returns a variant of the supplied icon to be used in a {@link CircularIconsPreference}. The
|
||||
* inner icon is 20x20 dp and it's contained in a circle of diameter 32dp, and is tinted
|
||||
* with the "material secondary container" color combination.
|
||||
* with the "material secondary" color combination.
|
||||
*/
|
||||
static Drawable makeSoundIcon(@NonNull Context context, @DrawableRes int iconResId) {
|
||||
static Drawable makeCircularIconPreferenceItem(@NonNull Context context,
|
||||
@DrawableRes int iconResId) {
|
||||
return composeIconCircle(
|
||||
Utils.getColorAttr(context,
|
||||
com.android.internal.R.attr.materialColorSecondaryContainer),
|
||||
@@ -102,6 +115,53 @@ class IconUtil {
|
||||
R.dimen.zen_mode_circular_icon_inner_icon_size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an icon representing a contact that doesn't have an associated photo, to be used in
|
||||
* a {@link CircularIconsPreference}, tinted with the "material tertiary". If the contact's
|
||||
* display name is not empty, it's the contact's monogram, otherwise it's a generic icon.
|
||||
*/
|
||||
static Drawable makeContactMonogram(@NonNull Context context, @Nullable String displayName) {
|
||||
Resources res = context.getResources();
|
||||
if (Strings.isNullOrEmpty(displayName)) {
|
||||
return composeIconCircle(
|
||||
Utils.getColorAttr(context,
|
||||
com.android.internal.R.attr.materialColorTertiaryContainer),
|
||||
res.getDimensionPixelSize(R.dimen.zen_mode_circular_icon_diameter),
|
||||
checkNotNull(context.getDrawable(R.drawable.ic_zen_mode_generic_contact)),
|
||||
Utils.getColorAttr(context,
|
||||
com.android.internal.R.attr.materialColorOnTertiaryContainer),
|
||||
res.getDimensionPixelSize(R.dimen.zen_mode_circular_icon_inner_icon_size));
|
||||
}
|
||||
|
||||
float diameter = res.getDimensionPixelSize(R.dimen.zen_mode_circular_icon_diameter);
|
||||
Bitmap bitmap = Bitmap.createBitmap((int) diameter, (int) diameter,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
|
||||
Paint circlePaint = new Paint();
|
||||
circlePaint.setColor(Utils.getColorAttrDefaultColor(context,
|
||||
com.android.internal.R.attr.materialColorTertiaryContainer));
|
||||
circlePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
|
||||
canvas.drawCircle(diameter / 2f, diameter / 2f, diameter / 2f, circlePaint);
|
||||
|
||||
Paint textPaint = new Paint();
|
||||
textPaint.setColor(Utils.getColorAttrDefaultColor(context,
|
||||
com.android.internal.R.attr.materialColorOnTertiaryContainer));
|
||||
textPaint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL));
|
||||
textPaint.setTextAlign(Paint.Align.LEFT);
|
||||
textPaint.setTextSize(res.getDimensionPixelSize(R.dimen.zen_mode_circular_icon_text_size));
|
||||
|
||||
String text = displayName.substring(0, 1).toUpperCase(Locale.getDefault());
|
||||
Rect textRect = new Rect();
|
||||
textPaint.getTextBounds(text, 0, text.length(), textRect);
|
||||
|
||||
float textX = diameter / 2f - textRect.width() / 2f - textRect.left;
|
||||
float textY = diameter / 2f + textRect.height() / 2f - textRect.bottom;
|
||||
canvas.drawText(text, textX, textY, textPaint);
|
||||
|
||||
return new BitmapDrawable(context.getResources(), bitmap);
|
||||
}
|
||||
|
||||
private static Drawable composeIconCircle(ColorStateList circleColor, @Px int circleDiameterPx,
|
||||
Drawable icon, ColorStateList iconColor, @Px int iconSizePx) {
|
||||
ShapeDrawable background = new ShapeDrawable(new OvalShape());
|
||||
|
||||
@@ -21,15 +21,22 @@ import android.app.INotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.ServiceManager;
|
||||
import android.provider.ContactsContract;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
|
||||
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -75,45 +82,99 @@ class ZenHelperBackend {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ParceledListSlice<ConversationChannelWrapper> getConversations(boolean onlyImportant) {
|
||||
ImmutableList<ConversationChannelWrapper> getImportantConversations() {
|
||||
try {
|
||||
return mInm.getConversations(onlyImportant);
|
||||
ImmutableList.Builder<ConversationChannelWrapper> list = new ImmutableList.Builder<>();
|
||||
ParceledListSlice<ConversationChannelWrapper> parceledList = mInm.getConversations(
|
||||
/* onlyImportant= */ true);
|
||||
if (parceledList != null) {
|
||||
for (ConversationChannelWrapper conversation : parceledList.getList()) {
|
||||
if (!conversation.getNotificationChannel().isDemoted()) {
|
||||
list.add(conversation);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.build();
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error calling NoMan", e);
|
||||
return ParceledListSlice.emptyList();
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
||||
|
||||
List<String> getStarredContacts() {
|
||||
record Contact(long id, @Nullable String displayName, @Nullable Uri photoUri) { }
|
||||
|
||||
ImmutableList<Contact> getAllContacts() {
|
||||
try (Cursor cursor = queryAllContactsData()) {
|
||||
return getContactsFromCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableList<Contact> getStarredContacts() {
|
||||
try (Cursor cursor = queryStarredContactsData()) {
|
||||
return getStarredContacts(cursor);
|
||||
return getContactsFromCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
List<String> getStarredContacts(Cursor cursor) {
|
||||
List<String> starredContacts = new ArrayList<>();
|
||||
private ImmutableList<Contact> getContactsFromCursor(Cursor cursor) {
|
||||
ImmutableList.Builder<Contact> list = new ImmutableList.Builder<>();
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
do {
|
||||
String contact = cursor.getString(0);
|
||||
starredContacts.add(contact != null ? contact :
|
||||
mContext.getString(R.string.zen_mode_starred_contacts_empty_name));
|
||||
|
||||
long id = cursor.getLong(0);
|
||||
String name = Strings.emptyToNull(cursor.getString(1));
|
||||
String photoUriStr = cursor.getString(2);
|
||||
Uri photoUri = !Strings.isNullOrEmpty(photoUriStr) ? Uri.parse(photoUriStr) : null;
|
||||
list.add(new Contact(id, name, photoUri));
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
return starredContacts;
|
||||
return list.build();
|
||||
}
|
||||
|
||||
int getAllContactsCount() {
|
||||
try (Cursor cursor = queryAllContactsData()) {
|
||||
return cursor != null ? cursor.getCount() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String[] CONTACTS_PROJECTION = new String[] {
|
||||
ContactsContract.Contacts._ID,
|
||||
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
|
||||
ContactsContract.Contacts.PHOTO_THUMBNAIL_URI
|
||||
};
|
||||
|
||||
private Cursor queryStarredContactsData() {
|
||||
return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
|
||||
new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
|
||||
ContactsContract.Data.STARRED + "=1", null,
|
||||
ContactsContract.Data.TIMES_CONTACTED);
|
||||
return mContext.getContentResolver().query(
|
||||
ContactsContract.Contacts.CONTENT_URI,
|
||||
CONTACTS_PROJECTION,
|
||||
/* selection= */ ContactsContract.Data.STARRED + "=1", /* selectionArgs= */ null,
|
||||
/* sortOrder= */ ContactsContract.Contacts.DISPLAY_NAME_PRIMARY);
|
||||
}
|
||||
|
||||
Cursor queryAllContactsData() {
|
||||
return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
|
||||
new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
|
||||
null, null, null);
|
||||
private Cursor queryAllContactsData() {
|
||||
return mContext.getContentResolver().query(
|
||||
ContactsContract.Contacts.CONTENT_URI,
|
||||
CONTACTS_PROJECTION,
|
||||
/* selection= */ null, /* selectionArgs= */ null,
|
||||
/* sortOrder= */ ContactsContract.Contacts.DISPLAY_NAME_PRIMARY);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
Drawable getContactPhoto(Contact contact) {
|
||||
if (contact.photoUri != null) {
|
||||
try (InputStream is = mContext.getContentResolver().openInputStream(contact.photoUri)) {
|
||||
if (is != null) {
|
||||
RoundedBitmapDrawable rbd = RoundedBitmapDrawableFactory.create(
|
||||
mContext.getResources(), is);
|
||||
if (rbd != null && rbd.getBitmap() != null) {
|
||||
rbd.setCircular(true);
|
||||
return rbd;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Couldn't load photo for " + contact, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to a monogram if no picture.
|
||||
return IconUtil.makeContactMonogram(mContext, contact.displayName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,6 @@ class ZenModeOtherLinkPreferenceController extends AbstractZenModePreferenceCont
|
||||
}
|
||||
}
|
||||
return new CircularIconSet<>(icons.build(),
|
||||
iconResId -> IconUtil.makeSoundIcon(mContext, iconResId));
|
||||
iconResId -> IconUtil.makeCircularIconPreferenceItem(mContext, iconResId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,25 +17,67 @@
|
||||
package com.android.settings.notification.modes;
|
||||
|
||||
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
|
||||
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE;
|
||||
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
|
||||
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_NONE;
|
||||
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE;
|
||||
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_CONTACTS;
|
||||
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_NONE;
|
||||
import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED;
|
||||
import static android.service.notification.ZenPolicy.STATE_ALLOW;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.service.notification.ZenPolicy;
|
||||
import android.service.notification.ZenPolicy.ConversationSenders;
|
||||
import android.service.notification.ZenPolicy.PeopleType;
|
||||
import android.util.IconDrawableFactory;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.notification.modes.ZenHelperBackend.Contact;
|
||||
import com.android.settingslib.notification.ConversationIconFactory;
|
||||
import com.android.settingslib.notification.modes.ZenMode;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Preference with a link and summary about what calls and messages can break through the mode
|
||||
* Preference with a link and summary about what calls and messages can break through the mode,
|
||||
* and icons representing those people.
|
||||
*/
|
||||
class ZenModePeopleLinkPreferenceController extends AbstractZenModePreferenceController {
|
||||
|
||||
private final ZenModeSummaryHelper mSummaryHelper;
|
||||
private final ZenHelperBackend mHelperBackend;
|
||||
private final ConversationIconFactory mConversationIconFactory;
|
||||
|
||||
public ZenModePeopleLinkPreferenceController(Context context, String key,
|
||||
ZenModePeopleLinkPreferenceController(Context context, String key,
|
||||
ZenHelperBackend helperBackend) {
|
||||
this(context, key, helperBackend,
|
||||
new ConversationIconFactory(context,
|
||||
context.getSystemService(LauncherApps.class),
|
||||
context.getPackageManager(),
|
||||
IconDrawableFactory.newInstance(context, false),
|
||||
context.getResources().getDimensionPixelSize(
|
||||
R.dimen.zen_mode_circular_icon_diameter)));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
ZenModePeopleLinkPreferenceController(Context context, String key,
|
||||
ZenHelperBackend helperBackend, ConversationIconFactory conversationIconFactory) {
|
||||
super(context, key);
|
||||
mSummaryHelper = new ZenModeSummaryHelper(mContext, helperBackend);
|
||||
mHelperBackend = helperBackend;
|
||||
mConversationIconFactory = conversationIconFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,8 +92,104 @@ class ZenModePeopleLinkPreferenceController extends AbstractZenModePreferenceCon
|
||||
ZenSubSettingLauncher.forModeFragment(mContext, ZenModePeopleFragment.class,
|
||||
zenMode.getId(), 0).toIntent());
|
||||
|
||||
preference.setSummary(mSummaryHelper.getPeopleSummary(zenMode));
|
||||
// TODO: b/346551087 - Show people icons
|
||||
((CircularIconsPreference) preference).displayIcons(CircularIconSet.EMPTY);
|
||||
preference.setSummary(mSummaryHelper.getPeopleSummary(zenMode.getPolicy()));
|
||||
((CircularIconsPreference) preference).displayIcons(getPeopleIcons(zenMode.getPolicy()));
|
||||
}
|
||||
|
||||
// Represents "Either<Contact, ConversationChannelWrapper>".
|
||||
record PeopleItem(@Nullable Contact contact,
|
||||
@Nullable ConversationChannelWrapper conversation) {
|
||||
|
||||
PeopleItem(@NonNull Contact contact) {
|
||||
this(contact, null);
|
||||
}
|
||||
|
||||
PeopleItem(@NonNull ConversationChannelWrapper conversation) {
|
||||
this(null, conversation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CircularIconSet<?> getPeopleIcons(ZenPolicy policy) {
|
||||
if (getCallersOrMessagesAllowed(policy) == PEOPLE_TYPE_ANYONE) {
|
||||
return new CircularIconSet<>(
|
||||
ImmutableList.of(IconUtil.makeCircularIconPreferenceItem(mContext,
|
||||
R.drawable.ic_zen_mode_people_all)),
|
||||
Function.identity());
|
||||
}
|
||||
|
||||
ImmutableList.Builder<PeopleItem> peopleItems = ImmutableList.builder();
|
||||
fetchContactsAllowed(policy, peopleItems);
|
||||
fetchConversationsAllowed(policy, peopleItems);
|
||||
return new CircularIconSet<>(peopleItems.build(), this::loadPeopleIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@link PeopleItem} entries corresponding to the set of people (contacts) who can
|
||||
* break through via either call OR message.
|
||||
*/
|
||||
private void fetchContactsAllowed(ZenPolicy policy,
|
||||
ImmutableList.Builder<PeopleItem> peopleItems) {
|
||||
@PeopleType int peopleAllowed = getCallersOrMessagesAllowed(policy);
|
||||
|
||||
ImmutableList<Contact> contactsAllowed = ImmutableList.of();
|
||||
if (peopleAllowed == PEOPLE_TYPE_CONTACTS) {
|
||||
contactsAllowed = mHelperBackend.getAllContacts();
|
||||
} else if (peopleAllowed == PEOPLE_TYPE_STARRED) {
|
||||
contactsAllowed = mHelperBackend.getStarredContacts();
|
||||
}
|
||||
|
||||
for (Contact contact : contactsAllowed) {
|
||||
peopleItems.add(new PeopleItem(contact));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@link PeopleItem} entries corresponding to the set of conversation channels that can
|
||||
* break through.
|
||||
*/
|
||||
private void fetchConversationsAllowed(ZenPolicy policy,
|
||||
ImmutableList.Builder<PeopleItem> peopleItems) {
|
||||
@ConversationSenders int conversationSendersAllowed =
|
||||
policy.getPriorityCategoryConversations() == STATE_ALLOW
|
||||
? policy.getPriorityConversationSenders()
|
||||
: CONVERSATION_SENDERS_NONE;
|
||||
ImmutableList<ConversationChannelWrapper> conversationsAllowed = ImmutableList.of();
|
||||
if (conversationSendersAllowed == CONVERSATION_SENDERS_ANYONE) {
|
||||
// TODO: b/354658240 - Need to handle CONVERSATION_SENDERS_ANYONE?
|
||||
return;
|
||||
} else if (conversationSendersAllowed == CONVERSATION_SENDERS_IMPORTANT) {
|
||||
conversationsAllowed = mHelperBackend.getImportantConversations();
|
||||
}
|
||||
|
||||
for (ConversationChannelWrapper conversation : conversationsAllowed) {
|
||||
peopleItems.add(new PeopleItem(conversation));
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the broadest set of people who can call OR message. */
|
||||
private @PeopleType int getCallersOrMessagesAllowed(ZenPolicy policy) {
|
||||
@PeopleType int callersAllowed = policy.getPriorityCategoryCalls() == STATE_ALLOW
|
||||
? policy.getPriorityCallSenders() : PEOPLE_TYPE_NONE;
|
||||
@PeopleType int messagesAllowed = policy.getPriorityCategoryMessages() == STATE_ALLOW
|
||||
? policy.getPriorityMessageSenders() : PEOPLE_TYPE_NONE;
|
||||
|
||||
// Order is ANYONE -> CONTACTS -> STARRED -> NONE, so just taking the minimum works.
|
||||
return Math.min(callersAllowed, messagesAllowed);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private Drawable loadPeopleIcon(PeopleItem peopleItem) {
|
||||
if (peopleItem.contact != null) {
|
||||
return mHelperBackend.getContactPhoto(peopleItem.contact);
|
||||
} else if (peopleItem.conversation != null) {
|
||||
return mConversationIconFactory.getConversationDrawable(
|
||||
peopleItem.conversation.getShortcutInfo(),
|
||||
peopleItem.conversation.getPkg(),
|
||||
peopleItem.conversation.getUid(),
|
||||
/* important= */ true);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Neither contact nor conversation!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,8 @@ import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.icu.text.MessageFormat;
|
||||
import android.provider.Contacts;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.service.notification.ZenPolicy;
|
||||
import android.view.View;
|
||||
|
||||
@@ -167,17 +165,7 @@ class ZenModePrioritySendersPreferenceController
|
||||
}
|
||||
|
||||
private void updateChannelCounts() {
|
||||
ParceledListSlice<ConversationChannelWrapper> impConversations =
|
||||
mHelperBackend.getConversations(true);
|
||||
int numImportantConversations = 0;
|
||||
if (impConversations != null) {
|
||||
for (ConversationChannelWrapper conversation : impConversations.getList()) {
|
||||
if (!conversation.getNotificationChannel().isDemoted()) {
|
||||
numImportantConversations++;
|
||||
}
|
||||
}
|
||||
}
|
||||
mNumImportantConversations = numImportantConversations;
|
||||
mNumImportantConversations = mHelperBackend.getImportantConversations().size();
|
||||
}
|
||||
|
||||
private int getPrioritySenders(ZenPolicy policy) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_MESSAGES;
|
||||
import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_REMINDERS;
|
||||
import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS;
|
||||
import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_SYSTEM;
|
||||
import static android.service.notification.ZenPolicy.STATE_ALLOW;
|
||||
import static android.service.notification.ZenPolicy.VISUAL_EFFECT_AMBIENT;
|
||||
import static android.service.notification.ZenPolicy.VISUAL_EFFECT_BADGE;
|
||||
import static android.service.notification.ZenPolicy.VISUAL_EFFECT_FULL_SCREEN_INTENT;
|
||||
@@ -45,6 +46,8 @@ import android.provider.Settings;
|
||||
import android.service.notification.ZenDeviceEffects;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.service.notification.ZenPolicy;
|
||||
import android.service.notification.ZenPolicy.ConversationSenders;
|
||||
import android.service.notification.ZenPolicy.PeopleType;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -56,6 +59,7 @@ import com.android.settings.R;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
import com.android.settingslib.notification.modes.ZenMode;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -365,7 +369,12 @@ class ZenModeSummaryHelper {
|
||||
}
|
||||
|
||||
public String getStarredContactsSummary() {
|
||||
List<String> starredContacts = mBackend.getStarredContacts();
|
||||
List<String> starredContacts = mBackend.getStarredContacts().stream()
|
||||
.map(ZenHelperBackend.Contact::displayName)
|
||||
.map(name -> Strings.isNullOrEmpty(name)
|
||||
? mContext.getString(R.string.zen_mode_starred_contacts_empty_name)
|
||||
: name)
|
||||
.toList();
|
||||
int numStarredContacts = starredContacts.size();
|
||||
MessageFormat msgFormat = new MessageFormat(
|
||||
mContext.getString(R.string.zen_mode_starred_contacts_summary_contacts),
|
||||
@@ -389,26 +398,32 @@ class ZenModeSummaryHelper {
|
||||
mContext.getString(R.string.zen_mode_contacts_count),
|
||||
Locale.getDefault());
|
||||
Map<String, Object> args = new HashMap<>();
|
||||
args.put("count", mBackend.queryAllContactsData().getCount());
|
||||
args.put("count", mBackend.getAllContactsCount());
|
||||
return msgFormat.format(args);
|
||||
}
|
||||
|
||||
public String getPeopleSummary(ZenMode zenMode) {
|
||||
final int callersAllowed = zenMode.getPolicy().getPriorityCallSenders();
|
||||
final int messagesAllowed = zenMode.getPolicy().getPriorityMessageSenders();
|
||||
final int conversationsAllowed = zenMode.getPolicy().getPriorityConversationSenders();
|
||||
public String getPeopleSummary(ZenPolicy policy) {
|
||||
@PeopleType int callersAllowed = policy.getPriorityCategoryCalls() == STATE_ALLOW
|
||||
? policy.getPriorityCallSenders() : PEOPLE_TYPE_NONE;
|
||||
@PeopleType int messagesAllowed = policy.getPriorityCategoryMessages() == STATE_ALLOW
|
||||
? policy.getPriorityMessageSenders() : PEOPLE_TYPE_NONE;
|
||||
@ConversationSenders int conversationsAllowed =
|
||||
policy.getPriorityCategoryConversations() == STATE_ALLOW
|
||||
? policy.getPriorityConversationSenders()
|
||||
: CONVERSATION_SENDERS_NONE;
|
||||
final boolean areRepeatCallersAllowed =
|
||||
zenMode.getPolicy().isCategoryAllowed(PRIORITY_CATEGORY_REPEAT_CALLERS, false);
|
||||
policy.isCategoryAllowed(PRIORITY_CATEGORY_REPEAT_CALLERS, false);
|
||||
|
||||
if (callersAllowed == PEOPLE_TYPE_ANYONE
|
||||
&& messagesAllowed == PEOPLE_TYPE_ANYONE
|
||||
&& conversationsAllowed == CONVERSATION_SENDERS_ANYONE) {
|
||||
return mContext.getResources().getString(R.string.zen_mode_people_all);
|
||||
return mContext.getString(R.string.zen_mode_people_all);
|
||||
} else if (callersAllowed == PEOPLE_TYPE_NONE
|
||||
&& messagesAllowed == PEOPLE_TYPE_NONE
|
||||
&& conversationsAllowed == CONVERSATION_SENDERS_NONE
|
||||
&& !areRepeatCallersAllowed) {
|
||||
return mContext.getResources().getString(R.string.zen_mode_people_none);
|
||||
&& conversationsAllowed == CONVERSATION_SENDERS_NONE) {
|
||||
return mContext.getString(
|
||||
areRepeatCallersAllowed ? R.string.zen_mode_people_repeat_callers
|
||||
: R.string.zen_mode_people_none);
|
||||
} else {
|
||||
return mContext.getResources().getString(R.string.zen_mode_people_some);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user