1 /*
<lambda>null2  * 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 package com.android.systemui.mediaprojection.appselector.view
18 
19 import android.graphics.Rect
20 import android.view.View
21 import android.view.ViewGroup
22 import android.widget.ImageView
23 import androidx.recyclerview.widget.RecyclerView.ViewHolder
24 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelector
25 import com.android.systemui.mediaprojection.appselector.data.BadgedAppIconLoader
26 import com.android.systemui.mediaprojection.appselector.data.RecentTask
27 import com.android.systemui.mediaprojection.appselector.data.RecentTaskLabelLoader
28 import com.android.systemui.mediaprojection.appselector.data.RecentTaskThumbnailLoader
29 import com.android.systemui.res.R
30 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
31 import dagger.assisted.Assisted
32 import dagger.assisted.AssistedFactory
33 import dagger.assisted.AssistedInject
34 import kotlinx.coroutines.CoroutineScope
35 import kotlinx.coroutines.Job
36 import kotlinx.coroutines.launch
37 
38 class RecentTaskViewHolder
39 @AssistedInject
40 constructor(
41     @Assisted private val root: ViewGroup,
42     private val iconLoader: BadgedAppIconLoader,
43     private val thumbnailLoader: RecentTaskThumbnailLoader,
44     private val labelLoader: RecentTaskLabelLoader,
45     private val taskViewSizeProvider: TaskPreviewSizeProvider,
46     @MediaProjectionAppSelector private val scope: CoroutineScope
47 ) : ViewHolder(root), ConfigurationListener, TaskPreviewSizeProvider.TaskPreviewSizeListener {
48 
49     val thumbnailView: MediaProjectionTaskView = root.requireViewById(R.id.task_thumbnail)
50     private val iconView: ImageView = root.requireViewById(R.id.task_icon)
51 
52     private var job: Job? = null
53 
54     init {
55         updateThumbnailSize()
56     }
57 
58     fun bind(task: RecentTask, onClick: (View) -> Unit) {
59         taskViewSizeProvider.addCallback(this)
60         job?.cancel()
61 
62         job =
63             scope.launch {
64                 task.baseIntentComponent?.let { component ->
65                     launch {
66                         val icon = iconLoader.loadIcon(task.userId, task.userType, component)
67                         iconView.setImageDrawable(icon)
68                     }
69                     launch {
70                         val label = labelLoader.loadLabel(task.userId, component)
71                         root.contentDescription =
72                             label
73                                 ?: root.context.getString(com.android.settingslib.R.string.unknown)
74                     }
75                 }
76                 launch {
77                     val thumbnail = thumbnailLoader.loadThumbnail(task.taskId)
78                     thumbnailView.bindTask(task, thumbnail)
79                 }
80             }
81 
82         root.setOnClickListener(onClick)
83     }
84 
85     fun onRecycled() {
86         taskViewSizeProvider.removeCallback(this)
87         iconView.setImageDrawable(null)
88         thumbnailView.bindTask(null, null)
89         job?.cancel()
90         job = null
91     }
92 
93     override fun onTaskSizeChanged(size: Rect) {
94         updateThumbnailSize()
95     }
96 
97     private fun updateThumbnailSize() {
98         thumbnailView.layoutParams =
99             thumbnailView.layoutParams.apply {
100                 width = taskViewSizeProvider.size.width()
101                 height = taskViewSizeProvider.size.height()
102             }
103     }
104 
105     @AssistedFactory
106     fun interface Factory {
107         fun create(root: ViewGroup): RecentTaskViewHolder
108     }
109 }
110