1 /* 2 * Copyright (C) 2025 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 package com.android.wm.shell.common.pip 17 18 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM 19 import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED 20 import android.window.DesktopExperienceFlags 21 import android.window.DesktopModeFlags 22 import com.android.wm.shell.Flags 23 import com.android.wm.shell.RootTaskDisplayAreaOrganizer 24 import com.android.wm.shell.desktopmode.DesktopUserRepositories 25 import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler 26 import java.util.Optional 27 28 /** Helper class for PiP on Desktop Mode. */ 29 class PipDesktopState( 30 private val pipDisplayLayoutState: PipDisplayLayoutState, 31 private val desktopUserRepositoriesOptional: Optional<DesktopUserRepositories>, 32 private val dragToDesktopTransitionHandlerOptional: Optional<DragToDesktopTransitionHandler>, 33 private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer 34 ) { 35 /** 36 * Returns whether PiP in Desktop Windowing is enabled by checking the following: 37 * - PiP in Desktop Windowing flag is enabled 38 * - DesktopUserRepositories is present 39 * - DragToDesktopTransitionHandler is present 40 */ isDesktopWindowingPipEnablednull41 fun isDesktopWindowingPipEnabled(): Boolean = 42 DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue && 43 desktopUserRepositoriesOptional.isPresent && 44 dragToDesktopTransitionHandlerOptional.isPresent 45 46 /** 47 * Returns whether PiP in Connected Displays is enabled by checking the following: 48 * - PiP in Connected Displays flag is enabled 49 * - PiP2 flag is enabled 50 */ 51 fun isConnectedDisplaysPipEnabled(): Boolean = 52 DesktopExperienceFlags.ENABLE_CONNECTED_DISPLAYS_PIP.isTrue && Flags.enablePip2() 53 54 /** Returns whether the display with the PiP task is in freeform windowing mode. */ 55 private fun isDisplayInFreeform(): Boolean { 56 val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo( 57 pipDisplayLayoutState.displayId 58 ) 59 60 return tdaInfo?.configuration?.windowConfiguration?.windowingMode == WINDOWING_MODE_FREEFORM 61 } 62 63 /** Returns whether PiP is active in a display that is in active Desktop Mode session. */ isPipInDesktopModenull64 fun isPipInDesktopMode(): Boolean { 65 if (!isDesktopWindowingPipEnabled()) { 66 return false 67 } 68 69 val displayId = pipDisplayLayoutState.displayId 70 return desktopUserRepositoriesOptional.get().current.isAnyDeskActive(displayId) 71 } 72 73 /** Returns the windowing mode to restore to when resizing out of PIP direction. */ 74 // TODO(b/403345629): Update this for Multi-Desktop. getOutPipWindowingModenull75 fun getOutPipWindowingMode(): Int { 76 // If we are exiting PiP while the device is in Desktop mode, the task should expand to 77 // freeform windowing mode. 78 // 1) If the display windowing mode is freeform, set windowing mode to UNDEFINED so it will 79 // resolve the windowing mode to the display's windowing mode. 80 // 2) If the display windowing mode is not FREEFORM, set windowing mode to FREEFORM. 81 if (isPipInDesktopMode()) { 82 return if (isDisplayInFreeform()) { 83 WINDOWING_MODE_UNDEFINED 84 } else { 85 WINDOWING_MODE_FREEFORM 86 } 87 } 88 89 // By default, or if the task is going to fullscreen, reset the windowing mode to undefined. 90 return WINDOWING_MODE_UNDEFINED 91 } 92 93 /** Returns whether there is a drag-to-desktop transition in progress. */ isDragToDesktopInProgressnull94 fun isDragToDesktopInProgress(): Boolean = 95 isDesktopWindowingPipEnabled() && dragToDesktopTransitionHandlerOptional.get().inProgress 96 } 97