1 /* 2 * Copyright (C) 2024 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.stack 18 19 import android.util.IndentingPrintWriter 20 import com.android.systemui.statusbar.notification.stack.shared.model.AccessibilityScrollEvent 21 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape 22 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrollState 23 import com.android.systemui.util.printSection 24 import com.android.systemui.util.println 25 import java.util.function.Consumer 26 27 /** 28 * This is a state holder object used by [NSSL][NotificationStackScrollLayout] to contain states 29 * provided by the `NotificationScrollViewBinder` to the `NotificationScrollView`. 30 * 31 * Unlike AmbientState, no class other than NSSL should ever have access to this class in any way. 32 * These fields are effectively NSSL's private fields. 33 */ 34 class ScrollViewFields { 35 /** Used to produce the clipping path */ 36 var clippingShape: ShadeScrimShape? = null 37 38 /** Used to produce a negative clipping path */ 39 var negativeClippingShape: ShadeScrimShape? = null 40 41 /** Scroll state of the notification shade. */ 42 var scrollState: ShadeScrollState = ShadeScrollState() 43 44 /** 45 * Height in view pixels at which the Notification Stack would like to be laid out, including 46 * Notification rows, paddings the Shelf and the Footer. 47 */ 48 var intrinsicStackHeight: Int = 0 49 50 /** 51 * When internal NSSL expansion requires the stack to be scrolled (e.g. to keep an expanding 52 * notification in view), that scroll amount can be sent here and it will be handled by the 53 * placeholder 54 */ 55 var syntheticScrollConsumer: Consumer<Float>? = null 56 57 /** 58 * When the NSSL navigates through the notifications with TalkBack, it can send scroll events 59 * here, to be able to browse through the whole list of notifications in the shade. 60 */ 61 var accessibilityScrollEventConsumer: Consumer<AccessibilityScrollEvent>? = null 62 63 /** 64 * When a gesture is consumed internally by NSSL but needs to be handled by other elements (such 65 * as the notif scrim) as overscroll, we can notify the placeholder through here. 66 */ 67 var currentGestureOverscrollConsumer: Consumer<Boolean>? = null 68 /** 69 * When a gesture is on open notification guts, which means scene container should not close the 70 * guts off of this gesture, we can notify the placeholder through here. 71 */ 72 var currentGestureInGutsConsumer: Consumer<Boolean>? = null 73 74 /** 75 * When a notification begins remote input, its bottom Y bound is sent to the placeholder 76 * through here in order to adjust to accommodate the IME. 77 */ 78 var remoteInputRowBottomBoundConsumer: Consumer<Float?>? = null 79 80 /** send the [syntheticScroll] to the [syntheticScrollConsumer], if present. */ sendSyntheticScrollnull81 fun sendSyntheticScroll(syntheticScroll: Float) = 82 syntheticScrollConsumer?.accept(syntheticScroll) 83 84 /** send [isCurrentGestureOverscroll] to the [currentGestureOverscrollConsumer], if present. */ 85 fun sendCurrentGestureOverscroll(isCurrentGestureOverscroll: Boolean) = 86 currentGestureOverscrollConsumer?.accept(isCurrentGestureOverscroll) 87 88 /** send [isCurrentGestureInGuts] to the [currentGestureInGutsConsumer], if present. */ 89 fun sendCurrentGestureInGuts(isCurrentGestureInGuts: Boolean) = 90 currentGestureInGutsConsumer?.accept(isCurrentGestureInGuts) 91 92 /** send [bottomY] to the [remoteInputRowBottomBoundConsumer], if present. */ 93 fun sendRemoteInputRowBottomBound(bottomY: Float?) = 94 remoteInputRowBottomBoundConsumer?.accept(bottomY) 95 96 /** send an [AccessibilityScrollEvent] to the [accessibilityScrollEventConsumer] if present */ 97 fun sendAccessibilityScrollEvent(event: AccessibilityScrollEvent) { 98 accessibilityScrollEventConsumer?.accept(event) 99 } 100 dumpnull101 fun dump(pw: IndentingPrintWriter) { 102 pw.printSection("StackViewStates") { 103 pw.println("scrimClippingShape", clippingShape) 104 pw.println("negativeClippingShape", negativeClippingShape) 105 pw.println("scrollState", scrollState) 106 } 107 } 108 } 109