• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 package com.android.car.notification.template;
17 
18 import android.annotation.ColorInt;
19 import android.app.Notification;
20 import android.car.userlib.CarUserManagerHelper;
21 import android.content.Context;
22 import android.content.pm.ApplicationInfo;
23 import android.content.pm.PackageManager;
24 import android.content.res.TypedArray;
25 import android.graphics.drawable.Drawable;
26 import android.os.Bundle;
27 import android.service.notification.StatusBarNotification;
28 import android.text.TextUtils;
29 import android.util.AttributeSet;
30 import android.util.Log;
31 import android.view.View;
32 import android.widget.DateTimeView;
33 import android.widget.ImageView;
34 import android.widget.LinearLayout;
35 import android.widget.TextView;
36 
37 import androidx.annotation.Nullable;
38 
39 import com.android.car.notification.R;
40 
41 /**
42  * Notification header view that contains the issuer app icon and name, and extra information.
43  */
44 public class CarNotificationHeaderView extends LinearLayout {
45 
46     private static final String TAG = "car_notification_header";
47 
48     private final PackageManager mPackageManager;
49     private final CarUserManagerHelper mCarUserManagerHelper;
50     private final int mDefaultTextColor;
51     private final String mSeparatorText;
52 
53     private boolean mIsHeadsUp;
54     private ImageView mIconView;
55     private TextView mHeaderTextView;
56     private DateTimeView mTimeView;
57 
CarNotificationHeaderView(Context context)58     public CarNotificationHeaderView(Context context) {
59         super(context);
60     }
61 
CarNotificationHeaderView(Context context, AttributeSet attrs)62     public CarNotificationHeaderView(Context context, AttributeSet attrs) {
63         super(context, attrs);
64         init(attrs);
65     }
66 
CarNotificationHeaderView(Context context, AttributeSet attrs, int defStyleAttr)67     public CarNotificationHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
68         super(context, attrs, defStyleAttr);
69         init(attrs);
70     }
71 
CarNotificationHeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)72     public CarNotificationHeaderView(Context context, AttributeSet attrs, int defStyleAttr,
73             int defStyleRes) {
74         super(context, attrs, defStyleAttr, defStyleRes);
75         init(attrs);
76     }
77 
78     {
79         mPackageManager = getContext().getPackageManager();
80         mCarUserManagerHelper = new CarUserManagerHelper(getContext());
81         mDefaultTextColor = getContext().getColor(R.color.primary_text_color);
82         mSeparatorText = getContext().getString(R.string.header_text_separator);
getContext()83         inflate(getContext(), R.layout.car_notification_header_view, this);
84     }
85 
init(AttributeSet attrs)86     private void init(AttributeSet attrs) {
87         TypedArray attributes =
88                 getContext().obtainStyledAttributes(attrs, R.styleable.CarNotificationHeaderView);
89         mIsHeadsUp =
90                 attributes.getBoolean(R.styleable.CarNotificationHeaderView_isHeadsUp,
91                         /* defValue= */ false);
92         attributes.recycle();
93     }
94 
95     @Override
onFinishInflate()96     protected void onFinishInflate() {
97         super.onFinishInflate();
98         mIconView = findViewById(R.id.app_icon);
99         mHeaderTextView = findViewById(R.id.header_text);
100         mTimeView = findViewById(R.id.time);
101         mTimeView.setShowRelativeTime(true);
102     }
103 
104     /**
105      * Binds the notification header that contains the issuer app icon and name.
106      *
107      * @param statusBarNotification the notification to be bound.
108      * @param isInGroup whether this notification is part of a grouped notification.
109      */
bind(StatusBarNotification statusBarNotification, boolean isInGroup)110     public void bind(StatusBarNotification statusBarNotification, boolean isInGroup) {
111         if (isInGroup) {
112             // if the notification is part of a group, individual headers are not shown
113             // instead, there is a header for the entire group in the group notification template
114             return;
115         }
116 
117         Notification notification = statusBarNotification.getNotification();
118 
119         Context packageContext = statusBarNotification.getPackageContext(getContext());
120 
121         // app icon
122         mIconView.setVisibility(View.VISIBLE);
123         Drawable drawable = notification.getSmallIcon().loadDrawable(packageContext);
124         mIconView.setImageDrawable(drawable);
125 
126         StringBuilder stringBuilder = new StringBuilder();
127 
128         // app name
129         mHeaderTextView.setVisibility(View.VISIBLE);
130 
131         if (mIsHeadsUp) {
132             mHeaderTextView.setText(loadHeaderAppName(statusBarNotification.getPackageName()));
133             mTimeView.setVisibility(View.GONE);
134             return;
135         }
136 
137         stringBuilder.append(loadHeaderAppName(statusBarNotification.getPackageName()));
138         Bundle extras = notification.extras;
139 
140         // optional field: sub text
141         if (!TextUtils.isEmpty(extras.getCharSequence(Notification.EXTRA_SUB_TEXT))) {
142             stringBuilder.append(mSeparatorText);
143             stringBuilder.append(extras.getCharSequence(Notification.EXTRA_SUB_TEXT));
144         }
145 
146         // optional field: content info
147         if (!TextUtils.isEmpty(extras.getCharSequence(Notification.EXTRA_INFO_TEXT))) {
148             stringBuilder.append(mSeparatorText);
149             stringBuilder.append(extras.getCharSequence(Notification.EXTRA_INFO_TEXT));
150         }
151 
152         // optional field: time
153         if (notification.showsTime()) {
154             stringBuilder.append(mSeparatorText);
155             mTimeView.setVisibility(View.VISIBLE);
156             mTimeView.setTime(notification.when);
157         }
158 
159         mHeaderTextView.setText(stringBuilder);
160     }
161 
162     /**
163      * Sets the color for the small icon.
164      */
setSmallIconColor(@olorInt int color)165     public void setSmallIconColor(@ColorInt int color) {
166         mIconView.setColorFilter(color);
167     }
168 
169     /**
170      * Sets the header text color.
171      */
setHeaderTextColor(@olorInt int color)172     public void setHeaderTextColor(@ColorInt int color) {
173         mHeaderTextView.setTextColor(color);
174     }
175 
176     /**
177      * Sets the text color for the time field.
178      */
setTimeTextColor(@olorInt int color)179     public void setTimeTextColor(@ColorInt int color) {
180         mTimeView.setTextColor(color);
181     }
182 
183     /**
184      * Resets the notification header empty.
185      */
reset()186     public void reset() {
187         mIconView.setVisibility(View.GONE);
188         mIconView.setImageDrawable(null);
189         setSmallIconColor(mDefaultTextColor);
190 
191         mHeaderTextView.setVisibility(View.GONE);
192         mHeaderTextView.setText(null);
193         setHeaderTextColor(mDefaultTextColor);
194 
195         mTimeView.setVisibility(View.GONE);
196         mTimeView.setTime(0);
197         setTimeTextColor(mDefaultTextColor);
198     }
199 
200     /**
201      * Fetches the application label given the package name.
202      *
203      * @param packageName The package name of the application.
204      * @return application label. Returns {@code null} when application name is not found.
205      */
206     @Nullable
loadHeaderAppName(String packageName)207     private String loadHeaderAppName(String packageName) {
208         ApplicationInfo info;
209         try {
210             info = mPackageManager.getApplicationInfoAsUser(packageName.trim(), /* flags= */ 0,
211                     mCarUserManagerHelper.getCurrentForegroundUserId());
212         } catch (PackageManager.NameNotFoundException e) {
213             Log.e(TAG, "Error fetching app name in car notification header" + e);
214             return null;
215         }
216         return String.valueOf(mPackageManager.getApplicationLabel(info));
217     }
218 }
219