Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [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 | |
Tarandeep Singh | b9538cd | 2020-02-20 17:51:18 -0800 | [diff] [blame] | 19 | import static android.view.InsetsController.AnimationType; |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 20 | import static android.view.InsetsController.DEBUG; |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 21 | import static android.view.InsetsState.ISIDE_BOTTOM; |
| 22 | import static android.view.InsetsState.ISIDE_FLOATING; |
| 23 | import static android.view.InsetsState.ISIDE_LEFT; |
| 24 | import static android.view.InsetsState.ISIDE_RIGHT; |
| 25 | import static android.view.InsetsState.ISIDE_TOP; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 26 | |
Adrian Roos | 5398997 | 2020-03-19 20:15:57 +0100 | [diff] [blame] | 27 | import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; |
| 28 | |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 29 | import android.annotation.Nullable; |
| 30 | import android.graphics.Insets; |
| 31 | import android.graphics.Matrix; |
| 32 | import android.graphics.Rect; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 33 | import android.util.ArraySet; |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 34 | import android.util.Log; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 35 | import android.util.SparseArray; |
| 36 | import android.util.SparseIntArray; |
| 37 | import android.util.SparseSetArray; |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 38 | import android.view.InsetsState.InternalInsetsSide; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 39 | import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams; |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 40 | import android.view.WindowInsets.Type.InsetsType; |
Adrian Roos | db5b0c2 | 2020-02-12 15:05:27 -0800 | [diff] [blame] | 41 | import android.view.WindowInsetsAnimation.Bounds; |
Jorim Jaggi | 648e588 | 2019-01-24 13:24:02 +0100 | [diff] [blame] | 42 | import android.view.WindowManager.LayoutParams; |
Jorim Jaggi | dd3304e | 2020-01-20 17:24:51 +0100 | [diff] [blame] | 43 | import android.view.animation.Interpolator; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 44 | |
| 45 | import com.android.internal.annotations.VisibleForTesting; |
| 46 | |
| 47 | import java.util.ArrayList; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 48 | |
| 49 | /** |
| 50 | * Implements {@link WindowInsetsAnimationController} |
| 51 | * @hide |
| 52 | */ |
| 53 | @VisibleForTesting |
Jorim Jaggi | 6d5c801 | 2020-02-28 01:40:27 +0100 | [diff] [blame] | 54 | public class InsetsAnimationControlImpl implements WindowInsetsAnimationController, |
| 55 | InsetsAnimationControlRunner { |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 56 | |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 57 | private static final String TAG = "InsetsAnimationCtrlImpl"; |
| 58 | |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 59 | private final Rect mTmpFrame = new Rect(); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 60 | |
| 61 | private final WindowInsetsAnimationControlListener mListener; |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 62 | private final SparseArray<InsetsSourceControl> mControls; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 63 | private final SparseIntArray mTypeSideMap = new SparseIntArray(); |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 64 | private final SparseSetArray<InsetsSourceControl> mSideSourceMap = new SparseSetArray<>(); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 65 | |
| 66 | /** @see WindowInsetsAnimationController#getHiddenStateInsets */ |
| 67 | private final Insets mHiddenInsets; |
| 68 | |
| 69 | /** @see WindowInsetsAnimationController#getShownStateInsets */ |
| 70 | private final Insets mShownInsets; |
| 71 | private final Matrix mTmpMatrix = new Matrix(); |
| 72 | private final InsetsState mInitialInsetsState; |
Tarandeep Singh | b9538cd | 2020-02-20 17:51:18 -0800 | [diff] [blame] | 73 | private final @AnimationType int mAnimationType; |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 74 | private final @InsetsType int mTypes; |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 75 | private final InsetsAnimationControlCallbacks mController; |
Adrian Roos | db5b0c2 | 2020-02-12 15:05:27 -0800 | [diff] [blame] | 76 | private final WindowInsetsAnimation mAnimation; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 77 | private Insets mCurrentInsets; |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 78 | private Insets mPendingInsets; |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 79 | private float mPendingFraction; |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 80 | private boolean mFinished; |
| 81 | private boolean mCancelled; |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 82 | private boolean mShownOnFinish; |
Jorim Jaggi | 580aef5 | 2020-02-26 18:28:28 +0100 | [diff] [blame] | 83 | private float mCurrentAlpha = 1.0f; |
| 84 | private float mPendingAlpha = 1.0f; |
Adrian Roos | 5398997 | 2020-03-19 20:15:57 +0100 | [diff] [blame] | 85 | @VisibleForTesting(visibility = PACKAGE) |
| 86 | public boolean mReadyDispatched; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 87 | |
| 88 | @VisibleForTesting |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 89 | public InsetsAnimationControlImpl(SparseArray<InsetsSourceControl> controls, Rect frame, |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 90 | InsetsState state, WindowInsetsAnimationControlListener listener, |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 91 | @InsetsType int types, |
Jorim Jaggi | dd3304e | 2020-01-20 17:24:51 +0100 | [diff] [blame] | 92 | InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator, |
Jorim Jaggi | 5875cca | 2020-03-17 13:44:57 +0100 | [diff] [blame] | 93 | @AnimationType int animationType) { |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 94 | mControls = controls; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 95 | mListener = listener; |
| 96 | mTypes = types; |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 97 | mController = controller; |
| 98 | mInitialInsetsState = new InsetsState(state, true /* copySources */); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 99 | mCurrentInsets = getInsetsFromState(mInitialInsetsState, frame, null /* typeSideMap */); |
Jorim Jaggi | 1f2c7eb | 2020-01-08 00:07:13 +0100 | [diff] [blame] | 100 | mPendingInsets = mCurrentInsets; |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 101 | mHiddenInsets = calculateInsets(mInitialInsetsState, frame, controls, false /* shown */, |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 102 | null /* typeSideMap */); |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 103 | mShownInsets = calculateInsets(mInitialInsetsState, frame, controls, true /* shown */, |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 104 | mTypeSideMap); |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 105 | buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 106 | |
Adrian Roos | db5b0c2 | 2020-02-12 15:05:27 -0800 | [diff] [blame] | 107 | mAnimation = new WindowInsetsAnimation(mTypes, interpolator, |
Jorim Jaggi | dd3304e | 2020-01-20 17:24:51 +0100 | [diff] [blame] | 108 | durationMs); |
Tarandeep Singh | 699aa67 | 2019-11-22 23:19:30 -0800 | [diff] [blame] | 109 | mAnimation.setAlpha(getCurrentAlpha()); |
Tarandeep Singh | b9538cd | 2020-02-20 17:51:18 -0800 | [diff] [blame] | 110 | mAnimationType = animationType; |
Jorim Jaggi | a51168a | 2019-12-27 15:17:44 +0100 | [diff] [blame] | 111 | mController.startAnimation(this, listener, types, mAnimation, |
Jorim Jaggi | 6d5c801 | 2020-02-28 01:40:27 +0100 | [diff] [blame] | 112 | new Bounds(mHiddenInsets, mShownInsets)); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | @Override |
| 116 | public Insets getHiddenStateInsets() { |
| 117 | return mHiddenInsets; |
| 118 | } |
| 119 | |
| 120 | @Override |
| 121 | public Insets getShownStateInsets() { |
| 122 | return mShownInsets; |
| 123 | } |
| 124 | |
| 125 | @Override |
| 126 | public Insets getCurrentInsets() { |
| 127 | return mCurrentInsets; |
| 128 | } |
| 129 | |
| 130 | @Override |
Tarandeep Singh | 699aa67 | 2019-11-22 23:19:30 -0800 | [diff] [blame] | 131 | public float getCurrentAlpha() { |
| 132 | return mCurrentAlpha; |
| 133 | } |
| 134 | |
| 135 | @Override |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 136 | @InsetsType public int getTypes() { |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 137 | return mTypes; |
| 138 | } |
| 139 | |
Jorim Jaggi | 6d5c801 | 2020-02-28 01:40:27 +0100 | [diff] [blame] | 140 | @Override |
| 141 | public @AnimationType int getAnimationType() { |
Tarandeep Singh | b9538cd | 2020-02-20 17:51:18 -0800 | [diff] [blame] | 142 | return mAnimationType; |
| 143 | } |
| 144 | |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 145 | @Override |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 146 | public void setInsetsAndAlpha(Insets insets, float alpha, float fraction) { |
Jorim Jaggi | f103588 | 2020-03-31 22:47:12 +0200 | [diff] [blame] | 147 | setInsetsAndAlpha(insets, alpha, fraction, false /* allowWhenFinished */); |
| 148 | } |
| 149 | |
| 150 | private void setInsetsAndAlpha(Insets insets, float alpha, float fraction, |
| 151 | boolean allowWhenFinished) { |
| 152 | if (!allowWhenFinished && mFinished) { |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 153 | throw new IllegalStateException( |
| 154 | "Can't change insets on an animation that is finished."); |
| 155 | } |
| 156 | if (mCancelled) { |
| 157 | throw new IllegalStateException( |
| 158 | "Can't change insets on an animation that is cancelled."); |
| 159 | } |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 160 | mPendingFraction = sanitize(fraction); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 161 | mPendingInsets = sanitize(insets); |
Jorim Jaggi | 580aef5 | 2020-02-26 18:28:28 +0100 | [diff] [blame] | 162 | mPendingAlpha = sanitize(alpha); |
Adrian Roos | 6a4448f | 2020-04-01 15:01:08 +0200 | [diff] [blame] | 163 | mController.scheduleApplyChangeInsets(this); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 164 | } |
| 165 | |
Jorim Jaggi | fae3e27 | 2019-01-14 14:05:05 +0100 | [diff] [blame] | 166 | @VisibleForTesting |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 167 | /** |
| 168 | * @return Whether the finish callback of this animation should be invoked. |
| 169 | */ |
| 170 | public boolean applyChangeInsets(InsetsState state) { |
| 171 | if (mCancelled) { |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 172 | if (DEBUG) Log.d(TAG, "applyChangeInsets canceled"); |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 173 | return false; |
| 174 | } |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 175 | final Insets offset = Insets.subtract(mShownInsets, mPendingInsets); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 176 | ArrayList<SurfaceParams> params = new ArrayList<>(); |
Tarandeep Singh | 699aa67 | 2019-11-22 23:19:30 -0800 | [diff] [blame] | 177 | updateLeashesForSide(ISIDE_LEFT, offset.left, mShownInsets.left, mPendingInsets.left, |
Jorim Jaggi | 1df5bd2 | 2020-03-05 15:52:21 +0100 | [diff] [blame] | 178 | params, state, mPendingAlpha); |
Tarandeep Singh | 699aa67 | 2019-11-22 23:19:30 -0800 | [diff] [blame] | 179 | updateLeashesForSide(ISIDE_TOP, offset.top, mShownInsets.top, mPendingInsets.top, params, |
Jorim Jaggi | 1df5bd2 | 2020-03-05 15:52:21 +0100 | [diff] [blame] | 180 | state, mPendingAlpha); |
Tarandeep Singh | 699aa67 | 2019-11-22 23:19:30 -0800 | [diff] [blame] | 181 | updateLeashesForSide(ISIDE_RIGHT, offset.right, mShownInsets.right, mPendingInsets.right, |
Jorim Jaggi | 1df5bd2 | 2020-03-05 15:52:21 +0100 | [diff] [blame] | 182 | params, state, mPendingAlpha); |
Tarandeep Singh | 699aa67 | 2019-11-22 23:19:30 -0800 | [diff] [blame] | 183 | updateLeashesForSide(ISIDE_BOTTOM, offset.bottom, mShownInsets.bottom, |
Jorim Jaggi | 1df5bd2 | 2020-03-05 15:52:21 +0100 | [diff] [blame] | 184 | mPendingInsets.bottom, params, state, mPendingAlpha); |
Tarandeep Singh | 699aa67 | 2019-11-22 23:19:30 -0800 | [diff] [blame] | 185 | updateLeashesForSide(ISIDE_FLOATING, 0 /* offset */, 0 /* inset */, 0 /* maxInset */, |
Jorim Jaggi | 1df5bd2 | 2020-03-05 15:52:21 +0100 | [diff] [blame] | 186 | params, state, mPendingAlpha); |
Tarandeep Singh | 95a3dbf | 2019-10-22 10:39:24 -0700 | [diff] [blame] | 187 | |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 188 | mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()])); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 189 | mCurrentInsets = mPendingInsets; |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 190 | mAnimation.setFraction(mPendingFraction); |
Jorim Jaggi | 580aef5 | 2020-02-26 18:28:28 +0100 | [diff] [blame] | 191 | mCurrentAlpha = mPendingAlpha; |
| 192 | mAnimation.setAlpha(mPendingAlpha); |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 193 | if (mFinished) { |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 194 | if (DEBUG) Log.d(TAG, String.format( |
| 195 | "notifyFinished shown: %s, currentAlpha: %f, currentInsets: %s", |
| 196 | mShownOnFinish, mCurrentAlpha, mCurrentInsets)); |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 197 | mController.notifyFinished(this, mShownOnFinish); |
Rob Carr | 3a367c4b | 2020-03-10 15:51:35 -0700 | [diff] [blame] | 198 | releaseLeashes(); |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 199 | } |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 200 | if (DEBUG) Log.d(TAG, "Animation finished abruptly."); |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 201 | return mFinished; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 202 | } |
| 203 | |
Rob Carr | 3a367c4b | 2020-03-10 15:51:35 -0700 | [diff] [blame] | 204 | private void releaseLeashes() { |
| 205 | for (int i = mControls.size() - 1; i >= 0; i--) { |
| 206 | final InsetsSourceControl c = mControls.valueAt(i); |
| 207 | if (c == null) continue; |
| 208 | c.release(mController::releaseSurfaceControlFromRt); |
| 209 | } |
| 210 | } |
| 211 | |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 212 | @Override |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 213 | public void finish(boolean shown) { |
Yunfan Chen | b5d2db7 | 2019-12-06 15:43:43 +0900 | [diff] [blame] | 214 | if (mCancelled || mFinished) { |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 215 | if (DEBUG) Log.d(TAG, "Animation already canceled or finished, not notifying."); |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 216 | return; |
| 217 | } |
Taran Singh | 0485041 | 2020-03-23 15:04:58 -0700 | [diff] [blame] | 218 | mShownOnFinish = shown; |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 219 | mFinished = true; |
Jorim Jaggi | f103588 | 2020-03-31 22:47:12 +0200 | [diff] [blame] | 220 | setInsetsAndAlpha(shown ? mShownInsets : mHiddenInsets, 1f /* alpha */, 1f /* fraction */, |
| 221 | true /* allowWhenFinished */); |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 222 | |
| 223 | if (DEBUG) Log.d(TAG, "notify control request finished for types: " + mTypes); |
Adrian Roos | 5d557ed | 2020-03-17 20:04:35 +0100 | [diff] [blame] | 224 | mListener.onFinished(this); |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 225 | } |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 226 | |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 227 | @Override |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 228 | @VisibleForTesting |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 229 | public float getCurrentFraction() { |
| 230 | return mAnimation.getFraction(); |
| 231 | } |
| 232 | |
Jorim Jaggi | 6d5c801 | 2020-02-28 01:40:27 +0100 | [diff] [blame] | 233 | @Override |
| 234 | public void cancel() { |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 235 | if (mFinished) { |
| 236 | return; |
| 237 | } |
| 238 | mCancelled = true; |
Adrian Roos | 5398997 | 2020-03-19 20:15:57 +0100 | [diff] [blame] | 239 | mListener.onCancelled(mReadyDispatched ? this : null); |
Taran Singh | 85661e3 | 2020-05-07 14:45:34 -0700 | [diff] [blame] | 240 | if (DEBUG) Log.d(TAG, "notify Control request cancelled for types: " + mTypes); |
Rob Carr | 3a367c4b | 2020-03-10 15:51:35 -0700 | [diff] [blame] | 241 | |
| 242 | releaseLeashes(); |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 243 | } |
| 244 | |
Adrian Roos | 5d557ed | 2020-03-17 20:04:35 +0100 | [diff] [blame] | 245 | @Override |
| 246 | public boolean isFinished() { |
| 247 | return mFinished; |
| 248 | } |
| 249 | |
| 250 | @Override |
Jorim Jaggi | 3182ef1 | 2020-01-30 00:16:18 +0100 | [diff] [blame] | 251 | public boolean isCancelled() { |
| 252 | return mCancelled; |
| 253 | } |
| 254 | |
Jorim Jaggi | 6d5c801 | 2020-02-28 01:40:27 +0100 | [diff] [blame] | 255 | @Override |
| 256 | public WindowInsetsAnimation getAnimation() { |
Jorim Jaggi | 5ed50cc | 2019-01-23 16:59:42 +0100 | [diff] [blame] | 257 | return mAnimation; |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 258 | } |
| 259 | |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 260 | WindowInsetsAnimationControlListener getListener() { |
| 261 | return mListener; |
| 262 | } |
| 263 | |
Jorim Jaggi | 6d5c801 | 2020-02-28 01:40:27 +0100 | [diff] [blame] | 264 | SparseArray<InsetsSourceControl> getControls() { |
| 265 | return mControls; |
| 266 | } |
| 267 | |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 268 | private Insets calculateInsets(InsetsState state, Rect frame, |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 269 | SparseArray<InsetsSourceControl> controls, boolean shown, |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 270 | @Nullable @InternalInsetsSide SparseIntArray typeSideMap) { |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 271 | for (int i = controls.size() - 1; i >= 0; i--) { |
| 272 | // control may be null if it got revoked. |
| 273 | if (controls.valueAt(i) == null) continue; |
| 274 | state.getSource(controls.valueAt(i).getType()).setVisible(shown); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 275 | } |
| 276 | return getInsetsFromState(state, frame, typeSideMap); |
| 277 | } |
| 278 | |
| 279 | private Insets getInsetsFromState(InsetsState state, Rect frame, |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 280 | @Nullable @InternalInsetsSide SparseIntArray typeSideMap) { |
Jorim Jaggi | 580aef5 | 2020-02-26 18:28:28 +0100 | [diff] [blame] | 281 | return state.calculateInsets(frame, null /* ignoringVisibilityState */, |
| 282 | false /* isScreenRound */, |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 283 | false /* alwaysConsumeSystemBars */, null /* displayCutout */, |
Jorim Jaggi | 7f76187 | 2020-01-10 18:24:27 +0100 | [diff] [blame] | 284 | LayoutParams.SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode*/, |
| 285 | 0 /* legacySystemUiFlags */, typeSideMap) |
Jorim Jaggi | 73f3e8a | 2019-01-14 13:06:23 +0100 | [diff] [blame] | 286 | .getInsets(mTypes); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 287 | } |
| 288 | |
| 289 | private Insets sanitize(Insets insets) { |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 290 | if (insets == null) { |
| 291 | insets = getCurrentInsets(); |
| 292 | } |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 293 | return Insets.max(Insets.min(insets, mShownInsets), mHiddenInsets); |
| 294 | } |
| 295 | |
Tarandeep Singh | 54554e2 | 2019-11-01 14:43:05 -0700 | [diff] [blame] | 296 | private static float sanitize(float alpha) { |
| 297 | return alpha >= 1 ? 1 : (alpha <= 0 ? 0 : alpha); |
| 298 | } |
| 299 | |
Jorim Jaggi | 580aef5 | 2020-02-26 18:28:28 +0100 | [diff] [blame] | 300 | private void updateLeashesForSide(@InternalInsetsSide int side, int offset, int maxInset, |
| 301 | int inset, ArrayList<SurfaceParams> surfaceParams, InsetsState state, Float alpha) { |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 302 | ArraySet<InsetsSourceControl> items = mSideSourceMap.get(side); |
Jorim Jaggi | 956ca41 | 2019-01-07 14:49:14 +0100 | [diff] [blame] | 303 | if (items == null) { |
| 304 | return; |
| 305 | } |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 306 | // TODO: Implement behavior when inset spans over multiple types |
| 307 | for (int i = items.size() - 1; i >= 0; i--) { |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 308 | final InsetsSourceControl control = items.valueAt(i); |
| 309 | final InsetsSource source = mInitialInsetsState.getSource(control.getType()); |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 310 | final SurfaceControl leash = control.getLeash(); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 311 | |
Tarandeep Singh | 215929b | 2019-01-11 18:24:37 -0800 | [diff] [blame] | 312 | mTmpMatrix.setTranslate(control.getSurfacePosition().x, control.getSurfacePosition().y); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 313 | mTmpFrame.set(source.getFrame()); |
Jorim Jaggi | 6768488 | 2019-01-22 17:36:34 +0100 | [diff] [blame] | 314 | addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 315 | |
Jorim Jaggi | 580aef5 | 2020-02-26 18:28:28 +0100 | [diff] [blame] | 316 | state.getSource(source.getType()).setVisible(side == ISIDE_FLOATING || inset != 0); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 317 | state.getSource(source.getType()).setFrame(mTmpFrame); |
Jorim Jaggi | a12ea56 | 2019-01-07 17:47:47 +0100 | [diff] [blame] | 318 | |
| 319 | // If the system is controlling the insets source, the leash can be null. |
| 320 | if (leash != null) { |
Winson Chung | 7e895da | 2020-02-03 13:28:44 -0800 | [diff] [blame] | 321 | SurfaceParams params = new SurfaceParams.Builder(leash) |
| 322 | .withAlpha(side == ISIDE_FLOATING ? 1 : alpha) |
| 323 | .withMatrix(mTmpMatrix) |
| 324 | .withVisibility(side == ISIDE_FLOATING |
Taran Singh | 0485041 | 2020-03-23 15:04:58 -0700 | [diff] [blame] | 325 | ? mShownOnFinish |
Winson Chung | 7e895da | 2020-02-03 13:28:44 -0800 | [diff] [blame] | 326 | : inset != 0 /* visible */) |
| 327 | .build(); |
| 328 | surfaceParams.add(params); |
Jorim Jaggi | a12ea56 | 2019-01-07 17:47:47 +0100 | [diff] [blame] | 329 | } |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 330 | } |
| 331 | } |
| 332 | |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 333 | private void addTranslationToMatrix(@InternalInsetsSide int side, int inset, Matrix m, |
| 334 | Rect frame) { |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 335 | switch (side) { |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 336 | case ISIDE_LEFT: |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 337 | m.postTranslate(-inset, 0); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 338 | frame.offset(-inset, 0); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 339 | break; |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 340 | case ISIDE_TOP: |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 341 | m.postTranslate(0, -inset); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 342 | frame.offset(0, -inset); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 343 | break; |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 344 | case ISIDE_RIGHT: |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 345 | m.postTranslate(inset, 0); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 346 | frame.offset(inset, 0); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 347 | break; |
Tiger Huang | 332793b | 2019-10-29 23:21:27 +0800 | [diff] [blame] | 348 | case ISIDE_BOTTOM: |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 349 | m.postTranslate(0, inset); |
Jorim Jaggi | 02a741f | 2018-12-12 17:40:19 -0800 | [diff] [blame] | 350 | frame.offset(0, inset); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 351 | break; |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | private static void buildTypeSourcesMap(SparseIntArray typeSideMap, |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 356 | SparseSetArray<InsetsSourceControl> sideSourcesMap, |
| 357 | SparseArray<InsetsSourceControl> controls) { |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 358 | for (int i = typeSideMap.size() - 1; i >= 0; i--) { |
Jorim Jaggi | 956ca41 | 2019-01-07 14:49:14 +0100 | [diff] [blame] | 359 | final int type = typeSideMap.keyAt(i); |
| 360 | final int side = typeSideMap.valueAt(i); |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 361 | final InsetsSourceControl control = controls.get(type); |
| 362 | if (control == null) { |
Jorim Jaggi | 956ca41 | 2019-01-07 14:49:14 +0100 | [diff] [blame] | 363 | // If the types that we are controlling are less than the types that the system has, |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 364 | // there can be some null controllers. |
Jorim Jaggi | 956ca41 | 2019-01-07 14:49:14 +0100 | [diff] [blame] | 365 | continue; |
| 366 | } |
Yunfan Chen | 02abf55 | 2019-12-05 14:51:09 +0900 | [diff] [blame] | 367 | sideSourcesMap.add(side, control); |
Jorim Jaggi | 5bb571d | 2018-11-06 14:42:04 +0100 | [diff] [blame] | 368 | } |
| 369 | } |
| 370 | } |