diff --git a/packages/SystemUI/res/drawable/ic_cake.xml b/packages/SystemUI/res/drawable/ic_cake.xml
new file mode 100644
index 0000000000000..9c83b43ab057e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_cake.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_celebration.xml b/packages/SystemUI/res/drawable/ic_celebration.xml
new file mode 100644
index 0000000000000..10fe4066994c2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_celebration.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_gift.xml b/packages/SystemUI/res/drawable/ic_gift.xml
new file mode 100644
index 0000000000000..fab36c3ce0dfc
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_gift.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_pages.xml b/packages/SystemUI/res/drawable/ic_pages.xml
new file mode 100644
index 0000000000000..9cd076d106316
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_pages.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_play_games.xml b/packages/SystemUI/res/drawable/ic_play_games.xml
new file mode 100644
index 0000000000000..20096f45b812b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_play_games.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_video.xml b/packages/SystemUI/res/drawable/ic_video.xml
new file mode 100644
index 0000000000000..3668338a0e438
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_video.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/layout/people_tile_large_with_content.xml b/packages/SystemUI/res/layout/people_tile_large_with_content.xml
index 4994c696e9022..e294dad6ce34c 100644
--- a/packages/SystemUI/res/layout/people_tile_large_with_content.xml
+++ b/packages/SystemUI/res/layout/people_tile_large_with_content.xml
@@ -34,8 +34,6 @@
@@ -73,12 +71,12 @@
diff --git a/packages/SystemUI/res/layout/people_tile_medium_empty.xml b/packages/SystemUI/res/layout/people_tile_medium_empty.xml
index bebc872be5141..8b2fddc5c9272 100644
--- a/packages/SystemUI/res/layout/people_tile_medium_empty.xml
+++ b/packages/SystemUI/res/layout/people_tile_medium_empty.xml
@@ -27,19 +27,23 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
+
+
+
+
@@ -112,7 +110,8 @@
android:clipToOutline="true">
diff --git a/packages/SystemUI/res/layout/people_tile_small.xml b/packages/SystemUI/res/layout/people_tile_small.xml
index 4e5c04cb5ad6a..7a1371d034b6d 100644
--- a/packages/SystemUI/res/layout/people_tile_small.xml
+++ b/packages/SystemUI/res/layout/people_tile_small.xml
@@ -39,7 +39,7 @@
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java b/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java
index f3cb35959ed45..96aeb60ae93c5 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java
@@ -29,6 +29,8 @@ import android.graphics.drawable.Drawable;
import android.util.IconDrawableFactory;
import android.util.Log;
+import androidx.core.graphics.drawable.RoundedBitmapDrawable;
+
import com.android.settingslib.Utils;
import com.android.systemui.R;
@@ -58,7 +60,7 @@ class PeopleStoryIconFactory implements AutoCloseable {
mIconDrawableFactory = iconDrawableFactory;
mImportantConversationColor = context.getColor(R.color.important_conversation);
mAccentColor = Utils.getColorAttr(context,
- com.android.internal.R.attr.colorAccentPrimary).getDefaultColor();
+ com.android.internal.R.attr.colorAccentPrimaryVariant).getDefaultColor();
mContext = context;
}
@@ -83,7 +85,8 @@ class PeopleStoryIconFactory implements AutoCloseable {
* Returns a {@link Drawable} for the entire conversation. The shortcut icon will be badged
* with the launcher icon of the app specified by packageName.
*/
- public Drawable getPeopleTileDrawable(Drawable headDrawable, String packageName, int userId,
+ public Drawable getPeopleTileDrawable(RoundedBitmapDrawable headDrawable, String packageName,
+ int userId,
boolean important, boolean newStory) {
return new PeopleStoryIconDrawable(headDrawable, getAppBadge(packageName, userId),
mIconBitmapSize, mImportantConversationColor, important, mIconSize, mDensity,
@@ -96,7 +99,7 @@ class PeopleStoryIconFactory implements AutoCloseable {
*/
public static class PeopleStoryIconDrawable extends Drawable {
private float mFullIconSize;
- private Drawable mAvatar;
+ private RoundedBitmapDrawable mAvatar;
private Drawable mBadgeIcon;
private int mIconSize;
private Paint mPriorityRingPaint;
@@ -105,12 +108,13 @@ class PeopleStoryIconFactory implements AutoCloseable {
private Paint mStoryPaint;
private float mDensity;
- PeopleStoryIconDrawable(Drawable avatar,
+ PeopleStoryIconDrawable(RoundedBitmapDrawable avatar,
Drawable badgeIcon,
int iconSize,
@ColorInt int ringColor,
boolean showImportantRing, float fullIconSize, float density,
@ColorInt int accentColor, boolean showStoryRing) {
+ avatar.setCircular(true);
mAvatar = avatar;
mBadgeIcon = badgeIcon;
mIconSize = iconSize;
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 59c7fd197c8b9..72d382ac0799b 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -45,9 +45,6 @@ import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
-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.UserHandle;
@@ -61,6 +58,9 @@ import android.view.View;
import android.widget.RemoteViews;
import android.widget.TextView;
+import androidx.core.graphics.drawable.RoundedBitmapDrawable;
+import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.systemui.R;
@@ -72,6 +72,7 @@ import java.text.NumberFormat;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -94,6 +95,8 @@ public class PeopleTileViewHelper {
public static final int LAYOUT_LARGE = 2;
private static final int MIN_CONTENT_MAX_LINES = 2;
+ private static final int NAME_MAX_LINES_WITHOUT_LAST_INTERACTION = 3;
+ private static final int NAME_MAX_LINES_WITH_LAST_INTERACTION = 1;
private static final int FIXED_HEIGHT_DIMENS_FOR_LARGE_NOTIF_CONTENT = 16 + 22 + 8 + 16;
private static final int FIXED_HEIGHT_DIMENS_FOR_LARGE_STATUS_CONTENT = 16 + 16 + 24 + 4 + 16;
@@ -225,7 +228,9 @@ public class PeopleTileViewHelper {
Log.d(TAG,
"Create status view for: " + statusesForEntireView.get(0).getActivity());
}
- return createStatusRemoteViews(statusesForEntireView.get(0));
+ ConversationStatus mostRecentlyStartedStatus = statusesForEntireView.stream().max(
+ Comparator.comparing(s -> s.getStartTimeMillis())).get();
+ return createStatusRemoteViews(mostRecentlyStartedStatus);
}
return createLastInteractionRemoteViews();
@@ -579,11 +584,33 @@ public class PeopleTileViewHelper {
setMaxLines(views, false);
}
setAvailabilityDotPadding(views, R.dimen.availability_dot_status_padding);
- // TODO: Set status pre-defined icons
- views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_person);
+ views.setImageViewResource(R.id.predefined_icon, getDrawableForStatus(status));
return views;
}
+ private int getDrawableForStatus(ConversationStatus status) {
+ switch (status.getActivity()) {
+ case ACTIVITY_NEW_STORY:
+ return R.drawable.ic_pages;
+ case ACTIVITY_ANNIVERSARY:
+ return R.drawable.ic_celebration;
+ case ACTIVITY_UPCOMING_BIRTHDAY:
+ return R.drawable.ic_gift;
+ case ACTIVITY_BIRTHDAY:
+ return R.drawable.ic_cake;
+ case ACTIVITY_LOCATION:
+ return R.drawable.ic_location;
+ case ACTIVITY_GAME:
+ return R.drawable.ic_play_games;
+ case ACTIVITY_VIDEO:
+ return R.drawable.ic_video;
+ case ACTIVITY_AUDIO:
+ return R.drawable.ic_music_note;
+ default:
+ return R.drawable.ic_person;
+ }
+ }
+
/**
* Update the padding of the availability dot. The padding on the availability dot decreases
* on the status layouts compared to all other layouts.
@@ -658,7 +685,6 @@ public class PeopleTileViewHelper {
}
private RemoteViews decorateBackground(RemoteViews views, CharSequence content) {
- int visibility = View.GONE;
CharSequence emoji = getDoubleEmoji(content);
if (!TextUtils.isEmpty(emoji)) {
setEmojiBackground(views, emoji);
@@ -768,6 +794,7 @@ public class PeopleTileViewHelper {
}
private RemoteViews setViewForContentLayout(RemoteViews views) {
+ views = decorateBackground(views, "");
if (mLayoutSize == LAYOUT_SMALL) {
views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
views.setViewVisibility(R.id.name, View.GONE);
@@ -819,6 +846,7 @@ public class PeopleTileViewHelper {
private RemoteViews createLastInteractionRemoteViews() {
RemoteViews views = new RemoteViews(mContext.getPackageName(), getEmptyLayout());
+ views.setInt(R.id.name, "setMaxLines", NAME_MAX_LINES_WITH_LAST_INTERACTION);
if (mLayoutSize == LAYOUT_SMALL) {
views.setViewVisibility(R.id.name, View.VISIBLE);
views.setViewVisibility(R.id.predefined_icon, View.GONE);
@@ -836,6 +864,9 @@ public class PeopleTileViewHelper {
} else {
if (DEBUG) Log.d(TAG, "Hide last interaction");
views.setViewVisibility(R.id.last_interaction, View.GONE);
+ if (mLayoutSize == LAYOUT_MEDIUM) {
+ views.setInt(R.id.name, "setMaxLines", NAME_MAX_LINES_WITHOUT_LAST_INTERACTION);
+ }
}
return views;
}
@@ -891,8 +922,9 @@ public class PeopleTileViewHelper {
context.getPackageManager(),
IconDrawableFactory.newInstance(context, false),
maxAvatarSize);
- Drawable drawable = icon.loadDrawable(context);
- Drawable personDrawable = storyIcon.getPeopleTileDrawable(drawable,
+ RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory.create(
+ context.getResources(), icon.getBitmap());
+ Drawable personDrawable = storyIcon.getPeopleTileDrawable(roundedDrawable,
tile.getPackageName(), getUserId(tile), tile.isImportantConversation(),
hasNewStory);
return convertDrawableToBitmap(personDrawable);
@@ -907,14 +939,11 @@ public class PeopleTileViewHelper {
}
long now = System.currentTimeMillis();
Duration durationSinceLastInteraction = Duration.ofMillis(now - lastInteraction);
- MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(),
- MeasureFormat.FormatWidth.WIDE);
if (durationSinceLastInteraction.toDays() <= ONE_DAY) {
return null;
} else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK) {
- return context.getString(R.string.days_timestamp, formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toDays(),
- MeasureUnit.DAY)));
+ return context.getString(R.string.days_timestamp,
+ durationSinceLastInteraction.toDays());
} else if (durationSinceLastInteraction.toDays() == DAYS_IN_A_WEEK) {
return context.getString(R.string.one_week_timestamp);
} else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK * 2) {
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 9e0dd72e77f54..2602d7a3e369a 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -667,12 +667,16 @@ public class PeopleSpaceWidgetManager {
if (icon != null) {
updatedTile.setUserIcon(icon);
}
+ if (DEBUG) Log.d(TAG, "Statuses: " + conversation.getStatuses().toString());
+ NotificationChannel channel = conversation.getParentNotificationChannel();
+ if (channel != null) {
+ if (DEBUG) Log.d(TAG, "Important:" + channel.isImportantConversation());
+ updatedTile.setIsImportantConversation(channel.isImportantConversation());
+ }
updatedTile
.setContactUri(uri)
.setStatuses(conversation.getStatuses())
- .setLastInteractionTimestamp(conversation.getLastEventTimestamp())
- .setIsImportantConversation(conversation.getParentNotificationChannel() != null
- && conversation.getParentNotificationChannel().isImportantConversation());
+ .setLastInteractionTimestamp(conversation.getLastEventTimestamp());
updateAppWidgetOptionsAndView(appWidgetId, updatedTile.build());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
index 3b56f225ba046..67505c42ef9a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
@@ -69,6 +69,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.time.Duration;
import java.util.Arrays;
@RunWith(AndroidTestingRunner.class)
@@ -184,6 +185,30 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
assertEquals(View.GONE, largeResult.findViewById(R.id.last_interaction).getVisibility());
}
+ @Test
+ public void testLastInteractionTime() {
+ long now = System.currentTimeMillis();
+ long fiveDaysAgo = now - Duration.ofDays(5).toMillis();
+ String lastInteractionString = PeopleTileViewHelper.getLastInteractionString(mContext,
+ fiveDaysAgo);
+ assertThat(lastInteractionString).isEqualTo("5 days ago");
+
+ long lessThanOneDayAgo = now - Duration.ofHours(20).toMillis();
+ lastInteractionString = PeopleTileViewHelper.getLastInteractionString(mContext,
+ lessThanOneDayAgo);
+ assertThat(lastInteractionString).isNull();
+
+ long overOneWeekAgo = now - Duration.ofDays(8).toMillis();
+ lastInteractionString = PeopleTileViewHelper.getLastInteractionString(mContext,
+ overOneWeekAgo);
+ assertThat(lastInteractionString).isEqualTo("Over 1 week ago");
+
+ long overTwoWeeksAgo = now - Duration.ofDays(15).toMillis();
+ lastInteractionString = PeopleTileViewHelper.getLastInteractionString(mContext,
+ overTwoWeeksAgo);
+ assertThat(lastInteractionString).isEqualTo("Over 2 weeks ago");
+ }
+
@Test
public void testCreateRemoteViewsWithLastInteractionTime() {
PeopleSpaceTile tileWithLastInteraction =
diff --git a/services/people/java/com/android/server/people/data/ConversationStatusExpirationBroadcastReceiver.java b/services/people/java/com/android/server/people/data/ConversationStatusExpirationBroadcastReceiver.java
index c631026f43891..49d5e50e03450 100644
--- a/services/people/java/com/android/server/people/data/ConversationStatusExpirationBroadcastReceiver.java
+++ b/services/people/java/com/android/server/people/data/ConversationStatusExpirationBroadcastReceiver.java
@@ -20,26 +20,18 @@ import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
import android.app.people.ConversationStatus;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
+import android.os.Binder;
import android.os.CancellationSignal;
-import android.os.SystemClock;
import com.android.server.LocalServices;
-import com.android.server.notification.NotificationRecord;
import com.android.server.people.PeopleServiceInternal;
-import java.util.concurrent.TimeUnit;
-
/**
* If a {@link ConversationStatus} is added to the system with an expiration time, remove that
* status at that time
@@ -53,18 +45,22 @@ public class ConversationStatusExpirationBroadcastReceiver extends BroadcastRece
void scheduleExpiration(Context context, @UserIdInt int userId, String pkg,
String conversationId, ConversationStatus status) {
-
- final PendingIntent pi = PendingIntent.getBroadcast(context,
- REQUEST_CODE,
- new Intent(ACTION)
- .setData(new Uri.Builder().scheme(SCHEME)
- .appendPath(getKey(userId, pkg, conversationId, status))
- .build())
- .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
- .putExtra(EXTRA_USER_ID, userId),
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- context.getSystemService(AlarmManager.class).setExactAndAllowWhileIdle(
- AlarmManager.RTC_WAKEUP, status.getEndTimeMillis(), pi);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final PendingIntent pi = PendingIntent.getBroadcast(context,
+ REQUEST_CODE,
+ new Intent(ACTION)
+ .setData(new Uri.Builder().scheme(SCHEME)
+ .appendPath(getKey(userId, pkg, conversationId, status))
+ .build())
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+ .putExtra(EXTRA_USER_ID, userId),
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ context.getSystemService(AlarmManager.class).setExactAndAllowWhileIdle(
+ AlarmManager.RTC_WAKEUP, status.getEndTimeMillis(), pi);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
private static String getKey(@UserIdInt int userId, String pkg,