blob: e6a4cff0d8930c8b2f6fc6ac0c6ab2da63d307c7 [file] [log] [blame]
Gus Prevas8ba88a82018-12-18 11:13:44 -05001/*
Ned Burns012048d2020-01-08 19:57:30 -05002 * Copyright (C) 2020 The Android Open Source Project
Gus Prevas8ba88a82018-12-18 11:13:44 -05003 *
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
Ned Burns012048d2020-01-08 19:57:30 -050017package com.android.systemui.statusbar.notification.collection.inflation;
Gus Prevas8ba88a82018-12-18 11:13:44 -050018
Kevin Han37423222020-03-10 16:05:07 -070019import static java.util.Objects.requireNonNull;
20
Gus Prevas8ba88a82018-12-18 11:13:44 -050021import android.annotation.Nullable;
22import android.content.Context;
Gus Prevas8ba88a82018-12-18 11:13:44 -050023import android.os.Build;
Gus Prevas8ba88a82018-12-18 11:13:44 -050024import android.view.ViewGroup;
25
Gus Prevas8ba88a82018-12-18 11:13:44 -050026import com.android.internal.util.NotificationMessagingUtil;
Gus Prevas8ba88a82018-12-18 11:13:44 -050027import com.android.systemui.statusbar.NotificationLockscreenUserManager;
28import com.android.systemui.statusbar.NotificationPresenter;
29import com.android.systemui.statusbar.NotificationRemoteInputManager;
30import com.android.systemui.statusbar.NotificationUiAdjustment;
Ned Burnsc5864672019-02-20 12:57:29 -050031import com.android.systemui.statusbar.notification.InflationException;
32import com.android.systemui.statusbar.notification.NotificationClicker;
Ned Burns012048d2020-01-08 19:57:30 -050033import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Ned Burnsd8b51542020-03-13 20:52:43 -040034import com.android.systemui.statusbar.notification.icon.IconManager;
Beverly Taid1e175c2020-03-10 16:37:04 +000035import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
Gus Prevas8ba88a82018-12-18 11:13:44 -050036import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
Dave Mankoffc0211ff2020-02-07 15:36:12 -050037import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
Kevin Han933dc7c2020-01-29 11:17:46 -080038import com.android.systemui.statusbar.notification.row.NotifBindPipeline;
Kevin Han0f98a6d2019-12-13 16:28:54 -080039import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder;
Kevin Han933dc7c2020-01-29 11:17:46 -080040import com.android.systemui.statusbar.notification.row.RowContentBindParams;
41import com.android.systemui.statusbar.notification.row.RowContentBindStage;
Gus Prevas8ba88a82018-12-18 11:13:44 -050042import com.android.systemui.statusbar.notification.row.RowInflaterTask;
Dave Mankoffc0211ff2020-02-07 15:36:12 -050043import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
Gus Prevas8ba88a82018-12-18 11:13:44 -050044import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
Daulet Zhanguzind0549ae2020-01-03 11:08:54 +000045
Dave Mankoff02dcaf52020-01-08 15:42:06 -050046import javax.inject.Inject;
Dave Mankoff56fe9e42020-01-08 15:42:06 -050047import javax.inject.Provider;
Dave Mankoff02dcaf52020-01-08 15:42:06 -050048import javax.inject.Singleton;
49
Gus Prevas8ba88a82018-12-18 11:13:44 -050050/** Handles inflating and updating views for notifications. */
Dave Mankoff02dcaf52020-01-08 15:42:06 -050051@Singleton
Ned Burnsc5864672019-02-20 12:57:29 -050052public class NotificationRowBinderImpl implements NotificationRowBinder {
Gus Prevas8ba88a82018-12-18 11:13:44 -050053
54 private static final String TAG = "NotificationViewManager";
55
Gus Prevas8ba88a82018-12-18 11:13:44 -050056 private final Context mContext;
Gus Prevas8ba88a82018-12-18 11:13:44 -050057 private final NotificationMessagingUtil mMessagingUtil;
Dave Mankoff02dcaf52020-01-08 15:42:06 -050058 private final NotificationRemoteInputManager mNotificationRemoteInputManager;
59 private final NotificationLockscreenUserManager mNotificationLockscreenUserManager;
Ned Burnsd8b51542020-03-13 20:52:43 -040060 private final NotifBindPipeline mNotifBindPipeline;
61 private final RowContentBindStage mRowContentBindStage;
62 private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
63 private final Provider<RowInflaterTask> mRowInflaterTaskProvider;
64 private final ExpandableNotificationRowComponent.Builder
65 mExpandableNotificationRowComponentBuilder;
66 private final IconManager mIconManager;
Gus Prevas8ba88a82018-12-18 11:13:44 -050067
Gus Prevas8ba88a82018-12-18 11:13:44 -050068 private NotificationPresenter mPresenter;
69 private NotificationListContainer mListContainer;
Gus Prevas8ba88a82018-12-18 11:13:44 -050070 private BindRowCallback mBindRowCallback;
71 private NotificationClicker mNotificationClicker;
Gus Prevas8ba88a82018-12-18 11:13:44 -050072
Dave Mankoff02dcaf52020-01-08 15:42:06 -050073 @Inject
Evan Laird181de622019-10-24 09:53:02 -040074 public NotificationRowBinderImpl(
75 Context context,
Dave Mankoffc0211ff2020-02-07 15:36:12 -050076 NotificationMessagingUtil notificationMessagingUtil,
Dave Mankoff02dcaf52020-01-08 15:42:06 -050077 NotificationRemoteInputManager notificationRemoteInputManager,
78 NotificationLockscreenUserManager notificationLockscreenUserManager,
Kevin Han933dc7c2020-01-29 11:17:46 -080079 NotifBindPipeline notifBindPipeline,
80 RowContentBindStage rowContentBindStage,
Beverly Taid1e175c2020-03-10 16:37:04 +000081 NotificationInterruptStateProvider notificationInterruptionStateProvider,
Dave Mankoff56fe9e42020-01-08 15:42:06 -050082 Provider<RowInflaterTask> rowInflaterTaskProvider,
Ned Burnsd8b51542020-03-13 20:52:43 -040083 ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder,
84 IconManager iconManager) {
Gus Prevas8ba88a82018-12-18 11:13:44 -050085 mContext = context;
Kevin Han933dc7c2020-01-29 11:17:46 -080086 mNotifBindPipeline = notifBindPipeline;
87 mRowContentBindStage = rowContentBindStage;
Dave Mankoffc0211ff2020-02-07 15:36:12 -050088 mMessagingUtil = notificationMessagingUtil;
Dave Mankoff02dcaf52020-01-08 15:42:06 -050089 mNotificationRemoteInputManager = notificationRemoteInputManager;
90 mNotificationLockscreenUserManager = notificationLockscreenUserManager;
Beverly Taid1e175c2020-03-10 16:37:04 +000091 mNotificationInterruptStateProvider = notificationInterruptionStateProvider;
Dave Mankoff56fe9e42020-01-08 15:42:06 -050092 mRowInflaterTaskProvider = rowInflaterTaskProvider;
Dave Mankoffc0211ff2020-02-07 15:36:12 -050093 mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder;
Ned Burnsd8b51542020-03-13 20:52:43 -040094 mIconManager = iconManager;
Gus Prevas8ba88a82018-12-18 11:13:44 -050095 }
96
Gus Prevas8ba88a82018-12-18 11:13:44 -050097 /**
98 * Sets up late-bound dependencies for this component.
99 */
100 public void setUpWithPresenter(NotificationPresenter presenter,
101 NotificationListContainer listContainer,
Gus Prevas8ba88a82018-12-18 11:13:44 -0500102 BindRowCallback bindRowCallback) {
103 mPresenter = presenter;
104 mListContainer = listContainer;
Gus Prevas8ba88a82018-12-18 11:13:44 -0500105 mBindRowCallback = bindRowCallback;
Ned Burnsd8b51542020-03-13 20:52:43 -0400106
107 mIconManager.attach();
Gus Prevas8ba88a82018-12-18 11:13:44 -0500108 }
109
110 public void setNotificationClicker(NotificationClicker clicker) {
111 mNotificationClicker = clicker;
112 }
113
Gus Prevas8ba88a82018-12-18 11:13:44 -0500114 /**
115 * Inflates the views for the given entry (possibly asynchronously).
116 */
Ned Burnsc5864672019-02-20 12:57:29 -0500117 @Override
Kevin Hanbd142932020-03-10 18:27:50 -0700118 public void inflateViews(
119 NotificationEntry entry,
120 Runnable onDismissRunnable,
121 NotificationRowContentBinder.InflationCallback callback)
Gus Prevas86928bb2019-01-04 16:46:13 -0500122 throws InflationException {
Gus Prevas8ba88a82018-12-18 11:13:44 -0500123 ViewGroup parent = mListContainer.getViewParentForNotification(entry);
Gus Prevas8ba88a82018-12-18 11:13:44 -0500124
Gus Prevas8ba88a82018-12-18 11:13:44 -0500125 if (entry.rowExists()) {
Ned Burnsd8b51542020-03-13 20:52:43 -0400126 mIconManager.updateIcons(entry);
Kevin Han37423222020-03-10 16:05:07 -0700127 ExpandableNotificationRow row = entry.getRow();
128 row.reset();
129 updateRow(entry, row);
Kevin Hanbd142932020-03-10 18:27:50 -0700130 inflateContentViews(entry, row, callback);
Dave Mankoffc0211ff2020-02-07 15:36:12 -0500131 entry.getRowController().setOnDismissRunnable(onDismissRunnable);
Gus Prevas8ba88a82018-12-18 11:13:44 -0500132 } else {
Ned Burnsd8b51542020-03-13 20:52:43 -0400133 mIconManager.createIcons(entry);
Dave Mankoff56fe9e42020-01-08 15:42:06 -0500134 mRowInflaterTaskProvider.get().inflate(mContext, parent, entry,
Gus Prevas8ba88a82018-12-18 11:13:44 -0500135 row -> {
Dave Mankoffc0211ff2020-02-07 15:36:12 -0500136 // Setup the controller for the view.
137 ExpandableNotificationRowComponent component =
138 mExpandableNotificationRowComponentBuilder
139 .expandableNotificationRow(row)
140 .notificationEntry(entry)
141 .onDismissRunnable(onDismissRunnable)
Dave Mankoffc0211ff2020-02-07 15:36:12 -0500142 .rowContentBindStage(mRowContentBindStage)
143 .onExpandClickListener(mPresenter)
144 .build();
145 ExpandableNotificationRowController rowController =
146 component.getExpandableNotificationRowController();
147 rowController.init();
148 entry.setRowController(rowController);
Kevin Han37423222020-03-10 16:05:07 -0700149 bindRow(entry, row);
150 updateRow(entry, row);
Kevin Hanbd142932020-03-10 18:27:50 -0700151 inflateContentViews(entry, row, callback);
Gus Prevas8ba88a82018-12-18 11:13:44 -0500152 });
153 }
154 }
155
Kevin Han37423222020-03-10 16:05:07 -0700156 /**
157 * Bind row to various controllers and managers. This is only called when the row is first
158 * created.
159 *
160 * TODO: This method associates a row with an entry, but eventually needs to not do that
161 */
162 private void bindRow(NotificationEntry entry, ExpandableNotificationRow row) {
Kevin Han5182c9f2020-01-07 17:54:43 -0800163 mListContainer.bindRow(row);
164 mNotificationRemoteInputManager.bindRow(row);
Kevin Han37423222020-03-10 16:05:07 -0700165 row.setOnActivatedListener(mPresenter);
Kevin Han933dc7c2020-01-29 11:17:46 -0800166 entry.setRow(row);
167 row.setEntry(entry);
168 mNotifBindPipeline.manageRow(entry, row);
Kevin Han37423222020-03-10 16:05:07 -0700169 mBindRowCallback.onBindRow(row);
Gus Prevas8ba88a82018-12-18 11:13:44 -0500170 }
171
172 /**
173 * Updates the views bound to an entry when the entry's ranking changes, either in-place or by
174 * reinflating them.
Kevin Hanbd142932020-03-10 18:27:50 -0700175 *
176 * TODO: Should this method be in this class?
Gus Prevas8ba88a82018-12-18 11:13:44 -0500177 */
Ned Burnsc5864672019-02-20 12:57:29 -0500178 @Override
Gus Prevas8ba88a82018-12-18 11:13:44 -0500179 public void onNotificationRankingUpdated(
Ned Burnsf81c4c42019-01-07 14:10:43 -0500180 NotificationEntry entry,
Gus Prevas8ba88a82018-12-18 11:13:44 -0500181 @Nullable Integer oldImportance,
182 NotificationUiAdjustment oldAdjustment,
Kevin Han13909302020-04-15 14:53:17 -0700183 NotificationUiAdjustment newAdjustment,
184 NotificationRowContentBinder.InflationCallback callback) {
Gus Prevas8ba88a82018-12-18 11:13:44 -0500185 if (NotificationUiAdjustment.needReinflate(oldAdjustment, newAdjustment)) {
186 if (entry.rowExists()) {
Kevin Han37423222020-03-10 16:05:07 -0700187 ExpandableNotificationRow row = entry.getRow();
188 row.reset();
189 updateRow(entry, row);
Kevin Han13909302020-04-15 14:53:17 -0700190 inflateContentViews(entry, row, callback);
Gus Prevas8ba88a82018-12-18 11:13:44 -0500191 } else {
192 // Once the RowInflaterTask is done, it will pick up the updated entry, so
193 // no-op here.
194 }
195 } else {
Ned Burns60e94592019-09-06 14:47:25 -0400196 if (oldImportance != null && entry.getImportance() != oldImportance) {
Gus Prevas8ba88a82018-12-18 11:13:44 -0500197 if (entry.rowExists()) {
198 entry.getRow().onNotificationRankingUpdated();
199 }
200 }
201 }
202 }
203
Kevin Han37423222020-03-10 16:05:07 -0700204 /**
205 * Update row after the notification has updated.
206 *
207 * @param entry notification that has updated
208 */
209 private void updateRow(
Ned Burnsf81c4c42019-01-07 14:10:43 -0500210 NotificationEntry entry,
Ned Burnsf529ec22019-02-12 19:33:50 -0500211 ExpandableNotificationRow row) {
Gus Prevas8ba88a82018-12-18 11:13:44 -0500212 row.setLegacy(entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD
213 && entry.targetSdk < Build.VERSION_CODES.LOLLIPOP);
214
Kevin Han37423222020-03-10 16:05:07 -0700215 // bind the click event to the content area
216 requireNonNull(mNotificationClicker).register(row, entry.getSbn());
217 }
Gus Prevas8ba88a82018-12-18 11:13:44 -0500218
Kevin Han37423222020-03-10 16:05:07 -0700219 /**
220 * Inflate the row's basic content views.
221 */
222 private void inflateContentViews(
223 NotificationEntry entry,
Kevin Hanbd142932020-03-10 18:27:50 -0700224 ExpandableNotificationRow row,
Kevin Han13909302020-04-15 14:53:17 -0700225 @Nullable NotificationRowContentBinder.InflationCallback inflationCallback) {
Kevin Han933dc7c2020-01-29 11:17:46 -0800226 final boolean useIncreasedCollapsedHeight =
Kevin Han37423222020-03-10 16:05:07 -0700227 mMessagingUtil.isImportantMessaging(entry.getSbn(), entry.getImportance());
Kevin Han933dc7c2020-01-29 11:17:46 -0800228 final boolean isLowPriority = entry.isAmbient();
229
230 RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
231 params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
Kevin Han933dc7c2020-01-29 11:17:46 -0800232 params.setUseLowPriority(entry.isAmbient());
Gus Prevas8ba88a82018-12-18 11:13:44 -0500233
Kevin Han37423222020-03-10 16:05:07 -0700234 // TODO: Replace this API with RowContentBindParams directly. Also move to a separate
235 // redaction controller.
Dave Mankoff02dcaf52020-01-08 15:42:06 -0500236 row.setNeedsRedaction(mNotificationLockscreenUserManager.needsRedaction(entry));
Kevin Han37423222020-03-10 16:05:07 -0700237
Kevin Han27453362020-02-06 16:54:50 -0800238 params.rebindAllContentViews();
Kevin Han933dc7c2020-01-29 11:17:46 -0800239 mRowContentBindStage.requestRebind(entry, en -> {
240 row.setUsesIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
Kevin Han933dc7c2020-01-29 11:17:46 -0800241 row.setIsLowPriority(isLowPriority);
Kevin Han13909302020-04-15 14:53:17 -0700242 if (inflationCallback != null) {
243 inflationCallback.onAsyncInflationFinished(en);
244 }
Kevin Han933dc7c2020-01-29 11:17:46 -0800245 });
Gus Prevas8ba88a82018-12-18 11:13:44 -0500246 }
247
Gus Prevas8ba88a82018-12-18 11:13:44 -0500248 /** Callback for when a row is bound to an entry. */
249 public interface BindRowCallback {
250 /**
Kevin Han37423222020-03-10 16:05:07 -0700251 * Called when a new row is created and bound to a notification.
Gus Prevas8ba88a82018-12-18 11:13:44 -0500252 */
Kevin Han37423222020-03-10 16:05:07 -0700253 void onBindRow(ExpandableNotificationRow row);
Gus Prevas8ba88a82018-12-18 11:13:44 -0500254 }
255}