• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
18 
19 import static android.service.notification.NotificationListenerService.Ranking;
20 
21 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.ENABLE_NAS_FEEDBACK;
22 
23 import android.app.NotificationManager;
24 import android.content.Context;
25 import android.os.Handler;
26 import android.provider.DeviceConfig;
27 import android.util.Pair;
28 
29 import com.android.internal.R;
30 import com.android.systemui.dagger.SysUISingleton;
31 import com.android.systemui.dagger.qualifiers.Main;
32 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
33 import com.android.systemui.util.DeviceConfigProxy;
34 
35 import javax.inject.Inject;
36 
37 /**
38  * Determines whether to show any indicators or controls related to notification assistant.
39  *
40  * Flags protect any changes from being shown. Notifications that are adjusted by the assistant
41  * should show an indicator.
42  */
43 @SysUISingleton
44 public class AssistantFeedbackController {
45     private final Context mContext;
46     private final Handler mHandler;
47     private final DeviceConfigProxy mDeviceConfigProxy;
48 
49     public static final int STATUS_UNCHANGED = 0;
50     public static final int STATUS_ALERTED = 1;
51     public static final int STATUS_SILENCED = 2;
52     public static final int STATUS_PROMOTED = 3;
53     public static final int STATUS_DEMOTED = 4;
54 
55     private volatile boolean mFeedbackEnabled;
56 
57     private final DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener =
58             new DeviceConfig.OnPropertiesChangedListener() {
59                 @Override
60                 public void onPropertiesChanged(DeviceConfig.Properties properties) {
61                     if (properties.getKeyset().contains(ENABLE_NAS_FEEDBACK)) {
62                         mFeedbackEnabled = properties.getBoolean(
63                                 ENABLE_NAS_FEEDBACK, false);
64                     }
65                 }
66             };
67 
68     /** Injected constructor */
69     @Inject
AssistantFeedbackController(@ain Handler handler, Context context, DeviceConfigProxy proxy)70     public AssistantFeedbackController(@Main Handler handler,
71             Context context, DeviceConfigProxy proxy) {
72         mHandler = handler;
73         mContext = context;
74         mDeviceConfigProxy = proxy;
75         mFeedbackEnabled = mDeviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
76                 ENABLE_NAS_FEEDBACK, false);
77         mDeviceConfigProxy.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
78                 this::postToHandler, mPropertiesChangedListener);
79     }
80 
postToHandler(Runnable r)81     private void postToHandler(Runnable r) {
82         this.mHandler.post(r);
83     }
84 
85     /**
86      * Determines whether to show any user controls related to the assistant based on the
87      * DeviceConfig flag value
88      */
isFeedbackEnabled()89     public boolean isFeedbackEnabled() {
90         return mFeedbackEnabled;
91     }
92 
93     /**
94      * Get the feedback status according to assistant's adjustments
95      *
96      * @param entry Notification Entry to show feedback for
97      */
getFeedbackStatus(NotificationEntry entry)98     public int getFeedbackStatus(NotificationEntry entry) {
99         if (!isFeedbackEnabled()) {
100             return STATUS_UNCHANGED;
101         }
102         Ranking ranking = entry.getRanking();
103         int oldImportance = ranking.getChannel().getImportance();
104         int newImportance = ranking.getImportance();
105         if (oldImportance < NotificationManager.IMPORTANCE_DEFAULT
106                 && newImportance >= NotificationManager.IMPORTANCE_DEFAULT) {
107             return STATUS_ALERTED;
108         } else if (oldImportance >= NotificationManager.IMPORTANCE_DEFAULT
109                 && newImportance < NotificationManager.IMPORTANCE_DEFAULT) {
110             return STATUS_SILENCED;
111         } else if (oldImportance < newImportance
112                 || ranking.getRankingAdjustment() == Ranking.RANKING_PROMOTED) {
113             return STATUS_PROMOTED;
114         } else if (oldImportance > newImportance
115                 || ranking.getRankingAdjustment() == Ranking.RANKING_DEMOTED) {
116             return STATUS_DEMOTED;
117         } else {
118             return STATUS_UNCHANGED;
119         }
120     }
121 
122     /**
123      * Determines whether to show feedback indicator. The feedback indicator will be shown
124      * if {@link #isFeedbackEnabled()} is enabled and assistant has changed this notification's rank
125      * or importance.
126      *
127      * @param entry Notification Entry to show feedback for
128      */
showFeedbackIndicator(NotificationEntry entry)129     public boolean showFeedbackIndicator(NotificationEntry entry) {
130         return getFeedbackStatus(entry) != STATUS_UNCHANGED;
131     }
132 
133     /**
134      * Get the feedback indicator image and content description resources according to assistant's
135      * changes on this notification's rank or importance.
136      *
137      * @param entry Notification Entry to show feedback for
138      */
getFeedbackResources(NotificationEntry entry)139     public Pair<Integer, Integer> getFeedbackResources(NotificationEntry entry) {
140         int feedbackStatus = getFeedbackStatus(entry);
141         switch (feedbackStatus) {
142             case STATUS_ALERTED:
143                 return new Pair(R.drawable.ic_feedback_alerted,
144                         R.string.notification_feedback_indicator_alerted);
145             case STATUS_SILENCED:
146                 return new Pair(R.drawable.ic_feedback_silenced,
147                         R.string.notification_feedback_indicator_silenced);
148             case STATUS_PROMOTED:
149                 return new Pair(R.drawable.ic_feedback_uprank,
150                         R.string.notification_feedback_indicator_promoted);
151             case STATUS_DEMOTED:
152                 return new Pair(R.drawable.ic_feedback_downrank,
153                         R.string.notification_feedback_indicator_demoted);
154             default:
155                 return new Pair(0, 0);
156         }
157     }
158 
159     /**
160      * Get the inline settings description resource according to assistant's changes on this
161      * notification's rank or importance.
162      *
163      * @param entry Notification Entry to show feedback for
164      */
getInlineDescriptionResource(NotificationEntry entry)165     public int getInlineDescriptionResource(NotificationEntry entry) {
166         int feedbackStatus = getFeedbackStatus(entry);
167         switch (feedbackStatus) {
168             case STATUS_ALERTED:
169                 return com.android.systemui.R.string.notification_channel_summary_automatic_alerted;
170             case STATUS_SILENCED:
171                 return com.android.systemui.R.string
172                         .notification_channel_summary_automatic_silenced;
173             case STATUS_PROMOTED:
174                 return com.android.systemui.R.string
175                         .notification_channel_summary_automatic_promoted;
176             case STATUS_DEMOTED:
177                 return com.android.systemui.R.string.notification_channel_summary_automatic_demoted;
178             default:
179                 return com.android.systemui.R.string.notification_channel_summary_automatic;
180         }
181     }
182 }
183