ExpandableNotificationRow.java revision 8fc93c90839e5d9dd52bca9dd97c198c0fe68af1
151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren/*
251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren * Copyright (C) 2013 The Android Open Source Project
351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren *
451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren * Licensed under the Apache License, Version 2.0 (the "License");
551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren * you may not use this file except in compliance with the License.
651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren * You may obtain a copy of the License at
751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren *
851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren *      http://www.apache.org/licenses/LICENSE-2.0
951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren *
1051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren * Unless required by applicable law or agreed to in writing, software
1151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren * distributed under the License is distributed on an "AS IS" BASIS,
1251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren * See the License for the specific language governing permissions and
1451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren * limitations under the License.
1551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren */
1651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenpackage com.android.systemui.statusbar;
1851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
19a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinekimport android.app.Notification;
2051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenimport android.content.Context;
21cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.AnimatedVectorDrawable;
22cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.AnimationDrawable;
23b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport android.graphics.drawable.ColorDrawable;
24cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.Drawable;
25b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggiimport android.service.notification.StatusBarNotification;
2651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenimport android.util.AttributeSet;
271a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinekimport android.view.MotionEvent;
28eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinekimport android.view.NotificationHeaderView;
29a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport android.view.View;
30b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggiimport android.view.ViewStub;
31fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggiimport android.view.accessibility.AccessibilityEvent;
32b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport android.view.animation.LinearInterpolator;
3398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinekimport android.widget.Chronometer;
34cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.widget.ImageView;
35eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinekimport android.widget.RemoteViews;
36b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
37a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport com.android.systemui.R;
380e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport com.android.systemui.classifier.FalsingManager;
39b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.phone.NotificationGroupManager;
40b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.NotificationChildrenContainer;
41b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackScrollState;
42b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackStateAnimator;
43b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackViewState;
44b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
45b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport java.util.List;
46a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
474222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggipublic class ExpandableNotificationRow extends ActivatableNotificationView {
48b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
49b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
50b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int COLORED_DIVIDER_ALPHA = 0x7B;
51b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private final LinearInterpolator mLinearInterpolator = new LinearInterpolator();
521685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mRowMinHeight;
5351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
541685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Does this row contain layouts that can adapt to row expansion */
5551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mExpandable;
561685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Has the user actively changed the expansion state of this row */
571685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mHasUserChangedExpansion;
581685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
5951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserExpanded;
601685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Is the user touching this row */
6151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserLocked;
621685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Are we showing the "public" version */
63a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    private boolean mShowingPublic;
64ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mSensitive;
65ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mShowingPublicInitialized;
6660122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek    private boolean mHideSensitiveForIntrinsicHeight;
6751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
681685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
691685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Is this notification expanded by the system. The expansion state can be overridden by the
701685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * user expansion.
711685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
721685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mIsSystemExpanded;
73dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
74dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
7583bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * Whether the notification is on the keyguard and the expansion is disabled.
76dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
7783bc78338437a460076a4b5778ded38440ac3501Selim Cinek    private boolean mOnKeyguard;
78dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
79be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPublicLayout;
80be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPrivateLayout;
811685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mMaxExpandHeight;
828d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private int mHeadsUpHeight;
83863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek    private View mVetoButton;
840d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    private boolean mClearable;
8578403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private ExpansionLogger mLogger;
8678403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private String mLoggingKey;
87a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek    private boolean mWasReset;
888d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private NotificationGuts mGuts;
89b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    private StatusBarNotification mStatusBarNotification;
901a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    private boolean mIsHeadsUp;
9198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private boolean mLastChronometerRunning = true;
92eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    private NotificationHeaderView mNotificationHeader;
93b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private ViewStub mChildrenContainerStub;
94b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationGroupManager mGroupManager;
95b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mChildrenExpanded;
96263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private boolean mIsSummaryWithChildren;
97b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationChildrenContainer mChildrenContainer;
98ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    private ViewStub mGutsStub;
99b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mIsSystemChildExpanded;
100684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    private boolean mIsPinned;
1010e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski    private FalsingManager mFalsingManager;
102b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
1035eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    private boolean mJustClicked;
10434d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    private boolean mShowNoBackground;
105388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    private ExpandableNotificationRow mNotificationParent;
106eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    private OnClickListener mExpandClickListener = new OnClickListener() {
107eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        @Override
108eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        public void onClick(View v) {
109eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            if (mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
110eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                mGroupManager.toggleGroupExpansion(mStatusBarNotification);
111eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            } else {
112eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                setUserExpanded(!isExpanded());
113eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                notifyHeightChanged(true);
114eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
115eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        }
116eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    };
1175eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
1188d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPrivateLayout() {
1198d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPrivateLayout;
1208d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
1218d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
1228d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPublicLayout() {
1238d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPublicLayout;
1248d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
1258d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
126cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    public void setIconAnimationRunning(boolean running) {
127cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        setIconAnimationRunning(running, mPublicLayout);
128cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        setIconAnimationRunning(running, mPrivateLayout);
129cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
130cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
131cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunning(boolean running, NotificationContentView layout) {
132cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (layout != null) {
133cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View contractedChild = layout.getContractedChild();
134cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View expandedChild = layout.getExpandedChild();
1358d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
136cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, contractedChild);
137cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, expandedChild);
1388d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            setIconAnimationRunningForChild(running, headsUpChild);
139cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
140cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
141cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
142cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunningForChild(boolean running, View child) {
143cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (child != null) {
144cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView icon = (ImageView) child.findViewById(com.android.internal.R.id.icon);
145cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(icon, running);
146cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView rightIcon = (ImageView) child.findViewById(
147cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    com.android.internal.R.id.right_icon);
148cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(rightIcon, running);
149cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
150cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
151cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
152cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconRunning(ImageView imageView, boolean running) {
153cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (imageView != null) {
154cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            Drawable drawable = imageView.getDrawable();
155cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            if (drawable instanceof AnimationDrawable) {
156cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
157cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
158cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
159cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
160cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
161cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
162cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            } else if (drawable instanceof AnimatedVectorDrawable) {
163cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimatedVectorDrawable animationDrawable = (AnimatedVectorDrawable) drawable;
164cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
165cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
166cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
167cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
168cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
169cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            }
170cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
171cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
172cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
1738fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek    public void updateStatusBarNotification(StatusBarNotification statusBarNotification) {
174b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        mStatusBarNotification = statusBarNotification;
1758fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        mPrivateLayout.onNotificationUpdated(statusBarNotification);
1768fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        mPublicLayout.onNotificationUpdated(statusBarNotification);
177a37774f098a5204947ff4b4787c4b753bb9016dbSelim Cinek        updateVetoButton();
1788fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        if (mIsSummaryWithChildren) {
1798fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek            recreateNotificationHeader();
1808fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        }
181263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
182b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
183b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
184b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    public StatusBarNotification getStatusBarNotification() {
185b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        return mStatusBarNotification;
186b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
187b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
188b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    public boolean isHeadsUp() {
189b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek        return mIsHeadsUp;
190b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
191b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
1921a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    public void setHeadsUp(boolean isHeadsUp) {
193c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        int intrinsicBefore = getIntrinsicHeight();
1941a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mIsHeadsUp = isHeadsUp;
1958d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mPrivateLayout.setHeadsUp(isHeadsUp);
196c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
197c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek            notifyHeightChanged(false  /* needsAnimation */);
198c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        }
1991a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    }
2001a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek
201b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setGroupManager(NotificationGroupManager groupManager) {
202b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mGroupManager = groupManager;
20383bc78338437a460076a4b5778ded38440ac3501Selim Cinek        mPrivateLayout.setGroupManager(groupManager);
204b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
205b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
206b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row) {
207b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        addChildNotification(row, -1);
208b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
209b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
210b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
211b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Add a child notification to this view.
212b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
213b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param row the row to add
214b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childIndex the index to add it at, if -1 it will be added at the end
215b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
216b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row, int childIndex) {
217b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer == null) {
218b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainerStub.inflate();
219b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
220b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainer.addNotification(row, childIndex);
221263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
222263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(true, this);
223b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
224b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
225b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void removeChildNotification(ExpandableNotificationRow row) {
226b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer != null) {
227b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.removeNotification(row);
228b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
229263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
230263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(false, null);
231263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
232263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
233263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isChildInGroup() {
234a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        return mNotificationParent != null;
235263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
236263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
237388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public ExpandableNotificationRow getNotificationParent() {
238388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        return mNotificationParent;
239388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
240388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
241263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    /**
242263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param isChildInGroup Is this notification now in a group
243263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param parent the new parent notification
244263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     */
245a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {;
246a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        boolean childInGroup = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
247a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mNotificationParent = childInGroup ? parent : null;
248a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mPrivateLayout.setIsChildInGroup(childInGroup);
249a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateNoBackgroundState();
25034d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    }
25134d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek
25234d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    @Override
25334d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    protected boolean shouldHideBackground() {
25434d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek        return super.shouldHideBackground() || mShowNoBackground;
255263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
256263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
257263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    @Override
258263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isSummaryWithChildren() {
259263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        return mIsSummaryWithChildren;
260b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
261b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
262b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    @Override
263b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public boolean areChildrenExpanded() {
264b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenExpanded;
265b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
266b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
267b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public List<ExpandableNotificationRow> getNotificationChildren() {
268b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenContainer == null ? null : mChildrenContainer.getNotificationChildren();
269b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
270b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
271eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    public int getNumberOfNotificationChildren() {
272eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        if (mChildrenContainer == null) {
273eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek            return 0;
274eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        }
275eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mChildrenContainer.getNotificationChildren().size();
276eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    }
277eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek
278b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
279b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Apply the order given in the list to the children.
280b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
281b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childOrder the new list order
282b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @return whether the list order has changed
283b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
284b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder) {
285b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder);
286b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
287b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
288b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void getChildrenStates(StackScrollState resultState) {
28983bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
290b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            StackViewState parentState = resultState.getViewStateForView(this);
291b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.getState(resultState, parentState);
292b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
293b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
294b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
295b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void applyChildrenState(StackScrollState state) {
29683bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
297b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.applyState(state);
298b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
299b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
300b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
301b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void prepareExpansionChanged(StackScrollState state) {
30283bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
303b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.prepareExpansionChanged(state);
304b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
305b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
306b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
307b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void startChildAnimation(StackScrollState finalState,
308b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            StackStateAnimator stateAnimator, boolean withDelays, long delay, long duration) {
30983bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
310b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.startAnimationToState(finalState, stateAnimator, withDelays, delay,
311b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                    duration);
312b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
313b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
314b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
315b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public ExpandableNotificationRow getViewAtPosition(float y) {
31683bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (!mIsSummaryWithChildren || !mChildrenExpanded) {
317b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return this;
318b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
319b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ExpandableNotificationRow view = mChildrenContainer.getViewAtPosition(y);
320b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return view == null ? this : view;
321b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
322b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
323b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
324ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public NotificationGuts getGuts() {
325ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        return mGuts;
326ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
327ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
328684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    /**
329684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
330684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * the notification will be rendered on top of the screen.
331684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     *
332684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * @param pinned whether it is pinned
333684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     */
334684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public void setPinned(boolean pinned) {
335684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        mIsPinned = pinned;
33698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(mLastChronometerRunning);
337b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
338b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
339684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public boolean isPinned() {
340684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        return mIsPinned;
341b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
342b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
343b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    public int getHeadsUpHeight() {
3448d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mHeadsUpHeight;
345b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
346b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
3475eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
3485eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * Mark whether this notification was just clicked, i.e. the user has just clicked this
3495eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * notification in this frame.
3505eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
3515eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public void setJustClicked(boolean justClicked) {
3525eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        mJustClicked = justClicked;
3535eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
3545eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
3555eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
3565eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * @return true if this notification has been clicked in this frame, false otherwise
3575eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
3585eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public boolean wasJustClicked() {
3595eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        return mJustClicked;
3605eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
3615eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
36298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    public void setChronometerRunning(boolean running) {
36398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        mLastChronometerRunning = running;
36498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPrivateLayout);
36598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPublicLayout);
36698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (mChildrenContainer != null) {
36798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
36898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                    mChildrenContainer.getNotificationChildren();
36998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
37098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
37198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                child.setChronometerRunning(running);
37298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
37398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
37498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
37598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
37698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunning(boolean running, NotificationContentView layout) {
37798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (layout != null) {
37898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            running = running || isPinned();
37998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View contractedChild = layout.getContractedChild();
38098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View expandedChild = layout.getExpandedChild();
38198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
38298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, contractedChild);
38398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, expandedChild);
38498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, headsUpChild);
38598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
38698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
38798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
38898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunningForChild(boolean running, View child) {
38998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (child != null) {
39098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View chronometer = child.findViewById(com.android.internal.R.id.chronometer);
39198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            if (chronometer instanceof Chronometer) {
39298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ((Chronometer) chronometer).setStarted(running);
39398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
39498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
39598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
39698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
3978d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek    public CharSequence getSubText() {
3988d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        Notification notification = mStatusBarNotification.getNotification();
3998d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        CharSequence subText = notification.extras.getCharSequence(Notification.EXTRA_SUMMARY_TEXT);
4008d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        if (subText == null) {
4018d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek            subText = notification.extras.getCharSequence(Notification.EXTRA_SUB_TEXT);
4028d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        }
4038d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        return subText;
4048d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek    }
4058d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek
4068d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek    public void setContentSubTextVisible(boolean visible) {
4078d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        mPrivateLayout.setSubTextVisible(visible);
4088d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek    }
4098d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek
41078403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public interface ExpansionLogger {
41178403d79739605511ea88b653564d81d7bf4bbbaChris Wren        public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
41278403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
4131685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
41451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
41551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        super(context, attrs);
4160e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager = FalsingManager.getInstance(context);
41751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
41851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
419a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    /**
420a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     * Resets this view so it can be re-used for an updated notification.
421a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     */
42222f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer    @Override
423a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    public void reset() {
42422f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer        super.reset();
425a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mRowMinHeight = 0;
42678403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
427379ff8f6b18b236b679a59a2dc14c0baeede3baeSelim Cinek        mMaxViewHeight = 0;
428a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mExpandable = false;
429a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mHasUserChangedExpansion = false;
430a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mUserLocked = false;
431a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mShowingPublic = false;
432ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = false;
433ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = false;
434a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mIsSystemExpanded = false;
43583bc78338437a460076a4b5778ded38440ac3501Selim Cinek        mOnKeyguard = false;
4361a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mPublicLayout.reset(mIsHeadsUp);
4371a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mPrivateLayout.reset(mIsHeadsUp);
43831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        resetHeight();
43931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        logExpansionEvent(false, wasExpanded);
44031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    }
44131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek
44231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public void resetHeight() {
4431a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        if (mIsHeadsUp) {
4441a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek            resetActualHeight();
4451a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        }
446a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mMaxExpandHeight = 0;
4478d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mHeadsUpHeight = 0;
448a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek        mWasReset = true;
44931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        onHeightReset();
4506e28a678c7f9fe2cae5a51bfdbab3071a2d8d0baSelim Cinek        requestLayout();
451a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    }
452a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer
453251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    @Override
4541a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    protected boolean filterMotionEvent(MotionEvent event) {
4551a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        return mIsHeadsUp || super.filterMotionEvent(event);
4561a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    }
4571a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek
4581a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    @Override
459251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    protected void onFinishInflate() {
460251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi        super.onFinishInflate();
461be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
462be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
463eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.setExpandClickListener(mExpandClickListener);
464eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPublicLayout.setExpandClickListener(mExpandClickListener);
465ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub = (ViewStub) findViewById(R.id.notification_guts_stub);
466ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub.setOnInflateListener(new ViewStub.OnInflateListener() {
467b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            @Override
468b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            public void onInflate(ViewStub stub, View inflated) {
469b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts = (NotificationGuts) inflated;
470b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setClipTopAmount(getClipTopAmount());
471b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setActualHeight(getActualHeight());
472ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek                mGutsStub = null;
473b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            }
474b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        });
475b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub = (ViewStub) findViewById(R.id.child_container_stub);
476b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub.setOnInflateListener(new ViewStub.OnInflateListener() {
477b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
478b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            @Override
479b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            public void onInflate(ViewStub stub, View inflated) {
480b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                mChildrenContainer = (NotificationChildrenContainer) inflated;
481388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek                mChildrenContainer.setNotificationParent(ExpandableNotificationRow.this);
482b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            }
483b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        });
484863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek        mVetoButton = findViewById(R.id.veto);
485fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    }
486fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi
487ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public void inflateGuts() {
488ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        if (mGuts == null) {
489ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek            mGutsStub.inflate();
490ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        }
491ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
492ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
493b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private void updateChildrenVisibility(boolean animated) {
494b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer == null) {
495b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return;
496b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
497eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        mChildrenContainer.setVisibility(mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
498eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mNotificationHeader.setVisibility(mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
499eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        mPrivateLayout.setVisibility(!mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
500b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
501b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
502fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    @Override
503a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
504a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        if (super.onRequestSendAccessibilityEventInternal(child, event)) {
505fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // Add a record for the entire layout since its content is somehow small.
506fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // The event comes from a leaf view that is interacted with.
507fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            AccessibilityEvent record = AccessibilityEvent.obtain();
508fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            onInitializeAccessibilityEvent(record);
509fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            dispatchPopulateAccessibilityEvent(record);
510fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            event.appendRecord(record);
511fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            return true;
512fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        }
513fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        return false;
514c5dc0d0cce373fbf292e13633c114a431d747167Jorim Jaggi    }
51551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
516e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    @Override
5174e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    public void setDark(boolean dark, boolean fade, long delay) {
5184e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        super.setDark(dark, fade, delay);
519e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        final NotificationContentView showing = getShowingLayout();
520e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        if (showing != null) {
5214e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            showing.setDark(dark, fade, delay);
522e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        }
523e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    }
524e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock
5251685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
5261685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mRowMinHeight = rowMinHeight;
527379ff8f6b18b236b679a59a2dc14c0baeede3baeSelim Cinek        mMaxViewHeight = rowMaxHeight;
528816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        mPrivateLayout.setSmallHeight(mRowMinHeight);
529816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        mPublicLayout.setSmallHeight(mRowMinHeight);
53051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
53151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
53251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isExpandable() {
533388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
534388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return !mChildrenExpanded;
535388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
53651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mExpandable;
53751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
53851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
53951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setExpandable(boolean expandable) {
54051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mExpandable = expandable;
541eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
54251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
54351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
5441685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
5451685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the user has changed the expansion state
5461685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
5471685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean hasUserChangedExpansion() {
5481685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mHasUserChangedExpansion;
5491685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
5501685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
55151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserExpanded() {
55251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserExpanded;
55351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
55451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
5551685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
5561685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the user
5571685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
5581685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param userExpanded whether the user wants this notification to be expanded
5591685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
56051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserExpanded(boolean userExpanded) {
561388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        setUserExpanded(userExpanded, false /* allowChildExpansion */);
562388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
563388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
564388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    /**
565388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * Set this notification to be expanded by the user
566388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     *
567388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param userExpanded whether the user wants this notification to be expanded
568388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param allowChildExpansion whether a call to this method allows expanding children
569388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     */
570388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) {
5710e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager.setNotificationExpanded();
572388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic && allowChildExpansion) {
573388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            mGroupManager.setGroupExpanded(mStatusBarNotification, userExpanded);
574388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return;
575388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
576a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        if (userExpanded && !mExpandable) return;
57778403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
5781685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mHasUserChangedExpansion = true;
57951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserExpanded = userExpanded;
58078403d79739605511ea88b653564d81d7bf4bbbaChris Wren        logExpansionEvent(true, wasExpanded);
58151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
58251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
583ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    public void resetUserExpansion() {
584ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mHasUserChangedExpansion = false;
585ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mUserExpanded = false;
586ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    }
587ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek
58851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserLocked() {
58951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserLocked;
59051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
59151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
59251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserLocked(boolean userLocked) {
59351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserLocked = userLocked;
59451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
59551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
5961685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
5971685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return has the system set this notification to be expanded
5981685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
5991685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean isSystemExpanded() {
6001685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mIsSystemExpanded;
6011685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
6021685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
6031685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
6041685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the system.
6051685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
6061685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param expand whether the system wants this notification to be expanded.
6071685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
6081685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setSystemExpanded(boolean expand) {
60931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        if (expand != mIsSystemExpanded) {
61031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
61131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            mIsSystemExpanded = expand;
612b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            notifyHeightChanged(false /* needsAnimation */);
61331094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            logExpansionEvent(false, wasExpanded);
61483bc78338437a460076a4b5778ded38440ac3501Selim Cinek            if (mChildrenContainer != null) {
61583bc78338437a460076a4b5778ded38440ac3501Selim Cinek                mChildrenContainer.updateGroupOverflow();
61683bc78338437a460076a4b5778ded38440ac3501Selim Cinek            }
61731094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
618dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    }
619dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
620dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
62183bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * @param onKeyguard whether to prevent notification expansion
622dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
62383bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public void setOnKeyguard(boolean onKeyguard) {
62483bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (onKeyguard != mOnKeyguard) {
62531094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
62683bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mOnKeyguard = onKeyguard;
62731094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            logExpansionEvent(false, wasExpanded);
62831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            if (wasExpanded != isExpanded()) {
629b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                notifyHeightChanged(false  /* needsAnimation */);
63031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            }
63131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
6321685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
6331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
6341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
6350d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     * @return Can the underlying notification be cleared?
6360d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     */
6370d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    public boolean isClearable() {
638a37774f098a5204947ff4b4787c4b753bb9016dbSelim Cinek        return mStatusBarNotification != null && mStatusBarNotification.isClearable();
6390d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
6400d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
6410d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    /**
6421685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Apply an expansion state to the layout.
6431685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
644dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    public void applyExpansionToLayout() {
645dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi        boolean expand = isExpanded();
64651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        if (expand && mExpandable) {
647eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek            setActualHeight(mMaxExpandHeight);
64851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        } else {
649eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek            setActualHeight(mRowMinHeight);
65051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        }
65151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
652a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
6539cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    @Override
6549cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    public int getIntrinsicHeight() {
655be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (isUserLocked()) {
656be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            return getActualHeight();
657be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
6581685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        boolean inExpansionState = isExpanded();
65960122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek        if (mSensitive && mHideSensitiveForIntrinsicHeight) {
66060122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek            return mRowMinHeight;
66183bc78338437a460076a4b5778ded38440ac3501Selim Cinek        } else if (mIsSummaryWithChildren && !mOnKeyguard) {
662eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getIntrinsicHeight();
66360122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek        } else if (mIsHeadsUp) {
6648d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            if (inExpansionState) {
66583bc78338437a460076a4b5778ded38440ac3501Selim Cinek                return Math.max(mMaxExpandHeight, mHeadsUpHeight);
6668d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            } else {
66783bc78338437a460076a4b5778ded38440ac3501Selim Cinek                return Math.max(mRowMinHeight, mHeadsUpHeight);
6688d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            }
669a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        } else if (!inExpansionState || (isChildInGroup() && !isGroupExpanded())) {
67083bc78338437a460076a4b5778ded38440ac3501Selim Cinek            return getMinHeight();
671b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
67283bc78338437a460076a4b5778ded38440ac3501Selim Cinek            return getMaxExpandHeight();
6731685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        }
674b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
6751685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
676eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    private boolean isGroupExpanded() {
677eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mGroupManager.isGroupExpanded(mStatusBarNotification);
678b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
679b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
680eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    /**
681eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek     * @return whether this view has a header on the top of the content
682eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek     */
683eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    private boolean hasNotificationHeader() {
684eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mIsSummaryWithChildren;
6851685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
6861685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
687263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private void onChildrenCountChanged() {
6888fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        mIsSummaryWithChildren = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS
689263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek                && mGroupManager.hasGroupChildren(mStatusBarNotification);
6908fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        if (mIsSummaryWithChildren) {
691eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            if (mChildrenContainer == null) {
692eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                mChildrenContainerStub.inflate();
693eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
6948fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek            if (mNotificationHeader == null) {
695eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                recreateNotificationHeader();
696eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
697263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        }
698eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
699eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        updateHeaderChildCount();
700263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        updateChildrenVisibility(true);
701263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
702263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
7031685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
7041685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Check whether the view state is currently expanded. This is given by the system in {@link
7051685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * #setSystemExpanded(boolean)} and can be overridden by user expansion or
7061685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
7071685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * view can differ from this state, if layout params are modified from outside.
7081685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
7091685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the view state is currently expanded.
7101685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
71183bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public boolean isExpanded() {
71283bc78338437a460076a4b5778ded38440ac3501Selim Cinek        return !mOnKeyguard
713b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                && (!hasUserChangedExpansion() && (isSystemExpanded() || isSystemChildExpanded())
714b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                || isUserExpanded());
715b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
716b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
717b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean isSystemChildExpanded() {
718b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mIsSystemChildExpanded;
719b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
720b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
721b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setSystemChildExpanded(boolean expanded) {
722b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mIsSystemChildExpanded = expanded;
7231685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
7241685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
7251685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    @Override
7261685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
7271685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        super.onLayout(changed, left, top, right, bottom);
728a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek        boolean updateExpandHeight = mMaxExpandHeight == 0 && !mWasReset;
7298d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        updateMaxHeights();
730be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (updateExpandHeight) {
731dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi            applyExpansionToLayout();
732be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
733a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek        mWasReset = false;
7341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
7351685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
7368d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private void updateMaxHeights() {
737d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        int intrinsicBefore = getIntrinsicHeight();
7388d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View expandedChild = mPrivateLayout.getExpandedChild();
7398d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        if (expandedChild == null) {
7408d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            expandedChild = mPrivateLayout.getContractedChild();
7418d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
7428d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mMaxExpandHeight = expandedChild.getHeight();
7438d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View headsUpChild = mPrivateLayout.getHeadsUpChild();
7441f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        if (headsUpChild == null) {
7451f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek            headsUpChild = mPrivateLayout.getContractedChild();
7468d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
7471f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        mHeadsUpHeight = headsUpChild.getHeight();
748d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
749b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            notifyHeightChanged(false  /* needsAnimation */);
750d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        }
751d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek    }
752d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek
753ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setSensitive(boolean sensitive) {
754ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = sensitive;
755ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
756ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
757ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
75860122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek        mHideSensitiveForIntrinsicHeight = hideSensitive;
759ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
760ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
761ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
762ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            long duration) {
763ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        boolean oldShowingPublic = mShowingPublic;
764ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublic = mSensitive && hideSensitive;
765ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
766ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            return;
767ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
768a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
769a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler        // bail out if no public version
7701685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        if (mPublicLayout.getChildCount() == 0) return;
771a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
772ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (!animated) {
773ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.animate().cancel();
774ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.animate().cancel();
775ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setAlpha(1f);
776ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.setAlpha(1f);
777ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
778263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek            mPrivateLayout.setVisibility(!mShowingPublic && !mIsSummaryWithChildren ? View.VISIBLE
779263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek                    : View.INVISIBLE);
780ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        } else {
781ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            animateShowingPublic(delay, duration);
782ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
7830d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
784eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
7850d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        updateVetoButton();
786ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = true;
787ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
788ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
789ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private void animateShowingPublic(long delay, long duration) {
790ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        final View source = mShowingPublic ? mPrivateLayout : mPublicLayout;
791ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        View target = mShowingPublic ? mPublicLayout : mPrivateLayout;
792ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        source.setVisibility(View.VISIBLE);
793ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        target.setVisibility(View.VISIBLE);
794ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        target.setAlpha(0f);
795ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        source.animate().cancel();
796ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        target.animate().cancel();
797ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        source.animate()
798ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .alpha(0f)
799ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .setStartDelay(delay)
800ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .setDuration(duration)
801ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .withEndAction(new Runnable() {
802ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                    @Override
803ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                    public void run() {
804ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                        source.setVisibility(View.INVISIBLE);
805ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                    }
806ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                });
807ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        target.animate()
808ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .alpha(1f)
809ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .setStartDelay(delay)
810ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .setDuration(duration);
8110d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
8120d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
8130d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    private void updateVetoButton() {
8140d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        // public versions cannot be dismissed
8150d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        mVetoButton.setVisibility(isClearable() && !mShowingPublic ? View.VISIBLE : View.GONE);
816a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
817251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi
818b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setChildrenExpanded(boolean expanded, boolean animate) {
819b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenExpanded = expanded;
82083bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mChildrenContainer != null) {
82183bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mChildrenContainer.setChildrenExpanded(expanded);
82283bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
823b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
824b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
825eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    public void updateHeaderChildCount() {
826eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        if (mIsSummaryWithChildren) {
827eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            mNotificationHeader.setChildCount(
828eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                    mChildrenContainer.getNotificationChildren().size());
829b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
830b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
831b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
832b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public static void applyTint(View v, int color) {
833b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        int alpha;
834b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (color != 0) {
835b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = COLORED_DIVIDER_ALPHA;
836b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
837b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            color = 0xff000000;
838b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = DEFAULT_DIVIDER_ALPHA;
839b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
840b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (v.getBackground() instanceof ColorDrawable) {
841b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ColorDrawable background = (ColorDrawable) v.getBackground();
842b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.mutate();
843b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setColor(color);
844b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setAlpha(alpha);
845b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
846b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
847b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
8481685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public int getMaxExpandHeight() {
849b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mMaxExpandHeight;
850a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
851584a7aa62c54bcbd654a6696d4fbb56e124874e7Jorim Jaggi
852be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
8534222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public boolean isContentExpandable() {
8542f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
8552f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.isContentExpandable();
8564222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
8574222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
8584222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
859560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    protected View getContentView() {
860560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek        return getShowingLayout();
861560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    }
862560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek
863560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    @Override
864d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int height, boolean notifyListeners) {
865b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        super.setActualHeight(height, notifyListeners);
866eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        int contentHeight = Math.max(getMinHeight(), height);
867b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mPrivateLayout.setContentHeight(contentHeight);
868b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mPublicLayout.setContentHeight(contentHeight);
869b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
870b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setActualHeight(height);
871b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
872be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        invalidate();
873be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
874be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
875be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
876b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public int getMaxContentHeight() {
87783bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
878eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getMaxContentHeight();
87983bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
8802f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
8812f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.getMaxHeight();
882be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
883be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
884be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
8854222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public int getMinHeight() {
886816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
887816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return showingLayout.getMinHeight();
888816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    }
889816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek
890816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    @Override
891816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    public int getMinExpandHeight() {
89283bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren && !mOnKeyguard) {
893eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getMinHeight();
89483bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
895816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return getMinHeight();
8964222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
8974222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
8984222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
899263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    protected boolean shouldLimitViewHeight() {
900263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        return !mIsSummaryWithChildren;
901263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
902263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
903263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    @Override
904be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
905be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super.setClipTopAmount(clipTopAmount);
906be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout.setClipTopAmount(clipTopAmount);
9072f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        mPublicLayout.setClipTopAmount(clipTopAmount);
908b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
909b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setClipTopAmount(clipTopAmount);
910b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
911be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
912be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
913eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    private void recreateNotificationHeader() {
914eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(),
915eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                getStatusBarNotification().getNotification());
916eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        final RemoteViews header = builder.makeNotificationHeader();
917eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        if (mNotificationHeader == null) {
918eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            mNotificationHeader = (NotificationHeaderView) header.apply(getContext(), this);
919eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            final View expandButton = mNotificationHeader.findViewById(
920eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                    com.android.internal.R.id.expand_button);
921eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            expandButton.setVisibility(VISIBLE);
922eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            mNotificationHeader.setOnClickListener(mExpandClickListener);
923eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            addView(mNotificationHeader);
924eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        } else {
925eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            header.reapply(getContext(), mNotificationHeader);
926eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        }
9278fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        updateHeaderChildCount();
928343e6e258ab6a9f647eabebaed05ce3acafd2ff1Selim Cinek    }
9297d447726e2cb9fae80db417012039828daab8fe7Selim Cinek
93031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public boolean isMaxExpandHeightInitialized() {
93131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        return mMaxExpandHeight != 0;
9327d447726e2cb9fae80db417012039828daab8fe7Selim Cinek    }
9332f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek
9342f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    private NotificationContentView getShowingLayout() {
9352f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return mShowingPublic ? mPublicLayout : mPrivateLayout;
9362f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    }
93778403d79739605511ea88b653564d81d7bf4bbbaChris Wren
93859ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    @Override
93959ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    public void setShowingLegacyBackground(boolean showing) {
94059ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi        super.setShowingLegacyBackground(showing);
94159ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi        mPrivateLayout.setShowingLegacyBackground(showing);
94259ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi        mPublicLayout.setShowingLegacyBackground(showing);
94359ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    }
94459ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi
945a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    @Override
946a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    protected void updateBackgroundTint() {
947a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        super.updateBackgroundTint();
948a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateNoBackgroundState();
949a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        if (mIsSummaryWithChildren) {
950a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
951a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                    mChildrenContainer.getNotificationChildren();
952a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
953a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
954a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                child.updateNoBackgroundState();
955a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            }
956a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        }
957a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
958a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
959a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    private void updateNoBackgroundState() {
960a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mShowNoBackground = isChildInGroup() && hasSameBgColor(mNotificationParent);
961a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateBackground();
962a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
963a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
96478403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public void setExpansionLogger(ExpansionLogger logger, String key) {
96578403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLogger = logger;
96678403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLoggingKey = key;
96778403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
96878403d79739605511ea88b653564d81d7bf4bbbaChris Wren
96978403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private void logExpansionEvent(boolean userAction, boolean wasExpanded) {
97078403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean nowExpanded = isExpanded();
97178403d79739605511ea88b653564d81d7bf4bbbaChris Wren        if (wasExpanded != nowExpanded && mLogger != null) {
97278403d79739605511ea88b653564d81d7bf4bbbaChris Wren            mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded) ;
97378403d79739605511ea88b653564d81d7bf4bbbaChris Wren        }
97478403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
97551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren}
976