diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt index 3555d0a7e7fbb..2d37c292a6b8e 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt @@ -172,12 +172,6 @@ interface ControlsController : UserAwareController { */ fun removeFavorites(componentName: ComponentName): Boolean - /** - * Checks if the favorites can be removed. You can't remove components from the preferred list. - * @param componentName the name of the service that provides the [Control] - */ - fun canRemoveFavorites(componentName: ComponentName): Boolean - /** * Replaces the favorites for the given structure. * diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt index 854790360f6ac..e8c97bf772716 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt @@ -37,6 +37,7 @@ import com.android.systemui.controls.ControlStatus import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.panels.AuthorizedPanelsRepository +import com.android.systemui.controls.panels.SelectedComponentRepository import com.android.systemui.controls.ui.ControlsUiController import com.android.systemui.controls.ui.SelectedItem import com.android.systemui.dagger.SysUISingleton @@ -55,16 +56,17 @@ import javax.inject.Inject @SysUISingleton class ControlsControllerImpl @Inject constructor ( - private val context: Context, - @Background private val executor: DelayableExecutor, - private val uiController: ControlsUiController, - private val bindingController: ControlsBindingController, - private val listingController: ControlsListingController, - private val userFileManager: UserFileManager, - private val userTracker: UserTracker, - private val authorizedPanelsRepository: AuthorizedPanelsRepository, - optionalWrapper: Optional, - dumpManager: DumpManager, + private val context: Context, + @Background private val executor: DelayableExecutor, + private val uiController: ControlsUiController, + private val selectedComponentRepository: SelectedComponentRepository, + private val bindingController: ControlsBindingController, + private val listingController: ControlsListingController, + private val userFileManager: UserFileManager, + private val userTracker: UserTracker, + private val authorizedPanelsRepository: AuthorizedPanelsRepository, + optionalWrapper: Optional, + dumpManager: DumpManager, ) : Dumpable, ControlsController { companion object { @@ -497,17 +499,14 @@ class ControlsControllerImpl @Inject constructor ( } } - override fun canRemoveFavorites(componentName: ComponentName): Boolean = - !authorizedPanelsRepository.getPreferredPackages().contains(componentName.packageName) - override fun removeFavorites(componentName: ComponentName): Boolean { if (!confirmAvailability()) return false - if (!canRemoveFavorites(componentName)) return false executor.execute { - Favorites.removeStructures(componentName) + if (Favorites.removeStructures(componentName)) { + persistenceWrapper.storeFavorites(Favorites.getAllStructures()) + } authorizedPanelsRepository.removeAuthorizedPanels(setOf(componentName.packageName)) - persistenceWrapper.storeFavorites(Favorites.getAllStructures()) } return true } @@ -574,7 +573,9 @@ class ControlsControllerImpl @Inject constructor ( } override fun setPreferredSelection(selectedItem: SelectedItem) { - uiController.updatePreferences(selectedItem) + selectedComponentRepository.setSelectedComponent( + SelectedComponentRepository.SelectedComponent(selectedItem) + ) } override fun dump(pw: PrintWriter, args: Array) { diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt index d949d11192228..2af49aa5fa1a5 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt @@ -36,6 +36,8 @@ import com.android.systemui.controls.management.ControlsProviderSelectorActivity import com.android.systemui.controls.management.ControlsRequestDialog import com.android.systemui.controls.panels.AuthorizedPanelsRepository import com.android.systemui.controls.panels.AuthorizedPanelsRepositoryImpl +import com.android.systemui.controls.panels.SelectedComponentRepository +import com.android.systemui.controls.panels.SelectedComponentRepositoryImpl import com.android.systemui.controls.settings.ControlsSettingsDialogManager import com.android.systemui.controls.settings.ControlsSettingsDialogManagerImpl import com.android.systemui.controls.ui.ControlActionCoordinator @@ -114,6 +116,11 @@ abstract class ControlsModule { repository: AuthorizedPanelsRepositoryImpl ): AuthorizedPanelsRepository + @Binds + abstract fun providePreferredPanelRepository( + repository: SelectedComponentRepositoryImpl + ): SelectedComponentRepository + @BindsOptionalOf abstract fun optionalPersistenceWrapper(): ControlsFavoritePersistenceWrapper diff --git a/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt index e51e8326c0a5a..5c2402ba41495 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt @@ -20,6 +20,8 @@ package com.android.systemui.controls.panels import android.content.Context import android.content.SharedPreferences import com.android.systemui.R +import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl @@ -30,7 +32,8 @@ class AuthorizedPanelsRepositoryImpl constructor( private val context: Context, private val userFileManager: UserFileManager, - private val userTracker: UserTracker + private val userTracker: UserTracker, + private val featureFlags: FeatureFlags, ) : AuthorizedPanelsRepository { override fun getAuthorizedPanels(): Set { @@ -71,8 +74,18 @@ constructor( userTracker.userId, ) - // If we've never run this (i.e., the key doesn't exist), add the default packages - if (sharedPref.getStringSet(KEY, null) == null) { + // We should add default packages in two cases: + // 1) We've never run this + // 2) APP_PANELS_REMOVE_APPS_ALLOWED got disabled after user removed all apps + val needToSetup = + if (featureFlags.isEnabled(Flags.APP_PANELS_REMOVE_APPS_ALLOWED)) { + sharedPref.getStringSet(KEY, null) == null + } else { + // There might be an empty set that need to be overridden after the feature has been + // turned off after being turned on + sharedPref.getStringSet(KEY, null).isNullOrEmpty() + } + if (needToSetup) { sharedPref.edit().putStringSet(KEY, getPreferredPackages()).apply() } return sharedPref diff --git a/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepository.kt b/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepository.kt new file mode 100644 index 0000000000000..5bb6eece90982 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepository.kt @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 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.controls.panels + +import android.content.ComponentName +import com.android.systemui.controls.ui.ControlsUiController +import com.android.systemui.controls.ui.SelectedItem +import com.android.systemui.flags.Flags + +/** Stores user-selected preferred component. */ +interface SelectedComponentRepository { + + /** + * Returns currently set preferred component, or null when nothing is set. Consider using + * [ControlsUiController.getPreferredSelectedItem] to get domain specific data + */ + fun getSelectedComponent(): SelectedComponent? + + /** Sets preferred component. Use [getSelectedComponent] to get current one */ + fun setSelectedComponent(selectedComponent: SelectedComponent) + + /** Clears current preferred component. [getSelectedComponent] will return null afterwards */ + fun removeSelectedComponent() + + /** + * Return true when default preferred component should be set up and false the otherwise. This + * is always true when [Flags.APP_PANELS_REMOVE_APPS_ALLOWED] is disabled + */ + fun shouldAddDefaultComponent(): Boolean + + /** + * Sets if default component should be added. This is ignored when + * [Flags.APP_PANELS_REMOVE_APPS_ALLOWED] is disabled + */ + fun setShouldAddDefaultComponent(shouldAdd: Boolean) + + data class SelectedComponent( + val name: String, + val componentName: ComponentName?, + val isPanel: Boolean, + ) { + constructor( + selectedItem: SelectedItem + ) : this( + name = selectedItem.name.toString(), + componentName = selectedItem.componentName, + isPanel = selectedItem is SelectedItem.PanelItem, + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepositoryImpl.kt new file mode 100644 index 0000000000000..0fb5b66ef93c8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/controls/panels/SelectedComponentRepositoryImpl.kt @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2023 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.controls.panels + +import android.content.ComponentName +import android.content.Context +import android.content.SharedPreferences +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags +import com.android.systemui.settings.UserFileManager +import com.android.systemui.settings.UserTracker +import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl +import javax.inject.Inject + +@SysUISingleton +class SelectedComponentRepositoryImpl +@Inject +constructor( + private val userFileManager: UserFileManager, + private val userTracker: UserTracker, + private val featureFlags: FeatureFlags, +) : SelectedComponentRepository { + + private companion object { + const val PREF_COMPONENT = "controls_component" + const val PREF_STRUCTURE_OR_APP_NAME = "controls_structure" + const val PREF_IS_PANEL = "controls_is_panel" + const val SHOULD_ADD_DEFAULT_PANEL = "should_add_default_panel" + } + + private val sharedPreferences: SharedPreferences + get() = + userFileManager.getSharedPreferences( + fileName = DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, + mode = Context.MODE_PRIVATE, + userId = userTracker.userId + ) + + override fun getSelectedComponent(): SelectedComponentRepository.SelectedComponent? { + with(sharedPreferences) { + val componentString = getString(PREF_COMPONENT, null) ?: return null + return SelectedComponentRepository.SelectedComponent( + name = getString(PREF_STRUCTURE_OR_APP_NAME, "")!!, + componentName = ComponentName.unflattenFromString(componentString), + isPanel = getBoolean(PREF_IS_PANEL, false) + ) + } + } + + override fun setSelectedComponent( + selectedComponent: SelectedComponentRepository.SelectedComponent + ) { + sharedPreferences + .edit() + .putString(PREF_COMPONENT, selectedComponent.componentName?.flattenToString()) + .putString(PREF_STRUCTURE_OR_APP_NAME, selectedComponent.name) + .putBoolean(PREF_IS_PANEL, selectedComponent.isPanel) + .apply() + } + + override fun removeSelectedComponent() { + sharedPreferences + .edit() + .remove(PREF_COMPONENT) + .remove(PREF_STRUCTURE_OR_APP_NAME) + .remove(PREF_IS_PANEL) + .apply() + } + + override fun shouldAddDefaultComponent(): Boolean = + if (featureFlags.isEnabled(Flags.APP_PANELS_REMOVE_APPS_ALLOWED)) { + sharedPreferences.getBoolean(SHOULD_ADD_DEFAULT_PANEL, true) + } else { + true + } + + override fun setShouldAddDefaultComponent(shouldAdd: Boolean) { + sharedPreferences.edit().putBoolean(SHOULD_ADD_DEFAULT_PANEL, shouldAdd).apply() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/controls/start/ControlsStartable.kt b/packages/SystemUI/src/com/android/systemui/controls/start/ControlsStartable.kt index 9d99253de741d..3a4a00c0ccd37 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/start/ControlsStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/start/ControlsStartable.kt @@ -18,17 +18,16 @@ package com.android.systemui.controls.start import android.content.Context -import android.content.res.Resources import android.os.UserHandle import com.android.systemui.CoreStartable -import com.android.systemui.R import com.android.systemui.controls.controller.ControlsController import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.management.ControlsListingController +import com.android.systemui.controls.panels.AuthorizedPanelsRepository +import com.android.systemui.controls.panels.SelectedComponentRepository import com.android.systemui.controls.ui.SelectedItem import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.settings.UserTracker import java.util.concurrent.Executor import javax.inject.Inject @@ -37,7 +36,7 @@ import javax.inject.Inject * Started with SystemUI to perform early operations for device controls subsystem (only if enabled) * * In particular, it will perform the following: - * * If there is no preferred selection for provider and at least one of the preferred packages + * * If there is no preferred selection for provider and at least one of the preferred packages * provides a panel, it will select the first one that does. * * If the preferred selection provides a panel, it will bind to that service (to reduce latency on * displaying the panel). @@ -48,10 +47,11 @@ import javax.inject.Inject class ControlsStartable @Inject constructor( - @Main private val resources: Resources, - @Background private val executor: Executor, - private val controlsComponent: ControlsComponent, - private val userTracker: UserTracker + @Background private val executor: Executor, + private val controlsComponent: ControlsComponent, + private val userTracker: UserTracker, + private val authorizedPanelsRepository: AuthorizedPanelsRepository, + private val selectedComponentRepository: SelectedComponentRepository, ) : CoreStartable { // These two controllers can only be accessed after `start` method once we've checked if the @@ -85,12 +85,15 @@ constructor( } private fun selectDefaultPanelIfNecessary() { + if (!selectedComponentRepository.shouldAddDefaultComponent()) { + return + } val currentSelection = controlsController.getPreferredSelection() if (currentSelection == SelectedItem.EMPTY_SELECTION) { val availableServices = controlsListingController.getCurrentServices() val panels = availableServices.filter { it.panelActivity != null } - resources - .getStringArray(R.array.config_controlsPreferredPackages) + authorizedPanelsRepository + .getPreferredPackages() // Looking for the first element in the string array such that there is one package // that has a panel. It will return null if there are no packages in the array, // or if no packages in the array have a panel associated with it. diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt index 58673bb6f567b..0d5311752ab9b 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt @@ -64,8 +64,6 @@ interface ControlsUiController { * This element will be the one that appears when the user first opens the controls activity. */ fun getPreferredSelectedItem(structures: List): SelectedItem - - fun updatePreferences(selectedItem: SelectedItem) } sealed class SelectedItem { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index c61dad6fc0752..5da86de933e63 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -64,6 +64,7 @@ import com.android.systemui.controls.management.ControlsFavoritingActivity import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.management.ControlsProviderSelectorActivity import com.android.systemui.controls.panels.AuthorizedPanelsRepository +import com.android.systemui.controls.panels.SelectedComponentRepository import com.android.systemui.controls.settings.ControlsSettingsRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background @@ -73,9 +74,7 @@ import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.globalactions.GlobalActionsPopupMenu import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker -import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.asIndenting import com.android.systemui.util.concurrency.DelayableExecutor @@ -84,7 +83,7 @@ import com.android.wm.shell.TaskViewFactory import dagger.Lazy import java.io.PrintWriter import java.text.Collator -import java.util.* +import java.util.Optional import java.util.function.Consumer import javax.inject.Inject @@ -98,25 +97,22 @@ class ControlsUiControllerImpl @Inject constructor ( @Main val uiExecutor: DelayableExecutor, @Background val bgExecutor: DelayableExecutor, val controlsListingController: Lazy, - val controlActionCoordinator: ControlActionCoordinator, + private val controlActionCoordinator: ControlActionCoordinator, private val activityStarter: ActivityStarter, private val iconCache: CustomIconCache, private val controlsMetricsLogger: ControlsMetricsLogger, private val keyguardStateController: KeyguardStateController, - private val userFileManager: UserFileManager, private val userTracker: UserTracker, private val taskViewFactory: Optional, private val controlsSettingsRepository: ControlsSettingsRepository, private val authorizedPanelsRepository: AuthorizedPanelsRepository, + private val selectedComponentRepository: SelectedComponentRepository, private val featureFlags: FeatureFlags, private val dialogsFactory: ControlsDialogsFactory, dumpManager: DumpManager ) : ControlsUiController, Dumpable { companion object { - private const val PREF_COMPONENT = "controls_component" - private const val PREF_STRUCTURE_OR_APP_NAME = "controls_structure" - private const val PREF_IS_PANEL = "controls_is_panel" private const val FADE_IN_MILLIS = 200L @@ -138,12 +134,6 @@ class ControlsUiControllerImpl @Inject constructor ( private val popupThemedContext = ContextThemeWrapper(context, R.style.Control_ListPopupWindow) private var retainCache = false private var lastSelections = emptyList() - private val sharedPreferences - get() = userFileManager.getSharedPreferences( - fileName = DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, - mode = 0, - userId = userTracker.userId - ) private var taskViewController: PanelTaskViewController? = null @@ -341,20 +331,18 @@ class ControlsUiControllerImpl @Inject constructor ( if (!controlsController.get().removeFavorites(componentName)) { return@createRemoveAppDialog } - if ( - sharedPreferences.getString(PREF_COMPONENT, "") == - componentName.flattenToString() - ) { - sharedPreferences - .edit() - .remove(PREF_COMPONENT) - .remove(PREF_STRUCTURE_OR_APP_NAME) - .remove(PREF_IS_PANEL) - .commit() + + if (selectedComponentRepository.getSelectedComponent()?.componentName == + componentName) { + selectedComponentRepository.removeSelectedComponent() } - allStructures = controlsController.get().getFavorites() - selectedItem = getPreferredSelectedItem(allStructures) + val selectedItem = getPreferredSelectedItem(controlsController.get().getFavorites()) + if (selectedItem == SelectedItem.EMPTY_SELECTION) { + // User removed the last panel. In this case we start app selection flow and don't + // want to auto-add it again + selectedComponentRepository.setShouldAddDefaultComponent(false) + } reload(parent) }.apply { show() } } @@ -522,8 +510,7 @@ class ControlsUiControllerImpl @Inject constructor ( ADD_APP_ID )) } - if (featureFlags.isEnabled(Flags.APP_PANELS_REMOVE_APPS_ALLOWED) && - controlsController.get().canRemoveFavorites(selectedItem.componentName)) { + if (featureFlags.isEnabled(Flags.APP_PANELS_REMOVE_APPS_ALLOWED)) { add(OverflowMenuAdapter.MenuItem( context.getText(R.string.controls_menu_remove), REMOVE_APP_ID, @@ -569,7 +556,7 @@ class ControlsUiControllerImpl @Inject constructor ( ADD_CONTROLS_ID -> startFavoritingActivity(selectedStructure) EDIT_CONTROLS_ID -> startEditingActivity(selectedStructure) REMOVE_APP_ID -> startRemovingApp( - selectedStructure.componentName, selectionItem.appName + selectionItem.componentName, selectionItem.appName ) } dismiss() @@ -714,29 +701,22 @@ class ControlsUiControllerImpl @Inject constructor ( } override fun getPreferredSelectedItem(structures: List): SelectedItem { - val sp = sharedPreferences - - val component = sp.getString(PREF_COMPONENT, null)?.let { - ComponentName.unflattenFromString(it) - } ?: EMPTY_COMPONENT - val name = sp.getString(PREF_STRUCTURE_OR_APP_NAME, "")!! - val isPanel = sp.getBoolean(PREF_IS_PANEL, false) - return if (isPanel) { - SelectedItem.PanelItem(name, component) + val preferredPanel = selectedComponentRepository.getSelectedComponent() + val component = preferredPanel?.componentName ?: EMPTY_COMPONENT + return if (preferredPanel?.isPanel == true) { + SelectedItem.PanelItem(preferredPanel.name, component) } else { if (structures.isEmpty()) return SelectedItem.EMPTY_SELECTION SelectedItem.StructureItem(structures.firstOrNull { - component == it.componentName && name == it.structure - } ?: structures.get(0)) + component == it.componentName && preferredPanel?.name == it.structure + } ?: structures[0]) } } - override fun updatePreferences(selectedItem: SelectedItem) { - sharedPreferences.edit() - .putString(PREF_COMPONENT, selectedItem.componentName.flattenToString()) - .putString(PREF_STRUCTURE_OR_APP_NAME, selectedItem.name.toString()) - .putBoolean(PREF_IS_PANEL, selectedItem is SelectedItem.PanelItem) - .apply() + private fun updatePreferences(selectedItem: SelectedItem) { + selectedComponentRepository.setSelectedComponent( + SelectedComponentRepository.SelectedComponent(selectedItem) + ) } private fun maybeUpdateSelectedItem(item: SelectionItem): Boolean { diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt index 28e80057a672f..c98d5374311d1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt @@ -34,6 +34,7 @@ import com.android.systemui.controls.ControlStatus import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.panels.AuthorizedPanelsRepository +import com.android.systemui.controls.panels.FakeSelectedComponentRepository import com.android.systemui.controls.ui.ControlsUiController import com.android.systemui.dump.DumpManager import com.android.systemui.settings.UserFileManager @@ -56,7 +57,6 @@ import org.mockito.ArgumentMatchers.anyString import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito -import org.mockito.Mockito.`when` import org.mockito.Mockito.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.inOrder @@ -66,6 +66,7 @@ import org.mockito.Mockito.reset import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions +import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations import java.io.File import java.util.* @@ -108,6 +109,8 @@ class ControlsControllerImplTest : SysuiTestCase() { private lateinit var listingCallbackCaptor: ArgumentCaptor + private val preferredPanelRepository = FakeSelectedComponentRepository() + private lateinit var delayableExecutor: FakeExecutor private lateinit var controller: ControlsControllerImpl private lateinit var canceller: DidRunRunnable @@ -168,6 +171,7 @@ class ControlsControllerImplTest : SysuiTestCase() { wrapper, delayableExecutor, uiController, + preferredPanelRepository, bindingController, listingController, userFileManager, @@ -221,6 +225,7 @@ class ControlsControllerImplTest : SysuiTestCase() { mContext, delayableExecutor, uiController, + preferredPanelRepository, bindingController, listingController, userFileManager, @@ -240,6 +245,7 @@ class ControlsControllerImplTest : SysuiTestCase() { mContext, delayableExecutor, uiController, + preferredPanelRepository, bindingController, listingController, userFileManager, diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt index 7ac1953ee4951..272f5895390ce 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt @@ -22,6 +22,8 @@ import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase +import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.Flags import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker import com.android.systemui.util.FakeSharedPreferences @@ -40,6 +42,8 @@ class AuthorizedPanelsRepositoryImplTest : SysuiTestCase() { @Mock private lateinit var userTracker: UserTracker + private val featureFlags = FakeFeatureFlags() + @Before fun setUp() { MockitoAnnotations.initMocks(this) @@ -48,6 +52,7 @@ class AuthorizedPanelsRepositoryImplTest : SysuiTestCase() { arrayOf() ) whenever(userTracker.userId).thenReturn(0) + featureFlags.set(Flags.APP_PANELS_REMOVE_APPS_ALLOWED, true) } @Test @@ -127,8 +132,25 @@ class AuthorizedPanelsRepositoryImplTest : SysuiTestCase() { assertThat(sharedPrefs.getStringSet(KEY, null)).isEmpty() } + @Test + fun testSetAuthorizedPackageAfterFeatureDisabled() { + mContext.orCreateTestableResources.addOverride( + R.array.config_controlsPreferredPackages, + arrayOf(TEST_PACKAGE) + ) + val sharedPrefs = FakeSharedPreferences() + val fileManager = FakeUserFileManager(mapOf(0 to sharedPrefs)) + val repository = createRepository(fileManager) + + repository.removeAuthorizedPanels(setOf(TEST_PACKAGE)) + + featureFlags.set(Flags.APP_PANELS_REMOVE_APPS_ALLOWED, false) + + assertThat(repository.getAuthorizedPanels()).isEqualTo(setOf(TEST_PACKAGE)) + } + private fun createRepository(userFileManager: UserFileManager): AuthorizedPanelsRepositoryImpl { - return AuthorizedPanelsRepositoryImpl(mContext, userFileManager, userTracker) + return AuthorizedPanelsRepositoryImpl(mContext, userFileManager, userTracker, featureFlags) } private class FakeUserFileManager(private val sharedPrefs: Map) : diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/FakeSelectedComponentRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/FakeSelectedComponentRepository.kt new file mode 100644 index 0000000000000..a7677cca9f294 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/FakeSelectedComponentRepository.kt @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 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.controls.panels + +class FakeSelectedComponentRepository : SelectedComponentRepository { + + private var selectedComponent: SelectedComponentRepository.SelectedComponent? = null + private var shouldAddDefaultPanel: Boolean = true + + override fun getSelectedComponent(): SelectedComponentRepository.SelectedComponent? = + selectedComponent + + override fun setSelectedComponent( + selectedComponent: SelectedComponentRepository.SelectedComponent + ) { + this.selectedComponent = selectedComponent + } + + override fun removeSelectedComponent() { + selectedComponent = null + } + + override fun shouldAddDefaultComponent(): Boolean = shouldAddDefaultPanel + + override fun setShouldAddDefaultComponent(shouldAdd: Boolean) { + shouldAddDefaultPanel = shouldAdd + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt new file mode 100644 index 0000000000000..0c7b9cb82b942 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2023 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.controls.panels + +import android.content.ComponentName +import android.content.SharedPreferences +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.Flags +import com.android.systemui.settings.UserFileManager +import com.android.systemui.settings.UserTracker +import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl +import com.android.systemui.util.FakeSharedPreferences +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class SelectedComponentRepositoryTest : SysuiTestCase() { + + private companion object { + val COMPONENT_A = + SelectedComponentRepository.SelectedComponent( + name = "a", + componentName = ComponentName.unflattenFromString("pkg/.cls_a"), + isPanel = false, + ) + val COMPONENT_B = + SelectedComponentRepository.SelectedComponent( + name = "b", + componentName = ComponentName.unflattenFromString("pkg/.cls_b"), + isPanel = false, + ) + } + + @Mock private lateinit var userTracker: UserTracker + @Mock private lateinit var userFileManager: UserFileManager + + private val featureFlags = FakeFeatureFlags() + private val sharedPreferences: SharedPreferences = FakeSharedPreferences() + + // under test + private lateinit var repository: SelectedComponentRepository + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + whenever(userFileManager.getSharedPreferences(any(), any(), any())) + .thenReturn(sharedPreferences) + + repository = SelectedComponentRepositoryImpl(userFileManager, userTracker, featureFlags) + } + + @Test + fun testUnsetIsNull() { + assertThat(repository.getSelectedComponent()).isNull() + } + + @Test + fun testGetReturnsSet() { + repository.setSelectedComponent(COMPONENT_A) + + assertThat(repository.getSelectedComponent()).isEqualTo(COMPONENT_A) + } + + @Test + fun testSetOverrides() { + repository.setSelectedComponent(COMPONENT_A) + repository.setSelectedComponent(COMPONENT_B) + + assertThat(repository.getSelectedComponent()).isEqualTo(COMPONENT_B) + } + + @Test + fun testRemove() { + repository.setSelectedComponent(COMPONENT_A) + + repository.removeSelectedComponent() + + assertThat(repository.getSelectedComponent()).isNull() + } + + @Test + fun testFeatureEnabled_shouldAddDefaultPanelDefaultsToTrue() { + featureFlags.set(Flags.APP_PANELS_REMOVE_APPS_ALLOWED, true) + + assertThat(repository.shouldAddDefaultComponent()).isTrue() + } + + @Test + fun testFeatureDisabled_shouldAddDefaultPanelDefaultsToTrue() { + featureFlags.set(Flags.APP_PANELS_REMOVE_APPS_ALLOWED, false) + + assertThat(repository.shouldAddDefaultComponent()).isTrue() + } + + @Test + fun testFeatureEnabled_shouldAddDefaultPanelChecked() { + featureFlags.set(Flags.APP_PANELS_REMOVE_APPS_ALLOWED, true) + repository.setShouldAddDefaultComponent(false) + + assertThat(repository.shouldAddDefaultComponent()).isFalse() + } + + @Test + fun testFeatureDisabled_shouldAlwaysAddDefaultPanelAlwaysTrue() { + featureFlags.set(Flags.APP_PANELS_REMOVE_APPS_ALLOWED, false) + repository.setShouldAddDefaultComponent(false) + + assertThat(repository.shouldAddDefaultComponent()).isTrue() + } + + @Test + fun testGetPreferredStructure_differentUserId() { + sharedPreferences.savePanel(COMPONENT_A) + whenever( + userFileManager.getSharedPreferences( + DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, + 0, + 1, + ) + ) + .thenReturn(FakeSharedPreferences().also { it.savePanel(COMPONENT_B) }) + + val previousPreferredStructure = repository.getSelectedComponent() + whenever(userTracker.userId).thenReturn(1) + val currentPreferredStructure = repository.getSelectedComponent() + + assertThat(previousPreferredStructure).isEqualTo(COMPONENT_A) + assertThat(currentPreferredStructure).isNotEqualTo(previousPreferredStructure) + assertThat(currentPreferredStructure).isEqualTo(COMPONENT_B) + } + + private fun SharedPreferences.savePanel(panel: SelectedComponentRepository.SelectedComponent) { + edit() + .putString("controls_component", panel.componentName?.flattenToString()) + .putString("controls_structure", panel.name) + .putBoolean("controls_is_panel", panel.isPanel) + .commit() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/start/ControlsStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/start/ControlsStartableTest.kt index 7ecaca6c36d01..9d8084d4f2f43 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/start/ControlsStartableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/start/ControlsStartableTest.kt @@ -23,17 +23,19 @@ import android.content.pm.ApplicationInfo import android.content.pm.ServiceInfo import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.controller.ControlsController import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.management.ControlsListingController +import com.android.systemui.controls.panels.AuthorizedPanelsRepository +import com.android.systemui.controls.panels.FakeSelectedComponentRepository import com.android.systemui.controls.ui.SelectedItem import com.android.systemui.settings.UserTracker import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import java.util.Optional import org.junit.Before @@ -53,16 +55,16 @@ class ControlsStartableTest : SysuiTestCase() { @Mock private lateinit var controlsController: ControlsController @Mock private lateinit var controlsListingController: ControlsListingController @Mock private lateinit var userTracker: UserTracker + @Mock private lateinit var authorizedPanelsRepository: AuthorizedPanelsRepository + + private val preferredPanelsRepository = FakeSelectedComponentRepository() private lateinit var fakeExecutor: FakeExecutor @Before fun setUp() { MockitoAnnotations.initMocks(this) - context.orCreateTestableResources.addOverride( - R.array.config_controlsPreferredPackages, - arrayOf() - ) + whenever(authorizedPanelsRepository.getPreferredPackages()).thenReturn(setOf()) fakeExecutor = FakeExecutor(FakeSystemClock()) } @@ -87,10 +89,8 @@ class ControlsStartableTest : SysuiTestCase() { @Test fun testPreferredPackagesNotInstalled_noNewSelection() { - context.orCreateTestableResources.addOverride( - R.array.config_controlsPreferredPackages, - arrayOf(TEST_PACKAGE_PANEL) - ) + whenever(authorizedPanelsRepository.getPreferredPackages()) + .thenReturn(setOf(TEST_PACKAGE_PANEL)) `when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION) `when`(controlsListingController.getCurrentServices()).thenReturn(emptyList()) @@ -101,10 +101,8 @@ class ControlsStartableTest : SysuiTestCase() { @Test fun testPreferredPackageNotPanel_noNewSelection() { - context.orCreateTestableResources.addOverride( - R.array.config_controlsPreferredPackages, - arrayOf(TEST_PACKAGE_PANEL) - ) + whenever(authorizedPanelsRepository.getPreferredPackages()) + .thenReturn(setOf(TEST_PACKAGE_PANEL)) `when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION) val listings = listOf(ControlsServiceInfo(TEST_COMPONENT, "not panel", hasPanel = false)) `when`(controlsListingController.getCurrentServices()).thenReturn(listings) @@ -116,10 +114,8 @@ class ControlsStartableTest : SysuiTestCase() { @Test fun testExistingSelection_noNewSelection() { - context.orCreateTestableResources.addOverride( - R.array.config_controlsPreferredPackages, - arrayOf(TEST_PACKAGE_PANEL) - ) + whenever(authorizedPanelsRepository.getPreferredPackages()) + .thenReturn(setOf(TEST_PACKAGE_PANEL)) `when`(controlsController.getPreferredSelection()) .thenReturn(mock()) val listings = listOf(ControlsServiceInfo(TEST_COMPONENT_PANEL, "panel", hasPanel = true)) @@ -132,10 +128,8 @@ class ControlsStartableTest : SysuiTestCase() { @Test fun testPanelAdded() { - context.orCreateTestableResources.addOverride( - R.array.config_controlsPreferredPackages, - arrayOf(TEST_PACKAGE_PANEL) - ) + whenever(authorizedPanelsRepository.getPreferredPackages()) + .thenReturn(setOf(TEST_PACKAGE_PANEL)) `when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION) val listings = listOf(ControlsServiceInfo(TEST_COMPONENT_PANEL, "panel", hasPanel = true)) `when`(controlsListingController.getCurrentServices()).thenReturn(listings) @@ -147,10 +141,8 @@ class ControlsStartableTest : SysuiTestCase() { @Test fun testMultiplePreferredOnlyOnePanel_panelAdded() { - context.orCreateTestableResources.addOverride( - R.array.config_controlsPreferredPackages, - arrayOf("other_package", TEST_PACKAGE_PANEL) - ) + whenever(authorizedPanelsRepository.getPreferredPackages()) + .thenReturn(setOf(TEST_PACKAGE_PANEL)) `when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION) val listings = listOf( @@ -166,10 +158,8 @@ class ControlsStartableTest : SysuiTestCase() { @Test fun testMultiplePreferredMultiplePanels_firstPreferredAdded() { - context.orCreateTestableResources.addOverride( - R.array.config_controlsPreferredPackages, - arrayOf(TEST_PACKAGE_PANEL, "other_package") - ) + whenever(authorizedPanelsRepository.getPreferredPackages()) + .thenReturn(setOf(TEST_PACKAGE_PANEL)) `when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION) val listings = listOf( @@ -217,6 +207,20 @@ class ControlsStartableTest : SysuiTestCase() { verify(controlsController, never()).bindComponentForPanel(any()) } + @Test + fun testAlreadyAddedPanel_noNewSelection() { + preferredPanelsRepository.setShouldAddDefaultComponent(false) + whenever(authorizedPanelsRepository.getPreferredPackages()) + .thenReturn(setOf(TEST_PACKAGE_PANEL)) + `when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION) + val listings = listOf(ControlsServiceInfo(TEST_COMPONENT_PANEL, "panel", hasPanel = true)) + `when`(controlsListingController.getCurrentServices()).thenReturn(listings) + + createStartable(enabled = true).start() + + verify(controlsController, never()).setPreferredSelection(any()) + } + private fun createStartable(enabled: Boolean): ControlsStartable { val component: ControlsComponent = mock() { @@ -230,7 +234,13 @@ class ControlsStartableTest : SysuiTestCase() { `when`(getControlsListingController()).thenReturn(Optional.empty()) } } - return ControlsStartable(context.resources, fakeExecutor, component, userTracker) + return ControlsStartable( + fakeExecutor, + component, + userTracker, + authorizedPanelsRepository, + preferredPanelsRepository, + ) } private fun ControlsServiceInfo( diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt index 23faa99c0b9d2..3f61bf75740a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt @@ -42,16 +42,14 @@ import com.android.systemui.controls.controller.StructureInfo import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.management.ControlsProviderSelectorActivity import com.android.systemui.controls.panels.AuthorizedPanelsRepository +import com.android.systemui.controls.panels.FakeSelectedComponentRepository +import com.android.systemui.controls.panels.SelectedComponentRepository import com.android.systemui.controls.settings.FakeControlsSettingsRepository import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FeatureFlags import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker -import com.android.systemui.shade.ShadeController -import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl import com.android.systemui.statusbar.policy.KeyguardStateController -import com.android.systemui.util.FakeSharedPreferences import com.android.systemui.util.FakeSystemUIDialogController import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any @@ -64,20 +62,18 @@ import com.android.systemui.util.time.FakeSystemClock import com.android.wm.shell.TaskView import com.android.wm.shell.TaskViewFactory import com.google.common.truth.Truth.assertThat +import java.util.Optional +import java.util.function.Consumer import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock -import org.mockito.Mockito.`when` -import org.mockito.Mockito.anyInt -import org.mockito.Mockito.anyString import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations -import java.util.Optional -import java.util.function.Consumer @SmallTest @RunWith(AndroidTestingRunner::class) @@ -87,11 +83,9 @@ class ControlsUiControllerImplTest : SysuiTestCase() { @Mock lateinit var controlsListingController: ControlsListingController @Mock lateinit var controlActionCoordinator: ControlActionCoordinator @Mock lateinit var activityStarter: ActivityStarter - @Mock lateinit var shadeController: ShadeController @Mock lateinit var iconCache: CustomIconCache @Mock lateinit var controlsMetricsLogger: ControlsMetricsLogger @Mock lateinit var keyguardStateController: KeyguardStateController - @Mock lateinit var userFileManager: UserFileManager @Mock lateinit var userTracker: UserTracker @Mock lateinit var taskViewFactory: TaskViewFactory @Mock lateinit var dumpManager: DumpManager @@ -99,7 +93,7 @@ class ControlsUiControllerImplTest : SysuiTestCase() { @Mock lateinit var featureFlags: FeatureFlags @Mock lateinit var packageManager: PackageManager - private val sharedPreferences = FakeSharedPreferences() + private val preferredPanelRepository = FakeSelectedComponentRepository() private val fakeDialogController = FakeSystemUIDialogController() private val uiExecutor = FakeExecutor(FakeSystemClock()) private val bgExecutor = FakeExecutor(FakeSystemClock()) @@ -138,94 +132,30 @@ class ControlsUiControllerImplTest : SysuiTestCase() { iconCache, controlsMetricsLogger, keyguardStateController, - userFileManager, userTracker, Optional.of(taskViewFactory), controlsSettingsRepository, authorizedPanelsRepository, + preferredPanelRepository, featureFlags, ControlsDialogsFactory { fakeDialogController.dialog }, dumpManager, ) - `when`( - userFileManager.getSharedPreferences( - DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, - 0, - 0 - ) - ) - .thenReturn(sharedPreferences) - `when`(userFileManager.getSharedPreferences(anyString(), anyInt(), anyInt())) - .thenReturn(sharedPreferences) `when`(userTracker.userId).thenReturn(0) `when`(userTracker.userHandle).thenReturn(UserHandle.of(0)) } - @Test - fun testGetPreferredStructure() { - val structureInfo = mock() - underTest.getPreferredSelectedItem(listOf(structureInfo)) - verify(userFileManager) - .getSharedPreferences( - fileName = DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, - mode = 0, - userId = 0 - ) - } - - @Test - fun testGetPreferredStructure_differentUserId() { - val selectedItems = - listOf( - SelectedItem.StructureItem( - StructureInfo(ComponentName.unflattenFromString("pkg/.cls1"), "a", ArrayList()) - ), - SelectedItem.StructureItem( - StructureInfo(ComponentName.unflattenFromString("pkg/.cls2"), "b", ArrayList()) - ), - ) - val structures = selectedItems.map { it.structure } - sharedPreferences - .edit() - .putString("controls_component", selectedItems[0].componentName.flattenToString()) - .putString("controls_structure", selectedItems[0].name.toString()) - .commit() - - val differentSharedPreferences = FakeSharedPreferences() - differentSharedPreferences - .edit() - .putString("controls_component", selectedItems[1].componentName.flattenToString()) - .putString("controls_structure", selectedItems[1].name.toString()) - .commit() - - val previousPreferredStructure = underTest.getPreferredSelectedItem(structures) - - `when`( - userFileManager.getSharedPreferences( - DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, - 0, - 1 - ) - ) - .thenReturn(differentSharedPreferences) - `when`(userTracker.userId).thenReturn(1) - - val currentPreferredStructure = underTest.getPreferredSelectedItem(structures) - - assertThat(previousPreferredStructure).isEqualTo(selectedItems[0]) - assertThat(currentPreferredStructure).isEqualTo(selectedItems[1]) - assertThat(currentPreferredStructure).isNotEqualTo(previousPreferredStructure) - } - @Test fun testGetPreferredPanel() { val panel = SelectedItem.PanelItem("App name", ComponentName("pkg", "cls")) - sharedPreferences - .edit() - .putString("controls_component", panel.componentName.flattenToString()) - .putString("controls_structure", panel.appName.toString()) - .putBoolean("controls_is_panel", true) - .commit() + + preferredPanelRepository.setSelectedComponent( + SelectedComponentRepository.SelectedComponent( + name = panel.appName.toString(), + componentName = panel.componentName, + isPanel = true, + ) + ) val selected = underTest.getPreferredSelectedItem(emptyList()) @@ -369,11 +299,9 @@ class ControlsUiControllerImplTest : SysuiTestCase() { StructureInfo(ComponentName.unflattenFromString("pkg/.cls1"), "a", ArrayList()) ), ) - sharedPreferences - .edit() - .putString("controls_component", selectedItems[0].componentName.flattenToString()) - .putString("controls_structure", selectedItems[0].name.toString()) - .commit() + preferredPanelRepository.setSelectedComponent( + SelectedComponentRepository.SelectedComponent(selectedItems[0]) + ) assertThat(underTest.resolveActivity()) .isEqualTo(ControlsProviderSelectorActivity::class.java) @@ -418,12 +346,9 @@ class ControlsUiControllerImplTest : SysuiTestCase() { val componentName = ComponentName(context, "cls") whenever(controlsController.removeFavorites(eq(componentName))).thenReturn(true) val panel = SelectedItem.PanelItem("App name", componentName) - sharedPreferences - .edit() - .putString("controls_component", panel.componentName.flattenToString()) - .putString("controls_structure", panel.appName.toString()) - .putBoolean("controls_is_panel", true) - .commit() + preferredPanelRepository.setSelectedComponent( + SelectedComponentRepository.SelectedComponent(panel) + ) underTest.show(parent, {}, context) underTest.startRemovingApp(componentName, "Test App") @@ -432,11 +357,8 @@ class ControlsUiControllerImplTest : SysuiTestCase() { verify(controlsController).removeFavorites(eq(componentName)) assertThat(underTest.getPreferredSelectedItem(emptyList())) .isEqualTo(SelectedItem.EMPTY_SELECTION) - with(sharedPreferences) { - assertThat(contains("controls_component")).isFalse() - assertThat(contains("controls_structure")).isFalse() - assertThat(contains("controls_is_panel")).isFalse() - } + assertThat(preferredPanelRepository.shouldAddDefaultComponent()).isFalse() + assertThat(preferredPanelRepository.getSelectedComponent()).isNull() } @Test @@ -452,12 +374,9 @@ class ControlsUiControllerImplTest : SysuiTestCase() { private fun setUpPanel(panel: SelectedItem.PanelItem): ControlsServiceInfo { val activity = ComponentName(context, "activity") - sharedPreferences - .edit() - .putString("controls_component", panel.componentName.flattenToString()) - .putString("controls_structure", panel.appName.toString()) - .putBoolean("controls_is_panel", true) - .commit() + preferredPanelRepository.setSelectedComponent( + SelectedComponentRepository.SelectedComponent(panel) + ) return ControlsServiceInfo(panel.componentName, panel.appName, activity) }