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.view.InsetsFlags 20 import android.view.InsetsVisibilities 21 import android.view.ViewDebug 22 import android.view.WindowInsetsController.Appearance 23 import android.view.WindowInsetsController.Behavior 24 import com.android.internal.statusbar.LetterboxDetails 25 import com.android.internal.view.AppearanceRegion 26 import com.android.systemui.dump.DumpManager 27 import com.android.systemui.statusbar.SysuiStatusBarStateController 28 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent 29 import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope 30 import java.io.PrintWriter 31 import javax.inject.Inject 32 33 /** 34 * Top-level listener of system attributes changed. This class is __always the first__ one to be 35 * notified about changes. 36 * 37 * It is responsible for modifying any attributes if necessary, and then notifying the other 38 * downstream listeners. 39 */ 40 @CentralSurfacesScope 41 class SystemBarAttributesListener 42 @Inject 43 internal constructor( 44 private val centralSurfaces: CentralSurfaces, 45 private val letterboxAppearanceCalculator: LetterboxAppearanceCalculator, 46 private val statusBarStateController: SysuiStatusBarStateController, 47 private val lightBarController: LightBarController, 48 private val dumpManager: DumpManager, 49 ) : CentralSurfacesComponent.Startable, StatusBarBoundsProvider.BoundsChangeListener { 50 51 private var lastLetterboxAppearance: LetterboxAppearance? = null 52 private var lastSystemBarAttributesParams: SystemBarAttributesParams? = null 53 startnull54 override fun start() { 55 dumpManager.registerDumpable(javaClass.simpleName, this::dump) 56 } 57 stopnull58 override fun stop() { 59 dumpManager.unregisterDumpable(javaClass.simpleName) 60 } 61 onStatusBarBoundsChangednull62 override fun onStatusBarBoundsChanged() { 63 val params = lastSystemBarAttributesParams 64 if (params != null && shouldUseLetterboxAppearance(params.letterboxesArray)) { 65 onSystemBarAttributesChanged( 66 params.displayId, 67 params.appearance, 68 params.appearanceRegionsArray, 69 params.navbarColorManagedByIme, 70 params.behavior, 71 params.requestedVisibilities, 72 params.packageName, 73 params.letterboxesArray) 74 } 75 } 76 onSystemBarAttributesChangednull77 fun onSystemBarAttributesChanged( 78 displayId: Int, 79 @Appearance originalAppearance: Int, 80 originalAppearanceRegions: Array<AppearanceRegion>, 81 navbarColorManagedByIme: Boolean, 82 @Behavior behavior: Int, 83 requestedVisibilities: InsetsVisibilities, 84 packageName: String, 85 letterboxDetails: Array<LetterboxDetails> 86 ) { 87 lastSystemBarAttributesParams = 88 SystemBarAttributesParams( 89 displayId, 90 originalAppearance, 91 originalAppearanceRegions.toList(), 92 navbarColorManagedByIme, 93 behavior, 94 requestedVisibilities, 95 packageName, 96 letterboxDetails.toList()) 97 98 val (appearance, appearanceRegions) = 99 modifyAppearanceIfNeeded( 100 originalAppearance, originalAppearanceRegions, letterboxDetails) 101 102 val barModeChanged = centralSurfaces.setAppearance(appearance) 103 104 lightBarController.onStatusBarAppearanceChanged( 105 appearanceRegions, barModeChanged, centralSurfaces.barMode, navbarColorManagedByIme) 106 107 centralSurfaces.updateBubblesVisibility() 108 statusBarStateController.setSystemBarAttributes( 109 appearance, behavior, requestedVisibilities, packageName) 110 } 111 modifyAppearanceIfNeedednull112 private fun modifyAppearanceIfNeeded( 113 appearance: Int, 114 appearanceRegions: Array<AppearanceRegion>, 115 letterboxDetails: Array<LetterboxDetails> 116 ): Pair<Int, Array<AppearanceRegion>> = 117 if (shouldUseLetterboxAppearance(letterboxDetails)) { 118 val letterboxAppearance = 119 letterboxAppearanceCalculator.getLetterboxAppearance( 120 appearance, appearanceRegions, letterboxDetails) 121 lastLetterboxAppearance = letterboxAppearance 122 Pair(letterboxAppearance.appearance, letterboxAppearance.appearanceRegions) 123 } else { 124 lastLetterboxAppearance = null 125 Pair(appearance, appearanceRegions) 126 } 127 shouldUseLetterboxAppearancenull128 private fun shouldUseLetterboxAppearance(letterboxDetails: Array<LetterboxDetails>) = 129 letterboxDetails.isNotEmpty() 130 131 private fun dump(printWriter: PrintWriter, strings: Array<String>) { 132 printWriter.println("lastSystemBarAttributesParams: $lastSystemBarAttributesParams") 133 printWriter.println("lastLetterboxAppearance: $lastLetterboxAppearance") 134 } 135 } 136 137 /** 138 * Keeps track of the parameters passed in 139 * [SystemBarAttributesListener.onSystemBarAttributesChanged]. 140 */ 141 private data class SystemBarAttributesParams( 142 val displayId: Int, 143 @Appearance val appearance: Int, 144 val appearanceRegions: List<AppearanceRegion>, 145 val navbarColorManagedByIme: Boolean, 146 @Behavior val behavior: Int, 147 val requestedVisibilities: InsetsVisibilities, 148 val packageName: String, 149 val letterboxes: List<LetterboxDetails>, 150 ) { 151 val letterboxesArray = letterboxes.toTypedArray() 152 val appearanceRegionsArray = appearanceRegions.toTypedArray() toStringnull153 override fun toString(): String { 154 val appearanceToString = 155 ViewDebug.flagsToString(InsetsFlags::class.java, "appearance", appearance) 156 return """SystemBarAttributesParams( 157 displayId=$displayId, 158 appearance=$appearanceToString, 159 appearanceRegions=$appearanceRegions, 160 navbarColorManagedByIme=$navbarColorManagedByIme, 161 behavior=$behavior, 162 requestedVisibilities=$requestedVisibilities, 163 packageName='$packageName', 164 letterboxes=$letterboxes, 165 letterboxesArray=${letterboxesArray.contentToString()}, 166 appearanceRegionsArray=${appearanceRegionsArray.contentToString()} 167 )""".trimMargin() 168 } 169 } 170