blob: d02be88ef0d4a57c3bd834cded6a66182590acd3 [file] [log] [blame]
Jorim Jaggi28620472019-01-02 23:21:49 +01001/*
2 * Copyright (C) 2019 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
Jorim Jaggi956ca412019-01-07 14:49:14 +010019import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
20import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
Jorim Jaggi28620472019-01-02 23:21:49 +010021import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
22import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Tarandeep Singhb9538cd2020-02-20 17:51:18 -080023import static android.view.InsetsController.ANIMATION_TYPE_HIDE;
24import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
Tiger Huang332793b2019-10-29 23:21:27 +080025import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
26import static android.view.InsetsState.ITYPE_STATUS_BAR;
Yunfan Chenb5d2db72019-12-06 15:43:43 +090027import static android.view.SyncRtSurfaceTransactionApplier.applyParams;
wilsonshihe8321942019-10-18 18:39:46 +080028import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
Jorim Jaggi28620472019-01-02 23:21:49 +010029import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
30
31import android.annotation.Nullable;
Jorim Jaggi956ca412019-01-07 14:49:14 +010032import android.app.StatusBarManager;
33import android.util.IntArray;
Yunfan Chenb5d2db72019-12-06 15:43:43 +090034import android.util.SparseArray;
35import android.view.InsetsAnimationControlCallbacks;
36import android.view.InsetsAnimationControlImpl;
Jorim Jaggi6d5c8012020-02-28 01:40:27 +010037import android.view.InsetsAnimationControlRunner;
Yunfan Chenb5d2db72019-12-06 15:43:43 +090038import android.view.InsetsController;
39import android.view.InsetsSourceControl;
Jorim Jaggi956ca412019-01-07 14:49:14 +010040import android.view.InsetsState;
Tiger Huang332793b2019-10-29 23:21:27 +080041import android.view.InsetsState.InternalInsetsType;
Yunfan Chenb5d2db72019-12-06 15:43:43 +090042import android.view.SurfaceControl;
43import android.view.SyncRtSurfaceTransactionApplier;
Jorim Jaggi956ca412019-01-07 14:49:14 +010044import android.view.ViewRootImpl;
Adrian Roosdb5b0c22020-02-12 15:05:27 -080045import android.view.WindowInsetsAnimation;
Jorim Jaggi6d5c8012020-02-28 01:40:27 +010046import android.view.WindowInsetsAnimation.Bounds;
Yunfan Chenb5d2db72019-12-06 15:43:43 +090047import android.view.WindowInsetsAnimationControlListener;
48
Tiger Huanga16634032020-02-05 17:10:03 +080049import com.android.internal.annotations.VisibleForTesting;
Yunfan Chenb5d2db72019-12-06 15:43:43 +090050import com.android.server.DisplayThread;
Jorim Jaggi28620472019-01-02 23:21:49 +010051
52/**
53 * Policy that implements who gets control over the windows generating insets.
54 */
55class InsetsPolicy {
56
57 private final InsetsStateController mStateController;
58 private final DisplayContent mDisplayContent;
59 private final DisplayPolicy mPolicy;
Jorim Jaggi956ca412019-01-07 14:49:14 +010060 private final IntArray mShowingTransientTypes = new IntArray();
61
Tiger Huangb9510ef2020-03-03 23:03:39 +080062 /** For resetting visibilities of insets sources. */
Tiger Huangaf2c7c42020-05-12 19:53:18 +080063 private final InsetsControlTarget mDummyControlTarget = new InsetsControlTarget() {
64
65 @Override
66 public void notifyInsetsControlChanged() {
67 boolean hasLeash = false;
68 final InsetsSourceControl[] controls =
69 mStateController.getControlsForDispatch(this);
70 if (controls == null) {
71 return;
72 }
73 for (InsetsSourceControl control : controls) {
74 final @InternalInsetsType int type = control.getType();
75 if (mShowingTransientTypes.indexOf(type) != -1) {
76 // The visibilities of transient bars will be handled with animations.
77 continue;
78 }
79 final SurfaceControl leash = control.getLeash();
80 if (leash != null) {
81 hasLeash = true;
82
83 // We use alpha to control the visibility here which aligns the logic at
84 // SurfaceAnimator.createAnimationLeash
85 mDisplayContent.getPendingTransaction().setAlpha(
86 leash, InsetsState.getDefaultVisibility(type) ? 1f : 0f);
87 }
88 }
89 if (hasLeash) {
90 mDisplayContent.scheduleAnimation();
91 }
92 }
93 };
Tiger Huangb9510ef2020-03-03 23:03:39 +080094
Jorim Jaggi956ca412019-01-07 14:49:14 +010095 private WindowState mFocusedWin;
Tiger Huang4a7835f2019-11-06 00:07:56 +080096 private BarWindow mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR);
Jorim Jaggi956ca412019-01-07 14:49:14 +010097 private BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR);
Yunfan Chenb5d2db72019-12-06 15:43:43 +090098 private boolean mAnimatingShown;
99 private final float[] mTmpFloat9 = new float[9];
Jorim Jaggi28620472019-01-02 23:21:49 +0100100
101 InsetsPolicy(InsetsStateController stateController, DisplayContent displayContent) {
102 mStateController = stateController;
103 mDisplayContent = displayContent;
104 mPolicy = displayContent.getDisplayPolicy();
105 }
106
107 /** Updates the target which can control system bars. */
108 void updateBarControlTarget(@Nullable WindowState focusedWin) {
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100109 if (mFocusedWin != focusedWin){
110 abortTransient();
111 }
Jorim Jaggi956ca412019-01-07 14:49:14 +0100112 mFocusedWin = focusedWin;
Tiger Huang4a7835f2019-11-06 00:07:56 +0800113 mStateController.onBarControlTargetChanged(getStatusControlTarget(focusedWin),
114 getFakeStatusControlTarget(focusedWin),
Jorim Jaggi956ca412019-01-07 14:49:14 +0100115 getNavControlTarget(focusedWin),
116 getFakeNavControlTarget(focusedWin));
117 if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
118 return;
119 }
Tiger Huang4a7835f2019-11-06 00:07:56 +0800120 mStatusBar.setVisible(focusedWin == null
121 || focusedWin != getStatusControlTarget(focusedWin)
Jorim Jaggi0dd0cf92019-12-27 15:17:44 +0100122 || focusedWin.getRequestedInsetsState().getSource(ITYPE_STATUS_BAR).isVisible());
Jorim Jaggi956ca412019-01-07 14:49:14 +0100123 mNavBar.setVisible(focusedWin == null
124 || focusedWin != getNavControlTarget(focusedWin)
Jorim Jaggi0dd0cf92019-12-27 15:17:44 +0100125 || focusedWin.getRequestedInsetsState().getSource(ITYPE_NAVIGATION_BAR)
126 .isVisible());
Tiger Huang9ff42bd2020-05-01 03:27:33 +0800127 mPolicy.updateHideNavInputEventReceiver();
Jorim Jaggi956ca412019-01-07 14:49:14 +0100128 }
129
Tiger Huang332793b2019-10-29 23:21:27 +0800130 boolean isHidden(@InternalInsetsType int type) {
Jorim Jaggi956ca412019-01-07 14:49:14 +0100131 final InsetsSourceProvider provider = mStateController.peekSourceProvider(type);
132 return provider != null && provider.hasWindow() && !provider.getSource().isVisible();
133 }
134
135 void showTransient(IntArray types) {
136 boolean changed = false;
137 for (int i = types.size() - 1; i >= 0; i--) {
138 final int type = types.get(i);
139 if (mShowingTransientTypes.indexOf(type) != -1) {
140 continue;
141 }
142 if (!isHidden(type)) {
143 continue;
144 }
145 mShowingTransientTypes.add(type);
146 changed = true;
147 }
148 if (changed) {
Tiger Huanga16634032020-02-05 17:10:03 +0800149 mPolicy.getStatusBarManagerInternal().showTransient(mDisplayContent.getDisplayId(),
150 mShowingTransientTypes.toArray());
151 updateBarControlTarget(mFocusedWin);
Tiger Huange480e5f2020-04-16 23:26:49 +0800152
153 // The leashes can be created while updating bar control target. The surface transaction
154 // of the new leashes might not be applied yet. The callback posted here ensures we can
155 // get the valid leashes because the surface transaction will be applied in the next
156 // animation frame which will be triggered if a new leash is created.
157 mDisplayContent.mWmService.mAnimator.getChoreographer().postFrameCallback(time -> {
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900158 synchronized (mDisplayContent.mWmService.mGlobalLock) {
Tiger Huange480e5f2020-04-16 23:26:49 +0800159 final InsetsState state = new InsetsState(mStateController.getRawInsetsState());
160 startAnimation(true /* show */, () -> {
161 synchronized (mDisplayContent.mWmService.mGlobalLock) {
162 mStateController.notifyInsetsChanged();
163 }
164 }, state);
165 mStateController.onInsetsModified(mDummyControlTarget, state);
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900166 }
Tiger Huange480e5f2020-04-16 23:26:49 +0800167 });
Jorim Jaggi956ca412019-01-07 14:49:14 +0100168 }
169 }
170
171 void hideTransient() {
172 if (mShowingTransientTypes.size() == 0) {
173 return;
174 }
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100175 InsetsState state = new InsetsState(mStateController.getRawInsetsState());
Tiger Huanga16634032020-02-05 17:10:03 +0800176 startAnimation(false /* show */, () -> {
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900177 synchronized (mDisplayContent.mWmService.mGlobalLock) {
178 mShowingTransientTypes.clear();
179 mStateController.notifyInsetsChanged();
180 updateBarControlTarget(mFocusedWin);
181 }
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100182 }, state);
183 mStateController.onInsetsModified(mDummyControlTarget, state);
Jorim Jaggi956ca412019-01-07 14:49:14 +0100184 }
185
Tiger Huang4a7835f2019-11-06 00:07:56 +0800186 boolean isTransient(@InternalInsetsType int type) {
187 return mShowingTransientTypes.indexOf(type) != -1;
188 }
189
Jorim Jaggi956ca412019-01-07 14:49:14 +0100190 /**
191 * @see InsetsStateController#getInsetsForDispatch
192 */
193 InsetsState getInsetsForDispatch(WindowState target) {
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100194 InsetsState originalState = mStateController.getInsetsForDispatch(target);
195 InsetsState state = originalState;
Jorim Jaggi956ca412019-01-07 14:49:14 +0100196 for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100197 state = new InsetsState(state);
Jorim Jaggi956ca412019-01-07 14:49:14 +0100198 state.setSourceVisible(mShowingTransientTypes.get(i), false);
199 }
Tiger Huangb9510ef2020-03-03 23:03:39 +0800200 if (mFocusedWin != null && getStatusControlTarget(mFocusedWin) == mDummyControlTarget) {
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100201 if (state == originalState) {
202 state = new InsetsState(state);
203 }
Tiger Huangb9510ef2020-03-03 23:03:39 +0800204 state.setSourceVisible(ITYPE_STATUS_BAR, mFocusedWin.getRequestedInsetsState());
205 }
206 if (mFocusedWin != null && getNavControlTarget(mFocusedWin) == mDummyControlTarget) {
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100207 if (state == originalState) {
208 state = new InsetsState(state);
209 }
Tiger Huangb9510ef2020-03-03 23:03:39 +0800210 state.setSourceVisible(ITYPE_NAVIGATION_BAR, mFocusedWin.getRequestedInsetsState());
211 }
Jorim Jaggi956ca412019-01-07 14:49:14 +0100212 return state;
213 }
214
215 void onInsetsModified(WindowState windowState, InsetsState state) {
216 mStateController.onInsetsModified(windowState, state);
217 checkAbortTransient(windowState, state);
218 if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
219 return;
220 }
Tiger Huang4a7835f2019-11-06 00:07:56 +0800221 if (windowState == getStatusControlTarget(mFocusedWin)) {
222 mStatusBar.setVisible(state.getSource(ITYPE_STATUS_BAR).isVisible());
Jorim Jaggi956ca412019-01-07 14:49:14 +0100223 }
224 if (windowState == getNavControlTarget(mFocusedWin)) {
Tiger Huang332793b2019-10-29 23:21:27 +0800225 mNavBar.setVisible(state.getSource(ITYPE_NAVIGATION_BAR).isVisible());
Jorim Jaggi956ca412019-01-07 14:49:14 +0100226 }
Tiger Huang9ff42bd2020-05-01 03:27:33 +0800227 mPolicy.updateHideNavInputEventReceiver();
Jorim Jaggi956ca412019-01-07 14:49:14 +0100228 }
229
230 /**
231 * Called when a window modified the insets state. If the window set a insets source to visible
232 * while it is shown transiently, we need to abort the transient state.
233 *
234 * @param windowState who changed the insets state.
235 * @param state the modified insets state.
236 */
237 private void checkAbortTransient(WindowState windowState, InsetsState state) {
238 if (mShowingTransientTypes.size() != 0) {
239 IntArray abortTypes = new IntArray();
240 for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
241 final int type = mShowingTransientTypes.get(i);
242 if (mStateController.isFakeTarget(type, windowState)
243 && state.getSource(type).isVisible()) {
244 mShowingTransientTypes.remove(i);
245 abortTypes.add(type);
246 }
247 }
248 if (abortTypes.size() > 0) {
249 mPolicy.getStatusBarManagerInternal().abortTransient(mDisplayContent.getDisplayId(),
250 abortTypes.toArray());
251 updateBarControlTarget(mFocusedWin);
252 }
253 }
254 }
255
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100256 private void abortTransient() {
257 mPolicy.getStatusBarManagerInternal().abortTransient(mDisplayContent.getDisplayId(),
258 mShowingTransientTypes.toArray());
259 mShowingTransientTypes.clear();
260 updateBarControlTarget(mFocusedWin);
261 }
262
Tiger Huang4a7835f2019-11-06 00:07:56 +0800263 private @Nullable InsetsControlTarget getFakeStatusControlTarget(
264 @Nullable WindowState focused) {
Tiger Huangb9510ef2020-03-03 23:03:39 +0800265 return getStatusControlTarget(focused) == mDummyControlTarget ? focused : null;
Jorim Jaggi956ca412019-01-07 14:49:14 +0100266 }
267
268 private @Nullable InsetsControlTarget getFakeNavControlTarget(@Nullable WindowState focused) {
Tiger Huangb9510ef2020-03-03 23:03:39 +0800269 return getNavControlTarget(focused) == mDummyControlTarget ? focused : null;
Jorim Jaggi28620472019-01-02 23:21:49 +0100270 }
271
Tiger Huang4a7835f2019-11-06 00:07:56 +0800272 private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin) {
Tiger Huang332793b2019-10-29 23:21:27 +0800273 if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
Tiger Huangb9510ef2020-03-03 23:03:39 +0800274 return mDummyControlTarget;
Jorim Jaggi956ca412019-01-07 14:49:14 +0100275 }
Jorim Jaggi026ed752020-01-29 00:30:24 +0100276 if (focusedWin == mPolicy.getNotificationShade()) {
277 // Notification shade has control anyways, no reason to force anything.
278 return focusedWin;
279 }
Tiger Huangb9510ef2020-03-03 23:03:39 +0800280 if (forceShowsSystemBarsForWindowingMode()) {
281 // Status bar is forcibly shown for the windowing mode which is a steady state.
282 // We don't want the client to control the status bar, and we will dispatch the real
283 // visibility of status bar to the client.
Jorim Jaggi28620472019-01-02 23:21:49 +0100284 return null;
285 }
Tiger Huangb9510ef2020-03-03 23:03:39 +0800286 if (forceShowsStatusBarTransiently()) {
287 // Status bar is forcibly shown transiently, and its new visibility won't be
288 // dispatched to the client so that we can keep the layout stable. We will dispatch the
289 // fake control to the client, so that it can re-show the bar during this scenario.
290 return mDummyControlTarget;
291 }
Jorim Jaggi28620472019-01-02 23:21:49 +0100292 return focusedWin;
293 }
294
295 private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin) {
Tiger Huang332793b2019-10-29 23:21:27 +0800296 if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) {
Tiger Huangb9510ef2020-03-03 23:03:39 +0800297 return mDummyControlTarget;
Jorim Jaggi956ca412019-01-07 14:49:14 +0100298 }
Jorim Jaggi026ed752020-01-29 00:30:24 +0100299 if (focusedWin == mPolicy.getNotificationShade()) {
300 // Notification shade has control anyways, no reason to force anything.
301 return focusedWin;
302 }
Tiger Huangb9510ef2020-03-03 23:03:39 +0800303 if (forceShowsSystemBarsForWindowingMode()) {
304 // Navigation bar is forcibly shown for the windowing mode which is a steady state.
305 // We don't want the client to control the navigation bar, and we will dispatch the real
306 // visibility of navigation bar to the client.
Jorim Jaggi28620472019-01-02 23:21:49 +0100307 return null;
308 }
Tiger Huangb9510ef2020-03-03 23:03:39 +0800309 if (forceShowsNavigationBarTransiently()) {
310 // Navigation bar is forcibly shown transiently, and its new visibility won't be
311 // dispatched to the client so that we can keep the layout stable. We will dispatch the
312 // fake control to the client, so that it can re-show the bar during this scenario.
313 return mDummyControlTarget;
314 }
Jorim Jaggi28620472019-01-02 23:21:49 +0100315 return focusedWin;
316 }
317
Tiger Huangb9510ef2020-03-03 23:03:39 +0800318 private boolean forceShowsStatusBarTransiently() {
319 final WindowState win = mPolicy.getStatusBar();
320 return win != null && (win.mAttrs.privateFlags & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0;
Jorim Jaggi28620472019-01-02 23:21:49 +0100321 }
322
Tiger Huangb9510ef2020-03-03 23:03:39 +0800323 private boolean forceShowsNavigationBarTransiently() {
324 final WindowState win = mPolicy.getNotificationShade();
325 return win != null
326 && (win.mAttrs.privateFlags & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0;
Jorim Jaggi28620472019-01-02 23:21:49 +0100327 }
328
Tiger Huangb9510ef2020-03-03 23:03:39 +0800329 private boolean forceShowsSystemBarsForWindowingMode() {
Andrii Kulian4c0fd0d2020-03-29 13:32:14 -0700330 final boolean isDockedStackVisible = mDisplayContent.getDefaultTaskDisplayArea()
331 .isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
332 final boolean isFreeformStackVisible = mDisplayContent.getDefaultTaskDisplayArea()
333 .isStackVisible(WINDOWING_MODE_FREEFORM);
Jorim Jaggi28620472019-01-02 23:21:49 +0100334 final boolean isResizing = mDisplayContent.getDockedDividerController().isResizing();
335
336 // We need to force system bars when the docked stack is visible, when the freeform stack
337 // is visible but also when we are resizing for the transitions when docked stack
338 // visibility changes.
JianYang Liuae86b3f2020-04-03 20:20:35 -0700339 return isDockedStackVisible
340 || isFreeformStackVisible
341 || isResizing
342 || mPolicy.getForceShowSystemBars();
Jorim Jaggi28620472019-01-02 23:21:49 +0100343 }
344
Tiger Huanga16634032020-02-05 17:10:03 +0800345 @VisibleForTesting
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100346 void startAnimation(boolean show, Runnable callback, InsetsState state) {
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900347 int typesReady = 0;
348 final SparseArray<InsetsSourceControl> controls = new SparseArray<>();
Tiger Huanga16634032020-02-05 17:10:03 +0800349 final IntArray showingTransientTypes = mShowingTransientTypes;
350 for (int i = showingTransientTypes.size() - 1; i >= 0; i--) {
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100351 int type = showingTransientTypes.get(i);
352 InsetsSourceProvider provider = mStateController.getSourceProvider(type);
Tiger Huangb9510ef2020-03-03 23:03:39 +0800353 InsetsSourceControl control = provider.getControl(mDummyControlTarget);
Tiger Huanga16634032020-02-05 17:10:03 +0800354 if (control == null || control.getLeash() == null) {
355 continue;
356 }
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100357 typesReady |= InsetsState.toPublicType(type);
Tiger Huanga16634032020-02-05 17:10:03 +0800358 controls.put(control.getType(), new InsetsSourceControl(control));
Jorim Jaggi49b9f6c2020-03-24 22:28:38 +0100359 state.setSourceVisible(type, show);
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900360 }
361 controlAnimationUnchecked(typesReady, controls, show, callback);
362 }
363
364 private void controlAnimationUnchecked(int typesReady,
365 SparseArray<InsetsSourceControl> controls, boolean show, Runnable callback) {
366 InsetsPolicyAnimationControlListener listener =
Jorim Jaggi5875cca2020-03-17 13:44:57 +0100367 new InsetsPolicyAnimationControlListener(show, callback, typesReady);
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900368 listener.mControlCallbacks.controlAnimationUnchecked(typesReady, controls, show);
369 }
370
Jorim Jaggi956ca412019-01-07 14:49:14 +0100371 private class BarWindow {
372
373 private final int mId;
374 private @StatusBarManager.WindowVisibleState int mState =
375 StatusBarManager.WINDOW_STATE_SHOWING;
376
377 BarWindow(int id) {
378 mId = id;
379 }
380
381 private void setVisible(boolean visible) {
382 final int state = visible ? WINDOW_STATE_SHOWING : WINDOW_STATE_HIDDEN;
383 if (mState != state) {
384 mState = state;
385 mPolicy.getStatusBarManagerInternal().setWindowState(
386 mDisplayContent.getDisplayId(), mId, state);
387 }
388 }
389 }
390
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900391 private class InsetsPolicyAnimationControlListener extends
392 InsetsController.InternalAnimationControlListener {
393 Runnable mFinishCallback;
394 InsetsPolicyAnimationControlCallbacks mControlCallbacks;
395
Jorim Jaggi5875cca2020-03-17 13:44:57 +0100396 InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback, int types) {
397 super(show, false /* hasCallbacks */, types);
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900398 mFinishCallback = finishCallback;
399 mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this);
400 }
401
402 @Override
403 protected void onAnimationFinish() {
404 super.onAnimationFinish();
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900405 DisplayThread.getHandler().post(mFinishCallback);
406 }
407
408 private class InsetsPolicyAnimationControlCallbacks implements
409 InsetsAnimationControlCallbacks {
410 private InsetsAnimationControlImpl mAnimationControl = null;
411 private InsetsPolicyAnimationControlListener mListener;
412
413 InsetsPolicyAnimationControlCallbacks(InsetsPolicyAnimationControlListener listener) {
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900414 mListener = listener;
415 }
416
417 private void controlAnimationUnchecked(int typesReady,
418 SparseArray<InsetsSourceControl> controls, boolean show) {
419 if (typesReady == 0) {
420 // nothing to animate.
421 return;
422 }
423 mAnimatingShown = show;
424
425 mAnimationControl = new InsetsAnimationControlImpl(controls,
426 mFocusedWin.getDisplayContent().getBounds(), getState(),
427 mListener, typesReady, this, mListener.getDurationMs(),
Jorim Jaggi5875cca2020-03-17 13:44:57 +0100428 InsetsController.SYSTEM_BARS_INTERPOLATOR,
Tarandeep Singhb9538cd2020-02-20 17:51:18 -0800429 show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE);
Tiger Huanga16634032020-02-05 17:10:03 +0800430 SurfaceAnimationThread.getHandler().post(
431 () -> mListener.onReady(mAnimationControl, typesReady));
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900432 }
433
Tiger Huanga16634032020-02-05 17:10:03 +0800434 /** Called on SurfaceAnimationThread without global WM lock held. */
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900435 @Override
Adrian Roos6a4448f2020-04-01 15:01:08 +0200436 public void scheduleApplyChangeInsets(InsetsAnimationControlRunner runner) {
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900437 InsetsState state = getState();
438 if (mAnimationControl.applyChangeInsets(state)) {
439 mAnimationControl.finish(mAnimatingShown);
440 }
441 }
442
443 @Override
Jorim Jaggi6d5c8012020-02-28 01:40:27 +0100444 public void notifyFinished(InsetsAnimationControlRunner runner, boolean shown) {
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900445 // Nothing's needed here. Finish steps is handled in the listener
446 // onAnimationFinished callback.
447 }
448
449 /**
450 * This method will return a state with fullscreen frame override. No need to make copy
451 * after getting state from this method.
452 * @return The client insets state with full display frame override.
453 */
454 private InsetsState getState() {
455 // To animate the transient animation correctly, we need to let the state hold
456 // the full display frame.
457 InsetsState overrideState = new InsetsState(mFocusedWin.getRequestedInsetsState(),
458 true);
459 overrideState.setDisplayFrame(mFocusedWin.getDisplayContent().getBounds());
460 return overrideState;
461 }
462
Tiger Huanga16634032020-02-05 17:10:03 +0800463 /** Called on SurfaceAnimationThread without global WM lock held. */
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900464 @Override
465 public void applySurfaceParams(
466 final SyncRtSurfaceTransactionApplier.SurfaceParams... params) {
467 SurfaceControl.Transaction t = new SurfaceControl.Transaction();
468 for (int i = params.length - 1; i >= 0; i--) {
469 SyncRtSurfaceTransactionApplier.SurfaceParams surfaceParams = params[i];
470 applyParams(t, surfaceParams, mTmpFloat9);
471 }
472 t.apply();
Jorim Jaggi6d5c8012020-02-28 01:40:27 +0100473 t.close();
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900474 }
475
Rob Carr3a367c42020-03-10 15:51:35 -0700476 // Since we don't push applySurfaceParams to a Handler-queue we don't need
477 // to push release in this case.
478 @Override
479 public void releaseSurfaceControlFromRt(SurfaceControl sc) {
480 sc.release();
481 }
482
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900483 @Override
484 public void startAnimation(InsetsAnimationControlImpl controller,
485 WindowInsetsAnimationControlListener listener, int types,
Adrian Roosdb5b0c22020-02-12 15:05:27 -0800486 WindowInsetsAnimation animation,
Jorim Jaggi6d5c8012020-02-28 01:40:27 +0100487 Bounds bounds) {
Yunfan Chenb5d2db72019-12-06 15:43:43 +0900488 }
489 }
490 }
Jorim Jaggi28620472019-01-02 23:21:49 +0100491}