Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cf1d058 authored by Selim Cinek's avatar Selim Cinek
Browse files

Fixed an issue where the qs panel wasn't properly placed

The QS panel should only be placed below the notifications
if it has notifications above the shelf. This ensures that
all animations including icons are appearing in the right
place.

Test: runtest -x packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
Test: runtest -x packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
Fixes: 35305470
Change-Id: I97fb0c76ed69b7638ce83a7c06856d87bf6bf65f
parent 1581bb0b
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
import com.android.systemui.statusbar.NotificationGuts.GutsContent;
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
import com.android.systemui.statusbar.notification.AboveShelfObserver;
import com.android.systemui.statusbar.notification.HybridNotificationView;
import com.android.systemui.statusbar.notification.NotificationInflater;
import com.android.systemui.statusbar.notification.NotificationUtils;
@@ -162,6 +164,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    private boolean mIsSystemChildExpanded;
    private boolean mIsPinned;
    private FalsingManager mFalsingManager;
    private AboveShelfChangedListener mAboveShelfChangedListener;
    private HeadsUpManager mHeadsUpManager;

    private boolean mJustClicked;
@@ -388,6 +391,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        expandedIcon.setStaticDrawableColor(color);
    }

    public void setAboveShelfChangedListener(AboveShelfChangedListener aboveShelfChangedListener) {
        mAboveShelfChangedListener = aboveShelfChangedListener;
    }

    @Override
    public boolean isDimmable() {
        if (!getShowingLayout().isDimmable()) {
@@ -442,6 +449,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    }

    public void setHeadsUp(boolean isHeadsUp) {
        boolean wasAboveShelf = isAboveShelf();
        int intrinsicBefore = getIntrinsicHeight();
        mIsHeadsUp = isHeadsUp;
        mPrivateLayout.setHeadsUp(isHeadsUp);
@@ -454,6 +462,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        }
        if (isHeadsUp) {
            setAboveShelf(true);
        } else if (isAboveShelf() != wasAboveShelf) {
            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
        }
    }

@@ -634,6 +644,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
     */
    public void setPinned(boolean pinned) {
        int intrinsicHeight = getIntrinsicHeight();
        boolean wasAboveShelf = isAboveShelf();
        mIsPinned = pinned;
        if (intrinsicHeight != getIntrinsicHeight()) {
            notifyHeightChanged(false /* needsAnimation */);
@@ -645,6 +656,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
            setUserExpanded(true);
        }
        setChronometerRunning(mLastChronometerRunning);
        if (isAboveShelf() != wasAboveShelf) {
            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
        }
    }

    public boolean isPinned() {
@@ -993,8 +1007,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    }

    public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
        boolean wasAboveShelf = isAboveShelf();
        mHeadsupDisappearRunning = headsUpAnimatingAway;
        mPrivateLayout.setHeadsUpAnimatingAway(headsUpAnimatingAway);
        if (isAboveShelf() != wasAboveShelf) {
            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
        }
    }

    /**
@@ -1555,6 +1573,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
     */
    public void setOnKeyguard(boolean onKeyguard) {
        if (onKeyguard != mOnKeyguard) {
            boolean wasAboveShelf = isAboveShelf();
            final boolean wasExpanded = isExpanded();
            mOnKeyguard = onKeyguard;
            onExpansionChanged(false /* userAction */, wasExpanded);
@@ -1564,6 +1583,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
                }
                notifyHeightChanged(false /* needsAnimation */);
            }
            if (isAboveShelf() != wasAboveShelf) {
                mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
            }
        }
    }

@@ -2214,7 +2236,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    }

    public void setAboveShelf(boolean aboveShelf) {
        boolean wasAboveShelf = isAboveShelf();
        mAboveShelf = aboveShelf;
        if (isAboveShelf() != wasAboveShelf) {
            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
        }
    }

    public static class NotificationViewState extends ExpandableViewState {
+2 −1
Original line number Diff line number Diff line
@@ -179,7 +179,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
                mShelfState.notGoneIndex = Math.min(mShelfState.notGoneIndex, mNotGoneIndex);
            }
            mShelfState.hasItemsInStableShelf = lastViewState.inShelf;
            mShelfState.hidden = !mAmbientState.isShadeExpanded();
            mShelfState.hidden = !mAmbientState.isShadeExpanded()
                    || mAmbientState.isQsCustomizerShowing();
            mShelfState.maxShelfEnd = maxShelfEnd;
        } else {
            mShelfState.hidden = true;
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.systemui.statusbar.notification;

/**
 * A listener for when the above shelf state of notification changes
 */
public interface AboveShelfChangedListener {

    /**
     * Notifies a listener that the above shelf state changed
     */
    void onAboveShelfStateChanged(boolean aboveShelf);
}
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.systemui.statusbar.notification;

import android.view.View;
import android.view.ViewGroup;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.statusbar.ExpandableNotificationRow;

/**
 * An observer that listens to the above shelf state and can notify listeners
 */
public class AboveShelfObserver implements AboveShelfChangedListener {

    private final ViewGroup mHostLayout;
    private boolean mHasViewsAboveShelf = false;
    private HasViewAboveShelfChangedListener mListener;

    public AboveShelfObserver(ViewGroup hostLayout) {
        mHostLayout = hostLayout;
    }

    public void setListener(HasViewAboveShelfChangedListener listener) {
        mListener = listener;
    }

    @Override
    public void onAboveShelfStateChanged(boolean aboveShelf) {
        boolean hasViewsAboveShelf = aboveShelf;
        if (!hasViewsAboveShelf && mHostLayout != null) {
            int n = mHostLayout.getChildCount();
            for (int i = 0; i < n; i++) {
                View child = mHostLayout.getChildAt(i);
                if (child instanceof ExpandableNotificationRow) {
                    if (((ExpandableNotificationRow) child).isAboveShelf()) {
                        hasViewsAboveShelf = true;
                        break;
                    }
                }
            }
        }
        if (mHasViewsAboveShelf != hasViewsAboveShelf) {
            mHasViewsAboveShelf = hasViewsAboveShelf;
            if (mListener != null) {
                mListener.onHasViewsAboveShelfChanged(hasViewsAboveShelf);
            }
        }
    }

    @VisibleForTesting
    boolean hasViewsAboveShelf() {
        return mHasViewsAboveShelf;
    }

    public interface HasViewAboveShelfChangedListener {
        void onHasViewsAboveShelfChanged(boolean hasViewsAboveShelf);
    }
}
+10 −18
Original line number Diff line number Diff line
@@ -34,18 +34,19 @@ import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.notification.AboveShelfObserver;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;

/**
 * The container with notification stack scroller and quick settings inside.
 */
public class NotificationsQuickSettingsContainer extends FrameLayout
        implements OnInflateListener, FragmentListener, OnHeadsUpChangedListener {
        implements OnInflateListener, FragmentListener,
        AboveShelfObserver.HasViewAboveShelfChangedListener {

    private FrameLayout mQsFrame;
    private View mUserSwitcher;
    private View mStackScroller;
    private NotificationStackScrollLayout mStackScroller;
    private View mKeyguardStatusBar;
    private boolean mInflated;
    private boolean mQsExpanded;
@@ -53,8 +54,7 @@ public class NotificationsQuickSettingsContainer extends FrameLayout

    private int mBottomPadding;
    private int mStackScrollerMargin;
    private boolean mHeadsUp;
    private HeadsUpManager mHeadsUpManager;
    private boolean mHasViewsAboveShelf;

    public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -76,16 +76,12 @@ public class NotificationsQuickSettingsContainer extends FrameLayout
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        FragmentHostManager.get(this).addTagListener(QS.TAG, this);
        mHeadsUpManager = SysUiServiceProvider.getComponent(getContext(), StatusBar.class)
                .mHeadsUpManager;
        mHeadsUpManager.addListener(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        FragmentHostManager.get(this).removeTagListener(QS.TAG, this);
        mHeadsUpManager.removeListener(this);
    }

    @Override
@@ -116,7 +112,7 @@ public class NotificationsQuickSettingsContainer extends FrameLayout
        boolean userSwitcherVisible = mInflated && mUserSwitcher.getVisibility() == View.VISIBLE;
        boolean statusBarVisible = mKeyguardStatusBar.getVisibility() == View.VISIBLE;

        final boolean qsBottom = mHeadsUp;
        final boolean qsBottom = mHasViewsAboveShelf;
        View stackQsTop = qsBottom ? mStackScroller : mQsFrame;
        View stackQsBottom = !qsBottom ? mStackScroller : mQsFrame;
        // Invert the order of the scroll view and user switcher such that the notifications receive
@@ -183,7 +179,7 @@ public class NotificationsQuickSettingsContainer extends FrameLayout
            setPadding(0, 0, 0, mBottomPadding);
            setBottomMargin(mStackScroller, mStackScrollerMargin);
        }

        mStackScroller.setQsCustomizerShowing(isShowing);
    }

    private void setBottomMargin(View v, int bottomMargin) {
@@ -193,12 +189,8 @@ public class NotificationsQuickSettingsContainer extends FrameLayout
    }

    @Override
    public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
        boolean hasHeadsUp = mHeadsUpManager.getAllEntries().size() != 0;
        if (mHeadsUp == hasHeadsUp) {
            return;
        }
        mHeadsUp = hasHeadsUp;
    public void onHasViewsAboveShelfChanged(boolean hasViewsAboveShelf) {
        mHasViewsAboveShelf = hasViewsAboveShelf;
        invalidate();
    }
}
Loading