1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar.notification.row; 18 19 import android.annotation.Nullable; 20 import android.content.Context; 21 import android.graphics.drawable.Icon; 22 import android.text.TextUtils; 23 import android.util.AttributeSet; 24 import android.view.View; 25 import android.widget.FrameLayout; 26 import android.widget.ImageView; 27 import android.widget.TextView; 28 29 import com.android.internal.widget.ConversationLayout; 30 import com.android.systemui.R; 31 import com.android.systemui.statusbar.notification.NotificationFadeAware; 32 33 /** 34 * A hybrid view which may contain information about one ore more conversations. 35 */ 36 public class HybridConversationNotificationView extends HybridNotificationView { 37 38 private ImageView mConversationIconView; 39 private TextView mConversationSenderName; 40 private View mConversationFacePile; 41 private int mSingleAvatarSize; 42 private int mFacePileSize; 43 private int mFacePileAvatarSize; 44 private int mFacePileProtectionWidth; 45 HybridConversationNotificationView(Context context)46 public HybridConversationNotificationView(Context context) { 47 this(context, null); 48 } 49 HybridConversationNotificationView(Context context, @Nullable AttributeSet attrs)50 public HybridConversationNotificationView(Context context, @Nullable AttributeSet attrs) { 51 this(context, attrs, 0); 52 } 53 HybridConversationNotificationView( Context context, @Nullable AttributeSet attrs, int defStyleAttr)54 public HybridConversationNotificationView( 55 Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 56 this(context, attrs, defStyleAttr, 0); 57 } 58 HybridConversationNotificationView( Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)59 public HybridConversationNotificationView( 60 Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { 61 super(context, attrs, defStyleAttr, defStyleRes); 62 } 63 64 @Override onFinishInflate()65 protected void onFinishInflate() { 66 super.onFinishInflate(); 67 mConversationIconView = requireViewById(com.android.internal.R.id.conversation_icon); 68 mConversationFacePile = requireViewById(com.android.internal.R.id.conversation_face_pile); 69 mConversationSenderName = requireViewById(R.id.conversation_notification_sender); 70 mFacePileSize = getResources() 71 .getDimensionPixelSize(R.dimen.conversation_single_line_face_pile_size); 72 mFacePileAvatarSize = getResources() 73 .getDimensionPixelSize(R.dimen.conversation_single_line_face_pile_avatar_size); 74 mSingleAvatarSize = getResources() 75 .getDimensionPixelSize(R.dimen.conversation_single_line_avatar_size); 76 mFacePileProtectionWidth = getResources().getDimensionPixelSize( 77 R.dimen.conversation_single_line_face_pile_protection_width); 78 mTransformationHelper.addViewTransformingToSimilar(mConversationIconView); 79 mTransformationHelper.addTransformedView(mConversationSenderName); 80 } 81 82 @Override bind(@ullable CharSequence title, @Nullable CharSequence text, @Nullable View contentView)83 public void bind(@Nullable CharSequence title, @Nullable CharSequence text, 84 @Nullable View contentView) { 85 if (!(contentView instanceof ConversationLayout)) { 86 super.bind(title, text, contentView); 87 return; 88 } 89 90 ConversationLayout conversationLayout = (ConversationLayout) contentView; 91 Icon conversationIcon = conversationLayout.getConversationIcon(); 92 if (conversationIcon != null) { 93 mConversationFacePile.setVisibility(GONE); 94 mConversationIconView.setVisibility(VISIBLE); 95 mConversationIconView.setImageIcon(conversationIcon); 96 setSize(mConversationIconView, mSingleAvatarSize); 97 } else { 98 // If there isn't an icon, generate a "face pile" based on the sender avatars 99 mConversationIconView.setVisibility(GONE); 100 mConversationFacePile.setVisibility(VISIBLE); 101 102 mConversationFacePile = 103 requireViewById(com.android.internal.R.id.conversation_face_pile); 104 ImageView facePileBottomBg = mConversationFacePile.requireViewById( 105 com.android.internal.R.id.conversation_face_pile_bottom_background); 106 ImageView facePileBottom = mConversationFacePile.requireViewById( 107 com.android.internal.R.id.conversation_face_pile_bottom); 108 ImageView facePileTop = mConversationFacePile.requireViewById( 109 com.android.internal.R.id.conversation_face_pile_top); 110 conversationLayout.bindFacePile(facePileBottomBg, facePileBottom, facePileTop); 111 setSize(mConversationFacePile, mFacePileSize); 112 setSize(facePileBottom, mFacePileAvatarSize); 113 setSize(facePileTop, mFacePileAvatarSize); 114 setSize(facePileBottomBg, mFacePileAvatarSize + 2 * mFacePileProtectionWidth); 115 mTransformationHelper.addViewTransformingToSimilar(facePileTop); 116 mTransformationHelper.addViewTransformingToSimilar(facePileBottom); 117 mTransformationHelper.addViewTransformingToSimilar(facePileBottomBg); 118 } 119 CharSequence conversationTitle = conversationLayout.getConversationTitle(); 120 if (TextUtils.isEmpty(conversationTitle)) { 121 conversationTitle = title; 122 } 123 if (conversationLayout.isOneToOne()) { 124 mConversationSenderName.setVisibility(GONE); 125 } else { 126 mConversationSenderName.setVisibility(VISIBLE); 127 mConversationSenderName.setText(conversationLayout.getConversationSenderName()); 128 } 129 CharSequence conversationText = conversationLayout.getConversationText(); 130 if (TextUtils.isEmpty(conversationText)) { 131 conversationText = text; 132 } 133 super.bind(conversationTitle, conversationText, conversationLayout); 134 } 135 setSize(View view, int size)136 private static void setSize(View view, int size) { 137 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) view.getLayoutParams(); 138 lp.width = size; 139 lp.height = size; 140 view.setLayoutParams(lp); 141 } 142 143 /** 144 * Apply the faded state as a layer type change to the face pile view which needs to have 145 * overlapping contents render precisely. 146 */ 147 @Override setNotificationFaded(boolean faded)148 public void setNotificationFaded(boolean faded) { 149 super.setNotificationFaded(faded); 150 NotificationFadeAware.setLayerTypeForFaded(mConversationFacePile, faded); 151 } 152 } 153