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.interruption; 18 19 import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP; 20 21 import android.util.ArrayMap; 22 23 import androidx.annotation.Nullable; 24 import androidx.core.os.CancellationSignal; 25 26 import com.android.internal.util.NotificationMessagingUtil; 27 import com.android.systemui.dagger.SysUISingleton; 28 import com.android.systemui.statusbar.NotificationPresenter; 29 import com.android.systemui.statusbar.notification.collection.NotificationEntry; 30 import com.android.systemui.statusbar.notification.collection.coordinator.HeadsUpCoordinator; 31 import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback; 32 import com.android.systemui.statusbar.notification.row.RowContentBindParams; 33 import com.android.systemui.statusbar.notification.row.RowContentBindStage; 34 35 import java.util.Map; 36 37 import javax.inject.Inject; 38 39 /** 40 * Wrapper around heads up view binding logic. {@link HeadsUpViewBinder} is responsible for 41 * figuring out the right heads up inflation parameters and inflating/freeing the heads up 42 * content view. 43 * 44 * TODO: This should be moved into {@link HeadsUpCoordinator} when the old pipeline is deprecated 45 * (i.e. when {@link HeadsUpController} is removed). 46 */ 47 @SysUISingleton 48 public class HeadsUpViewBinder { 49 private final RowContentBindStage mStage; 50 private final NotificationMessagingUtil mNotificationMessagingUtil; 51 private final Map<NotificationEntry, CancellationSignal> mOngoingBindCallbacks = 52 new ArrayMap<>(); 53 54 private NotificationPresenter mNotificationPresenter; 55 56 @Inject HeadsUpViewBinder( NotificationMessagingUtil notificationMessagingUtil, RowContentBindStage bindStage)57 HeadsUpViewBinder( 58 NotificationMessagingUtil notificationMessagingUtil, 59 RowContentBindStage bindStage) { 60 mNotificationMessagingUtil = notificationMessagingUtil; 61 mStage = bindStage; 62 } 63 64 /** 65 * Set notification presenter to determine parameters for heads up view inflation. 66 */ setPresenter(NotificationPresenter presenter)67 public void setPresenter(NotificationPresenter presenter) { 68 mNotificationPresenter = presenter; 69 } 70 71 /** 72 * Bind heads up view to the notification row. 73 * @param callback callback after heads up view is bound 74 */ bindHeadsUpView(NotificationEntry entry, @Nullable BindCallback callback)75 public void bindHeadsUpView(NotificationEntry entry, @Nullable BindCallback callback) { 76 RowContentBindParams params = mStage.getStageParams(entry); 77 final boolean isImportantMessage = mNotificationMessagingUtil.isImportantMessaging( 78 entry.getSbn(), entry.getImportance()); 79 final boolean useIncreasedHeadsUp = isImportantMessage 80 && !mNotificationPresenter.isPresenterFullyCollapsed(); 81 params.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp); 82 params.requireContentViews(FLAG_CONTENT_VIEW_HEADS_UP); 83 CancellationSignal signal = mStage.requestRebind(entry, en -> { 84 en.getRow().setUsesIncreasedHeadsUpHeight(params.useIncreasedHeadsUpHeight()); 85 if (callback != null) { 86 callback.onBindFinished(en); 87 } 88 }); 89 abortBindCallback(entry); 90 mOngoingBindCallbacks.put(entry, signal); 91 } 92 93 /** 94 * Abort any callbacks waiting for heads up view binding to finish for a given notification. 95 * @param entry notification with bind in progress 96 */ abortBindCallback(NotificationEntry entry)97 public void abortBindCallback(NotificationEntry entry) { 98 CancellationSignal ongoingBindCallback = mOngoingBindCallbacks.remove(entry); 99 if (ongoingBindCallback != null) { 100 ongoingBindCallback.cancel(); 101 } 102 } 103 104 /** 105 * Unbind the heads up view from the notification row. 106 */ unbindHeadsUpView(NotificationEntry entry)107 public void unbindHeadsUpView(NotificationEntry entry) { 108 abortBindCallback(entry); 109 mStage.getStageParams(entry).markContentViewsFreeable(FLAG_CONTENT_VIEW_HEADS_UP); 110 mStage.requestRebind(entry, null); 111 } 112 } 113