Merge "Bind panels with lower priority flags" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
91536b0198
@@ -51,12 +51,21 @@ interface ControlsBindingController : UserAwareController {
|
|||||||
fun bindAndLoadSuggested(component: ComponentName, callback: LoadCallback)
|
fun bindAndLoadSuggested(component: ComponentName, callback: LoadCallback)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to bind to the given service.
|
* Request to bind to the given service. This should only be used for services using the full
|
||||||
|
* [ControlsProviderService] API, where SystemUI renders the devices' UI.
|
||||||
*
|
*
|
||||||
* @param component The [ComponentName] of the service to bind
|
* @param component The [ComponentName] of the service to bind
|
||||||
*/
|
*/
|
||||||
fun bindService(component: ComponentName)
|
fun bindService(component: ComponentName)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind to a service that provides a Device Controls panel (embedded activity). This will allow
|
||||||
|
* the app to remain "warm", and reduce latency.
|
||||||
|
*
|
||||||
|
* @param component The [ComponentName] of the [ControlsProviderService] to bind.
|
||||||
|
*/
|
||||||
|
fun bindServiceForPanel(component: ComponentName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a subscribe message to retrieve status of a set of controls.
|
* Send a subscribe message to retrieve status of a set of controls.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -170,6 +170,10 @@ open class ControlsBindingControllerImpl @Inject constructor(
|
|||||||
retrieveLifecycleManager(component).bindService()
|
retrieveLifecycleManager(component).bindService()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun bindServiceForPanel(component: ComponentName) {
|
||||||
|
retrieveLifecycleManager(component).bindServiceForPanel()
|
||||||
|
}
|
||||||
|
|
||||||
override fun changeUser(newUser: UserHandle) {
|
override fun changeUser(newUser: UserHandle) {
|
||||||
if (newUser == currentUser) return
|
if (newUser == currentUser) return
|
||||||
|
|
||||||
|
|||||||
@@ -188,6 +188,14 @@ interface ControlsController : UserAwareController {
|
|||||||
/** See [ControlsUiController.getPreferredSelectedItem]. */
|
/** See [ControlsUiController.getPreferredSelectedItem]. */
|
||||||
fun getPreferredSelection(): SelectedItem
|
fun getPreferredSelection(): SelectedItem
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind to a service that provides a Device Controls panel (embedded activity). This will allow
|
||||||
|
* the app to remain "warm", and reduce latency.
|
||||||
|
*
|
||||||
|
* @param component The [ComponentName] of the [ControlsProviderService] to bind.
|
||||||
|
*/
|
||||||
|
fun bindComponentForPanel(componentName: ComponentName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for structure to pass data to [ControlsFavoritingActivity].
|
* Interface for structure to pass data to [ControlsFavoritingActivity].
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -477,6 +477,10 @@ class ControlsControllerImpl @Inject constructor (
|
|||||||
bindingController.unsubscribe()
|
bindingController.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun bindComponentForPanel(componentName: ComponentName) {
|
||||||
|
bindingController.bindServiceForPanel(componentName)
|
||||||
|
}
|
||||||
|
|
||||||
override fun addFavorite(
|
override fun addFavorite(
|
||||||
componentName: ComponentName,
|
componentName: ComponentName,
|
||||||
structureName: CharSequence,
|
structureName: CharSequence,
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ class ControlsProviderLifecycleManager(
|
|||||||
private const val DEBUG = true
|
private const val DEBUG = true
|
||||||
private val BIND_FLAGS = Context.BIND_AUTO_CREATE or Context.BIND_FOREGROUND_SERVICE or
|
private val BIND_FLAGS = Context.BIND_AUTO_CREATE or Context.BIND_FOREGROUND_SERVICE or
|
||||||
Context.BIND_NOT_PERCEPTIBLE
|
Context.BIND_NOT_PERCEPTIBLE
|
||||||
|
// Use BIND_NOT_PERCEPTIBLE so it will be at lower priority from SystemUI.
|
||||||
|
// However, don't use WAIVE_PRIORITY, as by itself, it will kill the app
|
||||||
|
// once the Task is finished in the device controls panel.
|
||||||
|
private val BIND_FLAGS_PANEL = Context.BIND_AUTO_CREATE or Context.BIND_NOT_PERCEPTIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
private val intent = Intent().apply {
|
private val intent = Intent().apply {
|
||||||
@@ -87,18 +91,19 @@ class ControlsProviderLifecycleManager(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindService(bind: Boolean) {
|
private fun bindService(bind: Boolean, forPanel: Boolean = false) {
|
||||||
executor.execute {
|
executor.execute {
|
||||||
requiresBound = bind
|
requiresBound = bind
|
||||||
if (bind) {
|
if (bind) {
|
||||||
if (bindTryCount != MAX_BIND_RETRIES) {
|
if (bindTryCount != MAX_BIND_RETRIES && wrapper == null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Binding service $intent")
|
Log.d(TAG, "Binding service $intent")
|
||||||
}
|
}
|
||||||
bindTryCount++
|
bindTryCount++
|
||||||
try {
|
try {
|
||||||
|
val flags = if (forPanel) BIND_FLAGS_PANEL else BIND_FLAGS
|
||||||
val bound = context
|
val bound = context
|
||||||
.bindServiceAsUser(intent, serviceConnection, BIND_FLAGS, user)
|
.bindServiceAsUser(intent, serviceConnection, flags, user)
|
||||||
if (!bound) {
|
if (!bound) {
|
||||||
context.unbindService(serviceConnection)
|
context.unbindService(serviceConnection)
|
||||||
}
|
}
|
||||||
@@ -279,6 +284,10 @@ class ControlsProviderLifecycleManager(
|
|||||||
bindService(true)
|
bindService(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun bindServiceForPanel() {
|
||||||
|
bindService(bind = true, forPanel = true)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request unbind from the service.
|
* Request unbind from the service.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -232,6 +232,8 @@ class ControlsUiControllerImpl @Inject constructor (
|
|||||||
ControlKey(selected.structure.componentName, it.ci.controlId)
|
ControlKey(selected.structure.componentName, it.ci.controlId)
|
||||||
}
|
}
|
||||||
controlsController.get().subscribeToFavorites(selected.structure)
|
controlsController.get().subscribeToFavorites(selected.structure)
|
||||||
|
} else {
|
||||||
|
controlsController.get().bindComponentForPanel(selected.componentName)
|
||||||
}
|
}
|
||||||
listingCallback = createCallback(::showControlsView)
|
listingCallback = createCallback(::showControlsView)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,6 +268,14 @@ class ControlsBindingControllerImplTest : SysuiTestCase() {
|
|||||||
verify(providers[0]).bindService()
|
verify(providers[0]).bindService()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testBindServiceForPanel() {
|
||||||
|
controller.bindServiceForPanel(TEST_COMPONENT_NAME_1)
|
||||||
|
executor.runAllReady()
|
||||||
|
|
||||||
|
verify(providers[0]).bindServiceForPanel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSubscribe() {
|
fun testSubscribe() {
|
||||||
val controlInfo1 = ControlInfo("id_1", "", "", DeviceTypes.TYPE_UNKNOWN)
|
val controlInfo1 = ControlInfo("id_1", "", "", DeviceTypes.TYPE_UNKNOWN)
|
||||||
|
|||||||
@@ -919,6 +919,12 @@ class ControlsControllerImplTest : SysuiTestCase() {
|
|||||||
.getFile(ControlsFavoritePersistenceWrapper.FILE_NAME, context.user.identifier)
|
.getFile(ControlsFavoritePersistenceWrapper.FILE_NAME, context.user.identifier)
|
||||||
assertThat(userStructure.file).isNotNull()
|
assertThat(userStructure.file).isNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testBindForPanel() {
|
||||||
|
controller.bindComponentForPanel(TEST_COMPONENT)
|
||||||
|
verify(bindingController).bindServiceForPanel(TEST_COMPONENT)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DidRunRunnable() : Runnable {
|
private class DidRunRunnable() : Runnable {
|
||||||
|
|||||||
@@ -104,6 +104,22 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
|
|||||||
assertTrue(context.isBound(componentName))
|
assertTrue(context.isBound(componentName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testBindForPanel() {
|
||||||
|
manager.bindServiceForPanel()
|
||||||
|
executor.runAllReady()
|
||||||
|
assertTrue(context.isBound(componentName))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUnbindPanelIsUnbound() {
|
||||||
|
manager.bindServiceForPanel()
|
||||||
|
executor.runAllReady()
|
||||||
|
manager.unbindService()
|
||||||
|
executor.runAllReady()
|
||||||
|
assertFalse(context.isBound(componentName))
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testNullBinding() {
|
fun testNullBinding() {
|
||||||
val mockContext = mock(Context::class.java)
|
val mockContext = mock(Context::class.java)
|
||||||
|
|||||||
@@ -228,6 +228,15 @@ class ControlsUiControllerImplTest : SysuiTestCase() {
|
|||||||
verify(controlsController, never()).refreshStatus(any(), any())
|
verify(controlsController, never()).refreshStatus(any(), any())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testPanelBindsForPanel() {
|
||||||
|
val panel = SelectedItem.PanelItem("App name", ComponentName("pkg", "cls"))
|
||||||
|
setUpPanel(panel)
|
||||||
|
|
||||||
|
underTest.show(parent, {}, context)
|
||||||
|
verify(controlsController).bindComponentForPanel(panel.componentName)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPanelCallsTaskViewFactoryCreate() {
|
fun testPanelCallsTaskViewFactoryCreate() {
|
||||||
mockLayoutInflater()
|
mockLayoutInflater()
|
||||||
|
|||||||
Reference in New Issue
Block a user