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:
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user