ExpandableNotificationRow.java revision 3c76d509d362cf5086a63722ab41e04f5d539182
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
194b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.Animator;
204b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.AnimatorListenerAdapter;
214b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.AnimatorSet;
224b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.ObjectAnimator;
234b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.ValueAnimator;
244b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.ValueAnimator.AnimatorUpdateListener;
25a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinekimport android.app.Notification;
2651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenimport android.content.Context;
27cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.AnimatedVectorDrawable;
28cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.AnimationDrawable;
29b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport android.graphics.drawable.ColorDrawable;
30cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.Drawable;
31da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinekimport android.os.Build;
32b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggiimport android.service.notification.StatusBarNotification;
3351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenimport android.util.AttributeSet;
3401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinekimport android.view.LayoutInflater;
356183d12926a189b08cc3be8d9c78470617e63db0Selim Cinekimport android.view.MotionEvent;
36eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinekimport android.view.NotificationHeaderView;
37a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport android.view.View;
38b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggiimport android.view.ViewStub;
39fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggiimport android.view.accessibility.AccessibilityEvent;
4098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinekimport android.widget.Chronometer;
41cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.widget.ImageView;
42eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinekimport android.widget.RemoteViews;
43b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
44a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport com.android.systemui.R;
450e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport com.android.systemui.classifier.FalsingManager;
460ffbda62e55ad390e05e6c3ff52e1378e420285cSelim Cinekimport com.android.systemui.statusbar.notification.NotificationViewWrapper;
47b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.phone.NotificationGroupManager;
4831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinekimport com.android.systemui.statusbar.policy.HeadsUpManager;
49b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.NotificationChildrenContainer;
50b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackScrollState;
51b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackStateAnimator;
52b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackViewState;
53b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
544b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport java.util.ArrayList;
55b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport java.util.List;
56a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
574222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggipublic class ExpandableNotificationRow extends ActivatableNotificationView {
58b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
59b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
60b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int COLORED_DIVIDER_ALPHA = 0x7B;
6101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMinHeightLegacy;
6201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mMaxHeadsUpHeightLegacy;
6301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mMaxHeadsUpHeight;
6401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMinHeight;
6501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMaxHeight;
6651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
671685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Does this row contain layouts that can adapt to row expansion */
6851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mExpandable;
691685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Has the user actively changed the expansion state of this row */
701685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mHasUserChangedExpansion;
711685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
7251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserExpanded;
7331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek
7431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    /**
7531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * Has this notification been expanded while it was pinned
7631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     */
7731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    private boolean mExpandedWhenPinned;
781685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Is the user touching this row */
7951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserLocked;
801685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Are we showing the "public" version */
81a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    private boolean mShowingPublic;
82ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mSensitive;
833c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek    private boolean mSensitiveHiddenInGeneral;
84ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mShowingPublicInitialized;
8560122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek    private boolean mHideSensitiveForIntrinsicHeight;
8651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
871685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
881685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Is this notification expanded by the system. The expansion state can be overridden by the
891685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * user expansion.
901685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
911685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mIsSystemExpanded;
92dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
93dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
9483bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * Whether the notification is on the keyguard and the expansion is disabled.
95dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
9683bc78338437a460076a4b5778ded38440ac3501Selim Cinek    private boolean mOnKeyguard;
97dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
984b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private AnimatorSet mTranslateAnim;
994b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private ArrayList<View> mTranslateableViews;
100be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPublicLayout;
101be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPrivateLayout;
1021685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mMaxExpandHeight;
1038d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private int mHeadsUpHeight;
104863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek    private View mVetoButton;
1050d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    private boolean mClearable;
10678403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private ExpansionLogger mLogger;
10778403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private String mLoggingKey;
108a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek    private boolean mWasReset;
1094b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private NotificationSettingsIconRow mSettingsIconRow;
1108d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private NotificationGuts mGuts;
111da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private NotificationData.Entry mEntry;
112b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    private StatusBarNotification mStatusBarNotification;
1131a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    private boolean mIsHeadsUp;
11498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private boolean mLastChronometerRunning = true;
115eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    private NotificationHeaderView mNotificationHeader;
1169c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek    private NotificationViewWrapper mNotificationHeaderWrapper;
117b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private ViewStub mChildrenContainerStub;
118b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationGroupManager mGroupManager;
119b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mChildrenExpanded;
120263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private boolean mIsSummaryWithChildren;
121b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationChildrenContainer mChildrenContainer;
1224b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private ViewStub mSettingsIconRowStub;
123ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    private ViewStub mGutsStub;
124b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mIsSystemChildExpanded;
125684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    private boolean mIsPinned;
1260e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski    private FalsingManager mFalsingManager;
12731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    private HeadsUpManager mHeadsUpManager;
128ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    private NotificationHeaderUtil mHeaderUtil = new NotificationHeaderUtil(this);
129b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
1305eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    private boolean mJustClicked;
1315a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek    private boolean mIconAnimationRunning;
13234d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    private boolean mShowNoBackground;
133388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    private ExpandableNotificationRow mNotificationParent;
134570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    private OnExpandClickListener mOnExpandClickListener;
135eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    private OnClickListener mExpandClickListener = new OnClickListener() {
136eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        @Override
137eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        public void onClick(View v) {
138624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek            if (!mShowingPublic && mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
139eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                mGroupManager.toggleGroupExpansion(mStatusBarNotification);
14031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                mOnExpandClickListener.onExpandClicked(mEntry,
141570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek                        mGroupManager.isGroupExpanded(mStatusBarNotification));
142eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            } else {
14331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                boolean nowExpanded;
14431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                if (isPinned()) {
14531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    nowExpanded = !mExpandedWhenPinned;
14631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    mExpandedWhenPinned = nowExpanded;
14731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                } else {
14831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    nowExpanded = !isExpanded();
14931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    setUserExpanded(nowExpanded);
15031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                }
151eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                notifyHeightChanged(true);
15231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                mOnExpandClickListener.onExpandClicked(mEntry, nowExpanded);
153eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
154eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        }
155eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    };
1565eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
1578d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPrivateLayout() {
1588d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPrivateLayout;
1598d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
1608d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
1618d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPublicLayout() {
1628d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPublicLayout;
1638d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
1648d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
165cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    public void setIconAnimationRunning(boolean running) {
166cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        setIconAnimationRunning(running, mPublicLayout);
167cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        setIconAnimationRunning(running, mPrivateLayout);
1685a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        setIconAnimationRunningForChild(running, mNotificationHeader);
1695a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        if (mIsSummaryWithChildren) {
1705a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            List<ExpandableNotificationRow> notificationChildren =
1715a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                    mChildrenContainer.getNotificationChildren();
1725a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
1735a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
1745a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                child.setIconAnimationRunning(running);
1755a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            }
1765a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        }
1775a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        mIconAnimationRunning = running;
178cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
179cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
180cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunning(boolean running, NotificationContentView layout) {
181cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (layout != null) {
182cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View contractedChild = layout.getContractedChild();
183cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View expandedChild = layout.getExpandedChild();
1848d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
185cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, contractedChild);
186cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, expandedChild);
1878d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            setIconAnimationRunningForChild(running, headsUpChild);
188cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
189cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
190cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
191cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunningForChild(boolean running, View child) {
192cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (child != null) {
193cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView icon = (ImageView) child.findViewById(com.android.internal.R.id.icon);
194cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(icon, running);
195cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView rightIcon = (ImageView) child.findViewById(
196cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    com.android.internal.R.id.right_icon);
197cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(rightIcon, running);
198cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
199cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
200cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
201cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconRunning(ImageView imageView, boolean running) {
202cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (imageView != null) {
203cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            Drawable drawable = imageView.getDrawable();
204cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            if (drawable instanceof AnimationDrawable) {
205cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
206cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
207cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
208cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
209cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
210cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
211cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            } else if (drawable instanceof AnimatedVectorDrawable) {
212cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimatedVectorDrawable animationDrawable = (AnimatedVectorDrawable) drawable;
213cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
214cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
215cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
216cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
217cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
218cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            }
219cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
220cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
221cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
222da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    public void onNotificationUpdated(NotificationData.Entry entry) {
223da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        mEntry = entry;
224da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        mStatusBarNotification = entry.notification;
225b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos        mPrivateLayout.onNotificationUpdated(entry);
226b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos        mPublicLayout.onNotificationUpdated(entry);
227757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek        mShowingPublicInitialized = false;
228757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek        updateClearability();
2298fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        if (mIsSummaryWithChildren) {
2308fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek            recreateNotificationHeader();
2318fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        }
2325a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        if (mIconAnimationRunning) {
2335a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            setIconAnimationRunning(true);
2345a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        }
235ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        if (mNotificationParent != null) {
236ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek            mNotificationParent.updateChildrenHeaderAppearance();
237ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        }
238263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
239624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek        // The public layouts expand button is always visible
240624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek        mPublicLayout.updateExpandButtons(true);
241da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateLimits();
242da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    }
243da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek
244da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private void updateLimits() {
245da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        boolean customView = getPrivateLayout().getContractedChild().getId()
246da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek                != com.android.internal.R.id.status_bar_latest_event_content;
247da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
248da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        int minHeight = customView && beforeN && !mIsSummaryWithChildren ?
249da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek                mNotificationMinHeightLegacy : mNotificationMinHeight;
25077019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        boolean headsUpCustom = getPrivateLayout().getHeadsUpChild() != null &&
25177019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek                getPrivateLayout().getHeadsUpChild().getId()
25277019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek                != com.android.internal.R.id.status_bar_latest_event_content;
25377019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        int headsUpheight = headsUpCustom && beforeN ? mMaxHeadsUpHeightLegacy
25477019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek                : mMaxHeadsUpHeight;
255860b6dac964d3aa1818133c767eb825c8153a594Selim Cinek        mPrivateLayout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight);
256860b6dac964d3aa1818133c767eb825c8153a594Selim Cinek        mPublicLayout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight);
257b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
258b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
259b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    public StatusBarNotification getStatusBarNotification() {
260b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        return mStatusBarNotification;
261b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
262b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
263b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    public boolean isHeadsUp() {
264b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek        return mIsHeadsUp;
265b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
266b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
2671a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    public void setHeadsUp(boolean isHeadsUp) {
268c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        int intrinsicBefore = getIntrinsicHeight();
2691a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mIsHeadsUp = isHeadsUp;
2708d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mPrivateLayout.setHeadsUp(isHeadsUp);
271c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
272c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek            notifyHeightChanged(false  /* needsAnimation */);
273c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        }
2741a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    }
2751a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek
276b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setGroupManager(NotificationGroupManager groupManager) {
277b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mGroupManager = groupManager;
27883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        mPrivateLayout.setGroupManager(groupManager);
279b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
280b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
281b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos    public void setRemoteInputController(RemoteInputController r) {
282b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos        mPrivateLayout.setRemoteInputController(r);
283b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos    }
284b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos
285b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row) {
286b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        addChildNotification(row, -1);
287b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
288b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
289b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
290b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Add a child notification to this view.
291b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
292b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param row the row to add
293b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childIndex the index to add it at, if -1 it will be added at the end
294b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
295b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row, int childIndex) {
296b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer == null) {
297b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainerStub.inflate();
298b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
299b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainer.addNotification(row, childIndex);
300263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
301263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(true, this);
302b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
303b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
304b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void removeChildNotification(ExpandableNotificationRow row) {
305b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer != null) {
306b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.removeNotification(row);
307b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
308ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        mHeaderUtil.restoreNotificationHeader(row);
309263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
310263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(false, null);
311263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
312263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
313263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isChildInGroup() {
314a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        return mNotificationParent != null;
315263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
316263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
317388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public ExpandableNotificationRow getNotificationParent() {
318388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        return mNotificationParent;
319388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
320388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
321263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    /**
322263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param isChildInGroup Is this notification now in a group
323263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param parent the new parent notification
324263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     */
325a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {;
326a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        boolean childInGroup = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
327a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mNotificationParent = childInGroup ? parent : null;
328a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mPrivateLayout.setIsChildInGroup(childInGroup);
329a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateNoBackgroundState();
33034d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    }
33134d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek
33234d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    @Override
3337210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    public boolean onTouchEvent(MotionEvent event) {
3347210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        if (event.getActionMasked() != MotionEvent.ACTION_DOWN
3357210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek                || !isChildInGroup() || isGroupExpanded()) {
3367210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek            return super.onTouchEvent(event);
3377210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        } else {
3387210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek            return false;
3397210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        }
3407210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    }
3417210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek
3427210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    @Override
343f062580d395a8c99631c104d6aec250f961152ddMady Mellor    protected boolean handleSlideBack() {
344f062580d395a8c99631c104d6aec250f961152ddMady Mellor        if (mSettingsIconRow != null && mSettingsIconRow.isVisible()) {
345f062580d395a8c99631c104d6aec250f961152ddMady Mellor            animateTranslateNotification(0 /* targetLeft */);
346f062580d395a8c99631c104d6aec250f961152ddMady Mellor            return true;
347f062580d395a8c99631c104d6aec250f961152ddMady Mellor        }
348f062580d395a8c99631c104d6aec250f961152ddMady Mellor        return false;
349f062580d395a8c99631c104d6aec250f961152ddMady Mellor    }
350f062580d395a8c99631c104d6aec250f961152ddMady Mellor
351f062580d395a8c99631c104d6aec250f961152ddMady Mellor    @Override
35234d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    protected boolean shouldHideBackground() {
35334d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek        return super.shouldHideBackground() || mShowNoBackground;
354263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
355263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
356263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    @Override
357263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isSummaryWithChildren() {
358263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        return mIsSummaryWithChildren;
359b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
360b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
361b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    @Override
362b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public boolean areChildrenExpanded() {
363b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenExpanded;
364b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
365b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
366b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public List<ExpandableNotificationRow> getNotificationChildren() {
367b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenContainer == null ? null : mChildrenContainer.getNotificationChildren();
368b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
369b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
370eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    public int getNumberOfNotificationChildren() {
371eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        if (mChildrenContainer == null) {
372eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek            return 0;
373eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        }
374eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mChildrenContainer.getNotificationChildren().size();
375eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    }
376eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek
377b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
378b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Apply the order given in the list to the children.
379b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
380b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childOrder the new list order
381b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @return whether the list order has changed
382b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
383b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder) {
384b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder);
385b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
386b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
387b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void getChildrenStates(StackScrollState resultState) {
38883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
389b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            StackViewState parentState = resultState.getViewStateForView(this);
390b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.getState(resultState, parentState);
391b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
392b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
393b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
394b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void applyChildrenState(StackScrollState state) {
39583bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
396b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.applyState(state);
397b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
398b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
399b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
400b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void prepareExpansionChanged(StackScrollState state) {
40183bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
402b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.prepareExpansionChanged(state);
403b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
404b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
405b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
406b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void startChildAnimation(StackScrollState finalState,
4079969559da02f54fcbd7832de9810507a581d98d8Selim Cinek            StackStateAnimator stateAnimator, long delay, long duration) {
40883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
4099969559da02f54fcbd7832de9810507a581d98d8Selim Cinek            mChildrenContainer.startAnimationToState(finalState, stateAnimator, delay,
410b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                    duration);
411b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
412b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
413b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
414b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public ExpandableNotificationRow getViewAtPosition(float y) {
41583bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (!mIsSummaryWithChildren || !mChildrenExpanded) {
416b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return this;
417b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
418b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ExpandableNotificationRow view = mChildrenContainer.getViewAtPosition(y);
419b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return view == null ? this : view;
420b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
421b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
422b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
423ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public NotificationGuts getGuts() {
424ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        return mGuts;
425ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
426ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
427684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    /**
428684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
429684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * the notification will be rendered on top of the screen.
430684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     *
431684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * @param pinned whether it is pinned
432684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     */
433684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public void setPinned(boolean pinned) {
434684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        mIsPinned = pinned;
43531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if (pinned) {
43631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            setIconAnimationRunning(true);
43731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            mExpandedWhenPinned = false;
43831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mExpandedWhenPinned) {
43931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            setUserExpanded(true);
44031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        }
44198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(mLastChronometerRunning);
442b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
443b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
444684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public boolean isPinned() {
445684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        return mIsPinned;
446b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
447b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
44831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    /**
44931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * @param atLeastMinHeight should the value returned be at least the minimum height.
45031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     *                         Used to avoid cyclic calls
45131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * @return the height of the heads up notification when pinned
45231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     */
45331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    public int getPinnedHeadsUpHeight(boolean atLeastMinHeight) {
45477019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        if (mIsSummaryWithChildren) {
45577019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek            return mChildrenContainer.getIntrinsicHeight();
45677019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        }
45731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if(mExpandedWhenPinned) {
45831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return Math.max(getMaxExpandHeight(), mHeadsUpHeight);
45931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (atLeastMinHeight) {
46031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return Math.max(getMinHeight(), mHeadsUpHeight);
46131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else {
46231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return mHeadsUpHeight;
46331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        }
464b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
465b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
4665eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
4675eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * Mark whether this notification was just clicked, i.e. the user has just clicked this
4685eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * notification in this frame.
4695eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
4705eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public void setJustClicked(boolean justClicked) {
4715eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        mJustClicked = justClicked;
4725eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
4735eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
4745eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
4755eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * @return true if this notification has been clicked in this frame, false otherwise
4765eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
4775eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public boolean wasJustClicked() {
4785eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        return mJustClicked;
4795eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
4805eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
48198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    public void setChronometerRunning(boolean running) {
48298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        mLastChronometerRunning = running;
48398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPrivateLayout);
48498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPublicLayout);
48598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (mChildrenContainer != null) {
48698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
48798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                    mChildrenContainer.getNotificationChildren();
48898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
48998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
49098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                child.setChronometerRunning(running);
49198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
49298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
49398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
49498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
49598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunning(boolean running, NotificationContentView layout) {
49698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (layout != null) {
49798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            running = running || isPinned();
49898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View contractedChild = layout.getContractedChild();
49998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View expandedChild = layout.getExpandedChild();
50098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
50198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, contractedChild);
50298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, expandedChild);
50398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, headsUpChild);
50498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
50598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
50698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
50798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunningForChild(boolean running, View child) {
50898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (child != null) {
50998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View chronometer = child.findViewById(com.android.internal.R.id.chronometer);
51098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            if (chronometer instanceof Chronometer) {
51198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ((Chronometer) chronometer).setStarted(running);
51298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
51398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
51498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
51598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
516ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    public NotificationHeaderView getNotificationHeader() {
517ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        if (mNotificationHeader != null) {
518ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek            return mNotificationHeader;
5198d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        }
520ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        return mPrivateLayout.getNotificationHeader();
5218d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek    }
5228d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek
52334eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek    private NotificationHeaderView getVisibleNotificationHeader() {
52434eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        if (mNotificationHeader != null) {
52534eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek            return mNotificationHeader;
52634eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        }
52734eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        return getShowingLayout().getVisibleNotificationHeader();
52834eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek    }
52934eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek
530570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) {
531570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek        mOnExpandClickListener = onExpandClickListener;
532570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    }
533570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek
53431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    public void setHeadsUpManager(HeadsUpManager headsUpManager) {
53531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        mHeadsUpManager = headsUpManager;
53631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    }
53731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek
53801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    public void reInflateViews() {
53901af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        initDimens();
54001af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        if (mIsSummaryWithChildren) {
54101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            removeView(mNotificationHeader);
54201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mNotificationHeader = null;
54301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            recreateNotificationHeader();
54401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            if (mChildrenContainer != null) {
54501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek                mChildrenContainer.reInflateViews();
54601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            }
54701af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        }
54801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        if (mGuts != null) {
54901af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            View oldGuts = mGuts;
55001af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            int index = indexOfChild(oldGuts);
55101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            removeView(oldGuts);
55201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mGuts = (NotificationGuts) LayoutInflater.from(mContext).inflate(
55301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek                    R.layout.notification_guts, this, false);
55401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mGuts.setVisibility(oldGuts.getVisibility());
55501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            addView(mGuts, index);
55601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        }
5574b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mSettingsIconRow != null) {
5584b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            View oldSettings = mSettingsIconRow;
5594b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            int settingsIndex = indexOfChild(oldSettings);
5604b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            removeView(oldSettings);
5614b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRow = (NotificationSettingsIconRow) LayoutInflater.from(mContext).inflate(
5624b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                    R.layout.notification_settings_icon_row, this, false);
5634b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRow.setNotificationRowParent(ExpandableNotificationRow.this);
5644b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRow.setVisibility(oldSettings.getVisibility());
5654b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            addView(mSettingsIconRow, settingsIndex);
5664b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
5674b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
568de33a4ad5696173942dca363339027c892927e8dSelim Cinek        mPrivateLayout.reInflateViews();
569de33a4ad5696173942dca363339027c892927e8dSelim Cinek        mPublicLayout.reInflateViews();
57001af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    }
57101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek
57278403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public interface ExpansionLogger {
57378403d79739605511ea88b653564d81d7bf4bbbaChris Wren        public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
57478403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
5751685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
57651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
57751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        super(context, attrs);
5780e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager = FalsingManager.getInstance(context);
57901af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        initDimens();
58001af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    }
58101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek
58201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private void initDimens() {
583f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMinHeightLegacy = getFontScaledHeight(R.dimen.notification_min_height_legacy);
584f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMinHeight = getFontScaledHeight(R.dimen.notification_min_height);
585f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMaxHeight = getFontScaledHeight(R.dimen.notification_max_height);
586f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mMaxHeadsUpHeightLegacy = getFontScaledHeight(
58777019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek                R.dimen.notification_max_heads_up_height_legacy);
588f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mMaxHeadsUpHeight = getFontScaledHeight(R.dimen.notification_max_heads_up_height);
589f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    }
590f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek
591f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    /**
592f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     * @param dimenId the dimen to look up
593f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     * @return the font scaled dimen as if it were in sp but doesn't shrink sizes below dp
594f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     */
595f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    private int getFontScaledHeight(int dimenId) {
596f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        int dimensionPixelSize = getResources().getDimensionPixelSize(dimenId);
597f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        float factor = Math.max(1.0f, getResources().getDisplayMetrics().scaledDensity /
598f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek                getResources().getDisplayMetrics().density);
599f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        return (int) (dimensionPixelSize * factor);
60051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
60151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
602a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    /**
603a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     * Resets this view so it can be re-used for an updated notification.
604a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     */
60522f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer    @Override
606a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    public void reset() {
60722f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer        super.reset();
60878403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
609a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mExpandable = false;
610a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mHasUserChangedExpansion = false;
611a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mUserLocked = false;
612a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mShowingPublic = false;
613ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = false;
614ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = false;
615a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mIsSystemExpanded = false;
61683bc78338437a460076a4b5778ded38440ac3501Selim Cinek        mOnKeyguard = false;
6171a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mPublicLayout.reset(mIsHeadsUp);
6181a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mPrivateLayout.reset(mIsHeadsUp);
61931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        resetHeight();
6204b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        resetTranslation();
62131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        logExpansionEvent(false, wasExpanded);
62231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    }
62331094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek
62431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public void resetHeight() {
6251a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        if (mIsHeadsUp) {
6261a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek            resetActualHeight();
6271a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        }
628a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mMaxExpandHeight = 0;
6298d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mHeadsUpHeight = 0;
630a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek        mWasReset = true;
63131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        onHeightReset();
6326e28a678c7f9fe2cae5a51bfdbab3071a2d8d0baSelim Cinek        requestLayout();
633a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    }
634a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer
635251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    @Override
636251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    protected void onFinishInflate() {
637251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi        super.onFinishInflate();
638be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
639fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        mPublicLayout.setContainingNotification(this);
640be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
641eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.setExpandClickListener(mExpandClickListener);
642fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        mPrivateLayout.setContainingNotification(this);
643eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPublicLayout.setExpandClickListener(mExpandClickListener);
6444b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mSettingsIconRowStub = (ViewStub) findViewById(R.id.settings_icon_row_stub);
6454b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mSettingsIconRowStub.setOnInflateListener(new ViewStub.OnInflateListener() {
6464b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            @Override
6474b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            public void onInflate(ViewStub stub, View inflated) {
6484b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mSettingsIconRow = (NotificationSettingsIconRow) inflated;
6494b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mSettingsIconRow.setNotificationRowParent(ExpandableNotificationRow.this);
6504b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
6514b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        });
652ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub = (ViewStub) findViewById(R.id.notification_guts_stub);
653ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub.setOnInflateListener(new ViewStub.OnInflateListener() {
654b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            @Override
655b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            public void onInflate(ViewStub stub, View inflated) {
656b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts = (NotificationGuts) inflated;
657b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setClipTopAmount(getClipTopAmount());
658b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setActualHeight(getActualHeight());
6594b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mTranslateableViews.add(mGuts);
660ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek                mGutsStub = null;
661b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            }
662b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        });
663b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub = (ViewStub) findViewById(R.id.child_container_stub);
664b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub.setOnInflateListener(new ViewStub.OnInflateListener() {
665b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
666b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            @Override
667b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            public void onInflate(ViewStub stub, View inflated) {
668b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                mChildrenContainer = (NotificationChildrenContainer) inflated;
669388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek                mChildrenContainer.setNotificationParent(ExpandableNotificationRow.this);
6704b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mTranslateableViews.add(mChildrenContainer);
671b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            }
672b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        });
673863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek        mVetoButton = findViewById(R.id.veto);
6744b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
6754b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        // Add the views that we translate to reveal the gear
6764b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews = new ArrayList<View>();
6774b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        for (int i = 0; i < getChildCount(); i++) {
6784b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mTranslateableViews.add(getChildAt(i));
6794b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
6804b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        // Remove views that don't translate
6814b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews.remove(mVetoButton);
6824b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews.remove(mSettingsIconRowStub);
6834b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews.remove(mChildrenContainerStub);
6844b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews.remove(mGutsStub);
6854b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
6864b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
6874b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public void setTranslationForOutline(float translationX) {
6884b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        setOutlineRect(false, translationX, getTop(), getRight() + translationX, getBottom());
6894b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
6904b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
6914b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public void resetTranslation() {
6924b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mTranslateableViews != null) {
6934b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            for (int i = 0; i < mTranslateableViews.size(); i++) {
6944b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mTranslateableViews.get(i).setTranslationX(0);
6954b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
6964b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            setTranslationForOutline(0);
6974b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
6984b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mSettingsIconRow != null) {
6994b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRow.resetState();
7004b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
7014b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
7024b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
7034b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public void animateTranslateNotification(final float leftTarget) {
7044b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mTranslateAnim != null) {
7054b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mTranslateAnim.cancel();
7064b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
7074b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        AnimatorSet set = new AnimatorSet();
7084b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mTranslateableViews != null) {
7094b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            for (int i = 0; i < mTranslateableViews.size(); i++) {
7104b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                final View animView = mTranslateableViews.get(i);
7114b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                final ObjectAnimator translateAnim = ObjectAnimator.ofFloat(
7124b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        animView, "translationX", leftTarget);
7134b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                if (i == 0) {
7144b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                    translateAnim.addUpdateListener(new AnimatorUpdateListener() {
7154b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        @Override
7164b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        public void onAnimationUpdate(ValueAnimator animation) {
7174b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                            setTranslationForOutline((float) animation.getAnimatedValue());
7184b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        }
7194b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                    });
7204b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                }
7214b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                translateAnim.addListener(new AnimatorListenerAdapter() {
7224b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                    @Override
7234b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                    public void onAnimationEnd(Animator anim) {
7244b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        if (mSettingsIconRow != null && leftTarget == 0) {
7254b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                            mSettingsIconRow.resetState();
7264b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        }
7274b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        mTranslateAnim = null;
7284b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                    }
7294b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                });
7304b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                set.play(translateAnim);
7314b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
7324b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
7334b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateAnim = set;
7344b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        set.start();
7354b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
7364b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
7374b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public float getSpaceForGear() {
7384b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mSettingsIconRow != null) {
7394b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            return mSettingsIconRow.getSpaceForGear();
7404b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
7414b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        return 0;
7424b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
7434b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
7444b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public NotificationSettingsIconRow getSettingsRow() {
7454b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mSettingsIconRow == null) {
7464b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRowStub.inflate();
7474b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
7484b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        return mSettingsIconRow;
7494b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
7504b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
7514b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public ArrayList<View> getContentViews() {
7524b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        return mTranslateableViews;
753fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    }
754fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi
755ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public void inflateGuts() {
756ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        if (mGuts == null) {
757ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek            mGutsStub.inflate();
758ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        }
759ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
760ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
761da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private void updateChildrenVisibility() {
762d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        mPrivateLayout.setVisibility(!mShowingPublic && !mIsSummaryWithChildren ? VISIBLE
763d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                : INVISIBLE);
764ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek        if (mChildrenContainer != null) {
765ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek            mChildrenContainer.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
766ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek                    : INVISIBLE);
767ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek        }
768ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek        if (mNotificationHeader != null) {
769ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek            mNotificationHeader.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
770ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek                    : INVISIBLE);
771b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
772da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        // The limits might have changed if the view suddenly became a group or vice versa
773da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateLimits();
774b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
775b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
776fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    @Override
777a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
778a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        if (super.onRequestSendAccessibilityEventInternal(child, event)) {
779fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // Add a record for the entire layout since its content is somehow small.
780fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // The event comes from a leaf view that is interacted with.
781fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            AccessibilityEvent record = AccessibilityEvent.obtain();
782fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            onInitializeAccessibilityEvent(record);
783fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            dispatchPopulateAccessibilityEvent(record);
784fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            event.appendRecord(record);
785fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            return true;
786fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        }
787fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        return false;
788c5dc0d0cce373fbf292e13633c114a431d747167Jorim Jaggi    }
78951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
790e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    @Override
7914e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    public void setDark(boolean dark, boolean fade, long delay) {
7924e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        super.setDark(dark, fade, delay);
793e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        final NotificationContentView showing = getShowingLayout();
794e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        if (showing != null) {
7954e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            showing.setDark(dark, fade, delay);
796e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        }
7979c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek        if (mIsSummaryWithChildren) {
7989c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek            mChildrenContainer.setDark(dark, fade, delay);
7999c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek            mNotificationHeaderWrapper.setDark(dark, fade, delay);
8009c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek        }
801e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    }
802e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock
80351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isExpandable() {
804388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
805388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return !mChildrenExpanded;
806388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
80751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mExpandable;
80851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
80951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
81051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setExpandable(boolean expandable) {
81151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mExpandable = expandable;
812eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
81351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
81451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
8154ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    @Override
8164ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    public void setClipToActualHeight(boolean clipToActualHeight) {
817084c16b8b380e7ff0d38d9e2846db321f0214931Selim Cinek        super.setClipToActualHeight(clipToActualHeight || isUserLocked());
818084c16b8b380e7ff0d38d9e2846db321f0214931Selim Cinek        getShowingLayout().setClipToActualHeight(clipToActualHeight || isUserLocked());
8194ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    }
8204ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek
8211685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
8221685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the user has changed the expansion state
8231685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
8241685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean hasUserChangedExpansion() {
8251685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mHasUserChangedExpansion;
8261685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
8271685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
82851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserExpanded() {
82951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserExpanded;
83051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
83151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
8321685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
8331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the user
8341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
8351685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param userExpanded whether the user wants this notification to be expanded
8361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
83751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserExpanded(boolean userExpanded) {
838388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        setUserExpanded(userExpanded, false /* allowChildExpansion */);
839388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
840388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
841388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    /**
842388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * Set this notification to be expanded by the user
843388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     *
844388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param userExpanded whether the user wants this notification to be expanded
845388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param allowChildExpansion whether a call to this method allows expanding children
846388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     */
847388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) {
8480e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager.setNotificationExpanded();
849388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic && allowChildExpansion) {
850388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            mGroupManager.setGroupExpanded(mStatusBarNotification, userExpanded);
851388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return;
852388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
853a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        if (userExpanded && !mExpandable) return;
85478403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
8551685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mHasUserChangedExpansion = true;
85651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserExpanded = userExpanded;
85778403d79739605511ea88b653564d81d7bf4bbbaChris Wren        logExpansionEvent(true, wasExpanded);
85851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
85951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
860ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    public void resetUserExpansion() {
861ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mHasUserChangedExpansion = false;
862ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mUserExpanded = false;
863ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    }
864ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek
86551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserLocked() {
86651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserLocked;
86751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
86851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
86951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserLocked(boolean userLocked) {
87051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserLocked = userLocked;
87151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
87251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
8731685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
8741685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return has the system set this notification to be expanded
8751685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
8761685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean isSystemExpanded() {
8771685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mIsSystemExpanded;
8781685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
8791685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
8801685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
8811685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the system.
8821685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
8831685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param expand whether the system wants this notification to be expanded.
8841685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
8851685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setSystemExpanded(boolean expand) {
88631094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        if (expand != mIsSystemExpanded) {
88731094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
88831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            mIsSystemExpanded = expand;
889b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            notifyHeightChanged(false /* needsAnimation */);
89031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            logExpansionEvent(false, wasExpanded);
89183bc78338437a460076a4b5778ded38440ac3501Selim Cinek            if (mChildrenContainer != null) {
89283bc78338437a460076a4b5778ded38440ac3501Selim Cinek                mChildrenContainer.updateGroupOverflow();
89383bc78338437a460076a4b5778ded38440ac3501Selim Cinek            }
89431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
895dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    }
896dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
897dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
89883bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * @param onKeyguard whether to prevent notification expansion
899dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
90083bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public void setOnKeyguard(boolean onKeyguard) {
90183bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (onKeyguard != mOnKeyguard) {
90231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
90383bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mOnKeyguard = onKeyguard;
90431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            logExpansionEvent(false, wasExpanded);
90531094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            if (wasExpanded != isExpanded()) {
9062108fe0d6d6830d14bf809737c1fe1080366ea4aSelim Cinek                if (mIsSummaryWithChildren) {
9072108fe0d6d6830d14bf809737c1fe1080366ea4aSelim Cinek                    mChildrenContainer.updateGroupOverflow();
9082108fe0d6d6830d14bf809737c1fe1080366ea4aSelim Cinek                }
9094b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                notifyHeightChanged(false /* needsAnimation */);
91031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            }
91131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
9121685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
9131685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
9141685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
9150d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     * @return Can the underlying notification be cleared?
9160d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     */
9170d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    public boolean isClearable() {
918a37774f098a5204947ff4b4787c4b753bb9016dbSelim Cinek        return mStatusBarNotification != null && mStatusBarNotification.isClearable();
9190d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
9200d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
9210d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    /**
9221685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Apply an expansion state to the layout.
9231685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
924dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    public void applyExpansionToLayout() {
925dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi        boolean expand = isExpanded();
92651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        if (expand && mExpandable) {
927eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek            setActualHeight(mMaxExpandHeight);
92851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        } else {
929860b6dac964d3aa1818133c767eb825c8153a594Selim Cinek            setActualHeight(getMinHeight());
93051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        }
93151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
932a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
9339cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    @Override
9349cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    public int getIntrinsicHeight() {
935be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (isUserLocked()) {
936be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            return getActualHeight();
937be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
938d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        if (mGuts != null && mGuts.areGutsExposed()) {
939d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return mGuts.getHeight();
940d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else if ((isChildInGroup() && !isGroupExpanded())) {
941d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return mPrivateLayout.getMinHeight();
942d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else if (mSensitive && mHideSensitiveForIntrinsicHeight) {
943d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return getMinHeight();
94483bc78338437a460076a4b5778ded38440ac3501Selim Cinek        } else if (mIsSummaryWithChildren && !mOnKeyguard) {
945eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getIntrinsicHeight();
94660122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek        } else if (mIsHeadsUp) {
94731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            if (isPinned()) {
94831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                return getPinnedHeadsUpHeight(true /* atLeastMinHeight */);
94931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            } else if (isExpanded()) {
950d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                return Math.max(getMaxExpandHeight(), mHeadsUpHeight);
9518d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            } else {
952d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                return Math.max(getMinHeight(), mHeadsUpHeight);
9538d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            }
95431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (isExpanded()) {
95583bc78338437a460076a4b5778ded38440ac3501Selim Cinek            return getMaxExpandHeight();
956d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else {
957d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return getMinHeight();
9581685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        }
959b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
9601685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
961eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    private boolean isGroupExpanded() {
962eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mGroupManager.isGroupExpanded(mStatusBarNotification);
963b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
964b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
965eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    /**
966eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek     * @return whether this view has a header on the top of the content
967eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek     */
968eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    private boolean hasNotificationHeader() {
969eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mIsSummaryWithChildren;
9701685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
9711685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
972263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private void onChildrenCountChanged() {
9738fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        mIsSummaryWithChildren = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS
974263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek                && mGroupManager.hasGroupChildren(mStatusBarNotification);
9758fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        if (mIsSummaryWithChildren) {
976eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            if (mChildrenContainer == null) {
977eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                mChildrenContainerStub.inflate();
978eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
9798fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek            if (mNotificationHeader == null) {
980eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                recreateNotificationHeader();
981eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
982263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        }
983eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
984ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        updateChildrenHeaderAppearance();
985eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        updateHeaderChildCount();
986da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateChildrenVisibility();
987263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
988263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
9891685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
9901685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Check whether the view state is currently expanded. This is given by the system in {@link
9911685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * #setSystemExpanded(boolean)} and can be overridden by user expansion or
9921685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
9931685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * view can differ from this state, if layout params are modified from outside.
9941685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
9951685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the view state is currently expanded.
9961685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
99783bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public boolean isExpanded() {
99883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        return !mOnKeyguard
999b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                && (!hasUserChangedExpansion() && (isSystemExpanded() || isSystemChildExpanded())
1000b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                || isUserExpanded());
1001b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1002b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1003b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean isSystemChildExpanded() {
1004b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mIsSystemChildExpanded;
1005b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1006b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1007b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setSystemChildExpanded(boolean expanded) {
1008b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mIsSystemChildExpanded = expanded;
10091685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
10101685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
10111685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    @Override
10121685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
10131685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        super.onLayout(changed, left, top, right, bottom);
1014a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek        boolean updateExpandHeight = mMaxExpandHeight == 0 && !mWasReset;
10158d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        updateMaxHeights();
1016be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (updateExpandHeight) {
1017dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi            applyExpansionToLayout();
1018be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
1019a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek        mWasReset = false;
10201685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
10211685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
10228d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private void updateMaxHeights() {
1023d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        int intrinsicBefore = getIntrinsicHeight();
10248d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View expandedChild = mPrivateLayout.getExpandedChild();
10258d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        if (expandedChild == null) {
10268d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            expandedChild = mPrivateLayout.getContractedChild();
10278d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
10288d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mMaxExpandHeight = expandedChild.getHeight();
10298d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View headsUpChild = mPrivateLayout.getHeadsUpChild();
10301f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        if (headsUpChild == null) {
10311f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek            headsUpChild = mPrivateLayout.getContractedChild();
10328d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
10331f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        mHeadsUpHeight = headsUpChild.getHeight();
1034d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
1035b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            notifyHeightChanged(false  /* needsAnimation */);
1036d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        }
1037d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek    }
1038d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek
1039fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    @Override
1040fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    public void notifyHeightChanged(boolean needsAnimation) {
1041fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        super.notifyHeightChanged(needsAnimation);
1042fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        getShowingLayout().requestSelectLayout(needsAnimation || isUserLocked());
1043fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    }
1044fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek
10453c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek    public void setSensitive(boolean sensitive, boolean hideSensitive) {
1046ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = sensitive;
10473c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek        mSensitiveHiddenInGeneral = hideSensitive;
1048ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1049ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
1050ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
105160122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek        mHideSensitiveForIntrinsicHeight = hideSensitive;
1052ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1053ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
1054ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
1055ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            long duration) {
1056ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        boolean oldShowingPublic = mShowingPublic;
1057ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublic = mSensitive && hideSensitive;
1058ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
1059ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            return;
1060ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
1061a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
1062a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler        // bail out if no public version
10631685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        if (mPublicLayout.getChildCount() == 0) return;
1064a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
1065ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (!animated) {
1066ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.animate().cancel();
1067ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.animate().cancel();
1068ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setAlpha(1f);
1069ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.setAlpha(1f);
1070ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
1071d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            updateChildrenVisibility();
1072ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        } else {
1073ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            animateShowingPublic(delay, duration);
1074ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
10750d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
1076eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
1077757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek        updateClearability();
1078ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = true;
1079ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1080ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
1081ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private void animateShowingPublic(long delay, long duration) {
1082d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] privateViews = mIsSummaryWithChildren ?
1083d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                new View[] {mChildrenContainer, mNotificationHeader}
1084d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                : new View[] {mPrivateLayout};
1085d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] publicViews = new View[] {mPublicLayout};
1086d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] hiddenChildren = mShowingPublic ? privateViews : publicViews;
1087d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] shownChildren = mShowingPublic ? publicViews : privateViews;
1088d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        for (final View hiddenView : hiddenChildren) {
1089d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.setVisibility(View.VISIBLE);
1090d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.animate().cancel();
1091d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.animate()
1092d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .alpha(0f)
1093d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setStartDelay(delay)
1094d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setDuration(duration)
1095d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .withEndAction(new Runnable() {
1096d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        @Override
1097d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        public void run() {
1098d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                            hiddenView.setVisibility(View.INVISIBLE);
1099d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        }
1100d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    });
1101d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        }
1102d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        for (View showView : shownChildren) {
1103d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.setVisibility(View.VISIBLE);
1104d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.setAlpha(0f);
1105d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.animate().cancel();
1106d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.animate()
1107d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .alpha(1f)
1108d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setStartDelay(delay)
1109d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setDuration(duration);
1110d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        }
11110d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
11120d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
11133776fe007550451bb237c705d333247eab2a291cSelim Cinek    public boolean mustStayOnScreen() {
11143776fe007550451bb237c705d333247eab2a291cSelim Cinek        return mIsHeadsUp;
11153776fe007550451bb237c705d333247eab2a291cSelim Cinek    }
11163776fe007550451bb237c705d333247eab2a291cSelim Cinek
1117757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek    private void updateClearability() {
11180d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        // public versions cannot be dismissed
11193c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek        mVetoButton.setVisibility(isClearable() && (!mShowingPublic
11203c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek                || !mSensitiveHiddenInGeneral) ? View.VISIBLE : View.GONE);
1121a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
1122251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi
1123b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setChildrenExpanded(boolean expanded, boolean animate) {
1124b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenExpanded = expanded;
11257b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek        if (mNotificationHeader != null) {
11267b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek            mNotificationHeader.setExpanded(expanded);
11277b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek        }
112883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mChildrenContainer != null) {
112983bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mChildrenContainer.setChildrenExpanded(expanded);
113083bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
1131b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1132b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1133eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    public void updateHeaderChildCount() {
1134eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        if (mIsSummaryWithChildren) {
1135eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            mNotificationHeader.setChildCount(
1136eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                    mChildrenContainer.getNotificationChildren().size());
1137b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1138b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1139b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1140b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public static void applyTint(View v, int color) {
1141b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        int alpha;
1142b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (color != 0) {
1143b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = COLORED_DIVIDER_ALPHA;
1144b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
1145b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            color = 0xff000000;
1146b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = DEFAULT_DIVIDER_ALPHA;
1147b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1148b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (v.getBackground() instanceof ColorDrawable) {
1149b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ColorDrawable background = (ColorDrawable) v.getBackground();
1150b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.mutate();
1151b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setColor(color);
1152b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setAlpha(alpha);
1153b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1154b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1155b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
11561685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public int getMaxExpandHeight() {
1157b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mMaxExpandHeight;
1158a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
1159584a7aa62c54bcbd654a6696d4fbb56e124874e7Jorim Jaggi
1160be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
11614222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public boolean isContentExpandable() {
11622f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
11632f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.isContentExpandable();
11644222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
11654222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
11664222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
1167560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    protected View getContentView() {
1168560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek        return getShowingLayout();
1169560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    }
1170560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek
1171560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    @Override
1172d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int height, boolean notifyListeners) {
1173b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        super.setActualHeight(height, notifyListeners);
1174eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        int contentHeight = Math.max(getMinHeight(), height);
1175b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mPrivateLayout.setContentHeight(contentHeight);
1176b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mPublicLayout.setContentHeight(contentHeight);
1177b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
1178b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setActualHeight(height);
1179b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
1180be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        invalidate();
1181be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
1182be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
1183be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
1184b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public int getMaxContentHeight() {
118583bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1186eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getMaxContentHeight();
118783bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
11882f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
11892f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.getMaxHeight();
1190be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
1191be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
1192be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
11934222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public int getMinHeight() {
119431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if (mIsHeadsUp && mHeadsUpManager.isTrackingHeadsUp()) {
119531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                return getPinnedHeadsUpHeight(false /* atLeastMinHeight */);
119631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mIsSummaryWithChildren && !isGroupExpanded() && !mShowingPublic) {
1197b55386d64aeb80f74ed21035d1e389d86be89db6Selim Cinek            return mChildrenContainer.getMinHeight();
119831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mIsHeadsUp) {
119931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return mHeadsUpHeight;
1200b55386d64aeb80f74ed21035d1e389d86be89db6Selim Cinek        }
1201816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
1202816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return showingLayout.getMinHeight();
1203816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    }
1204816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek
1205816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    @Override
1206816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    public int getMinExpandHeight() {
120783bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren && !mOnKeyguard) {
1208b55386d64aeb80f74ed21035d1e389d86be89db6Selim Cinek            return mChildrenContainer.getMinExpandHeight();
120983bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
1210816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return getMinHeight();
12114222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
12124222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
12134222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
1214be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
1215be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super.setClipTopAmount(clipTopAmount);
1216be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout.setClipTopAmount(clipTopAmount);
12172f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        mPublicLayout.setClipTopAmount(clipTopAmount);
1218b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
1219b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setClipTopAmount(clipTopAmount);
1220b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
1221be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
1222be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
1223eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    private void recreateNotificationHeader() {
1224eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(),
1225eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                getStatusBarNotification().getNotification());
1226eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        final RemoteViews header = builder.makeNotificationHeader();
1227eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        if (mNotificationHeader == null) {
1228eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            mNotificationHeader = (NotificationHeaderView) header.apply(getContext(), this);
1229eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            final View expandButton = mNotificationHeader.findViewById(
1230eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                    com.android.internal.R.id.expand_button);
1231eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            expandButton.setVisibility(VISIBLE);
1232eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            mNotificationHeader.setOnClickListener(mExpandClickListener);
12339c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek            mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(),
12349c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek                    mNotificationHeader);
1235b5a83613fe935cc60106746d311bab2acbce37faSelim Cinek            addView(mNotificationHeader, indexOfChild(mChildrenContainer) + 1);
12364b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mTranslateableViews.add(mNotificationHeader);
1237eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        } else {
1238eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            header.reapply(getContext(), mNotificationHeader);
12394ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek            mNotificationHeaderWrapper.notifyContentUpdated(mEntry.notification);
1240eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        }
12417b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek        updateHeaderExpandButton();
1242ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        updateChildrenHeaderAppearance();
12438fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        updateHeaderChildCount();
1244343e6e258ab6a9f647eabebaed05ce3acafd2ff1Selim Cinek    }
12457d447726e2cb9fae80db417012039828daab8fe7Selim Cinek
12467b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek    private void updateHeaderExpandButton() {
12477b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek        if (mIsSummaryWithChildren) {
12487b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek            mNotificationHeader.setIsGroupHeader(true /* isGroupHeader*/);
12497b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek        }
12507b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek    }
12517b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek
1252ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    public void updateChildrenHeaderAppearance() {
1253ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        if (mIsSummaryWithChildren) {
1254ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek            mHeaderUtil.updateChildrenHeaderAppearance();
1255ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        }
1256ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    }
1257ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek
125831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public boolean isMaxExpandHeightInitialized() {
125931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        return mMaxExpandHeight != 0;
12607d447726e2cb9fae80db417012039828daab8fe7Selim Cinek    }
12612f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek
12622f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    private NotificationContentView getShowingLayout() {
12632f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return mShowingPublic ? mPublicLayout : mPrivateLayout;
12642f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    }
126578403d79739605511ea88b653564d81d7bf4bbbaChris Wren
126659ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    @Override
126759ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    public void setShowingLegacyBackground(boolean showing) {
126859ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi        super.setShowingLegacyBackground(showing);
126959ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi        mPrivateLayout.setShowingLegacyBackground(showing);
127059ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi        mPublicLayout.setShowingLegacyBackground(showing);
127159ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    }
127259ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi
1273a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    @Override
1274a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    protected void updateBackgroundTint() {
1275a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        super.updateBackgroundTint();
1276a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateNoBackgroundState();
1277a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        if (mIsSummaryWithChildren) {
1278a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
1279a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                    mChildrenContainer.getNotificationChildren();
1280a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
1281a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
1282a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                child.updateNoBackgroundState();
1283a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            }
1284a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        }
1285a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
1286a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
1287a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    private void updateNoBackgroundState() {
1288a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mShowNoBackground = isChildInGroup() && hasSameBgColor(mNotificationParent);
1289a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateBackground();
1290a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
1291a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
129278403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public void setExpansionLogger(ExpansionLogger logger, String key) {
129378403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLogger = logger;
129478403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLoggingKey = key;
129578403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
129678403d79739605511ea88b653564d81d7bf4bbbaChris Wren
12976183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    @Override
129861633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek    public boolean needsIncreasedPadding() {
129961633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek        return mIsSummaryWithChildren && isGroupExpanded();
130061633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek    }
130161633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek
130261633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek    @Override
13036183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    protected boolean disallowSingleClick(MotionEvent event) {
13046183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        float x = event.getX();
13056183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        float y = event.getY();
130634eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        NotificationHeaderView header = getVisibleNotificationHeader();
13076183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        if (header != null) {
13086183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek            return header.isInTouchRect(x, y);
13096183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        }
13106183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        return super.disallowSingleClick(event);
13116183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    }
13126183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek
131378403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private void logExpansionEvent(boolean userAction, boolean wasExpanded) {
131478403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean nowExpanded = isExpanded();
131578403d79739605511ea88b653564d81d7bf4bbbaChris Wren        if (wasExpanded != nowExpanded && mLogger != null) {
131678403d79739605511ea88b653564d81d7bf4bbbaChris Wren            mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded) ;
131778403d79739605511ea88b653564d81d7bf4bbbaChris Wren        }
131878403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
1319570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek
1320570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    public interface OnExpandClickListener {
132131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        void onExpandClicked(NotificationData.Entry clickedEntry, boolean nowExpanded);
1322570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    }
132351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren}
1324