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.dagger;
18 
19 import android.content.Context;
20 import android.content.pm.ApplicationInfo;
21 import android.content.pm.PackageManager;
22 import android.service.notification.StatusBarNotification;
23 
24 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
25 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
26 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
27 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
28 import com.android.systemui.statusbar.phone.CentralSurfaces;
29 
30 import dagger.Binds;
31 import dagger.BindsInstance;
32 import dagger.Module;
33 import dagger.Provides;
34 import dagger.Subcomponent;
35 
36 /**
37  * Dagger Component for a {@link ExpandableNotificationRow}.
38  */
39 @Subcomponent(modules = {
40         ActivatableNotificationViewModule.class,
41         ExpandableNotificationRowComponent.ExpandableNotificationRowModule.class,
42         RemoteInputViewModule.class
43 })
44 @NotificationRowScope
45 public interface ExpandableNotificationRowComponent {
46 
47     /**
48      * Builder for {@link NotificationRowComponent}.
49      */
50     @Subcomponent.Builder
51     interface Builder {
52         // TODO: NotificationEntry contains a reference to ExpandableNotificationRow, so it
53         // should be possible to pull one from the other, but they aren't connected at the time
54         // this component is constructed.
55         @BindsInstance
expandableNotificationRow(ExpandableNotificationRow view)56         Builder expandableNotificationRow(ExpandableNotificationRow view);
57         @BindsInstance
notificationEntry(NotificationEntry entry)58         Builder notificationEntry(NotificationEntry entry);
59         @BindsInstance
onExpandClickListener(ExpandableNotificationRow.OnExpandClickListener presenter)60         Builder onExpandClickListener(ExpandableNotificationRow.OnExpandClickListener presenter);
build()61         ExpandableNotificationRowComponent build();
62     }
63 
64     /**
65      * Creates a ExpandableNotificationRowController.
66      */
67     @NotificationRowScope
getExpandableNotificationRowController()68     ExpandableNotificationRowController getExpandableNotificationRowController();
69 
70     /**
71      * Dagger Module that extracts interesting properties from an ExpandableNotificationRow.
72      */
73     @Module
74     abstract class ExpandableNotificationRowModule {
75 
76         /** ExpandableNotificationRow is provided as an instance of ActivatableNotificationView. */
77         @Binds
bindExpandableView(ExpandableNotificationRow view)78         abstract ActivatableNotificationView bindExpandableView(ExpandableNotificationRow view);
79 
80         @Provides
provideStatusBarNotification( NotificationEntry notificationEntry)81         static StatusBarNotification provideStatusBarNotification(
82                 NotificationEntry notificationEntry) {
83             return notificationEntry.getSbn();
84         }
85 
86         @Provides
87         @NotificationKey
provideNotificationKey(StatusBarNotification statusBarNotification)88         static String provideNotificationKey(StatusBarNotification statusBarNotification) {
89             return statusBarNotification.getKey();
90         }
91 
92         @Provides
93         @AppName
provideAppName(Context context, StatusBarNotification statusBarNotification)94         static String provideAppName(Context context, StatusBarNotification statusBarNotification) {
95             // Get the app name.
96             // Note that Notification.Builder#bindHeaderAppName has similar logic
97             // but since this field is used in the guts, it must be accurate.
98             // Therefore we will only show the application label, or, failing that, the
99             // package name. No substitutions.
100             PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(
101                     context, statusBarNotification.getUser().getIdentifier());
102             final String pkg = statusBarNotification.getPackageName();
103             try {
104                 final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
105                         PackageManager.MATCH_UNINSTALLED_PACKAGES
106                                 | PackageManager.MATCH_DISABLED_COMPONENTS);
107                 if (info != null) {
108                     return String.valueOf(pmUser.getApplicationLabel(info));
109                 }
110             } catch (PackageManager.NameNotFoundException e) {
111                 // Do nothing
112             }
113 
114             return pkg;
115         }
116     }
117 }
118