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 final float mOverflowNumberSizeDark; 41 private final int mOverflowNumberPaddingDark; 42 private final float mOverflowNumberSize; 43 private final 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 54 Resources res = mContext.getResources(); 55 mOverflowNumberSize = res.getDimensionPixelSize( 56 R.dimen.group_overflow_number_size); 57 mOverflowNumberSizeDark = res.getDimensionPixelSize( 58 R.dimen.group_overflow_number_size_dark); 59 mOverflowNumberPadding = res.getDimensionPixelSize( 60 R.dimen.group_overflow_number_padding); 61 mOverflowNumberPaddingDark = mOverflowNumberPadding + res.getDimensionPixelSize( 62 R.dimen.group_overflow_number_extra_padding_dark); 63 } 64 inflateHybridViewWithStyle(int style)65 private HybridNotificationView inflateHybridViewWithStyle(int style) { 66 LayoutInflater inflater = new ContextThemeWrapper(mContext, style) 67 .getSystemService(LayoutInflater.class); 68 HybridNotificationView hybrid = (HybridNotificationView) inflater.inflate( 69 R.layout.hybrid_notification, mParent, false); 70 mParent.addView(hybrid); 71 return hybrid; 72 } 73 inflateOverflowNumber()74 private TextView inflateOverflowNumber() { 75 LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class); 76 TextView numberView = (TextView) inflater.inflate( 77 R.layout.hybrid_overflow_number, mParent, false); 78 mParent.addView(numberView); 79 updateOverFlowNumberColor(numberView); 80 return numberView; 81 } 82 updateOverFlowNumberColor(TextView numberView)83 private void updateOverFlowNumberColor(TextView numberView) { 84 numberView.setTextColor(NotificationUtils.interpolateColors( 85 mOverflowNumberColor, mOverflowNumberColorDark, mDarkAmount)); 86 } 87 setOverflowNumberColor(TextView numberView, int colorRegular, int colorDark)88 public void setOverflowNumberColor(TextView numberView, int colorRegular, int colorDark) { 89 mOverflowNumberColor = colorRegular; 90 mOverflowNumberColorDark = colorDark; 91 if (numberView != null) { 92 updateOverFlowNumberColor(numberView); 93 } 94 } 95 bindFromNotification(HybridNotificationView reusableView, Notification notification)96 public HybridNotificationView bindFromNotification(HybridNotificationView reusableView, 97 Notification notification) { 98 return bindFromNotificationWithStyle(reusableView, notification, 99 R.style.HybridNotification); 100 } 101 bindAmbientFromNotification(HybridNotificationView reusableView, Notification notification)102 public HybridNotificationView bindAmbientFromNotification(HybridNotificationView reusableView, 103 Notification notification) { 104 return bindFromNotificationWithStyle(reusableView, notification, 105 R.style.HybridNotification_Ambient); 106 } 107 bindFromNotificationWithStyle( HybridNotificationView reusableView, Notification notification, int style)108 private HybridNotificationView bindFromNotificationWithStyle( 109 HybridNotificationView reusableView, Notification notification, int style) { 110 if (reusableView == null) { 111 reusableView = inflateHybridViewWithStyle(style); 112 } 113 CharSequence titleText = resolveTitle(notification); 114 CharSequence contentText = resolveText(notification); 115 reusableView.bind(titleText, contentText); 116 return reusableView; 117 } 118 resolveText(Notification notification)119 private CharSequence resolveText(Notification notification) { 120 CharSequence contentText = notification.extras.getCharSequence(Notification.EXTRA_TEXT); 121 if (contentText == null) { 122 contentText = notification.extras.getCharSequence(Notification.EXTRA_BIG_TEXT); 123 } 124 return contentText; 125 } 126 resolveTitle(Notification notification)127 private CharSequence resolveTitle(Notification notification) { 128 CharSequence titleText = notification.extras.getCharSequence(Notification.EXTRA_TITLE); 129 if (titleText == null) { 130 titleText = notification.extras.getCharSequence(Notification.EXTRA_TITLE_BIG); 131 } 132 return titleText; 133 } 134 bindOverflowNumber(TextView reusableView, int number)135 public TextView bindOverflowNumber(TextView reusableView, int number) { 136 if (reusableView == null) { 137 reusableView = inflateOverflowNumber(); 138 } 139 String text = mContext.getResources().getString( 140 R.string.notification_group_overflow_indicator, number); 141 if (!text.equals(reusableView.getText())) { 142 reusableView.setText(text); 143 } 144 String contentDescription = String.format(mContext.getResources().getQuantityString( 145 R.plurals.notification_group_overflow_description, number), number); 146 147 reusableView.setContentDescription(contentDescription); 148 return reusableView; 149 } 150 setOverflowNumberDark(TextView view, boolean dark, boolean fade, long delay)151 public void setOverflowNumberDark(TextView view, boolean dark, boolean fade, long delay) { 152 mDozer.setIntensityDark((f)->{ 153 mDarkAmount = f; 154 updateOverFlowNumberColor(view); 155 }, dark, fade, delay); 156 view.setTextSize(TypedValue.COMPLEX_UNIT_PX, 157 dark ? mOverflowNumberSizeDark : mOverflowNumberSize); 158 int paddingEnd = dark ? mOverflowNumberPaddingDark : mOverflowNumberPadding; 159 view.setPaddingRelative(view.getPaddingStart(), view.getPaddingTop(), paddingEnd, 160 view.getPaddingBottom()); 161 } 162 } 163