• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 package com.android.systemui.controls.ui
19 
20 import android.app.ActivityOptions
21 import android.app.ActivityTaskManager
22 import android.app.ActivityTaskManager.INVALID_TASK_ID
23 import android.app.PendingIntent
24 import android.content.ComponentName
25 import android.content.Context
26 import android.content.Intent
27 import android.graphics.Color
28 import android.graphics.drawable.ShapeDrawable
29 import android.graphics.drawable.shapes.RoundRectShape
30 import android.os.Trace
31 import com.android.systemui.R
32 import com.android.systemui.util.boundsOnScreen
33 import com.android.wm.shell.TaskView
34 import java.util.concurrent.Executor
35 
36 class PanelTaskViewController(
37     private val activityContext: Context,
38     private val uiExecutor: Executor,
39     private val pendingIntent: PendingIntent,
40     val taskView: TaskView,
<lambda>null41     private val hide: () -> Unit = {}
42 ) {
43 
44     private var detailTaskId = INVALID_TASK_ID
45 
46     private val fillInIntent =
<lambda>null47         Intent().apply {
48             // Apply flags to make behaviour match documentLaunchMode=always.
49             addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
50             addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
51         }
52 
removeDetailTasknull53     private fun removeDetailTask() {
54         if (detailTaskId == INVALID_TASK_ID) return
55         ActivityTaskManager.getInstance().removeTask(detailTaskId)
56         detailTaskId = INVALID_TASK_ID
57     }
58 
59     private val stateCallback =
60         object : TaskView.Listener {
onInitializednull61             override fun onInitialized() {
62 
63                 val options =
64                     ActivityOptions.makeCustomAnimation(
65                         activityContext,
66                         0 /* enterResId */,
67                         0 /* exitResId */
68                     )
69                 options.taskAlwaysOnTop = true
70 
71                 taskView.post {
72                     val roundedCorner =
73                         activityContext.resources.getDimensionPixelSize(
74                             R.dimen.controls_panel_corner_radius
75                         )
76                     val radii = FloatArray(8) { roundedCorner.toFloat() }
77                     taskView.background =
78                         ShapeDrawable(RoundRectShape(radii, null, null)).apply {
79                             setTint(Color.TRANSPARENT)
80                         }
81                     taskView.clipToOutline = true
82                     taskView.startActivity(
83                         pendingIntent,
84                         fillInIntent,
85                         options,
86                         taskView.boundsOnScreen
87                     )
88                     Trace.instant(Trace.TRACE_TAG_APP, "PanelTaskViewController - startActivity")
89                 }
90             }
91 
onTaskRemovalStartednull92             override fun onTaskRemovalStarted(taskId: Int) {
93                 detailTaskId = INVALID_TASK_ID
94                 dismiss()
95             }
96 
onTaskCreatednull97             override fun onTaskCreated(taskId: Int, name: ComponentName?) {
98                 detailTaskId = taskId
99             }
100 
onReleasednull101             override fun onReleased() {
102                 removeDetailTask()
103             }
104 
onBackPressedOnTaskRootnull105             override fun onBackPressedOnTaskRoot(taskId: Int) {
106                 dismiss()
107                 hide()
108             }
109         }
110 
refreshBoundsnull111     fun refreshBounds() {
112         taskView.onLocationChanged()
113     }
114 
dismissnull115     fun dismiss() {
116         taskView.release()
117     }
118 
launchTaskViewnull119     fun launchTaskView() {
120         taskView.setListener(uiExecutor, stateCallback)
121     }
122 }
123