Implemented FacePile if no group icon is present

Bug: 150905003
Test: add group without largeicon
Change-Id: I28444df41394a205622d1fb4fede2768b8aa3353
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 5e94b71..ce40504 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -117,6 +117,8 @@
     private CachingIconView mIcon;
     private int mExpandedGroupTopMargin;
     private int mExpandButtonExpandedSize;
+    private View mConversationFacePile;
+    private int mNotificationBackgroundColor;
 
     public ConversationLayout(@NonNull Context context) {
         super(context);
@@ -175,6 +177,7 @@
                 R.dimen.conversation_icon_size_centered);
         mExpandedGroupTopMargin = getResources().getDimensionPixelSize(
                 R.dimen.conversation_icon_margin_top_centered);
+        mConversationFacePile = findViewById(R.id.conversation_face_pile);
     }
 
     @RemotableViewMethod
@@ -297,6 +300,7 @@
             // Let's resolve the icon / text from the last sender
             mConversationIcon.setVisibility(VISIBLE);
             mHeaderText.setVisibility(VISIBLE);
+            mConversationFacePile.setVisibility(GONE);
             CharSequence userKey = getKey(mUser);
             for (int i = mGroups.size() - 1; i >= 0; i--) {
                 MessagingGroup messagingGroup = mGroups.get(i);
@@ -314,13 +318,19 @@
         } else {
             mHeaderText.setVisibility(GONE);
             if (mIsCollapsed) {
-                mConversationIcon.setVisibility(VISIBLE);
                 if (mLargeIcon != null) {
+                    mConversationIcon.setVisibility(VISIBLE);
+                    mConversationFacePile.setVisibility(GONE);
                     mConversationIcon.setImageIcon(mLargeIcon);
                 } else {
-                    // TODO: generate LargeIcon from Conversation
+                    mConversationIcon.setVisibility(GONE);
+                    // This will also inflate it!
+                    mConversationFacePile.setVisibility(VISIBLE);
+                    mConversationFacePile = findViewById(R.id.conversation_face_pile);
+                    bindFacePile();
                 }
             } else {
+                mConversationFacePile.setVisibility(GONE);
                 mConversationIcon.setVisibility(GONE);
             }
         }
@@ -336,6 +346,48 @@
         updateIconPositionAndSize();
     }
 
+    private void bindFacePile() {
+        // Let's bind the face pile
+        View bottomBackground = mConversationFacePile.findViewById(
+                R.id.conversation_face_pile_bottom_background);
+        applyNotificationBackgroundColor(bottomBackground);
+        ImageView bottomView = mConversationFacePile.findViewById(
+                R.id.conversation_face_pile_bottom);
+        ImageView topView = mConversationFacePile.findViewById(
+                R.id.conversation_face_pile_top);
+        // Let's find the two last conversations:
+        Icon secondLastIcon = null;
+        CharSequence lastKey = null;
+        Icon lastIcon = null;
+        CharSequence userKey = getKey(mUser);
+        for (int i = mGroups.size() - 1; i >= 0; i--) {
+            MessagingGroup messagingGroup = mGroups.get(i);
+            Person messageSender = messagingGroup.getSender();
+            boolean notUser = messageSender != null
+                    && !TextUtils.equals(userKey, getKey(messageSender));
+            boolean notIncluded = messageSender != null
+                    && !TextUtils.equals(lastKey, getKey(messageSender));
+            if ((notUser && notIncluded)
+                    || (i == 0 && lastKey == null)) {
+                if (lastIcon == null) {
+                    lastIcon = messagingGroup.getAvatarIcon();
+                    lastKey = getKey(messageSender);
+                } else {
+                    secondLastIcon = messagingGroup.getAvatarIcon();
+                    break;
+                }
+            }
+        }
+        if (lastIcon == null) {
+            lastIcon = createAvatarSymbol(" ", "", mLayoutColor);
+        }
+        bottomView.setImageIcon(lastIcon);
+        if (secondLastIcon == null) {
+            secondLastIcon = createAvatarSymbol("", "", mLayoutColor);
+        }
+        topView.setImageIcon(secondLastIcon);
+    }
+
     /**
      * update the icon position and sizing
      */
@@ -532,7 +584,12 @@
      */
     @RemotableViewMethod
     public void setNotificationBackgroundColor(int color) {
-        mConversationIconBadge.setBackgroundTintList(ColorStateList.valueOf(color));
+        mNotificationBackgroundColor = color;
+        applyNotificationBackgroundColor(mConversationIconBadge);
+    }
+
+    private void applyNotificationBackgroundColor(View view) {
+        view.setBackgroundTintList(ColorStateList.valueOf(mNotificationBackgroundColor));
     }
 
     @RemotableViewMethod
diff --git a/core/res/res/layout/conversation_face_pile_layout.xml b/core/res/res/layout/conversation_face_pile_layout.xml
new file mode 100644
index 0000000..1db3870
--- /dev/null
+++ b/core/res/res/layout/conversation_face_pile_layout.xml
@@ -0,0 +1,45 @@
+<?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
+  -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/conversation_face_pile"
+    android:layout_width="@dimen/conversation_avatar_size"
+    android:layout_height="@dimen/conversation_avatar_size"
+    android:forceHasOverlappingRendering="false"
+    >
+    <ImageView
+        android:id="@+id/conversation_face_pile_top"
+        android:layout_width="36dp"
+        android:layout_height="36dp"
+        android:scaleType="centerCrop"
+        android:layout_gravity="end|top"
+        />
+    <FrameLayout
+        android:id="@+id/conversation_face_pile_bottom_background"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:layout_gravity="start|bottom"
+        android:background="@drawable/conversation_badge_background">
+        <ImageView
+            android:id="@+id/conversation_face_pile_bottom"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
+            android:scaleType="centerCrop"
+            android:layout_gravity="center"
+            />
+    </FrameLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml
index 1d7e6ba..e81dc4a 100644
--- a/core/res/res/layout/notification_template_material_conversation.xml
+++ b/core/res/res/layout/notification_template_material_conversation.xml
@@ -48,6 +48,13 @@
                 android:importantForAccessibility="no"
             />
 
+            <ViewStub
+                android:layout="@layout/conversation_face_pile_layout"
+                android:layout_width="@dimen/conversation_avatar_size"
+                android:layout_height="@dimen/conversation_avatar_size"
+                android:id="@+id/conversation_face_pile"
+                />
+
             <FrameLayout
                 android:id="@+id/conversation_icon_badge"
                 android:layout_width="20dp"
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index cd86f0c..382551c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3883,6 +3883,10 @@
   <java-symbol type="id" name="messaging_group_content_container" />
   <java-symbol type="id" name="expand_button_and_content_container" />
   <java-symbol type="id" name="conversation_header" />
+  <java-symbol type="id" name="conversation_face_pile_bottom_background" />
+  <java-symbol type="id" name="conversation_face_pile_bottom" />
+  <java-symbol type="id" name="conversation_face_pile_top" />
+  <java-symbol type="id" name="conversation_face_pile" />
   <java-symbol type="dimen" name="conversation_expand_button_top_margin_expanded" />
   <java-symbol type="dimen" name="conversation_expand_button_expanded_size" />
   <java-symbol type="dimen" name="messaging_group_singleline_sender_padding_end" />
@@ -3891,6 +3895,7 @@
   <java-symbol type="dimen" name="conversation_icon_size_centered" />
   <java-symbol type="dimen" name="conversation_icon_margin_top_centered" />
   <java-symbol type="layout" name="notification_template_material_conversation" />
+  <java-symbol type="layout" name="conversation_face_pile_layout" />
 
   <!-- Intent resolver and share sheet -->
   <java-symbol type="color" name="resolver_tabs_active_color" />