diff --git a/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt b/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt index a89cbf57f95be..9ac45b3c77cc9 100644 --- a/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt +++ b/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt @@ -4,30 +4,32 @@ import android.content.ComponentName import android.content.Context import android.content.pm.PackageManager import android.util.Log +import com.android.internal.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FlagListenable import com.android.systemui.flags.Flags -import javax.inject.Inject +import com.android.systemui.settings.UserTracker import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext +import javax.inject.Inject @SysUISingleton class ChooserSelector @Inject constructor( private val context: Context, + private val userTracker: UserTracker, private val featureFlags: FeatureFlags, @Application private val coroutineScope: CoroutineScope, - @Background private val bgDispatcher: CoroutineDispatcher + @Background private val bgDispatcher: CoroutineDispatcher, ) : CoreStartable { - private val packageManager = context.packageManager private val chooserComponent = ComponentName.unflattenFromString( - context.resources.getString(ChooserSelectorResourceHelper.CONFIG_CHOOSER_ACTIVITY)) + context.resources.getString(R.string.config_chooserActivity)) override fun start() { coroutineScope.launch { @@ -56,10 +58,17 @@ class ChooserSelector @Inject constructor( } else { PackageManager.COMPONENT_ENABLED_STATE_DISABLED } - try { - packageManager.setComponentEnabledSetting(chooserComponent, newState, /* flags = */ 0) - } catch (e: IllegalArgumentException) { - Log.w("ChooserSelector", "Unable to set IntentResolver enabled=" + enabled, e) + userTracker.userProfiles.forEach { + try { + context.createContextAsUser(it.userHandle, /* flags = */ 0).packageManager + .setComponentEnabledSetting(chooserComponent, newState, /* flags = */ 0) + } catch (e: IllegalArgumentException) { + Log.w( + "ChooserSelector", + "Unable to set IntentResolver enabled=$enabled for user ${it.id}", + e, + ) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/ChooserSelectorResourceHelper.java b/packages/SystemUI/src/com/android/systemui/ChooserSelectorResourceHelper.java deleted file mode 100644 index 7a2de7b6a78da..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/ChooserSelectorResourceHelper.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2022 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; - -import androidx.annotation.StringRes; - -import com.android.internal.R; - -/** Helper class for referencing resources */ -class ChooserSelectorResourceHelper { - - private ChooserSelectorResourceHelper() { - } - - @StringRes - static final int CONFIG_CHOOSER_ACTIVITY = R.string.config_chooserActivity; -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt index 6b1ef389a98ee..81d0034128b17 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt @@ -3,6 +3,7 @@ package com.android.systemui import android.content.ComponentName import android.content.Context import android.content.pm.PackageManager +import android.content.pm.UserInfo import android.content.res.Resources import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest @@ -11,9 +12,11 @@ import com.android.systemui.flags.Flag import com.android.systemui.flags.FlagListenable import com.android.systemui.flags.Flags import com.android.systemui.flags.UnreleasedFlag +import com.android.systemui.settings.UserTracker import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.kotlinArgumentCaptor +import com.android.systemui.util.mockito.whenever import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel @@ -26,9 +29,9 @@ import org.mockito.Mock import org.mockito.Mockito.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never +import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyZeroInteractions -import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @@ -44,6 +47,8 @@ class ChooserSelectorTest : SysuiTestCase() { private lateinit var chooserSelector: ChooserSelector @Mock private lateinit var mockContext: Context + @Mock private lateinit var mockProfileContext: Context + @Mock private lateinit var mockUserTracker: UserTracker @Mock private lateinit var mockPackageManager: PackageManager @Mock private lateinit var mockResources: Resources @Mock private lateinit var mockFeatureFlags: FeatureFlags @@ -52,12 +57,20 @@ class ChooserSelectorTest : SysuiTestCase() { fun setup() { MockitoAnnotations.initMocks(this) - `when`(mockContext.packageManager).thenReturn(mockPackageManager) - `when`(mockContext.resources).thenReturn(mockResources) - `when`(mockResources.getString(anyInt())).thenReturn( + whenever(mockContext.createContextAsUser(any(), anyInt())).thenReturn(mockProfileContext) + whenever(mockContext.resources).thenReturn(mockResources) + whenever(mockProfileContext.packageManager).thenReturn(mockPackageManager) + whenever(mockResources.getString(anyInt())).thenReturn( ComponentName("TestPackage", "TestClass").flattenToString()) + whenever(mockUserTracker.userProfiles).thenReturn(listOf(UserInfo(), UserInfo())) - chooserSelector = ChooserSelector(mockContext, mockFeatureFlags, testScope, testDispatcher) + chooserSelector = ChooserSelector( + mockContext, + mockUserTracker, + mockFeatureFlags, + testScope, + testDispatcher, + ) } @After @@ -74,7 +87,9 @@ class ChooserSelectorTest : SysuiTestCase() { // Assert verify(mockFeatureFlags).addListener( - eq>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) + eq>(Flags.CHOOSER_UNBUNDLED), + flagListener.capture(), + ) verify(mockFeatureFlags, never()).removeListener(any()) // Act @@ -87,86 +102,102 @@ class ChooserSelectorTest : SysuiTestCase() { @Test fun initialize_enablesUnbundledChooser_whenFlagEnabled() { // Arrange - `when`(mockFeatureFlags.isEnabled(any())).thenReturn(true) + whenever(mockFeatureFlags.isEnabled(any())).thenReturn(true) // Act chooserSelector.start() // Assert - verify(mockPackageManager).setComponentEnabledSetting( + verify(mockPackageManager, times(2)).setComponentEnabledSetting( eq(ComponentName("TestPackage", "TestClass")), eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED), - anyInt()) + anyInt(), + ) } @Test fun initialize_disablesUnbundledChooser_whenFlagDisabled() { // Arrange - `when`(mockFeatureFlags.isEnabled(any())).thenReturn(false) + whenever(mockFeatureFlags.isEnabled(any())).thenReturn(false) // Act chooserSelector.start() // Assert - verify(mockPackageManager).setComponentEnabledSetting( + verify(mockPackageManager, times(2)).setComponentEnabledSetting( eq(ComponentName("TestPackage", "TestClass")), eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED), - anyInt()) + anyInt(), + ) } @Test fun enablesUnbundledChooser_whenFlagBecomesEnabled() { // Arrange - `when`(mockFeatureFlags.isEnabled(any())).thenReturn(false) + whenever(mockFeatureFlags.isEnabled(any())).thenReturn(false) chooserSelector.start() verify(mockFeatureFlags).addListener( - eq>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) + eq>(Flags.CHOOSER_UNBUNDLED), + flagListener.capture(), + ) verify(mockPackageManager, never()).setComponentEnabledSetting( - any(), eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED), anyInt()) + any(), + eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED), + anyInt(), + ) // Act - `when`(mockFeatureFlags.isEnabled(any())).thenReturn(true) + whenever(mockFeatureFlags.isEnabled(any())).thenReturn(true) flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id)) // Assert - verify(mockPackageManager).setComponentEnabledSetting( + verify(mockPackageManager, times(2)).setComponentEnabledSetting( eq(ComponentName("TestPackage", "TestClass")), eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED), - anyInt()) + anyInt(), + ) } @Test fun disablesUnbundledChooser_whenFlagBecomesDisabled() { // Arrange - `when`(mockFeatureFlags.isEnabled(any())).thenReturn(true) + whenever(mockFeatureFlags.isEnabled(any())).thenReturn(true) chooserSelector.start() verify(mockFeatureFlags).addListener( - eq>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) + eq>(Flags.CHOOSER_UNBUNDLED), + flagListener.capture(), + ) verify(mockPackageManager, never()).setComponentEnabledSetting( - any(), eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED), anyInt()) + any(), + eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED), + anyInt(), + ) // Act - `when`(mockFeatureFlags.isEnabled(any())).thenReturn(false) + whenever(mockFeatureFlags.isEnabled(any())).thenReturn(false) flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id)) // Assert - verify(mockPackageManager).setComponentEnabledSetting( + verify(mockPackageManager, times(2)).setComponentEnabledSetting( eq(ComponentName("TestPackage", "TestClass")), eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED), - anyInt()) + anyInt(), + ) } @Test fun doesNothing_whenAnotherFlagChanges() { // Arrange - `when`(mockFeatureFlags.isEnabled(any())).thenReturn(false) + whenever(mockFeatureFlags.isEnabled(any())).thenReturn(false) chooserSelector.start() verify(mockFeatureFlags).addListener( - eq>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) + eq>(Flags.CHOOSER_UNBUNDLED), + flagListener.capture(), + ) clearInvocations(mockPackageManager) // Act - `when`(mockFeatureFlags.isEnabled(any())).thenReturn(false) + whenever(mockFeatureFlags.isEnabled(any())).thenReturn(false) flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id + 1)) // Assert