Keep ControlsActivity on orientation change
When the orientation changes, we need to do one of two things: * relayout the controls if showing SystemUI controls, or * tell the TaskView that its location has changed. We don't need to recreate the activity nor hide and reinflate everything. Test: manual with both panel and API apps Test: atest com.android.systemui.controls Fixes: 270583496 Change-Id: Ied2d96e237f96658d2274d2de869d3fb05049ebd
This commit is contained in:
@@ -878,7 +878,7 @@
|
||||
android:showForAllUsers="true"
|
||||
android:finishOnTaskLaunch="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:configChanges="screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden"
|
||||
android:configChanges="screenLayout|keyboard|keyboardHidden|orientation"
|
||||
android:visibleToInstantApps="true">
|
||||
</activity>
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.os.RemoteException
|
||||
import android.service.dreams.IDreamManager
|
||||
@@ -57,9 +59,11 @@ class ControlsActivity @Inject constructor(
|
||||
private lateinit var parent: ViewGroup
|
||||
private lateinit var broadcastReceiver: BroadcastReceiver
|
||||
private var mExitToDream: Boolean = false
|
||||
private lateinit var lastConfiguration: Configuration
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
lastConfiguration = resources.configuration
|
||||
if (featureFlags.isEnabled(Flags.USE_APP_PANELS)) {
|
||||
window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
|
||||
}
|
||||
@@ -92,6 +96,14 @@ class ControlsActivity @Inject constructor(
|
||||
initBroadcastReceiver()
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
if (lastConfiguration.diff(newConfig) and ActivityInfo.CONFIG_ORIENTATION != 0 ) {
|
||||
uiController.onOrientationChange()
|
||||
}
|
||||
lastConfiguration = newConfig
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@ 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 onOrientationChange()
|
||||
}
|
||||
|
||||
sealed class SelectedItem {
|
||||
|
||||
@@ -124,6 +124,7 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
}
|
||||
|
||||
private var selectedItem: SelectedItem = SelectedItem.EMPTY_SELECTION
|
||||
private var selectionItem: SelectionItem? = null
|
||||
private lateinit var allStructures: List<StructureInfo>
|
||||
private val controlsById = mutableMapOf<ControlKey, ControlWithState>()
|
||||
private val controlViewsById = mutableMapOf<ControlKey, ControlViewHolder>()
|
||||
@@ -230,6 +231,7 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
this.overflowMenuAdapter = null
|
||||
hidden = false
|
||||
retainCache = false
|
||||
selectionItem = null
|
||||
|
||||
controlActionCoordinator.activityContext = activityContext
|
||||
|
||||
@@ -272,7 +274,7 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
}
|
||||
}
|
||||
|
||||
private fun reload(parent: ViewGroup) {
|
||||
private fun reload(parent: ViewGroup, dismissTaskView: Boolean = true) {
|
||||
if (hidden) return
|
||||
|
||||
controlsListingController.get().removeCallback(listingCallback)
|
||||
@@ -425,6 +427,7 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
} else {
|
||||
Log.w(ControlsUiController.TAG, "Not TaskViewFactory to display panel $selectionItem")
|
||||
}
|
||||
this.selectionItem = selectionItem
|
||||
|
||||
bgExecutor.execute {
|
||||
val intent = Intent(Intent.ACTION_MAIN)
|
||||
@@ -657,6 +660,7 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
val maxColumns = ControlAdapter.findMaxColumns(activityContext.resources)
|
||||
|
||||
val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup
|
||||
listView.removeAllViews()
|
||||
var lastRow: ViewGroup = createRow(inflater, listView)
|
||||
selectedStructure.controls.forEach {
|
||||
val key = ControlKey(selectedStructure.componentName, it.controlId)
|
||||
@@ -804,6 +808,15 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOrientationChange() {
|
||||
selectionItem?.let {
|
||||
when (selectedItem) {
|
||||
is SelectedItem.StructureItem -> createListView(it)
|
||||
is SelectedItem.PanelItem -> taskViewController?.refreshBounds() ?: reload(parent)
|
||||
}
|
||||
} ?: reload(parent)
|
||||
}
|
||||
|
||||
private fun createRow(inflater: LayoutInflater, listView: ViewGroup): ViewGroup {
|
||||
val row = inflater.inflate(R.layout.controls_row, listView, false) as ViewGroup
|
||||
listView.addView(row)
|
||||
|
||||
@@ -37,7 +37,7 @@ class PanelTaskViewController(
|
||||
private val activityContext: Context,
|
||||
private val uiExecutor: Executor,
|
||||
private val pendingIntent: PendingIntent,
|
||||
private val taskView: TaskView,
|
||||
val taskView: TaskView,
|
||||
private val hide: () -> Unit = {}
|
||||
) {
|
||||
|
||||
@@ -108,6 +108,10 @@ class PanelTaskViewController(
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshBounds() {
|
||||
taskView.onLocationChanged()
|
||||
}
|
||||
|
||||
fun dismiss() {
|
||||
taskView.release()
|
||||
}
|
||||
|
||||
@@ -372,6 +372,38 @@ class ControlsUiControllerImplTest : SysuiTestCase() {
|
||||
verify(fakeDialogController.dialog).cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnRotationWithPanelUpdateBoundsCalled() {
|
||||
mockLayoutInflater()
|
||||
val packageName = "pkg"
|
||||
`when`(authorizedPanelsRepository.getAuthorizedPanels()).thenReturn(setOf(packageName))
|
||||
val panel = SelectedItem.PanelItem("App name", ComponentName(packageName, "cls"))
|
||||
val serviceInfo = setUpPanel(panel)
|
||||
|
||||
underTest.show(parent, {}, context)
|
||||
|
||||
val captor = argumentCaptor<ControlsListingController.ControlsListingCallback>()
|
||||
|
||||
verify(controlsListingController).addCallback(capture(captor))
|
||||
captor.value.onServicesUpdated(listOf(serviceInfo))
|
||||
FakeExecutor.exhaustExecutors(uiExecutor, bgExecutor)
|
||||
|
||||
val taskViewConsumerCaptor = argumentCaptor<Consumer<TaskView>>()
|
||||
verify(taskViewFactory).create(eq(context), eq(uiExecutor), capture(taskViewConsumerCaptor))
|
||||
|
||||
val taskView: TaskView = mock {
|
||||
`when`(this.post(any())).thenAnswer {
|
||||
uiExecutor.execute(it.arguments[0] as Runnable)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
taskViewConsumerCaptor.value.accept(taskView)
|
||||
|
||||
underTest.onOrientationChange()
|
||||
verify(taskView).onLocationChanged()
|
||||
}
|
||||
|
||||
private fun setUpPanel(panel: SelectedItem.PanelItem): ControlsServiceInfo {
|
||||
val activity = ComponentName(context, "activity")
|
||||
preferredPanelRepository.setSelectedComponent(
|
||||
|
||||
@@ -152,4 +152,12 @@ class PanelTaskViewControllerTest : SysuiTestCase() {
|
||||
listenerCaptor.value.onTaskRemovalStarted(0)
|
||||
verify(taskView).release()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnRefreshBounds() {
|
||||
underTest.launchTaskView()
|
||||
|
||||
underTest.refreshBounds()
|
||||
verify(taskView).onLocationChanged()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user