Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bd7796e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Made image messages display externally in the layout" into rvc-dev

parents 100012bd 514b52c0
Loading
Loading
Loading
Loading
+59 −14
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.internal.widget;

import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_EXTERNAL;
import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE;

import android.annotation.AttrRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -35,6 +38,7 @@ import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
@@ -46,6 +50,7 @@ import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.TextView;

@@ -109,13 +114,13 @@ public class ConversationLayout extends FrameLayout
    private View mExpandButtonContainer;
    private ViewGroup mExpandButtonAndContentContainer;
    private NotificationExpandButton mExpandButton;
    private MessagingLinearLayout mImageMessageContainer;
    private int mExpandButtonExpandedTopMargin;
    private int mBadgedSideMargins;
    private int mIconSizeBadged;
    private int mIconSizeCentered;
    private CachingIconView mIcon;
    private int mExpandedGroupTopMargin;
    private int mExpandButtonExpandedSize;
    private View mConversationFacePile;
    private int mNotificationBackgroundColor;
    private CharSequence mFallbackChatName;
@@ -126,6 +131,7 @@ public class ConversationLayout extends FrameLayout
    private View mContentContainer;
    private boolean mExpandable = true;
    private int mContentMarginEnd;
    private Rect mMessagingClipRect;

    public ConversationLayout(@NonNull Context context) {
        super(context);
@@ -150,12 +156,13 @@ public class ConversationLayout extends FrameLayout
        super.onFinishInflate();
        mMessagingLinearLayout = findViewById(R.id.notification_messaging);
        mMessagingLinearLayout.setMessagingLayout(this);
        mImageMessageContainer = findViewById(R.id.conversation_image_message_container);
        // We still want to clip, but only on the top, since views can temporarily out of bounds
        // during transitions.
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        int size = Math.max(displayMetrics.widthPixels, displayMetrics.heightPixels);
        Rect rect = new Rect(0, 0, size, size);
        mMessagingLinearLayout.setClipBounds(rect);
        mMessagingClipRect = new Rect(0, 0, size, size);
        setMessagingClippingDisabled(false);
        mTitleView = findViewById(R.id.title);
        mAvatarSize = getResources().getDimensionPixelSize(R.dimen.messaging_avatar_size);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
@@ -176,8 +183,6 @@ public class ConversationLayout extends FrameLayout
        mExpandButton = findViewById(R.id.expand_button);
        mExpandButtonExpandedTopMargin = getResources().getDimensionPixelSize(
                R.dimen.conversation_expand_button_top_margin_expanded);
        mExpandButtonExpandedSize = getResources().getDimensionPixelSize(
                R.dimen.conversation_expand_button_expanded_size);
        mNotificationHeaderExpandedPadding = getResources().getDimensionPixelSize(
                R.dimen.conversation_header_expanded_padding_end);
        mContentMarginEnd = getResources().getDimensionPixelSize(
@@ -370,6 +375,41 @@ public class ConversationLayout extends FrameLayout
            messagingGroup.setCanHideSenderIfFirst(canHide);
        }
        updateIconPositionAndSize();
        updateImageMessages();
    }

    private void updateImageMessages() {
        boolean displayExternalImage = false;
        ArraySet<View> newMessages = new ArraySet<>();
        if (mIsCollapsed) {

            // When collapsed, we're displaying all image messages in a dedicated container
            // on the right of the layout instead of inline. Let's add all isolated images there
            int imageIndex = 0;
            for (int i = 0; i < mGroups.size(); i++) {
                MessagingGroup messagingGroup = mGroups.get(i);
                MessagingImageMessage isolatedMessage = messagingGroup.getIsolatedMessage();
                if (isolatedMessage != null) {
                    newMessages.add(isolatedMessage.getView());
                    displayExternalImage = true;
                    if (imageIndex
                            != mImageMessageContainer.indexOfChild(isolatedMessage.getView())) {
                        mImageMessageContainer.removeView(isolatedMessage.getView());
                        mImageMessageContainer.addView(isolatedMessage.getView(), imageIndex);
                    }
                    imageIndex++;
                }
            }
        }
        // Remove all messages that don't belong into the image layout
        for (int i = 0; i < mImageMessageContainer.getChildCount(); i++) {
            View child = mImageMessageContainer.getChildAt(i);
            if (!newMessages.contains(child)) {
                mImageMessageContainer.removeView(child);
                i--;
            }
        }
        mImageMessageContainer.setVisibility(displayExternalImage ? VISIBLE : GONE);
    }

    private void bindFacePile() {
@@ -662,7 +702,9 @@ public class ConversationLayout extends FrameLayout
                newGroup = MessagingGroup.createGroup(mMessagingLinearLayout);
                mAddedGroups.add(newGroup);
            }
            newGroup.setDisplayImagesAtEnd(mIsCollapsed);
            newGroup.setImageDisplayLocation(mIsCollapsed
                    ? IMAGE_DISPLAY_LOCATION_EXTERNAL
                    : IMAGE_DISPLAY_LOCATION_INLINE);
            newGroup.setIsInConversation(true);
            newGroup.setLayoutColor(mLayoutColor);
            newGroup.setTextColors(mSenderTextColor, mMessageTextColor);
@@ -817,6 +859,10 @@ public class ConversationLayout extends FrameLayout
        return mMessagingLinearLayout;
    }

    public @NonNull ViewGroup getImageMessageContainer() {
        return mImageMessageContainer;
    }

    public ArrayList<MessagingGroup> getMessagingGroups() {
        return mGroups;
    }
@@ -827,20 +873,17 @@ public class ConversationLayout extends FrameLayout
        int gravity;
        int topMargin = 0;
        ViewGroup newContainer;
        int newContainerHeight;
        if (mIsCollapsed) {
            drawableId = R.drawable.ic_expand_notification;
            contentDescriptionId = R.string.expand_button_content_description_collapsed;
            gravity = Gravity.CENTER;
            newContainer = mExpandButtonAndContentContainer;
            newContainerHeight = LayoutParams.MATCH_PARENT;
        } else {
            drawableId = R.drawable.ic_collapse_notification;
            contentDescriptionId = R.string.expand_button_content_description_expanded;
            gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
            topMargin = mExpandButtonExpandedTopMargin;
            newContainer = this;
            newContainerHeight = mExpandButtonExpandedSize;
        }
        mExpandButton.setImageDrawable(getContext().getDrawable(drawableId));
        mExpandButton.setColorFilter(mExpandButton.getOriginalNotificationColor());
@@ -850,14 +893,11 @@ public class ConversationLayout extends FrameLayout
        if (newContainer != mExpandButtonContainer.getParent()) {
            ((ViewGroup) mExpandButtonContainer.getParent()).removeView(mExpandButtonContainer);
            newContainer.addView(mExpandButtonContainer);
            MarginLayoutParams layoutParams =
                    (MarginLayoutParams) mExpandButtonContainer.getLayoutParams();
            layoutParams.height = newContainerHeight;
            mExpandButtonContainer.setLayoutParams(layoutParams);
        }

        // update if the expand button is centered
        FrameLayout.LayoutParams layoutParams = (LayoutParams) mExpandButton.getLayoutParams();
        LinearLayout.LayoutParams layoutParams =
                (LinearLayout.LayoutParams) mExpandButton.getLayoutParams();
        layoutParams.gravity = gravity;
        layoutParams.topMargin = topMargin;
        mExpandButton.setLayoutParams(layoutParams);
@@ -905,4 +945,9 @@ public class ConversationLayout extends FrameLayout
        }
        updateContentPaddings();
    }

    @Override
    public void setMessagingClippingDisabled(boolean clippingDisabled) {
        mMessagingLinearLayout.setClipBounds(clippingDisabled ? null : mMessagingClipRect);
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -39,4 +39,9 @@ public interface IMessagingLayout {
     * @return the list of messaging groups
     */
    ArrayList<MessagingGroup> getMessagingGroups();

    /**
     * Disable the clipping of the messaging container.
     */
    void setMessagingClippingDisabled(boolean clippingDisabled);
}
+40 −7
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.widget;

import android.annotation.AttrRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StyleRes;
@@ -44,6 +45,8 @@ import android.widget.RemoteViews;

import com.android.internal.R;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

@@ -54,6 +57,23 @@ import java.util.List;
public class MessagingGroup extends LinearLayout implements MessagingLinearLayout.MessagingChild {
    private static Pools.SimplePool<MessagingGroup> sInstancePool
            = new Pools.SynchronizedPool<>(10);

    /**
     * Images are displayed inline.
     */
    public static final int IMAGE_DISPLAY_LOCATION_INLINE = 0;

    /**
     * Images are displayed at the end of the group.
     */
    public static final int IMAGE_DISPLAY_LOCATION_AT_END = 1;

    /**
     *     Images are displayed externally.
     */
    public static final int IMAGE_DISPLAY_LOCATION_EXTERNAL = 2;


    private MessagingLinearLayout mMessageContainer;
    ImageFloatingTextView mSenderView;
    private ImageView mAvatarView;
@@ -70,7 +90,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
    private boolean mIsHidingAnimated;
    private boolean mNeedsGeneratedAvatar;
    private Person mSender;
    private boolean mImagesAtEnd;
    private @ImageDisplayLocation int mImageDisplayLocation;
    private ViewGroup mImageContainer;
    private MessagingImageMessage mIsolatedMessage;
    private boolean mClippingDisabled;
@@ -476,7 +496,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
                mAddedMessages.add(message);
            }
            boolean isImage = message instanceof MessagingImageMessage;
            if (mImagesAtEnd && isImage) {
            if (mImageDisplayLocation != IMAGE_DISPLAY_LOCATION_INLINE && isImage) {
                isolatedMessage = (MessagingImageMessage) message;
            } else {
                if (removeFromParentIfDifferent(message, mMessageContainer)) {
@@ -500,9 +520,12 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
            }
        }
        if (isolatedMessage != null) {
            if (removeFromParentIfDifferent(isolatedMessage, mImageContainer)) {
            if (mImageDisplayLocation == IMAGE_DISPLAY_LOCATION_AT_END
                    && removeFromParentIfDifferent(isolatedMessage, mImageContainer)) {
                mImageContainer.removeAllViews();
                mImageContainer.addView(isolatedMessage.getView());
            } else if (mImageDisplayLocation == IMAGE_DISPLAY_LOCATION_EXTERNAL) {
                mImageContainer.removeAllViews();
            }
            isolatedMessage.setIsolated(true);
        } else if (mIsolatedMessage != null) {
@@ -515,7 +538,8 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
    }

    private void updateImageContainerVisibility() {
        mImageContainer.setVisibility(mIsolatedMessage != null && mImagesAtEnd
        mImageContainer.setVisibility(mIsolatedMessage != null
                && mImageDisplayLocation == IMAGE_DISPLAY_LOCATION_AT_END
                ? View.VISIBLE : View.GONE);
    }

@@ -620,9 +644,9 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
        mClippingDisabled = disabled;
    }

    public void setDisplayImagesAtEnd(boolean atEnd) {
        if (mImagesAtEnd != atEnd) {
            mImagesAtEnd = atEnd;
    public void setImageDisplayLocation(@ImageDisplayLocation int displayLocation) {
        if (mImageDisplayLocation != displayLocation) {
            mImageDisplayLocation = displayLocation;
            updateImageContainerVisibility();
        }
    }
@@ -670,4 +694,13 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
            mMessagingIconContainer.setLayoutParams(layoutParams);
        }
    }

    @IntDef(prefix = {"IMAGE_DISPLAY_LOCATION_"}, value = {
            IMAGE_DISPLAY_LOCATION_INLINE,
            IMAGE_DISPLAY_LOCATION_AT_END,
            IMAGE_DISPLAY_LOCATION_EXTERNAL
    })
    @Retention(RetentionPolicy.SOURCE)
    private @interface ImageDisplayLocation {
    }
}
+19 −11
Original line number Diff line number Diff line
@@ -149,10 +149,16 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage
    protected void onDraw(Canvas canvas) {
        canvas.save();
        canvas.clipPath(getRoundedRectPath());
        int width = (int) Math.max(getActualWidth(), getActualHeight() * mAspectRatio);
        int height = (int) (width / mAspectRatio);
        // Calculate the right sizing ensuring that the image is nicely centered in the layout
        // during transitions
        int width = (int) Math.max((Math.min(getHeight(), getActualHeight()) * mAspectRatio),
                getActualWidth());
        int height = (int) Math.max((Math.min(getWidth(), getActualWidth()) / mAspectRatio),
                getActualHeight());
        height = (int) Math.max(height, width / mAspectRatio);
        int left = (int) ((getActualWidth() - width) / 2.0f);
        mDrawable.setBounds(left, 0, left + width, height);
        int top = (int) ((getActualHeight() - height) / 2.0f);
        mDrawable.setBounds(left, top, left + width, top + height);
        mDrawable.draw(canvas);
        canvas.restore();
    }
@@ -222,8 +228,17 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mIsIsolated) {
            // When isolated we have a fixed size, let's use that sizing.
            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
                    MeasureSpec.getSize(heightMeasureSpec));
        } else {
            // If we are displaying inline, we never want to go wider than actual size of the
            // image, otherwise it will look quite blurry.
            int width = Math.min(MeasureSpec.getSize(widthMeasureSpec),
                    mDrawable.getIntrinsicWidth());
            int height = (int) Math.min(MeasureSpec.getSize(heightMeasureSpec), width
                    / mAspectRatio);
            setMeasuredDimension(width, height);
        }
    }

@@ -231,7 +246,7 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        // TODO: ensure that this isn't called when transforming
        setActualWidth(getStaticWidth());
        setActualWidth(getWidth());
        setActualHeight(getHeight());
    }

@@ -258,13 +273,6 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage
        return mActualHeight;
    }

    public int getStaticWidth() {
        if (mIsIsolated) {
            return getWidth();
        }
        return (int) (getHeight() * mAspectRatio);
    }

    public void setIsolated(boolean isolated) {
        if (mIsIsolated != isolated) {
            mIsIsolated = isolated;
+11 −1
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.internal.widget;

import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_AT_END;
import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE;

import android.annotation.AttrRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -447,7 +450,9 @@ public class MessagingLayout extends FrameLayout
                newGroup = MessagingGroup.createGroup(mMessagingLinearLayout);
                mAddedGroups.add(newGroup);
            }
            newGroup.setDisplayImagesAtEnd(mDisplayImagesAtEnd);
            newGroup.setImageDisplayLocation(mDisplayImagesAtEnd
                    ? IMAGE_DISPLAY_LOCATION_AT_END
                    : IMAGE_DISPLAY_LOCATION_INLINE);
            newGroup.setIsInConversation(false);
            newGroup.setLayoutColor(mLayoutColor);
            newGroup.setTextColors(mSenderTextColor, mMessageTextColor);
@@ -599,4 +604,9 @@ public class MessagingLayout extends FrameLayout
    public ArrayList<MessagingGroup> getMessagingGroups() {
        return mGroups;
    }

    @Override
    public void setMessagingClippingDisabled(boolean clippingDisabled) {
        // Don't do anything, this is only used for the ConversationLayout
    }
}
Loading