Loading packages/SystemUI/src/com/android/systemui/ChooserSelector.kt +17 −8 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -56,10 +58,17 @@ class ChooserSelector @Inject constructor( } else { PackageManager.COMPONENT_ENABLED_STATE_DISABLED } userTracker.userProfiles.forEach { try { packageManager.setComponentEnabledSetting(chooserComponent, newState, /* flags = */ 0) context.createContextAsUser(it.userHandle, /* flags = */ 0).packageManager .setComponentEnabledSetting(chooserComponent, newState, /* flags = */ 0) } catch (e: IllegalArgumentException) { Log.w("ChooserSelector", "Unable to set IntentResolver enabled=" + enabled, e) Log.w( "ChooserSelector", "Unable to set IntentResolver enabled=$enabled for user ${it.id}", e, ) } } } Loading packages/SystemUI/src/com/android/systemui/ChooserSelectorResourceHelper.javadeleted 100644 → 0 +0 −31 Original line number Diff line number Diff line /* * 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; } packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt +59 −28 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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) Loading @@ -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 Loading @@ -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()) chooserSelector = ChooserSelector(mockContext, mockFeatureFlags, testScope, testDispatcher) whenever(mockUserTracker.userProfiles).thenReturn(listOf(UserInfo(), UserInfo())) chooserSelector = ChooserSelector( mockContext, mockUserTracker, mockFeatureFlags, testScope, testDispatcher, ) } @After Loading @@ -74,7 +87,9 @@ class ChooserSelectorTest : SysuiTestCase() { // Assert verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture(), ) verify(mockFeatureFlags, never()).removeListener(any()) // Act Loading @@ -87,86 +102,102 @@ class ChooserSelectorTest : SysuiTestCase() { @Test fun initialize_enablesUnbundledChooser_whenFlagEnabled() { // Arrange `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).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<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).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<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) chooserSelector.start() verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) eq<Flag<*>>(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<UnreleasedFlag>())).thenReturn(true) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).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<UnreleasedFlag>())).thenReturn(true) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true) chooserSelector.start() verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) eq<Flag<*>>(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<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).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<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) chooserSelector.start() verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture(), ) clearInvocations(mockPackageManager) // Act `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id + 1)) // Assert Loading Loading
packages/SystemUI/src/com/android/systemui/ChooserSelector.kt +17 −8 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -56,10 +58,17 @@ class ChooserSelector @Inject constructor( } else { PackageManager.COMPONENT_ENABLED_STATE_DISABLED } userTracker.userProfiles.forEach { try { packageManager.setComponentEnabledSetting(chooserComponent, newState, /* flags = */ 0) context.createContextAsUser(it.userHandle, /* flags = */ 0).packageManager .setComponentEnabledSetting(chooserComponent, newState, /* flags = */ 0) } catch (e: IllegalArgumentException) { Log.w("ChooserSelector", "Unable to set IntentResolver enabled=" + enabled, e) Log.w( "ChooserSelector", "Unable to set IntentResolver enabled=$enabled for user ${it.id}", e, ) } } } Loading
packages/SystemUI/src/com/android/systemui/ChooserSelectorResourceHelper.javadeleted 100644 → 0 +0 −31 Original line number Diff line number Diff line /* * 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; }
packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt +59 −28 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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) Loading @@ -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 Loading @@ -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()) chooserSelector = ChooserSelector(mockContext, mockFeatureFlags, testScope, testDispatcher) whenever(mockUserTracker.userProfiles).thenReturn(listOf(UserInfo(), UserInfo())) chooserSelector = ChooserSelector( mockContext, mockUserTracker, mockFeatureFlags, testScope, testDispatcher, ) } @After Loading @@ -74,7 +87,9 @@ class ChooserSelectorTest : SysuiTestCase() { // Assert verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture(), ) verify(mockFeatureFlags, never()).removeListener(any()) // Act Loading @@ -87,86 +102,102 @@ class ChooserSelectorTest : SysuiTestCase() { @Test fun initialize_enablesUnbundledChooser_whenFlagEnabled() { // Arrange `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).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<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).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<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) chooserSelector.start() verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) eq<Flag<*>>(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<UnreleasedFlag>())).thenReturn(true) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).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<UnreleasedFlag>())).thenReturn(true) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true) chooserSelector.start() verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) eq<Flag<*>>(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<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).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<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) chooserSelector.start() verify(mockFeatureFlags).addListener( eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture()) eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture(), ) clearInvocations(mockPackageManager) // Act `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false) flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id + 1)) // Assert Loading