Merge "Show messages count in People Tile" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5785c5c68f
@@ -56,6 +56,7 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
private CharSequence mNotificationContent;
|
||||
private String mNotificationCategory;
|
||||
private Uri mNotificationDataUri;
|
||||
private int mMessagesCount;
|
||||
private Intent mIntent;
|
||||
private long mNotificationTimestamp;
|
||||
private List<ConversationStatus> mStatuses;
|
||||
@@ -74,6 +75,7 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
mNotificationContent = b.mNotificationContent;
|
||||
mNotificationCategory = b.mNotificationCategory;
|
||||
mNotificationDataUri = b.mNotificationDataUri;
|
||||
mMessagesCount = b.mMessagesCount;
|
||||
mIntent = b.mIntent;
|
||||
mNotificationTimestamp = b.mNotificationTimestamp;
|
||||
mStatuses = b.mStatuses;
|
||||
@@ -140,6 +142,10 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
return mNotificationDataUri;
|
||||
}
|
||||
|
||||
public int getMessagesCount() {
|
||||
return mMessagesCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an intent to launch. If present, we should manually launch the intent on tile
|
||||
* click, rather than calling {@link android.content.pm.LauncherApps} to launch the shortcut ID.
|
||||
@@ -175,6 +181,7 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
builder.setNotificationContent(mNotificationContent);
|
||||
builder.setNotificationCategory(mNotificationCategory);
|
||||
builder.setNotificationDataUri(mNotificationDataUri);
|
||||
builder.setMessagesCount(mMessagesCount);
|
||||
builder.setIntent(mIntent);
|
||||
builder.setNotificationTimestamp(mNotificationTimestamp);
|
||||
builder.setStatuses(mStatuses);
|
||||
@@ -196,6 +203,7 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
private CharSequence mNotificationContent;
|
||||
private String mNotificationCategory;
|
||||
private Uri mNotificationDataUri;
|
||||
private int mMessagesCount;
|
||||
private Intent mIntent;
|
||||
private long mNotificationTimestamp;
|
||||
private List<ConversationStatus> mStatuses;
|
||||
@@ -320,6 +328,12 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the number of messages associated with the Tile. */
|
||||
public Builder setMessagesCount(int messagesCount) {
|
||||
mMessagesCount = messagesCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets an intent to launch on click. */
|
||||
public Builder setIntent(Intent intent) {
|
||||
mIntent = intent;
|
||||
@@ -359,6 +373,7 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
mNotificationContent = in.readCharSequence();
|
||||
mNotificationCategory = in.readString();
|
||||
mNotificationDataUri = in.readParcelable(Uri.class.getClassLoader());
|
||||
mMessagesCount = in.readInt();
|
||||
mIntent = in.readParcelable(Intent.class.getClassLoader());
|
||||
mNotificationTimestamp = in.readLong();
|
||||
mStatuses = new ArrayList<>();
|
||||
@@ -385,6 +400,7 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
dest.writeCharSequence(mNotificationContent);
|
||||
dest.writeString(mNotificationCategory);
|
||||
dest.writeParcelable(mNotificationDataUri, flags);
|
||||
dest.writeInt(mMessagesCount);
|
||||
dest.writeParcelable(mIntent, flags);
|
||||
dest.writeLong(mNotificationTimestamp);
|
||||
dest.writeParcelableList(mStatuses, flags);
|
||||
|
||||
@@ -235,6 +235,7 @@ public class PeopleSpaceTileTest {
|
||||
.setStatuses(statusList).setNotificationKey("key")
|
||||
.setNotificationContent("content")
|
||||
.setNotificationDataUri(Uri.parse("data"))
|
||||
.setMessagesCount(2)
|
||||
.setIntent(new Intent())
|
||||
.build();
|
||||
|
||||
@@ -256,6 +257,7 @@ public class PeopleSpaceTileTest {
|
||||
assertThat(readTile.getNotificationKey()).isEqualTo(tile.getNotificationKey());
|
||||
assertThat(readTile.getNotificationContent()).isEqualTo(tile.getNotificationContent());
|
||||
assertThat(readTile.getNotificationDataUri()).isEqualTo(tile.getNotificationDataUri());
|
||||
assertThat(readTile.getMessagesCount()).isEqualTo(tile.getMessagesCount());
|
||||
assertThat(readTile.getIntent().toString()).isEqualTo(tile.getIntent().toString());
|
||||
}
|
||||
|
||||
@@ -290,6 +292,17 @@ public class PeopleSpaceTileTest {
|
||||
assertThat(tile.getNotificationDataUri()).isEqualTo(Uri.parse("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessagesCount() {
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile.Builder(new ShortcutInfo.Builder(mContext, "123").build(),
|
||||
mLauncherApps)
|
||||
.setMessagesCount(2)
|
||||
.build();
|
||||
|
||||
assertThat(tile.getMessagesCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntent() {
|
||||
PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<solid android:color="#9ED582" />
|
||||
<corners android:radius="@dimen/people_space_messages_count_radius" />
|
||||
</shape>
|
||||
@@ -98,8 +98,8 @@
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="4dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToOutline="true">
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:gravity="center_vertical"
|
||||
@@ -112,7 +112,21 @@
|
||||
android:ellipsize="end"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messages_count"
|
||||
android:gravity="end"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:background="@drawable/people_space_messages_count_background"
|
||||
android:textSize="14sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<ImageView
|
||||
android:id="@+id/predefined_icon"
|
||||
android:gravity="end|center_vertical"
|
||||
|
||||
@@ -1353,6 +1353,7 @@
|
||||
|
||||
<dimen name="people_space_widget_radius">28dp</dimen>
|
||||
<dimen name="people_space_image_radius">20dp</dimen>
|
||||
<dimen name="people_space_messages_count_radius">12dp</dimen>
|
||||
<dimen name="people_space_widget_background_padding">6dp</dimen>
|
||||
<dimen name="required_width_for_medium">146dp</dimen>
|
||||
<dimen name="required_width_for_large">138dp</dimen>
|
||||
|
||||
@@ -2865,6 +2865,8 @@
|
||||
<string name="empty_status">Let’s chat tonight!</string>
|
||||
<!-- Default text for missed call notifications on their Conversation widget [CHAR LIMIT=20] -->
|
||||
<string name="missed_call">Missed call</string>
|
||||
<!-- Text when a Notification may have more messages than the number indicated [CHAR LIMIT=5] -->
|
||||
<string name="messages_count_overflow_indicator"><xliff:g id="number" example="7">%d</xliff:g>+</string>
|
||||
<!-- Description text for adding a Conversation widget [CHAR LIMIT=100] -->
|
||||
<string name="people_tile_description">See recent messages, missed calls, and status updates</string>
|
||||
<!-- Title text displayed for the Conversation widget [CHAR LIMIT=50] -->
|
||||
|
||||
@@ -274,13 +274,17 @@ public class PeopleSpaceUtils {
|
||||
return tile;
|
||||
}
|
||||
boolean isMissedCall = Objects.equals(notification.category, CATEGORY_MISSED_CALL);
|
||||
Notification.MessagingStyle.Message message = getLastMessagingStyleMessage(notification);
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
getMessagingStyleMessages(notification);
|
||||
|
||||
if (!isMissedCall && message == null) {
|
||||
if (!isMissedCall && ArrayUtils.isEmpty(messages)) {
|
||||
if (DEBUG) Log.d(TAG, "Notification has no content");
|
||||
return 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());
|
||||
@@ -294,12 +298,16 @@ public class PeopleSpaceUtils {
|
||||
.setNotificationCategory(notification.category)
|
||||
.setNotificationContent(content)
|
||||
.setNotificationDataUri(dataUri)
|
||||
.setMessagesCount(messagesCount)
|
||||
.build();
|
||||
}
|
||||
|
||||
/** Gets the most recent {@link Notification.MessagingStyle.Message} from the notification. */
|
||||
/**
|
||||
* Returns {@link Notification.MessagingStyle.Message}s from the Notification in chronological
|
||||
* order from most recent to least.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static Notification.MessagingStyle.Message getLastMessagingStyleMessage(
|
||||
public static List<Notification.MessagingStyle.Message> getMessagingStyleMessages(
|
||||
Notification notification) {
|
||||
if (notification == null) {
|
||||
return null;
|
||||
@@ -312,7 +320,7 @@ public class PeopleSpaceUtils {
|
||||
Notification.MessagingStyle.Message.getMessagesFromBundleArray(messages);
|
||||
sortedMessages.sort(Collections.reverseOrder(
|
||||
Comparator.comparing(Notification.MessagingStyle.Message::getTimestamp)));
|
||||
return sortedMessages.get(0);
|
||||
return sortedMessages;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -58,8 +58,10 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.people.widget.LaunchConversationActivity;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -82,6 +84,8 @@ class PeopleTileViewHelper {
|
||||
private static final int FIXED_HEIGHT_DIMENS_FOR_SMALL = 6 + 4 + 8;
|
||||
private static final int FIXED_WIDTH_DIMENS_FOR_SMALL = 4 + 4;
|
||||
|
||||
private static final int MESSAGES_COUNT_OVERFLOW = 7;
|
||||
|
||||
private static final Pattern DOUBLE_EXCLAMATION_PATTERN = Pattern.compile("[!][!]+");
|
||||
private static final Pattern DOUBLE_QUESTION_PATTERN = Pattern.compile("[?][?]+");
|
||||
private static final Pattern ANY_DOUBLE_MARK_PATTERN = Pattern.compile("[!?][!?]+");
|
||||
@@ -97,6 +101,9 @@ class PeopleTileViewHelper {
|
||||
private int mHeight;
|
||||
private int mLayoutSize;
|
||||
|
||||
private Locale mLocale;
|
||||
private NumberFormat mIntegerFormat;
|
||||
|
||||
PeopleTileViewHelper(Context context, PeopleSpaceTile tile,
|
||||
int appWidgetId, Bundle options) {
|
||||
mContext = context;
|
||||
@@ -354,12 +361,35 @@ class PeopleTileViewHelper {
|
||||
views.setViewVisibility(R.id.image, View.GONE);
|
||||
views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_message);
|
||||
}
|
||||
if (mTile.getMessagesCount() > 1 && mLayoutSize == LAYOUT_MEDIUM) {
|
||||
views.setViewVisibility(R.id.messages_count, View.VISIBLE);
|
||||
views.setTextViewText(R.id.messages_count,
|
||||
getMessagesCountText(mTile.getMessagesCount()));
|
||||
}
|
||||
// TODO: Set subtext as Group Sender name once storing the name in PeopleSpaceTile and
|
||||
// subtract 1 from maxLines when present.
|
||||
views.setViewVisibility(R.id.subtext, View.GONE);
|
||||
return views;
|
||||
}
|
||||
|
||||
// Some messaging apps only include up to 7 messages in their notifications.
|
||||
private String getMessagesCountText(int count) {
|
||||
if (count >= MESSAGES_COUNT_OVERFLOW) {
|
||||
return mContext.getResources().getString(
|
||||
R.string.messages_count_overflow_indicator, MESSAGES_COUNT_OVERFLOW);
|
||||
}
|
||||
|
||||
// Cache the locale-appropriate NumberFormat. Configuration locale is guaranteed
|
||||
// non-null, so the first time this is called we will always get the appropriate
|
||||
// NumberFormat, then never regenerate it unless the locale changes on the fly.
|
||||
final Locale curLocale = mContext.getResources().getConfiguration().getLocales().get(0);
|
||||
if (!curLocale.equals(mLocale)) {
|
||||
mLocale = curLocale;
|
||||
mIntegerFormat = NumberFormat.getIntegerInstance(curLocale);
|
||||
}
|
||||
return mIntegerFormat.format(count);
|
||||
}
|
||||
|
||||
private RemoteViews createStatusRemoteViews(ConversationStatus status) {
|
||||
RemoteViews views = getViewForContentLayout();
|
||||
CharSequence statusText = status.getDescription();
|
||||
|
||||
@@ -328,6 +328,7 @@ public class PeopleSpaceWidgetManager {
|
||||
.setNotificationKey(null)
|
||||
.setNotificationContent(null)
|
||||
.setNotificationDataUri(null)
|
||||
.setMessagesCount(0)
|
||||
// Reset missed calls category.
|
||||
.setNotificationCategory(null)
|
||||
.build();
|
||||
|
||||
@@ -65,6 +65,7 @@ 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;
|
||||
@@ -119,6 +120,7 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
.setNotificationKey(NOTIFICATION_KEY)
|
||||
.setNotificationContent(NOTIFICATION_CONTENT)
|
||||
.setNotificationDataUri(URI)
|
||||
.setMessagesCount(1)
|
||||
.build();
|
||||
|
||||
private final ShortcutInfo mShortcutInfo = new ShortcutInfo.Builder(mContext,
|
||||
@@ -318,7 +320,7 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastMessagingStyleMessageNoMessage() {
|
||||
public void testGetMessagingStyleMessagesNoMessage() {
|
||||
Notification notification = new Notification.Builder(mContext, "test")
|
||||
.setContentTitle("TEST_TITLE")
|
||||
.setContentText("TEST_TEXT")
|
||||
@@ -328,22 +330,23 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
.setNotification(notification)
|
||||
.build();
|
||||
|
||||
Notification.MessagingStyle.Message lastMessage =
|
||||
PeopleSpaceUtils.getLastMessagingStyleMessage(sbn.getNotification());
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
PeopleSpaceUtils.getMessagingStyleMessages(sbn.getNotification());
|
||||
|
||||
assertThat(lastMessage).isNull();
|
||||
assertThat(ArrayUtils.isEmpty(messages)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastMessagingStyleMessage() {
|
||||
public void testGetMessagingStyleMessages() {
|
||||
StatusBarNotification sbn = new SbnBuilder()
|
||||
.setNotification(mNotification1)
|
||||
.build();
|
||||
|
||||
Notification.MessagingStyle.Message lastMessage =
|
||||
PeopleSpaceUtils.getLastMessagingStyleMessage(sbn.getNotification());
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
PeopleSpaceUtils.getMessagingStyleMessages(sbn.getNotification());
|
||||
|
||||
assertThat(lastMessage.getText().toString()).isEqualTo(NOTIFICATION_TEXT_2);
|
||||
assertThat(messages.size()).isEqualTo(3);
|
||||
assertThat(messages.get(0).getText().toString()).isEqualTo(NOTIFICATION_TEXT_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -467,6 +467,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
assertEquals(View.VISIBLE,
|
||||
smallResult.findViewById(R.id.person_icon).getVisibility());
|
||||
|
||||
// Has a single message, no count shown.
|
||||
assertEquals(View.GONE, result.findViewById(R.id.messages_count).getVisibility());
|
||||
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
@@ -491,6 +494,36 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
assertThat(statusContent.getMaxLines()).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateRemoteViewsWithNotificationTemplateTwoMessages() {
|
||||
PeopleSpaceTile tileWithStatusAndNotification = PERSON_TILE.toBuilder()
|
||||
.setNotificationDataUri(null)
|
||||
.setStatuses(Arrays.asList(GAME_STATUS,
|
||||
NEW_STORY_WITH_AVAILABILITY))
|
||||
.setMessagesCount(2).build();
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
TextView name = (TextView) result.findViewById(R.id.name);
|
||||
assertEquals(name.getText(), NAME);
|
||||
TextView subtext = (TextView) result.findViewById(R.id.subtext);
|
||||
assertEquals(View.GONE, subtext.getVisibility());
|
||||
// Has availability.
|
||||
View availability = result.findViewById(R.id.availability);
|
||||
assertEquals(View.VISIBLE, availability.getVisibility());
|
||||
// Has person icon.
|
||||
View personIcon = result.findViewById(R.id.person_icon);
|
||||
assertEquals(View.VISIBLE, personIcon.getVisibility());
|
||||
// Has notification content.
|
||||
TextView statusContent = (TextView) result.findViewById(R.id.text_content);
|
||||
assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
|
||||
|
||||
// Has 2 messages, show count.
|
||||
assertEquals(View.VISIBLE, result.findViewById(R.id.messages_count).getVisibility());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetBackgroundTextFromMessageNoPunctuation() {
|
||||
String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test");
|
||||
|
||||
Reference in New Issue
Block a user