Merge "Controls - Do not recreate intent" into sc-dev am: 060ab6630b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16148688

Change-Id: I61e2d7bf3daadb242e02e1dec689d7c720fa6bc3
This commit is contained in:
TreeHugger Robot
2021-12-09 13:44:46 +00:00
committed by Automerger Merge Worker
3 changed files with 93 additions and 17 deletions

View File

@@ -18,6 +18,7 @@ package com.android.systemui.controls.ui
import android.annotation.MainThread
import android.app.Dialog
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
@@ -88,7 +89,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
bouncerOrRun(createAction(cvh.cws.ci.controlId, {
cvh.layout.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)
if (cvh.usePanel()) {
showDetail(cvh, control.getAppIntent().getIntent())
showDetail(cvh, control.getAppIntent())
} else {
cvh.action(CommandAction(templateId))
}
@@ -116,7 +117,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
// Long press snould only be called when there is valid control state, otherwise ignore
cvh.cws.control?.let {
cvh.layout.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
showDetail(cvh, it.getAppIntent().getIntent())
showDetail(cvh, it.getAppIntent())
}
}, false /* blockable */))
}
@@ -167,10 +168,10 @@ class ControlActionCoordinatorImpl @Inject constructor(
bgExecutor.execute { vibrator.vibrate(effect) }
}
private fun showDetail(cvh: ControlViewHolder, intent: Intent) {
private fun showDetail(cvh: ControlViewHolder, pendingIntent: PendingIntent) {
bgExecutor.execute {
val activities: List<ResolveInfo> = context.packageManager.queryIntentActivities(
intent,
pendingIntent.getIntent(),
PackageManager.MATCH_DEFAULT_ONLY
)
@@ -178,7 +179,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
// make sure the intent is valid before attempting to open the dialog
if (activities.isNotEmpty() && taskViewFactory.isPresent) {
taskViewFactory.get().create(context, uiExecutor, {
dialog = DetailDialog(activityContext, it, intent, cvh).also {
dialog = DetailDialog(activityContext, it, pendingIntent, cvh).also {
it.setOnDismissListener { _ -> dialog = null }
it.show()
}

View File

@@ -43,7 +43,7 @@ import com.android.wm.shell.TaskView
class DetailDialog(
val activityContext: Context?,
val taskView: TaskView,
val intent: Intent,
val pendingIntent: PendingIntent,
val cvh: ControlViewHolder
) : Dialog(
activityContext ?: cvh.context,
@@ -59,6 +59,14 @@ class DetailDialog(
var detailTaskId = INVALID_TASK_ID
private val fillInIntent = Intent().apply {
putExtra(EXTRA_USE_PANEL, true)
// Apply flags to make behaviour match documentLaunchMode=always.
addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
}
fun removeDetailTask() {
if (detailTaskId == INVALID_TASK_ID) return
ActivityTaskManager.getInstance().removeTask(detailTaskId)
@@ -67,13 +75,6 @@ class DetailDialog(
val stateCallback = object : TaskView.Listener {
override fun onInitialized() {
val launchIntent = Intent(intent)
launchIntent.putExtra(EXTRA_USE_PANEL, true)
// Apply flags to make behaviour match documentLaunchMode=always.
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
launchIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
val options = activityContext?.let {
ActivityOptions.makeCustomAnimation(
it,
@@ -82,9 +83,8 @@ class DetailDialog(
)
} ?: ActivityOptions.makeBasic()
taskView.startActivity(
PendingIntent.getActivity(context, 0, launchIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE),
null /* fillInIntent */,
pendingIntent,
fillInIntent,
options,
getTaskViewBounds()
)
@@ -97,6 +97,9 @@ class DetailDialog(
override fun onTaskCreated(taskId: Int, name: ComponentName?) {
detailTaskId = taskId
requireViewById<ViewGroup>(R.id.controls_activity_view).apply {
setAlpha(1f)
}
}
override fun onReleased() {
@@ -121,6 +124,7 @@ class DetailDialog(
requireViewById<ViewGroup>(R.id.controls_activity_view).apply {
addView(taskView)
setAlpha(0f)
}
requireViewById<ImageView>(R.id.control_detail_close).apply {
@@ -134,7 +138,7 @@ class DetailDialog(
removeDetailTask()
dismiss()
context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
v.context.startActivity(intent)
pendingIntent.send()
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2021 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.ui
import android.app.PendingIntent
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.wm.shell.TaskView
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class DetailDialogTest : SysuiTestCase() {
@Mock
private lateinit var taskView: TaskView
@Mock
private lateinit var controlViewHolder: ControlViewHolder
@Mock
private lateinit var pendingIntent: PendingIntent
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun testPendingIntentIsUnModified() {
// GIVEN the dialog is created with a PendingIntent
val dialog = createDialog(pendingIntent)
// WHEN the TaskView is initialized
dialog.stateCallback.onInitialized()
// THEN the PendingIntent used to call startActivity is unmodified by systemui
verify(taskView).startActivity(eq(pendingIntent), any(), any(), any())
}
private fun createDialog(pendingIntent: PendingIntent): DetailDialog {
return DetailDialog(
mContext,
taskView,
pendingIntent,
controlViewHolder
)
}
}