1 /* <lambda>null2 * Copyright (C) 2024 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.screenshot.policy 18 19 import android.os.UserHandle 20 import com.android.systemui.screenshot.data.model.DisplayContentModel 21 import com.android.systemui.screenshot.data.model.ProfileType 22 import com.android.systemui.screenshot.data.repository.ProfileTypeRepository 23 import com.android.systemui.screenshot.policy.CapturePolicy.PolicyResult 24 import com.android.systemui.screenshot.policy.CapturePolicy.PolicyResult.Matched 25 import com.android.systemui.screenshot.policy.CapturePolicy.PolicyResult.NotMatched 26 import com.android.systemui.screenshot.policy.CaptureType.FullScreen 27 import javax.inject.Inject 28 29 /** 30 * Condition: When any visible task belongs to a private user. 31 * 32 * Parameters: Capture the whole screen, owned by the private user. 33 */ 34 class PrivateProfilePolicy 35 @Inject 36 constructor( 37 private val profileTypes: ProfileTypeRepository, 38 ) : CapturePolicy { 39 override suspend fun check(content: DisplayContentModel): PolicyResult { 40 // The systemUI notification shade isn't a private profile app, skip. 41 if (content.systemUiState.shadeExpanded) { 42 return NotMatched(policy = NAME, reason = SHADE_EXPANDED) 43 } 44 45 // Find the first visible rootTaskInfo with a child task owned by a private user 46 val childTask = 47 content.rootTasks 48 .filter { it.isVisible } 49 .firstNotNullOfOrNull { root -> 50 root 51 .childTasksTopDown() 52 .firstOrNull { 53 profileTypes.getProfileType(it.userId) == ProfileType.PRIVATE 54 } 55 } 56 ?: return NotMatched(policy = NAME, reason = NO_VISIBLE_TASKS) 57 58 // If matched, return parameters needed to modify the request. 59 return Matched( 60 policy = NAME, 61 reason = PRIVATE_TASK_VISIBLE, 62 CaptureParameters( 63 type = FullScreen(content.displayId), 64 component = content.rootTasks.first { it.isVisible }.topActivity, 65 owner = UserHandle.of(childTask.userId), 66 ) 67 ) 68 } 69 companion object { 70 const val NAME = "PrivateProfile" 71 const val SHADE_EXPANDED = "Notification shade is expanded" 72 const val NO_VISIBLE_TASKS = "No private profile tasks are visible" 73 const val PRIVATE_TASK_VISIBLE = "At least one private profile task is visible" 74 } 75 } 76