Fix component in ControlsRequestDialog
It was using the wrong component name (the one from the Activity)
instead of the service one.
Test: manual, with apk
Test: atest ControlsRequestDialogTest
Fixes: 159951190
Change-Id: I99b2cee91aed0079e86ab50e7c0153ebac86e05b
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
index 15d15e8..4ed6106 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
@@ -41,7 +41,7 @@
import com.android.systemui.util.LifecycleActivity
import javax.inject.Inject
-class ControlsRequestDialog @Inject constructor(
+open class ControlsRequestDialog @Inject constructor(
private val controller: ControlsController,
private val broadcastDispatcher: BroadcastDispatcher,
private val controlsListingController: ControlsListingController
@@ -51,7 +51,7 @@
private const val TAG = "ControlsRequestDialog"
}
- private lateinit var component: ComponentName
+ private lateinit var controlComponent: ComponentName
private lateinit var control: Control
private var dialog: Dialog? = null
private val callback = object : ControlsListingController.ControlsListingCallback {
@@ -86,7 +86,7 @@
finish()
}
- component = intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME) ?: run {
+ controlComponent = intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME) ?: run {
Log.e(TAG, "Request did not contain componentName")
finish()
return
@@ -103,7 +103,7 @@
super.onResume()
val label = verifyComponentAndGetLabel()
if (label == null) {
- Log.e(TAG, "The component specified (${component.flattenToString()} " +
+ Log.e(TAG, "The component specified (${controlComponent.flattenToString()} " +
"is not a valid ControlsProviderService")
finish()
return
@@ -127,16 +127,16 @@
}
private fun verifyComponentAndGetLabel(): CharSequence? {
- return controlsListingController.getAppLabel(component)
+ return controlsListingController.getAppLabel(controlComponent)
}
private fun isCurrentFavorite(): Boolean {
- val favorites = controller.getFavoritesForComponent(component)
+ val favorites = controller.getFavoritesForComponent(controlComponent)
return favorites.any { it.controls.any { it.controlId == control.controlId } }
}
fun createDialog(label: CharSequence): Dialog {
- val renderInfo = RenderInfo.lookup(this, component, control.deviceType)
+ val renderInfo = RenderInfo.lookup(this, controlComponent, control.deviceType)
val frame = LayoutInflater.from(this).inflate(R.layout.controls_dialog, null).apply {
requireViewById<ImageView>(R.id.icon).apply {
setImageDrawable(renderInfo.icon)
@@ -170,7 +170,7 @@
override fun onClick(dialog: DialogInterface?, which: Int) {
if (which == Dialog.BUTTON_POSITIVE) {
controller.addFavorite(
- componentName,
+ controlComponent,
control.structure ?: "",
ControlInfo(control.controlId, control.title, control.subtitle, control.deviceType)
)
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 9c94b86..65e5baa7 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -74,6 +74,11 @@
android:excludeFromRecents="true"
android:exported="false" />
+ <activity android:name="com.android.systemui.controls.management.TestControlsRequestDialog"
+ android:exported="false"
+ android:excludeFromRecents="true"
+ />
+
<provider
android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
tools:replace="android:authorities"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
new file mode 100644
index 0000000..0122db6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2020 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.management
+
+import android.app.Dialog
+import android.app.PendingIntent
+import android.content.ComponentName
+import android.content.IIntentSender
+import android.content.Intent
+import android.os.UserHandle
+import android.service.controls.Control
+import android.service.controls.ControlsProviderService
+import android.service.controls.DeviceTypes
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.lifecycle.Lifecycle
+import androidx.test.filters.MediumTest
+import androidx.test.rule.ActivityTestRule
+import androidx.test.runner.intercepting.SingleActivityFactory
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.controls.controller.ControlInfo
+import com.android.systemui.controls.controller.ControlsController
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@MediumTest
+@RunWith(AndroidTestingRunner::class)
[email protected]
+class ControlsRequestDialogTest : SysuiTestCase() {
+
+ companion object {
+ private val CONTROL_COMPONENT = ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS")!!
+ private const val LABEL = "TEST_LABEL"
+
+ private val USER_ID = UserHandle.USER_SYSTEM
+ private const val CONTROL_ID = "id"
+ }
+
+ @Mock
+ private lateinit var controller: ControlsController
+
+ @Mock
+ private lateinit var listingController: ControlsListingController
+ @Mock
+ private lateinit var broadcastDispatcher: BroadcastDispatcher
+ @Mock
+ private lateinit var iIntentSender: IIntentSender
+ @Captor
+ private lateinit var captor: ArgumentCaptor<ControlInfo>
+
+ @Rule
+ @JvmField
+ var activityRule = ActivityTestRule<TestControlsRequestDialog>(
+ object : SingleActivityFactory<TestControlsRequestDialog>(
+ TestControlsRequestDialog::class.java
+ ) {
+ override fun create(intent: Intent?): TestControlsRequestDialog {
+ return TestControlsRequestDialog(
+ controller,
+ broadcastDispatcher,
+ listingController
+ )
+ }
+ }, false, false)
+
+ private lateinit var control: Control
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ control = Control.StatelessBuilder(CONTROL_ID, PendingIntent(iIntentSender))
+ .setTitle("TITLE")
+ .setSubtitle("SUBTITLE")
+ .setDeviceType(DeviceTypes.TYPE_LIGHT)
+ .setStructure("STRUCTURE")
+ .build()
+
+ val intent = Intent(mContext, TestControlsRequestDialog::class.java)
+ intent.putExtra(Intent.EXTRA_USER_ID, USER_ID)
+ intent.putExtra(Intent.EXTRA_COMPONENT_NAME, CONTROL_COMPONENT)
+ intent.putExtra(ControlsProviderService.EXTRA_CONTROL, control)
+
+ `when`(controller.currentUserId).thenReturn(USER_ID)
+ `when`(controller.available).thenReturn(true)
+ `when`(listingController.getAppLabel(CONTROL_COMPONENT)).thenReturn(LABEL)
+ `when`(controller.getFavoritesForComponent(CONTROL_COMPONENT)).thenReturn(emptyList())
+
+ activityRule.launchActivity(intent)
+ }
+
+ @After
+ fun tearDown() {
+ activityRule.finishActivity()
+ }
+
+ @Test
+ fun testActivityNotFinished() {
+ assertNotEquals(Lifecycle.State.DESTROYED,
+ activityRule.getActivity().lifecycle.currentState)
+ }
+
+ @Test
+ fun testDialogAddsCorrectControl() {
+ activityRule.activity.onClick(null, Dialog.BUTTON_POSITIVE)
+
+ verify(controller)
+ .addFavorite(eq(CONTROL_COMPONENT), eq(control.structure!!), capture(captor))
+
+ captor.value.let {
+ assertEquals(control.controlId, it.controlId)
+ assertEquals(control.title, it.controlTitle)
+ assertEquals(control.subtitle, it.controlSubtitle)
+ assertEquals(control.deviceType, it.deviceType)
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt
new file mode 100644
index 0000000..3f6308b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2020 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.management
+
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.controls.controller.ControlsController
+
+class TestControlsRequestDialog(
+ controller: ControlsController,
+ dispatcher: BroadcastDispatcher,
+ listingController: ControlsListingController
+) : ControlsRequestDialog(controller, dispatcher, listingController)
\ No newline at end of file