Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72c330e5 authored by Chris Göllner's avatar Chris Göllner Committed by Android (Google) Code Review
Browse files

Merge "PSS: Make sure recent task thumbnails are up to date" into main

parents 0a050b7d 4370a27d
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -155,6 +155,26 @@ public class ActivityManagerWrapper {
        }
    }


    /**
     * Requests for a new snapshot to be taken for the given task, stores it in the cache, and
     * returns a {@link ThumbnailData} with the result.
     */
    @NonNull
    public ThumbnailData takeTaskThumbnail(int taskId) {
        TaskSnapshot snapshot = null;
        try {
            snapshot = getService().takeTaskSnapshot(taskId, /* updateCache= */ true);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to take task snapshot", e);
        }
        if (snapshot != null) {
            return new ThumbnailData(snapshot);
        } else {
            return new ThumbnailData();
        }
    }

    /**
     * Removes the outdated snapshot of home task.
     *
+22 −1
Original line number Diff line number Diff line
@@ -20,10 +20,15 @@ import android.content.ComponentName
import android.os.UserHandle
import com.android.systemui.mediaprojection.appselector.data.RecentTask
import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
import com.android.systemui.mediaprojection.appselector.data.RecentTaskThumbnailLoader
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
import com.android.systemui.shared.recents.model.ThumbnailData
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.cancel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch

@MediaProjectionAppSelectorScope
@@ -36,7 +41,8 @@ constructor(
    @HostUserHandle private val hostUserHandle: UserHandle,
    @MediaProjectionAppSelector private val scope: CoroutineScope,
    @MediaProjectionAppSelector private val appSelectorComponentName: ComponentName,
    @MediaProjectionAppSelector private val callerPackageName: String?
    @MediaProjectionAppSelector private val callerPackageName: String?,
    private val thumbnailLoader: RecentTaskThumbnailLoader,
) {

    fun init() {
@@ -46,6 +52,11 @@ constructor(
            val tasks =
                recentTasks.filterDevicePolicyRestrictedTasks().filterAppSelector().sortedTasks()

            // Thumbnails are not fresh for the foreground task(s). They are only refreshed at
            // launch, going to home, or going to overview.
            // For this reason, we need to refresh them here.
            refreshForegroundTaskThumbnails(tasks)

            view.bind(tasks)
        }
    }
@@ -54,6 +65,16 @@ constructor(
        scope.cancel()
    }

    private suspend fun refreshForegroundTaskThumbnails(tasks: List<RecentTask>) {
        coroutineScope {
            val thumbnails: List<Deferred<ThumbnailData?>> =
                tasks
                    .filter { it.isForegroundTask }
                    .map { async { thumbnailLoader.captureThumbnail(it.taskId) } }
            thumbnails.forEach { thumbnail -> thumbnail.await() }
        }
    }

    /** Removes all recent tasks that should be blocked according to the policy */
    private fun List<RecentTask>.filterDevicePolicyRestrictedTasks(): List<RecentTask> = filter {
        devicePolicyResolver.isScreenCaptureAllowed(
+2 −1
Original line number Diff line number Diff line
@@ -25,5 +25,6 @@ data class RecentTask(
    @UserIdInt val userId: Int,
    val topActivityComponent: ComponentName?,
    val baseIntentComponent: ComponentName?,
    @ColorInt val colorBackground: Int?
    @ColorInt val colorBackground: Int?,
    val isForegroundTask: Boolean,
)
+10 −4
Original line number Diff line number Diff line
@@ -48,9 +48,14 @@ constructor(

    override suspend fun loadRecentTasks(): List<RecentTask> =
        withContext(coroutineDispatcher) {
            val rawRecentTasks: List<GroupedRecentTaskInfo> = recents?.getTasks() ?: emptyList()

            rawRecentTasks
            val groupedTasks: List<GroupedRecentTaskInfo> = recents?.getTasks() ?: emptyList()
            // Note: the returned task list is from the most-recent to least-recent order.
            // The last foreground task is at index 1, because at index 0 will be our app selector.
            val foregroundGroup = groupedTasks.elementAtOrNull(1)
            val foregroundTaskId1 = foregroundGroup?.taskInfo1?.taskId
            val foregroundTaskId2 = foregroundGroup?.taskInfo2?.taskId
            val foregroundTaskIds = listOfNotNull(foregroundTaskId1, foregroundTaskId2)
            groupedTasks
                .flatMap { listOfNotNull(it.taskInfo1, it.taskInfo2) }
                .map {
                    RecentTask(
@@ -58,7 +63,8 @@ constructor(
                        it.userId,
                        it.topActivity,
                        it.baseIntent?.component,
                        it.taskDescription?.backgroundColor
                        it.taskDescription?.backgroundColor,
                        isForegroundTask = it.taskId in foregroundTaskIds
                    )
                }
        }
+10 −3
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import kotlinx.coroutines.withContext

interface RecentTaskThumbnailLoader {
    suspend fun loadThumbnail(taskId: Int): ThumbnailData?

    suspend fun captureThumbnail(taskId: Int): ThumbnailData?
}

class ActivityTaskManagerThumbnailLoader
@@ -36,8 +38,13 @@ constructor(

    override suspend fun loadThumbnail(taskId: Int): ThumbnailData? =
        withContext(coroutineDispatcher) {
            val thumbnailData =
                activityManager.getTaskThumbnail(taskId, /* isLowResolution= */ false)
            if (thumbnailData.thumbnail == null) null else thumbnailData
            activityManager.getTaskThumbnail(taskId, /* isLowResolution= */ false).takeIf {
                it.thumbnail != null
            }
        }

    override suspend fun captureThumbnail(taskId: Int): ThumbnailData? =
        withContext(coroutineDispatcher) {
            activityManager.takeTaskThumbnail(taskId).takeIf { it.thumbnail != null }
        }
}
Loading