Calculate People Tiles messages count properly
Change-Id: If072e43e1c827ebbf7250f832b969118df81755a Test: manual Bug: 183382000
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.systemui.people;
|
||||
|
||||
import static android.Manifest.permission.READ_CONTACTS;
|
||||
import static android.app.Notification.CATEGORY_MISSED_CALL;
|
||||
import static android.app.Notification.EXTRA_MESSAGES;
|
||||
import static android.app.Notification.EXTRA_PEOPLE_LIST;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Notification;
|
||||
import android.app.Person;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Parcelable;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/** Helper functions to handle notifications in People Tiles. */
|
||||
public class NotificationHelper {
|
||||
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
|
||||
private static final String TAG = "PeopleNotificationHelper";
|
||||
|
||||
/** Returns the notification with highest priority to be shown in People Tiles. */
|
||||
public static NotificationEntry getHighestPriorityNotification(
|
||||
Set<NotificationEntry> notificationEntries) {
|
||||
if (notificationEntries == null || notificationEntries.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return notificationEntries
|
||||
.stream()
|
||||
.filter(NotificationHelper::isMissedCallOrHasContent)
|
||||
.sorted(notificationEntryComparator)
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
|
||||
/** Notification comparator, checking category and timestamps, in reverse order of priority. */
|
||||
public static Comparator<NotificationEntry> notificationEntryComparator =
|
||||
new Comparator<NotificationEntry>() {
|
||||
@Override
|
||||
public int compare(NotificationEntry e1, NotificationEntry e2) {
|
||||
Notification n1 = e1.getSbn().getNotification();
|
||||
Notification n2 = e2.getSbn().getNotification();
|
||||
|
||||
boolean missedCall1 = isMissedCall(n1);
|
||||
boolean missedCall2 = isMissedCall(n2);
|
||||
if (missedCall1 && !missedCall2) {
|
||||
return -1;
|
||||
}
|
||||
if (!missedCall1 && missedCall2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get messages in reverse chronological order.
|
||||
List<Notification.MessagingStyle.Message> messages1 =
|
||||
getMessagingStyleMessages(n1);
|
||||
List<Notification.MessagingStyle.Message> messages2 =
|
||||
getMessagingStyleMessages(n2);
|
||||
|
||||
if (messages1 != null && messages2 != null) {
|
||||
Notification.MessagingStyle.Message message1 = messages1.get(0);
|
||||
Notification.MessagingStyle.Message message2 = messages2.get(0);
|
||||
return (int) (message2.getTimestamp() - message1.getTimestamp());
|
||||
}
|
||||
|
||||
if (messages1 == null) {
|
||||
return 1;
|
||||
}
|
||||
if (messages2 == null) {
|
||||
return -1;
|
||||
}
|
||||
return (int) (n2.when - n1.when);
|
||||
}
|
||||
};
|
||||
|
||||
/** Returns whether {@code e} is a missed call notification. */
|
||||
public static boolean isMissedCall(NotificationEntry e) {
|
||||
return e != null && e.getSbn().getNotification() != null
|
||||
&& isMissedCall(e.getSbn().getNotification());
|
||||
}
|
||||
|
||||
/** Returns whether {@code notification} is a missed call notification. */
|
||||
public static boolean isMissedCall(Notification notification) {
|
||||
return notification != null && Objects.equals(notification.category, CATEGORY_MISSED_CALL);
|
||||
}
|
||||
|
||||
private static boolean hasContent(NotificationEntry e) {
|
||||
if (e == null) {
|
||||
return false;
|
||||
}
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
getMessagingStyleMessages(e.getSbn().getNotification());
|
||||
return messages != null && !messages.isEmpty();
|
||||
}
|
||||
|
||||
/** Returns whether {@code e} is a valid conversation notification. */
|
||||
public static boolean isValid(NotificationEntry e) {
|
||||
return e != null && e.getRanking() != null
|
||||
&& e.getRanking().getConversationShortcutInfo() != null
|
||||
&& e.getSbn().getNotification() != null;
|
||||
}
|
||||
|
||||
/** Returns whether conversation notification should be shown in People Tile. */
|
||||
public static boolean isMissedCallOrHasContent(NotificationEntry e) {
|
||||
return isMissedCall(e) || hasContent(e);
|
||||
}
|
||||
|
||||
/** Returns whether {@code sbn}'s package has permission to read contacts. */
|
||||
public static boolean hasReadContactsPermission(
|
||||
PackageManager packageManager, StatusBarNotification sbn) {
|
||||
return packageManager.checkPermission(READ_CONTACTS,
|
||||
sbn.getPackageName()) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a notification should be matched to other Tiles by Uri.
|
||||
*
|
||||
* <p>Currently only matches missed calls.
|
||||
*/
|
||||
public static boolean shouldMatchNotificationByUri(StatusBarNotification sbn) {
|
||||
Notification notification = sbn.getNotification();
|
||||
if (notification == null) {
|
||||
if (DEBUG) Log.d(TAG, "Notification is null");
|
||||
return false;
|
||||
}
|
||||
boolean isMissedCall = isMissedCall(notification);
|
||||
if (!isMissedCall) {
|
||||
if (DEBUG) Log.d(TAG, "Not missed call");
|
||||
}
|
||||
return isMissedCall;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to retrieve a valid Uri via {@code sbn}, falling back to the {@code
|
||||
* contactUriFromShortcut} if valid.
|
||||
*/
|
||||
@Nullable
|
||||
public static String getContactUri(StatusBarNotification sbn) {
|
||||
// First, try to get a Uri from the Person directly set on the Notification.
|
||||
ArrayList<Person> people = sbn.getNotification().extras.getParcelableArrayList(
|
||||
EXTRA_PEOPLE_LIST);
|
||||
if (people != null && people.get(0) != null) {
|
||||
String contactUri = people.get(0).getUri();
|
||||
if (contactUri != null && !contactUri.isEmpty()) {
|
||||
return contactUri;
|
||||
}
|
||||
}
|
||||
|
||||
// Then, try to get a Uri from the Person set on the Notification message.
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
getMessagingStyleMessages(sbn.getNotification());
|
||||
if (messages != null && !messages.isEmpty()) {
|
||||
Notification.MessagingStyle.Message message = messages.get(0);
|
||||
Person sender = message.getSenderPerson();
|
||||
if (sender != null && sender.getUri() != null && !sender.getUri().isEmpty()) {
|
||||
return sender.getUri();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link Notification.MessagingStyle.Message}s from the Notification in chronological
|
||||
* order from most recent to least.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
@Nullable
|
||||
public static List<Notification.MessagingStyle.Message> getMessagingStyleMessages(
|
||||
Notification notification) {
|
||||
if (notification == null) {
|
||||
return null;
|
||||
}
|
||||
if (Notification.MessagingStyle.class.equals(notification.getNotificationStyle())
|
||||
&& notification.extras != null) {
|
||||
final Parcelable[] messages = notification.extras.getParcelableArray(EXTRA_MESSAGES);
|
||||
if (!ArrayUtils.isEmpty(messages)) {
|
||||
List<Notification.MessagingStyle.Message> sortedMessages =
|
||||
Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
|
||||
sortedMessages.sort(Collections.reverseOrder(
|
||||
Comparator.comparing(Notification.MessagingStyle.Message::getTimestamp)));
|
||||
return sortedMessages;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,36 +16,28 @@
|
||||
|
||||
package com.android.systemui.people;
|
||||
|
||||
import android.app.people.IPeopleManager;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
|
||||
import com.android.systemui.shared.system.PeopleProviderUtils;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
|
||||
/** API that returns a People Tile preview. */
|
||||
public class PeopleProvider extends ContentProvider {
|
||||
|
||||
LauncherApps mLauncherApps;
|
||||
IPeopleManager mPeopleManager;
|
||||
NotificationEntryManager mNotificationEntryManager;
|
||||
|
||||
private static final String TAG = "PeopleProvider";
|
||||
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
|
||||
private static final String EMPTY_STRING = "";
|
||||
|
||||
PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
|
||||
|
||||
@Override
|
||||
public Bundle call(String method, String arg, Bundle extras) {
|
||||
if (!doesCallerHavePermission()) {
|
||||
@@ -83,17 +75,11 @@ public class PeopleProvider extends ContentProvider {
|
||||
throw new IllegalArgumentException("Null user handle");
|
||||
}
|
||||
|
||||
// If services are not set as mocks in tests, fetch them now.
|
||||
mPeopleManager = mPeopleManager != null ? mPeopleManager
|
||||
: IPeopleManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.PEOPLE_SERVICE));
|
||||
mLauncherApps = mLauncherApps != null ? mLauncherApps
|
||||
: getContext().getSystemService(LauncherApps.class);
|
||||
mNotificationEntryManager = mNotificationEntryManager != null ? mNotificationEntryManager
|
||||
: Dependency.get(NotificationEntryManager.class);
|
||||
|
||||
RemoteViews view = PeopleSpaceUtils.getPreview(getContext(), mPeopleManager, mLauncherApps,
|
||||
mNotificationEntryManager, shortcutId, userHandle, packageName, extras);
|
||||
if (mPeopleSpaceWidgetManager == null) {
|
||||
mPeopleSpaceWidgetManager = new PeopleSpaceWidgetManager(getContext());
|
||||
}
|
||||
RemoteViews view =
|
||||
mPeopleSpaceWidgetManager.getPreview(shortcutId, userHandle, packageName, extras);
|
||||
if (view == null) {
|
||||
if (DEBUG) Log.d(TAG, "No preview available for shortcutId: " + shortcutId);
|
||||
return null;
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
|
||||
import com.android.systemui.people.widget.PeopleTileKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -136,14 +137,15 @@ public class PeopleSpaceActivity extends Activity {
|
||||
getSizeInDp(mContext, R.dimen.avatar_size_for_medium,
|
||||
mContext.getResources().getDisplayMetrics().density)));
|
||||
|
||||
tileView.setOnClickListener(v -> storeWidgetConfiguration(tile));
|
||||
PeopleTileKey key = new PeopleTileKey(tile);
|
||||
tileView.setOnClickListener(v -> storeWidgetConfiguration(tile, key));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Couldn't retrieve shortcut information", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Stores the user selected configuration for {@code mAppWidgetId}. */
|
||||
private void storeWidgetConfiguration(PeopleSpaceTile tile) {
|
||||
private void storeWidgetConfiguration(PeopleSpaceTile tile, PeopleTileKey key) {
|
||||
if (PeopleSpaceUtils.DEBUG) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Put " + tile.getUserName() + "'s shortcut ID: "
|
||||
@@ -151,7 +153,7 @@ public class PeopleSpaceActivity extends Activity {
|
||||
+ mAppWidgetId);
|
||||
}
|
||||
}
|
||||
mPeopleSpaceWidgetManager.addNewWidget(mAppWidgetId, tile);
|
||||
mPeopleSpaceWidgetManager.addNewWidget(mAppWidgetId, key);
|
||||
finishActivity();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
|
||||
package com.android.systemui.people;
|
||||
|
||||
import static android.app.Notification.CATEGORY_MISSED_CALL;
|
||||
import static android.app.Notification.EXTRA_MESSAGES;
|
||||
import static com.android.systemui.people.NotificationHelper.getContactUri;
|
||||
import static com.android.systemui.people.NotificationHelper.getMessagingStyleMessages;
|
||||
import static com.android.systemui.people.NotificationHelper.hasReadContactsPermission;
|
||||
import static com.android.systemui.people.NotificationHelper.isMissedCall;
|
||||
import static com.android.systemui.people.NotificationHelper.shouldMatchNotificationByUri;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.people.ConversationChannel;
|
||||
@@ -27,6 +30,7 @@ import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
@@ -36,9 +40,6 @@ import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.ContactsContract;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
@@ -56,19 +57,16 @@ import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.people.widget.AppWidgetOptionsHelper;
|
||||
import com.android.systemui.people.widget.PeopleTileKey;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -185,73 +183,85 @@ public class PeopleSpaceUtils {
|
||||
editor.putStringSet(storageKey, storedWidgetIds);
|
||||
}
|
||||
|
||||
/** Augments a single {@link PeopleSpaceTile} with notification content, if one is present. */
|
||||
public static PeopleSpaceTile augmentSingleTileFromVisibleNotifications(Context context,
|
||||
PeopleSpaceTile tile, NotificationEntryManager notificationEntryManager) {
|
||||
List<PeopleSpaceTile> augmentedTile = augmentTilesFromVisibleNotifications(
|
||||
context, Arrays.asList(tile), notificationEntryManager);
|
||||
return augmentedTile.get(0);
|
||||
}
|
||||
|
||||
/** Adds to {@code tiles} any visible notifications. */
|
||||
public static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context,
|
||||
List<PeopleSpaceTile> tiles, NotificationEntryManager notificationEntryManager) {
|
||||
if (notificationEntryManager == null) {
|
||||
Log.w(TAG, "NotificationEntryManager is null");
|
||||
return tiles;
|
||||
/** Returns notifications that match provided {@code contactUri}. */
|
||||
public static List<NotificationEntry> getNotificationsByUri(
|
||||
PackageManager packageManager, String contactUri,
|
||||
Map<PeopleTileKey, Set<NotificationEntry>> notifications) {
|
||||
if (DEBUG) Log.d(TAG, "Getting notifications by contact URI.");
|
||||
if (TextUtils.isEmpty(contactUri)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map<PeopleTileKey, NotificationEntry> visibleNotifications = notificationEntryManager
|
||||
.getVisibleNotifications()
|
||||
.stream()
|
||||
.filter(entry -> entry.getRanking() != null
|
||||
&& entry.getRanking().getConversationShortcutInfo() != null)
|
||||
.collect(Collectors.toMap(PeopleTileKey::new, e -> e,
|
||||
// Handle duplicate keys to avoid crashes.
|
||||
(e1, e2) -> e1.getSbn().getNotification().when
|
||||
> e2.getSbn().getNotification().when ? e1 : e2));
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Number of visible notifications:" + visibleNotifications.size());
|
||||
}
|
||||
return tiles
|
||||
.stream()
|
||||
.map(entry -> augmentTileFromVisibleNotifications(
|
||||
context, entry, visibleNotifications))
|
||||
return notifications.entrySet().stream().flatMap(e -> e.getValue().stream())
|
||||
.filter(e ->
|
||||
hasReadContactsPermission(packageManager, e.getSbn())
|
||||
&& shouldMatchNotificationByUri(e.getSbn())
|
||||
&& Objects.equals(contactUri, getContactUri(e.getSbn()))
|
||||
)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
static PeopleSpaceTile augmentTileFromVisibleNotifications(Context context,
|
||||
PeopleSpaceTile tile, Map<PeopleTileKey, NotificationEntry> visibleNotifications) {
|
||||
PeopleTileKey key = new PeopleTileKey(
|
||||
tile.getId(), getUserId(tile), tile.getPackageName());
|
||||
// TODO: Match missed calls with matching Uris in addition to keys.
|
||||
if (!visibleNotifications.containsKey(key)) {
|
||||
if (DEBUG) Log.d(TAG, "No existing notifications for key:" + key.toString());
|
||||
return tile;
|
||||
/** Returns the total messages in {@code notificationEntries}.*/
|
||||
public static int getMessagesCount(Set<NotificationEntry> notificationEntries) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Calculating messages count from " + notificationEntries.size()
|
||||
+ " notifications.");
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Augmenting tile from visible notifications, key:" + key.toString());
|
||||
return augmentTileFromNotification(context, tile, visibleNotifications.get(key).getSbn());
|
||||
int messagesCount = 0;
|
||||
for (NotificationEntry entry : notificationEntries) {
|
||||
Notification notification = entry.getSbn().getNotification();
|
||||
// Should not count messages from missed call notifications.
|
||||
if (isMissedCall(notification)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
getMessagingStyleMessages(notification);
|
||||
if (messages != null) {
|
||||
messagesCount += messages.size();
|
||||
}
|
||||
}
|
||||
return messagesCount;
|
||||
}
|
||||
|
||||
/** Augments {@code tile} with the notification content from {@code sbn}. */
|
||||
public static PeopleSpaceTile augmentTileFromNotification(Context context, PeopleSpaceTile tile,
|
||||
StatusBarNotification sbn) {
|
||||
Notification notification = sbn.getNotification();
|
||||
if (notification == null) {
|
||||
if (DEBUG) Log.d(TAG, "Notification is null");
|
||||
return tile;
|
||||
/** Removes all notification related fields from {@code tile}. */
|
||||
public static PeopleSpaceTile removeNotificationFields(PeopleSpaceTile tile) {
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Removing any notification stored for tile Id: " + tile.getId());
|
||||
}
|
||||
boolean isMissedCall = Objects.equals(notification.category, CATEGORY_MISSED_CALL);
|
||||
return tile
|
||||
.toBuilder()
|
||||
// Reset notification content.
|
||||
.setNotificationKey(null)
|
||||
.setNotificationContent(null)
|
||||
.setNotificationDataUri(null)
|
||||
.setMessagesCount(0)
|
||||
// Reset missed calls category.
|
||||
.setNotificationCategory(null)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Augments {@code tile} with the notification content from {@code notificationEntry} and
|
||||
* {@code messagesCount}.
|
||||
*/
|
||||
public static PeopleSpaceTile augmentTileFromNotification(Context context, PeopleSpaceTile tile,
|
||||
NotificationEntry notificationEntry, int messagesCount) {
|
||||
if (notificationEntry == null || notificationEntry.getSbn().getNotification() == null) {
|
||||
if (DEBUG) Log.d(TAG, "Notification is null");
|
||||
return removeNotificationFields(tile);
|
||||
}
|
||||
Notification notification = notificationEntry.getSbn().getNotification();
|
||||
boolean isMissedCall = isMissedCall(notification);
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
getMessagingStyleMessages(notification);
|
||||
|
||||
if (!isMissedCall && ArrayUtils.isEmpty(messages)) {
|
||||
if (DEBUG) Log.d(TAG, "Notification has no content");
|
||||
return tile;
|
||||
return removeNotificationFields(tile);
|
||||
}
|
||||
|
||||
// messages are in chronological order from most recent to least.
|
||||
Notification.MessagingStyle.Message message = messages != null ? messages.get(0) : null;
|
||||
int messagesCount = messages != null ? messages.size() : 0;
|
||||
// If it's a missed call notification and it doesn't include content, use fallback value,
|
||||
// otherwise, use notification content.
|
||||
boolean hasMessageText = message != null && !TextUtils.isEmpty(message.getText());
|
||||
@@ -262,7 +272,7 @@ public class PeopleSpaceUtils {
|
||||
|
||||
return tile
|
||||
.toBuilder()
|
||||
.setNotificationKey(sbn.getKey())
|
||||
.setNotificationKey(notificationEntry.getSbn().getKey())
|
||||
.setNotificationCategory(notification.category)
|
||||
.setNotificationContent(content)
|
||||
.setNotificationDataUri(dataUri)
|
||||
@@ -270,30 +280,6 @@ public class PeopleSpaceUtils {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link Notification.MessagingStyle.Message}s from the Notification in chronological
|
||||
* order from most recent to least.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static List<Notification.MessagingStyle.Message> getMessagingStyleMessages(
|
||||
Notification notification) {
|
||||
if (notification == null) {
|
||||
return null;
|
||||
}
|
||||
if (Notification.MessagingStyle.class.equals(notification.getNotificationStyle())
|
||||
&& notification.extras != null) {
|
||||
final Parcelable[] messages = notification.extras.getParcelableArray(EXTRA_MESSAGES);
|
||||
if (!ArrayUtils.isEmpty(messages)) {
|
||||
List<Notification.MessagingStyle.Message> sortedMessages =
|
||||
Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
|
||||
sortedMessages.sort(Collections.reverseOrder(
|
||||
Comparator.comparing(Notification.MessagingStyle.Message::getTimestamp)));
|
||||
return sortedMessages;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Returns a list sorted by ascending last interaction time from {@code stream}. */
|
||||
public static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager,
|
||||
LauncherApps launcherApps, UserManager userManager,
|
||||
@@ -467,7 +453,14 @@ public class PeopleSpaceUtils {
|
||||
/** Updates the current widget view with provided {@link PeopleSpaceTile}. */
|
||||
public static void updateAppWidgetViews(AppWidgetManager appWidgetManager,
|
||||
Context context, int appWidgetId, PeopleSpaceTile tile, Bundle options) {
|
||||
if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName());
|
||||
if (tile == null) {
|
||||
if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ". Tile is null, skipping update");
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName() + ", "
|
||||
+ tile.getPackageName());
|
||||
}
|
||||
RemoteViews views = new PeopleTileViewHelper(context, tile, appWidgetId,
|
||||
options).getViews();
|
||||
|
||||
@@ -478,10 +471,24 @@ public class PeopleSpaceUtils {
|
||||
/** Updates tile in app widget options and the current view. */
|
||||
public static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
|
||||
Context context, int appWidgetId, PeopleSpaceTile tile) {
|
||||
if (tile == null) {
|
||||
Log.d(TAG, "Tile is null, skipping storage and update.");
|
||||
return;
|
||||
}
|
||||
Bundle options = AppWidgetOptionsHelper.setPeopleTile(appWidgetManager, appWidgetId, tile);
|
||||
updateAppWidgetViews(appWidgetManager, context, appWidgetId, tile, options);
|
||||
}
|
||||
|
||||
/** Wrapper around {@link #updateAppWidgetOptionsAndView} with optional tile as a parameter. */
|
||||
public static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
|
||||
Context context, int appWidgetId, Optional<PeopleSpaceTile> optionalTile) {
|
||||
if (!optionalTile.isPresent()) {
|
||||
Log.d(TAG, "Tile is null, skipping storage and update.");
|
||||
return;
|
||||
}
|
||||
updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId, optionalTile.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns lookup keys for all contacts with a birthday today.
|
||||
*
|
||||
@@ -523,42 +530,6 @@ public class PeopleSpaceUtils {
|
||||
return lookupKeysWithBirthdaysToday;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link RemoteViews} preview of a Conversation's People Tile. Returns null if one
|
||||
* is not available.
|
||||
*/
|
||||
public static RemoteViews getPreview(Context context, IPeopleManager peopleManager,
|
||||
LauncherApps launcherApps, NotificationEntryManager notificationEntryManager,
|
||||
String shortcutId, UserHandle userHandle, String packageName, Bundle options) {
|
||||
peopleManager = (peopleManager != null) ? peopleManager : IPeopleManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.PEOPLE_SERVICE));
|
||||
launcherApps = (launcherApps != null) ? launcherApps
|
||||
: context.getSystemService(LauncherApps.class);
|
||||
if (peopleManager == null || launcherApps == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ConversationChannel channel;
|
||||
try {
|
||||
channel = peopleManager.getConversation(
|
||||
packageName, userHandle.getIdentifier(), shortcutId);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Exception getting tiles: " + e);
|
||||
return null;
|
||||
}
|
||||
PeopleSpaceTile tile = PeopleSpaceUtils.getTile(channel, launcherApps);
|
||||
|
||||
if (tile == null) {
|
||||
if (DEBUG) Log.i(TAG, "No tile was returned");
|
||||
return null;
|
||||
}
|
||||
PeopleSpaceTile augmentedTile = augmentSingleTileFromVisibleNotifications(
|
||||
context, tile, notificationEntryManager);
|
||||
|
||||
if (DEBUG) Log.i(TAG, "Returning tile preview for shortcutId: " + shortcutId);
|
||||
return new PeopleTileViewHelper(context, augmentedTile, 0, options).getViews();
|
||||
}
|
||||
|
||||
/** Returns the userId associated with a {@link PeopleSpaceTile} */
|
||||
public static int getUserId(PeopleSpaceTile tile) {
|
||||
return tile.getUserHandle().getIdentifier();
|
||||
|
||||
@@ -71,7 +71,8 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class PeopleTileViewHelper {
|
||||
/** Functions that help creating the People tile layouts. */
|
||||
public class PeopleTileViewHelper {
|
||||
/** Turns on debugging information about People Space. */
|
||||
public static final boolean DEBUG = true;
|
||||
private static final String TAG = "PeopleTileView";
|
||||
@@ -115,7 +116,7 @@ class PeopleTileViewHelper {
|
||||
private Locale mLocale;
|
||||
private NumberFormat mIntegerFormat;
|
||||
|
||||
PeopleTileViewHelper(Context context, PeopleSpaceTile tile,
|
||||
public PeopleTileViewHelper(Context context, PeopleSpaceTile tile,
|
||||
int appWidgetId, Bundle options) {
|
||||
mContext = context;
|
||||
mTile = tile;
|
||||
@@ -346,6 +347,7 @@ class PeopleTileViewHelper {
|
||||
private RemoteViews createMissedCallRemoteViews() {
|
||||
RemoteViews views = getViewForContentLayout();
|
||||
views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
|
||||
views.setViewVisibility(R.id.messages_count, View.GONE);
|
||||
setMaxLines(views);
|
||||
views.setTextViewText(R.id.text_content, mTile.getNotificationContent());
|
||||
views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_phone_missed);
|
||||
@@ -546,7 +548,6 @@ class PeopleTileViewHelper {
|
||||
if (mLayoutSize == LAYOUT_SMALL) {
|
||||
views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
|
||||
views.setViewVisibility(R.id.name, View.GONE);
|
||||
views.setViewVisibility(R.id.messages_count, View.GONE);
|
||||
} else {
|
||||
views.setViewVisibility(R.id.predefined_icon, View.GONE);
|
||||
views.setViewVisibility(R.id.name, View.VISIBLE);
|
||||
@@ -561,6 +562,7 @@ class PeopleTileViewHelper {
|
||||
views.setViewPadding(R.id.item, horizontalPadding, verticalPadding, horizontalPadding,
|
||||
verticalPadding);
|
||||
}
|
||||
views.setViewVisibility(R.id.messages_count, View.GONE);
|
||||
return views;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,24 +17,25 @@
|
||||
package com.android.systemui.people.widget;
|
||||
|
||||
import static android.Manifest.permission.READ_CONTACTS;
|
||||
import static android.app.Notification.CATEGORY_MISSED_CALL;
|
||||
import static android.app.Notification.EXTRA_PEOPLE_LIST;
|
||||
|
||||
import static com.android.systemui.people.NotificationHelper.getContactUri;
|
||||
import static com.android.systemui.people.NotificationHelper.getHighestPriorityNotification;
|
||||
import static com.android.systemui.people.NotificationHelper.shouldMatchNotificationByUri;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.augmentTileFromNotification;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.getMessagingStyleMessages;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.getStoredWidgetIds;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.getMessagesCount;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.getNotificationsByUri;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.removeNotificationFields;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetViews;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.INotificationManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Person;
|
||||
@@ -67,10 +68,13 @@ import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.internal.logging.UiEventLoggerImpl;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.people.NotificationHelper;
|
||||
import com.android.systemui.people.PeopleSpaceUtils;
|
||||
import com.android.systemui.people.PeopleTileViewHelper;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -78,8 +82,10 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -272,9 +278,10 @@ public class PeopleSpaceWidgetManager {
|
||||
private void updateWidgetsWithNotificationChangedInBackground(StatusBarNotification sbn,
|
||||
PeopleSpaceUtils.NotificationAction action) {
|
||||
try {
|
||||
String sbnShortcutId = sbn.getShortcutId();
|
||||
if (sbnShortcutId == null) {
|
||||
if (DEBUG) Log.d(TAG, "Sbn shortcut id is null");
|
||||
PeopleTileKey key = new PeopleTileKey(
|
||||
sbn.getShortcutId(), sbn.getUser().getIdentifier(), sbn.getPackageName());
|
||||
if (!key.isValid()) {
|
||||
Log.d(TAG, "Invalid key from sbn");
|
||||
return;
|
||||
}
|
||||
int[] widgetIds = mAppWidgetManager.getAppWidgetIds(
|
||||
@@ -284,21 +291,15 @@ public class PeopleSpaceWidgetManager {
|
||||
Log.d(TAG, "No app widget ids returned");
|
||||
return;
|
||||
}
|
||||
PeopleTileKey key = new PeopleTileKey(
|
||||
sbnShortcutId,
|
||||
sbn.getUser().getIdentifier(),
|
||||
sbn.getPackageName());
|
||||
if (!key.isValid()) {
|
||||
Log.d(TAG, "Invalid key");
|
||||
return;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
// First, update People Tiles associated with the Notification's package/shortcut.
|
||||
Set<String> tilesUpdatedByKey = getStoredWidgetIds(mSharedPrefs, key);
|
||||
updateWidgetIdsForNotificationAction(tilesUpdatedByKey, sbn, action);
|
||||
|
||||
// Then, update People Tiles across other packages that use the same Uri.
|
||||
updateTilesByUri(key, sbn, action);
|
||||
Set<String> tilesUpdated = getMatchingKeyWidgetIds(key);
|
||||
Set<String> tilesUpdatedByUri = getMatchingUriWidgetIds(sbn, action);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Widgets by key to be updated:" + tilesUpdated.toString());
|
||||
Log.d(TAG, "Widgets by URI to be updated:" + tilesUpdatedByUri.toString());
|
||||
}
|
||||
tilesUpdated.addAll(tilesUpdatedByUri);
|
||||
updateWidgetIdsBasedOnNotifications(tilesUpdated);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Throwing exception: " + e);
|
||||
@@ -306,36 +307,142 @@ public class PeopleSpaceWidgetManager {
|
||||
}
|
||||
|
||||
/** Updates {@code widgetIdsToUpdate} with {@code action}. */
|
||||
private void updateWidgetIdsForNotificationAction(Set<String> widgetIdsToUpdate,
|
||||
StatusBarNotification sbn, PeopleSpaceUtils.NotificationAction action) {
|
||||
for (String widgetIdString : widgetIdsToUpdate) {
|
||||
int widgetId = Integer.parseInt(widgetIdString);
|
||||
PeopleSpaceTile storedTile = getTileForExistingWidget(widgetId);
|
||||
if (storedTile == null) {
|
||||
if (DEBUG) Log.d(TAG, "Could not find stored tile for notification");
|
||||
continue;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
|
||||
updateStorageAndViewWithNotificationData(sbn, action, widgetId,
|
||||
storedTile);
|
||||
private void updateWidgetIdsBasedOnNotifications(Set<String> widgetIdsToUpdate) {
|
||||
Log.d(TAG, "Fetching grouped notifications");
|
||||
try {
|
||||
Map<PeopleTileKey, Set<NotificationEntry>> groupedNotifications =
|
||||
getGroupedConversationNotifications();
|
||||
|
||||
widgetIdsToUpdate
|
||||
.stream()
|
||||
.map(Integer::parseInt)
|
||||
.collect(Collectors.toMap(
|
||||
Function.identity(),
|
||||
id -> getAugmentedTileForExistingWidget(id, groupedNotifications)))
|
||||
.forEach((id, tile) ->
|
||||
updateAppWidgetOptionsAndView(mAppWidgetManager, mContext, id, tile));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception updating widgets: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates tiles with matched Uris, dependent on the {@code action}.
|
||||
* Augments {@code tile} based on notifications returned from {@code notificationEntryManager}.
|
||||
*/
|
||||
public PeopleSpaceTile augmentTileFromNotificationEntryManager(PeopleSpaceTile tile) {
|
||||
Log.d(TAG, "Augmenting tile from NotificationEntryManager widget: " + tile.getId());
|
||||
Map<PeopleTileKey, Set<NotificationEntry>> notifications =
|
||||
getGroupedConversationNotifications();
|
||||
String contactUri = null;
|
||||
if (tile.getContactUri() != null) {
|
||||
contactUri = tile.getContactUri().toString();
|
||||
}
|
||||
return augmentTileFromNotifications(tile, contactUri, notifications);
|
||||
}
|
||||
|
||||
/** Returns active and pending notifications grouped by {@link PeopleTileKey}. */
|
||||
public Map<PeopleTileKey, Set<NotificationEntry>> getGroupedConversationNotifications() {
|
||||
List<NotificationEntry> notifications =
|
||||
new ArrayList<>(mNotificationEntryManager.getVisibleNotifications());
|
||||
Iterable<NotificationEntry> pendingNotifications =
|
||||
mNotificationEntryManager.getPendingNotificationsIterator();
|
||||
for (NotificationEntry entry : pendingNotifications) {
|
||||
notifications.add(entry);
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Number of total notifications: " + notifications.size());
|
||||
Map<PeopleTileKey, Set<NotificationEntry>> groupedNotifications =
|
||||
notifications
|
||||
.stream()
|
||||
.filter(entry -> NotificationHelper.isValid(entry)
|
||||
&& NotificationHelper.isMissedCallOrHasContent(entry))
|
||||
.collect(Collectors.groupingBy(
|
||||
PeopleTileKey::new,
|
||||
Collectors.mapping(Function.identity(), Collectors.toSet())));
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Number of grouped conversation notifications keys: "
|
||||
+ groupedNotifications.keySet().size());
|
||||
}
|
||||
return groupedNotifications;
|
||||
}
|
||||
|
||||
/** Augments {@code tile} based on {@code notifications}, matching {@code contactUri}. */
|
||||
public PeopleSpaceTile augmentTileFromNotifications(PeopleSpaceTile tile, String contactUri,
|
||||
Map<PeopleTileKey, Set<NotificationEntry>> notifications) {
|
||||
if (DEBUG) Log.d(TAG, "Augmenting tile from notifications. Tile id: " + tile.getId());
|
||||
boolean hasReadContactsPermission = mPackageManager.checkPermission(READ_CONTACTS,
|
||||
tile.getPackageName()) == PackageManager.PERMISSION_GRANTED;
|
||||
|
||||
List<NotificationEntry> notificationsByUri = new ArrayList<>();
|
||||
if (hasReadContactsPermission) {
|
||||
notificationsByUri = getNotificationsByUri(mPackageManager, contactUri, notifications);
|
||||
if (!notificationsByUri.isEmpty()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Number of notifications matched by contact URI: "
|
||||
+ notificationsByUri.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PeopleTileKey key = new PeopleTileKey(tile);
|
||||
Set<NotificationEntry> allNotifications = notifications.get(key);
|
||||
if (allNotifications == null) {
|
||||
allNotifications = new HashSet<>();
|
||||
}
|
||||
if (allNotifications.isEmpty() && notificationsByUri.isEmpty()) {
|
||||
if (DEBUG) Log.d(TAG, "No existing notifications for tile: " + key);
|
||||
return removeNotificationFields(tile);
|
||||
}
|
||||
|
||||
// Merge notifications matched by key and by contact URI.
|
||||
allNotifications.addAll(notificationsByUri);
|
||||
if (DEBUG) Log.d(TAG, "Total notifications matching tile: " + allNotifications.size());
|
||||
|
||||
int messagesCount = getMessagesCount(allNotifications);
|
||||
NotificationEntry highestPriority = getHighestPriorityNotification(allNotifications);
|
||||
|
||||
if (DEBUG) Log.d(TAG, "Augmenting tile from notification, key: " + key.toString());
|
||||
return augmentTileFromNotification(mContext, tile, highestPriority, messagesCount);
|
||||
}
|
||||
|
||||
/** Returns an augmented tile for an existing widget. */
|
||||
@Nullable
|
||||
public Optional<PeopleSpaceTile> getAugmentedTileForExistingWidget(int widgetId,
|
||||
Map<PeopleTileKey, Set<NotificationEntry>> notifications) {
|
||||
Log.d(TAG, "Augmenting tile for widget: " + widgetId);
|
||||
PeopleSpaceTile tile = getTileForExistingWidget(widgetId);
|
||||
if (tile == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
String contactUriString = mSharedPrefs.getString(String.valueOf(widgetId), null);
|
||||
// Should never be null, but using ofNullable for extra safety.
|
||||
return Optional.ofNullable(
|
||||
augmentTileFromNotifications(tile, contactUriString, notifications));
|
||||
}
|
||||
|
||||
/** Returns stored widgets for the conversation specified. */
|
||||
public Set<String> getMatchingKeyWidgetIds(PeopleTileKey key) {
|
||||
if (!key.isValid()) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return new HashSet<>(mSharedPrefs.getStringSet(key.toString(), new HashSet<>()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates in-memory map of tiles with matched Uris, dependent on the {@code action}.
|
||||
*
|
||||
* <p>If the notification was added, adds the notification based on the contact Uri within
|
||||
* {@code sbn}.
|
||||
* <p>If the notification was removed, removes the notification based on the in-memory map of
|
||||
* widgets previously updated by Uri (since the contact Uri is stripped from the {@code sbn}).
|
||||
*/
|
||||
private void updateTilesByUri(PeopleTileKey key, StatusBarNotification sbn,
|
||||
@Nullable
|
||||
private Set<String> getMatchingUriWidgetIds(StatusBarNotification sbn,
|
||||
PeopleSpaceUtils.NotificationAction action) {
|
||||
if (action.equals(PeopleSpaceUtils.NotificationAction.POSTED)) {
|
||||
Set<String> widgetIdsUpdatedByUri = supplementTilesByUri(sbn, action, key);
|
||||
Set<String> widgetIdsUpdatedByUri = fetchMatchingUriWidgetIds(sbn);
|
||||
if (widgetIdsUpdatedByUri != null && !widgetIdsUpdatedByUri.isEmpty()) {
|
||||
if (DEBUG) Log.d(TAG, "Added due to uri: " + widgetIdsUpdatedByUri);
|
||||
mNotificationKeyToWidgetIdsMatchedByUri.put(sbn.getKey(), widgetIdsUpdatedByUri);
|
||||
return widgetIdsUpdatedByUri;
|
||||
}
|
||||
} else {
|
||||
// Remove the notification on any widgets where the notification was added
|
||||
@@ -343,21 +450,16 @@ public class PeopleSpaceWidgetManager {
|
||||
Set<String> widgetsPreviouslyUpdatedByUri =
|
||||
mNotificationKeyToWidgetIdsMatchedByUri.remove(sbn.getKey());
|
||||
if (widgetsPreviouslyUpdatedByUri != null && !widgetsPreviouslyUpdatedByUri.isEmpty()) {
|
||||
if (DEBUG) Log.d(TAG, "Remove due to uri: " + widgetsPreviouslyUpdatedByUri);
|
||||
updateWidgetIdsForNotificationAction(widgetsPreviouslyUpdatedByUri, sbn,
|
||||
action);
|
||||
return widgetsPreviouslyUpdatedByUri;
|
||||
}
|
||||
}
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves from storage any tiles with the same contact Uri as linked via the {@code sbn}.
|
||||
* Supplements the tiles with the notification content only if they still have {@link
|
||||
* android.Manifest.permission.READ_CONTACTS} permission.
|
||||
*/
|
||||
/** Fetches widget Ids that match the contact URI in {@code sbn}. */
|
||||
@Nullable
|
||||
private Set<String> supplementTilesByUri(StatusBarNotification sbn,
|
||||
PeopleSpaceUtils.NotificationAction notificationAction, PeopleTileKey key) {
|
||||
private Set<String> fetchMatchingUriWidgetIds(StatusBarNotification sbn) {
|
||||
// Check if it's a missed call notification
|
||||
if (!shouldMatchNotificationByUri(sbn)) {
|
||||
if (DEBUG) Log.d(TAG, "Should not supplement conversation");
|
||||
return null;
|
||||
@@ -377,80 +479,7 @@ public class PeopleSpaceWidgetManager {
|
||||
if (DEBUG) Log.d(TAG, "No tiles for contact");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mPackageManager.checkPermission(READ_CONTACTS,
|
||||
sbn.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (DEBUG) Log.d(TAG, "Notifying app missing permissions");
|
||||
return null;
|
||||
}
|
||||
|
||||
Set<String> widgetIdsUpdatedByUri = new HashSet<>();
|
||||
for (String widgetIdString : storedWidgetIdsByUri) {
|
||||
int widgetId = Integer.parseInt(widgetIdString);
|
||||
PeopleSpaceTile storedTile = getTileForExistingWidget(widgetId);
|
||||
// Don't update a widget already updated.
|
||||
if (key.equals(new PeopleTileKey(storedTile))) {
|
||||
continue;
|
||||
}
|
||||
if (storedTile == null || mPackageManager.checkPermission(READ_CONTACTS,
|
||||
storedTile.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (DEBUG) Log.d(TAG, "Cannot supplement tile: " + storedTile.getUserName());
|
||||
continue;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Adding notification by uri: " + sbn.getKey());
|
||||
updateStorageAndViewWithNotificationData(sbn, notificationAction,
|
||||
widgetId, storedTile);
|
||||
widgetIdsUpdatedByUri.add(String.valueOf(widgetId));
|
||||
}
|
||||
return widgetIdsUpdatedByUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to retrieve a valid Uri via {@code sbn}, falling back to the {@code
|
||||
* contactUriFromShortcut} if valid.
|
||||
*/
|
||||
@Nullable
|
||||
private String getContactUri(StatusBarNotification sbn) {
|
||||
// First, try to get a Uri from the Person directly set on the Notification.
|
||||
ArrayList<Person> people = sbn.getNotification().extras.getParcelableArrayList(
|
||||
EXTRA_PEOPLE_LIST);
|
||||
if (people != null && people.get(0) != null) {
|
||||
String contactUri = people.get(0).getUri();
|
||||
if (contactUri != null && !contactUri.isEmpty()) {
|
||||
return contactUri;
|
||||
}
|
||||
}
|
||||
|
||||
// Then, try to get a Uri from the Person set on the Notification message.
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
getMessagingStyleMessages(sbn.getNotification());
|
||||
if (messages != null && !messages.isEmpty()) {
|
||||
Notification.MessagingStyle.Message message = messages.get(0);
|
||||
Person sender = message.getSenderPerson();
|
||||
if (sender != null && sender.getUri() != null && !sender.getUri().isEmpty()) {
|
||||
return sender.getUri();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a notification should be matched to other Tiles by Uri.
|
||||
*
|
||||
* <p>Currently only matches missed calls.
|
||||
*/
|
||||
private boolean shouldMatchNotificationByUri(StatusBarNotification sbn) {
|
||||
Notification notification = sbn.getNotification();
|
||||
if (notification == null) {
|
||||
if (DEBUG) Log.d(TAG, "Notification is null");
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(notification.category, CATEGORY_MISSED_CALL)) {
|
||||
if (DEBUG) Log.d(TAG, "Not missed call");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return storedWidgetIdsByUri;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -461,7 +490,7 @@ public class PeopleSpaceWidgetManager {
|
||||
synchronized (mLock) {
|
||||
PeopleTileKey key = new PeopleTileKey(
|
||||
info.getId(), info.getUserId(), info.getPackage());
|
||||
Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, key);
|
||||
Set<String> storedWidgetIds = getMatchingKeyWidgetIds(key);
|
||||
for (String widgetIdString : storedWidgetIds) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
@@ -469,7 +498,7 @@ public class PeopleSpaceWidgetManager {
|
||||
+ info.getLabel());
|
||||
}
|
||||
updateStorageAndViewWithConversationData(conversation,
|
||||
Integer.valueOf(widgetIdString));
|
||||
Integer.parseInt(widgetIdString));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -504,34 +533,6 @@ public class PeopleSpaceWidgetManager {
|
||||
updateAppWidgetOptionsAndView(mAppWidgetManager, mContext, appWidgetId, storedTile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update {@code appWidgetId} with the new data provided by {@code sbn}.
|
||||
*/
|
||||
private void updateStorageAndViewWithNotificationData(
|
||||
StatusBarNotification sbn,
|
||||
PeopleSpaceUtils.NotificationAction notificationAction,
|
||||
int appWidgetId, PeopleSpaceTile storedTile) {
|
||||
if (notificationAction == PeopleSpaceUtils.NotificationAction.POSTED) {
|
||||
if (DEBUG) Log.i(TAG, "Adding notification to storage, appWidgetId: " + appWidgetId);
|
||||
storedTile = augmentTileFromNotification(mContext, storedTile, sbn);
|
||||
} else if (Objects.equals(storedTile.getNotificationKey(), sbn.getKey())) {
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Removing notification from storage, appWidgetId: " + appWidgetId);
|
||||
}
|
||||
storedTile = storedTile
|
||||
.toBuilder()
|
||||
// Reset notification content.
|
||||
.setNotificationKey(null)
|
||||
.setNotificationContent(null)
|
||||
.setNotificationDataUri(null)
|
||||
.setMessagesCount(0)
|
||||
// Reset missed calls category.
|
||||
.setNotificationCategory(null)
|
||||
.build();
|
||||
}
|
||||
updateAppWidgetOptionsAndView(mAppWidgetManager, mContext, appWidgetId, storedTile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the manager to the pipeline, making it ready to receive events. Should only be
|
||||
* called once.
|
||||
@@ -615,22 +616,10 @@ public class PeopleSpaceWidgetManager {
|
||||
public void addNewWidget(int appWidgetId, PeopleTileKey key) {
|
||||
if (DEBUG) Log.d(TAG, "addNewWidget called with key for appWidgetId: " + appWidgetId);
|
||||
PeopleSpaceTile tile = getTileFromPersistentStorage(key);
|
||||
tile = PeopleSpaceUtils.augmentSingleTileFromVisibleNotifications(
|
||||
mContext, tile, mNotificationEntryManager);
|
||||
if (tile != null) {
|
||||
addNewWidget(appWidgetId, tile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a widget based on {@code tile} mapped to {@code appWidgetId}.
|
||||
* The tile provided should already be augmented.
|
||||
*/
|
||||
public void addNewWidget(int appWidgetId, PeopleSpaceTile tile) {
|
||||
if (DEBUG) Log.d(TAG, "addNewWidget called for appWidgetId: " + appWidgetId);
|
||||
if (tile == null) {
|
||||
return;
|
||||
}
|
||||
tile = augmentTileFromNotificationEntryManager(tile);
|
||||
|
||||
PeopleTileKey existingKeyIfStored;
|
||||
synchronized (mLock) {
|
||||
@@ -648,7 +637,6 @@ public class PeopleSpaceWidgetManager {
|
||||
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getId());
|
||||
PeopleTileKey key = new PeopleTileKey(tile);
|
||||
PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId,
|
||||
tile.getContactUri());
|
||||
}
|
||||
@@ -780,8 +768,7 @@ public class PeopleSpaceWidgetManager {
|
||||
public boolean requestPinAppWidget(ShortcutInfo shortcutInfo, Bundle options) {
|
||||
if (DEBUG) Log.d(TAG, "Requesting pin widget, shortcutId: " + shortcutInfo.getId());
|
||||
|
||||
RemoteViews widgetPreview = PeopleSpaceUtils.getPreview(mContext, mIPeopleManager,
|
||||
mLauncherApps, mNotificationEntryManager, shortcutInfo.getId(),
|
||||
RemoteViews widgetPreview = getPreview(shortcutInfo.getId(),
|
||||
shortcutInfo.getUserHandle(), shortcutInfo.getPackage(), options);
|
||||
if (widgetPreview == null) {
|
||||
Log.w(TAG, "Skipping pinning widget: no tile for shortcutId: " + shortcutInfo.getId());
|
||||
@@ -811,8 +798,6 @@ public class PeopleSpaceWidgetManager {
|
||||
List<PeopleSpaceTile> priorityTiles = PeopleSpaceUtils.getSortedTiles(mIPeopleManager,
|
||||
mLauncherApps, mUserManager,
|
||||
priorityConversations);
|
||||
priorityTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications(
|
||||
mContext, priorityTiles, mNotificationEntryManager);
|
||||
return priorityTiles;
|
||||
}
|
||||
|
||||
@@ -839,9 +824,33 @@ public class PeopleSpaceWidgetManager {
|
||||
List<PeopleSpaceTile> recentTiles =
|
||||
PeopleSpaceUtils.getSortedTiles(mIPeopleManager, mLauncherApps, mUserManager,
|
||||
mergedStream);
|
||||
|
||||
recentTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications(
|
||||
mContext, recentTiles, mNotificationEntryManager);
|
||||
return recentTiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link RemoteViews} preview of a Conversation's People Tile. Returns null if one
|
||||
* is not available.
|
||||
*/
|
||||
public RemoteViews getPreview(String shortcutId, UserHandle userHandle, String packageName,
|
||||
Bundle options) {
|
||||
PeopleSpaceTile tile;
|
||||
ConversationChannel channel;
|
||||
try {
|
||||
channel = mIPeopleManager.getConversation(
|
||||
packageName, userHandle.getIdentifier(), shortcutId);
|
||||
tile = PeopleSpaceUtils.getTile(channel, mLauncherApps);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Exception getting tiles: " + e);
|
||||
return null;
|
||||
}
|
||||
if (tile == null) {
|
||||
if (DEBUG) Log.i(TAG, "No tile was returned");
|
||||
return null;
|
||||
}
|
||||
|
||||
PeopleSpaceTile augmentedTile = augmentTileFromNotificationEntryManager(tile);
|
||||
|
||||
if (DEBUG) Log.i(TAG, "Returning tile preview for shortcutId: " + shortcutId);
|
||||
return new PeopleTileViewHelper(mContext, augmentedTile, 0, options).getViews();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.systemui.people;
|
||||
|
||||
import static android.app.Notification.CATEGORY_MISSED_CALL;
|
||||
|
||||
import static com.android.systemui.people.NotificationHelper.getHighestPriorityNotification;
|
||||
import static com.android.systemui.people.NotificationHelper.getMessagingStyleMessages;
|
||||
import static com.android.systemui.people.NotificationHelper.isMissedCall;
|
||||
import static com.android.systemui.people.NotificationHelper.isMissedCallOrHasContent;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.Person;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.SbnBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@SmallTest
|
||||
public class NotificationHelperTest extends SysuiTestCase {
|
||||
private static final String SHORTCUT_ID_1 = "101";
|
||||
private static final String SHORTCUT_ID_2 = "102";
|
||||
|
||||
private static final String NOTIFICATION_TEXT_1 = "notification_text_1";
|
||||
private static final String NOTIFICATION_TEXT_2 = "notification_text_2";
|
||||
private static final String NOTIFICATION_TEXT_3 = "notification_text_3";
|
||||
private static final Uri URI = Uri.parse("fake_uri");
|
||||
private static final Person PERSON = new Person.Builder()
|
||||
.setName("name")
|
||||
.setKey("abc")
|
||||
.setUri(URI.toString())
|
||||
.setBot(false)
|
||||
.build();
|
||||
|
||||
private final Notification mNotification1 = new Notification.Builder(mContext, "test")
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(SHORTCUT_ID_1)
|
||||
.setStyle(new Notification.MessagingStyle(PERSON)
|
||||
.addMessage(new Notification.MessagingStyle.Message(
|
||||
NOTIFICATION_TEXT_1, 0, PERSON))
|
||||
.addMessage(new Notification.MessagingStyle.Message(
|
||||
NOTIFICATION_TEXT_2, 20, PERSON))
|
||||
.addMessage(new Notification.MessagingStyle.Message(
|
||||
NOTIFICATION_TEXT_3, 10, PERSON))
|
||||
)
|
||||
.build();
|
||||
|
||||
private final Notification mNotification2 = new Notification.Builder(mContext, "test")
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(SHORTCUT_ID_1)
|
||||
.setStyle(new Notification.MessagingStyle(PERSON)
|
||||
.addMessage(new Notification.MessagingStyle.Message(
|
||||
NOTIFICATION_TEXT_1, 0, PERSON))
|
||||
)
|
||||
.build();
|
||||
|
||||
private final Notification mNoContentNotification = new Notification.Builder(mContext, "test")
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(SHORTCUT_ID_1)
|
||||
.setStyle(new Notification.MessagingStyle(PERSON))
|
||||
.build();
|
||||
|
||||
private final Notification mMissedCallNotification = new Notification.Builder(mContext, "test")
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(SHORTCUT_ID_2)
|
||||
.setCategory(CATEGORY_MISSED_CALL)
|
||||
.setStyle(new Notification.MessagingStyle(PERSON))
|
||||
.build();
|
||||
|
||||
private final NotificationEntry mNotificationEntry1 = new NotificationEntryBuilder()
|
||||
.setNotification(mNotification1)
|
||||
.setShortcutInfo(new ShortcutInfo.Builder(mContext, SHORTCUT_ID_1).build())
|
||||
.setUser(UserHandle.of(0))
|
||||
.setPkg(PACKAGE_NAME)
|
||||
.build();
|
||||
|
||||
private final NotificationEntry mNotificationEntry2 = new NotificationEntryBuilder()
|
||||
.setNotification(mNotification2)
|
||||
.setShortcutInfo(new ShortcutInfo.Builder(mContext, SHORTCUT_ID_1).build())
|
||||
.setUser(UserHandle.of(0))
|
||||
.setPkg(PACKAGE_NAME)
|
||||
.build();
|
||||
|
||||
|
||||
private final NotificationEntry mMissedCallNotificationEntry = new NotificationEntryBuilder()
|
||||
.setNotification(mMissedCallNotification)
|
||||
.setShortcutInfo(new ShortcutInfo.Builder(mContext, SHORTCUT_ID_1).build())
|
||||
.setUser(UserHandle.of(0))
|
||||
.setPkg(PACKAGE_NAME)
|
||||
.build();
|
||||
|
||||
private final NotificationEntry mNoContentNotificationEntry = new NotificationEntryBuilder()
|
||||
.setNotification(mNoContentNotification)
|
||||
.setShortcutInfo(new ShortcutInfo.Builder(mContext, SHORTCUT_ID_1).build())
|
||||
.setUser(UserHandle.of(0))
|
||||
.setPkg(PACKAGE_NAME)
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void testGetMessagingStyleMessagesNoMessage() {
|
||||
Notification notification = new Notification.Builder(mContext, "test")
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(SHORTCUT_ID_1)
|
||||
.build();
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(notification)
|
||||
.build();
|
||||
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
getMessagingStyleMessages(sbn.getNotification());
|
||||
|
||||
assertThat(ArrayUtils.isEmpty(messages)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMessagingStyleMessages() {
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(mNotification1)
|
||||
.build();
|
||||
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
getMessagingStyleMessages(sbn.getNotification());
|
||||
|
||||
assertThat(messages.size()).isEqualTo(3);
|
||||
assertThat(messages.get(0).getText().toString()).isEqualTo(NOTIFICATION_TEXT_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsMissedCall_notMissedCall() {
|
||||
assertFalse(isMissedCall(mNotificationEntry1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsMissedCall_missedCall() {
|
||||
assertTrue(isMissedCall(mMissedCallNotificationEntry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testisMissedCallOrHasContent_NoContent() {
|
||||
assertFalse(isMissedCallOrHasContent(mNoContentNotificationEntry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testisMissedCallOrHasContent_Hasontent() {
|
||||
assertTrue(isMissedCallOrHasContent(mNotificationEntry1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHighestPriorityNotification_missedCallHigherPriority() {
|
||||
Set<NotificationEntry> notifications = Set.of(
|
||||
mNotificationEntry1, mMissedCallNotificationEntry);
|
||||
|
||||
assertThat(getHighestPriorityNotification(notifications))
|
||||
.isEqualTo(mMissedCallNotificationEntry);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHighestPriorityNotification_moreRecentLastMessage() {
|
||||
Set<NotificationEntry> notifications = Set.of(
|
||||
mNotificationEntry1, mNotificationEntry2);
|
||||
|
||||
assertThat(getHighestPriorityNotification(notifications))
|
||||
.isEqualTo(mNotificationEntry1);
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,11 @@ package com.android.systemui.people;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.people.ConversationChannel;
|
||||
import android.app.people.IPeopleManager;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.net.Uri;
|
||||
@@ -36,8 +35,8 @@ import android.widget.RemoteViews;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
|
||||
import com.android.systemui.shared.system.PeopleProviderUtils;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
@@ -68,14 +67,12 @@ public class PeopleProviderTest extends SysuiTestCase {
|
||||
|
||||
private Bundle mExtras = new Bundle();
|
||||
|
||||
@Mock
|
||||
private LauncherApps mLauncherApps;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private IPeopleManager mPeopleManager;
|
||||
private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
|
||||
@Mock
|
||||
private NotificationEntryManager mNotificationEntryManager;
|
||||
private RemoteViews mRemoteViews;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -85,9 +82,7 @@ public class PeopleProviderTest extends SysuiTestCase {
|
||||
PeopleProviderTestable provider = new PeopleProviderTestable();
|
||||
provider.initializeForTesting(
|
||||
mContext, PeopleProviderUtils.PEOPLE_PROVIDER_AUTHORITY);
|
||||
provider.setLauncherApps(mLauncherApps);
|
||||
provider.setPeopleManager(mPeopleManager);
|
||||
provider.setNotificationEntryManager(mNotificationEntryManager);
|
||||
provider.setPeopleSpaceWidgetManager(mPeopleSpaceWidgetManager);
|
||||
mContext.getContentResolver().addProvider(
|
||||
PeopleProviderUtils.PEOPLE_PROVIDER_AUTHORITY, provider);
|
||||
|
||||
@@ -95,9 +90,9 @@ public class PeopleProviderTest extends SysuiTestCase {
|
||||
PeopleProviderUtils.GET_PEOPLE_TILE_PREVIEW_PERMISSION,
|
||||
PackageManager.PERMISSION_GRANTED);
|
||||
|
||||
when(mPeopleManager.getConversation(
|
||||
eq(PACKAGE_NAME_A), eq(USER_HANDLE_A.getIdentifier()), eq(SHORTCUT_ID_A)))
|
||||
.thenReturn(mConversationChannel);
|
||||
when(mPeopleSpaceWidgetManager.getPreview(
|
||||
eq(SHORTCUT_ID_A), eq(USER_HANDLE_A), eq(PACKAGE_NAME_A), any()))
|
||||
.thenReturn(mRemoteViews);
|
||||
|
||||
mExtras.putString(PeopleProviderUtils.EXTRAS_KEY_SHORTCUT_ID, SHORTCUT_ID_A);
|
||||
mExtras.putString(PeopleProviderUtils.EXTRAS_KEY_PACKAGE_NAME, PACKAGE_NAME_A);
|
||||
@@ -146,8 +141,8 @@ public class PeopleProviderTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testPermissionGrantedNoConversationForShortcutReturnsNull() throws RemoteException {
|
||||
when(mPeopleManager.getConversation(
|
||||
eq(PACKAGE_NAME_A), eq(USER_HANDLE_A.getIdentifier()), eq(SHORTCUT_ID_A)))
|
||||
when(mPeopleSpaceWidgetManager.getPreview(
|
||||
eq(SHORTCUT_ID_A), eq(USER_HANDLE_A), eq(PACKAGE_NAME_A), any()))
|
||||
.thenReturn(null);
|
||||
try {
|
||||
Bundle result = mContext.getContentResolver().call(
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
|
||||
package com.android.systemui.people;
|
||||
|
||||
import android.app.people.IPeopleManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.ProviderInfo;
|
||||
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
|
||||
|
||||
public class PeopleProviderTestable extends PeopleProvider {
|
||||
|
||||
@@ -32,15 +30,7 @@ public class PeopleProviderTestable extends PeopleProvider {
|
||||
attachInfoForTesting(context, info);
|
||||
}
|
||||
|
||||
void setLauncherApps(LauncherApps launcherApps) {
|
||||
mLauncherApps = launcherApps;
|
||||
}
|
||||
|
||||
void setPeopleManager(IPeopleManager peopleManager) {
|
||||
mPeopleManager = peopleManager;
|
||||
}
|
||||
|
||||
void setNotificationEntryManager(NotificationEntryManager notificationEntryManager) {
|
||||
mNotificationEntryManager = notificationEntryManager;
|
||||
void setPeopleSpaceWidgetManager(PeopleSpaceWidgetManager peopleSpaceWidgetManager) {
|
||||
mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,19 +51,15 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.appwidget.IAppWidgetService;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.people.widget.PeopleTileKey;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.SbnBuilder;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
@@ -227,42 +223,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
.thenReturn(List.of(mNotificationEntry1, mNotificationEntry2, mNotificationEntry3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMessagingStyleMessagesNoMessage() {
|
||||
Notification notification = new Notification.Builder(mContext, "test")
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(SHORTCUT_ID_1)
|
||||
.build();
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(notification)
|
||||
.build();
|
||||
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
PeopleSpaceUtils.getMessagingStyleMessages(sbn.getNotification());
|
||||
|
||||
assertThat(ArrayUtils.isEmpty(messages)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMessagingStyleMessages() {
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(mNotification1)
|
||||
.build();
|
||||
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
PeopleSpaceUtils.getMessagingStyleMessages(sbn.getNotification());
|
||||
|
||||
assertThat(messages.size()).isEqualTo(3);
|
||||
assertThat(messages.get(0).getText().toString()).isEqualTo(NOTIFICATION_TEXT_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromNotification() {
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(mNotification1)
|
||||
.build();
|
||||
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID_1, "userName", ICON, new Intent())
|
||||
@@ -270,17 +232,13 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
PeopleSpaceTile actual = PeopleSpaceUtils
|
||||
.augmentTileFromNotification(mContext, tile, sbn);
|
||||
.augmentTileFromNotification(mContext, tile, mNotificationEntry1, 0);
|
||||
|
||||
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromNotificationNoContent() {
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(mNotification3)
|
||||
.build();
|
||||
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID_3, "userName", ICON, new Intent())
|
||||
@@ -288,106 +246,11 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
PeopleSpaceTile actual = PeopleSpaceUtils
|
||||
.augmentTileFromNotification(mContext, tile, sbn);
|
||||
.augmentTileFromNotification(mContext, tile, mNotificationEntry3, 0);
|
||||
|
||||
assertThat(actual.getNotificationContent()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromVisibleNotifications() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID_1, "userName", ICON, new Intent())
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
PeopleSpaceTile actual = PeopleSpaceUtils
|
||||
.augmentTileFromVisibleNotifications(mContext, tile,
|
||||
Map.of(new PeopleTileKey(mNotificationEntry1), mNotificationEntry1));
|
||||
|
||||
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromVisibleNotificationsDifferentShortcutId() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID_4, "userName", ICON, new Intent())
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
PeopleSpaceTile actual = PeopleSpaceUtils
|
||||
.augmentTileFromVisibleNotifications(mContext, tile,
|
||||
Map.of(new PeopleTileKey(mNotificationEntry1), mNotificationEntry1));
|
||||
|
||||
assertThat(actual.getNotificationContent()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTilesFromVisibleNotificationsSingleTile() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID_1, "userName", ICON, new Intent())
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
List<PeopleSpaceTile> actualList = PeopleSpaceUtils
|
||||
.augmentTilesFromVisibleNotifications(
|
||||
mContext, List.of(tile), mNotificationEntryManager);
|
||||
|
||||
assertThat(actualList.size()).isEqualTo(1);
|
||||
assertThat(actualList.get(0).getNotificationContent().toString())
|
||||
.isEqualTo(NOTIFICATION_TEXT_2);
|
||||
|
||||
verify(mNotificationEntryManager, times(1)).getVisibleNotifications();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTilesFromVisibleNotificationsMultipleTiles() {
|
||||
PeopleSpaceTile tile1 =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID_1, "userName", ICON, new Intent())
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
PeopleSpaceTile tile2 =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID_2, "userName2", ICON, new Intent())
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
List<PeopleSpaceTile> actualList = PeopleSpaceUtils
|
||||
.augmentTilesFromVisibleNotifications(mContext, List.of(tile1, tile2),
|
||||
mNotificationEntryManager);
|
||||
|
||||
assertThat(actualList.size()).isEqualTo(2);
|
||||
assertThat(actualList.get(0).getNotificationContent().toString())
|
||||
.isEqualTo(NOTIFICATION_TEXT_2);
|
||||
assertThat(actualList.get(1).getNotificationContent().toString())
|
||||
.isEqualTo(NOTIFICATION_TEXT_4);
|
||||
|
||||
verify(mNotificationEntryManager, times(1)).getVisibleNotifications();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentSingleTileFromVisibleNotificationsSingleTile() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID_1, "userName", ICON, new Intent())
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
PeopleSpaceTile augmentedTile = PeopleSpaceUtils
|
||||
.augmentSingleTileFromVisibleNotifications(
|
||||
mContext, tile, mNotificationEntryManager);
|
||||
|
||||
assertThat(augmentedTile).isNotNull();
|
||||
assertThat(augmentedTile.getNotificationContent().toString())
|
||||
.isEqualTo(NOTIFICATION_TEXT_2);
|
||||
|
||||
verify(mNotificationEntryManager, times(1)).getVisibleNotifications();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNotUpdateSingleConversationAppWidgetWhenNotBirthday() {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT};
|
||||
|
||||
@@ -68,6 +68,7 @@ import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
@@ -86,6 +87,7 @@ import com.android.systemui.statusbar.SbnBuilder;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NoManSimulator;
|
||||
import com.android.systemui.statusbar.notification.collection.NoManSimulator.NotifEvent;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
@@ -99,8 +101,10 @@ import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -124,7 +128,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
private static final String SHORTCUT_ID = "101";
|
||||
private static final String OTHER_SHORTCUT_ID = "102";
|
||||
private static final String NOTIFICATION_KEY = "0|com.android.systemui.tests|0|null|0";
|
||||
private static final String NOTIFICATION_CONTENT = "message text";
|
||||
private static final String NOTIFICATION_CONTENT_1 = "message text 1";
|
||||
private static final Uri URI = Uri.parse("fake_uri");
|
||||
private static final Icon ICON = Icon.createWithResource("package", R.drawable.ic_android);
|
||||
private static final PeopleTileKey KEY = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
|
||||
@@ -140,7 +144,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.setPackageName(TEST_PACKAGE_A)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.setNotificationKey(NOTIFICATION_KEY + "1")
|
||||
.setNotificationContent(NOTIFICATION_CONTENT)
|
||||
.setNotificationContent(NOTIFICATION_CONTENT_1)
|
||||
.setNotificationDataUri(URI)
|
||||
.setContactUri(URI)
|
||||
.build();
|
||||
@@ -154,8 +158,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
// Same contact uri.
|
||||
.setContactUri(URI)
|
||||
.build();
|
||||
private final ShortcutInfo mShortcutInfo = new ShortcutInfo.Builder(mContext,
|
||||
SHORTCUT_ID).setLongLabel("name").build();
|
||||
private ShortcutInfo mShortcutInfo;
|
||||
private NotificationEntry mNotificationEntry;
|
||||
|
||||
private PeopleSpaceWidgetManager mManager;
|
||||
|
||||
@@ -215,6 +219,17 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
|
||||
.thenReturn(new Bundle());
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
|
||||
|
||||
when(mMockContext.getPackageName()).thenReturn(TEST_PACKAGE_A);
|
||||
when(mMockContext.getUserId()).thenReturn(0);
|
||||
mShortcutInfo = new ShortcutInfo.Builder(mMockContext,
|
||||
SHORTCUT_ID).setLongLabel("name").build();
|
||||
mNotificationEntry = new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false))
|
||||
.setId(1)
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -490,7 +505,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
ACTIVITY_GAME).setDescription("Playing a game!").build();
|
||||
ConversationStatus status2 = new ConversationStatus.Builder(OTHER_SHORTCUT_ID,
|
||||
ACTIVITY_BIRTHDAY).build();
|
||||
ConversationChannel conversationChannel = getConversationWithShortcutId(OTHER_SHORTCUT_ID,
|
||||
ConversationChannel conversationChannel = getConversationWithShortcutId(
|
||||
new PeopleTileKey(OTHER_SHORTCUT_ID, 0, TEST_PACKAGE_A),
|
||||
Arrays.asList(status1, status2));
|
||||
mManager.updateWidgetsWithConversationChanged(conversationChannel);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
@@ -508,7 +524,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
|
||||
ConversationStatus status = new ConversationStatus.Builder(SHORTCUT_ID,
|
||||
ACTIVITY_GAME).setDescription("Playing a game!").build();
|
||||
ConversationChannel conversationChannel = getConversationWithShortcutId(SHORTCUT_ID,
|
||||
ConversationChannel conversationChannel = getConversationWithShortcutId(
|
||||
new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A),
|
||||
Arrays.asList(status));
|
||||
mManager.updateWidgetsWithConversationChanged(conversationChannel);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
@@ -529,8 +546,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
|
||||
ConversationStatus status = new ConversationStatus.Builder(SHORTCUT_ID,
|
||||
ACTIVITY_ANNIVERSARY).build();
|
||||
ConversationChannel conversationChannel = getConversationWithShortcutId(SHORTCUT_ID,
|
||||
Arrays.asList(status));
|
||||
ConversationChannel conversationChannel = getConversationWithShortcutId(
|
||||
new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A), Arrays.asList(status));
|
||||
mManager.updateWidgetsWithConversationChanged(conversationChannel);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
@@ -550,11 +567,15 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
public void testUpdateNotificationPostedIfExistingTile() throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
NotificationEntryBuilder builder = new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false))
|
||||
.setId(1));
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.setId(1);
|
||||
NotificationEntry entry = builder.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry));
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(builder);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -563,7 +584,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
Bundle bundle = mBundleArgumentCaptor.getValue();
|
||||
PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(tile.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
|
||||
assertThat(tile.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT_1);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
}
|
||||
@@ -620,11 +641,15 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
NotificationEntryBuilder builder = new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ false, /* isMissedCall = */ true))
|
||||
.setId(1));
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.setId(1);
|
||||
NotificationEntry entry = builder.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry));
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(builder);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -645,11 +670,15 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
NotificationEntryBuilder builder = new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
|
||||
.setId(1));
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.setId(1);
|
||||
NotificationEntry entry = builder.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry));
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(builder);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -659,7 +688,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
|
||||
PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(tile.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
|
||||
assertThat(tile.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT_1);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
}
|
||||
@@ -670,11 +699,15 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
int[] widgetIdsArray =
|
||||
{WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
NotificationEntryBuilder builder = new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
|
||||
.setId(1));
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.setId(1);
|
||||
NotificationEntry entry = builder.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry));
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(builder);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -684,7 +717,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
|
||||
NOTIFICATION_CONTENT);
|
||||
NOTIFICATION_CONTENT_1);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -693,7 +726,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
Bundle bundleForSameUriTile = requireNonNull(mBundleArgumentCaptor.getValue());
|
||||
PeopleSpaceTile tileWithSameUri = bundleForSameUriTile.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tileWithSameUri.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
|
||||
assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT_1);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
|
||||
any());
|
||||
}
|
||||
@@ -704,12 +737,19 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
int[] widgetIdsArray =
|
||||
{WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
NotificationEntryBuilder builder = new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
|
||||
.setId(1));
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.setId(1);
|
||||
|
||||
NotificationEntry entry = builder.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry));
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(builder);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of());
|
||||
NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn.cloneLight(), 0);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
@@ -732,46 +772,12 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNotRemoveMissedCallIfMatchingUriTileMissingReadContactsPermissionWhenPosted()
|
||||
throws Exception {
|
||||
when(mPackageManager.checkPermission(any(),
|
||||
eq(PERSON_TILE_WITH_SAME_URI.getPackageName()))).thenReturn(
|
||||
PERMISSION_HARD_DENIED);
|
||||
int[] widgetIdsArray =
|
||||
{WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
|
||||
.setId(1));
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
// We should only try to remove the notification if the Missed Call was added when posted.
|
||||
NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn.cloneLight(), 0);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(2)).updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
Bundle bundle = mBundleArgumentCaptor.getValue();
|
||||
PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(null);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(null);
|
||||
verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
verify(mAppWidgetManager, times(0))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI), any());
|
||||
verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
|
||||
any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMissedCallNotificationWithContentPostedIfMatchingUriTileFromSender()
|
||||
throws Exception {
|
||||
int[] widgetIdsArray =
|
||||
{WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
Notification notificationWithPersonOnlyInSender =
|
||||
createMessagingStyleNotificationWithoutExtras(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */
|
||||
@@ -782,9 +788,15 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.setUid(0)
|
||||
.setUser(new UserHandle(0))
|
||||
.build();
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
NotificationEntryBuilder builder = new NotificationEntryBuilder()
|
||||
.setRank(1)
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.setSbn(sbn)
|
||||
.setId(1));
|
||||
.setId(1);
|
||||
NotificationEntry entry = builder.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry));
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(builder);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -794,7 +806,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
|
||||
NOTIFICATION_CONTENT);
|
||||
NOTIFICATION_CONTENT_1);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -803,7 +815,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
Bundle bundleForSameUriTile = requireNonNull(mBundleArgumentCaptor.getValue());
|
||||
PeopleSpaceTile tileWithSameUri = bundleForSameUriTile.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tileWithSameUri.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
|
||||
assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT_1);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
|
||||
any());
|
||||
}
|
||||
@@ -814,14 +826,13 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
int[] widgetIdsArray =
|
||||
{WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
// Notification posted without any Person attached.
|
||||
Notification notificationWithoutPersonObject =
|
||||
createMessagingStyleNotificationWithoutExtras(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */
|
||||
true).setStyle(new Notification.MessagingStyle("sender")
|
||||
.addMessage(
|
||||
new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT, 10,
|
||||
new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT_1, 10,
|
||||
"sender"))
|
||||
).build();
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
@@ -830,9 +841,15 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.setUid(0)
|
||||
.setUser(new UserHandle(0))
|
||||
.build();
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
NotificationEntryBuilder builder = new NotificationEntryBuilder()
|
||||
.setSbn(sbn)
|
||||
.setId(1));
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.setId(1);
|
||||
NotificationEntry entry = builder.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry));
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(builder);
|
||||
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -842,7 +859,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
|
||||
NOTIFICATION_CONTENT);
|
||||
NOTIFICATION_CONTENT_1);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
// Do not update since notification doesn't include a Person reference.
|
||||
@@ -863,11 +880,15 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
int[] widgetIdsArray =
|
||||
{WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_DIFFERENT_URI};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
NotificationEntryBuilder builder = new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
|
||||
.setId(1));
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.setId(1);
|
||||
NotificationEntry entry = builder.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry));
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(builder);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -877,7 +898,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
|
||||
NOTIFICATION_CONTENT);
|
||||
NOTIFICATION_CONTENT_1);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
// Do not update since missing permission to read contacts.
|
||||
@@ -897,11 +918,15 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
int[] widgetIdsArray =
|
||||
{WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
NotificationEntryBuilder builder = new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
|
||||
.setId(1));
|
||||
.setShortcutInfo(mShortcutInfo)
|
||||
.setId(1);
|
||||
NotificationEntry entry = builder.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications()).thenReturn(List.of(entry));
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(builder);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
@@ -911,14 +936,18 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
|
||||
NOTIFICATION_CONTENT);
|
||||
NOTIFICATION_CONTENT_1);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
// Do not update since missing permission to read contacts.
|
||||
verify(mAppWidgetManager, times(0))
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
|
||||
any());
|
||||
verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
|
||||
mBundleArgumentCaptor.capture());
|
||||
Bundle noNotificationBundle = requireNonNull(mBundleArgumentCaptor.getValue());
|
||||
PeopleSpaceTile tileNoNotification =
|
||||
noNotificationBundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tileNoNotification.getNotificationKey()).isNull();
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
|
||||
any());
|
||||
}
|
||||
|
||||
@@ -952,7 +981,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
public void testAddThenReconfigureWidgetsUpdatesStorageCacheAndListeners()
|
||||
throws Exception {
|
||||
clearStorage();
|
||||
mManager.addNewWidget(WIDGET_ID_WITH_SHORTCUT, PERSON_TILE);
|
||||
mManager.addNewWidget(WIDGET_ID_WITH_SHORTCUT, new PeopleTileKey(PERSON_TILE));
|
||||
// Check storage.
|
||||
SharedPreferences widgetSp = mContext.getSharedPreferences(
|
||||
String.valueOf(WIDGET_ID_WITH_SHORTCUT),
|
||||
@@ -971,7 +1000,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
|
||||
|
||||
// Reconfigure WIDGET_ID_WITH_SHORTCUT from PERSON_TILE to PERSON_TILE_WITH_SAME_URI
|
||||
mManager.addNewWidget(WIDGET_ID_WITH_SHORTCUT, PERSON_TILE_WITH_SAME_URI);
|
||||
mManager.addNewWidget(
|
||||
WIDGET_ID_WITH_SHORTCUT, new PeopleTileKey(PERSON_TILE_WITH_SAME_URI));
|
||||
|
||||
// Check listener is removed and shortcut is uncached.
|
||||
verify(mPeopleManager).unregisterConversationListener(any());
|
||||
@@ -1120,26 +1150,28 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testGetPeopleTileFromPersistentStorageExistingConversation()
|
||||
throws Exception {
|
||||
when(mIPeopleManager.getConversation(PACKAGE_NAME, 0, SHORTCUT_ID)).thenReturn(
|
||||
getConversationWithShortcutId(SHORTCUT_ID));
|
||||
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, PACKAGE_NAME);
|
||||
ConversationChannel channel = getConversationWithShortcutId(
|
||||
new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A));
|
||||
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(channel);
|
||||
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
|
||||
PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key);
|
||||
assertThat(tile.getId()).isEqualTo(key.getShortcutId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPeopleTileFromPersistentStorageNoConversation() {
|
||||
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, PACKAGE_NAME);
|
||||
public void testGetPeopleTileFromPersistentStorageNoConversation() throws RemoteException {
|
||||
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(null);
|
||||
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
|
||||
PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key);
|
||||
assertThat(tile).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestPinAppWidgetExistingConversation() throws Exception {
|
||||
when(mMockContext.getPackageName()).thenReturn(PACKAGE_NAME);
|
||||
when(mMockContext.getUserId()).thenReturn(0);
|
||||
when(mIPeopleManager.getConversation(PACKAGE_NAME, 0, SHORTCUT_ID))
|
||||
.thenReturn(getConversationWithShortcutId(SHORTCUT_ID));
|
||||
ConversationChannel channel = getConversationWithShortcutId(
|
||||
new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A));
|
||||
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID))
|
||||
.thenReturn(channel);
|
||||
when(mAppWidgetManager.requestPinAppWidget(any(), any(), any())).thenReturn(true);
|
||||
|
||||
ShortcutInfo info = new ShortcutInfo.Builder(mMockContext, SHORTCUT_ID).build();
|
||||
@@ -1152,9 +1184,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testRequestPinAppWidgetNoConversation() throws Exception {
|
||||
when(mMockContext.getPackageName()).thenReturn(PACKAGE_NAME);
|
||||
when(mMockContext.getUserId()).thenReturn(0);
|
||||
when(mIPeopleManager.getConversation(PACKAGE_NAME, 0, SHORTCUT_ID)).thenReturn(null);
|
||||
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(null);
|
||||
|
||||
ShortcutInfo info = new ShortcutInfo.Builder(mMockContext, SHORTCUT_ID).build();
|
||||
boolean valid = mManager.requestPinAppWidget(info, new Bundle());
|
||||
@@ -1163,6 +1193,57 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
verify(mAppWidgetManager, never()).requestPinAppWidget(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromNotifications() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID, "userName", ICON, new Intent())
|
||||
.setPackageName(TEST_PACKAGE_A)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
PeopleSpaceTile actual = mManager.augmentTileFromNotifications(tile, EMPTY_STRING,
|
||||
Map.of(new PeopleTileKey(mNotificationEntry),
|
||||
new HashSet<>(Collections.singleton(mNotificationEntry))));
|
||||
|
||||
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_CONTENT_1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromNotificationsDifferentShortcutId() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(OTHER_SHORTCUT_ID, "userName", ICON, new Intent())
|
||||
.setPackageName(TEST_PACKAGE_A)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
PeopleSpaceTile actual = mManager
|
||||
.augmentTileFromNotifications(tile, EMPTY_STRING,
|
||||
Map.of(new PeopleTileKey(mNotificationEntry),
|
||||
new HashSet<>(Collections.singleton(mNotificationEntry))));
|
||||
|
||||
assertThat(actual.getNotificationContent()).isEqualTo(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromNotificationEntryManager() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID, "userName", ICON, new Intent())
|
||||
.setPackageName(TEST_PACKAGE_A)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
when(mNotificationEntryManager.getVisibleNotifications())
|
||||
.thenReturn(List.of(mNotificationEntry));
|
||||
|
||||
PeopleSpaceTile actual =
|
||||
mManager.augmentTileFromNotificationEntryManager(tile);
|
||||
|
||||
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_CONTENT_1);
|
||||
|
||||
verify(mNotificationEntryManager, times(1))
|
||||
.getVisibleNotifications();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds another widget for {@code PERSON_TILE} with widget ID: {@code
|
||||
* SECOND_WIDGET_ID_WITH_SHORTCUT}.
|
||||
@@ -1179,10 +1260,11 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
setStorageForTile(tile.getId(), tile.getPackageName(), widgetId, tile.getContactUri());
|
||||
Bundle options = new Bundle();
|
||||
options.putParcelable(OPTIONS_PEOPLE_TILE, tile);
|
||||
ConversationChannel channel = getConversationWithShortcutId(new PeopleTileKey(tile));
|
||||
when(mAppWidgetManager.getAppWidgetOptions(eq(widgetId)))
|
||||
.thenReturn(options);
|
||||
when(mIPeopleManager.getConversation(tile.getPackageName(), 0, tile.getId())).thenReturn(
|
||||
getConversationWithShortcutId(tile.getId()));
|
||||
when(mIPeopleManager.getConversation(tile.getPackageName(), 0, tile.getId()))
|
||||
.thenReturn(channel);
|
||||
when(mPackageManager.checkPermission(any(), eq(tile.getPackageName()))).thenReturn(
|
||||
PERMISSION_GRANTED);
|
||||
}
|
||||
@@ -1190,17 +1272,19 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
/**
|
||||
* Returns a single conversation associated with {@code shortcutId}.
|
||||
*/
|
||||
private ConversationChannel getConversationWithShortcutId(String shortcutId) throws Exception {
|
||||
return getConversationWithShortcutId(shortcutId, Arrays.asList());
|
||||
private ConversationChannel getConversationWithShortcutId(PeopleTileKey key) throws Exception {
|
||||
return getConversationWithShortcutId(key, Arrays.asList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single conversation associated with {@code shortcutId} and {@code statuses}.
|
||||
*/
|
||||
private ConversationChannel getConversationWithShortcutId(String shortcutId,
|
||||
private ConversationChannel getConversationWithShortcutId(PeopleTileKey key,
|
||||
List<ConversationStatus> statuses) throws Exception {
|
||||
ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
|
||||
"name").setPerson(PERSON).build();
|
||||
when(mMockContext.getPackageName()).thenReturn(key.getPackageName());
|
||||
when(mMockContext.getUserId()).thenReturn(key.getUserId());
|
||||
ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mMockContext, key.getShortcutId())
|
||||
.setLongLabel("name").setPerson(PERSON).build();
|
||||
ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
|
||||
0L, false, false, statuses);
|
||||
return convo;
|
||||
@@ -1220,7 +1304,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
if (isMessagingStyle) {
|
||||
builder.setStyle(new Notification.MessagingStyle(PERSON)
|
||||
.addMessage(
|
||||
new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT, 10,
|
||||
new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT_1, 10,
|
||||
PERSON))
|
||||
);
|
||||
}
|
||||
@@ -1239,7 +1323,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
if (isMessagingStyle) {
|
||||
builder.setStyle(new Notification.MessagingStyle(PERSON)
|
||||
.addMessage(
|
||||
new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT, 10,
|
||||
new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT_1, 10,
|
||||
PERSON))
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user