• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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