diff options
| author | 2021-02-17 15:46:55 +0000 | |
|---|---|---|
| committer | 2021-02-17 15:46:55 +0000 | |
| commit | e49eb5062cfcde8ff17e9e687e6489e0e5ab0e07 (patch) | |
| tree | 8cd9890830047b6aefcbf95d24649ac78ebd9b21 | |
| parent | 8b0ca1e4874ff7498bb5981545c72b8f8ec102a3 (diff) | |
| parent | 469c69b53ee3688b18a92fac116a4ff9b56aee12 (diff) | |
Merge "Add new templates & show Statuses in People Tiles" into sc-dev
| -rw-r--r-- | packages/SystemUI/res/drawable/circle_green_10dp.xml | 22 | ||||
| -rw-r--r-- | packages/SystemUI/res/drawable/people_space_content_background.xml | 2 | ||||
| -rw-r--r-- | packages/SystemUI/res/drawable/people_space_new_story_outline.xml (renamed from packages/SystemUI/res/drawable/people_space_round_tile_view_card.xml) | 5 | ||||
| -rw-r--r-- | packages/SystemUI/res/layout/people_space_large_avatar_tile.xml | 70 | ||||
| -rw-r--r-- | packages/SystemUI/res/layout/people_space_notification_content_tile.xml | 154 | ||||
| -rw-r--r-- | packages/SystemUI/res/layout/people_space_small_avatar_tile.xml | 271 | ||||
| -rw-r--r-- | packages/SystemUI/res/layout/punctuation_layout.xml | 100 | ||||
| -rw-r--r-- | packages/SystemUI/res/values/dimens.xml | 4 | ||||
| -rw-r--r-- | packages/SystemUI/res/values/strings.xml | 22 | ||||
| -rw-r--r-- | packages/SystemUI/res/xml/people_space_widget_info.xml | 6 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java | 218 | ||||
| -rw-r--r-- | packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java | 178 |
12 files changed, 817 insertions, 235 deletions
diff --git a/packages/SystemUI/res/drawable/circle_green_10dp.xml b/packages/SystemUI/res/drawable/circle_green_10dp.xml new file mode 100644 index 000000000000..571ec621da9f --- /dev/null +++ b/packages/SystemUI/res/drawable/circle_green_10dp.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="oval"> + <size android:height="10dp" + android:width="10dp" /> + <solid android:color="#34A853" /> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/people_space_content_background.xml b/packages/SystemUI/res/drawable/people_space_content_background.xml index 5310840939b8..32314d29277e 100644 --- a/packages/SystemUI/res/drawable/people_space_content_background.xml +++ b/packages/SystemUI/res/drawable/people_space_content_background.xml @@ -16,5 +16,5 @@ --> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="?android:attr/colorControlHighlight" /> - <corners android:radius="@dimen/people_space_widget_radius" /> + <corners android:radius="@dimen/people_space_image_radius" /> </shape> diff --git a/packages/SystemUI/res/drawable/people_space_round_tile_view_card.xml b/packages/SystemUI/res/drawable/people_space_new_story_outline.xml index 59af7750dada..a1737f92fa22 100644 --- a/packages/SystemUI/res/drawable/people_space_round_tile_view_card.xml +++ b/packages/SystemUI/res/drawable/people_space_new_story_outline.xml @@ -13,7 +13,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -<shape xmlns:android="http://schemas.android.com/apk/res/android"> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="oval"> <solid android:color="?android:attr/colorBackground" /> - <corners android:radius="@dimen/people_space_widget_round_radius" /> + <stroke android:width="2dp" android:color="?android:attr/colorAccent" /> </shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/people_space_large_avatar_tile.xml b/packages/SystemUI/res/layout/people_space_large_avatar_tile.xml index e9f3424547fa..b1c13287d203 100644 --- a/packages/SystemUI/res/layout/people_space_large_avatar_tile.xml +++ b/packages/SystemUI/res/layout/people_space_large_avatar_tile.xml @@ -19,70 +19,78 @@ android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout - android:background="@drawable/people_space_round_tile_view_card" + android:background="@drawable/people_space_tile_view_card" android:id="@+id/item" - android:paddingVertical="6dp" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="horizontal" - android:gravity="center_vertical" - android:paddingStart="12dp" + android:gravity="center" + android:paddingVertical="2dp" + android:paddingHorizontal="8dp" android:layout_width="match_parent" android:layout_height="match_parent"> - + <LinearLayout + android:background="@drawable/people_space_new_story_outline" + android:id="@+id/person_icon_with_story" + android:gravity="center_horizontal" + android:layout_width="60dp" + android:layout_height="60dp"> <ImageView - android:id="@+id/person_icon" - android:layout_width="60dp" - android:layout_height="60dp" /> - - <LinearLayout - android:background="@drawable/people_space_rounded_border" - android:layout_marginStart="-12dp" - android:layout_marginTop="28dp" - android:layout_marginBottom="14dp" - android:layout_width="16dp" - android:layout_height="16dp"> + android:id="@+id/person_icon_inside_ring" + android:layout_marginEnd="4dp" + android:layout_marginStart="4dp" + android:layout_marginBottom="4dp" + android:layout_marginTop="4dp" + android:layout_width="52dp" + android:layout_height="52dp"/> + </LinearLayout> + <ImageView + android:id="@+id/person_icon_only" + android:layout_width="60dp" + android:layout_height="60dp"/> - <ImageView - android:id="@+id/package_icon" - android:layout_width="12dp" - android:layout_marginStart="2dp" - android:layout_marginEnd="2dp" - android:layout_marginBottom="2dp" - android:layout_marginTop="2dp" - android:layout_height="12dp" /> - </LinearLayout> + <ImageView + android:id="@+id/package_icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_marginStart="-20dp" + android:layout_marginTop="22dp"/> <LinearLayout android:orientation="vertical" android:paddingStart="8dp" - android:paddingEnd="12dp" android:layout_width="match_parent" android:layout_height="wrap_content"> + <ImageView + android:id="@+id/availability" + android:layout_width="10dp" + android:layout_height="10dp" + android:background="@drawable/circle_green_10dp"/> <TextView android:id="@+id/name" + android:text="@string/empty_user_name" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" android:textColor="?android:attr/textColorPrimary" - android:textSize="16sp" + android:textSize="14sp" android:maxLines="1" android:ellipsize="end" android:layout_width="wrap_content" - android:layout_height="wrap_content" /> + android:layout_height="wrap_content"/> <TextView - android:id="@+id/status" + android:id="@+id/last_interaction" + android:text="@string/empty_status" android:textColor="?android:attr/textColorSecondary" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:paddingVertical="3dp" android:textSize="12sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="3" - android:ellipsize="end" /> + android:ellipsize="end"/> </LinearLayout> </LinearLayout> </LinearLayout> diff --git a/packages/SystemUI/res/layout/people_space_notification_content_tile.xml b/packages/SystemUI/res/layout/people_space_notification_content_tile.xml new file mode 100644 index 000000000000..739738ae9e35 --- /dev/null +++ b/packages/SystemUI/res/layout/people_space_notification_content_tile.xml @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + <RelativeLayout + android:background="@drawable/people_space_tile_view_card" + android:id="@+id/people_tile" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <include layout="@layout/punctuation_layout"/> + <RelativeLayout + android:gravity="start" + android:id="@+id/column_one" + android:paddingVertical="10dp" + android:paddingStart="8dp" + android:layout_width="wrap_content" + android:layout_height="match_parent"> + <TextView + android:id="@+id/subtext" + android:layout_toStartOf="@+id/content_layout" + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" + android:gravity="top|start" + android:textColor="?android:attr/textColorSecondary" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" + android:textSize="12sp" + android:maxWidth="60dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:maxLines="1" + android:ellipsize="end"/> + <LinearLayout + android:orientation="horizontal" + android:id="@+id/avatar_and_app_icon" + android:layout_alignParentBottom="true" + android:layout_alignParentStart="true" + android:gravity="center" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + <LinearLayout + android:id="@+id/person_icon_with_story" + android:background="@drawable/people_space_new_story_outline" + android:gravity="center_horizontal" + android:layout_width="48dp" + android:layout_height="48dp"> + <ImageView + android:id="@+id/person_icon_inside_ring" + android:layout_marginEnd="4dp" + android:layout_marginStart="4dp" + android:layout_marginBottom="4dp" + android:layout_marginTop="4dp" + android:layout_width="40dp" + android:layout_height="40dp"/> + </LinearLayout> + <ImageView + android:id="@+id/person_icon_only" + android:layout_width="48dp" + android:layout_height="48dp"/> + <ImageView + android:id="@id/package_icon" + android:layout_marginStart="-16dp" + android:layout_marginTop="18dp" + android:paddingBottom="10dp" + android:paddingEnd="8dp" + android:layout_width="28dp" + android:layout_height="32dp"/> + </LinearLayout> + </RelativeLayout> + <LinearLayout + android:id="@+id/content_layout" + android:paddingBottom="4dp" + android:paddingStart="4dp" + android:paddingTop="8dp" + android:paddingEnd="8dp" + android:layout_alignParentEnd="true" + android:layout_alignParentTop="true" + android:layout_toEndOf="@id/column_one" + android:gravity="top|end" + android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + <TextView + android:id="@+id/content" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" + android:textColor="?android:attr/textColorPrimary" + android:gravity="top|end" + android:textSize="12sp" + android:paddingTop="2dp" + android:paddingEnd="4dp" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:maxLines="2" + android:ellipsize="end"/> + <LinearLayout + android:id="@+id/content_background" + android:background="@drawable/people_space_content_background" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <ImageView + android:id="@+id/image" + android:adjustViewBounds="true" + android:maxHeight="44dp" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:scaleType="centerCrop"/> + </LinearLayout> + </LinearLayout> + <LinearLayout + android:id="@+id/person_label" + android:paddingBottom="10dp" + android:paddingEnd="8dp" + android:gravity="start|bottom" + android:layout_toEndOf="@id/column_one" + android:layout_alignParentBottom="true" + android:layout_alignParentEnd="true" + android:layout_below="@id/content_layout" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <ImageView + android:id="@+id/availability" + android:layout_width="10dp" + android:layout_height="10dp" + android:paddingVertical="2dp" + android:background="@drawable/circle_green_10dp"/> + <TextView + android:id="@+id/name" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" + android:textColor="?android:attr/textColorPrimary" + android:textSize="14sp" + android:maxLines="1" + android:ellipsize="end" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + </LinearLayout> + </RelativeLayout> +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/people_space_small_avatar_tile.xml b/packages/SystemUI/res/layout/people_space_small_avatar_tile.xml index 03589d34efd2..bb4a20e4108e 100644 --- a/packages/SystemUI/res/layout/people_space_small_avatar_tile.xml +++ b/packages/SystemUI/res/layout/people_space_small_avatar_tile.xml @@ -14,183 +14,144 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:background="@drawable/people_space_tile_view_card" + android:id="@+id/people_tile" android:layout_width="match_parent" android:layout_height="match_parent"> - <LinearLayout - android:orientation="horizontal" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:gravity="start"> - <TextView - android:id="@+id/punctuation1" - android:textColor="?android:attr/textColorSecondary" - android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:textSize="36sp" - android:textStyle="bold" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="5dp" - android:maxLines="1" - android:alpha="0.2" - android:rotation="350" /> - <TextView - android:id="@+id/punctuation2" - android:textColor="?android:attr/textColorSecondary" - android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:textSize="36sp" - android:textStyle="bold" + <RelativeLayout + android:gravity="start" + android:id="@+id/column_one" + android:paddingVertical="8dp" + android:paddingStart="8dp" + android:layout_width="wrap_content" + android:layout_height="match_parent"> + <LinearLayout + android:orientation="horizontal" + android:id="@+id/content_background" + android:background="@drawable/people_space_content_background" + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" + android:layout_width="60dp" + android:layout_height="60dp"> + <ImageView + android:id="@+id/image" + android:gravity="center" + android:background="@drawable/people_space_content_background" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:scaleType="centerCrop"/> + <ImageView + android:id="@+id/status_defined_icon" + android:gravity="start|top" + android:layout_marginStart="-52dp" + android:layout_marginTop="8dp" + android:layout_width="18dp" + android:layout_height="18dp"/> + </LinearLayout> + <LinearLayout + android:orientation="horizontal" + android:id="@+id/avatar_and_app_icon" + android:layout_alignParentBottom="true" + android:layout_alignParentStart="true" + android:paddingStart="4dp" + android:gravity="center" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="25dp" - android:maxLines="1" - android:alpha="0.2" - android:rotation="5" /> + android:layout_height="wrap_content"> + <LinearLayout + android:id="@+id/person_icon_with_story" + android:background="@drawable/people_space_new_story_outline" + android:gravity="center_horizontal" + android:layout_width="48dp" + android:layout_height="48dp"> + <ImageView + android:id="@+id/person_icon_inside_ring" + android:layout_marginEnd="4dp" + android:layout_marginStart="4dp" + android:layout_marginBottom="4dp" + android:layout_marginTop="4dp" + android:layout_width="40dp" + android:layout_height="40dp"/> + </LinearLayout> + <ImageView + android:id="@+id/person_icon_only" + android:layout_width="48dp" + android:layout_height="48dp"/> + <ImageView + android:id="@id/package_icon" + android:layout_marginStart="-16dp" + android:layout_marginTop="18dp" + android:paddingBottom="10dp" + android:paddingEnd="8dp" + android:layout_width="28dp" + android:layout_height="32dp"/> + </LinearLayout> + </RelativeLayout> + <LinearLayout + android:id="@+id/content_layout" + android:paddingTop="10dp" + android:paddingBottom="4dp" + android:paddingHorizontal="8dp" + android:layout_alignParentEnd="true" + android:layout_alignParentTop="true" + android:layout_toEndOf="@id/column_one" + android:gravity="top|end" + android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> <TextView - android:id="@+id/punctuation3" - android:textColor="?android:attr/textColorSecondary" + android:id="@+id/status" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:textSize="36sp" - android:textStyle="bold" + android:textColor="?android:attr/textColorPrimary" + android:textSize="12sp" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="5dp" - android:layout_marginStart="25dp" - android:maxLines="1" - android:alpha="0.2" - android:rotation="355"/> + android:maxLines="2" + android:ellipsize="end"/> + </LinearLayout> + <LinearLayout + android:id="@+id/person_label" + android:paddingBottom="10dp" + android:paddingEnd="8dp" + android:gravity="start|bottom" + android:layout_toEndOf="@id/column_one" + android:layout_alignParentBottom="true" + android:layout_alignParentEnd="true" + android:layout_below="@id/content_layout" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> <TextView - android:id="@+id/punctuation4" + android:id="@+id/time" android:textColor="?android:attr/textColorSecondary" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:textSize="36sp" - android:textStyle="bold" + android:textSize="12sp" + android:paddingVertical="2dp" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="-5dp" - android:layout_marginStart="25dp" android:maxLines="1" - android:alpha="0.2" - android:rotation="10" /> + android:visibility="gone" + android:ellipsize="end"/> + <ImageView + android:id="@+id/availability" + android:layout_width="10dp" + android:layout_height="10dp" + android:paddingVertical="2dp" + android:background="@drawable/circle_green_10dp"/> <TextView - android:id="@+id/punctuation5" - android:textColor="?android:attr/textColorSecondary" + android:id="@+id/name" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:textSize="36sp" - android:textStyle="bold" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="5dp" - android:layout_marginStart="25dp" + android:textColor="?android:attr/textColorPrimary" + android:textSize="14sp" android:maxLines="1" - android:alpha="0.2" - android:rotation="15" /> - <TextView - android:id="@+id/punctuation6" - android:textColor="?android:attr/textColorSecondary" - android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:textSize="36sp" - android:textStyle="bold" + android:ellipsize="end" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="-5dp" - android:layout_marginStart="25dp" - android:maxLines="1" - android:alpha="0.2" - android:rotation="345" /> - </LinearLayout> - <LinearLayout - android:id="@+id/item" - android:orientation="vertical" - android:paddingTop="6dp" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <LinearLayout - android:orientation="horizontal" - android:paddingHorizontal="12dp" - android:paddingBottom="4dp" - android:gravity="top" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <ImageView - android:id="@+id/person_icon" - android:layout_width="34dp" - android:layout_height="34dp" /> - - <LinearLayout - android:background="@drawable/people_space_rounded_border" - android:layout_marginStart="-5dp" - android:layout_marginTop="18dp" - android:layout_width="8dp" - android:layout_height="8dp"> - - <ImageView - android:id="@+id/package_icon" - android:layout_width="6dp" - android:layout_marginEnd="1dp" - android:layout_marginStart="1dp" - android:layout_marginBottom="1dp" - android:layout_marginTop="1dp" - android:layout_height="6dp" /> - </LinearLayout> - - <LinearLayout - android:orientation="vertical" - android:paddingStart="6dp" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <TextView - android:id="@+id/name" - android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:textColor="?android:attr/textColorPrimary" - android:textSize="14sp" - android:maxLines="1" - android:ellipsize="end" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - - <TextView - android:id="@+id/time" - android:textColor="?android:attr/textColorSecondary" - android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:textSize="10sp" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:maxLines="1" - android:ellipsize="end" /> - </LinearLayout> - </LinearLayout> - <LinearLayout - android:id="@+id/content_background" - android:background="@drawable/people_space_content_background" - android:layout_gravity="center" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <TextView - android:id="@+id/content" - android:paddingVertical="3dp" - android:paddingHorizontal="12dp" - android:gravity="center" - android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" - android:textSize="16sp" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:maxLines="2" - android:ellipsize="end" /> - <ImageView - android:id="@+id/image" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:visibility="gone" - android:scaleType="centerCrop"/> - </LinearLayout> + android:layout_height="wrap_content"/> </LinearLayout> </RelativeLayout> </LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/punctuation_layout.xml b/packages/SystemUI/res/layout/punctuation_layout.xml new file mode 100644 index 000000000000..25c7648530d6 --- /dev/null +++ b/packages/SystemUI/res/layout/punctuation_layout.xml @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/punctuation_layout" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="start"> + <TextView + android:id="@+id/punctuation1" + android:textColor="?android:attr/textColorSecondary" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" + android:textSize="36sp" + android:textStyle="bold" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="5dp" + android:maxLines="1" + android:alpha="0.2" + android:rotation="350"/> + <TextView + android:id="@+id/punctuation2" + android:textColor="?android:attr/textColorSecondary" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" + android:textSize="36sp" + android:textStyle="bold" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="25dp" + android:maxLines="1" + android:alpha="0.2" + android:rotation="5"/> + <TextView + android:id="@+id/punctuation3" + android:textColor="?android:attr/textColorSecondary" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" + android:textSize="36sp" + android:textStyle="bold" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="5dp" + android:layout_marginStart="25dp" + android:maxLines="1" + android:alpha="0.2" + android:rotation="355"/> + <TextView + android:id="@+id/punctuation4" + android:textColor="?android:attr/textColorSecondary" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" + android:textSize="36sp" + android:textStyle="bold" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="-5dp" + android:layout_marginStart="25dp" + android:maxLines="1" + android:alpha="0.2" + android:rotation="10"/> + <TextView + android:id="@+id/punctuation5" + android:textColor="?android:attr/textColorSecondary" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" + android:textSize="36sp" + android:textStyle="bold" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="5dp" + android:layout_marginStart="25dp" + android:maxLines="1" + android:alpha="0.2" + android:rotation="15"/> + <TextView + android:id="@+id/punctuation6" + android:textColor="?android:attr/textColorSecondary" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" + android:textSize="36sp" + android:textStyle="bold" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="-5dp" + android:layout_marginStart="25dp" + android:maxLines="1" + android:alpha="0.2" + android:rotation="345"/> +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 0d92aea6ed6f..b07df9caa95b 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1348,8 +1348,8 @@ <dimen name="media_output_dialog_icon_corner_radius">16dp</dimen> <dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen> - <dimen name="people_space_widget_radius">24dp</dimen> - <dimen name="people_space_widget_round_radius">100dp</dimen> + <dimen name="people_space_widget_radius">28dp</dimen> + <dimen name="people_space_image_radius">20dp</dimen> <dimen name="people_space_widget_background_padding">6dp</dimen> <dimen name="rounded_slider_height">48dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 32381be5b5d6..264da22a3fe0 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2813,8 +2813,26 @@ <string name="less_than_timestamp" translatable="false">Less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string> <!-- Timestamp for notification when over a certain time window [CHAR LIMIT=120] --> <string name="over_timestamp" translatable="false">Over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string> - <!-- Status text for a birthday today [CHAR LIMIT=120] --> - <string name="birthday_status" translatable="false">Today is their birthday!</string> + <!-- Status text for a birthday today [CHAR LIMIT=30] --> + <string name="birthday_status" translatable="false">Birthday</string> + <!-- Status text for an upcoming birthday [CHAR LIMIT=30] --> + <string name="upcoming_birthday_status" translatable="false">Birthday soon</string> + <!-- Status text for an anniversary [CHAR LIMIT=30] --> + <string name="anniversary_status" translatable="false">Anniversary</string> + <!-- Status text for sharing location [CHAR LIMIT=30] --> + <string name="location_status" translatable="false">Sharing location</string> + <!-- Status text for a new story posted [CHAR LIMIT=30] --> + <string name="new_story_status" translatable="false">New story</string> + <!-- Status text for watching a video [CHAR LIMIT=30] --> + <string name="video_status" translatable="false">Watching</string> + <!-- Status text for listening to audio [CHAR LIMIT=30] --> + <string name="audio_status" translatable="false">Listening</string> + <!-- Status text for playing a game [CHAR LIMIT=30] --> + <string name="game_status" translatable="false">Playing</string> + <!-- Empty user name before user has selected a friend [CHAR LIMIT=30] --> + <string name="empty_user_name" translatable="false">Your friend</string> + <!-- Empty status shown before user has selected a friend [CHAR LIMIT=30] --> + <string name="empty_status" translatable="false">Their status</string> <!-- Title to display in a notification when ACTION_BATTERY_CHANGED.EXTRA_PRESENT field is false [CHAR LIMIT=NONE] --> diff --git a/packages/SystemUI/res/xml/people_space_widget_info.xml b/packages/SystemUI/res/xml/people_space_widget_info.xml index d0c63a8b180c..fbdac5e1789b 100644 --- a/packages/SystemUI/res/xml/people_space_widget_info.xml +++ b/packages/SystemUI/res/xml/people_space_widget_info.xml @@ -16,11 +16,11 @@ <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="140dp" - android:minHeight="40dp" + android:minHeight="55dp" android:minResizeWidth="110dp" - android:minResizeHeight="40dp" + android:minResizeHeight="55dp" android:updatePeriodMillis="60000" - android:previewImage="@drawable/ic_android" + android:previewImage="@drawable/ic_person" android:resizeMode="horizontal|vertical" android:configure="com.android.systemui.people.PeopleSpaceActivity" android:initialLayout="@layout/people_space_widget"> diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java index cbcbd3b892a5..cd1131ba3e79 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java @@ -17,12 +17,21 @@ package com.android.systemui.people; import static android.app.Notification.EXTRA_MESSAGES; +import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY; +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_MEDIA; +import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY; +import static android.app.people.ConversationStatus.ACTIVITY_UPCOMING_BIRTHDAY; +import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE; import android.annotation.Nullable; import android.app.INotificationManager; import android.app.Notification; import android.app.PendingIntent; import android.app.people.ConversationChannel; +import android.app.people.ConversationStatus; import android.app.people.IPeopleManager; import android.app.people.PeopleSpaceTile; import android.appwidget.AppWidgetManager; @@ -37,6 +46,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; 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; @@ -71,6 +81,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import java.text.SimpleDateFormat; import java.time.Duration; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Date; @@ -441,20 +452,141 @@ public class PeopleSpaceUtils { /** Creates a {@link RemoteViews} for {@code tile}. */ public static RemoteViews createRemoteViews(Context context, PeopleSpaceTile tile, int appWidgetId) { - RemoteViews views; + RemoteViews viewsForTile = getViewForTile(context, tile); + RemoteViews views = setCommonRemoteViewsFields(context, viewsForTile, tile); + return setLaunchIntents(context, views, tile, appWidgetId); + } + + /** + * The prioritization for the {@code tile} content is missed calls, followed by notification + * content, then birthdays, then the most recent status, and finally last interaction. + */ + private static RemoteViews getViewForTile(Context context, PeopleSpaceTile tile) { if (tile.getNotificationKey() != null) { - views = createNotificationRemoteViews(context, tile); - } else if (tile.getBirthdayText() != null) { - views = createStatusRemoteViews(context, tile); + if (DEBUG) Log.d(TAG, "Create notification view"); + return createNotificationRemoteViews(context, tile); + } + + // TODO: Add sorting when we expose timestamp of statuses. + List<ConversationStatus> statusesForEntireView = + tile.getStatuses() == null ? Arrays.asList() : tile.getStatuses().stream().filter( + c -> isStatusValidForEntireStatusView(c)).collect(Collectors.toList()); + ConversationStatus birthdayStatus = getBirthdayStatus(tile, statusesForEntireView); + if (birthdayStatus != null) { + if (DEBUG) Log.d(TAG, "Create birthday view"); + return createStatusRemoteViews(context, birthdayStatus); + } + + if (!statusesForEntireView.isEmpty()) { + if (DEBUG) { + Log.d(TAG, + "Create status view for: " + statusesForEntireView.get(0).getActivity()); + } + return createStatusRemoteViews(context, statusesForEntireView.get(0)); + } + + return createLastInteractionRemoteViews(context, tile); + } + + @Nullable + private static ConversationStatus getBirthdayStatus(PeopleSpaceTile tile, + List<ConversationStatus> statuses) { + Optional<ConversationStatus> birthdayStatus = statuses.stream().filter( + c -> c.getActivity() == ACTIVITY_BIRTHDAY).findFirst(); + if (birthdayStatus.isPresent()) { + return birthdayStatus.get(); + } + if (!TextUtils.isEmpty(tile.getBirthdayText())) { + return new ConversationStatus.Builder(tile.getId(), ACTIVITY_BIRTHDAY).build(); + } + + return null; + } + + /** + * Returns whether a {@code status} should have its own entire templated view. + * + * <p>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) { + RemoteViews views = new RemoteViews( + context.getPackageName(), R.layout.people_space_small_avatar_tile); + CharSequence statusText = status.getDescription(); + if (TextUtils.isEmpty(statusText)) { + statusText = getStatusTextByType(context, status.getActivity()); + } + views.setTextViewText(R.id.status, statusText); + Icon statusIcon = status.getIcon(); + if (statusIcon != null) { + views.setImageViewIcon(R.id.image, statusIcon); + views.setBoolean(R.id.content_background, "setClipToOutline", true); } else { - views = createLastInteractionRemoteViews(context, tile); + views.setViewVisibility(R.id.content_background, View.GONE); + } + // TODO: Set status pre-defined icons + 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_MEDIA: + return context.getString(R.string.video_status); + case ACTIVITY_GAME: + return context.getString(R.string.game_status); + default: + return EMPTY_STRING; } - return setCommonRemoteViewsFields(context, views, tile, appWidgetId); } private static RemoteViews setCommonRemoteViewsFields(Context context, RemoteViews views, - PeopleSpaceTile tile, int appWidgetId) { + PeopleSpaceTile tile) { 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); + if (hasNewStory) { + views.setViewVisibility(R.id.person_icon_with_story, View.VISIBLE); + views.setViewVisibility(R.id.person_icon_only, View.GONE); + views.setImageViewIcon(R.id.person_icon_inside_ring, tile.getUserIcon()); + } else { + views.setViewVisibility(R.id.person_icon_with_story, View.GONE); + views.setViewVisibility(R.id.person_icon_only, View.VISIBLE); + views.setImageViewIcon(R.id.person_icon_only, tile.getUserIcon()); + } + views.setTextViewText(R.id.name, tile.getUserName().toString()); views.setImageViewIcon(R.id.person_icon, tile.getUserIcon()); views.setBoolean(R.id.content_background, "setClipToOutline", true); @@ -466,7 +598,16 @@ public class PeopleSpaceUtils { tile.getPackageName()) ) ); + 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 @@ -484,48 +625,42 @@ public class PeopleSpaceUtils { PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE)); return views; } catch (Exception e) { - Log.e(TAG, "Failed to set common fields: " + e); + Log.e(TAG, "Failed to add launch intents: " + e); } - return null; + return views; } private static RemoteViews createNotificationRemoteViews(Context context, PeopleSpaceTile tile) { RemoteViews views = new RemoteViews( - context.getPackageName(), R.layout.people_space_small_avatar_tile); + context.getPackageName(), R.layout.people_space_notification_content_tile); Uri image = tile.getNotificationDataUri(); if (image != null) { - //TODO: Use NotificationInlineImageCache + // TODO: Use NotificationInlineImageCache views.setImageViewUri(R.id.image, image); - views.setViewVisibility(R.id.image, View.VISIBLE); + views.setViewVisibility(R.id.content_background, View.VISIBLE); + views.setBoolean(R.id.content_background, "setClipToOutline", true); views.setViewVisibility(R.id.content, View.GONE); } else { CharSequence content = tile.getNotificationContent(); views = setPunctuationRemoteViewsFields(views, content); views.setTextViewText(R.id.content, content); views.setViewVisibility(R.id.content, View.VISIBLE); - views.setViewVisibility(R.id.image, View.GONE); + views.setViewVisibility(R.id.content_background, View.GONE); } - views.setTextViewText(R.id.time, PeopleSpaceUtils.getLastInteractionString( + // TODO: Set subtext as Group Sender name once storing the name in PeopleSpaceTile. + views.setTextViewText(R.id.subtext, PeopleSpaceUtils.getLastInteractionString( context, tile.getLastInteractionTimestamp(), false)); return views; } - private static RemoteViews createStatusRemoteViews(Context context, - PeopleSpaceTile tile) { - RemoteViews views = new RemoteViews( - context.getPackageName(), R.layout.people_space_large_avatar_tile); - views.setTextViewText(R.id.status, tile.getBirthdayText()); - return views; - } - private static RemoteViews createLastInteractionRemoteViews(Context context, PeopleSpaceTile tile) { RemoteViews views = new RemoteViews( context.getPackageName(), R.layout.people_space_large_avatar_tile); String status = PeopleSpaceUtils.getLastInteractionString( context, tile.getLastInteractionTimestamp(), true); - views.setTextViewText(R.id.status, status); + views.setTextViewText(R.id.last_interaction, status); return views; } @@ -682,20 +817,35 @@ public class PeopleSpaceUtils { Duration durationSinceLastInteraction = Duration.ofMillis(now - lastInteraction); MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(), MeasureFormat.FormatWidth.WIDE); + MeasureFormat shortFormatter = MeasureFormat.getInstance(Locale.getDefault(), + MeasureFormat.FormatWidth.SHORT); if (durationSinceLastInteraction.toHours() < MIN_HOUR) { - return context.getString(includeLastChatted ? R.string.last_interaction_status_less_than - : R.string.less_than_timestamp, - formatter.formatMeasures(new Measure(MIN_HOUR, MeasureUnit.HOUR))); + if (includeLastChatted) { + return context.getString(R.string.last_interaction_status_less_than, + formatter.formatMeasures(new Measure(MIN_HOUR, MeasureUnit.HOUR))); + } + return context.getString(R.string.timestamp, shortFormatter.formatMeasures( + new Measure(durationSinceLastInteraction.toMinutes(), MeasureUnit.MINUTE))); } else if (durationSinceLastInteraction.toDays() < ONE_DAY) { - return context.getString( - includeLastChatted ? R.string.last_interaction_status : R.string.timestamp, - formatter.formatMeasures( - new Measure(durationSinceLastInteraction.toHours(), MeasureUnit.HOUR))); + if (includeLastChatted) { + return context.getString(R.string.last_interaction_status, + formatter.formatMeasures( + new Measure(durationSinceLastInteraction.toHours(), + MeasureUnit.HOUR))); + } + return context.getString(R.string.timestamp, shortFormatter.formatMeasures( + new Measure(durationSinceLastInteraction.toHours(), + MeasureUnit.HOUR))); } else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK) { - return context.getString( - includeLastChatted ? R.string.last_interaction_status : R.string.timestamp, - formatter.formatMeasures( - new Measure(durationSinceLastInteraction.toDays(), MeasureUnit.DAY))); + if (includeLastChatted) { + return context.getString(R.string.last_interaction_status, + formatter.formatMeasures( + new Measure(durationSinceLastInteraction.toDays(), + MeasureUnit.DAY))); + } + return context.getString(R.string.timestamp, shortFormatter.formatMeasures( + new Measure(durationSinceLastInteraction.toHours(), + MeasureUnit.DAY))); } else { return context.getString(durationSinceLastInteraction.toDays() == DAYS_IN_A_WEEK ? (includeLastChatted ? R.string.last_interaction_status : 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 4ee2759028a9..d79155cbb2fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java @@ -16,11 +16,18 @@ package com.android.systemui.people; +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 com.android.systemui.people.PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE; import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -39,6 +46,7 @@ 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; @@ -46,13 +54,13 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; +import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; import android.database.Cursor; import android.graphics.drawable.Icon; import android.net.Uri; import android.os.Bundle; -import android.os.RemoteException; import android.os.UserHandle; import android.provider.ContactsContract; import android.provider.Settings; @@ -60,6 +68,9 @@ import android.service.notification.ConversationChannelWrapper; import android.service.notification.StatusBarNotification; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; +import android.view.View; +import android.widget.RemoteViews; +import android.widget.TextView; import com.android.internal.appwidget.IAppWidgetService; import com.android.systemui.R; @@ -101,27 +112,45 @@ 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 String NAME = "username"; private static final Person PERSON = new Person.Builder() .setName("name") .setKey("abc") .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, "username", ICON, new Intent()) + .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(); private final ShortcutInfo mShortcutInfo = new ShortcutInfo.Builder(mContext, SHORTCUT_ID_1).setLongLabel( - "name").setPerson(PERSON) + NAME).setPerson(PERSON) .build(); private final ShortcutInfo mShortcutInfoWithoutPerson = new ShortcutInfo.Builder(mContext, SHORTCUT_ID_1).setLongLabel( - "name") + NAME) .build(); private final Notification mNotification1 = new Notification.Builder(mContext, "test") .setContentTitle("TEST_TITLE") @@ -189,10 +218,12 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase { @Mock private Context mMockContext; @Mock + private PackageManager mPackageManager; + @Mock private NotificationEntryManager mNotificationEntryManager; @Before - public void setUp() throws RemoteException { + public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0); @@ -212,6 +243,12 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase { isNull())).thenReturn(mMockCursor); 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)); + when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null); when(mNotificationEntryManager.getVisibleNotifications()) .thenReturn(List.of(mNotificationEntry1, mNotificationEntry2, mNotificationEntry3)); } @@ -621,6 +658,137 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase { any()); } + @Test + public void testCreateRemoteViewsWithLastInteractionTime() { + RemoteViews views = PeopleSpaceUtils.createRemoteViews(mMockContext, + PERSON_TILE_WITHOUT_NOTIFICATION, 0); + 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()); + // No new story. + View personIcon = result.findViewById(R.id.person_icon_only); + View personIconWithStory = result.findViewById(R.id.person_icon_with_story); + assertEquals(View.VISIBLE, personIcon.getVisibility()); + assertEquals(View.GONE, personIconWithStory.getVisibility()); + // No status. + assertThat((View) result.findViewById(R.id.status)).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 = PeopleSpaceUtils.createRemoteViews(mMockContext, + tileWithAvailabilityAndNewStory, 0); + 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 new story. + View personIcon = result.findViewById(R.id.person_icon_only); + View personIconWithStory = result.findViewById(R.id.person_icon_with_story); + assertEquals(View.GONE, personIcon.getVisibility()); + assertEquals(View.VISIBLE, personIconWithStory.getVisibility()); + // No status. + assertThat((View) result.findViewById(R.id.status)).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 = PeopleSpaceUtils.createRemoteViews(mContext, + tileWithStatusTemplate, 0); + 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 new story. + View personIcon = result.findViewById(R.id.person_icon_only); + View personIconWithStory = result.findViewById(R.id.person_icon_with_story); + assertEquals(View.GONE, personIcon.getVisibility()); + assertEquals(View.VISIBLE, personIconWithStory.getVisibility()); + // Has status text from backup text. + TextView statusContent = (TextView) result.findViewById(R.id.status); + assertEquals(statusContent.getText(), mContext.getString(R.string.birthday_status)); + } + + @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); + 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 new story. + View personIcon = result.findViewById(R.id.person_icon_only); + View personIconWithStory = result.findViewById(R.id.person_icon_with_story); + assertEquals(View.GONE, personIcon.getVisibility()); + assertEquals(View.VISIBLE, personIconWithStory.getVisibility()); + // Has status. + TextView statusContent = (TextView) result.findViewById(R.id.status); + assertEquals(statusContent.getText(), GAME_DESCRIPTION); + } + + @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); + 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); + assertTrue(subtext.getText().toString().contains("weeks ago")); + // Has availability. + View availability = result.findViewById(R.id.availability); + assertEquals(View.VISIBLE, availability.getVisibility()); + // Has new story. + View personIcon = result.findViewById(R.id.person_icon_only); + View personIconWithStory = result.findViewById(R.id.person_icon_with_story); + assertEquals(View.GONE, personIcon.getVisibility()); + assertEquals(View.VISIBLE, personIconWithStory.getVisibility()); + // Has notification content. + TextView statusContent = (TextView) result.findViewById(R.id.content); + assertEquals(statusContent.getText(), NOTIFICATION_CONTENT); + } + private ConversationChannelWrapper getConversationChannelWrapper(String shortcutId, boolean importantConversation, long lastInteractionTimestamp) throws Exception { ConversationChannelWrapper convo = new ConversationChannelWrapper(); |