1 /* 2 * Copyright (C) 2015 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; 18 19 import android.app.Notification; 20 import android.content.Context; 21 import android.content.res.Resources; 22 import android.util.TypedValue; 23 import android.view.ContextThemeWrapper; 24 import android.view.LayoutInflater; 25 import android.view.ViewGroup; 26 import android.widget.TextView; 27 28 import com.android.systemui.R; 29 30 /** 31 * A class managing hybrid groups that include {@link HybridNotificationView} and the notification 32 * group overflow. 33 */ 34 public class HybridGroupManager { 35 36 private final Context mContext; 37 private final NotificationDozeHelper mDozer; 38 private final ViewGroup mParent; 39 40 private float mOverflowNumberSizeDark; 41 private int mOverflowNumberPaddingDark; 42 private float mOverflowNumberSize; 43 private int mOverflowNumberPadding; 44 45 private int mOverflowNumberColor; 46 private int mOverflowNumberColorDark; 47 private float mDarkAmount = 0f; 48 HybridGroupManager(Context ctx, ViewGroup parent)49 public HybridGroupManager(Context ctx, ViewGroup parent) { 50 mContext = ctx; 51 mParent = parent; 52 mDozer = new NotificationDozeHelper(); 53 initDimens(); 54 } 55 initDimens()56 public void initDimens() { 57 Resources res = mContext.getResources(); 58 mOverflowNumberSize = res.getDimensionPixelSize( 59 R.dimen.group_overflow_number_size); 60 mOverflowNumberSizeDark = res.getDimensionPixelSize( 61 R.dimen.group_overflow_number_size_dark); 62 mOverflowNumberPadding = res.getDimensionPixelSize( 63 R.dimen.group_overflow_number_padding); 64 mOverflowNumberPaddingDark = mOverflowNumberPadding + res.getDimensionPixelSize( 65 R.dimen.group_overflow_number_extra_padding_dark); 66 } 67 inflateHybridViewWithStyle(int style)68 private HybridNotificationView inflateHybridViewWithStyle(int style) { 69 LayoutInflater inflater = new ContextThemeWrapper(mContext, style) 70 .getSystemService(LayoutInflater.class); 71 HybridNotificationView hybrid = (HybridNotificationView) inflater.inflate( 72 R.layout.hybrid_notification, mParent, false); 73 mParent.addView(hybrid); 74 return hybrid; 75 } 76 inflateOverflowNumber()77 private TextView inflateOverflowNumber() { 78 LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class); 79 TextView numberView = (TextView) inflater.inflate( 80 R.layout.hybrid_overflow_number, mParent, false); 81 mParent.addView(numberView); 82 updateOverFlowNumberColor(numberView); 83 return numberView; 84 } 85 updateOverFlowNumberColor(TextView numberView)86 private void updateOverFlowNumberColor(TextView numberView) { 87 numberView.setTextColor(NotificationUtils.interpolateColors( 88 mOverflowNumberColor, mOverflowNumberColorDark, mDarkAmount)); 89 } 90 setOverflowNumberColor(TextView numberView, int colorRegular, int colorDark)91 public void setOverflowNumberColor(TextView numberView, int colorRegular, int colorDark) { 92 mOverflowNumberColor = colorRegular; 93 mOverflowNumberColorDark = colorDark; 94 if (numberView != null) { 95 updateOverFlowNumberColor(numberView); 96 } 97 } 98 bindFromNotification(HybridNotificationView reusableView, Notification notification)99 public HybridNotificationView bindFromNotification(HybridNotificationView reusableView, 100 Notification notification) { 101 return bindFromNotificationWithStyle(reusableView, notification, 102 R.style.HybridNotification); 103 } 104 bindAmbientFromNotification(HybridNotificationView reusableView, Notification notification)105 public HybridNotificationView bindAmbientFromNotification(HybridNotificationView reusableView, 106 Notification notification) { 107 return bindFromNotificationWithStyle(reusableView, notification, 108 R.style.HybridNotification_Ambient); 109 } 110 bindFromNotificationWithStyle( HybridNotificationView reusableView, Notification notification, int style)111 private HybridNotificationView bindFromNotificationWithStyle( 112 HybridNotificationView reusableView, Notification notification, int style) { 113 if (reusableView == null) { 114 reusableView = inflateHybridViewWithStyle(style); 115 } 116 CharSequence titleText = resolveTitle(notification); 117 CharSequence contentText = resolveText(notification); 118 reusableView.bind(titleText, contentText); 119 return reusableView; 120 } 121 resolveText(Notification notification)122 private CharSequence resolveText(Notification notification) { 123 CharSequence contentText = notification.extras.getCharSequence(Notification.EXTRA_TEXT); 124 if (contentText == null) { 125 contentText = notification.extras.getCharSequence(Notification.EXTRA_BIG_TEXT); 126 } 127 return contentText; 128 } 129 resolveTitle(Notification notification)130 private CharSequence resolveTitle(Notification notification) { 131 CharSequence titleText = notification.extras.getCharSequence(Notification.EXTRA_TITLE); 132 if (titleText == null) { 133 titleText = notification.extras.getCharSequence(Notification.EXTRA_TITLE_BIG); 134 } 135 return titleText; 136 } 137 bindOverflowNumber(TextView reusableView, int number)138 public TextView bindOverflowNumber(TextView reusableView, int number) { 139 if (reusableView == null) { 140 reusableView = inflateOverflowNumber(); 141 } 142 String text = mContext.getResources().getString( 143 R.string.notification_group_overflow_indicator, number); 144 if (!text.equals(reusableView.getText())) { 145 reusableView.setText(text); 146 } 147 String contentDescription = String.format(mContext.getResources().getQuantityString( 148 R.plurals.notification_group_overflow_description, number), number); 149 150 reusableView.setContentDescription(contentDescription); 151 return reusableView; 152 } 153 bindOverflowNumberAmbient(TextView titleView, Notification notification, int number)154 public TextView bindOverflowNumberAmbient(TextView titleView, Notification notification, 155 int number) { 156 String text = mContext.getResources().getString( 157 R.string.notification_group_overflow_indicator_ambient, 158 resolveTitle(notification), number); 159 if (!text.equals(titleView.getText())) { 160 titleView.setText(text); 161 } 162 return titleView; 163 } 164 setOverflowNumberDark(TextView view, boolean dark, boolean fade, long delay)165 public void setOverflowNumberDark(TextView view, boolean dark, boolean fade, long delay) { 166 mDozer.setIntensityDark((f)->{ 167 mDarkAmount = f; 168 updateOverFlowNumberColor(view); 169 }, dark, fade, delay, view); 170 view.setTextSize(TypedValue.COMPLEX_UNIT_PX, 171 dark ? mOverflowNumberSizeDark : mOverflowNumberSize); 172 int paddingEnd = dark ? mOverflowNumberPaddingDark : mOverflowNumberPadding; 173 view.setPaddingRelative(view.getPaddingStart(), view.getPaddingTop(), paddingEnd, 174 view.getPaddingBottom()); 175 } 176 } 177