Added core startable
This will make sure that panels of preferred packages are shown by default if there are no selection of provider and that panels will be bound on start. Test: manual, remove provider selected and observe. Test: atest ControlsStartableTest Fixes: 266703958 Change-Id: I04b8e442eb6336b4f7095055cb82a88f6f7530bc
This commit is contained in:
@@ -28,12 +28,13 @@ import android.content.pm.ResolveInfo
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.os.UserHandle
|
||||
import android.service.controls.ControlsProviderService
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.android.settingslib.applications.DefaultAppInfo
|
||||
import com.android.systemui.R
|
||||
import java.util.Objects
|
||||
|
||||
class ControlsServiceInfo(
|
||||
open class ControlsServiceInfo(
|
||||
private val context: Context,
|
||||
val serviceInfo: ServiceInfo
|
||||
) : DefaultAppInfo(
|
||||
@@ -64,7 +65,7 @@ class ControlsServiceInfo(
|
||||
* [R.array.config_controlsPreferredPackages] can declare activities for use as a panel.
|
||||
*/
|
||||
var panelActivity: ComponentName? = null
|
||||
private set
|
||||
protected set
|
||||
|
||||
private var resolved: Boolean = false
|
||||
|
||||
|
||||
@@ -121,16 +121,13 @@ class ControlsControllerImpl @Inject constructor (
|
||||
userChanging = false
|
||||
}
|
||||
|
||||
private val userTrackerCallback = object : UserTracker.Callback {
|
||||
override fun onUserChanged(newUser: Int, userContext: Context) {
|
||||
userChanging = true
|
||||
val newUserHandle = UserHandle.of(newUser)
|
||||
if (currentUser == newUserHandle) {
|
||||
userChanging = false
|
||||
return
|
||||
}
|
||||
setValuesForUser(newUserHandle)
|
||||
override fun changeUser(newUser: UserHandle) {
|
||||
userChanging = true
|
||||
if (currentUser == newUser) {
|
||||
userChanging = false
|
||||
return
|
||||
}
|
||||
setValuesForUser(newUser)
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -231,7 +228,6 @@ class ControlsControllerImpl @Inject constructor (
|
||||
dumpManager.registerDumpable(javaClass.name, this)
|
||||
resetFavorites()
|
||||
userChanging = false
|
||||
userTracker.addCallback(userTrackerCallback, executor)
|
||||
context.registerReceiver(
|
||||
restoreFinishedReceiver,
|
||||
IntentFilter(BackupHelper.ACTION_RESTORE_FINISHED),
|
||||
@@ -243,7 +239,6 @@ class ControlsControllerImpl @Inject constructor (
|
||||
}
|
||||
|
||||
fun destroy() {
|
||||
userTracker.removeCallback(userTrackerCallback)
|
||||
context.unregisterReceiver(restoreFinishedReceiver)
|
||||
listingController.removeCallback(listingCallback)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.dagger
|
||||
|
||||
import com.android.systemui.CoreStartable
|
||||
import com.android.systemui.controls.start.ControlsStartable
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.multibindings.ClassKey
|
||||
import dagger.multibindings.IntoMap
|
||||
|
||||
@Module
|
||||
abstract class StartControlsStartableModule {
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(ControlsStartable::class)
|
||||
abstract fun bindFeature(impl: ControlsStartable): CoreStartable
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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.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.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
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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).
|
||||
*
|
||||
* It will also perform those operations on user change.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class ControlsStartable
|
||||
@Inject
|
||||
constructor(
|
||||
@Main private val resources: Resources,
|
||||
@Background private val executor: Executor,
|
||||
private val controlsComponent: ControlsComponent,
|
||||
private val userTracker: UserTracker
|
||||
) : CoreStartable {
|
||||
|
||||
// These two controllers can only be accessed after `start` method once we've checked if the
|
||||
// feature is enabled
|
||||
private val controlsController: ControlsController
|
||||
get() = controlsComponent.getControlsController().get()
|
||||
|
||||
private val controlsListingController: ControlsListingController
|
||||
get() = controlsComponent.getControlsListingController().get()
|
||||
|
||||
private val userTrackerCallback =
|
||||
object : UserTracker.Callback {
|
||||
override fun onUserChanged(newUser: Int, userContext: Context) {
|
||||
controlsController.changeUser(UserHandle.of(newUser))
|
||||
startForUser()
|
||||
}
|
||||
}
|
||||
|
||||
override fun start() {
|
||||
if (!controlsComponent.isEnabled()) {
|
||||
// Controls is disabled, we don't need this anymore
|
||||
return
|
||||
}
|
||||
startForUser()
|
||||
userTracker.addCallback(userTrackerCallback, executor)
|
||||
}
|
||||
|
||||
private fun startForUser() {
|
||||
selectDefaultPanelIfNecessary()
|
||||
bindToPanel()
|
||||
}
|
||||
|
||||
private fun selectDefaultPanelIfNecessary() {
|
||||
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)
|
||||
// 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.
|
||||
.firstNotNullOfOrNull { name ->
|
||||
panels.firstOrNull { it.componentName.packageName == name }
|
||||
}
|
||||
?.let { info ->
|
||||
controlsController.setPreferredSelection(
|
||||
SelectedItem.PanelItem(info.loadLabel(), info.componentName)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindToPanel() {
|
||||
val currentSelection = controlsController.getPreferredSelection()
|
||||
val panels =
|
||||
controlsListingController.getCurrentServices().filter { it.panelActivity != null }
|
||||
if (
|
||||
currentSelection is SelectedItem.PanelItem &&
|
||||
panels.firstOrNull { it.componentName == currentSelection.componentName } != null
|
||||
) {
|
||||
controlsController.bindComponentForPanel(currentSelection.componentName)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import com.android.systemui.accessibility.SystemActions
|
||||
import com.android.systemui.accessibility.WindowMagnification
|
||||
import com.android.systemui.biometrics.AuthController
|
||||
import com.android.systemui.clipboardoverlay.ClipboardListener
|
||||
import com.android.systemui.controls.dagger.StartControlsStartableModule
|
||||
import com.android.systemui.dagger.qualifiers.PerUser
|
||||
import com.android.systemui.dreams.DreamMonitor
|
||||
import com.android.systemui.globalactions.GlobalActionsComponent
|
||||
@@ -64,7 +65,10 @@ import dagger.multibindings.IntoMap
|
||||
/**
|
||||
* Collection of {@link CoreStartable}s that should be run on AOSP.
|
||||
*/
|
||||
@Module(includes = [MultiUserUtilsModule::class])
|
||||
@Module(includes = [
|
||||
MultiUserUtilsModule::class,
|
||||
StartControlsStartableModule::class
|
||||
])
|
||||
abstract class SystemUICoreStartableModule {
|
||||
/** Inject into AuthController. */
|
||||
@Binds
|
||||
|
||||
@@ -103,8 +103,6 @@ class ControlsControllerImplTest : SysuiTestCase() {
|
||||
private lateinit var controlLoadCallbackCaptor2:
|
||||
ArgumentCaptor<ControlsBindingController.LoadCallback>
|
||||
|
||||
@Captor
|
||||
private lateinit var userTrackerCallbackCaptor: ArgumentCaptor<UserTracker.Callback>
|
||||
@Captor
|
||||
private lateinit var listingCallbackCaptor:
|
||||
ArgumentCaptor<ControlsListingController.ControlsListingCallback>
|
||||
@@ -178,10 +176,6 @@ class ControlsControllerImplTest : SysuiTestCase() {
|
||||
)
|
||||
controller.auxiliaryPersistenceWrapper = auxiliaryPersistenceWrapper
|
||||
|
||||
verify(userTracker).addCallback(
|
||||
capture(userTrackerCallbackCaptor), any()
|
||||
)
|
||||
|
||||
verify(listingController).addCallback(capture(listingCallbackCaptor))
|
||||
}
|
||||
|
||||
@@ -539,7 +533,7 @@ class ControlsControllerImplTest : SysuiTestCase() {
|
||||
|
||||
reset(persistenceWrapper)
|
||||
|
||||
userTrackerCallbackCaptor.value.onUserChanged(otherUser, mContext)
|
||||
controller.changeUser(UserHandle.of(otherUser))
|
||||
|
||||
verify(persistenceWrapper).changeFileAndBackupManager(any(), any())
|
||||
verify(persistenceWrapper).readFavorites()
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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.start
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
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.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.time.FakeSystemClock
|
||||
import java.util.Optional
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.verifyZeroInteractions
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
class ControlsStartableTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var controlsController: ControlsController
|
||||
@Mock private lateinit var controlsListingController: ControlsListingController
|
||||
@Mock private lateinit var userTracker: UserTracker
|
||||
|
||||
private lateinit var fakeExecutor: FakeExecutor
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.array.config_controlsPreferredPackages,
|
||||
arrayOf<String>()
|
||||
)
|
||||
|
||||
fakeExecutor = FakeExecutor(FakeSystemClock())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDisabledNothingIsCalled() {
|
||||
createStartable(enabled = false).start()
|
||||
|
||||
verifyZeroInteractions(controlsController, controlsListingController, userTracker)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNoPreferredPackagesNoDefaultSelected_noNewSelection() {
|
||||
`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())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPreferredPackagesNotInstalled_noNewSelection() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.array.config_controlsPreferredPackages,
|
||||
arrayOf(TEST_PACKAGE_PANEL)
|
||||
)
|
||||
`when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION)
|
||||
`when`(controlsListingController.getCurrentServices()).thenReturn(emptyList())
|
||||
|
||||
createStartable(enabled = true).start()
|
||||
|
||||
verify(controlsController, never()).setPreferredSelection(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPreferredPackageNotPanel_noNewSelection() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.array.config_controlsPreferredPackages,
|
||||
arrayOf(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)
|
||||
|
||||
createStartable(enabled = true).start()
|
||||
|
||||
verify(controlsController, never()).setPreferredSelection(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExistingSelection_noNewSelection() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.array.config_controlsPreferredPackages,
|
||||
arrayOf(TEST_PACKAGE_PANEL)
|
||||
)
|
||||
`when`(controlsController.getPreferredSelection())
|
||||
.thenReturn(mock<SelectedItem.PanelItem>())
|
||||
val listings = listOf(ControlsServiceInfo(TEST_COMPONENT_PANEL, "panel", hasPanel = true))
|
||||
`when`(controlsListingController.getCurrentServices()).thenReturn(listings)
|
||||
|
||||
createStartable(enabled = true).start()
|
||||
|
||||
verify(controlsController, never()).setPreferredSelection(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPanelAdded() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.array.config_controlsPreferredPackages,
|
||||
arrayOf(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).setPreferredSelection(listings[0].toPanelItem())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMultiplePreferredOnlyOnePanel_panelAdded() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.array.config_controlsPreferredPackages,
|
||||
arrayOf("other_package", TEST_PACKAGE_PANEL)
|
||||
)
|
||||
`when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION)
|
||||
val listings =
|
||||
listOf(
|
||||
ControlsServiceInfo(TEST_COMPONENT_PANEL, "panel", hasPanel = true),
|
||||
ControlsServiceInfo(ComponentName("other_package", "cls"), "non panel", false)
|
||||
)
|
||||
`when`(controlsListingController.getCurrentServices()).thenReturn(listings)
|
||||
|
||||
createStartable(enabled = true).start()
|
||||
|
||||
verify(controlsController).setPreferredSelection(listings[0].toPanelItem())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMultiplePreferredMultiplePanels_firstPreferredAdded() {
|
||||
context.orCreateTestableResources.addOverride(
|
||||
R.array.config_controlsPreferredPackages,
|
||||
arrayOf(TEST_PACKAGE_PANEL, "other_package")
|
||||
)
|
||||
`when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION)
|
||||
val listings =
|
||||
listOf(
|
||||
ControlsServiceInfo(ComponentName("other_package", "cls"), "panel", true),
|
||||
ControlsServiceInfo(TEST_COMPONENT_PANEL, "panel", hasPanel = true)
|
||||
)
|
||||
`when`(controlsListingController.getCurrentServices()).thenReturn(listings)
|
||||
|
||||
createStartable(enabled = true).start()
|
||||
|
||||
verify(controlsController).setPreferredSelection(listings[1].toPanelItem())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPreferredSelectionIsPanel_bindOnStart() {
|
||||
val listings = listOf(ControlsServiceInfo(TEST_COMPONENT_PANEL, "panel", hasPanel = true))
|
||||
`when`(controlsListingController.getCurrentServices()).thenReturn(listings)
|
||||
`when`(controlsController.getPreferredSelection()).thenReturn(listings[0].toPanelItem())
|
||||
|
||||
createStartable(enabled = true).start()
|
||||
|
||||
verify(controlsController).bindComponentForPanel(TEST_COMPONENT_PANEL)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPreferredSelectionPanel_listingNoPanel_notBind() {
|
||||
val listings = listOf(ControlsServiceInfo(TEST_COMPONENT_PANEL, "panel", hasPanel = false))
|
||||
`when`(controlsListingController.getCurrentServices()).thenReturn(listings)
|
||||
`when`(controlsController.getPreferredSelection())
|
||||
.thenReturn(SelectedItem.PanelItem("panel", TEST_COMPONENT_PANEL))
|
||||
|
||||
createStartable(enabled = true).start()
|
||||
|
||||
verify(controlsController, never()).bindComponentForPanel(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNotPanelSelection_noBind() {
|
||||
val listings = listOf(ControlsServiceInfo(TEST_COMPONENT_PANEL, "panel", hasPanel = false))
|
||||
`when`(controlsListingController.getCurrentServices()).thenReturn(listings)
|
||||
`when`(controlsController.getPreferredSelection()).thenReturn(SelectedItem.EMPTY_SELECTION)
|
||||
|
||||
createStartable(enabled = true).start()
|
||||
|
||||
verify(controlsController, never()).bindComponentForPanel(any())
|
||||
}
|
||||
|
||||
private fun createStartable(enabled: Boolean): ControlsStartable {
|
||||
val component: ControlsComponent =
|
||||
mock() {
|
||||
`when`(isEnabled()).thenReturn(enabled)
|
||||
if (enabled) {
|
||||
`when`(getControlsController()).thenReturn(Optional.of(controlsController))
|
||||
`when`(getControlsListingController())
|
||||
.thenReturn(Optional.of(controlsListingController))
|
||||
} else {
|
||||
`when`(getControlsController()).thenReturn(Optional.empty())
|
||||
`when`(getControlsListingController()).thenReturn(Optional.empty())
|
||||
}
|
||||
}
|
||||
return ControlsStartable(context.resources, fakeExecutor, component, userTracker)
|
||||
}
|
||||
|
||||
private fun ControlsServiceInfo(
|
||||
componentName: ComponentName,
|
||||
label: CharSequence,
|
||||
hasPanel: Boolean
|
||||
): ControlsServiceInfo {
|
||||
val serviceInfo =
|
||||
ServiceInfo().apply {
|
||||
applicationInfo = ApplicationInfo()
|
||||
packageName = componentName.packageName
|
||||
name = componentName.className
|
||||
}
|
||||
return FakeControlsServiceInfo(context, serviceInfo, label, hasPanel)
|
||||
}
|
||||
|
||||
private class FakeControlsServiceInfo(
|
||||
context: Context,
|
||||
serviceInfo: ServiceInfo,
|
||||
private val label: CharSequence,
|
||||
hasPanel: Boolean
|
||||
) : ControlsServiceInfo(context, serviceInfo) {
|
||||
|
||||
init {
|
||||
if (hasPanel) {
|
||||
panelActivity = serviceInfo.componentName
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadLabel(): CharSequence {
|
||||
return label
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun ControlsServiceInfo.toPanelItem(): SelectedItem.PanelItem {
|
||||
if (panelActivity == null) {
|
||||
throw IllegalArgumentException("$this is not a panel")
|
||||
}
|
||||
return SelectedItem.PanelItem(loadLabel(), componentName)
|
||||
}
|
||||
|
||||
private const val TEST_PACKAGE = "pkg"
|
||||
private val TEST_COMPONENT = ComponentName(TEST_PACKAGE, "service")
|
||||
private const val TEST_PACKAGE_PANEL = "pkg.panel"
|
||||
private val TEST_COMPONENT_PANEL = ComponentName(TEST_PACKAGE_PANEL, "service")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user