blob: 63083faaddb146e930dc9f3f77be8a18a3eae8d4 [file] [log] [blame]
Jorim Jaggif96c90a2018-09-26 16:55:15 +02001/*
2 * Copyright (C) 2018 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
Winson Chung8a168902020-03-12 22:39:22 -070019import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
Tiger Huang0f5347e2020-03-06 17:09:41 +080020import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Tiger Huanga16634032020-02-05 17:10:03 +080021import static android.view.InsetsState.ITYPE_CAPTION_BAR;
Tiger Huang332793b2019-10-29 23:21:27 +080022import static android.view.InsetsState.ITYPE_IME;
Charles Chenb8070fb2020-02-24 15:42:59 +080023import static android.view.InsetsState.ITYPE_INVALID;
Tiger Huang332793b2019-10-29 23:21:27 +080024import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
25import static android.view.InsetsState.ITYPE_STATUS_BAR;
Jorim Jaggia12ea562019-01-07 17:47:47 +010026import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
27import static android.view.ViewRootImpl.sNewInsetsMode;
Charles Chenb8070fb2020-02-24 15:42:59 +080028import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
29import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
30import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020031
Taran Singh85661e32020-05-07 14:45:34 -070032import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_IME;
33
Jorim Jaggib6030952018-10-23 18:31:52 +020034import android.annotation.NonNull;
35import android.annotation.Nullable;
Tiger Huang0f5347e2020-03-06 17:09:41 +080036import android.app.WindowConfiguration;
37import android.app.WindowConfiguration.WindowingMode;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020038import android.util.ArrayMap;
Jorim Jaggib6030952018-10-23 18:31:52 +020039import android.util.ArraySet;
40import android.util.SparseArray;
Jorim Jaggie35c0592018-11-06 16:21:08 +010041import android.view.InsetsSource;
Jorim Jaggib6030952018-10-23 18:31:52 +020042import android.view.InsetsSourceControl;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020043import android.view.InsetsState;
Tiger Huang332793b2019-10-29 23:21:27 +080044import android.view.InsetsState.InternalInsetsType;
Charles Chenb8070fb2020-02-24 15:42:59 +080045import android.view.WindowManager;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020046
Taran Singh85661e32020-05-07 14:45:34 -070047import com.android.server.protolog.common.ProtoLog;
48
Jorim Jaggif96c90a2018-09-26 16:55:15 +020049import java.io.PrintWriter;
Jorim Jaggib6030952018-10-23 18:31:52 +020050import java.util.ArrayList;
Jorim Jaggif96c90a2018-09-26 16:55:15 +020051import java.util.function.Consumer;
52
53/**
54 * Manages global window inset state in the system represented by {@link InsetsState}.
55 */
56class InsetsStateController {
57
58 private final InsetsState mLastState = new InsetsState();
59 private final InsetsState mState = new InsetsState();
60 private final DisplayContent mDisplayContent;
Jorim Jaggib6030952018-10-23 18:31:52 +020061
Jorim Jaggi28620472019-01-02 23:21:49 +010062 private final ArrayMap<Integer, InsetsSourceProvider> mProviders = new ArrayMap<>();
63 private final ArrayMap<InsetsControlTarget, ArrayList<Integer>> mControlTargetTypeMap =
64 new ArrayMap<>();
65 private final SparseArray<InsetsControlTarget> mTypeControlTargetMap = new SparseArray<>();
Jorim Jaggia12ea562019-01-07 17:47:47 +010066
67 /** @see #onControlFakeTargetChanged */
68 private final SparseArray<InsetsControlTarget> mTypeFakeControlTargetMap = new SparseArray<>();
69
Jorim Jaggi28620472019-01-02 23:21:49 +010070 private final ArraySet<InsetsControlTarget> mPendingControlChanged = new ArraySet<>();
Jorim Jaggif96c90a2018-09-26 16:55:15 +020071
72 private final Consumer<WindowState> mDispatchInsetsChanged = w -> {
73 if (w.isVisible()) {
74 w.notifyInsetsChanged();
75 }
76 };
Tiger Huangb9510ef2020-03-03 23:03:39 +080077 private final InsetsControlTarget mEmptyImeControlTarget = new InsetsControlTarget() { };
Jorim Jaggif96c90a2018-09-26 16:55:15 +020078
79 InsetsStateController(DisplayContent displayContent) {
80 mDisplayContent = displayContent;
81 }
82
83 /**
84 * When dispatching window state to the client, we'll need to exclude the source that represents
Tiger Huang0f5347e2020-03-06 17:09:41 +080085 * the window that is being dispatched. We also need to exclude certain types of insets source
86 * for client within specific windowing modes.
Jorim Jaggif96c90a2018-09-26 16:55:15 +020087 *
88 * @param target The client we dispatch the state to.
89 * @return The state stripped of the necessary information.
90 */
Charles Chenb8070fb2020-02-24 15:42:59 +080091 InsetsState getInsetsForDispatch(@NonNull WindowState target) {
Jorim Jaggi956ca412019-01-07 14:49:14 +010092 final InsetsSourceProvider provider = target.getControllableInsetProvider();
Tiger Huang0f5347e2020-03-06 17:09:41 +080093 final @InternalInsetsType int type = provider != null
94 ? provider.getSource().getType() : ITYPE_INVALID;
Tiger Huang57e2e1c2020-03-13 22:54:36 +080095 return getInsetsForDispatchInner(type, target.getWindowingMode(), target.isAlwaysOnTop(),
96 isAboveIme(target));
Charles Chenb8070fb2020-02-24 15:42:59 +080097 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +020098
Charles Chenb8070fb2020-02-24 15:42:59 +080099 InsetsState getInsetsForWindowMetrics(@NonNull WindowManager.LayoutParams attrs) {
100 final @InternalInsetsType int type = getInsetsTypeForWindowType(attrs.type);
Tiger Huang0f5347e2020-03-06 17:09:41 +0800101 final WindowToken token = mDisplayContent.getWindowToken(attrs.token);
102 final @WindowingMode int windowingMode = token != null
103 ? token.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
Tiger Huang57e2e1c2020-03-13 22:54:36 +0800104 final boolean alwaysOnTop = token != null && token.isAlwaysOnTop();
105 return getInsetsForDispatchInner(type, windowingMode, alwaysOnTop, isAboveIme(token));
106 }
107
108 private boolean isAboveIme(WindowContainer target) {
109 final WindowState imeWindow = mDisplayContent.mInputMethodWindow;
110 if (target == null || imeWindow == null) {
111 return false;
112 }
113 if (target instanceof WindowState) {
114 final WindowState win = (WindowState) target;
115 return win.needsRelativeLayeringToIme() || !win.mBehindIme;
116 }
117 return false;
Charles Chenb8070fb2020-02-24 15:42:59 +0800118 }
119
Tiger Huang0f5347e2020-03-06 17:09:41 +0800120 private static @InternalInsetsType int getInsetsTypeForWindowType(int type) {
Tiger Huang57e2e1c2020-03-13 22:54:36 +0800121 switch (type) {
Charles Chenb8070fb2020-02-24 15:42:59 +0800122 case TYPE_STATUS_BAR:
123 return ITYPE_STATUS_BAR;
124 case TYPE_NAVIGATION_BAR:
125 return ITYPE_NAVIGATION_BAR;
126 case TYPE_INPUT_METHOD:
127 return ITYPE_IME;
128 default:
129 return ITYPE_INVALID;
130 }
131 }
132
Tiger Huang0f5347e2020-03-06 17:09:41 +0800133 /** @see #getInsetsForDispatch */
Tiger Huang57e2e1c2020-03-13 22:54:36 +0800134 private InsetsState getInsetsForDispatchInner(@InternalInsetsType int type,
135 @WindowingMode int windowingMode, boolean isAlwaysOnTop, boolean aboveIme) {
Tiger Huang0f5347e2020-03-06 17:09:41 +0800136 InsetsState state = mState;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200137
Tiger Huang0f5347e2020-03-06 17:09:41 +0800138 if (type != ITYPE_INVALID) {
139 state = new InsetsState(state);
140 state.removeSource(type);
Tiger Huanga16634032020-02-05 17:10:03 +0800141
Tiger Huang0f5347e2020-03-06 17:09:41 +0800142 // Navigation bar doesn't get influenced by anything else
143 if (type == ITYPE_NAVIGATION_BAR) {
144 state.removeSource(ITYPE_IME);
145 state.removeSource(ITYPE_STATUS_BAR);
146 state.removeSource(ITYPE_CAPTION_BAR);
147 }
Jorim Jaggi9b4f4202020-01-28 17:05:06 +0100148
Tiger Huang0f5347e2020-03-06 17:09:41 +0800149 // Status bar doesn't get influenced by caption bar
150 if (type == ITYPE_STATUS_BAR) {
151 state.removeSource(ITYPE_CAPTION_BAR);
152 }
153
154 // IME needs different frames for certain cases (e.g. navigation bar in gesture nav).
155 if (type == ITYPE_IME) {
156 for (int i = mProviders.size() - 1; i >= 0; i--) {
157 InsetsSourceProvider otherProvider = mProviders.valueAt(i);
158 if (otherProvider.overridesImeFrame()) {
159 InsetsSource override =
160 new InsetsSource(
161 state.getSource(otherProvider.getSource().getType()));
162 override.setFrame(otherProvider.getImeOverrideFrame());
163 state.addSource(override);
164 }
Jorim Jaggi9b4f4202020-01-28 17:05:06 +0100165 }
166 }
167 }
168
Winson Chung8a168902020-03-12 22:39:22 -0700169 if (WindowConfiguration.isFloating(windowingMode)
170 || (windowingMode == WINDOWING_MODE_MULTI_WINDOW && isAlwaysOnTop)) {
Tiger Huang0f5347e2020-03-06 17:09:41 +0800171 state = new InsetsState(state);
172 state.removeSource(ITYPE_STATUS_BAR);
173 state.removeSource(ITYPE_NAVIGATION_BAR);
174 }
175
Tiger Huang57e2e1c2020-03-13 22:54:36 +0800176 if (aboveIme) {
Tiger Huangc0d837a2020-04-24 00:49:27 +0800177 InsetsSource imeSource = state.peekSource(ITYPE_IME);
178 if (imeSource != null && imeSource.isVisible()) {
179 imeSource = new InsetsSource(imeSource);
180 imeSource.setVisible(false);
Jorim Jaggied312592020-05-25 16:46:56 +0200181 imeSource.setFrame(0, 0, 0, 0);
Tiger Huangc0d837a2020-04-24 00:49:27 +0800182 state = new InsetsState(state);
183 state.addSource(imeSource);
184 }
Tiger Huang57e2e1c2020-03-13 22:54:36 +0800185 }
186
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200187 return state;
188 }
189
Evan Rosky8d782e02019-10-14 15:43:53 -0700190 InsetsState getRawInsetsState() {
191 return mState;
192 }
193
Jorim Jaggi28620472019-01-02 23:21:49 +0100194 @Nullable InsetsSourceControl[] getControlsForDispatch(InsetsControlTarget target) {
195 ArrayList<Integer> controlled = mControlTargetTypeMap.get(target);
Jorim Jaggib6030952018-10-23 18:31:52 +0200196 if (controlled == null) {
197 return null;
198 }
199 final int size = controlled.size();
200 final InsetsSourceControl[] result = new InsetsSourceControl[size];
201 for (int i = 0; i < size; i++) {
Jorim Jaggia12ea562019-01-07 17:47:47 +0100202 result[i] = mProviders.get(controlled.get(i)).getControl(target);
Jorim Jaggib6030952018-10-23 18:31:52 +0200203 }
204 return result;
205 }
206
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200207 /**
208 * @return The provider of a specific type.
209 */
Tiger Huang332793b2019-10-29 23:21:27 +0800210 InsetsSourceProvider getSourceProvider(@InternalInsetsType int type) {
211 if (type == ITYPE_IME) {
Tarandeep Singh500a38f2019-09-26 13:36:40 -0700212 return mProviders.computeIfAbsent(type,
213 key -> new ImeInsetsSourceProvider(
214 mState.getSource(key), this, mDisplayContent));
215 } else {
216 return mProviders.computeIfAbsent(type,
217 key -> new InsetsSourceProvider(mState.getSource(key), this, mDisplayContent));
218 }
219 }
220
221 ImeInsetsSourceProvider getImeSourceProvider() {
Tiger Huang332793b2019-10-29 23:21:27 +0800222 return (ImeInsetsSourceProvider) getSourceProvider(ITYPE_IME);
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200223 }
224
225 /**
Jorim Jaggi956ca412019-01-07 14:49:14 +0100226 * @return The provider of a specific type or null if we don't have it.
227 */
Tiger Huang332793b2019-10-29 23:21:27 +0800228 @Nullable InsetsSourceProvider peekSourceProvider(@InternalInsetsType int type) {
Jorim Jaggi956ca412019-01-07 14:49:14 +0100229 return mProviders.get(type);
230 }
231
232 /**
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200233 * Called when a layout pass has occurred.
234 */
235 void onPostLayout() {
Tarandeep Singha6f35612019-01-11 19:50:46 -0800236 mState.setDisplayFrame(mDisplayContent.getBounds());
Jorim Jaggi28620472019-01-02 23:21:49 +0100237 for (int i = mProviders.size() - 1; i >= 0; i--) {
238 mProviders.valueAt(i).onPostLayout();
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200239 }
Tiger Huang53c8eb82020-03-31 18:22:05 +0800240 final ArrayList<WindowState> winInsetsChanged = mDisplayContent.mWinInsetsChanged;
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200241 if (!mLastState.equals(mState)) {
242 mLastState.set(mState, true /* copySources */);
243 notifyInsetsChanged();
Tiger Huang53c8eb82020-03-31 18:22:05 +0800244 } else {
245 // The global insets state has not changed but there might be windows whose conditions
246 // (e.g., z-order) have changed. They can affect the insets states that we dispatch to
247 // the clients.
248 for (int i = winInsetsChanged.size() - 1; i >= 0; i--) {
Tiger Huang9cfd6852020-06-21 20:53:56 +0800249 mDispatchInsetsChanged.accept(winInsetsChanged.get(i));
Tiger Huang53c8eb82020-03-31 18:22:05 +0800250 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200251 }
Tiger Huang53c8eb82020-03-31 18:22:05 +0800252 winInsetsChanged.clear();
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200253 }
254
Evan Rosky8d782e02019-10-14 15:43:53 -0700255 void onInsetsModified(InsetsControlTarget windowState, InsetsState state) {
Jorim Jaggie35c0592018-11-06 16:21:08 +0100256 boolean changed = false;
Jorim Jaggibfa95a72020-06-18 22:51:49 +0200257 for (int i = 0; i < InsetsState.SIZE; i++) {
258 final InsetsSource source = state.peekSource(i);
259 if (source == null) continue;
Jorim Jaggi28620472019-01-02 23:21:49 +0100260 final InsetsSourceProvider provider = mProviders.get(source.getType());
Jorim Jaggie35c0592018-11-06 16:21:08 +0100261 if (provider == null) {
262 continue;
263 }
264 changed |= provider.onInsetsModified(windowState, source);
265 }
266 if (changed) {
267 notifyInsetsChanged();
Tiger Huangdd6db472020-02-13 21:38:46 +0800268 mDisplayContent.getDisplayPolicy().updateSystemUiVisibilityLw();
Jorim Jaggie35c0592018-11-06 16:21:08 +0100269 }
270 }
271
Riddle Hsuc7175762020-01-10 21:03:48 +0800272 /**
273 * Computes insets state of the insets provider window in the display frames.
274 *
275 * @param state The output state.
276 * @param win The owner window of insets provider.
277 * @param displayFrames The display frames to create insets source.
278 * @param windowFrames The specified frames to represent the owner window.
279 */
280 void computeSimulatedState(InsetsState state, WindowState win, DisplayFrames displayFrames,
281 WindowFrames windowFrames) {
282 for (int i = mProviders.size() - 1; i >= 0; i--) {
283 final InsetsSourceProvider provider = mProviders.valueAt(i);
284 if (provider.mWin == win) {
285 state.addSource(provider.createSimulatedSource(displayFrames, windowFrames));
286 }
287 }
288 }
289
Tiger Huang332793b2019-10-29 23:21:27 +0800290 boolean isFakeTarget(@InternalInsetsType int type, InsetsControlTarget target) {
Jorim Jaggi956ca412019-01-07 14:49:14 +0100291 return mTypeFakeControlTargetMap.get(type) == target;
292 }
293
Tarandeep Singha6590182020-01-24 16:05:18 -0800294 void onImeControlTargetChanged(@Nullable InsetsControlTarget imeTarget) {
Jorim Jaggif768ea52020-01-30 23:45:23 +0100295
296 // Make sure that we always have a control target for the IME, even if the IME target is
297 // null. Otherwise there is no leash that will hide it and IME becomes "randomly" visible.
Taran Singh85661e32020-05-07 14:45:34 -0700298 InsetsControlTarget target = imeTarget != null ? imeTarget : mEmptyImeControlTarget;
299 onControlChanged(ITYPE_IME, target);
300 ProtoLog.d(WM_DEBUG_IME, "onImeControlTargetChanged %s",
301 target != null ? target.getWindow() : "null");
Jorim Jaggib6030952018-10-23 18:31:52 +0200302 notifyPendingInsetsControlChanged();
303 }
304
305 /**
Jorim Jaggi28620472019-01-02 23:21:49 +0100306 * Called when the focused window that is able to control the system bars changes.
Jorim Jaggib6030952018-10-23 18:31:52 +0200307 *
Tiger Huanga16634032020-02-05 17:10:03 +0800308 * @param statusControlling The target that is now able to control the status bar appearance
309 * and visibility.
Jorim Jaggi28620472019-01-02 23:21:49 +0100310 * @param navControlling The target that is now able to control the nav bar appearance
311 * and visibility.
Jorim Jaggib6030952018-10-23 18:31:52 +0200312 */
Tiger Huanga16634032020-02-05 17:10:03 +0800313 void onBarControlTargetChanged(@Nullable InsetsControlTarget statusControlling,
314 @Nullable InsetsControlTarget fakeStatusControlling,
Jorim Jaggi956ca412019-01-07 14:49:14 +0100315 @Nullable InsetsControlTarget navControlling,
316 @Nullable InsetsControlTarget fakeNavControlling) {
Tiger Huanga16634032020-02-05 17:10:03 +0800317 onControlChanged(ITYPE_STATUS_BAR, statusControlling);
Tiger Huang332793b2019-10-29 23:21:27 +0800318 onControlChanged(ITYPE_NAVIGATION_BAR, navControlling);
Tiger Huanga16634032020-02-05 17:10:03 +0800319 onControlFakeTargetChanged(ITYPE_STATUS_BAR, fakeStatusControlling);
Tiger Huang332793b2019-10-29 23:21:27 +0800320 onControlFakeTargetChanged(ITYPE_NAVIGATION_BAR, fakeNavControlling);
Jorim Jaggib6030952018-10-23 18:31:52 +0200321 notifyPendingInsetsControlChanged();
322 }
323
Jorim Jaggi28620472019-01-02 23:21:49 +0100324 void notifyControlRevoked(@NonNull InsetsControlTarget previousControlTarget,
Jorim Jaggib6030952018-10-23 18:31:52 +0200325 InsetsSourceProvider provider) {
Jorim Jaggia12ea562019-01-07 17:47:47 +0100326 removeFromControlMaps(previousControlTarget, provider.getSource().getType(),
327 false /* fake */);
Jorim Jaggib6030952018-10-23 18:31:52 +0200328 }
329
Tiger Huang332793b2019-10-29 23:21:27 +0800330 private void onControlChanged(@InternalInsetsType int type,
Jorim Jaggi28620472019-01-02 23:21:49 +0100331 @Nullable InsetsControlTarget target) {
332 final InsetsControlTarget previous = mTypeControlTargetMap.get(type);
333 if (target == previous) {
Jorim Jaggib6030952018-10-23 18:31:52 +0200334 return;
335 }
Tiger Huang969c6082019-12-24 20:08:57 +0800336 final InsetsSourceProvider provider = mProviders.get(type);
Jorim Jaggi28620472019-01-02 23:21:49 +0100337 if (provider == null) {
Jorim Jaggib6030952018-10-23 18:31:52 +0200338 return;
339 }
Jorim Jaggi28620472019-01-02 23:21:49 +0100340 if (!provider.isControllable()) {
Jorim Jaggia2759b22019-01-24 13:21:40 +0100341 return;
342 }
Jorim Jaggi28620472019-01-02 23:21:49 +0100343 provider.updateControlForTarget(target, false /* force */);
Tiger Huang969c6082019-12-24 20:08:57 +0800344 target = provider.getControlTarget();
Jorim Jaggib6030952018-10-23 18:31:52 +0200345 if (previous != null) {
Jorim Jaggia12ea562019-01-07 17:47:47 +0100346 removeFromControlMaps(previous, type, false /* fake */);
Jorim Jaggib6030952018-10-23 18:31:52 +0200347 mPendingControlChanged.add(previous);
348 }
Jorim Jaggi28620472019-01-02 23:21:49 +0100349 if (target != null) {
Jorim Jaggia12ea562019-01-07 17:47:47 +0100350 addToControlMaps(target, type, false /* fake */);
Jorim Jaggi28620472019-01-02 23:21:49 +0100351 mPendingControlChanged.add(target);
Jorim Jaggib6030952018-10-23 18:31:52 +0200352 }
353 }
354
Jorim Jaggia12ea562019-01-07 17:47:47 +0100355 /**
356 * The fake target saved here will be used to pretend to the app that it's still under control
357 * of the bars while it's not really, but we still need to find out the apps intentions around
358 * showing/hiding. For example, when the transient bars are showing, and the fake target
359 * requests to show system bars, the transient state will be aborted.
360 */
Tiger Huang332793b2019-10-29 23:21:27 +0800361 void onControlFakeTargetChanged(@InternalInsetsType int type,
Jorim Jaggia12ea562019-01-07 17:47:47 +0100362 @Nullable InsetsControlTarget fakeTarget) {
363 if (sNewInsetsMode != NEW_INSETS_MODE_FULL) {
364 return;
365 }
366 final InsetsControlTarget previous = mTypeFakeControlTargetMap.get(type);
367 if (fakeTarget == previous) {
368 return;
369 }
370 final InsetsSourceProvider provider = mProviders.get(type);
371 if (provider == null) {
372 return;
373 }
374 provider.updateControlForFakeTarget(fakeTarget);
375 if (previous != null) {
376 removeFromControlMaps(previous, type, true /* fake */);
377 mPendingControlChanged.add(previous);
378 }
379 if (fakeTarget != null) {
380 addToControlMaps(fakeTarget, type, true /* fake */);
381 mPendingControlChanged.add(fakeTarget);
382 }
383 }
384
Jorim Jaggi28620472019-01-02 23:21:49 +0100385 private void removeFromControlMaps(@NonNull InsetsControlTarget target,
Tiger Huang332793b2019-10-29 23:21:27 +0800386 @InternalInsetsType int type, boolean fake) {
Jorim Jaggi28620472019-01-02 23:21:49 +0100387 final ArrayList<Integer> array = mControlTargetTypeMap.get(target);
Jorim Jaggib6030952018-10-23 18:31:52 +0200388 if (array == null) {
389 return;
390 }
391 array.remove((Integer) type);
392 if (array.isEmpty()) {
Jorim Jaggi28620472019-01-02 23:21:49 +0100393 mControlTargetTypeMap.remove(target);
Jorim Jaggib6030952018-10-23 18:31:52 +0200394 }
Jorim Jaggia12ea562019-01-07 17:47:47 +0100395 if (fake) {
396 mTypeFakeControlTargetMap.remove(type);
397 } else {
398 mTypeControlTargetMap.remove(type);
399 }
Jorim Jaggib6030952018-10-23 18:31:52 +0200400 }
401
Jorim Jaggi28620472019-01-02 23:21:49 +0100402 private void addToControlMaps(@NonNull InsetsControlTarget target,
Tiger Huang332793b2019-10-29 23:21:27 +0800403 @InternalInsetsType int type, boolean fake) {
Jorim Jaggi28620472019-01-02 23:21:49 +0100404 final ArrayList<Integer> array = mControlTargetTypeMap.computeIfAbsent(target,
Jorim Jaggib6030952018-10-23 18:31:52 +0200405 key -> new ArrayList<>());
406 array.add(type);
Jorim Jaggia12ea562019-01-07 17:47:47 +0100407 if (fake) {
408 mTypeFakeControlTargetMap.put(type, target);
409 } else {
410 mTypeControlTargetMap.put(type, target);
411 }
Jorim Jaggib6030952018-10-23 18:31:52 +0200412 }
413
Jorim Jaggi28620472019-01-02 23:21:49 +0100414 void notifyControlChanged(InsetsControlTarget target) {
Tarandeep Singh215929b2019-01-11 18:24:37 -0800415 mPendingControlChanged.add(target);
416 notifyPendingInsetsControlChanged();
417 }
418
Jorim Jaggib6030952018-10-23 18:31:52 +0200419 private void notifyPendingInsetsControlChanged() {
Jorim Jaggif86eb492019-01-09 17:37:08 +0100420 if (mPendingControlChanged.isEmpty()) {
421 return;
422 }
Jorim Jaggib6030952018-10-23 18:31:52 +0200423 mDisplayContent.mWmService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
Tiger Huange480e5f2020-04-16 23:26:49 +0800424 for (int i = mProviders.size() - 1; i >= 0; i--) {
425 final InsetsSourceProvider provider = mProviders.valueAt(i);
426 provider.onSurfaceTransactionApplied();
427 }
Jorim Jaggib6030952018-10-23 18:31:52 +0200428 for (int i = mPendingControlChanged.size() - 1; i >= 0; i--) {
Jorim Jaggi28620472019-01-02 23:21:49 +0100429 final InsetsControlTarget controlTarget = mPendingControlChanged.valueAt(i);
430 controlTarget.notifyInsetsControlChanged();
Jorim Jaggib6030952018-10-23 18:31:52 +0200431 }
432 mPendingControlChanged.clear();
433 });
434 }
435
Jorim Jaggi956ca412019-01-07 14:49:14 +0100436 void notifyInsetsChanged() {
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200437 mDisplayContent.forAllWindows(mDispatchInsetsChanged, true /* traverseTopToBottom */);
Evan Rosky8d782e02019-10-14 15:43:53 -0700438 if (mDisplayContent.mRemoteInsetsControlTarget != null) {
439 mDisplayContent.mRemoteInsetsControlTarget.notifyInsetsChanged();
440 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200441 }
442
443 void dump(String prefix, PrintWriter pw) {
444 pw.println(prefix + "WindowInsetsStateController");
445 mState.dump(prefix + " ", pw);
Jorim Jaggicfd6f3b2018-11-07 15:30:18 +0100446 pw.println(prefix + " " + "Control map:");
Jorim Jaggi28620472019-01-02 23:21:49 +0100447 for (int i = mTypeControlTargetMap.size() - 1; i >= 0; i--) {
Jorim Jaggicfd6f3b2018-11-07 15:30:18 +0100448 pw.print(prefix + " ");
Jorim Jaggi28620472019-01-02 23:21:49 +0100449 pw.println(InsetsState.typeToString(mTypeControlTargetMap.keyAt(i)) + " -> "
450 + mTypeControlTargetMap.valueAt(i));
Jorim Jaggicfd6f3b2018-11-07 15:30:18 +0100451 }
Taran Singh85661e32020-05-07 14:45:34 -0700452 pw.println(prefix + " " + "InsetsSourceProviders map:");
453 for (int i = mProviders.size() - 1; i >= 0; i--) {
454 pw.print(prefix + " ");
455 pw.println(InsetsState.typeToString(mProviders.keyAt(i)) + " -> ");
456 mProviders.valueAt(i).dump(pw, prefix);
457 }
Jorim Jaggif96c90a2018-09-26 16:55:15 +0200458 }
459}