Merge "Allow removing the last app from home controls" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
61e9d75db7
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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<ControlsFavoritePersistenceWrapper>,
|
||||
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<ControlsFavoritePersistenceWrapper>,
|
||||
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<out String>) {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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<String> {
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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<StructureInfo>): SelectedItem
|
||||
|
||||
fun updatePreferences(selectedItem: SelectedItem)
|
||||
}
|
||||
|
||||
sealed class SelectedItem {
|
||||
|
||||
@@ -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<ControlsListingController>,
|
||||
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<TaskViewFactory>,
|
||||
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<SelectionItem>()
|
||||
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<StructureInfo>): 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 {
|
||||
|
||||
@@ -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<ControlsListingController.ControlsListingCallback>
|
||||
|
||||
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,
|
||||
|
||||
@@ -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<String>()
|
||||
)
|
||||
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<Int, SharedPreferences>) :
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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<String>()
|
||||
)
|
||||
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<SelectedItem.PanelItem>())
|
||||
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(
|
||||
|
||||
@@ -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<StructureInfo>()
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user