• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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