Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 1 | /* |
| 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 | |
| 17 | package android.view; |
| 18 | |
Jorim Jaggi | 33a2183 | 2020-04-06 14:15:46 +0200 | [diff] [blame] | 19 | import static android.view.InsetsController.ANIMATION_TYPE_NONE; |
Tarandeep Singh | b9538cd | 2020-02-20 17:51:18 -0800 | [diff] [blame] | 20 | import static android.view.InsetsController.AnimationType; |
Tiger Huang | 026dec4 | 2020-06-11 17:50:04 +0800 | [diff] [blame] | 21 | import static android.view.InsetsState.getDefaultVisibility; |
Yohei Yukawa | f35971d | 2020-06-16 21:31:35 +0000 | [diff] [blame] | 22 | import static android.view.InsetsController.DEBUG; |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 23 | import static android.view.InsetsState.toPublicType; |
Jorim Jaggi | 1f2c7eb | 2020-01-08 00:07:13 +0100 | [diff] [blame] | 24 | |
Adrian Roos | 021f4a7 | 2020-06-05 17:06:07 +0200 | [diff] [blame] | 25 | import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; |
| 26 | |
Tarandeep Singh | 46d59f0 | 2019-01-29 18:09:15 -0800 | [diff] [blame] | 27 | import android.annotation.IntDef; |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 28 | import android.annotation.Nullable; |
Jorim Jaggi | 33a2183 | 2020-04-06 14:15:46 +0200 | [diff] [blame] | 29 | import android.graphics.Rect; |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 30 | import android.util.Log; |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 31 | import android.view.InsetsState.InternalInsetsType; |
Tarandeep Singh | 22f2b4c | 2019-01-10 19:41:30 -0800 | [diff] [blame] | 32 | import android.view.SurfaceControl.Transaction; |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 33 | import android.view.WindowInsets.Type.InsetsType; |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 34 | |
| 35 | import com.android.internal.annotations.VisibleForTesting; |
| 36 | |
Tarandeep Singh | 46d59f0 | 2019-01-29 18:09:15 -0800 | [diff] [blame] | 37 | import java.lang.annotation.Retention; |
| 38 | import java.lang.annotation.RetentionPolicy; |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 39 | import java.util.function.Supplier; |
| 40 | |
| 41 | /** |
| 42 | * Controls the visibility and animations of a single window insets source. |
| 43 | * @hide |
| 44 | */ |
| 45 | public class InsetsSourceConsumer { |
| 46 | |
Tarandeep Singh | 46d59f0 | 2019-01-29 18:09:15 -0800 | [diff] [blame] | 47 | @Retention(RetentionPolicy.SOURCE) |
Jorim Jaggi | d7f10ed | 2020-01-08 21:41:55 +0100 | [diff] [blame] | 48 | @IntDef(value = {ShowResult.SHOW_IMMEDIATELY, ShowResult.IME_SHOW_DELAYED, ShowResult.IME_SHOW_FAILED}) |
Tarandeep Singh | 46d59f0 | 2019-01-29 18:09:15 -0800 | [diff] [blame] | 49 | @interface ShowResult { |
| 50 | /** |
| 51 | * Window type is ready to be shown, will be shown immidiately. |
| 52 | */ |
| 53 | int SHOW_IMMEDIATELY = 0; |
| 54 | /** |
| 55 | * Result will be delayed. Window needs to be prepared or request is not from controller. |
| 56 | * Request will be delegated to controller and may or may not be shown. |
| 57 | */ |
Jorim Jaggi | d7f10ed | 2020-01-08 21:41:55 +0100 | [diff] [blame] | 58 | int IME_SHOW_DELAYED = 1; |
Tarandeep Singh | 46d59f0 | 2019-01-29 18:09:15 -0800 | [diff] [blame] | 59 | /** |
| 60 | * Window will not be shown because one of the conditions couldn't be met. |
| 61 | * (e.g. in IME's case, when no editor is focused.) |
| 62 | */ |
Jorim Jaggi | d7f10ed | 2020-01-08 21:41:55 +0100 | [diff] [blame] | 63 | int IME_SHOW_FAILED = 2; |
Tarandeep Singh | 46d59f0 | 2019-01-29 18:09:15 -0800 | [diff] [blame] | 64 | } |
| 65 | |
Tarandeep Singh | 2cbcd7f | 2019-01-25 11:47:57 -0800 | [diff] [blame] | 66 | protected final InsetsController mController; |
Jorim Jaggi | a51168a | 2019-12-27 15:17:44 +0100 | [diff] [blame] | 67 | protected boolean mRequestedVisible; |
Tarandeep Singh | b9538cd | 2020-02-20 17:51:18 -0800 | [diff] [blame] | 68 | protected final InsetsState mState; |
| 69 | protected final @InternalInsetsType int mType; |
| 70 | |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 71 | private static final String TAG = "InsetsSourceConsumer"; |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 72 | private final Supplier<Transaction> mTransactionSupplier; |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 73 | private @Nullable InsetsSourceControl mSourceControl; |
Tarandeep Singh | 92d2dd3 | 2019-08-07 14:45:01 -0700 | [diff] [blame] | 74 | private boolean mHasWindowFocus; |
Jorim Jaggi | 33a2183 | 2020-04-06 14:15:46 +0200 | [diff] [blame] | 75 | private Rect mPendingFrame; |
| 76 | private Rect mPendingVisibleFrame; |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 77 | |
Tiger Huang | e480e5f | 2020-04-16 23:26:49 +0800 | [diff] [blame] | 78 | /** |
| 79 | * Indicates if we have the pending animation. When we have the control, we need to play the |
| 80 | * animation if the requested visibility is different from the current state. But if we haven't |
| 81 | * had a leash yet, we will set this flag, and play the animation once we get the leash. |
| 82 | */ |
| 83 | private boolean mIsAnimationPending; |
| 84 | |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 85 | public InsetsSourceConsumer(@InternalInsetsType int type, InsetsState state, |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 86 | Supplier<Transaction> transactionSupplier, InsetsController controller) { |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 87 | mType = type; |
| 88 | mState = state; |
| 89 | mTransactionSupplier = transactionSupplier; |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 90 | mController = controller; |
Tiger Huang | 2ab590a | 2020-05-19 21:55:13 +0800 | [diff] [blame] | 91 | mRequestedVisible = getDefaultVisibility(type); |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 92 | } |
| 93 | |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 94 | /** |
| 95 | * Updates the control delivered from the server. |
| 96 | |
| 97 | * @param showTypes An integer array with a single entry that determines which types a show |
| 98 | * animation should be run after setting the control. |
| 99 | * @param hideTypes An integer array with a single entry that determines which types a hide |
| 100 | * animation should be run after setting the control. |
| 101 | */ |
| 102 | public void setControl(@Nullable InsetsSourceControl control, |
| 103 | @InsetsType int[] showTypes, @InsetsType int[] hideTypes) { |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 104 | if (mSourceControl == control) { |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 105 | return; |
| 106 | } |
Jorim Jaggi | ee54070 | 2020-04-02 21:40:52 +0200 | [diff] [blame] | 107 | SurfaceControl oldLeash = mSourceControl != null ? mSourceControl.getLeash() : null; |
| 108 | |
Rob Carr | ed48db3 | 2020-03-05 13:31:01 -0800 | [diff] [blame] | 109 | final InsetsSourceControl lastControl = mSourceControl; |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 110 | mSourceControl = control; |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 111 | if (control != null) { |
| 112 | if (DEBUG) Log.d(TAG, String.format("setControl -> %s on %s", |
| 113 | InsetsState.typeToString(control.getType()), |
| 114 | mController.getHost().getRootViewTitle())); |
| 115 | } |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 116 | // We are loosing control |
| 117 | if (mSourceControl == null) { |
| 118 | mController.notifyControlRevoked(this); |
| 119 | |
| 120 | // Restore server visibility. |
| 121 | mState.getSource(getType()).setVisible( |
| 122 | mController.getLastDispatchedState().getSource(getType()).isVisible()); |
| 123 | applyLocalVisibilityOverride(); |
Rob Carr | ed48db3 | 2020-03-05 13:31:01 -0800 | [diff] [blame] | 124 | } else { |
| 125 | // We are gaining control, and need to run an animation since previous state |
| 126 | // didn't match |
Tiger Huang | e480e5f | 2020-04-16 23:26:49 +0800 | [diff] [blame] | 127 | final boolean requestedVisible = isRequestedVisibleAwaitingControl(); |
| 128 | final boolean needAnimation = requestedVisible != mState.getSource(mType).isVisible(); |
| 129 | if (control.getLeash() != null && (needAnimation || mIsAnimationPending)) { |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 130 | if (DEBUG) Log.d(TAG, String.format("Gaining control in %s, requestedVisible: %b", |
| 131 | mController.getHost().getRootViewTitle(), requestedVisible)); |
Tiger Huang | e480e5f | 2020-04-16 23:26:49 +0800 | [diff] [blame] | 132 | if (requestedVisible) { |
Rob Carr | ed48db3 | 2020-03-05 13:31:01 -0800 | [diff] [blame] | 133 | showTypes[0] |= toPublicType(getType()); |
| 134 | } else { |
| 135 | hideTypes[0] |= toPublicType(getType()); |
| 136 | } |
Tiger Huang | e480e5f | 2020-04-16 23:26:49 +0800 | [diff] [blame] | 137 | mIsAnimationPending = false; |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 138 | } else { |
Tiger Huang | e480e5f | 2020-04-16 23:26:49 +0800 | [diff] [blame] | 139 | if (needAnimation) { |
| 140 | // We need animation but we haven't had a leash yet. Set this flag that when we |
| 141 | // get the leash we can play the deferred animation. |
| 142 | mIsAnimationPending = true; |
| 143 | } |
Jorim Jaggi | 49b9f6c | 2020-03-24 22:28:38 +0100 | [diff] [blame] | 144 | // We are gaining control, but don't need to run an animation. |
| 145 | // However make sure that the leash visibility is still up to date. |
| 146 | if (applyLocalVisibilityOverride()) { |
| 147 | mController.notifyVisibilityChanged(); |
Jorim Jaggi | ee54070 | 2020-04-02 21:40:52 +0200 | [diff] [blame] | 148 | } |
| 149 | |
| 150 | // If we have a new leash, make sure visibility is up-to-date, even though we |
| 151 | // didn't want to run an animation above. |
| 152 | SurfaceControl newLeash = mSourceControl.getLeash(); |
| 153 | if (oldLeash == null || newLeash == null || !oldLeash.isSameSurface(newLeash)) { |
Jorim Jaggi | 49b9f6c | 2020-03-24 22:28:38 +0100 | [diff] [blame] | 154 | applyHiddenToControl(); |
| 155 | } |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 156 | } |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 157 | } |
Rob Carr | ed48db3 | 2020-03-05 13:31:01 -0800 | [diff] [blame] | 158 | if (lastControl != null) { |
Robert Carr | 4c101c3 | 2020-03-31 14:43:25 -0700 | [diff] [blame] | 159 | lastControl.release(SurfaceControl::release); |
Jorim Jaggi | e35c059 | 2018-11-06 16:21:08 +0100 | [diff] [blame] | 160 | } |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | @VisibleForTesting |
| 164 | public InsetsSourceControl getControl() { |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 165 | return mSourceControl; |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 166 | } |
| 167 | |
Taran Singh | 9641cfc | 2020-04-09 16:59:10 -0700 | [diff] [blame] | 168 | /** |
| 169 | * Determines if the consumer will be shown after control is available. |
| 170 | * Note: for system bars this method is same as {@link #isRequestedVisible()}. |
| 171 | * |
| 172 | * @return {@code true} if consumer has a pending show. |
| 173 | */ |
| 174 | protected boolean isRequestedVisibleAwaitingControl() { |
| 175 | return isRequestedVisible(); |
| 176 | } |
| 177 | |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 178 | int getType() { |
| 179 | return mType; |
| 180 | } |
| 181 | |
| 182 | @VisibleForTesting |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 183 | public void show(boolean fromIme) { |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 184 | if (DEBUG) Log.d(TAG, String.format("Call show() for type: %s fromIme: %b ", |
| 185 | InsetsState.typeToString(mType), fromIme)); |
Jorim Jaggi | a51168a | 2019-12-27 15:17:44 +0100 | [diff] [blame] | 186 | setRequestedVisible(true); |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 187 | } |
| 188 | |
| 189 | @VisibleForTesting |
| 190 | public void hide() { |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 191 | if (DEBUG) Log.d(TAG, String.format("Call hide for %s on %s", |
| 192 | InsetsState.typeToString(mType), mController.getHost().getRootViewTitle())); |
Jorim Jaggi | a51168a | 2019-12-27 15:17:44 +0100 | [diff] [blame] | 193 | setRequestedVisible(false); |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 194 | } |
| 195 | |
Tarandeep Singh | b9538cd | 2020-02-20 17:51:18 -0800 | [diff] [blame] | 196 | void hide(boolean animationFinished, @AnimationType int animationType) { |
Tarandeep Singh | 94c9a83 | 2020-02-03 14:55:30 -0800 | [diff] [blame] | 197 | hide(); |
| 198 | } |
| 199 | |
Tarandeep Singh | 2cbcd7f | 2019-01-25 11:47:57 -0800 | [diff] [blame] | 200 | /** |
| 201 | * Called when current window gains focus |
| 202 | */ |
Tarandeep Singh | 92d2dd3 | 2019-08-07 14:45:01 -0700 | [diff] [blame] | 203 | public void onWindowFocusGained() { |
| 204 | mHasWindowFocus = true; |
| 205 | } |
Tarandeep Singh | 2cbcd7f | 2019-01-25 11:47:57 -0800 | [diff] [blame] | 206 | |
| 207 | /** |
| 208 | * Called when current window loses focus. |
| 209 | */ |
Tarandeep Singh | 92d2dd3 | 2019-08-07 14:45:01 -0700 | [diff] [blame] | 210 | public void onWindowFocusLost() { |
| 211 | mHasWindowFocus = false; |
| 212 | } |
| 213 | |
| 214 | boolean hasWindowFocus() { |
| 215 | return mHasWindowFocus; |
| 216 | } |
Tarandeep Singh | 2cbcd7f | 2019-01-25 11:47:57 -0800 | [diff] [blame] | 217 | |
Jorim Jaggi | e35c059 | 2018-11-06 16:21:08 +0100 | [diff] [blame] | 218 | boolean applyLocalVisibilityOverride() { |
Tiger Huang | 2ab590a | 2020-05-19 21:55:13 +0800 | [diff] [blame] | 219 | final InsetsSource source = mState.peekSource(mType); |
| 220 | final boolean isVisible = source != null ? source.isVisible() : getDefaultVisibility(mType); |
| 221 | final boolean hasControl = mSourceControl != null; |
| 222 | |
| 223 | // We still need to let the legacy app know the visibility change even if we don't have the |
Tiger Huang | 026dec4 | 2020-06-11 17:50:04 +0800 | [diff] [blame] | 224 | // control. If we don't have the source, we don't change the requested visibility for making |
| 225 | // the callback behavior compatible. |
Tiger Huang | 2ab590a | 2020-05-19 21:55:13 +0800 | [diff] [blame] | 226 | mController.updateCompatSysUiVisibility( |
Tiger Huang | 026dec4 | 2020-06-11 17:50:04 +0800 | [diff] [blame] | 227 | mType, (hasControl || source == null) ? mRequestedVisible : isVisible, hasControl); |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 228 | |
| 229 | // If we don't have control, we are not able to change the visibility. |
Tiger Huang | 2ab590a | 2020-05-19 21:55:13 +0800 | [diff] [blame] | 230 | if (!hasControl) { |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 231 | if (DEBUG) Log.d(TAG, "applyLocalVisibilityOverride: No control in " |
| 232 | + mController.getHost().getRootViewTitle() |
| 233 | + " requestedVisible " + mRequestedVisible); |
Jorim Jaggi | e35c059 | 2018-11-06 16:21:08 +0100 | [diff] [blame] | 234 | return false; |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 235 | } |
Tiger Huang | 2ab590a | 2020-05-19 21:55:13 +0800 | [diff] [blame] | 236 | if (isVisible == mRequestedVisible) { |
Jorim Jaggi | e35c059 | 2018-11-06 16:21:08 +0100 | [diff] [blame] | 237 | return false; |
| 238 | } |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 239 | if (DEBUG) Log.d(TAG, String.format("applyLocalVisibilityOverride: %s requestedVisible: %b", |
| 240 | mController.getHost().getRootViewTitle(), mRequestedVisible)); |
Jorim Jaggi | a51168a | 2019-12-27 15:17:44 +0100 | [diff] [blame] | 241 | mState.getSource(mType).setVisible(mRequestedVisible); |
Jorim Jaggi | e35c059 | 2018-11-06 16:21:08 +0100 | [diff] [blame] | 242 | return true; |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 243 | } |
| 244 | |
Tarandeep Singh | 22f2b4c | 2019-01-10 19:41:30 -0800 | [diff] [blame] | 245 | @VisibleForTesting |
Jorim Jaggi | a51168a | 2019-12-27 15:17:44 +0100 | [diff] [blame] | 246 | public boolean isRequestedVisible() { |
| 247 | return mRequestedVisible; |
Tarandeep Singh | 22f2b4c | 2019-01-10 19:41:30 -0800 | [diff] [blame] | 248 | } |
| 249 | |
Tarandeep Singh | 46d59f0 | 2019-01-29 18:09:15 -0800 | [diff] [blame] | 250 | /** |
| 251 | * Request to show current window type. |
| 252 | * |
| 253 | * @param fromController {@code true} if request is coming from controller. |
| 254 | * (e.g. in IME case, controller is |
| 255 | * {@link android.inputmethodservice.InputMethodService}). |
| 256 | * @return @see {@link ShowResult}. |
| 257 | */ |
Jorim Jaggi | d7f10ed | 2020-01-08 21:41:55 +0100 | [diff] [blame] | 258 | @VisibleForTesting |
| 259 | public @ShowResult int requestShow(boolean fromController) { |
Tarandeep Singh | 46d59f0 | 2019-01-29 18:09:15 -0800 | [diff] [blame] | 260 | return ShowResult.SHOW_IMMEDIATELY; |
| 261 | } |
| 262 | |
| 263 | /** |
| 264 | * Notify listeners that window is now hidden. |
| 265 | */ |
| 266 | void notifyHidden() { |
| 267 | // no-op for types that always return ShowResult#SHOW_IMMEDIATELY. |
| 268 | } |
| 269 | |
Jorim Jaggi | a51168a | 2019-12-27 15:17:44 +0100 | [diff] [blame] | 270 | /** |
Tarandeep Singh | 94c9a83 | 2020-02-03 14:55:30 -0800 | [diff] [blame] | 271 | * Remove surface on which this consumer type is drawn. |
| 272 | */ |
| 273 | public void removeSurface() { |
| 274 | // no-op for types that always return ShowResult#SHOW_IMMEDIATELY. |
| 275 | } |
| 276 | |
Adrian Roos | 021f4a7 | 2020-06-05 17:06:07 +0200 | [diff] [blame] | 277 | @VisibleForTesting(visibility = PACKAGE) |
Yohei Yukawa | f35971d | 2020-06-16 21:31:35 +0000 | [diff] [blame] | 278 | public void updateSource(InsetsSource newSource) { |
Jorim Jaggi | 33a2183 | 2020-04-06 14:15:46 +0200 | [diff] [blame] | 279 | InsetsSource source = mState.peekSource(mType); |
Yohei Yukawa | f35971d | 2020-06-16 21:31:35 +0000 | [diff] [blame] | 280 | if (source == null || mController.getAnimationType(mType) == ANIMATION_TYPE_NONE |
Jorim Jaggi | 33a2183 | 2020-04-06 14:15:46 +0200 | [diff] [blame] | 281 | || source.getFrame().equals(newSource.getFrame())) { |
Adrian Roos | 021f4a7 | 2020-06-05 17:06:07 +0200 | [diff] [blame] | 282 | mPendingFrame = null; |
| 283 | mPendingVisibleFrame = null; |
Jorim Jaggi | 33a2183 | 2020-04-06 14:15:46 +0200 | [diff] [blame] | 284 | mState.addSource(newSource); |
| 285 | return; |
| 286 | } |
| 287 | |
| 288 | // Frame is changing while animating. Keep note of the new frame but keep existing frame |
Yohei Yukawa | f35971d | 2020-06-16 21:31:35 +0000 | [diff] [blame] | 289 | // until animaition is finished. |
Jorim Jaggi | 33a2183 | 2020-04-06 14:15:46 +0200 | [diff] [blame] | 290 | newSource = new InsetsSource(newSource); |
| 291 | mPendingFrame = new Rect(newSource.getFrame()); |
| 292 | mPendingVisibleFrame = newSource.getVisibleFrame() != null |
| 293 | ? new Rect(newSource.getVisibleFrame()) |
| 294 | : null; |
| 295 | newSource.setFrame(source.getFrame()); |
| 296 | newSource.setVisibleFrame(source.getVisibleFrame()); |
| 297 | mState.addSource(newSource); |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 298 | if (DEBUG) Log.d(TAG, "updateSource: " + newSource); |
Jorim Jaggi | 33a2183 | 2020-04-06 14:15:46 +0200 | [diff] [blame] | 299 | } |
| 300 | |
Adrian Roos | 021f4a7 | 2020-06-05 17:06:07 +0200 | [diff] [blame] | 301 | @VisibleForTesting(visibility = PACKAGE) |
| 302 | public boolean notifyAnimationFinished() { |
Jorim Jaggi | 33a2183 | 2020-04-06 14:15:46 +0200 | [diff] [blame] | 303 | if (mPendingFrame != null) { |
| 304 | InsetsSource source = mState.getSource(mType); |
| 305 | source.setFrame(mPendingFrame); |
| 306 | source.setVisibleFrame(mPendingVisibleFrame); |
| 307 | mPendingFrame = null; |
| 308 | mPendingVisibleFrame = null; |
| 309 | return true; |
| 310 | } |
| 311 | return false; |
| 312 | } |
| 313 | |
Tarandeep Singh | 94c9a83 | 2020-02-03 14:55:30 -0800 | [diff] [blame] | 314 | /** |
Jorim Jaggi | a51168a | 2019-12-27 15:17:44 +0100 | [diff] [blame] | 315 | * Sets requested visibility from the client, regardless of whether we are able to control it at |
| 316 | * the moment. |
| 317 | */ |
Taran Singh | 9641cfc | 2020-04-09 16:59:10 -0700 | [diff] [blame] | 318 | protected void setRequestedVisible(boolean requestedVisible) { |
Tiger Huang | e480e5f | 2020-04-16 23:26:49 +0800 | [diff] [blame] | 319 | if (mRequestedVisible != requestedVisible) { |
| 320 | mRequestedVisible = requestedVisible; |
| 321 | mIsAnimationPending = false; |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 322 | if (DEBUG) Log.d(TAG, "setRequestedVisible: " + requestedVisible); |
Tiger Huang | e480e5f | 2020-04-16 23:26:49 +0800 | [diff] [blame] | 323 | } |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 324 | if (applyLocalVisibilityOverride()) { |
| 325 | mController.notifyVisibilityChanged(); |
| 326 | } |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 327 | } |
| 328 | |
| 329 | private void applyHiddenToControl() { |
Jorim Jaggi | 026ed75 | 2020-01-29 00:30:24 +0100 | [diff] [blame] | 330 | if (mSourceControl == null || mSourceControl.getLeash() == null) { |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 331 | return; |
| 332 | } |
| 333 | |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 334 | final Transaction t = mTransactionSupplier.get(); |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 335 | if (DEBUG) Log.d(TAG, "applyHiddenToControl: " + mRequestedVisible); |
Jorim Jaggi | a51168a | 2019-12-27 15:17:44 +0100 | [diff] [blame] | 336 | if (mRequestedVisible) { |
Jorim Jaggi | c8d6038 | 2018-10-31 17:06:06 +0100 | [diff] [blame] | 337 | t.show(mSourceControl.getLeash()); |
Jorim Jaggi | e35c059 | 2018-11-06 16:21:08 +0100 | [diff] [blame] | 338 | } else { |
| 339 | t.hide(mSourceControl.getLeash()); |
Jorim Jaggi | b603095 | 2018-10-23 18:31:52 +0200 | [diff] [blame] | 340 | } |
| 341 | t.apply(); |
| 342 | } |
| 343 | } |