Merge "Fixes for Test App e2e working and UX polish." into sc-dev am: 44061d90ec am: 384000d1fc

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14701662

Change-Id: Id06e9007faff2c1bb82ab2aa301f23ccff2fe9b9
This commit is contained in:
TreeHugger Robot
2021-05-25 13:19:09 +00:00
committed by Automerger Merge Worker
15 changed files with 282 additions and 66 deletions

View File

@@ -0,0 +1,24 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M19,14v-4c0,-1.1 -0.9,-2 -2,-2h-4L13,6.55c0.15,-0.09 0.29,-0.18 0.41,-0.31 0.39,-0.39 0.59,-0.92 0.59,-1.42s-0.2,-1.02 -0.59,-1.41L12,2l-1.41,1.41c-0.39,0.39 -0.59,0.91 -0.59,1.41s0.2,1.03 0.59,1.42c0.13,0.13 0.27,0.22 0.41,0.31L11,8L7,8c-1.1,0 -2,0.9 -2,2v4c-1.1,0 -2,0.9 -2,2v4c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-4c0,-1.1 -0.9,-2 -2,-2zM7,10h10v4L7,14v-4zM19,20L5,20v-4h14v4z"
android:fillColor="#FFFFFFFF"/>
</vector>

View File

@@ -0,0 +1,37 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M2,22l14,-5L7,8L2,22zM12.35,16.18L5.3,18.7l2.52,-7.05L12.35,16.18z"
android:fillColor="#FFFFFFFF"/>
<path
android:pathData="M14.53,12.53l5.59,-5.59c0.49,-0.49 1.28,-0.49 1.77,0l0.59,0.59l1.06,-1.06l-0.59,-0.59c-1.07,-1.07 -2.82,-1.07 -3.89,0l-5.59,5.59L14.53,12.53z"
android:fillColor="#FFFFFFFF"/>
<path
android:pathData="M10.06,6.88L9.47,7.47l1.06,1.06l0.59,-0.59c1.07,-1.07 1.07,-2.82 0,-3.89l-0.59,-0.59L9.47,4.53l0.59,0.59C10.54,5.6 10.54,6.4 10.06,6.88z"
android:fillColor="#FFFFFFFF"/>
<path
android:pathData="M17.06,11.88l-1.59,1.59l1.06,1.06l1.59,-1.59c0.49,-0.49 1.28,-0.49 1.77,0l1.61,1.61l1.06,-1.06l-1.61,-1.61C19.87,10.81 18.13,10.81 17.06,11.88z"
android:fillColor="#FFFFFFFF"/>
<path
android:pathData="M15.06,5.88l-3.59,3.59l1.06,1.06l3.59,-3.59c1.07,-1.07 1.07,-2.82 0,-3.89l-1.59,-1.59l-1.06,1.06l1.59,1.59C15.54,4.6 15.54,5.4 15.06,5.88z"
android:fillColor="#FFFFFFFF"/>
</vector>

View File

@@ -0,0 +1,24 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M22,5h-5.18C16.93,4.69 17,4.35 17,4c0,-1.65 -1.35,-3 -3,-3c-0.77,0 -1.47,0.3 -2,0.78C11.47,1.3 10.77,1 10,1C8.35,1 7,2.35 7,4c0,0.35 0.07,0.69 0.18,1H2v6h2v11h16V11h2V5zM14,3c0.55,0 1,0.45 1,1s-0.45,1 -1,1s-1,-0.45 -1,-1S13.45,3 14,3zM9,4c0,-0.55 0.45,-1 1,-1s1,0.45 1,1s-0.45,1 -1,1S9,4.55 9,4zM4,7h7v2H4V7zM6,11h5v9H6V11zM18,20h-5v-9h5V20zM20,9h-7V7h7V9z"
android:fillColor="#FFFFFFFF"/>
</vector>

View File

@@ -0,0 +1,24 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M19,5v14L5,19L5,5h14m0,-2L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM12,17l1.57,-3.43L17,12l-3.43,-1.57L12,7l-1.57,3.43L7,12l3.43,1.57L12,17z"
android:fillColor="#FFFFFFFF"/>
</vector>

View File

@@ -0,0 +1,24 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M20.47,8c-0.39,-2.3 -2.4,-4 -4.81,-4L8.34,4C5.93,4 3.93,5.7 3.53,8 3.53,8 2,16.8 2,16.93 2,18.07 2.93,19 4.07,19c0.57,0 1.09,-0.2 1.47,-0.58L9,15h6l3.46,3.42c0.38,0.38 0.89,0.58 1.47,0.58 1.15,0 2.07,-0.93 2.07,-2.07C22,16.8 20.47,8 20.47,8zM11,10L9,10v2L8,12v-2L6,10L6,9h2L8,7h1v2h2v1zM13.8,10.3c-0.44,0 -0.8,-0.36 -0.8,-0.8 0,-0.44 0.36,-0.8 0.8,-0.8 0.44,0 0.8,0.36 0.8,0.8 0,0.44 -0.36,0.8 -0.8,0.8zM15.49,12c-0.44,0 -0.8,-0.36 -0.8,-0.8 0,-0.44 0.36,-0.8 0.8,-0.8 0.44,0 0.8,0.36 0.8,0.8 0,0.44 -0.36,0.8 -0.8,0.8zM15.49,8.6c-0.44,0 -0.8,-0.36 -0.8,-0.8s0.36,-0.8 0.8,-0.8c0.44,0 0.8,0.36 0.8,0.8s-0.36,0.8 -0.8,0.8zM17.2,10.3c-0.44,0 -0.8,-0.36 -0.8,-0.8 0,-0.44 0.36,-0.8 0.8,-0.8s0.8,0.36 0.8,0.8c0,0.44 -0.36,0.8 -0.8,0.8z"
android:fillColor="#FFFFFFFF"/>
</vector>

View File

@@ -0,0 +1,24 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M9,7v8l7,-4zM21,3L3,3c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h5v2h8v-2h5c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,17L3,17L3,5h18v12z"
android:fillColor="#FFFFFFFF"/>
</vector>

View File

@@ -34,8 +34,6 @@
<ImageView <ImageView
android:id="@+id/person_icon" android:id="@+id/person_icon"
android:layout_marginStart="-2dp"
android:layout_marginTop="-2dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> android:layout_weight="1" />
@@ -73,12 +71,12 @@
<include layout="@layout/people_tile_emoji_background_large" /> <include layout="@layout/people_tile_emoji_background_large" />
<TextView <TextView
android:layout_gravity="top"
android:id="@+id/name" android:id="@+id/name"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingBottom="@dimen/below_name_text_padding" android:paddingBottom="@dimen/below_name_text_padding"
android:gravity="start|top" android:layout_gravity="start|center_vertical"
android:gravity="start|center_vertical"
android:singleLine="true" android:singleLine="true"
android:ellipsize="end" android:ellipsize="end"
android:text="@string/empty_user_name" android:text="@string/empty_user_name"
@@ -103,7 +101,7 @@
<ImageView <ImageView
android:id="@+id/predefined_icon" android:id="@+id/predefined_icon"
android:tint="?android:attr/colorAccent" android:tint="?android:attr/textColorTertiary"
android:gravity="start|center_vertical" android:gravity="start|center_vertical"
android:layout_width="@dimen/regular_predefined_icon" android:layout_width="@dimen/regular_predefined_icon"
android:layout_height="@dimen/regular_predefined_icon" /> android:layout_height="@dimen/regular_predefined_icon" />

View File

@@ -27,19 +27,23 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView <ImageView
android:id="@+id/person_icon" android:id="@+id/person_icon"
android:layout_marginTop="-2dp"
android:layout_marginStart="-2dp"
android:layout_width="64dp" android:layout_width="64dp"
android:layout_height="64dp" /> android:layout_height="64dp" />
<ImageView <ImageView
android:id="@+id/availability" android:id="@+id/availability"
android:gravity="top"
android:layout_marginStart="-2dp"
android:layout_width="10dp" android:layout_width="10dp"
android:layout_height="10dp" android:layout_height="10dp"
android:gravity="top"
android:layout_gravity="top"
android:layout_marginStart="-2dp"
android:background="@drawable/availability_dot_10dp" /> android:background="@drawable/availability_dot_10dp" />
</LinearLayout>
<LinearLayout <LinearLayout
android:orientation="vertical" android:orientation="vertical"
android:paddingStart="4dp" android:paddingStart="4dp"

View File

@@ -47,8 +47,6 @@
<ImageView <ImageView
android:gravity="start" android:gravity="start"
android:id="@+id/person_icon" android:id="@+id/person_icon"
android:layout_marginStart="-2dp"
android:layout_marginTop="-2dp"
android:layout_width="52dp" android:layout_width="52dp"
android:layout_height="52dp" /> android:layout_height="52dp" />
@@ -112,7 +110,8 @@
android:clipToOutline="true"> android:clipToOutline="true">
<TextView <TextView
android:id="@+id/name" android:id="@+id/name"
android:gravity="center_vertical" android:layout_gravity="start|center_vertical"
android:gravity="start|center_vertical"
android:layout_weight="1" android:layout_weight="1"
android:text="@string/empty_user_name" android:text="@string/empty_user_name"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
@@ -140,7 +139,7 @@
/> />
<ImageView <ImageView
android:id="@+id/predefined_icon" android:id="@+id/predefined_icon"
android:tint="?android:attr/colorAccent" android:tint="?android:attr/textColorTertiary"
android:gravity="end|center_vertical" android:gravity="end|center_vertical"
android:layout_width="@dimen/regular_predefined_icon" android:layout_width="@dimen/regular_predefined_icon"
android:layout_height="@dimen/regular_predefined_icon" /> android:layout_height="@dimen/regular_predefined_icon" />

View File

@@ -39,7 +39,7 @@
<ImageView <ImageView
android:id="@+id/predefined_icon" android:id="@+id/predefined_icon"
android:tint="?android:attr/colorAccent" android:tint="?android:attr/textColorTertiary"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_width="18dp" android:layout_width="18dp"
android:layout_height="22dp" /> android:layout_height="22dp" />

View File

@@ -29,6 +29,8 @@ import android.graphics.drawable.Drawable;
import android.util.IconDrawableFactory; import android.util.IconDrawableFactory;
import android.util.Log; import android.util.Log;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import com.android.settingslib.Utils; import com.android.settingslib.Utils;
import com.android.systemui.R; import com.android.systemui.R;
@@ -58,7 +60,7 @@ class PeopleStoryIconFactory implements AutoCloseable {
mIconDrawableFactory = iconDrawableFactory; mIconDrawableFactory = iconDrawableFactory;
mImportantConversationColor = context.getColor(R.color.important_conversation); mImportantConversationColor = context.getColor(R.color.important_conversation);
mAccentColor = Utils.getColorAttr(context, mAccentColor = Utils.getColorAttr(context,
com.android.internal.R.attr.colorAccentPrimary).getDefaultColor(); com.android.internal.R.attr.colorAccentPrimaryVariant).getDefaultColor();
mContext = context; mContext = context;
} }
@@ -83,7 +85,8 @@ class PeopleStoryIconFactory implements AutoCloseable {
* Returns a {@link Drawable} for the entire conversation. The shortcut icon will be badged * Returns a {@link Drawable} for the entire conversation. The shortcut icon will be badged
* with the launcher icon of the app specified by packageName. * 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) { boolean important, boolean newStory) {
return new PeopleStoryIconDrawable(headDrawable, getAppBadge(packageName, userId), return new PeopleStoryIconDrawable(headDrawable, getAppBadge(packageName, userId),
mIconBitmapSize, mImportantConversationColor, important, mIconSize, mDensity, mIconBitmapSize, mImportantConversationColor, important, mIconSize, mDensity,
@@ -96,7 +99,7 @@ class PeopleStoryIconFactory implements AutoCloseable {
*/ */
public static class PeopleStoryIconDrawable extends Drawable { public static class PeopleStoryIconDrawable extends Drawable {
private float mFullIconSize; private float mFullIconSize;
private Drawable mAvatar; private RoundedBitmapDrawable mAvatar;
private Drawable mBadgeIcon; private Drawable mBadgeIcon;
private int mIconSize; private int mIconSize;
private Paint mPriorityRingPaint; private Paint mPriorityRingPaint;
@@ -105,12 +108,13 @@ class PeopleStoryIconFactory implements AutoCloseable {
private Paint mStoryPaint; private Paint mStoryPaint;
private float mDensity; private float mDensity;
PeopleStoryIconDrawable(Drawable avatar, PeopleStoryIconDrawable(RoundedBitmapDrawable avatar,
Drawable badgeIcon, Drawable badgeIcon,
int iconSize, int iconSize,
@ColorInt int ringColor, @ColorInt int ringColor,
boolean showImportantRing, float fullIconSize, float density, boolean showImportantRing, float fullIconSize, float density,
@ColorInt int accentColor, boolean showStoryRing) { @ColorInt int accentColor, boolean showStoryRing) {
avatar.setCircular(true);
mAvatar = avatar; mAvatar = avatar;
mBadgeIcon = badgeIcon; mBadgeIcon = badgeIcon;
mIconSize = iconSize; mIconSize = iconSize;

View File

@@ -45,9 +45,6 @@ import android.content.res.Configuration;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon; 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.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
@@ -61,6 +58,9 @@ import android.view.View;
import android.widget.RemoteViews; import android.widget.RemoteViews;
import android.widget.TextView; 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.internal.annotations.VisibleForTesting;
import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.systemui.R; import com.android.systemui.R;
@@ -72,6 +72,7 @@ import java.text.NumberFormat;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
@@ -94,6 +95,8 @@ public class PeopleTileViewHelper {
public static final int LAYOUT_LARGE = 2; public static final int LAYOUT_LARGE = 2;
private static final int MIN_CONTENT_MAX_LINES = 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_NOTIF_CONTENT = 16 + 22 + 8 + 16;
private static final int FIXED_HEIGHT_DIMENS_FOR_LARGE_STATUS_CONTENT = 16 + 16 + 24 + 4 + 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, Log.d(TAG,
"Create status view for: " + statusesForEntireView.get(0).getActivity()); "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(); return createLastInteractionRemoteViews();
@@ -579,11 +584,33 @@ public class PeopleTileViewHelper {
setMaxLines(views, false); setMaxLines(views, false);
} }
setAvailabilityDotPadding(views, R.dimen.availability_dot_status_padding); setAvailabilityDotPadding(views, R.dimen.availability_dot_status_padding);
// TODO: Set status pre-defined icons views.setImageViewResource(R.id.predefined_icon, getDrawableForStatus(status));
views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_person);
return views; 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 * Update the padding of the availability dot. The padding on the availability dot decreases
* on the status layouts compared to all other layouts. * on the status layouts compared to all other layouts.
@@ -658,7 +685,6 @@ public class PeopleTileViewHelper {
} }
private RemoteViews decorateBackground(RemoteViews views, CharSequence content) { private RemoteViews decorateBackground(RemoteViews views, CharSequence content) {
int visibility = View.GONE;
CharSequence emoji = getDoubleEmoji(content); CharSequence emoji = getDoubleEmoji(content);
if (!TextUtils.isEmpty(emoji)) { if (!TextUtils.isEmpty(emoji)) {
setEmojiBackground(views, emoji); setEmojiBackground(views, emoji);
@@ -768,6 +794,7 @@ public class PeopleTileViewHelper {
} }
private RemoteViews setViewForContentLayout(RemoteViews views) { private RemoteViews setViewForContentLayout(RemoteViews views) {
views = decorateBackground(views, "");
if (mLayoutSize == LAYOUT_SMALL) { if (mLayoutSize == LAYOUT_SMALL) {
views.setViewVisibility(R.id.predefined_icon, View.VISIBLE); views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
views.setViewVisibility(R.id.name, View.GONE); views.setViewVisibility(R.id.name, View.GONE);
@@ -819,6 +846,7 @@ public class PeopleTileViewHelper {
private RemoteViews createLastInteractionRemoteViews() { private RemoteViews createLastInteractionRemoteViews() {
RemoteViews views = new RemoteViews(mContext.getPackageName(), getEmptyLayout()); RemoteViews views = new RemoteViews(mContext.getPackageName(), getEmptyLayout());
views.setInt(R.id.name, "setMaxLines", NAME_MAX_LINES_WITH_LAST_INTERACTION);
if (mLayoutSize == LAYOUT_SMALL) { if (mLayoutSize == LAYOUT_SMALL) {
views.setViewVisibility(R.id.name, View.VISIBLE); views.setViewVisibility(R.id.name, View.VISIBLE);
views.setViewVisibility(R.id.predefined_icon, View.GONE); views.setViewVisibility(R.id.predefined_icon, View.GONE);
@@ -836,6 +864,9 @@ public class PeopleTileViewHelper {
} else { } else {
if (DEBUG) Log.d(TAG, "Hide last interaction"); if (DEBUG) Log.d(TAG, "Hide last interaction");
views.setViewVisibility(R.id.last_interaction, View.GONE); 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; return views;
} }
@@ -891,8 +922,9 @@ public class PeopleTileViewHelper {
context.getPackageManager(), context.getPackageManager(),
IconDrawableFactory.newInstance(context, false), IconDrawableFactory.newInstance(context, false),
maxAvatarSize); maxAvatarSize);
Drawable drawable = icon.loadDrawable(context); RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory.create(
Drawable personDrawable = storyIcon.getPeopleTileDrawable(drawable, context.getResources(), icon.getBitmap());
Drawable personDrawable = storyIcon.getPeopleTileDrawable(roundedDrawable,
tile.getPackageName(), getUserId(tile), tile.isImportantConversation(), tile.getPackageName(), getUserId(tile), tile.isImportantConversation(),
hasNewStory); hasNewStory);
return convertDrawableToBitmap(personDrawable); return convertDrawableToBitmap(personDrawable);
@@ -907,14 +939,11 @@ public class PeopleTileViewHelper {
} }
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
Duration durationSinceLastInteraction = Duration.ofMillis(now - lastInteraction); Duration durationSinceLastInteraction = Duration.ofMillis(now - lastInteraction);
MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(),
MeasureFormat.FormatWidth.WIDE);
if (durationSinceLastInteraction.toDays() <= ONE_DAY) { if (durationSinceLastInteraction.toDays() <= ONE_DAY) {
return null; return null;
} else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK) { } else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK) {
return context.getString(R.string.days_timestamp, formatter.formatMeasures( return context.getString(R.string.days_timestamp,
new Measure(durationSinceLastInteraction.toDays(), durationSinceLastInteraction.toDays());
MeasureUnit.DAY)));
} else if (durationSinceLastInteraction.toDays() == DAYS_IN_A_WEEK) { } else if (durationSinceLastInteraction.toDays() == DAYS_IN_A_WEEK) {
return context.getString(R.string.one_week_timestamp); return context.getString(R.string.one_week_timestamp);
} else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK * 2) { } else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK * 2) {

View File

@@ -667,12 +667,16 @@ public class PeopleSpaceWidgetManager {
if (icon != null) { if (icon != null) {
updatedTile.setUserIcon(icon); 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 updatedTile
.setContactUri(uri) .setContactUri(uri)
.setStatuses(conversation.getStatuses()) .setStatuses(conversation.getStatuses())
.setLastInteractionTimestamp(conversation.getLastEventTimestamp()) .setLastInteractionTimestamp(conversation.getLastEventTimestamp());
.setIsImportantConversation(conversation.getParentNotificationChannel() != null
&& conversation.getParentNotificationChannel().isImportantConversation());
updateAppWidgetOptionsAndView(appWidgetId, updatedTile.build()); updateAppWidgetOptionsAndView(appWidgetId, updatedTile.build());
} }

View File

@@ -69,6 +69,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.time.Duration;
import java.util.Arrays; import java.util.Arrays;
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@@ -184,6 +185,30 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
assertEquals(View.GONE, largeResult.findViewById(R.id.last_interaction).getVisibility()); 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 @Test
public void testCreateRemoteViewsWithLastInteractionTime() { public void testCreateRemoteViewsWithLastInteractionTime() {
PeopleSpaceTile tileWithLastInteraction = PeopleSpaceTile tileWithLastInteraction =

View File

@@ -20,26 +20,18 @@ import android.annotation.UserIdInt;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.app.PendingIntent; 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.app.people.ConversationStatus;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.Uri; import android.net.Uri;
import android.os.Binder;
import android.os.CancellationSignal; import android.os.CancellationSignal;
import android.os.SystemClock;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import com.android.server.notification.NotificationRecord;
import com.android.server.people.PeopleServiceInternal; 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 * If a {@link ConversationStatus} is added to the system with an expiration time, remove that
* status at that time * status at that time
@@ -53,7 +45,8 @@ public class ConversationStatusExpirationBroadcastReceiver extends BroadcastRece
void scheduleExpiration(Context context, @UserIdInt int userId, String pkg, void scheduleExpiration(Context context, @UserIdInt int userId, String pkg,
String conversationId, ConversationStatus status) { String conversationId, ConversationStatus status) {
final long identity = Binder.clearCallingIdentity();
try {
final PendingIntent pi = PendingIntent.getBroadcast(context, final PendingIntent pi = PendingIntent.getBroadcast(context,
REQUEST_CODE, REQUEST_CODE,
new Intent(ACTION) new Intent(ACTION)
@@ -65,6 +58,9 @@ public class ConversationStatusExpirationBroadcastReceiver extends BroadcastRece
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
context.getSystemService(AlarmManager.class).setExactAndAllowWhileIdle( context.getSystemService(AlarmManager.class).setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP, status.getEndTimeMillis(), pi); AlarmManager.RTC_WAKEUP, status.getEndTimeMillis(), pi);
} finally {
Binder.restoreCallingIdentity(identity);
}
} }
private static String getKey(@UserIdInt int userId, String pkg, private static String getKey(@UserIdInt int userId, String pkg,