[SB] Remove Dependency.get(DarkIconDispatcher) from PhoneStatusBarView.
Bug: 218354102
Flag: EXEMPT refactor
Test: change wallpaper between light and dark -> verify status bar clock
and battery tints change
Test: change between light and dark mode and open various apps -> verify
status bar clock and battery tints change
Test: atest PhoneStatusBarViewTest PhoneStatusBarViewControllerTest
Change-Id: I059621f77af7fae460f84502b7e1d6fa18b99fed
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index f178708..04604e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -16,8 +16,6 @@
package com.android.systemui.statusbar.phone;
-
-
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
@@ -38,11 +36,8 @@
import com.android.systemui.Dependency;
import com.android.systemui.Flags;
import com.android.systemui.Gefingerpoken;
-import com.android.systemui.plugins.DarkIconDispatcher;
-import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer;
-import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.window.StatusBarWindowController;
import com.android.systemui.user.ui.binder.StatusBarUserChipViewBinder;
import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel;
@@ -55,8 +50,6 @@
private final StatusBarContentInsetsProvider mContentInsetsProvider;
private final StatusBarWindowController mStatusBarWindowController;
- private DarkReceiver mBattery;
- private Clock mClock;
private int mRotationOrientation = -1;
@Nullable
private View mCutoutSpace;
@@ -93,8 +86,6 @@
@Override
public void onFinishInflate() {
super.onFinishInflate();
- mBattery = findViewById(R.id.battery);
- mClock = findViewById(R.id.clock);
mCutoutSpace = findViewById(R.id.cutout_space_view);
updateResources();
@@ -103,9 +94,6 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- // Always have Battery meters in the status bar observe the dark/light modes.
- Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mBattery);
- Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mClock);
if (updateDisplayParameters()) {
updateLayoutForCutout();
updateWindowHeight();
@@ -115,8 +103,6 @@
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mBattery);
- Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mClock);
mDisplayCutout = null;
}
@@ -136,10 +122,6 @@
updateWindowHeight();
}
- void onDensityOrFontScaleChanged() {
- mClock.onDensityOrFontScaleChanged();
- }
-
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (updateDisplayParameters()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index a818c05..468a3c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -23,10 +23,13 @@
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
+import androidx.annotation.VisibleForTesting
import com.android.systemui.Flags
import com.android.systemui.Gefingerpoken
+import com.android.systemui.battery.BatteryMeterView
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.ENABLE_UNFOLD_STATUS_BAR_ANIMATIONS
+import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.ui.view.WindowRootView
@@ -35,6 +38,7 @@
import com.android.systemui.shade.ShadeViewController
import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
+import com.android.systemui.statusbar.policy.Clock
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.window.StatusBarWindowStateController
import com.android.systemui.unfold.SysUIUnfoldComponent
@@ -68,19 +72,27 @@
private val viewUtil: ViewUtil,
private val configurationController: ConfigurationController,
private val statusOverlayHoverListenerFactory: StatusOverlayHoverListenerFactory,
+ private val darkIconDispatcher: DarkIconDispatcher,
) : ViewController<PhoneStatusBarView>(view) {
+ private lateinit var battery: BatteryMeterView
+ private lateinit var clock: Clock
private lateinit var statusContainer: View
private val configurationListener =
object : ConfigurationController.ConfigurationListener {
override fun onDensityOrFontScaleChanged() {
- mView.onDensityOrFontScaleChanged()
+ clock.onDensityOrFontScaleChanged()
}
}
override fun onViewAttached() {
statusContainer = mView.requireViewById(R.id.system_icons)
+ clock = mView.requireViewById(R.id.clock)
+ battery = mView.requireViewById(R.id.battery)
+
+ addDarkReceivers()
+
statusContainer.setOnHoverListener(
statusOverlayHoverListenerFactory.createDarkAwareListener(statusContainer)
)
@@ -133,7 +145,9 @@
}
}
- override fun onViewDetached() {
+ @VisibleForTesting
+ public override fun onViewDetached() {
+ removeDarkReceivers()
statusContainer.setOnHoverListener(null)
progressProvider?.setReadyToHandleTransition(false)
moveFromCenterAnimationController?.onViewDetached()
@@ -182,6 +196,16 @@
}
}
+ private fun addDarkReceivers() {
+ darkIconDispatcher.addDarkReceiver(battery)
+ darkIconDispatcher.addDarkReceiver(clock)
+ }
+
+ private fun removeDarkReceivers() {
+ darkIconDispatcher.removeDarkReceiver(battery)
+ darkIconDispatcher.removeDarkReceiver(clock)
+ }
+
inner class PhoneStatusBarViewTouchHandler : Gefingerpoken {
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return if (Flags.statusBarSwipeOverChip()) {
@@ -285,6 +309,7 @@
private val viewUtil: ViewUtil,
private val configurationController: ConfigurationController,
private val statusOverlayHoverListenerFactory: StatusOverlayHoverListenerFactory,
+ private val darkIconDispatcher: DarkIconDispatcher,
) {
fun create(view: PhoneStatusBarView): PhoneStatusBarViewController {
val statusBarMoveFromCenterAnimationController =
@@ -309,6 +334,7 @@
viewUtil,
configurationController,
statusOverlayHoverListenerFactory,
+ darkIconDispatcher,
)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 5b45781..30e7247 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -33,8 +33,11 @@
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.systemui.SysuiTestCase
+import com.android.systemui.battery.BatteryMeterView
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.plugins.fakeDarkIconDispatcher
import com.android.systemui.res.R
import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.shade.ShadeControllerImpl
@@ -42,6 +45,7 @@
import com.android.systemui.shade.ShadeViewController
import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.policy.Clock
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.window.StatusBarWindowStateController
import com.android.systemui.unfold.SysUIUnfoldComponent
@@ -70,7 +74,9 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
class PhoneStatusBarViewControllerTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val fakeDarkIconDispatcher = kosmos.fakeDarkIconDispatcher
@Mock private lateinit var shadeViewController: ShadeViewController
@Mock private lateinit var panelExpansionInteractor: PanelExpansionInteractor
@Mock private lateinit var featureFlags: FeatureFlags
@@ -91,6 +97,12 @@
private lateinit var view: PhoneStatusBarView
private lateinit var controller: PhoneStatusBarViewController
+ private val clockView: Clock
+ get() = view.requireViewById(R.id.clock)
+
+ private val batteryView: BatteryMeterView
+ get() = view.requireViewById(R.id.battery)
+
private val unfoldConfig = UnfoldConfig()
@Before
@@ -114,16 +126,25 @@
@Test
fun onViewAttachedAndDrawn_startListeningConfigurationControllerCallback() {
val view = createViewMock()
- val argumentCaptor =
- ArgumentCaptor.forClass(ConfigurationController.ConfigurationListener::class.java)
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
controller = createAndInitController(view)
}
- verify(configurationController).addCallback(argumentCaptor.capture())
- argumentCaptor.value.onDensityOrFontScaleChanged()
+ verify(configurationController).addCallback(any())
+ }
- verify(view).onDensityOrFontScaleChanged()
+ @Test
+ fun onViewAttachedAndDrawn_darkReceiversRegistered() {
+ val view = createViewMock()
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ controller = createAndInitController(view)
+ }
+
+ assertThat(fakeDarkIconDispatcher.receivers.size).isEqualTo(2)
+ assertThat(fakeDarkIconDispatcher.receivers).contains(clockView)
+ assertThat(fakeDarkIconDispatcher.receivers).contains(batteryView)
}
@Test
@@ -158,6 +179,21 @@
}
@Test
+ fun onViewDetached_darkReceiversUnregistered() {
+ val view = createViewMock()
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ controller = createAndInitController(view)
+ }
+
+ assertThat(fakeDarkIconDispatcher.receivers).isNotEmpty()
+
+ controller.onViewDetached()
+
+ assertThat(fakeDarkIconDispatcher.receivers).isEmpty()
+ }
+
+ @Test
fun handleTouchEventFromStatusBar_panelsNotEnabled_returnsFalseAndNoViewEvent() {
`when`(centralSurfacesImpl.commandQueuePanelsEnabled).thenReturn(false)
val returnVal =
@@ -353,7 +389,8 @@
shadeLogger,
viewUtil,
configurationController,
- mStatusOverlayHoverListenerFactory
+ mStatusOverlayHoverListenerFactory,
+ fakeDarkIconDispatcher,
)
.create(view)
.also { it.init() }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
index abc50bc..ed5ec7b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
@@ -35,7 +35,6 @@
import com.android.systemui.Flags.FLAG_STATUS_BAR_SWIPE_OVER_CHIP
import com.android.systemui.Gefingerpoken
import com.android.systemui.SysuiTestCase
-import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.res.R
import com.android.systemui.statusbar.window.StatusBarWindowController
import com.android.systemui.util.mockito.mock
@@ -64,7 +63,6 @@
StatusBarContentInsetsProvider::class.java,
contentInsetsProvider
)
- mDependency.injectTestDependency(DarkIconDispatcher::class.java, mock<DarkIconDispatcher>())
mDependency.injectTestDependency(StatusBarWindowController::class.java, windowController)
context.ensureTestableResources()
view = spy(createStatusBarView())
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/DarkIconDispatcherKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/DarkIconDispatcherKosmos.kt
new file mode 100644
index 0000000..3d125e9
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/DarkIconDispatcherKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins
+
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.fakeDarkIconDispatcher: FakeDarkIconDispatcher by
+ Kosmos.Fixture { FakeDarkIconDispatcher() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/FakeDarkIconDispatcher.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/FakeDarkIconDispatcher.kt
new file mode 100644
index 0000000..102a853
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/FakeDarkIconDispatcher.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins
+
+import android.graphics.Rect
+import java.util.ArrayList
+
+class FakeDarkIconDispatcher : DarkIconDispatcher {
+ val receivers = mutableListOf<DarkIconDispatcher.DarkReceiver>()
+
+ override fun setIconsDarkArea(r: ArrayList<Rect>) {}
+
+ override fun addDarkReceiver(receiver: DarkIconDispatcher.DarkReceiver) {
+ receivers.add(receiver)
+ }
+
+ override fun removeDarkReceiver(receiver: DarkIconDispatcher.DarkReceiver) {
+ receivers.remove(receiver)
+ }
+
+ override fun applyDark(`object`: DarkIconDispatcher.DarkReceiver) {}
+}