Add MessagingStyle transitions

Fixes a particularly bad transition in the case where there
is one incoming message to a group.

Change-Id: Ieddece4a496292a69e14cdcd74d94986938d8223
Fixes: 29043489
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 83a2066..0fca78d 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4570,12 +4570,21 @@
                     : mConversationTitle;
             boolean hasTitle = !TextUtils.isEmpty(title);
 
-            if (!hasTitle && mMessages.size() == 1) {
-                CharSequence sender = mMessages.get(0).mSender;
-                CharSequence text = mMessages.get(0).mText;
+            if (mMessages.size() == 1) {
+                // Special case for a single message: Use the big text style
+                // so the collapsed and expanded versions match nicely.
+                CharSequence bigTitle;
+                CharSequence text;
+                if (hasTitle) {
+                    bigTitle = title;
+                    text = makeMessageLine(mMessages.get(0));
+                } else {
+                    bigTitle = mMessages.get(0).mSender;
+                    text = mMessages.get(0).mText;
+                }
                 RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
                         mBuilder.getBigTextLayoutResource(),
-                        false /* progress */, sender, null /* text */);
+                        false /* progress */, bigTitle, null /* text */);
                 BigTextStyle.applyBigTextContentView(mBuilder, contentView, text);
                 return contentView;
             }
@@ -4601,6 +4610,8 @@
             contentView.setInt(R.id.notification_messaging, "setNumIndentLines",
                     mBuilder.mN.mLargeIcon == null ? 0 : (hasTitle ? 1 : 2));
 
+            int contractedChildId = View.NO_ID;
+            Message contractedMessage = findLatestIncomingMessage();
             int firstMessage = Math.max(0, mMessages.size() - rowIds.length);
             while (firstMessage + i < mMessages.size() && i < rowIds.length) {
                 Message m = mMessages.get(firstMessage + i);
@@ -4609,8 +4620,15 @@
                 contentView.setViewVisibility(rowId, View.VISIBLE);
                 contentView.setTextViewText(rowId, makeMessageLine(m));
 
+                if (contractedMessage == m) {
+                    contractedChildId = rowId;
+                }
+
                 i++;
             }
+            // Record this here to allow transformation between the contracted and expanded views.
+            contentView.setInt(R.id.notification_messaging, "setContractedChildId",
+                    contractedChildId);
             return contentView;
         }
 
diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java
index dc7b7f5..d2a43b7 100644
--- a/core/java/com/android/internal/widget/MessagingLinearLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java
@@ -48,6 +48,11 @@
 
     private int mIndentLines;
 
+    /**
+     * Id of the child that's also visible in the contracted layout.
+     */
+    private int mContractedChildId;
+
     public MessagingLinearLayout(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
 
@@ -255,14 +260,29 @@
         return copy;
     }
 
-    @RemotableViewMethod
     /**
      * Sets how many lines should be indented to avoid a floating image.
      */
+    @RemotableViewMethod
     public void setNumIndentLines(int numberLines) {
         mIndentLines = numberLines;
     }
 
+    /**
+     * Set id of the child that's also visible in the contracted layout.
+     */
+    @RemotableViewMethod
+    public void setContractedChildId(int contractedChildId) {
+        mContractedChildId = contractedChildId;
+    }
+
+    /**
+     * Get id of the child that's also visible in the contracted layout.
+     */
+    public int getContractedChildId() {
+        return mContractedChildId;
+    }
+
     public static class LayoutParams extends MarginLayoutParams {
 
         boolean hide = false;