blob: 57d0588801180e2dee72f7383b2930cbd27a9180 [file] [log] [blame]
Kevina97ea052018-09-11 13:53:18 -07001/*
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.statusbar;
18
Ned Burns1a5e22f2019-02-14 15:11:52 -050019import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
Kevind5022f92018-10-08 18:30:26 -070020
Kevina97ea052018-09-11 13:53:18 -070021import android.annotation.NonNull;
22import android.content.Context;
23import android.content.res.Resources;
24import android.util.ArraySet;
25
26import com.android.internal.annotations.VisibleForTesting;
27import com.android.systemui.R;
Ned Burnsf81c4c42019-01-07 14:10:43 -050028import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Ned Burns1a5e22f2019-02-14 15:11:52 -050029import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
Kevina97ea052018-09-11 13:53:18 -070030
Jason Monk27d01a622018-12-10 15:57:09 -050031import javax.inject.Inject;
32import javax.inject.Singleton;
33
Kevina97ea052018-09-11 13:53:18 -070034/**
35 * Manager which handles high priority notifications that should "pulse" in when the device is
36 * dozing and/or in AOD. The pulse uses the notification's ambient view and pops in briefly
37 * before automatically dismissing the alert.
38 */
Jason Monk27d01a622018-12-10 15:57:09 -050039@Singleton
Lucas Dupinfb8bdbb2018-12-02 15:09:37 -080040public class AmbientPulseManager extends AlertingNotificationManager {
Kevina97ea052018-09-11 13:53:18 -070041
42 protected final ArraySet<OnAmbientChangedListener> mListeners = new ArraySet<>();
43 @VisibleForTesting
44 protected long mExtensionTime;
45
Jason Monk27d01a622018-12-10 15:57:09 -050046 @Inject
Kevina97ea052018-09-11 13:53:18 -070047 public AmbientPulseManager(@NonNull final Context context) {
48 Resources resources = context.getResources();
49 mAutoDismissNotificationDecay = resources.getInteger(R.integer.ambient_notification_decay);
50 mMinimumDisplayTime = resources.getInteger(R.integer.ambient_notification_minimum_time);
51 mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
52 }
53
54 /**
55 * Adds an OnAmbientChangedListener to observe events.
56 */
57 public void addListener(@NonNull OnAmbientChangedListener listener) {
58 mListeners.add(listener);
59 }
60
61 /**
62 * Removes the OnAmbientChangedListener from the observer list.
63 */
64 public void removeListener(@NonNull OnAmbientChangedListener listener) {
65 mListeners.remove(listener);
66 }
67
68 /**
69 * Extends the lifetime of the currently showing pulsing notification so that the pulse lasts
70 * longer.
71 */
72 public void extendPulse() {
73 AmbientEntry topEntry = getTopEntry();
74 if (topEntry == null) {
75 return;
76 }
77 topEntry.extendPulse();
78 }
79
Kevin01a53cb2018-11-09 18:19:54 -080080 public @InflationFlag int getContentFlag() {
81 return FLAG_CONTENT_VIEW_AMBIENT;
82 }
83
Kevina97ea052018-09-11 13:53:18 -070084 @Override
85 protected void onAlertEntryAdded(AlertEntry alertEntry) {
Ned Burnsf81c4c42019-01-07 14:10:43 -050086 NotificationEntry entry = alertEntry.mEntry;
Evan Laird94492852018-10-25 13:43:01 -040087 entry.setAmbientPulsing(true);
Kevina97ea052018-09-11 13:53:18 -070088 for (OnAmbientChangedListener listener : mListeners) {
89 listener.onAmbientStateChanged(entry, true);
90 }
91 }
92
93 @Override
94 protected void onAlertEntryRemoved(AlertEntry alertEntry) {
Ned Burnsf81c4c42019-01-07 14:10:43 -050095 NotificationEntry entry = alertEntry.mEntry;
Evan Laird94492852018-10-25 13:43:01 -040096 entry.setAmbientPulsing(false);
Kevina97ea052018-09-11 13:53:18 -070097 for (OnAmbientChangedListener listener : mListeners) {
98 listener.onAmbientStateChanged(entry, false);
99 }
Evan Laird94492852018-10-25 13:43:01 -0400100 entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT);
Kevina97ea052018-09-11 13:53:18 -0700101 }
102
103 @Override
104 protected AlertEntry createAlertEntry() {
105 return new AmbientEntry();
106 }
107
108 /**
109 * Get the top pulsing entry. This should be the currently showing one if there are multiple.
110 * @return the currently showing entry
111 */
112 private AmbientEntry getTopEntry() {
113 if (mAlertEntries.isEmpty()) {
114 return null;
115 }
116 AlertEntry topEntry = null;
117 for (AlertEntry entry : mAlertEntries.values()) {
118 if (topEntry == null || entry.compareTo(topEntry) < 0) {
119 topEntry = entry;
120 }
121 }
122 return (AmbientEntry) topEntry;
123 }
124
125 /**
126 * Observer interface for any changes in the ambient entries.
127 */
128 public interface OnAmbientChangedListener {
129 /**
130 * Called when an entry starts or stops pulsing.
131 * @param entry the entry that changed
132 * @param isPulsing true if the entry is now pulsing, false otherwise
133 */
Ned Burnsf81c4c42019-01-07 14:10:43 -0500134 void onAmbientStateChanged(NotificationEntry entry, boolean isPulsing);
Kevina97ea052018-09-11 13:53:18 -0700135 }
136
137 private final class AmbientEntry extends AlertEntry {
138 private boolean extended;
139
140 /**
141 * Extend the lifetime of the alertEntry so that it auto-removes later. Can only be
142 * extended once.
143 */
144 private void extendPulse() {
145 if (!extended) {
146 extended = true;
147 updateEntry(false);
148 }
149 }
150
151 @Override
152 public void reset() {
153 super.reset();
154 extended = false;
155 }
156
157 @Override
158 protected long calculateFinishTime() {
159 return super.calculateFinishTime() + (extended ? mExtensionTime : 0);
160 }
161 }
162}