diff options
9 files changed, 285 insertions, 2 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java index afcb03da39da..0bc29a8d0f16 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java @@ -122,6 +122,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.globalactions.domain.interactor.GlobalActionsInteractor; import com.android.systemui.plugins.GlobalActions.GlobalActionsManager; import com.android.systemui.plugins.GlobalActionsPanelPlugin; import com.android.systemui.scrim.ScrimDrawable; @@ -257,6 +258,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene private final ShadeController mShadeController; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final DialogTransitionAnimator mDialogTransitionAnimator; + private final GlobalActionsInteractor mInteractor; @VisibleForTesting public enum GlobalActionsEvent implements UiEventLogger.UiEventEnum { @@ -368,7 +370,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene ShadeController shadeController, KeyguardUpdateMonitor keyguardUpdateMonitor, DialogTransitionAnimator dialogTransitionAnimator, - SelectedUserInteractor selectedUserInteractor) { + SelectedUserInteractor selectedUserInteractor, + GlobalActionsInteractor interactor) { mContext = context; mWindowManagerFuncs = windowManagerFuncs; mAudioManager = audioManager; @@ -404,6 +407,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mKeyguardUpdateMonitor = keyguardUpdateMonitor; mDialogTransitionAnimator = dialogTransitionAnimator; mSelectedUserInteractor = selectedUserInteractor; + mInteractor = interactor; // receive broadcasts IntentFilter filter = new IntentFilter(); @@ -1333,6 +1337,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mUiEventLogger.log(GlobalActionsEvent.GA_POWER_MENU_CLOSE); mWindowManagerFuncs.onGlobalActionsHidden(); mLifecycle.setCurrentState(Lifecycle.State.CREATED); + mInteractor.onDismissed(); } /** @@ -1342,6 +1347,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene public void onShow(DialogInterface dialog) { mMetricsLogger.visible(MetricsEvent.POWER_MENU); mUiEventLogger.log(GlobalActionsEvent.GA_POWER_MENU_OPEN); + mInteractor.onShown(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepository.kt b/packages/SystemUI/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepository.kt new file mode 100644 index 000000000000..2550504cdc42 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepository.kt @@ -0,0 +1,35 @@ +/* + * 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.globalactions.data.repository + +import com.android.systemui.dagger.SysUISingleton +import javax.inject.Inject +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow + +/** Encapsulates application state for global actions. */ +@SysUISingleton +class GlobalActionsRepository @Inject constructor() { + private val _isVisible: MutableStateFlow<Boolean> = MutableStateFlow(false) + /** Is the global actions dialog visible. */ + val isVisible = _isVisible.asStateFlow() + + /** Sets whether the global actions dialog is visible. */ + fun setVisible(isVisible: Boolean) { + _isVisible.value = isVisible + } +} diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractor.kt b/packages/SystemUI/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractor.kt new file mode 100644 index 000000000000..c484a48a4058 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractor.kt @@ -0,0 +1,42 @@ +/* + * 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.globalactions.domain.interactor + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.globalactions.data.repository.GlobalActionsRepository +import javax.inject.Inject +import kotlinx.coroutines.flow.StateFlow + +@SysUISingleton +class GlobalActionsInteractor +@Inject +constructor( + private val repository: GlobalActionsRepository, +) { + /** Is the global actions dialog visible. */ + val isVisible: StateFlow<Boolean> = repository.isVisible + + /** Notifies that the global actions dialog is shown. */ + fun onShown() { + repository.setVisible(true) + } + + /** Notifies that the global actions dialog has been dismissed. */ + fun onDismissed() { + repository.setVisible(false) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java index 3f454925186c..77b30402c040 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java @@ -65,6 +65,8 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogTransitionAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; +import com.android.systemui.globalactions.domain.interactor.GlobalActionsInteractor; +import com.android.systemui.kosmos.KosmosJavaAdapter; import com.android.systemui.plugins.GlobalActions; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.settings.UserTracker; @@ -140,6 +142,8 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { @Captor private ArgumentCaptor<OnBackInvokedCallback> mOnBackInvokedCallback; private TestableLooper mTestableLooper; + private KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this); + private GlobalActionsInteractor mInteractor; @Before public void setUp() throws Exception { @@ -154,6 +158,7 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { mGlobalSettings = new FakeGlobalSettings(); mSecureSettings = new FakeSettings(); + mInteractor = mKosmos.getGlobalActionsInteractor(); mGlobalActionsDialogLite = new GlobalActionsDialogLite(mContext, mWindowManagerFuncs, @@ -189,7 +194,8 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { mShadeController, mKeyguardUpdateMonitor, mDialogTransitionAnimator, - mSelectedUserInteractor); + mSelectedUserInteractor, + mInteractor); mGlobalActionsDialogLite.setZeroDialogPressDelayForTesting(); ColorExtractor.GradientColors backdropColors = new ColorExtractor.GradientColors(); @@ -623,6 +629,18 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { assertThat(bugReportAction.showBeforeProvisioning()).isFalse(); } + @Test + public void testInteractor_onShow() { + mGlobalActionsDialogLite.onShow(null); + assertThat(mInteractor.isVisible().getValue()).isTrue(); + } + + @Test + public void testInteractor_onDismiss() { + mGlobalActionsDialogLite.onDismiss(mGlobalActionsDialogLite.mDialog); + assertThat(mInteractor.isVisible().getValue()).isFalse(); + } + private UserInfo mockCurrentUser(int flags) { return new UserInfo(10, "A User", flags); diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryTest.kt new file mode 100644 index 000000000000..e437c10c7b73 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryTest.kt @@ -0,0 +1,69 @@ +/* + * 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.globalactions.data.repository + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidJUnit4::class) +class GlobalActionsRepositoryTest : SysuiTestCase() { + private lateinit var underTest: GlobalActionsRepository + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + + @Before + fun setUp() { + underTest = kosmos.globalActionsRepository + } + + @Test + fun isVisible_initialValueFalse() { + testScope.runTest { + val isVisible by collectLastValue(underTest.isVisible) + runCurrent() + + assertThat(isVisible).isFalse() + } + } + + @Test + fun isVisible_onChange() { + testScope.runTest { + val isVisible by collectLastValue(underTest.isVisible) + runCurrent() + + underTest.setVisible(true) + assertThat(isVisible).isTrue() + + underTest.setVisible(false) + assertThat(isVisible).isFalse() + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorTest.kt new file mode 100644 index 000000000000..9275512009b2 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorTest.kt @@ -0,0 +1,67 @@ +/* + * 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.globalactions.domain.interactor + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidJUnit4::class) +class GlobalActionsInteractorTest : SysuiTestCase() { + private lateinit var underTest: GlobalActionsInteractor + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + + @Before + fun setup() { + underTest = kosmos.globalActionsInteractor + } + + @Test + fun OnDismissed() { + testScope.runTest { + val isVisible by collectLastValue(underTest.isVisible) + underTest.onDismissed() + runCurrent() + + assertThat(isVisible).isFalse() + } + } + + @Test + fun OnShown() { + testScope.runTest { + val isVisible by collectLastValue(underTest.isVisible) + underTest.onShown() + runCurrent() + + assertThat(isVisible).isTrue() + } + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryKosmos.kt new file mode 100644 index 000000000000..0e439b04f484 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryKosmos.kt @@ -0,0 +1,21 @@ +/* + * 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.globalactions.data.repository + +import com.android.systemui.kosmos.Kosmos + +val Kosmos.globalActionsRepository by Kosmos.Fixture { GlobalActionsRepository() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorKosmos.kt new file mode 100644 index 000000000000..72143095a114 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorKosmos.kt @@ -0,0 +1,23 @@ +/* + * 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.globalactions.domain.interactor + +import com.android.systemui.globalactions.data.repository.globalActionsRepository +import com.android.systemui.kosmos.Kosmos + +val Kosmos.globalActionsInteractor by + Kosmos.Fixture { GlobalActionsInteractor(globalActionsRepository) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt index f6b32800263a..3fc5af1a50ab 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt @@ -30,6 +30,7 @@ import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.flags.fakeFeatureFlagsClassic +import com.android.systemui.globalactions.domain.interactor.globalActionsInteractor import com.android.systemui.jank.interactionJankMonitor import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository @@ -91,6 +92,7 @@ class KosmosJavaAdapter( val fromPrimaryBouncerTransitionInteractor by lazy { kosmos.fromPrimaryBouncerTransitionInteractor } + val globalActionsInteractor by lazy { kosmos.globalActionsInteractor } val sceneDataSource by lazy { kosmos.sceneDataSource } init { |