1 /* 2 * Copyright (C) 2022 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.phone 18 19 import android.graphics.Rect 20 import android.view.View 21 import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent 22 import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.END_SIDE_CONTENT 23 import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.START_SIDE_CONTENT 24 import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentScope 25 import com.android.systemui.util.boundsOnScreen 26 import javax.inject.Inject 27 import javax.inject.Named 28 29 /** Provides various bounds within the status bar. */ 30 @StatusBarFragmentScope 31 class StatusBarBoundsProvider 32 @Inject 33 constructor( 34 private val changeListeners: Set<@JvmSuppressWildcards BoundsChangeListener>, 35 @Named(START_SIDE_CONTENT) private val startSideContent: View, 36 @Named(END_SIDE_CONTENT) private val endSideContent: View, 37 ) : StatusBarFragmentComponent.Startable { 38 39 interface BoundsChangeListener { 40 fun onStatusBarBoundsChanged() 41 } 42 43 private var previousBounds = 44 BoundsPair(start = startSideContent.boundsOnScreen, end = endSideContent.boundsOnScreen) 45 46 private val layoutListener = 47 View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> 48 val newBounds = BoundsPair(start = visibleStartSideBounds, end = visibleEndSideBounds) 49 if (previousBounds != newBounds) { 50 previousBounds = newBounds 51 changeListeners.forEach { it.onStatusBarBoundsChanged() } 52 } 53 } 54 55 override fun start() { 56 startSideContent.addOnLayoutChangeListener(layoutListener) 57 endSideContent.addOnLayoutChangeListener(layoutListener) 58 } 59 60 override fun stop() { 61 startSideContent.removeOnLayoutChangeListener(layoutListener) 62 endSideContent.removeOnLayoutChangeListener(layoutListener) 63 } 64 65 /** 66 * Returns the bounds of the end side of the status bar that are visible to the user. The end 67 * side is right when in LTR and is left when in RTL. 68 * 69 * Note that even though the layout might be larger, here we only return the bounds for what is 70 * visible to the user. 71 * 72 * The end side of the status bar contains the multi-user switcher and status icons such as 73 * wi-fi, battery, etc 74 */ 75 val visibleEndSideBounds: Rect 76 get() = endSideContent.boundsOnScreen 77 78 /** 79 * Returns the bounds of the start side of the status bar that are visible to the user. The 80 * start side is left when in LTR and is right when in RTL. 81 * 82 * Note that even though the layout might be larger, here we only return the bounds for what is 83 * visible to the user. 84 * 85 * The start side of the status bar contains the operator name, clock, on-going call chip, and 86 * notifications. 87 */ 88 val visibleStartSideBounds: Rect 89 get() = startSideContent.boundsOnScreen 90 } 91 92 private data class BoundsPair(val start: Rect, val end: Rect) 93