blob: 0162deb55143f28e0f5120142ff61f2b79eca287 [file] [log] [blame]
Gus Prevaseb4e2e12018-12-28 14:57:59 -05001/*
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
17package com.android.systemui;
18
19import android.app.Notification;
20import android.app.NotificationManager;
21import android.content.Context;
22import android.os.Bundle;
23import android.service.notification.StatusBarNotification;
24import android.util.Log;
25
26import com.android.internal.statusbar.NotificationVisibility;
Gus Prevaseb4e2e12018-12-28 14:57:59 -050027import com.android.systemui.statusbar.notification.NotificationEntryListener;
28import com.android.systemui.statusbar.notification.NotificationEntryManager;
Ned Burnsf81c4c42019-01-07 14:10:43 -050029import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Gus Prevaseb4e2e12018-12-28 14:57:59 -050030
31import javax.inject.Inject;
32import javax.inject.Singleton;
33
34/** Updates foreground service notification state in response to notification data events. */
35@Singleton
36public class ForegroundServiceNotificationListener {
37
38 private static final String TAG = "FgServiceController";
39 private static final boolean DBG = false;
40
41 private final Context mContext;
42 private final ForegroundServiceController mForegroundServiceController;
43
44 @Inject
45 public ForegroundServiceNotificationListener(Context context,
46 ForegroundServiceController foregroundServiceController,
47 NotificationEntryManager notificationEntryManager) {
48 mContext = context;
49 mForegroundServiceController = foregroundServiceController;
50 notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
51 @Override
Ned Burnsf81c4c42019-01-07 14:10:43 -050052 public void onPendingEntryAdded(NotificationEntry entry) {
Gus Prevaseb4e2e12018-12-28 14:57:59 -050053 addNotification(entry.notification, entry.importance);
54 }
55
56 @Override
Mady Mellor0ad5b9d2019-01-08 14:59:55 -080057 public void onPostEntryUpdated(NotificationEntry entry) {
Gus Prevaseb4e2e12018-12-28 14:57:59 -050058 updateNotification(entry.notification, entry.importance);
59 }
60
61 @Override
62 public void onEntryRemoved(
Ned Burnsf81c4c42019-01-07 14:10:43 -050063 NotificationEntry entry,
Gus Prevaseb4e2e12018-12-28 14:57:59 -050064 NotificationVisibility visibility,
Gus Prevaseb4e2e12018-12-28 14:57:59 -050065 boolean removedByUser) {
Ned Burnsef2ef6c2019-01-02 16:48:08 -050066 removeNotification(entry.notification);
Gus Prevaseb4e2e12018-12-28 14:57:59 -050067 }
68 });
Evan Laird05597642019-08-05 17:11:54 -040069
70 notificationEntryManager.addNotificationLifetimeExtender(
71 new ForegroundServiceLifetimeExtender());
Gus Prevaseb4e2e12018-12-28 14:57:59 -050072 }
73
74 /**
75 * @param sbn notification that was just posted
76 */
77 private void addNotification(StatusBarNotification sbn, int importance) {
78 updateNotification(sbn, importance);
79 }
80
81 /**
82 * @param sbn notification that was just removed
83 */
84 private void removeNotification(StatusBarNotification sbn) {
85 mForegroundServiceController.updateUserState(
86 sbn.getUserId(),
87 new ForegroundServiceController.UserStateUpdateCallback() {
88 @Override
89 public boolean updateUserState(ForegroundServicesUserState userState) {
90 if (mForegroundServiceController.isDisclosureNotification(sbn)) {
91 // if you remove the dungeon entirely, we take that to mean there are
92 // no running services
93 userState.setRunningServices(null, 0);
94 return true;
95 } else {
96 // this is safe to call on any notification, not just
97 // FLAG_FOREGROUND_SERVICE
98 return userState.removeNotification(sbn.getPackageName(), sbn.getKey());
99 }
100 }
101
102 @Override
103 public void userStateNotFound(int userId) {
104 if (DBG) {
105 Log.w(TAG, String.format(
106 "user %d with no known notifications got removeNotification "
107 + "for %s",
108 sbn.getUserId(), sbn));
109 }
110 }
111 },
112 false /* don't create */);
113 }
114
115 /**
116 * @param sbn notification that was just changed in some way
117 */
118 private void updateNotification(StatusBarNotification sbn, int newImportance) {
119 mForegroundServiceController.updateUserState(
120 sbn.getUserId(),
121 userState -> {
122 if (mForegroundServiceController.isDisclosureNotification(sbn)) {
123 final Bundle extras = sbn.getNotification().extras;
124 if (extras != null) {
125 final String[] svcs = extras.getStringArray(
126 Notification.EXTRA_FOREGROUND_APPS);
127 userState.setRunningServices(svcs, sbn.getNotification().when);
128 }
129 } else {
130 userState.removeNotification(sbn.getPackageName(), sbn.getKey());
131 if (0 != (sbn.getNotification().flags
132 & Notification.FLAG_FOREGROUND_SERVICE)) {
133 if (newImportance > NotificationManager.IMPORTANCE_MIN) {
134 userState.addImportantNotification(sbn.getPackageName(),
135 sbn.getKey());
136 }
137 final Notification.Builder builder =
138 Notification.Builder.recoverBuilder(
139 mContext, sbn.getNotification());
140 if (builder.usesStandardHeader()) {
141 userState.addStandardLayoutNotification(
142 sbn.getPackageName(), sbn.getKey());
143 }
144 }
145 }
146 return true;
147 },
148 true /* create if not found */);
149 }
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500150}