A status may still be shown on the view (for example, as a new story ring) even if it's
- * not valid to compose an entire view.
- */
- private static boolean isStatusValidForEntireStatusView(ConversationStatus status) {
- switch (status.getActivity()) {
- // Birthday & Anniversary don't require text provided or icon provided.
- case ACTIVITY_BIRTHDAY:
- case ACTIVITY_ANNIVERSARY:
- return true;
- default:
- // For future birthday, location, new story, video, music, game, and other, the
- // app must provide either text or an icon.
- return !TextUtils.isEmpty(status.getDescription())
- || status.getIcon() != null;
- }
- }
-
- private static RemoteViews createStatusRemoteViews(Context context, ConversationStatus status,
- int layoutSize) {
- int layout = layoutSize == SMALL_LAYOUT ? R.layout.people_space_small_view
- : R.layout.people_space_small_avatar_tile;
- RemoteViews views = new RemoteViews(context.getPackageName(), layout);
- CharSequence statusText = status.getDescription();
- if (TextUtils.isEmpty(statusText)) {
- statusText = getStatusTextByType(context, status.getActivity());
- }
- views.setViewVisibility(R.id.subtext, View.GONE);
- views.setViewVisibility(R.id.text_content, View.VISIBLE);
- TypedValue typedValue = new TypedValue();
- context.getTheme().resolveAttribute(android.R.attr.textColorSecondary, typedValue, true);
- int secondaryTextColor = context.getColor(typedValue.resourceId);
- views.setInt(R.id.text_content, "setTextColor", secondaryTextColor);
- views.setTextViewText(R.id.text_content, statusText);
- Icon statusIcon = status.getIcon();
- if (statusIcon != null) {
- views.setImageViewIcon(R.id.image, statusIcon);
- views.setBoolean(R.id.content_background, "setClipToOutline", true);
- } else {
- views.setViewVisibility(R.id.content_background, View.GONE);
- }
- // TODO: Set status pre-defined icons
- views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_person);
- ensurePredefinedIconVisibleOnSmallView(views, layoutSize);
- return views;
- }
-
- private static String getStatusTextByType(Context context, int activity) {
- switch (activity) {
- case ACTIVITY_BIRTHDAY:
- return context.getString(R.string.birthday_status);
- case ACTIVITY_UPCOMING_BIRTHDAY:
- return context.getString(R.string.upcoming_birthday_status);
- case ACTIVITY_ANNIVERSARY:
- return context.getString(R.string.anniversary_status);
- case ACTIVITY_LOCATION:
- return context.getString(R.string.location_status);
- case ACTIVITY_NEW_STORY:
- return context.getString(R.string.new_story_status);
- case ACTIVITY_VIDEO:
- return context.getString(R.string.video_status);
- case ACTIVITY_AUDIO:
- return context.getString(R.string.audio_status);
- case ACTIVITY_GAME:
- return context.getString(R.string.game_status);
- default:
- return EMPTY_STRING;
- }
- }
-
- private static RemoteViews setCommonRemoteViewsFields(Context context, RemoteViews views,
- PeopleSpaceTile tile, int maxAvatarSize) {
- try {
- boolean isAvailable =
- tile.getStatuses() != null && tile.getStatuses().stream().anyMatch(
- c -> c.getAvailability() == AVAILABILITY_AVAILABLE);
- if (isAvailable) {
- views.setViewVisibility(R.id.availability, View.VISIBLE);
- } else {
- views.setViewVisibility(R.id.availability, View.GONE);
- }
- boolean hasNewStory =
- tile.getStatuses() != null && tile.getStatuses().stream().anyMatch(
- c -> c.getActivity() == ACTIVITY_NEW_STORY);
- views.setTextViewText(R.id.name, tile.getUserName().toString());
- views.setBoolean(R.id.content_background, "setClipToOutline", true);
- Icon icon = tile.getUserIcon();
- PeopleStoryIconFactory storyIcon = new PeopleStoryIconFactory(context,
- context.getPackageManager(),
- IconDrawableFactory.newInstance(context, false),
- maxAvatarSize);
- Drawable drawable = icon.loadDrawable(context);
- Drawable personDrawable = storyIcon.getPeopleTileDrawable(drawable,
- tile.getPackageName(), getUserId(tile), tile.isImportantConversation(),
- hasNewStory);
- Bitmap bitmap = convertDrawableToBitmap(personDrawable);
- views.setImageViewBitmap(R.id.person_icon, bitmap);
-
- return views;
- } catch (Exception e) {
- Log.e(TAG, "Failed to set common fields: " + e);
- }
- return views;
- }
-
- private static RemoteViews setLaunchIntents(Context context, RemoteViews views,
- PeopleSpaceTile tile, int appWidgetId) {
- try {
- 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_USER_HANDLE,
- tile.getUserHandle());
- activityIntent.putExtra(
- PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY, tile.getNotificationKey());
- views.setOnClickPendingIntent(R.id.item, PendingIntent.getActivity(
- context,
- appWidgetId,
- activityIntent,
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE));
- return views;
- } catch (Exception e) {
- Log.e(TAG, "Failed to add launch intents: " + e);
- }
-
- return views;
- }
-
- private static RemoteViews createMissedCallRemoteViews(Context context,
- PeopleSpaceTile tile, int layoutSize) {
- int layout = layoutSize == SMALL_LAYOUT ? R.layout.people_space_small_view
- : R.layout.people_space_small_avatar_tile;
- RemoteViews views = new RemoteViews(context.getPackageName(), layout);
- views.setViewVisibility(R.id.subtext, View.GONE);
- views.setViewVisibility(R.id.text_content, View.VISIBLE);
- views.setTextViewText(R.id.text_content, tile.getNotificationContent());
- views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_phone_missed);
- ensurePredefinedIconVisibleOnSmallView(views, layoutSize);
- views.setBoolean(R.id.content_background, "setClipToOutline", true);
- return views;
- }
-
- private static void ensurePredefinedIconVisibleOnSmallView(RemoteViews views, int layoutSize) {
- if (layoutSize == SMALL_LAYOUT) {
- views.setViewVisibility(R.id.name, View.GONE);
- views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
- }
- }
-
- private static RemoteViews createNotificationRemoteViews(Context context,
- PeopleSpaceTile tile, int layoutSize) {
- int layout = layoutSize == SMALL_LAYOUT ? R.layout.people_space_small_view
- : R.layout.people_space_small_avatar_tile;
- RemoteViews views = new RemoteViews(context.getPackageName(), layout);
- if (layoutSize != MEDIUM_LAYOUT) {
- views.setViewVisibility(R.id.name, View.GONE);
- views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
- }
- Uri image = tile.getNotificationDataUri();
- ensurePredefinedIconVisibleOnSmallView(views, layoutSize);
- if (image != null) {
- // TODO: Use NotificationInlineImageCache
- views.setImageViewUri(R.id.image, image);
- views.setViewVisibility(R.id.content_background, View.VISIBLE);
- views.setBoolean(R.id.content_background, "setClipToOutline", true);
- views.setViewVisibility(R.id.text_content, View.GONE);
- views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_photo_camera);
- } else {
- CharSequence content = tile.getNotificationContent();
- views = setPunctuationRemoteViewsFields(views, content);
- views.setTextViewText(R.id.text_content, tile.getNotificationContent());
- // TODO: Measure max lines from height.
- views.setInt(R.id.text_content, "setMaxLines", 2);
- TypedValue typedValue = new TypedValue();
- context.getTheme().resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
- int primaryTextColor = context.getColor(typedValue.resourceId);
- views.setInt(R.id.text_content, "setTextColor", primaryTextColor);
- views.setViewVisibility(R.id.text_content, View.VISIBLE);
- views.setViewVisibility(R.id.content_background, View.GONE);
- views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_message);
- }
- // TODO: Set subtext as Group Sender name once storing the name in PeopleSpaceTile.
- views.setViewVisibility(R.id.subtext, View.GONE);
- return views;
- }
-
- private static RemoteViews createLastInteractionRemoteViews(Context context,
- PeopleSpaceTile tile, int layoutSize) {
- int layout = layoutSize == SMALL_LAYOUT ? R.layout.people_space_small_view
- : R.layout.people_space_large_avatar_tile;
- RemoteViews views = new RemoteViews(context.getPackageName(), layout);
- if (layoutSize == SMALL_LAYOUT) {
- views.setViewVisibility(R.id.name, View.VISIBLE);
- views.setViewVisibility(R.id.predefined_icon, View.GONE);
- }
- String status = PeopleSpaceUtils.getLastInteractionString(
- context, tile.getLastInteractionTimestamp());
- views.setTextViewText(R.id.last_interaction, status);
- return views;
- }
-
- private static RemoteViews setPunctuationRemoteViewsFields(
- RemoteViews views, CharSequence content) {
- String punctuation = getBackgroundTextFromMessage(content.toString());
- int visibility = View.GONE;
- if (punctuation != null) {
- visibility = View.VISIBLE;
- }
- views.setTextViewText(R.id.punctuation1, punctuation);
- views.setTextViewText(R.id.punctuation2, punctuation);
- views.setTextViewText(R.id.punctuation3, punctuation);
- views.setTextViewText(R.id.punctuation4, punctuation);
- views.setTextViewText(R.id.punctuation5, punctuation);
- views.setTextViewText(R.id.punctuation6, punctuation);
-
- views.setViewVisibility(R.id.punctuation1, visibility);
- views.setViewVisibility(R.id.punctuation2, visibility);
- views.setViewVisibility(R.id.punctuation3, visibility);
- views.setViewVisibility(R.id.punctuation4, visibility);
- views.setViewVisibility(R.id.punctuation5, visibility);
- views.setViewVisibility(R.id.punctuation6, visibility);
-
- return views;
- }
-
- /** Gets character for tile background decoration based on notification content. */
- @VisibleForTesting
- static String getBackgroundTextFromMessage(String message) {
- if (!ANY_DOUBLE_MARK_PATTERN.matcher(message).find()) {
- return null;
- }
- if (MIXED_MARK_PATTERN.matcher(message).find()) {
- return "!?";
- }
- Matcher doubleQuestionMatcher = DOUBLE_QUESTION_PATTERN.matcher(message);
- if (!doubleQuestionMatcher.find()) {
- return "!";
- }
- Matcher doubleExclamationMatcher = DOUBLE_EXCLAMATION_PATTERN.matcher(message);
- if (!doubleExclamationMatcher.find()) {
- return "?";
- }
- // If we have both "!!" and "??", return the one that comes first.
- if (doubleQuestionMatcher.start() < doubleExclamationMatcher.start()) {
- return "?";
- }
- return "!";
- }
-
/** Gets the most recent {@link Notification.MessagingStyle.Message} from the notification. */
@VisibleForTesting
public static Notification.MessagingStyle.Message getLastMessagingStyleMessage(
@@ -917,7 +521,8 @@ public class PeopleSpaceUtils {
public static void updateAppWidgetViews(AppWidgetManager appWidgetManager,
Context context, int appWidgetId, PeopleSpaceTile tile, Bundle options) {
if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName());
- RemoteViews views = createRemoteViews(context, tile, appWidgetId, options);
+ RemoteViews views = new PeopleTileViewHelper(context, tile, appWidgetId,
+ options).getViews();
// Tell the AppWidgetManager to perform an update on the current app widget.
appWidgetManager.updateAppWidget(appWidgetId, views);
@@ -1005,7 +610,7 @@ public class PeopleSpaceUtils {
if (DEBUG) Log.i(TAG, "Returning tile preview for shortcutId: " + shortcutId);
Bundle bundle = new Bundle();
- return PeopleSpaceUtils.createRemoteViews(context, augmentedTile, 0, bundle);
+ return new PeopleTileViewHelper(context, augmentedTile, 0, bundle).getViews();
}
/** Returns the userId associated with a {@link PeopleSpaceTile} */
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
new file mode 100644
index 0000000000000..ae81ab04ec101
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -0,0 +1,553 @@
+/*
+ * 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 android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
+import static android.app.people.ConversationStatus.ACTIVITY_AUDIO;
+import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
+import static android.app.people.ConversationStatus.ACTIVITY_GAME;
+import static android.app.people.ConversationStatus.ACTIVITY_LOCATION;
+import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
+import static android.app.people.ConversationStatus.ACTIVITY_UPCOMING_BIRTHDAY;
+import static android.app.people.ConversationStatus.ACTIVITY_VIDEO;
+import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
+
+import static com.android.systemui.people.PeopleSpaceUtils.convertDrawableToBitmap;
+import static com.android.systemui.people.PeopleSpaceUtils.getUserId;
+
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.app.people.ConversationStatus;
+import android.app.people.PeopleSpaceTile;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.IconDrawableFactory;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.RemoteViews;
+import android.widget.TextView;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
+import com.android.systemui.people.widget.LaunchConversationActivity;
+import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+class PeopleTileViewHelper {
+ /** Turns on debugging information about People Space. */
+ public static final boolean DEBUG = true;
+ private static final String TAG = "PeopleTileView";
+
+ public static final int LAYOUT_SMALL = 0;
+ public static final int LAYOUT_MEDIUM = 1;
+ public static final int LAYOUT_LARGE = 2;
+
+ private static final int MIN_CONTENT_MAX_LINES = 2;
+
+ private static final int FIXED_HEIGHT_DIMENS_FOR_LARGE_CONTENT = 14 + 12 + 4 + 16;
+ private static final int FIXED_HEIGHT_DIMENS_FOR_MEDIUM_CONTENT = 8 + 4 + 4 + 8;
+ 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 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("[!?][!?]+");
+ private static final Pattern MIXED_MARK_PATTERN = Pattern.compile("![?].*|.*[?]!");
+
+ public static final String EMPTY_STRING = "";
+
+ private Context mContext;
+ private PeopleSpaceTile mTile;
+ private float mDensity;
+ private int mAppWidgetId;
+ private int mWidth;
+ private int mHeight;
+ private int mLayoutSize;
+
+ PeopleTileViewHelper(Context context, PeopleSpaceTile tile,
+ int appWidgetId, Bundle options) {
+ mContext = context;
+ mTile = tile;
+ mAppWidgetId = appWidgetId;
+ mDensity = mContext.getResources().getDisplayMetrics().density;
+ int display = mContext.getResources().getConfiguration().orientation;
+ mWidth = display == Configuration.ORIENTATION_PORTRAIT
+ ? options.getInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.default_width)) : options.getInt(
+ OPTION_APPWIDGET_MAX_WIDTH,
+ getSizeInDp(R.dimen.default_width));
+ mHeight = display == Configuration.ORIENTATION_PORTRAIT ? options.getInt(
+ OPTION_APPWIDGET_MAX_HEIGHT,
+ getSizeInDp(R.dimen.default_height))
+ : options.getInt(OPTION_APPWIDGET_MIN_HEIGHT,
+ getSizeInDp(R.dimen.default_height));
+ mLayoutSize = getLayoutSize();
+ }
+
+ public RemoteViews getViews() {
+ RemoteViews viewsForTile = getViewForTile();
+ int maxAvatarSize = getMaxAvatarSize(viewsForTile);
+ RemoteViews views = setCommonRemoteViewsFields(viewsForTile, maxAvatarSize);
+ return setLaunchIntents(views);
+ }
+
+ /**
+ * The prioritization for the {@code mTile} content is missed calls, followed by notification
+ * content, then birthdays, then the most recent status, and finally last interaction.
+ */
+ private RemoteViews getViewForTile() {
+ if (Objects.equals(mTile.getNotificationCategory(), CATEGORY_MISSED_CALL)) {
+ if (DEBUG) Log.d(TAG, "Create missed call view");
+ return createMissedCallRemoteViews();
+ }
+
+ if (mTile.getNotificationKey() != null) {
+ if (DEBUG) Log.d(TAG, "Create notification view");
+ return createNotificationRemoteViews();
+ }
+
+ // TODO: Add sorting when we expose timestamp of statuses.
+ List A status may still be shown on the view (for example, as a new story ring) even if it's
+ * not valid to compose an entire view.
+ */
+ private boolean isStatusValidForEntireStatusView(ConversationStatus status) {
+ switch (status.getActivity()) {
+ // Birthday & Anniversary don't require text provided or icon provided.
+ case ACTIVITY_BIRTHDAY:
+ case ACTIVITY_ANNIVERSARY:
+ return true;
+ default:
+ // For future birthday, location, new story, video, music, game, and other, the
+ // app must provide either text or an icon.
+ return !TextUtils.isEmpty(status.getDescription())
+ || status.getIcon() != null;
+ }
+ }
+
+ private String getStatusTextByType(int activity) {
+ switch (activity) {
+ case ACTIVITY_BIRTHDAY:
+ return mContext.getString(R.string.birthday_status);
+ case ACTIVITY_UPCOMING_BIRTHDAY:
+ return mContext.getString(R.string.upcoming_birthday_status);
+ case ACTIVITY_ANNIVERSARY:
+ return mContext.getString(R.string.anniversary_status);
+ case ACTIVITY_LOCATION:
+ return mContext.getString(R.string.location_status);
+ case ACTIVITY_NEW_STORY:
+ return mContext.getString(R.string.new_story_status);
+ case ACTIVITY_VIDEO:
+ return mContext.getString(R.string.video_status);
+ case ACTIVITY_AUDIO:
+ return mContext.getString(R.string.audio_status);
+ case ACTIVITY_GAME:
+ return mContext.getString(R.string.game_status);
+ default:
+ return EMPTY_STRING;
+ }
+ }
+
+ private RemoteViews setPunctuationRemoteViewsFields(
+ RemoteViews views, CharSequence content) {
+ String punctuation = getBackgroundTextFromMessage(content.toString());
+ int visibility = View.GONE;
+ if (punctuation != null) {
+ visibility = View.VISIBLE;
+ }
+ views.setTextViewText(R.id.punctuation1, punctuation);
+ views.setTextViewText(R.id.punctuation2, punctuation);
+ views.setTextViewText(R.id.punctuation3, punctuation);
+ views.setTextViewText(R.id.punctuation4, punctuation);
+ views.setTextViewText(R.id.punctuation5, punctuation);
+ views.setTextViewText(R.id.punctuation6, punctuation);
+
+ views.setViewVisibility(R.id.punctuation1, visibility);
+ views.setViewVisibility(R.id.punctuation2, visibility);
+ views.setViewVisibility(R.id.punctuation3, visibility);
+ views.setViewVisibility(R.id.punctuation4, visibility);
+ views.setViewVisibility(R.id.punctuation5, visibility);
+ views.setViewVisibility(R.id.punctuation6, visibility);
+
+ return views;
+ }
+
+ /** Gets character for mTile background decoration based on notification content. */
+ @VisibleForTesting
+ String getBackgroundTextFromMessage(String message) {
+ if (!ANY_DOUBLE_MARK_PATTERN.matcher(message).find()) {
+ return null;
+ }
+ if (MIXED_MARK_PATTERN.matcher(message).find()) {
+ return "!?";
+ }
+ Matcher doubleQuestionMatcher = DOUBLE_QUESTION_PATTERN.matcher(message);
+ if (!doubleQuestionMatcher.find()) {
+ return "!";
+ }
+ Matcher doubleExclamationMatcher = DOUBLE_EXCLAMATION_PATTERN.matcher(message);
+ if (!doubleExclamationMatcher.find()) {
+ return "?";
+ }
+ // If we have both "!!" and "??", return the one that comes first.
+ if (doubleQuestionMatcher.start() < doubleExclamationMatcher.start()) {
+ return "?";
+ }
+ return "!";
+ }
+
+ private RemoteViews getViewForContentLayout() {
+ RemoteViews views = new RemoteViews(mContext.getPackageName(),
+ getLayoutForContent());
+ if (mLayoutSize == LAYOUT_SMALL) {
+ views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
+ views.setViewVisibility(R.id.name, View.GONE);
+ } else {
+ views.setViewVisibility(R.id.predefined_icon, View.GONE);
+ views.setViewVisibility(R.id.name, View.VISIBLE);
+ views.setViewVisibility(R.id.text_content, View.VISIBLE);
+ views.setViewVisibility(R.id.subtext, View.GONE);
+ }
+ return views;
+ }
+
+ private RemoteViews createLastInteractionRemoteViews() {
+ RemoteViews views = new RemoteViews(mContext.getPackageName(), getEmptyLayout());
+ if (mLayoutSize == LAYOUT_SMALL) {
+ views.setViewVisibility(R.id.name, View.VISIBLE);
+ views.setViewVisibility(R.id.predefined_icon, View.GONE);
+ }
+ String status = PeopleSpaceUtils.getLastInteractionString(mContext,
+ mTile.getLastInteractionTimestamp());
+ views.setTextViewText(R.id.last_interaction, status);
+ return views;
+ }
+
+ private int getEmptyLayout() {
+ switch (mLayoutSize) {
+ case LAYOUT_MEDIUM:
+ return R.layout.people_tile_medium_empty;
+ case LAYOUT_LARGE:
+ return R.layout.people_tile_large_empty;
+ case LAYOUT_SMALL:
+ default:
+ return R.layout.people_tile_small;
+ }
+ }
+
+ private int getLayoutForContent() {
+ switch (mLayoutSize) {
+ case LAYOUT_MEDIUM:
+ return R.layout.people_tile_medium_with_content;
+ case LAYOUT_LARGE:
+ return R.layout.people_tile_large_with_content;
+ case LAYOUT_SMALL:
+ default:
+ return R.layout.people_tile_small;
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
index ee98a591c8a03..1c7a84a364046 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
@@ -16,20 +16,11 @@
package com.android.systemui.people;
-import static android.app.Notification.CATEGORY_MISSED_CALL;
-import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
-import static android.app.people.ConversationStatus.ACTIVITY_GAME;
-import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
-import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
-import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
-
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
-import static com.android.systemui.people.PeopleSpaceUtils.REQUIRED_WIDTH_FOR_MEDIUM;
import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -48,7 +39,6 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Person;
import android.app.people.ConversationChannel;
-import android.app.people.ConversationStatus;
import android.app.people.IPeopleManager;
import android.app.people.PeopleSpaceTile;
import android.appwidget.AppWidgetManager;
@@ -70,9 +60,7 @@ import android.provider.ContactsContract;
import android.service.notification.ConversationChannelWrapper;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
-import android.view.View;
-import android.widget.RemoteViews;
-import android.widget.TextView;
+import android.util.DisplayMetrics;
import androidx.test.filters.SmallTest;
@@ -117,8 +105,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
private static final int TEST_COLUMN_INDEX = 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 String GAME_DESCRIPTION = "Playing a game!";
- private static final CharSequence MISSED_CALL = "Custom missed call message";
private static final String NAME = "username";
private static final Person PERSON = new Person.Builder()
.setName("name")
@@ -126,11 +112,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
.setUri(URI.toString())
.setBot(false)
.build();
- private static final PeopleSpaceTile PERSON_TILE_WITHOUT_NOTIFICATION =
- new PeopleSpaceTile
- .Builder(SHORTCUT_ID_1, NAME, ICON, new Intent())
- .setLastInteractionTimestamp(0L)
- .build();
private static final PeopleSpaceTile PERSON_TILE =
new PeopleSpaceTile
.Builder(SHORTCUT_ID_1, NAME, ICON, new Intent())
@@ -139,16 +120,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
.setNotificationContent(NOTIFICATION_CONTENT)
.setNotificationDataUri(URI)
.build();
- private static final ConversationStatus GAME_STATUS =
- new ConversationStatus
- .Builder(PERSON_TILE.getId(), ACTIVITY_GAME)
- .setDescription(GAME_DESCRIPTION)
- .build();
- private static final ConversationStatus NEW_STORY_WITH_AVAILABILITY =
- new ConversationStatus
- .Builder(PERSON_TILE.getId(), ACTIVITY_NEW_STORY)
- .setAvailability(AVAILABILITY_AVAILABLE)
- .build();
private final ShortcutInfo mShortcutInfo = new ShortcutInfo.Builder(mContext,
SHORTCUT_ID_1).setLongLabel(
@@ -244,6 +215,12 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
.thenReturn(new Bundle());
+ Configuration configuration = mock(Configuration.class);
+ DisplayMetrics displayMetrics = mock(DisplayMetrics.class);
+ Resources resources = mock(Resources.class);
+ when(mMockContext.getResources()).thenReturn(resources);
+ when(resources.getConfiguration()).thenReturn(configuration);
+ when(resources.getDisplayMetrics()).thenReturn(displayMetrics);
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
when(mMockContentResolver.query(any(Uri.class), any(), anyString(), any(),
isNull())).thenReturn(mMockCursor);
@@ -254,10 +231,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
when(mMockContext.getPackageManager()).thenReturn(mPackageManager);
when(mMockContext.getString(R.string.over_timestamp)).thenReturn(
mContext.getString(R.string.over_timestamp));
- Configuration configuration = mock(Configuration.class);
- Resources resources = mock(Resources.class);
- when(mMockContext.getResources()).thenReturn(resources);
- when(resources.getConfiguration()).thenReturn(configuration);
when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null);
when(mNotificationEntryManager.getVisibleNotifications())
.thenReturn(List.of(mNotificationEntry1, mNotificationEntry2, mNotificationEntry3));
@@ -361,95 +334,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
assertThat(lastMessage).isNull();
}
- @Test
- public void testGetBackgroundTextFromMessageNoPunctuation() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test");
-
- assertThat(backgroundText).isNull();
- }
-
- @Test
- public void testGetBackgroundTextFromMessageSingleExclamation() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test!");
-
- assertThat(backgroundText).isNull();
- }
-
- @Test
- public void testGetBackgroundTextFromMessageSingleQuestion() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("?test");
-
- assertThat(backgroundText).isNull();
- }
-
- @Test
- public void testGetBackgroundTextFromMessageSeparatedMarks() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test! right!");
-
- assertThat(backgroundText).isNull();
- }
-
- @Test
- public void testGetBackgroundTextFromMessageDoubleExclamation() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("!!test");
-
- assertThat(backgroundText).isEqualTo("!");
- }
-
- @Test
- public void testGetBackgroundTextFromMessageDoubleQuestion() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test??");
-
- assertThat(backgroundText).isEqualTo("?");
- }
-
- @Test
- public void testGetBackgroundTextFromMessageMixed() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage("test?!");
-
- assertThat(backgroundText).isEqualTo("!?");
- }
-
- @Test
- public void testGetBackgroundTextFromMessageMixedInTheMiddle() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
- "test!? in the middle");
-
- assertThat(backgroundText).isEqualTo("!?");
- }
-
- @Test
- public void testGetBackgroundTextFromMessageMixedDifferentOrder() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
- "test!? in the middle");
-
- assertThat(backgroundText).isEqualTo("!?");
- }
-
- @Test
- public void testGetBackgroundTextFromMessageMultiple() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
- "test!?!!? in the middle");
-
- assertThat(backgroundText).isEqualTo("!?");
- }
-
- @Test
- public void testGetBackgroundTextFromMessageQuestionFirst() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
- "test?? in the middle!!");
-
- assertThat(backgroundText).isEqualTo("?");
- }
-
- @Test
- public void testGetBackgroundTextFromMessageExclamationFirst() {
- String backgroundText = PeopleSpaceUtils.getBackgroundTextFromMessage(
- "test!! in the middle??");
-
- assertThat(backgroundText).isEqualTo("!");
- }
-
@Test
public void testGetLastMessagingStyleMessage() {
StatusBarNotification sbn = new SbnBuilder()
@@ -687,225 +571,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
any());
}
- @Test
- public void testCreateRemoteViewsWithLastInteractionTime() {
- RemoteViews views = PeopleSpaceUtils.createRemoteViews(mMockContext,
- PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions);
- View result = views.apply(mContext, null);
-
- TextView name = (TextView) result.findViewById(R.id.name);
- assertEquals(name.getText(), NAME);
- // Has last interaction.
- TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
- assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
- // No availability.
- View availability = result.findViewById(R.id.availability);
- assertEquals(View.GONE, availability.getVisibility());
- // Shows person icon.
- View personIcon = result.findViewById(R.id.person_icon);
- assertEquals(View.VISIBLE, personIcon.getVisibility());
- // No status.
- assertThat((View) result.findViewById(R.id.text_content)).isNull();
-
- mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
- RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
- PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions);
- View smallResult = smallView.apply(mContext, null);
-
- // Show name over predefined icon.
- assertEquals(View.VISIBLE, smallResult.findViewById(R.id.name).getVisibility());
- assertEquals(View.GONE, smallResult.findViewById(R.id.predefined_icon).getVisibility());
- // Shows person icon.
- assertEquals(View.VISIBLE, smallResult.findViewById(R.id.person_icon).getVisibility());
- }
-
- @Test
- public void testCreateRemoteViewsWithGameTypeOnlyIsIgnored() {
- PeopleSpaceTile tileWithAvailabilityAndNewStory =
- PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
- Arrays.asList(NEW_STORY_WITH_AVAILABILITY,
- new ConversationStatus.Builder(
- PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
- ACTIVITY_GAME).build())).build();
- RemoteViews views = PeopleSpaceUtils.createRemoteViews(mMockContext,
- tileWithAvailabilityAndNewStory, 0, mOptions);
- View result = views.apply(mContext, null);
-
- TextView name = (TextView) result.findViewById(R.id.name);
- assertEquals(name.getText(), NAME);
- // Has last interaction over status.
- TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
- assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
- // 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());
- // No status.
- assertThat((View) result.findViewById(R.id.text_content)).isNull();
-
- mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
- RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
- tileWithAvailabilityAndNewStory, 0, mOptions);
- View smallResult = smallView.apply(mContext, null);
-
- // Show name rather than game type.
- assertEquals(View.VISIBLE, smallResult.findViewById(R.id.name).getVisibility());
- assertEquals(View.GONE, smallResult.findViewById(R.id.predefined_icon).getVisibility());
- // Has person icon.
- assertEquals(View.VISIBLE,
- smallResult.findViewById(R.id.person_icon).getVisibility());
- }
-
- @Test
- public void testCreateRemoteViewsWithBirthdayTypeOnlyIsNotIgnored() {
- PeopleSpaceTile tileWithStatusTemplate =
- PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
- Arrays.asList(
- NEW_STORY_WITH_AVAILABILITY, new ConversationStatus.Builder(
- PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
- ACTIVITY_BIRTHDAY).build())).build();
- RemoteViews views = PeopleSpaceUtils.createRemoteViews(mContext,
- tileWithStatusTemplate, 0, mOptions);
- View result = views.apply(mContext, null);
-
- TextView name = (TextView) result.findViewById(R.id.name);
- assertEquals(name.getText(), NAME);
- // 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 status text from backup text.
- TextView statusContent = (TextView) result.findViewById(R.id.text_content);
- assertEquals(statusContent.getText(), mContext.getString(R.string.birthday_status));
-
- mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
- RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
- tileWithStatusTemplate, 0, mOptions);
- View smallResult = smallView.apply(mContext, null);
-
- // Show icon instead of name.
- assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
- assertEquals(View.VISIBLE,
- smallResult.findViewById(R.id.predefined_icon).getVisibility());
- // Has person icon.
- assertEquals(View.VISIBLE,
- smallResult.findViewById(R.id.person_icon).getVisibility());
- }
-
- @Test
- public void testCreateRemoteViewsWithStatusTemplate() {
- PeopleSpaceTile tileWithStatusTemplate =
- PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
- Arrays.asList(GAME_STATUS,
- NEW_STORY_WITH_AVAILABILITY)).build();
- RemoteViews views = PeopleSpaceUtils.createRemoteViews(mContext,
- tileWithStatusTemplate, 0, mOptions);
- View result = views.apply(mContext, null);
-
- TextView name = (TextView) result.findViewById(R.id.name);
- assertEquals(name.getText(), NAME);
- // 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 status.
- TextView statusContent = (TextView) result.findViewById(R.id.text_content);
- assertEquals(statusContent.getText(), GAME_DESCRIPTION);
-
- mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
- RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
- tileWithStatusTemplate, 0, mOptions);
- View smallResult = smallView.apply(mContext, null);
-
- // Show icon instead of name.
- assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
- assertEquals(View.VISIBLE,
- smallResult.findViewById(R.id.predefined_icon).getVisibility());
- // Has person icon.
- assertEquals(View.VISIBLE,
- smallResult.findViewById(R.id.person_icon).getVisibility());
- }
-
- @Test
- public void testCreateRemoteViewsWithMissedCallNotification() {
- PeopleSpaceTile tileWithMissedCallNotification = PERSON_TILE.toBuilder()
- .setNotificationDataUri(null)
- .setNotificationCategory(CATEGORY_MISSED_CALL)
- .setNotificationContent(MISSED_CALL)
- .build();
- RemoteViews views = PeopleSpaceUtils.createRemoteViews(mContext,
- tileWithMissedCallNotification, 0, mOptions);
- View result = views.apply(mContext, null);
-
- TextView name = (TextView) result.findViewById(R.id.name);
- assertEquals(name.getText(), NAME);
- // Has availability.
- View availability = result.findViewById(R.id.availability);
- assertEquals(View.GONE, availability.getVisibility());
- // Has person icon.
- View personIcon = result.findViewById(R.id.person_icon);
- assertEquals(View.VISIBLE, personIcon.getVisibility());
- // Has missed call notification content.
- TextView statusContent = (TextView) result.findViewById(R.id.text_content);
- assertEquals(statusContent.getText(), MISSED_CALL);
-
- mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
- RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
- tileWithMissedCallNotification, 0, mOptions);
- View smallResult = smallView.apply(mContext, null);
-
- // Show icon instead of name.
- assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
- assertEquals(View.VISIBLE,
- smallResult.findViewById(R.id.predefined_icon).getVisibility());
- // Has person icon.
- assertEquals(View.VISIBLE, smallResult.findViewById(R.id.person_icon).getVisibility());
- }
-
- @Test
- public void testCreateRemoteViewsWithNotificationTemplate() {
- PeopleSpaceTile tileWithStatusAndNotification = PERSON_TILE.toBuilder()
- .setNotificationDataUri(null)
- .setStatuses(Arrays.asList(GAME_STATUS,
- NEW_STORY_WITH_AVAILABILITY)).build();
- RemoteViews views = PeopleSpaceUtils.createRemoteViews(mContext,
- tileWithStatusAndNotification, 0, mOptions);
- 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);
-
- mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, REQUIRED_WIDTH_FOR_MEDIUM - 1);
- RemoteViews smallView = PeopleSpaceUtils.createRemoteViews(mContext,
- tileWithStatusAndNotification, 0, mOptions);
- View smallResult = smallView.apply(mContext, null);
-
- // Show icon instead of name.
- assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
- assertEquals(View.VISIBLE,
- smallResult.findViewById(R.id.predefined_icon).getVisibility());
- // Has person icon.
- assertEquals(View.VISIBLE,
- smallResult.findViewById(R.id.person_icon).getVisibility());
- }
-
private ConversationChannelWrapper getConversationChannelWrapper(String shortcutId,
boolean importantConversation, long lastInteractionTimestamp) throws Exception {
ConversationChannelWrapper convo = new ConversationChannelWrapper();
@@ -931,13 +596,4 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
eq(shortcutId))).thenReturn(lastInteractionTimestamp);
return convo;
}
-
- private ConversationChannel getConversationChannelWithoutTimestamp(String shortcutId)
- throws Exception {
- ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
- "name").build();
- ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
- 0L, false);
- return convo;
- }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
new file mode 100644
index 0000000000000..39bf060507419
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
@@ -0,0 +1,587 @@
+/*
+ * 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 android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
+import static android.app.people.ConversationStatus.ACTIVITY_GAME;
+import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
+import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
+import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
+
+import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.people.ConversationStatus;
+import android.app.people.PeopleSpaceTile;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Bundle;
+import android.testing.AndroidTestingRunner;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.widget.RemoteViews;
+import android.widget.TextView;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Arrays;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class PeopleTileViewHelperTest extends SysuiTestCase {
+
+ private static final String SHORTCUT_ID_1 = "101";
+ private static final String NOTIFICATION_KEY = "notification_key";
+ private static final String NOTIFICATION_CONTENT = "notification_content";
+ private static final Uri URI = Uri.parse("fake_uri");
+ private static final Icon ICON = Icon.createWithResource("package", R.drawable.ic_android);
+ private static final String GAME_DESCRIPTION = "Playing a game!";
+ private static final CharSequence MISSED_CALL = "Custom missed call message";
+ private static final String NAME = "username";
+ private static final PeopleSpaceTile PERSON_TILE_WITHOUT_NOTIFICATION =
+ new PeopleSpaceTile
+ .Builder(SHORTCUT_ID_1, NAME, ICON, new Intent())
+ .setLastInteractionTimestamp(0L)
+ .build();
+ private static final PeopleSpaceTile PERSON_TILE =
+ new PeopleSpaceTile
+ .Builder(SHORTCUT_ID_1, NAME, ICON, new Intent())
+ .setLastInteractionTimestamp(123L)
+ .setNotificationKey(NOTIFICATION_KEY)
+ .setNotificationContent(NOTIFICATION_CONTENT)
+ .setNotificationDataUri(URI)
+ .build();
+ private static final ConversationStatus GAME_STATUS =
+ new ConversationStatus
+ .Builder(PERSON_TILE.getId(), ACTIVITY_GAME)
+ .setDescription(GAME_DESCRIPTION)
+ .build();
+ private static final ConversationStatus NEW_STORY_WITH_AVAILABILITY =
+ new ConversationStatus
+ .Builder(PERSON_TILE.getId(), ACTIVITY_NEW_STORY)
+ .setAvailability(AVAILABILITY_AVAILABLE)
+ .build();
+
+ @Mock
+ private Context mMockContext;
+ @Mock
+ private PackageManager mPackageManager;
+
+ private Bundle mOptions;
+ private PeopleTileViewHelper mPeopleTileViewHelper;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mOptions = new Bundle();
+ mOptions.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
+
+ when(mMockContext.getString(R.string.birthday_status)).thenReturn(
+ mContext.getString(R.string.birthday_status));
+ when(mMockContext.getString(R.string.basic_status)).thenReturn(
+ mContext.getString(R.string.basic_status));
+ when(mMockContext.getPackageManager()).thenReturn(mPackageManager);
+ when(mMockContext.getString(R.string.over_timestamp)).thenReturn(
+ mContext.getString(R.string.over_timestamp));
+ Configuration configuration = mock(Configuration.class);
+ DisplayMetrics displayMetrics = mock(DisplayMetrics.class);
+ Resources resources = mock(Resources.class);
+ when(mMockContext.getResources()).thenReturn(resources);
+ when(resources.getConfiguration()).thenReturn(configuration);
+ when(resources.getDisplayMetrics()).thenReturn(displayMetrics);
+ TextView textView = mock(TextView.class);
+ // when(new TextView(mMockContext)).thenReturn(textView);
+ when(textView.getLineHeight()).thenReturn(16);
+ when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null);
+ mPeopleTileViewHelper = new PeopleTileViewHelper(mContext,
+ PERSON_TILE, 0, mOptions);
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithLastInteractionTime() {
+ RemoteViews views = new PeopleTileViewHelper(mContext,
+ PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+ View result = views.apply(mContext, null);
+
+ TextView name = (TextView) result.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ // Has last interaction.
+ TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
+ assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+ // No availability.
+ assertEquals(View.GONE, result.findViewById(R.id.availability).getVisibility());
+ // Shows person icon.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+ // No status.
+ assertThat((View) result.findViewById(R.id.text_content)).isNull();
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_medium) - 1);
+ RemoteViews smallView = new PeopleTileViewHelper(mContext,
+ PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+ View smallResult = smallView.apply(mContext, null);
+
+ // Show name over predefined icon.
+ assertEquals(View.VISIBLE, smallResult.findViewById(R.id.name).getVisibility());
+ assertEquals(View.GONE, smallResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Shows person icon.
+ assertEquals(View.VISIBLE, smallResult.findViewById(R.id.person_icon).getVisibility());
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_large));
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_height_for_large));
+ RemoteViews largeView = new PeopleTileViewHelper(mContext,
+ PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+ View largeResult = largeView.apply(mContext, null);
+
+ name = (TextView) largeResult.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ // Has last interaction.
+ lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
+ assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+ // No availability.
+ assertEquals(View.GONE, result.findViewById(R.id.availability).getVisibility());
+ // Shows person icon.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+ // No status.
+ assertThat((View) result.findViewById(R.id.text_content)).isNull();
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithGameTypeOnlyIsIgnored() {
+ PeopleSpaceTile tileWithAvailabilityAndNewStory =
+ PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
+ Arrays.asList(NEW_STORY_WITH_AVAILABILITY,
+ new ConversationStatus.Builder(
+ PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
+ ACTIVITY_GAME).build())).build();
+ RemoteViews views = new PeopleTileViewHelper(mContext,
+ tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
+ View result = views.apply(mContext, null);
+
+ TextView name = (TextView) result.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ // Has last interaction over status.
+ TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
+ assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+ // Has availability.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+ // No status.
+ assertThat((View) result.findViewById(R.id.text_content)).isNull();
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_medium) - 1);
+ RemoteViews smallView = new PeopleTileViewHelper(mContext,
+ tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
+ View smallResult = smallView.apply(mContext, null);
+
+ // Show name rather than game type.
+ assertEquals(View.VISIBLE, smallResult.findViewById(R.id.name).getVisibility());
+ assertEquals(View.GONE, smallResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE,
+ smallResult.findViewById(R.id.person_icon).getVisibility());
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_large));
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_height_for_large));
+ RemoteViews largeView = new PeopleTileViewHelper(mContext,
+ tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
+ View largeResult = largeView.apply(mContext, null);
+
+ name = (TextView) largeResult.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ // Has last interaction.
+ lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
+ assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+ // Has availability.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+ // Shows person icon.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+ // No status.
+ assertThat((View) result.findViewById(R.id.text_content)).isNull();
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithBirthdayTypeOnlyIsNotIgnored() {
+ PeopleSpaceTile tileWithStatusTemplate =
+ PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
+ Arrays.asList(
+ NEW_STORY_WITH_AVAILABILITY, new ConversationStatus.Builder(
+ PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
+ ACTIVITY_BIRTHDAY).build())).build();
+ RemoteViews views = new PeopleTileViewHelper(mContext,
+ tileWithStatusTemplate, 0, mOptions).getViews();
+ View result = views.apply(mContext, null);
+
+ TextView name = (TextView) result.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility());
+ assertEquals(View.VISIBLE, result.findViewById(R.id.predefined_icon).getVisibility());
+ // Has availability.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+ // Has status text from backup text.
+ TextView statusContent = (TextView) result.findViewById(R.id.text_content);
+ assertEquals(View.VISIBLE, statusContent.getVisibility());
+ assertEquals(statusContent.getText(), mContext.getString(R.string.birthday_status));
+ assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_medium) - 1);
+ RemoteViews smallView = new PeopleTileViewHelper(mContext,
+ tileWithStatusTemplate, 0, mOptions).getViews();
+ View smallResult = smallView.apply(mContext, null);
+
+ // Show icon instead of name.
+ assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
+ assertEquals(View.VISIBLE,
+ smallResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE,
+ smallResult.findViewById(R.id.person_icon).getVisibility());
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_large));
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_height_for_large));
+ RemoteViews largeView = new PeopleTileViewHelper(mContext,
+ tileWithStatusTemplate, 0, mOptions).getViews();
+ View largeResult = largeView.apply(mContext, null);
+
+ name = (TextView) largeResult.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility());
+ assertEquals(View.VISIBLE, largeResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Has availability.
+ assertEquals(View.VISIBLE, largeResult.findViewById(R.id.availability).getVisibility());
+ // Has person icon.
+ View personIcon = largeResult.findViewById(R.id.person_icon);
+ assertEquals(View.VISIBLE, personIcon.getVisibility());
+ // Has notification content.
+ statusContent = (TextView) largeResult.findViewById(R.id.text_content);
+ assertEquals(View.VISIBLE, statusContent.getVisibility());
+ assertEquals(statusContent.getText(), mContext.getString(R.string.birthday_status));
+ assertThat(statusContent.getMaxLines()).isEqualTo(3);
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithStatusTemplate() {
+ PeopleSpaceTile tileWithStatusTemplate =
+ PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
+ Arrays.asList(GAME_STATUS,
+ NEW_STORY_WITH_AVAILABILITY)).build();
+ RemoteViews views = new PeopleTileViewHelper(mContext,
+ tileWithStatusTemplate, 0, mOptions).getViews();
+ View result = views.apply(mContext, null);
+
+ TextView name = (TextView) result.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility());
+ assertEquals(View.VISIBLE, result.findViewById(R.id.predefined_icon).getVisibility());
+ // Has availability.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+ // Has status.
+ TextView statusContent = (TextView) result.findViewById(R.id.text_content);
+ assertEquals(statusContent.getText(), GAME_DESCRIPTION);
+ assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_medium) - 1);
+ RemoteViews smallView = new PeopleTileViewHelper(mContext,
+ tileWithStatusTemplate, 0, mOptions).getViews();
+ View smallResult = smallView.apply(mContext, null);
+
+ // Show icon instead of name.
+ assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
+ assertEquals(View.VISIBLE,
+ smallResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE,
+ smallResult.findViewById(R.id.person_icon).getVisibility());
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_large));
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_height_for_large));
+ RemoteViews largeView = new PeopleTileViewHelper(mContext,
+ tileWithStatusTemplate, 0, mOptions).getViews();
+ View largeResult = largeView.apply(mContext, null);
+
+ name = (TextView) largeResult.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility());
+ assertEquals(View.VISIBLE, largeResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Has availability.
+ assertEquals(View.VISIBLE, largeResult.findViewById(R.id.availability).getVisibility());
+ // Has person icon.
+ View personIcon = largeResult.findViewById(R.id.person_icon);
+ assertEquals(View.VISIBLE, personIcon.getVisibility());
+ // Has notification content.
+ statusContent = (TextView) largeResult.findViewById(R.id.text_content);
+ assertEquals(View.VISIBLE, statusContent.getVisibility());
+ assertEquals(statusContent.getText(), GAME_DESCRIPTION);
+ assertThat(statusContent.getMaxLines()).isEqualTo(3);
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithMissedCallNotification() {
+ PeopleSpaceTile tileWithMissedCallNotification = PERSON_TILE.toBuilder()
+ .setNotificationDataUri(null)
+ .setNotificationCategory(CATEGORY_MISSED_CALL)
+ .setNotificationContent(MISSED_CALL)
+ .build();
+ RemoteViews views = new PeopleTileViewHelper(mContext,
+ tileWithMissedCallNotification, 0, mOptions).getViews();
+ View result = views.apply(mContext, null);
+
+ TextView name = (TextView) result.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility());
+ assertEquals(View.VISIBLE, result.findViewById(R.id.predefined_icon).getVisibility());
+ // Has availability.
+ assertEquals(View.GONE, result.findViewById(R.id.availability).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+ // Has missed call notification content.
+ TextView statusContent = (TextView) result.findViewById(R.id.text_content);
+ assertEquals(View.VISIBLE, statusContent.getVisibility());
+ assertEquals(statusContent.getText(), MISSED_CALL);
+ assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_medium) - 1);
+ RemoteViews smallView = new PeopleTileViewHelper(mContext,
+ tileWithMissedCallNotification, 0, mOptions).getViews();
+ View smallResult = smallView.apply(mContext, null);
+
+ // Show icon instead of name.
+ assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
+ assertEquals(View.VISIBLE,
+ smallResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE, smallResult.findViewById(R.id.person_icon).getVisibility());
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_large));
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_height_for_large));
+ RemoteViews largeView = new PeopleTileViewHelper(mContext,
+ tileWithMissedCallNotification, 0, mOptions).getViews();
+ View largeResult = largeView.apply(mContext, null);
+
+ name = (TextView) largeResult.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility());
+ assertEquals(View.VISIBLE, largeResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Has availability.
+ assertEquals(View.GONE, largeResult.findViewById(R.id.availability).getVisibility());
+ // Has person icon.
+ View personIcon = largeResult.findViewById(R.id.person_icon);
+ assertEquals(View.VISIBLE, personIcon.getVisibility());
+ // Has notification content.
+ statusContent = (TextView) largeResult.findViewById(R.id.text_content);
+ assertEquals(View.VISIBLE, statusContent.getVisibility());
+ assertEquals(statusContent.getText(), MISSED_CALL);
+ assertThat(statusContent.getMaxLines()).isEqualTo(3);
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithNotificationTemplate() {
+ PeopleSpaceTile tileWithStatusAndNotification = PERSON_TILE.toBuilder()
+ .setNotificationDataUri(null)
+ .setStatuses(Arrays.asList(GAME_STATUS,
+ NEW_STORY_WITH_AVAILABILITY)).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);
+ assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility());
+ assertEquals(View.GONE, result.findViewById(R.id.predefined_icon).getVisibility());
+ // Has availability.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+ // Has notification content.
+ TextView statusContent = (TextView) result.findViewById(R.id.text_content);
+ assertEquals(View.VISIBLE, statusContent.getVisibility());
+ assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
+ assertThat(statusContent.getMaxLines()).isEqualTo(3);
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_medium) - 1);
+ RemoteViews smallView = new PeopleTileViewHelper(mContext,
+ tileWithStatusAndNotification, 0, mOptions).getViews();
+ View smallResult = smallView.apply(mContext, null);
+
+ // Show icon instead of name.
+ assertEquals(View.GONE, smallResult.findViewById(R.id.name).getVisibility());
+ assertEquals(View.VISIBLE,
+ smallResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Has person icon.
+ assertEquals(View.VISIBLE,
+ smallResult.findViewById(R.id.person_icon).getVisibility());
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_large));
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_height_for_large));
+ RemoteViews largeView = new PeopleTileViewHelper(mContext,
+ tileWithStatusAndNotification, 0, mOptions).getViews();
+ View largeResult = largeView.apply(mContext, null);
+
+ name = (TextView) largeResult.findViewById(R.id.name);
+ assertEquals(name.getText(), NAME);
+ assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility());
+ assertEquals(View.GONE, largeResult.findViewById(R.id.predefined_icon).getVisibility());
+ // Has availability.
+ assertEquals(View.VISIBLE, largeResult.findViewById(R.id.availability).getVisibility());
+ // Has person icon.
+ View personIcon = largeResult.findViewById(R.id.person_icon);
+ assertEquals(View.VISIBLE, personIcon.getVisibility());
+ // Has notification content.
+ statusContent = (TextView) largeResult.findViewById(R.id.text_content);
+ assertEquals(View.VISIBLE, statusContent.getVisibility());
+ assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
+ assertThat(statusContent.getMaxLines()).isEqualTo(3);
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageNoPunctuation() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test");
+
+ assertThat(backgroundText).isNull();
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageSingleExclamation() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test!");
+
+ assertThat(backgroundText).isNull();
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageSingleQuestion() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("?test");
+
+ assertThat(backgroundText).isNull();
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageSeparatedMarks() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test! right!");
+
+ assertThat(backgroundText).isNull();
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageDoubleExclamation() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("!!test");
+
+ assertThat(backgroundText).isEqualTo("!");
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageDoubleQuestion() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test??");
+
+ assertThat(backgroundText).isEqualTo("?");
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageMixed() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage("test?!");
+
+ assertThat(backgroundText).isEqualTo("!?");
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageMixedInTheMiddle() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+ "test!? in the middle");
+
+ assertThat(backgroundText).isEqualTo("!?");
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageMixedDifferentOrder() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+ "test!? in the middle");
+
+ assertThat(backgroundText).isEqualTo("!?");
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageMultiple() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+ "test!?!!? in the middle");
+
+ assertThat(backgroundText).isEqualTo("!?");
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageQuestionFirst() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+ "test?? in the middle!!");
+
+ assertThat(backgroundText).isEqualTo("?");
+ }
+
+ @Test
+ public void testGetBackgroundTextFromMessageExclamationFirst() {
+ String backgroundText = mPeopleTileViewHelper.getBackgroundTextFromMessage(
+ "test!! in the middle??");
+
+ assertThat(backgroundText).isEqualTo("!");
+ }
+
+ private int getSizeInDp(int dimenResourceId) {
+ return (int) (mContext.getResources().getDimension(dimenResourceId)
+ / mContext.getResources().getDisplayMetrics().density);
+ }
+}