Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt +9 −16 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.systemui.communal.view.viewmodel import android.appwidget.AppWidgetProviderInfo import android.content.ActivityNotFoundException import android.content.ComponentName import android.content.Intent import android.content.pm.PackageManager import android.content.pm.UserInfo import android.provider.Settings Loading @@ -27,7 +26,6 @@ import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityManager import android.view.accessibility.accessibilityManager import android.widget.RemoteViews import androidx.activity.result.ActivityResultLauncher import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.UiEventLogger Loading Loading @@ -88,7 +86,6 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { @Mock private lateinit var mediaHost: MediaHost @Mock private lateinit var uiEventLogger: UiEventLogger @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var activityResultLauncher: ActivityResultLauncher<Intent> @Mock private lateinit var metricsLogger: CommunalMetricsLogger private val kosmos = testKosmos() Loading Loading @@ -117,10 +114,7 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { communalSceneInteractor = kosmos.communalSceneInteractor communalInteractor = spy(kosmos.communalInteractor) kosmos.fakeUserRepository.setUserInfos(listOf(MAIN_USER_INFO)) kosmos.fakeUserTracker.set( userInfos = listOf(MAIN_USER_INFO), selectedUserIndex = 0, ) kosmos.fakeUserTracker.set(userInfos = listOf(MAIN_USER_INFO), selectedUserIndex = 0) kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true) accessibilityManager = kosmos.accessibilityManager Loading Loading @@ -257,10 +251,13 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { @Test fun onOpenWidgetPicker_launchesWidgetPickerActivity() { testScope.runTest { var activityStarted = false val success = underTest.onOpenWidgetPicker(testableResources.resources, activityResultLauncher) underTest.onOpenWidgetPicker(testableResources.resources) { _ -> run { activityStarted = true } } verify(activityResultLauncher).launch(any()) assertTrue(activityStarted) assertTrue(success) } } Loading @@ -268,14 +265,10 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { @Test fun onOpenWidgetPicker_activityLaunchThrowsException_failure() { testScope.runTest { whenever(activityResultLauncher.launch(any())) .thenThrow(ActivityNotFoundException::class.java) val success = underTest.onOpenWidgetPicker( testableResources.resources, activityResultLauncher, ) underTest.onOpenWidgetPicker(testableResources.resources) { _ -> run { throw ActivityNotFoundException() } } assertFalse(success) } Loading packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt +3 −4 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.os.UserHandle import android.util.Log import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityManager import androidx.activity.result.ActivityResultLauncher import com.android.internal.logging.UiEventLogger import com.android.systemui.communal.dagger.CommunalModule.Companion.LAUNCHER_PACKAGE import com.android.systemui.communal.data.model.CommunalWidgetCategories Loading Loading @@ -184,10 +183,10 @@ constructor( val isIdleOnCommunal: StateFlow<Boolean> = communalInteractor.isIdleOnCommunal /** Launch the widget picker activity using the given {@link ActivityResultLauncher}. */ /** Launch the widget picker activity using the given startActivity method. */ suspend fun onOpenWidgetPicker( resources: Resources, activityLauncher: ActivityResultLauncher<Intent>, startActivity: (intent: Intent) -> Unit, ): Boolean = withContext(backgroundDispatcher) { val widgets = communalInteractor.widgetContent.first() Loading @@ -199,7 +198,7 @@ constructor( } getWidgetPickerActivityIntent(resources, excludeList)?.let { try { activityLauncher.launch(it) startActivity(it) return@withContext true } catch (e: Exception) { Log.e(TAG, "Failed to launch widget picker activity", e) Loading packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt +49 −46 Original line number Diff line number Diff line Loading @@ -27,8 +27,6 @@ import android.view.IWindowManager import android.view.WindowInsets import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize Loading @@ -51,6 +49,7 @@ import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.Logger import com.android.systemui.log.dagger.CommunalLog import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.settings.UserTracker import javax.inject.Inject import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch Loading @@ -64,12 +63,15 @@ constructor( private val uiEventLogger: UiEventLogger, private val widgetConfiguratorFactory: WidgetConfigurationController.Factory, private val widgetSection: CommunalAppWidgetSection, private val userTracker: UserTracker, @CommunalLog logBuffer: LogBuffer, ) : ComponentActivity() { companion object { private const val TAG = "EditWidgetsActivity" private const val EXTRA_IS_PENDING_WIDGET_DRAG = "is_pending_widget_drag" const val EXTRA_OPEN_WIDGET_PICKER_ON_START = "open_widget_picker_on_start" private const val REQUEST_CODE_WIDGET_PICKER = 200 } /** Loading Loading @@ -110,7 +112,7 @@ constructor( object : ActivityLifecycleCallbacks { override fun onActivityCreated( activity: Activity, savedInstanceState: Bundle? savedInstanceState: Bundle?, ) { waitingForResult = savedInstanceState?.getBoolean(STATE_EXTRA_IS_WAITING_FOR_RESULT) Loading Loading @@ -172,41 +174,6 @@ constructor( if (communalEditWidgetsActivityFinishFix()) ActivityControllerImpl(this) else NopActivityController() private val addWidgetActivityLauncher: ActivityResultLauncher<Intent> = registerForActivityResult(StartActivityForResult()) { result -> when (result.resultCode) { RESULT_OK -> { uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_WIDGET_PICKER_SHOWN) result.data?.let { intent -> val isPendingWidgetDrag = intent.getBooleanExtra(EXTRA_IS_PENDING_WIDGET_DRAG, false) // Nothing to do when a widget is being dragged & dropped. The drop // target in the communal grid will receive the widget to be added (if // the user drops it over). if (!isPendingWidgetDrag) { val (componentName, user) = getWidgetExtraFromIntent(intent) if (componentName != null && user != null) { // Add widget at the end. communalViewModel.onAddWidget( componentName, user, configurator = widgetConfigurator, ) } else { run { Log.w(TAG, "No AppWidgetProviderInfo found in result.") } } } } ?: run { Log.w(TAG, "No data in result.") } } else -> Log.w( TAG, "Failed to receive result from widget picker, code=${result.resultCode}" ) } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Loading @@ -226,8 +193,7 @@ constructor( PlatformTheme { Box( modifier = Modifier.fillMaxSize() .background(MaterialTheme.colorScheme.surfaceDim), Modifier.fillMaxSize().background(MaterialTheme.colorScheme.surfaceDim) ) { CommunalHub( viewModel = communalViewModel, Loading Loading @@ -274,7 +240,13 @@ constructor( private fun onOpenWidgetPicker() { lifecycleScope.launch { communalViewModel.onOpenWidgetPicker(resources, addWidgetActivityLauncher) communalViewModel.onOpenWidgetPicker(resources) { intent: Intent -> startActivityForResultAsUser( intent, REQUEST_CODE_WIDGET_PICKER, userTracker.userHandle, ) } } } Loading @@ -285,7 +257,7 @@ constructor( communalViewModel.changeScene( scene = CommunalScenes.Communal, loggingReason = "edit mode closing", transitionKey = CommunalTransitionKeys.FromEditMode transitionKey = CommunalTransitionKeys.FromEditMode, ) // Wait for the current scene to be idle on communal. Loading @@ -309,7 +281,7 @@ constructor( flagsMask: Int, flagsValues: Int, extraFlags: Int, options: Bundle? options: Bundle?, ) { activityController.onWaitingForResult(true) super.startIntentSenderForResult( Loading @@ -319,15 +291,46 @@ constructor( flagsMask, flagsValues, extraFlags, options options, ) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { activityController.onWaitingForResult(false) super.onActivityResult(requestCode, resultCode, data) if (requestCode == WidgetConfigurationController.REQUEST_CODE) { when (requestCode) { WidgetConfigurationController.REQUEST_CODE -> widgetConfigurator.setConfigurationResult(resultCode) REQUEST_CODE_WIDGET_PICKER -> { if (resultCode != RESULT_OK) { Log.w(TAG, "Failed to receive result from widget picker, code=$resultCode") return } uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_WIDGET_PICKER_SHOWN) data?.let { intent -> val isPendingWidgetDrag = intent.getBooleanExtra(EXTRA_IS_PENDING_WIDGET_DRAG, false) // Nothing to do when a widget is being dragged & dropped. The drop // target in the communal grid will receive the widget to be added (if // the user drops it over). if (!isPendingWidgetDrag) { val (componentName, user) = getWidgetExtraFromIntent(intent) if (componentName != null && user != null) { // Add widget at the end. communalViewModel.onAddWidget( componentName, user, configurator = widgetConfigurator, ) } else { run { Log.w(TAG, "No AppWidgetProviderInfo found in result.") } } } } ?: run { Log.w(TAG, "No data in result.") } } } } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt +9 −16 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.systemui.communal.view.viewmodel import android.appwidget.AppWidgetProviderInfo import android.content.ActivityNotFoundException import android.content.ComponentName import android.content.Intent import android.content.pm.PackageManager import android.content.pm.UserInfo import android.provider.Settings Loading @@ -27,7 +26,6 @@ import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityManager import android.view.accessibility.accessibilityManager import android.widget.RemoteViews import androidx.activity.result.ActivityResultLauncher import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.UiEventLogger Loading Loading @@ -88,7 +86,6 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { @Mock private lateinit var mediaHost: MediaHost @Mock private lateinit var uiEventLogger: UiEventLogger @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var activityResultLauncher: ActivityResultLauncher<Intent> @Mock private lateinit var metricsLogger: CommunalMetricsLogger private val kosmos = testKosmos() Loading Loading @@ -117,10 +114,7 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { communalSceneInteractor = kosmos.communalSceneInteractor communalInteractor = spy(kosmos.communalInteractor) kosmos.fakeUserRepository.setUserInfos(listOf(MAIN_USER_INFO)) kosmos.fakeUserTracker.set( userInfos = listOf(MAIN_USER_INFO), selectedUserIndex = 0, ) kosmos.fakeUserTracker.set(userInfos = listOf(MAIN_USER_INFO), selectedUserIndex = 0) kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true) accessibilityManager = kosmos.accessibilityManager Loading Loading @@ -257,10 +251,13 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { @Test fun onOpenWidgetPicker_launchesWidgetPickerActivity() { testScope.runTest { var activityStarted = false val success = underTest.onOpenWidgetPicker(testableResources.resources, activityResultLauncher) underTest.onOpenWidgetPicker(testableResources.resources) { _ -> run { activityStarted = true } } verify(activityResultLauncher).launch(any()) assertTrue(activityStarted) assertTrue(success) } } Loading @@ -268,14 +265,10 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { @Test fun onOpenWidgetPicker_activityLaunchThrowsException_failure() { testScope.runTest { whenever(activityResultLauncher.launch(any())) .thenThrow(ActivityNotFoundException::class.java) val success = underTest.onOpenWidgetPicker( testableResources.resources, activityResultLauncher, ) underTest.onOpenWidgetPicker(testableResources.resources) { _ -> run { throw ActivityNotFoundException() } } assertFalse(success) } Loading
packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt +3 −4 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.os.UserHandle import android.util.Log import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityManager import androidx.activity.result.ActivityResultLauncher import com.android.internal.logging.UiEventLogger import com.android.systemui.communal.dagger.CommunalModule.Companion.LAUNCHER_PACKAGE import com.android.systemui.communal.data.model.CommunalWidgetCategories Loading Loading @@ -184,10 +183,10 @@ constructor( val isIdleOnCommunal: StateFlow<Boolean> = communalInteractor.isIdleOnCommunal /** Launch the widget picker activity using the given {@link ActivityResultLauncher}. */ /** Launch the widget picker activity using the given startActivity method. */ suspend fun onOpenWidgetPicker( resources: Resources, activityLauncher: ActivityResultLauncher<Intent>, startActivity: (intent: Intent) -> Unit, ): Boolean = withContext(backgroundDispatcher) { val widgets = communalInteractor.widgetContent.first() Loading @@ -199,7 +198,7 @@ constructor( } getWidgetPickerActivityIntent(resources, excludeList)?.let { try { activityLauncher.launch(it) startActivity(it) return@withContext true } catch (e: Exception) { Log.e(TAG, "Failed to launch widget picker activity", e) Loading
packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt +49 −46 Original line number Diff line number Diff line Loading @@ -27,8 +27,6 @@ import android.view.IWindowManager import android.view.WindowInsets import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize Loading @@ -51,6 +49,7 @@ import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.Logger import com.android.systemui.log.dagger.CommunalLog import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.settings.UserTracker import javax.inject.Inject import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch Loading @@ -64,12 +63,15 @@ constructor( private val uiEventLogger: UiEventLogger, private val widgetConfiguratorFactory: WidgetConfigurationController.Factory, private val widgetSection: CommunalAppWidgetSection, private val userTracker: UserTracker, @CommunalLog logBuffer: LogBuffer, ) : ComponentActivity() { companion object { private const val TAG = "EditWidgetsActivity" private const val EXTRA_IS_PENDING_WIDGET_DRAG = "is_pending_widget_drag" const val EXTRA_OPEN_WIDGET_PICKER_ON_START = "open_widget_picker_on_start" private const val REQUEST_CODE_WIDGET_PICKER = 200 } /** Loading Loading @@ -110,7 +112,7 @@ constructor( object : ActivityLifecycleCallbacks { override fun onActivityCreated( activity: Activity, savedInstanceState: Bundle? savedInstanceState: Bundle?, ) { waitingForResult = savedInstanceState?.getBoolean(STATE_EXTRA_IS_WAITING_FOR_RESULT) Loading Loading @@ -172,41 +174,6 @@ constructor( if (communalEditWidgetsActivityFinishFix()) ActivityControllerImpl(this) else NopActivityController() private val addWidgetActivityLauncher: ActivityResultLauncher<Intent> = registerForActivityResult(StartActivityForResult()) { result -> when (result.resultCode) { RESULT_OK -> { uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_WIDGET_PICKER_SHOWN) result.data?.let { intent -> val isPendingWidgetDrag = intent.getBooleanExtra(EXTRA_IS_PENDING_WIDGET_DRAG, false) // Nothing to do when a widget is being dragged & dropped. The drop // target in the communal grid will receive the widget to be added (if // the user drops it over). if (!isPendingWidgetDrag) { val (componentName, user) = getWidgetExtraFromIntent(intent) if (componentName != null && user != null) { // Add widget at the end. communalViewModel.onAddWidget( componentName, user, configurator = widgetConfigurator, ) } else { run { Log.w(TAG, "No AppWidgetProviderInfo found in result.") } } } } ?: run { Log.w(TAG, "No data in result.") } } else -> Log.w( TAG, "Failed to receive result from widget picker, code=${result.resultCode}" ) } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Loading @@ -226,8 +193,7 @@ constructor( PlatformTheme { Box( modifier = Modifier.fillMaxSize() .background(MaterialTheme.colorScheme.surfaceDim), Modifier.fillMaxSize().background(MaterialTheme.colorScheme.surfaceDim) ) { CommunalHub( viewModel = communalViewModel, Loading Loading @@ -274,7 +240,13 @@ constructor( private fun onOpenWidgetPicker() { lifecycleScope.launch { communalViewModel.onOpenWidgetPicker(resources, addWidgetActivityLauncher) communalViewModel.onOpenWidgetPicker(resources) { intent: Intent -> startActivityForResultAsUser( intent, REQUEST_CODE_WIDGET_PICKER, userTracker.userHandle, ) } } } Loading @@ -285,7 +257,7 @@ constructor( communalViewModel.changeScene( scene = CommunalScenes.Communal, loggingReason = "edit mode closing", transitionKey = CommunalTransitionKeys.FromEditMode transitionKey = CommunalTransitionKeys.FromEditMode, ) // Wait for the current scene to be idle on communal. Loading @@ -309,7 +281,7 @@ constructor( flagsMask: Int, flagsValues: Int, extraFlags: Int, options: Bundle? options: Bundle?, ) { activityController.onWaitingForResult(true) super.startIntentSenderForResult( Loading @@ -319,15 +291,46 @@ constructor( flagsMask, flagsValues, extraFlags, options options, ) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { activityController.onWaitingForResult(false) super.onActivityResult(requestCode, resultCode, data) if (requestCode == WidgetConfigurationController.REQUEST_CODE) { when (requestCode) { WidgetConfigurationController.REQUEST_CODE -> widgetConfigurator.setConfigurationResult(resultCode) REQUEST_CODE_WIDGET_PICKER -> { if (resultCode != RESULT_OK) { Log.w(TAG, "Failed to receive result from widget picker, code=$resultCode") return } uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_WIDGET_PICKER_SHOWN) data?.let { intent -> val isPendingWidgetDrag = intent.getBooleanExtra(EXTRA_IS_PENDING_WIDGET_DRAG, false) // Nothing to do when a widget is being dragged & dropped. The drop // target in the communal grid will receive the widget to be added (if // the user drops it over). if (!isPendingWidgetDrag) { val (componentName, user) = getWidgetExtraFromIntent(intent) if (componentName != null && user != null) { // Add widget at the end. communalViewModel.onAddWidget( componentName, user, configurator = widgetConfigurator, ) } else { run { Log.w(TAG, "No AppWidgetProviderInfo found in result.") } } } } ?: run { Log.w(TAG, "No data in result.") } } } } Loading