Merge "Show notification content in single tile widget."
This commit is contained in:
committed by
Android (Google) Code Review
commit
277dc6bf39
@@ -28,7 +28,6 @@ import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
|
||||
/**
|
||||
* The People Space tile contains all relevant information to render a tile in People Space: namely
|
||||
@@ -48,7 +47,10 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
private long mLastInteractionTimestamp;
|
||||
private boolean mIsImportantConversation;
|
||||
private boolean mIsHiddenConversation;
|
||||
private StatusBarNotification mNotification;
|
||||
private String mNotificationKey;
|
||||
// TODO: add mNotificationTimestamp
|
||||
private CharSequence mNotificationContent;
|
||||
private Uri mNotificationDataUri;
|
||||
private Intent mIntent;
|
||||
// TODO: add a List of the Status objects once created
|
||||
|
||||
@@ -62,7 +64,9 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
mLastInteractionTimestamp = b.mLastInteractionTimestamp;
|
||||
mIsImportantConversation = b.mIsImportantConversation;
|
||||
mIsHiddenConversation = b.mIsHiddenConversation;
|
||||
mNotification = b.mNotification;
|
||||
mNotificationKey = b.mNotificationKey;
|
||||
mNotificationContent = b.mNotificationContent;
|
||||
mNotificationDataUri = b.mNotificationDataUri;
|
||||
mIntent = b.mIntent;
|
||||
}
|
||||
|
||||
@@ -112,10 +116,18 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
|
||||
/**
|
||||
* If a notification is currently active that maps to the relevant shortcut ID, provides the
|
||||
* {@link StatusBarNotification} associated.
|
||||
* associated notification's key.
|
||||
*/
|
||||
public StatusBarNotification getNotification() {
|
||||
return mNotification;
|
||||
public String getNotificationKey() {
|
||||
return mNotificationKey;
|
||||
}
|
||||
|
||||
public CharSequence getNotificationContent() {
|
||||
return mNotificationContent;
|
||||
}
|
||||
|
||||
public Uri getNotificationDataUri() {
|
||||
return mNotificationDataUri;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,6 +141,22 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
return mIntent;
|
||||
}
|
||||
|
||||
/** Converts a {@link PeopleSpaceTile} into a {@link PeopleSpaceTile.Builder}. */
|
||||
public PeopleSpaceTile.Builder toBuilder() {
|
||||
PeopleSpaceTile.Builder builder =
|
||||
new PeopleSpaceTile.Builder(mId, mUserName.toString(), mUserIcon, mIntent);
|
||||
builder.setContactUri(mContactUri);
|
||||
builder.setUid(mUid);
|
||||
builder.setPackageName(mPackageName);
|
||||
builder.setLastInteractionTimestamp(mLastInteractionTimestamp);
|
||||
builder.setIsImportantConversation(mIsImportantConversation);
|
||||
builder.setIsHiddenConversation(mIsHiddenConversation);
|
||||
builder.setNotificationKey(mNotificationKey);
|
||||
builder.setNotificationContent(mNotificationContent);
|
||||
builder.setNotificationDataUri(mNotificationDataUri);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/** Builder to create a {@link PeopleSpaceTile}. */
|
||||
public static class Builder {
|
||||
private String mId;
|
||||
@@ -140,7 +168,9 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
private long mLastInteractionTimestamp;
|
||||
private boolean mIsImportantConversation;
|
||||
private boolean mIsHiddenConversation;
|
||||
private StatusBarNotification mNotification;
|
||||
private String mNotificationKey;
|
||||
private CharSequence mNotificationContent;
|
||||
private Uri mNotificationDataUri;
|
||||
private Intent mIntent;
|
||||
|
||||
/** Builder for use only if a shortcut is not available for the tile. */
|
||||
@@ -214,9 +244,21 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the associated notification. */
|
||||
public Builder setNotification(StatusBarNotification notification) {
|
||||
mNotification = notification;
|
||||
/** Sets the associated notification's key. */
|
||||
public Builder setNotificationKey(String notificationKey) {
|
||||
mNotificationKey = notificationKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the associated notification's content. */
|
||||
public Builder setNotificationContent(CharSequence notificationContent) {
|
||||
mNotificationContent = notificationContent;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the associated notification's data URI. */
|
||||
public Builder setNotificationDataUri(Uri notificationDataUri) {
|
||||
mNotificationDataUri = notificationDataUri;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -242,7 +284,9 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
mLastInteractionTimestamp = in.readLong();
|
||||
mIsImportantConversation = in.readBoolean();
|
||||
mIsHiddenConversation = in.readBoolean();
|
||||
mNotification = in.readParcelable(StatusBarNotification.class.getClassLoader());
|
||||
mNotificationKey = in.readString();
|
||||
mNotificationContent = in.readCharSequence();
|
||||
mNotificationDataUri = in.readParcelable(Uri.class.getClassLoader());
|
||||
mIntent = in.readParcelable(Intent.class.getClassLoader());
|
||||
}
|
||||
|
||||
@@ -259,9 +303,11 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
dest.writeInt(mUid);
|
||||
dest.writeString(mPackageName);
|
||||
dest.writeLong(mLastInteractionTimestamp);
|
||||
dest.writeParcelable(mNotification, flags);
|
||||
dest.writeBoolean(mIsImportantConversation);
|
||||
dest.writeBoolean(mIsHiddenConversation);
|
||||
dest.writeString(mNotificationKey);
|
||||
dest.writeCharSequence(mNotificationContent);
|
||||
dest.writeParcelable(mNotificationDataUri, flags);
|
||||
dest.writeParcelable(mIntent, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.LauncherApps;
|
||||
@@ -35,8 +34,6 @@ import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -186,17 +183,34 @@ public class PeopleSpaceTileTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotification() {
|
||||
Notification notification = new Notification.Builder(mContext, "test").build();
|
||||
StatusBarNotification sbn = new StatusBarNotification("pkg" /* pkg */, "pkg" /* opPkg */,
|
||||
1 /* id */, "" /* tag */, 0 /* uid */, 0 /* initialPid */, 0 /* score */,
|
||||
notification, UserHandle.CURRENT, 0 /* postTime */);
|
||||
public void testNotificationKey() {
|
||||
PeopleSpaceTile tile = new PeopleSpaceTile
|
||||
.Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
|
||||
.setNotification(sbn)
|
||||
.setNotificationKey("test")
|
||||
.build();
|
||||
|
||||
assertThat(tile.getNotification()).isEqualTo(sbn);
|
||||
assertThat(tile.getNotificationKey()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationContent() {
|
||||
PeopleSpaceTile tile = new PeopleSpaceTile
|
||||
.Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
|
||||
.setNotificationContent("test")
|
||||
.build();
|
||||
|
||||
assertThat(tile.getNotificationContent()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationDataUri() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile.Builder(new ShortcutInfo.Builder(mContext, "123").build(),
|
||||
mLauncherApps)
|
||||
.setNotificationDataUri(Uri.parse("test"))
|
||||
.build();
|
||||
|
||||
assertThat(tile.getNotificationDataUri()).isEqualTo(Uri.parse("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -82,16 +82,25 @@
|
||||
android:ellipsize="end" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/content"
|
||||
android:paddingVertical="3dp"
|
||||
android:paddingHorizontal="12dp"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
|
||||
<LinearLayout
|
||||
android:background="@drawable/people_space_content_background"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end" />
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:id="@+id/content"
|
||||
android:paddingVertical="3dp"
|
||||
android:paddingHorizontal="12dp"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end" />
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -136,8 +136,12 @@ public class PeopleSpaceActivity extends Activity {
|
||||
editor.putString(String.valueOf(mAppWidgetId), tile.getId());
|
||||
editor.commit();
|
||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
|
||||
Bundle options = new Bundle();
|
||||
options.putParcelable(PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE, tile);
|
||||
appWidgetManager.updateAppWidgetOptions(mAppWidgetId, options);
|
||||
int[] widgetIds = appWidgetManager.getAppWidgetIds(
|
||||
new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
|
||||
// TODO: Populate new widget with existing conversation notification, if there is any.
|
||||
PeopleSpaceUtils.updateSingleConversationWidgets(mContext, widgetIds, mAppWidgetManager,
|
||||
mNotificationManager);
|
||||
finishActivity();
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
package com.android.systemui.people;
|
||||
|
||||
import static android.app.Notification.EXTRA_MESSAGES;
|
||||
|
||||
import android.app.INotificationManager;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.people.ConversationChannel;
|
||||
import android.app.people.IPeopleManager;
|
||||
@@ -26,7 +29,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
@@ -34,20 +36,28 @@ import android.graphics.drawable.Drawable;
|
||||
import android.icu.text.MeasureFormat;
|
||||
import android.icu.util.Measure;
|
||||
import android.icu.util.MeasureUnit;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.people.widget.LaunchConversationActivity;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -63,6 +73,13 @@ public class PeopleSpaceUtils {
|
||||
private static final int DAYS_IN_A_WEEK = 7;
|
||||
private static final int MIN_HOUR = 1;
|
||||
private static final int ONE_DAY = 1;
|
||||
public static final String OPTIONS_PEOPLE_SPACE_TILE = "options_people_space_tile";
|
||||
|
||||
/** Represents whether {@link StatusBarNotification} was posted or removed. */
|
||||
public enum NotificationAction {
|
||||
POSTED,
|
||||
REMOVED
|
||||
}
|
||||
|
||||
/** Returns a list of map entries corresponding to user's conversations. */
|
||||
public static List<Map.Entry<Long, PeopleSpaceTile>> getTiles(
|
||||
@@ -93,75 +110,42 @@ public class PeopleSpaceUtils {
|
||||
/** Updates {@code appWidgetIds} with their associated conversation stored. */
|
||||
public static void updateSingleConversationWidgets(Context context, int[] appWidgetIds,
|
||||
AppWidgetManager appWidgetManager, INotificationManager notificationManager) {
|
||||
PackageManager mPackageManager = context.getPackageManager();
|
||||
IPeopleManager mPeopleManager = IPeopleManager.Stub.asInterface(
|
||||
IPeopleManager peopleManager = IPeopleManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.PEOPLE_SERVICE));
|
||||
LauncherApps mLauncherApps = context.getSystemService(LauncherApps.class);
|
||||
LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
Intent activityIntent = new Intent(context, LaunchConversationActivity.class);
|
||||
activityIntent.addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
| Intent.FLAG_ACTIVITY_NO_HISTORY
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
|
||||
try {
|
||||
List<Map.Entry<Long, PeopleSpaceTile>> shortcutInfos =
|
||||
PeopleSpaceUtils.getTiles(
|
||||
context, notificationManager,
|
||||
mPeopleManager, mLauncherApps);
|
||||
List<Map.Entry<Long, PeopleSpaceTile>> tiles =
|
||||
PeopleSpaceUtils.getTiles(context, notificationManager,
|
||||
peopleManager, launcherApps);
|
||||
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
String shortcutId = sp.getString(String.valueOf(appWidgetId), null);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Set widget: " + appWidgetId + " with shortcut ID: " + shortcutId);
|
||||
}
|
||||
|
||||
Optional<Map.Entry<Long, PeopleSpaceTile>> entry = shortcutInfos.stream().filter(
|
||||
Optional<Map.Entry<Long, PeopleSpaceTile>> entry = tiles.stream().filter(
|
||||
e -> e.getValue().getId().equals(shortcutId)).findFirst();
|
||||
if (!entry.isPresent() || shortcutId == null) {
|
||||
if (DEBUG) Log.d(TAG, "Matching conversation not found for shortcut ID");
|
||||
//TODO: Delete app widget id when crash is fixed (b/175486868)
|
||||
continue;
|
||||
}
|
||||
PeopleSpaceTile tile = entry.get().getValue();
|
||||
RemoteViews views = new RemoteViews(context.getPackageName(),
|
||||
getLayout(tile));
|
||||
PeopleSpaceTile tile =
|
||||
augmentTileFromStorage(entry.get().getValue(), appWidgetManager,
|
||||
appWidgetId);
|
||||
|
||||
String status = PeopleSpaceUtils.getLastInteractionString(context,
|
||||
entry.get().getKey());
|
||||
views.setTextViewText(R.id.status, status);
|
||||
views.setTextViewText(R.id.name, tile.getUserName().toString());
|
||||
RemoteViews views = createRemoteViews(context, tile, entry.get().getKey(),
|
||||
appWidgetId);
|
||||
|
||||
activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, tile.getId());
|
||||
activityIntent.putExtra(
|
||||
PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, tile.getPackageName());
|
||||
activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_UID, tile.getUid());
|
||||
views.setOnClickPendingIntent(R.id.item, PendingIntent.getActivity(
|
||||
context,
|
||||
appWidgetId,
|
||||
activityIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE));
|
||||
|
||||
views.setImageViewBitmap(
|
||||
R.id.package_icon,
|
||||
PeopleSpaceUtils.convertDrawableToBitmap(
|
||||
mPackageManager.getApplicationIcon(tile.getPackageName())
|
||||
)
|
||||
);
|
||||
views.setImageViewIcon(R.id.person_icon, tile.getUserIcon());
|
||||
// Tell the AppWidgetManager to perform an update on the current app widget.
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to retrieve conversations to set tiles");
|
||||
Log.e(TAG, "Exception updating single conversation widgets: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the layout ID for the {@code tile}. */
|
||||
private static int getLayout(PeopleSpaceTile tile) {
|
||||
return tile.getNotification() == null ? R.layout.people_space_large_avatar_tile :
|
||||
R.layout.people_space_small_avatar_tile;
|
||||
}
|
||||
|
||||
/** Returns a list sorted by ascending last interaction time from {@code stream}. */
|
||||
private static List<Map.Entry<Long, PeopleSpaceTile>> getSortedTiles(
|
||||
IPeopleManager peopleManager, Stream<PeopleSpaceTile> stream) {
|
||||
@@ -172,6 +156,152 @@ public class PeopleSpaceUtils {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/** Augment {@link PeopleSpaceTile} with fields from stored tile. */
|
||||
@VisibleForTesting
|
||||
static PeopleSpaceTile augmentTileFromStorage(PeopleSpaceTile tile,
|
||||
AppWidgetManager appWidgetManager, int appWidgetId) {
|
||||
Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
|
||||
PeopleSpaceTile storedTile = options.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
|
||||
if (storedTile == null) {
|
||||
return tile;
|
||||
}
|
||||
return tile.toBuilder()
|
||||
.setNotificationKey(storedTile.getNotificationKey())
|
||||
.setNotificationContent(storedTile.getNotificationContent())
|
||||
.setNotificationDataUri(storedTile.getNotificationDataUri())
|
||||
.build();
|
||||
}
|
||||
|
||||
/** If incoming notification changed tile, store the changes in the tile options. */
|
||||
public static void storeNotificationChange(StatusBarNotification sbn,
|
||||
NotificationAction notificationAction, AppWidgetManager appWidgetManager,
|
||||
int appWidgetId) {
|
||||
Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
|
||||
PeopleSpaceTile storedTile = options.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
|
||||
if (notificationAction == PeopleSpaceUtils.NotificationAction.POSTED) {
|
||||
if (DEBUG) Log.i(TAG, "Adding notification to storage, appWidgetId: " + appWidgetId);
|
||||
Notification.MessagingStyle.Message message = getLastMessagingStyleMessage(sbn);
|
||||
if (message == null) {
|
||||
if (DEBUG) Log.i(TAG, "Notification doesn't have content, skipping.");
|
||||
return;
|
||||
}
|
||||
storedTile = storedTile
|
||||
.toBuilder()
|
||||
.setNotificationKey(sbn.getKey())
|
||||
.setNotificationContent(message.getText())
|
||||
.setNotificationDataUri(message.getDataUri())
|
||||
.build();
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Removing notification from storage, appWidgetId: " + appWidgetId);
|
||||
}
|
||||
storedTile = storedTile
|
||||
.toBuilder()
|
||||
.setNotificationKey(null)
|
||||
.setNotificationContent(null)
|
||||
.setNotificationDataUri(null)
|
||||
.build();
|
||||
}
|
||||
Bundle newOptions = new Bundle();
|
||||
newOptions.putParcelable(OPTIONS_PEOPLE_SPACE_TILE, storedTile);
|
||||
appWidgetManager.updateAppWidgetOptions(appWidgetId, newOptions);
|
||||
}
|
||||
|
||||
private static RemoteViews createRemoteViews(Context context, PeopleSpaceTile tile,
|
||||
long lastInteraction, int appWidgetId) throws Exception {
|
||||
// TODO: If key is null or if text and data uri are null.
|
||||
if (tile.getNotificationKey() == null) {
|
||||
return createLastInteractionRemoteViews(context, tile, lastInteraction, appWidgetId);
|
||||
}
|
||||
return createNotificationRemoteViews(context, tile, lastInteraction, appWidgetId);
|
||||
}
|
||||
|
||||
private static RemoteViews createLastInteractionRemoteViews(Context context,
|
||||
PeopleSpaceTile tile, long lastInteraction, int appWidgetId)
|
||||
throws Exception {
|
||||
RemoteViews views = new RemoteViews(
|
||||
context.getPackageName(), R.layout.people_space_large_avatar_tile);
|
||||
String status = PeopleSpaceUtils.getLastInteractionString(
|
||||
context, lastInteraction);
|
||||
views.setTextViewText(R.id.status, status);
|
||||
|
||||
views = setCommonRemoteViewsFields(context, views, tile, appWidgetId);
|
||||
return views;
|
||||
}
|
||||
|
||||
private static RemoteViews createNotificationRemoteViews(Context context,
|
||||
PeopleSpaceTile tile, long lastInteraction, int appWidgetId)
|
||||
throws Exception {
|
||||
|
||||
RemoteViews views = new RemoteViews(
|
||||
context.getPackageName(), R.layout.people_space_small_avatar_tile);
|
||||
Uri image = tile.getNotificationDataUri();
|
||||
if (image != null) {
|
||||
//TODO: Use NotificationInlineImageCache
|
||||
views.setImageViewUri(R.id.image, image);
|
||||
views.setViewVisibility(R.id.image, View.VISIBLE);
|
||||
views.setViewVisibility(R.id.content, View.GONE);
|
||||
} else {
|
||||
views.setTextViewText(R.id.content, tile.getNotificationContent());
|
||||
views.setViewVisibility(R.id.content, View.VISIBLE);
|
||||
views.setViewVisibility(R.id.image, View.GONE);
|
||||
}
|
||||
|
||||
views = setCommonRemoteViewsFields(context, views, tile, appWidgetId);
|
||||
return views;
|
||||
}
|
||||
|
||||
private static RemoteViews setCommonRemoteViewsFields(
|
||||
Context context, RemoteViews views, PeopleSpaceTile tile, int appWidgetId)
|
||||
throws Exception {
|
||||
views.setTextViewText(R.id.name, tile.getUserName().toString());
|
||||
views.setImageViewBitmap(
|
||||
R.id.package_icon,
|
||||
PeopleSpaceUtils.convertDrawableToBitmap(
|
||||
context.getPackageManager().getApplicationIcon(tile.getPackageName())
|
||||
)
|
||||
);
|
||||
views.setImageViewIcon(R.id.person_icon, tile.getUserIcon());
|
||||
|
||||
Intent activityIntent = new Intent(context, LaunchConversationActivity.class);
|
||||
activityIntent.addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
| Intent.FLAG_ACTIVITY_NO_HISTORY
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
|
||||
activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, tile.getId());
|
||||
activityIntent.putExtra(
|
||||
PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, tile.getPackageName());
|
||||
activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_UID, tile.getUid());
|
||||
views.setOnClickPendingIntent(R.id.item, PendingIntent.getActivity(
|
||||
context,
|
||||
appWidgetId,
|
||||
activityIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE));
|
||||
return views;
|
||||
}
|
||||
|
||||
/** Gets the most recent {@link Notification.MessagingStyle.Message} from the notification. */
|
||||
public static Notification.MessagingStyle.Message getLastMessagingStyleMessage(
|
||||
StatusBarNotification sbn) {
|
||||
Notification notification = sbn.getNotification();
|
||||
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.get(0);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Returns the last interaction time with the user specified by {@code PeopleSpaceTile}. */
|
||||
private static Long getLastInteraction(IPeopleManager peopleManager,
|
||||
PeopleSpaceTile tile) {
|
||||
|
||||
@@ -21,8 +21,10 @@ import android.app.NotificationChannel;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
@@ -35,6 +37,8 @@ import com.android.systemui.people.PeopleSpaceUtils;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@@ -84,7 +88,6 @@ public class PeopleSpaceWidgetManager {
|
||||
int[] widgetIds = mAppWidgetService.getAppWidgetIds(
|
||||
new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
|
||||
);
|
||||
|
||||
if (widgetIds.length == 0) {
|
||||
if (DEBUG) Log.d(TAG, "no widgets to update");
|
||||
return;
|
||||
@@ -93,6 +96,7 @@ public class PeopleSpaceWidgetManager {
|
||||
if (DEBUG) Log.d(TAG, "updating " + widgetIds.length + " widgets");
|
||||
boolean showSingleConversation = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
|
||||
|
||||
if (showSingleConversation) {
|
||||
PeopleSpaceUtils.updateSingleConversationWidgets(mContext, widgetIds,
|
||||
mAppWidgetManager, mNotificationManager);
|
||||
@@ -106,6 +110,41 @@ public class PeopleSpaceWidgetManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any existing People tiles match the incoming notification change, and store the
|
||||
* change in the tile if so.
|
||||
*/
|
||||
public void storeNotificationChange(StatusBarNotification sbn,
|
||||
PeopleSpaceUtils.NotificationAction notificationAction) {
|
||||
if (DEBUG) Log.d(TAG, "storeNotificationChange called");
|
||||
boolean showSingleConversation = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
|
||||
if (!showSingleConversation) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int[] widgetIds = mAppWidgetService.getAppWidgetIds(
|
||||
new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
|
||||
);
|
||||
if (widgetIds.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
for (int widgetId : widgetIds) {
|
||||
String shortcutId = sp.getString(String.valueOf(widgetId), null);
|
||||
if (!Objects.equals(sbn.getShortcutId(), shortcutId)) {
|
||||
continue;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
|
||||
PeopleSpaceUtils.storeNotificationChange(
|
||||
sbn, notificationAction, mAppWidgetManager, widgetId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the manager to the pipeline, making it ready to receive events. Should only be
|
||||
* called once.
|
||||
@@ -120,6 +159,7 @@ public class PeopleSpaceWidgetManager {
|
||||
public void onNotificationPosted(
|
||||
StatusBarNotification sbn, NotificationListenerService.RankingMap rankingMap) {
|
||||
if (DEBUG) Log.d(TAG, "onNotificationPosted");
|
||||
storeNotificationChange(sbn, PeopleSpaceUtils.NotificationAction.POSTED);
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
@@ -129,6 +169,7 @@ public class PeopleSpaceWidgetManager {
|
||||
NotificationListenerService.RankingMap rankingMap
|
||||
) {
|
||||
if (DEBUG) Log.d(TAG, "onNotificationRemoved");
|
||||
storeNotificationChange(sbn, PeopleSpaceUtils.NotificationAction.REMOVED);
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
@@ -138,6 +179,7 @@ public class PeopleSpaceWidgetManager {
|
||||
NotificationListenerService.RankingMap rankingMap,
|
||||
int reason) {
|
||||
if (DEBUG) Log.d(TAG, "onNotificationRemoved with reason " + reason);
|
||||
storeNotificationChange(sbn, PeopleSpaceUtils.NotificationAction.REMOVED);
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.people;
|
||||
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE;
|
||||
|
||||
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.Notification;
|
||||
import android.app.Person;
|
||||
import android.app.people.PeopleSpaceTile;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.appwidget.IAppWidgetService;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.SbnBuilder;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
|
||||
private static final int WIDGET_ID_WITH_SHORTCUT = 1;
|
||||
private static final int WIDGET_ID_WITHOUT_SHORTCUT = 2;
|
||||
private static final String SHORTCUT_ID = "101";
|
||||
private static final String NOTIFICATION_KEY = "notification_key";
|
||||
private static final String NOTIFICATION_CONTENT = "notification_content";
|
||||
|
||||
@Mock
|
||||
private NotificationListener mListenerService;
|
||||
@Mock
|
||||
private IAppWidgetService mIAppWidgetService;
|
||||
@Mock
|
||||
private AppWidgetManager mAppWidgetManager;
|
||||
|
||||
private static Icon sIcon = Icon.createWithResource("package", R.drawable.ic_android);
|
||||
private static Uri sUri = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority("something")
|
||||
.path("test")
|
||||
.build();
|
||||
private static Person sPerson = new Person.Builder()
|
||||
.setName("name")
|
||||
.setKey("abc")
|
||||
.setUri("uri")
|
||||
.setBot(false)
|
||||
.build();
|
||||
private static PeopleSpaceTile sPeopleSpaceTile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID, "username", sIcon, new Intent())
|
||||
.setNotificationKey(NOTIFICATION_KEY)
|
||||
.setNotificationContent(NOTIFICATION_CONTENT)
|
||||
.setNotificationDataUri(sUri)
|
||||
.build();
|
||||
|
||||
@Before
|
||||
public void setUp() throws RemoteException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
|
||||
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
Bundle options = new Bundle();
|
||||
options.putParcelable(OPTIONS_PEOPLE_SPACE_TILE, sPeopleSpaceTile);
|
||||
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
|
||||
.thenReturn(options);
|
||||
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
|
||||
.thenReturn(new Bundle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastMessagingStyleMessageNoMessage() {
|
||||
Notification notification = new Notification.Builder(mContext, "test")
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(SHORTCUT_ID)
|
||||
.build();
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(notification)
|
||||
.build();
|
||||
|
||||
Notification.MessagingStyle.Message lastMessage =
|
||||
PeopleSpaceUtils.getLastMessagingStyleMessage(sbn);
|
||||
|
||||
assertThat(lastMessage).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastMessagingStyleMessage() {
|
||||
Notification notification = new Notification.Builder(mContext, "test")
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(SHORTCUT_ID)
|
||||
.setStyle(new Notification.MessagingStyle(sPerson)
|
||||
.addMessage(new Notification.MessagingStyle.Message("text1", 0, sPerson))
|
||||
.addMessage(new Notification.MessagingStyle.Message("text2", 20, sPerson))
|
||||
.addMessage(new Notification.MessagingStyle.Message("text3", 10, sPerson))
|
||||
)
|
||||
.build();
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(notification)
|
||||
.build();
|
||||
|
||||
Notification.MessagingStyle.Message lastMessage =
|
||||
PeopleSpaceUtils.getLastMessagingStyleMessage(sbn);
|
||||
|
||||
assertThat(lastMessage.getText()).isEqualTo("text2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromStorageWithNotification() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder("id", "userName", sIcon, new Intent())
|
||||
.build();
|
||||
PeopleSpaceTile actual = PeopleSpaceUtils
|
||||
.augmentTileFromStorage(tile, mAppWidgetManager, WIDGET_ID_WITH_SHORTCUT);
|
||||
|
||||
assertThat(actual.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
|
||||
assertThat(actual.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
|
||||
assertThat(actual.getNotificationDataUri()).isEqualTo(sUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromStorageWithoutNotification() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder("id", "userName", sIcon, new Intent())
|
||||
.build();
|
||||
PeopleSpaceTile actual = PeopleSpaceUtils
|
||||
.augmentTileFromStorage(tile, mAppWidgetManager, WIDGET_ID_WITHOUT_SHORTCUT);
|
||||
|
||||
assertThat(actual.getNotificationKey()).isEqualTo(null);
|
||||
assertThat(actual.getNotificationKey()).isEqualTo(null);
|
||||
assertThat(actual.getNotificationDataUri()).isEqualTo(null);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@ package com.android.systemui.people.widget;
|
||||
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
||||
import static android.app.NotificationManager.IMPORTANCE_HIGH;
|
||||
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -30,15 +32,24 @@ import static org.mockito.Mockito.when;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import android.app.INotificationManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.Person;
|
||||
import android.app.people.PeopleSpaceTile;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
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.provider.Settings;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
@@ -46,9 +57,11 @@ import androidx.preference.PreferenceManager;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.appwidget.IAppWidgetService;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
|
||||
import com.android.systemui.statusbar.SbnBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.NoManSimulator;
|
||||
import com.android.systemui.statusbar.notification.collection.NoManSimulator.NotifEvent;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
@@ -79,6 +92,9 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
private static final int WIDGET_ID_WITH_SHORTCUT = 1;
|
||||
private static final int WIDGET_ID_WITHOUT_SHORTCUT = 2;
|
||||
private static final String SHORTCUT_ID = "101";
|
||||
private static final String OTHER_SHORTCUT_ID = "102";
|
||||
private static final String NOTIFICATION_KEY = "notification_key";
|
||||
private static final String NOTIFICATION_CONTENT = "notification_content";
|
||||
|
||||
private PeopleSpaceWidgetManager mManager;
|
||||
|
||||
@@ -94,6 +110,26 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Captor
|
||||
private ArgumentCaptor<NotificationHandler> mListenerCaptor;
|
||||
|
||||
private static Icon sIcon = Icon.createWithResource("package", R.drawable.ic_android);
|
||||
private static Uri sUri = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority("something")
|
||||
.path("test")
|
||||
.build();
|
||||
private static Person sPerson = new Person.Builder()
|
||||
.setName("name")
|
||||
.setKey("abc")
|
||||
.setUri("uri")
|
||||
.setBot(false)
|
||||
.build();
|
||||
private static PeopleSpaceTile sPeopleSpaceTile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID, "username", sIcon, new Intent())
|
||||
.setNotificationKey(NOTIFICATION_KEY)
|
||||
.setNotificationContent(NOTIFICATION_CONTENT)
|
||||
.setNotificationDataUri(sUri)
|
||||
.build();
|
||||
|
||||
private final NoManSimulator mNoMan = new NoManSimulator();
|
||||
private final FakeSystemClock mClock = new FakeSystemClock();
|
||||
|
||||
@@ -110,6 +146,18 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
mNoMan.addListener(serviceListener);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 2);
|
||||
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), SHORTCUT_ID);
|
||||
editor.commit();
|
||||
Bundle options = new Bundle();
|
||||
options.putParcelable(OPTIONS_PEOPLE_SPACE_TILE, sPeopleSpaceTile);
|
||||
|
||||
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
|
||||
.thenReturn(options);
|
||||
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
|
||||
.thenReturn(new Bundle());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -123,7 +171,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.setPkg(TEST_PACKAGE_A));
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
|
||||
verify(mIAppWidgetService, never()).notifyAppWidgetViewDataChanged(any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@@ -140,7 +187,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.setPkg(TEST_PACKAGE_A));
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
|
||||
verify(mAppWidgetManager, never()).updateAppWidget(anyInt(), any(RemoteViews.class));
|
||||
verify(mIAppWidgetService, never()).notifyAppWidgetViewDataChanged(any(), any(), anyInt());
|
||||
}
|
||||
@@ -156,7 +202,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.setPkg(TEST_PACKAGE_A));
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
|
||||
verify(mIAppWidgetService, times(1))
|
||||
.notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
|
||||
verify(mIAppWidgetService, never()).updateAppWidgetIds(any(), any(),
|
||||
@@ -171,17 +216,12 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
when(mINotificationManager.getConversations(true)).thenReturn(
|
||||
new ParceledListSlice(getConversationWithShortcutId()));
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), SHORTCUT_ID);
|
||||
editor.commit();
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setPkg(TEST_PACKAGE_A)
|
||||
.setId(1));
|
||||
|
||||
verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
|
||||
verify(mIAppWidgetService, never())
|
||||
.notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
@@ -198,10 +238,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
when(mINotificationManager.getConversations(true)).thenReturn(
|
||||
new ParceledListSlice(getConversationWithShortcutId()));
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), SHORTCUT_ID);
|
||||
editor.commit();
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
@@ -212,7 +248,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.setPkg(TEST_PACKAGE_B)
|
||||
.setId(2));
|
||||
|
||||
verify(mIAppWidgetService, times(2)).getAppWidgetIds(any());
|
||||
verify(mIAppWidgetService, never())
|
||||
.notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
|
||||
verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
@@ -234,7 +269,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.setPkg(TEST_PACKAGE_B)
|
||||
.setId(2));
|
||||
|
||||
verify(mIAppWidgetService, times(2)).getAppWidgetIds(any());
|
||||
verify(mIAppWidgetService, times(2))
|
||||
.notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
|
||||
verify(mAppWidgetManager, never()).updateAppWidget(anyInt(),
|
||||
@@ -252,7 +286,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
mClock.advanceTime(4);
|
||||
NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn, 0);
|
||||
|
||||
verify(mIAppWidgetService, times(2)).getAppWidgetIds(any());
|
||||
verify(mIAppWidgetService, times(2))
|
||||
.notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
|
||||
verify(mAppWidgetManager, never()).updateAppWidget(anyInt(),
|
||||
@@ -290,13 +323,124 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
UserHandle.getUserHandleForUid(0), channel, IMPORTANCE_HIGH);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
|
||||
verify(mIAppWidgetService, times(1))
|
||||
.notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
|
||||
verify(mAppWidgetManager, never()).updateAppWidget(anyInt(),
|
||||
any(RemoteViews.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNotUpdateNotificationPostedIfNoExistingTile() throws RemoteException {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
|
||||
when(mINotificationManager.getConversations(true)).thenReturn(
|
||||
new ParceledListSlice(getConversationWithShortcutId()));
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbn = createConversationNotification(OTHER_SHORTCUT_ID);
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setSbn(sbn)
|
||||
.setPkg(TEST_PACKAGE_A)
|
||||
.setId(1));
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, never())
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNotUpdateNotificationRemovedIfNoExistingTile() throws RemoteException {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
|
||||
when(mINotificationManager.getConversations(true)).thenReturn(
|
||||
new ParceledListSlice(getConversationWithShortcutId()));
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbn = createConversationNotification(OTHER_SHORTCUT_ID);
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setSbn(sbn)
|
||||
.setPkg(TEST_PACKAGE_A)
|
||||
.setId(1));
|
||||
mClock.advanceTime(4);
|
||||
NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn, 0);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, never())
|
||||
.updateAppWidgetOptions(anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNotificationPostedIfExistingTile() throws RemoteException {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
|
||||
when(mINotificationManager.getConversations(true)).thenReturn(
|
||||
new ParceledListSlice(getConversationWithShortcutId()));
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbn = createConversationNotification(SHORTCUT_ID);
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setSbn(sbn)
|
||||
.setPkg(TEST_PACKAGE_A)
|
||||
.setId(1));
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNotUpdateNotificationPostedWithoutMessagesIfExistingTile()
|
||||
throws RemoteException {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
|
||||
when(mINotificationManager.getConversations(true)).thenReturn(
|
||||
new ParceledListSlice(getConversationWithShortcutId()));
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
Notification notification = new Notification.Builder(mContext)
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(SHORTCUT_ID)
|
||||
.build();
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(notification)
|
||||
.build();
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setSbn(sbn)
|
||||
.setPkg(TEST_PACKAGE_A)
|
||||
.setId(1));
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, never())
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNotificationRemovedIfExistingTile() throws RemoteException {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
|
||||
when(mINotificationManager.getConversations(true)).thenReturn(
|
||||
new ParceledListSlice(getConversationWithShortcutId()));
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbn = createConversationNotification(SHORTCUT_ID);
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setSbn(sbn)
|
||||
.setPkg(TEST_PACKAGE_A)
|
||||
.setId(1));
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn, 0);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(2))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT), any());
|
||||
}
|
||||
|
||||
/** Returns a list of a single conversation associated with {@code SHORTCUT_ID}. */
|
||||
private List<ConversationChannelWrapper> getConversationWithShortcutId() {
|
||||
List<ConversationChannelWrapper> convos = new ArrayList<>();
|
||||
@@ -306,4 +450,18 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
convos.add(convo1);
|
||||
return convos;
|
||||
}
|
||||
|
||||
private StatusBarNotification createConversationNotification(String shortcutId) {
|
||||
Notification notification = new Notification.Builder(mContext)
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
.setShortcutId(shortcutId)
|
||||
.setStyle(new Notification.MessagingStyle(sPerson)
|
||||
.addMessage(new Notification.MessagingStyle.Message("text3", 10, sPerson))
|
||||
)
|
||||
.build();
|
||||
return new SbnBuilder()
|
||||
.setNotification(notification)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user