Merge "Add work profile support to chooser selector" into tm-qpr-dev am: 978d953c71
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20341778 Change-Id: I236e29cb823b63af0e7b29fb7ca88633b4562a8a Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture())
|
||||
eq<Flag<*>>(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<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
|
||||
|
||||
Reference in New Issue
Block a user