115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root/*
215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Copyright (C) 2008 The Android Open Source Project
315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * you may not use this file except in compliance with the License.
615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * You may obtain a copy of the License at
715a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
815a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
915a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
1015a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Unless required by applicable law or agreed to in writing, software
1115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
1215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * See the License for the specific language governing permissions and
1415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * limitations under the License.
1515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root */
1615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root
17fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopackage com.android.systemui.statusbar.phone;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Lairdimport static android.content.res.Configuration.ORIENTATION_PORTRAIT;
20058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
216a4fa0ec183e20c32e7816f5475e72fa9126356cAdrian Roosimport static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
226a4fa0ec183e20c32e7816f5475e72fa9126356cAdrian Roos
23058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Lairdimport android.annotation.Nullable;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
25058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Lairdimport android.content.res.Configuration;
2613836059802a945ad073b8046a928777e474496cAdrian Roosimport android.graphics.Point;
27058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Lairdimport android.graphics.Rect;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
2964161ccb2f3341ebe1675e38a999250c7967d0adChris Wrenimport android.util.EventLog;
3013836059802a945ad073b8046a928777e474496cAdrian Roosimport android.util.Pair;
3113836059802a945ad073b8046a928777e474496cAdrian Roosimport android.view.Display;
32058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Lairdimport android.view.DisplayCutout;
336a4fa0ec183e20c32e7816f5475e72fa9126356cAdrian Roosimport android.view.Gravity;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MotionEvent;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
363e7592d0cbbde5b0b85d98b82d991ee5d2aab8a9Selim Cinekimport android.view.ViewGroup;
37edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roosimport android.view.WindowInsets;
386179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
39058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Lairdimport android.widget.FrameLayout;
40058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Lairdimport android.widget.LinearLayout;
4113836059802a945ad073b8046a928777e474496cAdrian Roos
42aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monkimport com.android.systemui.Dependency;
4364161ccb2f3341ebe1675e38a999250c7967d0adChris Wrenimport com.android.systemui.EventLogTags;
443e7592d0cbbde5b0b85d98b82d991ee5d2aab8a9Selim Cinekimport com.android.systemui.R;
45aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monkimport com.android.systemui.statusbar.policy.DarkIconDispatcher;
46aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monkimport com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
47edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos
48edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roosimport java.util.Objects;
4979de0c550037a5328bbc7f4fddaf02f192a5c283Joe Onorato
5008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandlerpublic class PhoneStatusBarView extends PanelBar {
51fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    private static final String TAG = "PhoneStatusBarView";
522a6ea9c2a1b52b0386270ec73e1e6d6a9b614a34Jason Monk    private static final boolean DEBUG = StatusBar.DEBUG;
53934025e8d79975444d8b93cf6a18c7d98760b3adChristoph Studer    private static final boolean DEBUG_GESTURES = false;
54058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    private static final int NO_VALUE = Integer.MIN_VALUE;
55198a0306e5b0ef6b02d61e299a4b4ab4c1c2cdc8Daniel Sandler
562a6ea9c2a1b52b0386270ec73e1e6d6a9b614a34Jason Monk    StatusBar mBar;
575a8aefa6c8ab2f129bc6477a49cd0876ec5d72faDaniel Sandler
589f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen    boolean mIsFullyOpenedPanel = false;
597edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    private final PhoneStatusBarTransitions mBarTransitions;
60ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private ScrimController mScrimController;
613d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    private float mMinFraction;
623d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    private float mPanelFraction;
6380c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek    private Runnable mHideExpandedRunnable = new Runnable() {
6480c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek        @Override
6580c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek        public void run() {
66529c5325f0e5cd3cf97fd7431d8dc9e79d7a627fSelim Cinek            if (mPanelFraction == 0.0f) {
67529c5325f0e5cd3cf97fd7431d8dc9e79d7a627fSelim Cinek                mBar.makeExpandedInvisible();
68529c5325f0e5cd3cf97fd7431d8dc9e79d7a627fSelim Cinek            }
6980c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek        }
7080c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek    };
71aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk    private DarkReceiver mBattery;
72058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    private int mLastOrientation;
73cda685dbe377639b2bc3051bac37e7cb0778e2a3Evan Laird    @Nullable
74058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    private View mCutoutSpace;
75058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    @Nullable
76058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    private DisplayCutout mDisplayCutout;
7717a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird    /**
7817a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird     * Draw this many pixels into the left/right side of the cutout to optimally use the space
7917a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird     */
8017a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird    private int mCutoutSideNudge = 0;
81119a4015f0f7ac1f63d596da158768f880f9fe9bJoe Onorato
82fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    public PhoneStatusBarView(Context context, AttributeSet attrs) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs);
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
857edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        mBarTransitions = new PhoneStatusBarTransitions(this);
86e932e30eadb5978591316ffe3d21d60604c0cd91John Spurlock    }
87e932e30eadb5978591316ffe3d21d60604c0cd91John Spurlock
88e932e30eadb5978591316ffe3d21d60604c0cd91John Spurlock    public BarTransitions getBarTransitions() {
89e932e30eadb5978591316ffe3d21d60604c0cd91John Spurlock        return mBarTransitions;
901c1edaa5f127d814058271ee4827fc0fe4a8de44Daniel Sandler    }
911c1edaa5f127d814058271ee4827fc0fe4a8de44Daniel Sandler
922a6ea9c2a1b52b0386270ec73e1e6d6a9b614a34Jason Monk    public void setBar(StatusBar bar) {
93efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler        mBar = bar;
94efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler    }
95efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler
96ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public void setScrimController(ScrimController scrimController) {
97ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mScrimController = scrimController;
98ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
99ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
100efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler    @Override
101acea100015dffbb77d137b0681d6c34992e72ae9Jorim Jaggi    public void onFinishInflate() {
102e6f0a716501e57616c8e1d809c0f60b08d21eb0aJohn Spurlock        mBarTransitions.init();
10351efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        mBattery = findViewById(R.id.battery);
104058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        mCutoutSpace = findViewById(R.id.cutout_space_view);
10517a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird
10617a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird        updateResources();
107aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk    }
108aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk
109aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk    @Override
110aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk    protected void onAttachedToWindow() {
111aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk        super.onAttachedToWindow();
112aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk        // Always have Battery meters in the status bar observe the dark/light modes.
113aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk        Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mBattery);
114058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        if (updateOrientationAndCutout(getResources().getConfiguration().orientation)) {
115edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos            updateLayoutForCutout();
116058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        }
117aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk    }
118aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk
119aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk    @Override
120aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk    protected void onDetachedFromWindow() {
121aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk        super.onDetachedFromWindow();
122aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk        Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mBattery);
123058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        mDisplayCutout = null;
124058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    }
125058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
126058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    @Override
127058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    protected void onConfigurationChanged(Configuration newConfig) {
128058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        super.onConfigurationChanged(newConfig);
129058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
130058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        // May trigger cutout space layout-ing
131058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        if (updateOrientationAndCutout(newConfig.orientation)) {
132edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos            updateLayoutForCutout();
133edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos            requestLayout();
134edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos        }
135edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos    }
136edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos
137edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos    @Override
138edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
139edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos        if (updateOrientationAndCutout(mLastOrientation)) {
140edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos            updateLayoutForCutout();
141edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos            requestLayout();
142058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        }
143edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos        return super.onApplyWindowInsets(insets);
144058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    }
145058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
146058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    /**
147058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird     *
148058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird     * @param newOrientation may pass NO_VALUE for no change
149058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird     * @return boolean indicating if we need to update the cutout location / margins
150058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird     */
151058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    private boolean updateOrientationAndCutout(int newOrientation) {
152058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        boolean changed = false;
153058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        if (newOrientation != NO_VALUE) {
154058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird            if (mLastOrientation != newOrientation) {
155058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird                changed = true;
156058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird                mLastOrientation = newOrientation;
157058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird            }
158058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        }
159058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
160edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos        if (!Objects.equals(getRootWindowInsets().getDisplayCutout(), mDisplayCutout)) {
161edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos            changed = true;
162edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos            mDisplayCutout = getRootWindowInsets().getDisplayCutout();
163058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        }
164058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
165058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        return changed;
166efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler    }
167efb0faf1c043777762eecfef87ec575632c365e1Daniel Sandler
1681c1edaa5f127d814058271ee4827fc0fe4a8de44Daniel Sandler    @Override
1699f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen    public boolean panelEnabled() {
1709764218ff979f735aee2f1189e3547d5f3b02f83John Spurlock        return mBar.panelsEnabled();
1711e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler    }
1721e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler
1731e8feef1faca7d2f14bf459691dbe724c8cf5c88Daniel Sandler    @Override
174a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
1755b0467522c8fd2e17d688e04ec592bdba9f2f012Alan Viverette        if (super.onRequestSendAccessibilityEventInternal(child, event)) {
17608d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            // The status bar is very small so augment the view that the user is touching
17708d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            // with the content of the status bar a whole. This way an accessibility service
17808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            // may announce the current item as well as the entire content if appropriate.
17908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            AccessibilityEvent record = AccessibilityEvent.obtain();
18008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            onInitializeAccessibilityEvent(record);
18108d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            dispatchPopulateAccessibilityEvent(record);
18208d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            event.appendRecord(record);
18308d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler            return true;
184d49258fed489bcd72a2b2a6ce3a3c38d4b2531e6Dianne Hackborn        }
18508d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        return false;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
18908d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler    public void onPanelPeeked() {
19008d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        super.onPanelPeeked();
191fa505a7f26bdf685c701e92b481602eb59d7ff56Jorim Jaggi        mBar.makeExpandedVisible(false);
19267eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler    }
19367eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler
19467eab79051eea2d4f8fda4a2a698900ffacfb557Daniel Sandler    @Override
1959f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen    public void onPanelCollapsed() {
1969f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen        super.onPanelCollapsed();
1972580a976ec93a01ed00fae51364ad872bc591d95Jorim Jaggi        // Close the status bar in the next frame so we can show the end of the animation.
19845e2d8faed70252f8c5535ed9dee903b45f60ac1Jorim Jaggi        post(mHideExpandedRunnable);
1999f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen        mIsFullyOpenedPanel = false;
2008e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler    }
2018e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler
20280c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek    public void removePendingHideExpandedRunnables() {
20345e2d8faed70252f8c5535ed9dee903b45f60ac1Jorim Jaggi        removeCallbacks(mHideExpandedRunnable);
20480c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek    }
20580c2abe5bb896bd31509b201428208dd4fce8c76Selim Cinek
2068e72c9e19cfb0b6c1463fa841f1dd02be8f3b4e1Daniel Sandler    @Override
2079f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen    public void onPanelFullyOpened() {
2089f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen        super.onPanelFullyOpened();
2099f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen        if (!mIsFullyOpenedPanel) {
2109f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen            mPanel.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
211bac221ff0b9e1406f95f23c9a5c3b580ece10eabCasey Burkhardt        }
2129f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen        mIsFullyOpenedPanel = true;
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onTouchEvent(MotionEvent event) {
21764161ccb2f3341ebe1675e38a999250c7967d0adChris Wren        boolean barConsumedEvent = mBar.interceptTouchEvent(event);
21864161ccb2f3341ebe1675e38a999250c7967d0adChris Wren
21964161ccb2f3341ebe1675e38a999250c7967d0adChris Wren        if (DEBUG_GESTURES) {
22064161ccb2f3341ebe1675e38a999250c7967d0adChris Wren            if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
22164161ccb2f3341ebe1675e38a999250c7967d0adChris Wren                EventLog.writeEvent(EventLogTags.SYSUI_PANELBAR_TOUCH,
22264161ccb2f3341ebe1675e38a999250c7967d0adChris Wren                        event.getActionMasked(), (int) event.getX(), (int) event.getY(),
22364161ccb2f3341ebe1675e38a999250c7967d0adChris Wren                        barConsumedEvent ? 1 : 0);
22464161ccb2f3341ebe1675e38a999250c7967d0adChris Wren            }
22564161ccb2f3341ebe1675e38a999250c7967d0adChris Wren        }
22664161ccb2f3341ebe1675e38a999250c7967d0adChris Wren
22764161ccb2f3341ebe1675e38a999250c7967d0adChris Wren        return barConsumedEvent || super.onTouchEvent(event);
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2319f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen    public void onTrackingStarted() {
2329f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen        super.onTrackingStarted();
233e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi        mBar.onTrackingStarted();
234ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mScrimController.onTrackingStarted();
235529c5325f0e5cd3cf97fd7431d8dc9e79d7a627fSelim Cinek        removePendingHideExpandedRunnables();
236e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi    }
237e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi
238e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi    @Override
239dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek    public void onClosingFinished() {
240dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek        super.onClosingFinished();
241dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek        mBar.onClosingFinished();
242dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek    }
243dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek
244dbbcfbe8aea1944fc0b0ecbf531034bcd5b5770aSelim Cinek    @Override
2459f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen    public void onTrackingStopped(boolean expand) {
2469f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen        super.onTrackingStopped(expand);
2472fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi        mBar.onTrackingStopped(expand);
2482fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi    }
2492fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi
2502fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi    @Override
2512fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi    public void onExpandingFinished() {
2522fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi        super.onExpandingFinished();
2532fbad7b6a724cf0a5b98b66fe639d58f5ab10af3Jorim Jaggi        mScrimController.onExpandingFinished();
254e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi    }
255e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi
256e70d31f48d1c123544eb5e72b7b007d81ae8d8c9Jorim Jaggi    @Override
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onInterceptTouchEvent(MotionEvent event) {
25808d05e3d1d6ade6924266296033981a96b47d5fbDaniel Sandler        return mBar.interceptTouchEvent(event) || super.onInterceptTouchEvent(event);
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2616179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov    @Override
2623d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    public void panelScrimMinFractionChanged(float minFraction) {
2633d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        if (mMinFraction != minFraction) {
2643d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek            mMinFraction = minFraction;
2653d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek            updateScrimFraction();
2663d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        }
2673d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    }
2683d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek
2693d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    @Override
2709f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen    public void panelExpansionChanged(float frac, boolean expanded) {
2719f96711e1adf4a28f961c440da1626ad40c03bc8Xiaohui Chen        super.panelExpansionChanged(frac, expanded);
2723d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        mPanelFraction = frac;
2733d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        updateScrimFraction();
27478f88d10ba61ebe25457aaeefc88b8a2460998e4Matthew Ng        if ((frac == 0 || frac == 1) && mBar.getNavigationBarView() != null) {
27578f88d10ba61ebe25457aaeefc88b8a2460998e4Matthew Ng            mBar.getNavigationBarView().onPanelExpandedChange(expanded);
27678f88d10ba61ebe25457aaeefc88b8a2460998e4Matthew Ng        }
2773d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    }
2783d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek
2793d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek    private void updateScrimFraction() {
280ae76b4c2f71ee6c2ad5f8d5c266f0addaf487f20Selim Cinek        float scrimFraction = mPanelFraction;
281ae76b4c2f71ee6c2ad5f8d5c266f0addaf487f20Selim Cinek        if (mMinFraction < 1.0f) {
282ae76b4c2f71ee6c2ad5f8d5c266f0addaf487f20Selim Cinek            scrimFraction = Math.max((mPanelFraction - mMinFraction) / (1.0f - mMinFraction),
283ae76b4c2f71ee6c2ad5f8d5c266f0addaf487f20Selim Cinek                    0);
284ae76b4c2f71ee6c2ad5f8d5c266f0addaf487f20Selim Cinek        }
2853d395c69fa67732ceb2c045d03ea81efa3710afaSelim Cinek        mScrimController.setPanelExpansion(scrimFraction);
2866179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov    }
2873e7592d0cbbde5b0b85d98b82d991ee5d2aab8a9Selim Cinek
28822af65082cd9faf7bd689097b87626e6929ab5b0Adrian Roos    public void updateResources() {
28917a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird        mCutoutSideNudge = getResources().getDimensionPixelSize(
29017a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird                R.dimen.display_cutout_margin_consumption);
29117a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird
2923e7592d0cbbde5b0b85d98b82d991ee5d2aab8a9Selim Cinek        ViewGroup.LayoutParams layoutParams = getLayoutParams();
2933e7592d0cbbde5b0b85d98b82d991ee5d2aab8a9Selim Cinek        layoutParams.height = getResources().getDimensionPixelSize(
2943e7592d0cbbde5b0b85d98b82d991ee5d2aab8a9Selim Cinek                R.dimen.status_bar_height);
2953e7592d0cbbde5b0b85d98b82d991ee5d2aab8a9Selim Cinek        setLayoutParams(layoutParams);
2963e7592d0cbbde5b0b85d98b82d991ee5d2aab8a9Selim Cinek    }
297058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
298058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    private void updateLayoutForCutout() {
29913836059802a945ad073b8046a928777e474496cAdrian Roos        Pair<Integer, Integer> cornerCutoutMargins = cornerCutoutMargins(mDisplayCutout,
30013836059802a945ad073b8046a928777e474496cAdrian Roos                getDisplay());
30113836059802a945ad073b8046a928777e474496cAdrian Roos        updateCutoutLocation(cornerCutoutMargins);
30213836059802a945ad073b8046a928777e474496cAdrian Roos        updateSafeInsets(cornerCutoutMargins);
303058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    }
304058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
30513836059802a945ad073b8046a928777e474496cAdrian Roos    private void updateCutoutLocation(Pair<Integer, Integer> cornerCutoutMargins) {
306cda685dbe377639b2bc3051bac37e7cb0778e2a3Evan Laird        // Not all layouts have a cutout (e.g., Car)
307cda685dbe377639b2bc3051bac37e7cb0778e2a3Evan Laird        if (mCutoutSpace == null) {
308cda685dbe377639b2bc3051bac37e7cb0778e2a3Evan Laird            return;
309cda685dbe377639b2bc3051bac37e7cb0778e2a3Evan Laird        }
310cda685dbe377639b2bc3051bac37e7cb0778e2a3Evan Laird
311058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        if (mDisplayCutout == null || mDisplayCutout.isEmpty()
31213836059802a945ad073b8046a928777e474496cAdrian Roos                    || mLastOrientation != ORIENTATION_PORTRAIT || cornerCutoutMargins != null) {
313058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird            mCutoutSpace.setVisibility(View.GONE);
314058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird            return;
315058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        }
316058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
317058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        mCutoutSpace.setVisibility(View.VISIBLE);
318058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mCutoutSpace.getLayoutParams();
3196a4fa0ec183e20c32e7816f5475e72fa9126356cAdrian Roos
3206a4fa0ec183e20c32e7816f5475e72fa9126356cAdrian Roos        Rect bounds = new Rect();
3216a4fa0ec183e20c32e7816f5475e72fa9126356cAdrian Roos        boundsFromDirection(mDisplayCutout, Gravity.TOP, bounds);
3226a4fa0ec183e20c32e7816f5475e72fa9126356cAdrian Roos
32317a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird        bounds.left = bounds.left + mCutoutSideNudge;
32417a96ba564afe9b45cfd2fe99d068e1c59d24b0dEvan Laird        bounds.right = bounds.right - mCutoutSideNudge;
3256a4fa0ec183e20c32e7816f5475e72fa9126356cAdrian Roos        lp.width = bounds.width();
3266a4fa0ec183e20c32e7816f5475e72fa9126356cAdrian Roos        lp.height = bounds.height();
327058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    }
328058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
32913836059802a945ad073b8046a928777e474496cAdrian Roos    private void updateSafeInsets(Pair<Integer, Integer> cornerCutoutMargins) {
330058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        // Depending on our rotation, we may have to work around a cutout in the middle of the view,
331058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        // or letterboxing from the right or left sides.
332058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
333058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
334edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos        if (mDisplayCutout == null) {
335058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird            lp.leftMargin = 0;
336058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird            lp.rightMargin = 0;
337058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird            return;
338058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird        }
339058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird
340edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos        lp.leftMargin = mDisplayCutout.getSafeInsetLeft();
341edfab3b8327326d6926b417981648f27f00eb0fdAdrian Roos        lp.rightMargin = mDisplayCutout.getSafeInsetRight();
34213836059802a945ad073b8046a928777e474496cAdrian Roos
34313836059802a945ad073b8046a928777e474496cAdrian Roos        if (cornerCutoutMargins != null) {
34413836059802a945ad073b8046a928777e474496cAdrian Roos            lp.leftMargin = Math.max(lp.leftMargin, cornerCutoutMargins.first);
34513836059802a945ad073b8046a928777e474496cAdrian Roos            lp.rightMargin = Math.max(lp.rightMargin, cornerCutoutMargins.second);
3468bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird
3478bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird            // If we're already inset enough (e.g. on the status bar side), we can have 0 margin
3488bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird            WindowInsets insets = getRootWindowInsets();
3498bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird            int leftInset = insets.getSystemWindowInsetLeft();
3508bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird            int rightInset = insets.getSystemWindowInsetRight();
3518bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird            if (lp.leftMargin <= leftInset) {
3528bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird                lp.leftMargin = 0;
3538bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird            }
3548bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird            if (lp.rightMargin <= rightInset) {
3558bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird                lp.rightMargin = 0;
3568bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird            }
3578bd70cb7583b3ee0505e8f562b9a468f28f4dbffEvan Laird
35813836059802a945ad073b8046a928777e474496cAdrian Roos        }
35913836059802a945ad073b8046a928777e474496cAdrian Roos    }
36013836059802a945ad073b8046a928777e474496cAdrian Roos
36113836059802a945ad073b8046a928777e474496cAdrian Roos    public static Pair<Integer, Integer> cornerCutoutMargins(DisplayCutout cutout,
36213836059802a945ad073b8046a928777e474496cAdrian Roos            Display display) {
36313836059802a945ad073b8046a928777e474496cAdrian Roos        if (cutout == null) {
36413836059802a945ad073b8046a928777e474496cAdrian Roos            return null;
36513836059802a945ad073b8046a928777e474496cAdrian Roos        }
36613836059802a945ad073b8046a928777e474496cAdrian Roos        Point size = new Point();
36713836059802a945ad073b8046a928777e474496cAdrian Roos        display.getRealSize(size);
36813836059802a945ad073b8046a928777e474496cAdrian Roos
36913836059802a945ad073b8046a928777e474496cAdrian Roos        Rect bounds = new Rect();
37013836059802a945ad073b8046a928777e474496cAdrian Roos        boundsFromDirection(cutout, Gravity.TOP, bounds);
37113836059802a945ad073b8046a928777e474496cAdrian Roos
37213836059802a945ad073b8046a928777e474496cAdrian Roos        if (bounds.left <= 0) {
37313836059802a945ad073b8046a928777e474496cAdrian Roos            return new Pair<>(bounds.right, 0);
37413836059802a945ad073b8046a928777e474496cAdrian Roos        }
37513836059802a945ad073b8046a928777e474496cAdrian Roos        if (bounds.right >= size.x) {
37613836059802a945ad073b8046a928777e474496cAdrian Roos            return new Pair<>(0, size.x - bounds.left);
37713836059802a945ad073b8046a928777e474496cAdrian Roos        }
37813836059802a945ad073b8046a928777e474496cAdrian Roos        return null;
379058c8aee39927bc9f0df35e0274e7aede59d8b56Evan Laird    }
3806179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov}
381