summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-11-06 15:24:40 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-11-06 15:24:40 +0000
commit6a1ca545cc85b95953ff353d2460615fac61a85e (patch)
tree3570914e301a562425a54943f977e5066f808b28
parent6e3cd07e02941a73ac217d57a16eca689308b5a7 (diff)
parent57807815ec6ff1a9ef35decb8fba75932479fcd0 (diff)
Merge changes Icbc6fcac,I3651e364 into main
* changes: Introduce DarkIconDispatcherStore for multiple displays Prepare DarkIconDispatcher for multiple displays
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt73
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt142
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java41
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStoreKosmos.kt33
7 files changed, 303 insertions, 11 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
new file mode 100644
index 000000000000..a2c3c66f4448
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.statusbar.data.repository
+
+import android.platform.test.annotations.EnableFlags
+import android.view.Display.DEFAULT_DISPLAY
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
+class MultiDisplayDarkIconDispatcherStoreTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val testScope = kosmos.testScope
+ private val fakeDisplayRepository = kosmos.displayRepository
+
+ // Lazy so that @EnableFlags has time to run before underTest is instantiated.
+ private val underTest by lazy { kosmos.multiDisplayDarkIconDispatcherStore }
+
+ @Before
+ fun start() {
+ underTest.start()
+ }
+
+ @Before fun addDisplays() = runBlocking { fakeDisplayRepository.addDisplay(DEFAULT_DISPLAY) }
+
+ @Test
+ fun beforeDisplayRemoved_doesNotStopInstances() =
+ testScope.runTest {
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+
+ verify(instance, never()).stop()
+ }
+
+ @Test
+ fun displayRemoved_stopsInstance() =
+ testScope.runTest {
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+
+ fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+
+ verify(instance).stop()
+ }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java
index 403c7c500426..43185fd08613 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java
@@ -36,6 +36,9 @@ import java.util.Collection;
public interface DarkIconDispatcher {
int VERSION = 2;
+ /** Called when work should stop and resources should be cleaned up. */
+ default void stop() {}
+
/**
* Sets the dark area so {@link #applyDark} only affects the icons in the specified area.
*
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java b/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
index d727a70de377..4149f9ae00c2 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
@@ -16,7 +16,10 @@
package com.android.systemui.dagger;
+import android.content.Context;
+
import com.android.systemui.classifier.FalsingManagerProxy;
+import com.android.systemui.dagger.qualifiers.Default;
import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.globalactions.GlobalActionsImpl;
import com.android.systemui.plugins.ActivityStarter;
@@ -33,11 +36,12 @@ import com.android.systemui.volume.VolumeDialogControllerImpl;
import dagger.Binds;
import dagger.Module;
+import dagger.Provides;
/**
* Module for binding Plugin implementations.
*
- * TODO(b/166258224): Many of these should be moved closer to their implementations.
+ * <p>TODO(b/166258224): Many of these should be moved closer to their implementations.
*/
@Module
public abstract class PluginModule {
@@ -47,12 +51,22 @@ public abstract class PluginModule {
abstract ActivityStarter provideActivityStarter(ActivityStarterImpl activityStarterImpl);
/** */
+ @Provides
+ @SysUISingleton
+ @Default
+ static DarkIconDispatcherImpl darkIconDispatcherImpl(
+ DarkIconDispatcherImpl.Factory factory, Context context) {
+ return factory.create(context.getDisplayId(), context);
+ }
+
+ /** */
@Binds
- abstract DarkIconDispatcher provideDarkIconDispatcher(DarkIconDispatcherImpl controllerImpl);
+ abstract DarkIconDispatcher provideDarkIconDispatcher(
+ @Default DarkIconDispatcherImpl controllerImpl);
@Binds
abstract SysuiDarkIconDispatcher provideSysuiDarkIconDispatcher(
- DarkIconDispatcherImpl controllerImpl);
+ @Default DarkIconDispatcherImpl controllerImpl);
/** */
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
index 39de28e7cb49..27d815190d85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.statusbar.data
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStoreModule
import com.android.systemui.statusbar.data.repository.KeyguardStatusBarRepositoryModule
import com.android.systemui.statusbar.data.repository.LightBarControllerStoreModule
import com.android.systemui.statusbar.data.repository.RemoteInputRepositoryModule
@@ -28,6 +29,7 @@ import dagger.Module
@Module(
includes =
[
+ DarkIconDispatcherStoreModule::class,
KeyguardStatusBarRepositoryModule::class,
LightBarControllerStoreModule::class,
RemoteInputRepositoryModule::class,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
new file mode 100644
index 000000000000..8183a487cee2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
@@ -0,0 +1,142 @@
+/*
+ * 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.statusbar.data.repository
+
+import android.content.Context
+import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.display.data.repository.DisplayRepository
+import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
+import com.android.systemui.display.data.repository.PerDisplayStore
+import com.android.systemui.display.data.repository.PerDisplayStoreImpl
+import com.android.systemui.display.data.repository.SingleDisplayStore
+import com.android.systemui.plugins.DarkIconDispatcher
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl
+import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
+import dagger.Binds
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/** Provides per display instances of [DarkIconDispatcher]. */
+interface DarkIconDispatcherStore : PerDisplayStore<DarkIconDispatcher>
+
+/** Provides per display instances of [SysuiDarkIconDispatcher]. */
+interface SysuiDarkIconDispatcherStore : PerDisplayStore<SysuiDarkIconDispatcher>
+
+/**
+ * Multi display implementation that should be used when the [StatusBarConnectedDisplays] flag is
+ * enabled.
+ */
+@SysUISingleton
+class MultiDisplayDarkIconDispatcherStore
+@Inject
+constructor(
+ @Background backgroundApplicationScope: CoroutineScope,
+ displayRepository: DisplayRepository,
+ private val factory: DarkIconDispatcherImpl.Factory,
+ private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
+) :
+ SysuiDarkIconDispatcherStore,
+ PerDisplayStoreImpl<SysuiDarkIconDispatcher>(backgroundApplicationScope, displayRepository) {
+
+ init {
+ StatusBarConnectedDisplays.assertInNewMode()
+ }
+
+ override fun createInstanceForDisplay(displayId: Int): SysuiDarkIconDispatcher {
+ val properties = displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+ return factory.create(displayId, properties.context)
+ }
+
+ override suspend fun onDisplayRemovalAction(instance: SysuiDarkIconDispatcher) {
+ instance.stop()
+ }
+
+ override val instanceClass = SysuiDarkIconDispatcher::class.java
+}
+
+/**
+ * Single display implementation that should be used when the [StatusBarConnectedDisplays] flag is
+ * disabled.
+ */
+@SysUISingleton
+class SingleDisplayDarkIconDispatcherStore
+@Inject
+constructor(factory: DarkIconDispatcherImpl.Factory, context: Context) :
+ SysuiDarkIconDispatcherStore,
+ PerDisplayStore<SysuiDarkIconDispatcher> by SingleDisplayStore(
+ defaultInstance = factory.create(context.displayId, context)
+ ) {
+
+ init {
+ StatusBarConnectedDisplays.assertInLegacyMode()
+ }
+}
+
+/** Extra implementation that simply implements the [DarkIconDispatcherStore] interface. */
+@SysUISingleton
+class DarkIconDispatcherStoreImpl
+@Inject
+constructor(private val store: SysuiDarkIconDispatcherStore) : DarkIconDispatcherStore {
+ override val defaultDisplay: DarkIconDispatcher
+ get() = store.defaultDisplay
+
+ override fun forDisplay(displayId: Int): DarkIconDispatcher = store.forDisplay(displayId)
+}
+
+@Module
+interface DarkIconDispatcherStoreModule {
+
+ @Binds fun store(impl: DarkIconDispatcherStoreImpl): DarkIconDispatcherStore
+
+ companion object {
+ @Provides
+ @SysUISingleton
+ fun sysUiStore(
+ singleDisplayLazy: Lazy<SingleDisplayDarkIconDispatcherStore>,
+ multiDisplayLazy: Lazy<MultiDisplayDarkIconDispatcherStore>,
+ ): SysuiDarkIconDispatcherStore {
+ return if (StatusBarConnectedDisplays.isEnabled) {
+ multiDisplayLazy.get()
+ } else {
+ singleDisplayLazy.get()
+ }
+ }
+
+ @Provides
+ @SysUISingleton
+ @IntoMap
+ @ClassKey(DarkIconDispatcherStore::class)
+ fun storeAsCoreStartable(
+ multiDisplayLazy: Lazy<MultiDisplayDarkIconDispatcherStore>
+ ): CoreStartable {
+ return if (StatusBarConnectedDisplays.isEnabled) {
+ multiDisplayLazy.get()
+ } else {
+ CoreStartable.NOP
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
index 398c1d43d4fc..90b591f173f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
@@ -23,11 +23,15 @@ import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Rect;
import android.util.ArrayMap;
+import android.view.Display;
import android.widget.ImageView;
-import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedFactory;
+import dagger.assisted.AssistedInject;
+
import kotlinx.coroutines.flow.FlowKt;
import kotlinx.coroutines.flow.MutableStateFlow;
import kotlinx.coroutines.flow.StateFlow;
@@ -36,17 +40,15 @@ import kotlinx.coroutines.flow.StateFlowKt;
import java.io.PrintWriter;
import java.util.ArrayList;
-import javax.inject.Inject;
-
/**
*/
-@SysUISingleton
public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher,
LightBarTransitionsController.DarkIntensityApplier {
private final LightBarTransitionsController mTransitionsController;
private final ArrayList<Rect> mTintAreas = new ArrayList<>();
private final ArrayMap<Object, DarkReceiver> mReceivers = new ArrayMap<>();
+ private final DumpManager mDumpManager;
private int mIconTint = DEFAULT_ICON_TINT;
private int mContrastTint = DEFAULT_INVERSE_ICON_TINT;
@@ -61,14 +63,25 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher,
private final MutableStateFlow<DarkChange> mDarkChangeFlow = StateFlowKt.MutableStateFlow(
DarkChange.EMPTY);
+ private final String mDumpableName;
+
+ /** */
+ @AssistedFactory
+ @FunctionalInterface
+ public interface Factory {
+ /** */
+ DarkIconDispatcherImpl create(int displayId, Context context);
+ }
+
/**
*/
- @Inject
+ @AssistedInject
public DarkIconDispatcherImpl(
- Context context,
+ @Assisted int displayId,
+ @Assisted Context context,
LightBarTransitionsController.Factory lightBarTransitionsControllerFactory,
DumpManager dumpManager) {
-
+ mDumpManager = dumpManager;
if (newStatusBarIcons()) {
mDarkModeIconColorSingleTone = Color.BLACK;
mLightModeIconColorSingleTone = Color.WHITE;
@@ -81,7 +94,19 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher,
mTransitionsController = lightBarTransitionsControllerFactory.create(this);
- dumpManager.registerDumpable(getClass().getSimpleName(), this);
+ mDumpableName = getDumpableName(displayId);
+ dumpManager.registerNormalDumpable(mDumpableName, this);
+ }
+
+ @Override
+ public void stop() {
+ mDumpManager.unregisterDumpable(mDumpableName);
+ }
+
+ private String getDumpableName(int displayId) {
+ String dumpableNameSuffix =
+ displayId == Display.DEFAULT_DISPLAY ? "" : String.valueOf(displayId);
+ return getClass().getSimpleName() + dumpableNameSuffix;
}
public LightBarTransitionsController getTransitionsController() {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStoreKosmos.kt
new file mode 100644
index 000000000000..6f723fecf7cd
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStoreKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.statusbar.data.repository
+
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.display.data.repository.displayWindowPropertiesRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import org.mockito.kotlin.mock
+
+val Kosmos.multiDisplayDarkIconDispatcherStore by
+ Kosmos.Fixture {
+ MultiDisplayDarkIconDispatcherStore(
+ backgroundApplicationScope = applicationCoroutineScope,
+ displayRepository = displayRepository,
+ factory = { _, _ -> mock() },
+ displayWindowPropertiesRepository = displayWindowPropertiesRepository,
+ )
+ }