blob: 3f81b389b31c1dfbe9e6f3cceb429ba9112b4aea [file] [log] [blame]
Winson Chung55893332017-02-17 17:13:10 -08001/*
2 * Copyright (C) 2017 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
17package com.android.server.wm;
18
19import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
Winson Chung9c844412017-04-27 17:36:41 -070020
Winson Chung8bca9e42017-04-16 15:59:43 -070021import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
22import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
23import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
24import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
Winson Chung55893332017-02-17 17:13:10 -080025
26import android.app.RemoteAction;
Wale Ogunwale687b4272017-07-27 02:56:23 -070027import android.content.res.Configuration;
Winson Chung55893332017-02-17 17:13:10 -080028import android.graphics.Rect;
29
30import com.android.server.UiThread;
31
32import java.util.List;
33
34/**
35 * Controller for the pinned stack container. See {@link StackWindowController}.
36 */
37public class PinnedStackWindowController extends StackWindowController {
38
Winson Chunga71febe2017-05-22 11:14:22 -070039 private Rect mTmpFromBounds = new Rect();
40 private Rect mTmpToBounds = new Rect();
Winson Chung55893332017-02-17 17:13:10 -080041
Winson Chung3a682872017-04-10 14:38:05 -070042 public PinnedStackWindowController(int stackId, PinnedStackWindowListener listener,
Wale Ogunwale687b4272017-07-27 02:56:23 -070043 int displayId, boolean onTop, Rect outBounds, Configuration outOverrideConfig) {
44 super(stackId, listener, displayId, onTop, outBounds, outOverrideConfig,
45 WindowManagerService.getInstance());
Winson Chung55893332017-02-17 17:13:10 -080046 }
47
48 /**
Winson Chunga71febe2017-05-22 11:14:22 -070049 * @return the {@param currentStackBounds} transformed to the give {@param aspectRatio}. If
50 * {@param currentStackBounds} is null, then the {@param aspectRatio} is applied to the
51 * default bounds.
Winson Chung9c844412017-04-27 17:36:41 -070052 */
Winson Chunga71febe2017-05-22 11:14:22 -070053 public Rect getPictureInPictureBounds(float aspectRatio, Rect stackBounds) {
Winson Chung9c844412017-04-27 17:36:41 -070054 synchronized (mWindowMap) {
55 if (!mService.mSupportsPictureInPicture || mContainer == null) {
56 return null;
57 }
58
Winson Chung9c844412017-04-27 17:36:41 -070059 final DisplayContent displayContent = mContainer.getDisplayContent();
60 if (displayContent == null) {
61 return null;
62 }
63
64 final PinnedStackController pinnedStackController =
65 displayContent.getPinnedStackController();
Winson Chunga71febe2017-05-22 11:14:22 -070066 if (stackBounds == null) {
67 // Calculate the aspect ratio bounds from the default bounds
Winson Chung9c844412017-04-27 17:36:41 -070068 stackBounds = pinnedStackController.getDefaultBounds();
69 }
70
71 if (pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)) {
Winson Chunga71febe2017-05-22 11:14:22 -070072 return pinnedStackController.transformBoundsToAspectRatio(stackBounds, aspectRatio,
73 true /* useCurrentMinEdgeSize */);
Winson Chung9c844412017-04-27 17:36:41 -070074 } else {
75 return stackBounds;
76 }
77 }
78 }
79
80 /**
Winson Chung55893332017-02-17 17:13:10 -080081 * Animates the pinned stack.
82 */
Winson Chung8bca9e42017-04-16 15:59:43 -070083 public void animateResizePinnedStack(Rect toBounds, Rect sourceHintBounds,
Winson Chunge7ba6862017-05-24 12:13:33 -070084 int animationDuration, boolean fromFullscreen) {
Winson Chung55893332017-02-17 17:13:10 -080085 synchronized (mWindowMap) {
86 if (mContainer == null) {
87 throw new IllegalArgumentException("Pinned stack container not found :(");
88 }
89
Winson Chung8bca9e42017-04-16 15:59:43 -070090 // Get the from-bounds
91 final Rect fromBounds = new Rect();
92 mContainer.getBounds(fromBounds);
Winson Chung55893332017-02-17 17:13:10 -080093
Winson Chung8bca9e42017-04-16 15:59:43 -070094 // Get non-null fullscreen to-bounds for animating if the bounds are null
95 @SchedulePipModeChangedState int schedulePipModeChangedState =
96 NO_PIP_MODE_CHANGED_CALLBACKS;
97 final boolean toFullscreen = toBounds == null;
98 if (toFullscreen) {
Winson Chunge7ba6862017-05-24 12:13:33 -070099 if (fromFullscreen) {
Winson Chung8bca9e42017-04-16 15:59:43 -0700100 throw new IllegalArgumentException("Should not defer scheduling PiP mode"
101 + " change on animation to fullscreen.");
102 }
103 schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_START;
104
Winson Chunga71febe2017-05-22 11:14:22 -0700105 mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpToBounds);
106 if (!mTmpToBounds.isEmpty()) {
Winson Chung8bca9e42017-04-16 15:59:43 -0700107 // If there is a fullscreen bounds, use that
Winson Chunga71febe2017-05-22 11:14:22 -0700108 toBounds = new Rect(mTmpToBounds);
Winson Chung8bca9e42017-04-16 15:59:43 -0700109 } else {
110 // Otherwise, use the display bounds
111 toBounds = new Rect();
112 mContainer.getDisplayContent().getLogicalDisplayRect(toBounds);
113 }
Winson Chunge7ba6862017-05-24 12:13:33 -0700114 } else if (fromFullscreen) {
Winson Chung8bca9e42017-04-16 15:59:43 -0700115 schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
Winson Chung55893332017-02-17 17:13:10 -0800116 }
117
Winson Chung8bca9e42017-04-16 15:59:43 -0700118 mContainer.setAnimationFinalBounds(sourceHintBounds, toBounds, toFullscreen);
119
120 final Rect finalToBounds = toBounds;
121 final @SchedulePipModeChangedState int finalSchedulePipModeChangedState =
122 schedulePipModeChangedState;
Winson Chunge7ba6862017-05-24 12:13:33 -0700123 mService.mBoundsAnimationController.getHandler().post(() -> {
Winson Chungbb250542017-03-20 20:06:46 -0700124 if (mContainer == null) {
125 return;
126 }
Winson Chung8bca9e42017-04-16 15:59:43 -0700127 mService.mBoundsAnimationController.animateBounds(mContainer, fromBounds,
128 finalToBounds, animationDuration, finalSchedulePipModeChangedState,
Winson Chunge7ba6862017-05-24 12:13:33 -0700129 fromFullscreen, toFullscreen);
Winson Chung55893332017-02-17 17:13:10 -0800130 });
131 }
132 }
133
134 /**
135 * Sets the current picture-in-picture aspect ratio.
136 */
137 public void setPictureInPictureAspectRatio(float aspectRatio) {
138 synchronized (mWindowMap) {
139 if (!mService.mSupportsPictureInPicture || mContainer == null) {
140 return;
141 }
142
Winson Chung55893332017-02-17 17:13:10 -0800143 final PinnedStackController pinnedStackController =
144 mContainer.getDisplayContent().getPinnedStackController();
Winson Chungc95ff842017-03-21 10:20:20 -0700145
146 if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) != 0) {
Winson Chunga71febe2017-05-22 11:14:22 -0700147 mContainer.getAnimationOrCurrentBounds(mTmpFromBounds);
148 mTmpToBounds.set(mTmpFromBounds);
149 getPictureInPictureBounds(aspectRatio, mTmpToBounds);
150 if (!mTmpToBounds.equals(mTmpFromBounds)) {
151 animateResizePinnedStack(mTmpToBounds, null /* sourceHintBounds */,
Winson Chunge7ba6862017-05-24 12:13:33 -0700152 -1 /* duration */, false /* fromFullscreen */);
Winson Chung08f81892017-03-02 15:40:51 -0800153 }
Winson Chungc95ff842017-03-21 10:20:20 -0700154 pinnedStackController.setAspectRatio(
155 pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
156 ? aspectRatio : -1f);
157 }
Winson Chung55893332017-02-17 17:13:10 -0800158 }
159 }
160
161 /**
162 * Sets the current picture-in-picture actions.
163 */
164 public void setPictureInPictureActions(List<RemoteAction> actions) {
165 synchronized (mWindowMap) {
166 if (!mService.mSupportsPictureInPicture || mContainer == null) {
167 return;
168 }
169
170 mContainer.getDisplayContent().getPinnedStackController().setActions(actions);
171 }
172 }
173
174 /**
Winson Chung8bca9e42017-04-16 15:59:43 -0700175 * @return whether the multi-window mode change should be deferred as a part of a transition
176 * from fullscreen to non-fullscreen bounds.
Winson Chung02e71932017-03-10 10:08:17 -0800177 */
Winson Chung8bca9e42017-04-16 15:59:43 -0700178 public boolean deferScheduleMultiWindowModeChanged() {
179 synchronized(mWindowMap) {
180 return mContainer.deferScheduleMultiWindowModeChanged();
181 }
Winson Chung19953ca2017-04-11 11:19:23 -0700182 }
183
Winson Chung02e71932017-03-10 10:08:17 -0800184 /**
Winson Chung8bca9e42017-04-16 15:59:43 -0700185 * @return whether the bounds are currently animating to fullscreen.
Winson Chung55893332017-02-17 17:13:10 -0800186 */
Winson Chung8bca9e42017-04-16 15:59:43 -0700187 public boolean isAnimatingBoundsToFullscreen() {
188 synchronized (mWindowMap) {
189 return mContainer.isAnimatingBoundsToFullscreen();
Winson Chung55893332017-02-17 17:13:10 -0800190 }
Winson Chung8bca9e42017-04-16 15:59:43 -0700191 }
192
193 /**
194 * @return whether the stack can be resized from the bounds animation.
195 */
196 public boolean pinnedStackResizeDisallowed() {
197 synchronized (mWindowMap) {
198 return mContainer.pinnedStackResizeDisallowed();
199 }
Winson Chung55893332017-02-17 17:13:10 -0800200 }
Winson Chung3a682872017-04-10 14:38:05 -0700201
202 /**
203 * The following calls are made from WM to AM.
204 */
205
206 /** Calls directly into activity manager so window manager lock shouldn't held. */
207 public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
208 if (mListener != null) {
209 PinnedStackWindowListener listener = (PinnedStackWindowListener) mListener;
210 listener.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
211 }
212 }
Winson Chung55893332017-02-17 17:13:10 -0800213}