ExpandableNotificationRow.java revision c1e389dadc234827354b95bac98a9c7146ed301c
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;
46c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinekimport com.android.systemui.statusbar.notification.HybridNotificationView;
470ffbda62e55ad390e05e6c3ff52e1378e420285cSelim Cinekimport com.android.systemui.statusbar.notification.NotificationViewWrapper;
48b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.phone.NotificationGroupManager;
4931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinekimport com.android.systemui.statusbar.policy.HeadsUpManager;
50b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.NotificationChildrenContainer;
51b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackScrollState;
52b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackStateAnimator;
53b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackViewState;
54b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
554b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport java.util.ArrayList;
56b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport java.util.List;
57a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
584222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggipublic class ExpandableNotificationRow extends ActivatableNotificationView {
59b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
60b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
61b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int COLORED_DIVIDER_ALPHA = 0x7B;
6201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMinHeightLegacy;
6301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mMaxHeadsUpHeightLegacy;
6401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mMaxHeadsUpHeight;
6501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMinHeight;
6601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMaxHeight;
6751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
681685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Does this row contain layouts that can adapt to row expansion */
6951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mExpandable;
701685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Has the user actively changed the expansion state of this row */
711685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mHasUserChangedExpansion;
721685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
7351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserExpanded;
7431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek
7531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    /**
7631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * Has this notification been expanded while it was pinned
7731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     */
7831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    private boolean mExpandedWhenPinned;
791685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Is the user touching this row */
8051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserLocked;
811685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Are we showing the "public" version */
82a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    private boolean mShowingPublic;
83ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mSensitive;
843c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek    private boolean mSensitiveHiddenInGeneral;
85ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mShowingPublicInitialized;
8660122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek    private boolean mHideSensitiveForIntrinsicHeight;
8751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
881685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
891685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Is this notification expanded by the system. The expansion state can be overridden by the
901685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * user expansion.
911685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
921685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mIsSystemExpanded;
93dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
94dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
9583bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * Whether the notification is on the keyguard and the expansion is disabled.
96dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
9783bc78338437a460076a4b5778ded38440ac3501Selim Cinek    private boolean mOnKeyguard;
98dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
994b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private AnimatorSet mTranslateAnim;
1004b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private ArrayList<View> mTranslateableViews;
101be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPublicLayout;
102be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPrivateLayout;
1031685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mMaxExpandHeight;
1048d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private int mHeadsUpHeight;
105863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek    private View mVetoButton;
1060d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    private boolean mClearable;
10778403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private ExpansionLogger mLogger;
10878403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private String mLoggingKey;
1094b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private NotificationSettingsIconRow mSettingsIconRow;
1108d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private NotificationGuts mGuts;
111da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private NotificationData.Entry mEntry;
112b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    private StatusBarNotification mStatusBarNotification;
1133fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor    private String mAppName;
1141a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    private boolean mIsHeadsUp;
11598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private boolean mLastChronometerRunning = true;
116eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    private NotificationHeaderView mNotificationHeader;
1179c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek    private NotificationViewWrapper mNotificationHeaderWrapper;
118b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private ViewStub mChildrenContainerStub;
119b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationGroupManager mGroupManager;
120b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mChildrenExpanded;
121263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private boolean mIsSummaryWithChildren;
122b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationChildrenContainer mChildrenContainer;
1234b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private ViewStub mSettingsIconRowStub;
124ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    private ViewStub mGutsStub;
125b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mIsSystemChildExpanded;
126684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    private boolean mIsPinned;
1270e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski    private FalsingManager mFalsingManager;
12831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    private HeadsUpManager mHeadsUpManager;
129ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    private NotificationHeaderUtil mHeaderUtil = new NotificationHeaderUtil(this);
130b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
1315eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    private boolean mJustClicked;
1325a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek    private boolean mIconAnimationRunning;
13334d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    private boolean mShowNoBackground;
134388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    private ExpandableNotificationRow mNotificationParent;
135570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    private OnExpandClickListener mOnExpandClickListener;
136eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    private OnClickListener mExpandClickListener = new OnClickListener() {
137eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        @Override
138eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        public void onClick(View v) {
139624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek            if (!mShowingPublic && mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
140eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                mGroupManager.toggleGroupExpansion(mStatusBarNotification);
14131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                mOnExpandClickListener.onExpandClicked(mEntry,
142570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek                        mGroupManager.isGroupExpanded(mStatusBarNotification));
143eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            } else {
14431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                boolean nowExpanded;
14531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                if (isPinned()) {
14631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    nowExpanded = !mExpandedWhenPinned;
14731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    mExpandedWhenPinned = nowExpanded;
14831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                } else {
14931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    nowExpanded = !isExpanded();
15031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    setUserExpanded(nowExpanded);
15131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                }
152eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                notifyHeightChanged(true);
15331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                mOnExpandClickListener.onExpandClicked(mEntry, nowExpanded);
154eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
155eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        }
156eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    };
1575eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
1588d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPrivateLayout() {
1598d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPrivateLayout;
1608d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
1618d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
1628d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPublicLayout() {
1638d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPublicLayout;
1648d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
1658d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
166cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    public void setIconAnimationRunning(boolean running) {
167cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        setIconAnimationRunning(running, mPublicLayout);
168cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        setIconAnimationRunning(running, mPrivateLayout);
1695a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        setIconAnimationRunningForChild(running, mNotificationHeader);
1705a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        if (mIsSummaryWithChildren) {
1715a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            List<ExpandableNotificationRow> notificationChildren =
1725a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                    mChildrenContainer.getNotificationChildren();
1735a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
1745a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
1755a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                child.setIconAnimationRunning(running);
1765a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            }
1775a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        }
1785a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        mIconAnimationRunning = running;
179cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
180cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
181cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunning(boolean running, NotificationContentView layout) {
182cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (layout != null) {
183cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View contractedChild = layout.getContractedChild();
184cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View expandedChild = layout.getExpandedChild();
1858d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
186cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, contractedChild);
187cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, expandedChild);
1888d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            setIconAnimationRunningForChild(running, headsUpChild);
189cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
190cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
191cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
192cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunningForChild(boolean running, View child) {
193cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (child != null) {
194cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView icon = (ImageView) child.findViewById(com.android.internal.R.id.icon);
195cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(icon, running);
196cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView rightIcon = (ImageView) child.findViewById(
197cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    com.android.internal.R.id.right_icon);
198cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(rightIcon, running);
199cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
200cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
201cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
202cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconRunning(ImageView imageView, boolean running) {
203cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (imageView != null) {
204cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            Drawable drawable = imageView.getDrawable();
205cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            if (drawable instanceof AnimationDrawable) {
206cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
207cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
208cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
209cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
210cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
211cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
212cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            } else if (drawable instanceof AnimatedVectorDrawable) {
213cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimatedVectorDrawable animationDrawable = (AnimatedVectorDrawable) drawable;
214cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
215cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
216cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
217cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
218cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
219cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            }
220cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
221cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
222cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
223da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    public void onNotificationUpdated(NotificationData.Entry entry) {
224da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        mEntry = entry;
225da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        mStatusBarNotification = entry.notification;
226b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos        mPrivateLayout.onNotificationUpdated(entry);
227b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos        mPublicLayout.onNotificationUpdated(entry);
228757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek        mShowingPublicInitialized = false;
229757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek        updateClearability();
2308fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        if (mIsSummaryWithChildren) {
2318fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek            recreateNotificationHeader();
232c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            mChildrenContainer.onNotificationUpdated();
2338fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        }
2345a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        if (mIconAnimationRunning) {
2355a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            setIconAnimationRunning(true);
2365a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        }
237ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        if (mNotificationParent != null) {
238ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek            mNotificationParent.updateChildrenHeaderAppearance();
239ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        }
240263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
241624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek        // The public layouts expand button is always visible
242624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek        mPublicLayout.updateExpandButtons(true);
243da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateLimits();
244da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    }
245da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek
246da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private void updateLimits() {
247a1744872f4447dd370002a607c32776dffe519f5Selim Cinek        updateLimitsForView(mPrivateLayout);
248a1744872f4447dd370002a607c32776dffe519f5Selim Cinek        updateLimitsForView(mPublicLayout);
249a1744872f4447dd370002a607c32776dffe519f5Selim Cinek    }
250a1744872f4447dd370002a607c32776dffe519f5Selim Cinek
251a1744872f4447dd370002a607c32776dffe519f5Selim Cinek    private void updateLimitsForView(NotificationContentView layout) {
252a1744872f4447dd370002a607c32776dffe519f5Selim Cinek        boolean customView = layout.getContractedChild().getId()
253da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek                != com.android.internal.R.id.status_bar_latest_event_content;
254da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
255da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        int minHeight = customView && beforeN && !mIsSummaryWithChildren ?
256da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek                mNotificationMinHeightLegacy : mNotificationMinHeight;
257a1744872f4447dd370002a607c32776dffe519f5Selim Cinek        boolean headsUpCustom = layout.getHeadsUpChild() != null &&
258a1744872f4447dd370002a607c32776dffe519f5Selim Cinek                layout.getHeadsUpChild().getId()
259a1744872f4447dd370002a607c32776dffe519f5Selim Cinek                        != com.android.internal.R.id.status_bar_latest_event_content;
26077019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        int headsUpheight = headsUpCustom && beforeN ? mMaxHeadsUpHeightLegacy
26177019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek                : mMaxHeadsUpHeight;
262a1744872f4447dd370002a607c32776dffe519f5Selim Cinek        layout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight);
263b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
264b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
265b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    public StatusBarNotification getStatusBarNotification() {
266b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        return mStatusBarNotification;
267b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
268b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
269b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    public boolean isHeadsUp() {
270b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek        return mIsHeadsUp;
271b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
272b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
2731a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    public void setHeadsUp(boolean isHeadsUp) {
274c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        int intrinsicBefore = getIntrinsicHeight();
2751a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mIsHeadsUp = isHeadsUp;
2768d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mPrivateLayout.setHeadsUp(isHeadsUp);
277c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
278c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek            notifyHeightChanged(false  /* needsAnimation */);
279c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        }
2801a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    }
2811a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek
282b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setGroupManager(NotificationGroupManager groupManager) {
283b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mGroupManager = groupManager;
28483bc78338437a460076a4b5778ded38440ac3501Selim Cinek        mPrivateLayout.setGroupManager(groupManager);
285b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
286b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
287b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos    public void setRemoteInputController(RemoteInputController r) {
288b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos        mPrivateLayout.setRemoteInputController(r);
289b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos    }
290b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos
2913fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor    public void setAppName(String appName) {
2923fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor        mAppName = appName;
2933fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor        if (mSettingsIconRow != null) {
2943fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor            mSettingsIconRow.setAppName(mAppName);
2953fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor        }
2963fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor    }
2973fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor
298b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row) {
299b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        addChildNotification(row, -1);
300b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
301b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
302b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
303b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Add a child notification to this view.
304b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
305b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param row the row to add
306b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childIndex the index to add it at, if -1 it will be added at the end
307b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
308b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row, int childIndex) {
309b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer == null) {
310b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainerStub.inflate();
311b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
312b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainer.addNotification(row, childIndex);
313263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
314263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(true, this);
315b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
316b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
317b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void removeChildNotification(ExpandableNotificationRow row) {
318b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer != null) {
319b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.removeNotification(row);
320b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
321ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        mHeaderUtil.restoreNotificationHeader(row);
322263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
323263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(false, null);
324263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
325263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
326263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isChildInGroup() {
327a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        return mNotificationParent != null;
328263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
329263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
330388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public ExpandableNotificationRow getNotificationParent() {
331388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        return mNotificationParent;
332388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
333388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
334263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    /**
335263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param isChildInGroup Is this notification now in a group
336263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param parent the new parent notification
337263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     */
338a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {;
339a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        boolean childInGroup = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
340a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mNotificationParent = childInGroup ? parent : null;
341a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mPrivateLayout.setIsChildInGroup(childInGroup);
342a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateNoBackgroundState();
34334d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    }
34434d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek
34534d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    @Override
3467210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    public boolean onTouchEvent(MotionEvent event) {
3477210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        if (event.getActionMasked() != MotionEvent.ACTION_DOWN
3487210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek                || !isChildInGroup() || isGroupExpanded()) {
3497210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek            return super.onTouchEvent(event);
3507210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        } else {
3517210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek            return false;
3527210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        }
3537210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    }
3547210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek
3557210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    @Override
356f062580d395a8c99631c104d6aec250f961152ddMady Mellor    protected boolean handleSlideBack() {
357f062580d395a8c99631c104d6aec250f961152ddMady Mellor        if (mSettingsIconRow != null && mSettingsIconRow.isVisible()) {
358f062580d395a8c99631c104d6aec250f961152ddMady Mellor            animateTranslateNotification(0 /* targetLeft */);
359f062580d395a8c99631c104d6aec250f961152ddMady Mellor            return true;
360f062580d395a8c99631c104d6aec250f961152ddMady Mellor        }
361f062580d395a8c99631c104d6aec250f961152ddMady Mellor        return false;
362f062580d395a8c99631c104d6aec250f961152ddMady Mellor    }
363f062580d395a8c99631c104d6aec250f961152ddMady Mellor
364f062580d395a8c99631c104d6aec250f961152ddMady Mellor    @Override
36534d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    protected boolean shouldHideBackground() {
36634d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek        return super.shouldHideBackground() || mShowNoBackground;
367263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
368263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
369263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    @Override
370263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isSummaryWithChildren() {
371263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        return mIsSummaryWithChildren;
372b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
373b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
374b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    @Override
375b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public boolean areChildrenExpanded() {
376b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenExpanded;
377b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
378b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
379b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public List<ExpandableNotificationRow> getNotificationChildren() {
380b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenContainer == null ? null : mChildrenContainer.getNotificationChildren();
381b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
382b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
383eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    public int getNumberOfNotificationChildren() {
384eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        if (mChildrenContainer == null) {
385eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek            return 0;
386eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        }
387eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mChildrenContainer.getNotificationChildren().size();
388eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    }
389eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek
390b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
391b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Apply the order given in the list to the children.
392b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
393b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childOrder the new list order
394b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @return whether the list order has changed
395b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
396b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder) {
397b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder);
398b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
399b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
400b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void getChildrenStates(StackScrollState resultState) {
40183bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
402b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            StackViewState parentState = resultState.getViewStateForView(this);
403b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.getState(resultState, parentState);
404b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
405b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
406b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
407b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void applyChildrenState(StackScrollState state) {
40883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
409b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.applyState(state);
410b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
411b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
412b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
413b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void prepareExpansionChanged(StackScrollState state) {
41483bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
415b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.prepareExpansionChanged(state);
416b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
417b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
418b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
419b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void startChildAnimation(StackScrollState finalState,
4209969559da02f54fcbd7832de9810507a581d98d8Selim Cinek            StackStateAnimator stateAnimator, long delay, long duration) {
42183bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
4229969559da02f54fcbd7832de9810507a581d98d8Selim Cinek            mChildrenContainer.startAnimationToState(finalState, stateAnimator, delay,
423b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                    duration);
424b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
425b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
426b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
427b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public ExpandableNotificationRow getViewAtPosition(float y) {
42843d30f03f45f3f9ad3955f5c83f4d21f26891de6Selim Cinek        if (!mIsSummaryWithChildren || !mChildrenExpanded) {
429b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return this;
430b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
431b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ExpandableNotificationRow view = mChildrenContainer.getViewAtPosition(y);
432b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return view == null ? this : view;
433b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
434b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
435b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
436ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public NotificationGuts getGuts() {
437ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        return mGuts;
438ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
439ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
440684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    /**
441684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
442684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * the notification will be rendered on top of the screen.
443684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     *
444684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * @param pinned whether it is pinned
445684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     */
446684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public void setPinned(boolean pinned) {
447684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        mIsPinned = pinned;
44831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if (pinned) {
44931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            setIconAnimationRunning(true);
45031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            mExpandedWhenPinned = false;
45131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mExpandedWhenPinned) {
45231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            setUserExpanded(true);
45331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        }
45498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(mLastChronometerRunning);
455b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
456b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
457684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public boolean isPinned() {
458684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        return mIsPinned;
459b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
460b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
46131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    /**
46231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * @param atLeastMinHeight should the value returned be at least the minimum height.
46331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     *                         Used to avoid cyclic calls
46431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * @return the height of the heads up notification when pinned
46531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     */
46631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    public int getPinnedHeadsUpHeight(boolean atLeastMinHeight) {
46777019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        if (mIsSummaryWithChildren) {
46877019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek            return mChildrenContainer.getIntrinsicHeight();
46977019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        }
47031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if(mExpandedWhenPinned) {
47131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return Math.max(getMaxExpandHeight(), mHeadsUpHeight);
47231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (atLeastMinHeight) {
473567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek            return Math.max(getCollapsedHeight(), mHeadsUpHeight);
47431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else {
47531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return mHeadsUpHeight;
47631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        }
477b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
478b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
4795eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
4805eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * Mark whether this notification was just clicked, i.e. the user has just clicked this
4815eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * notification in this frame.
4825eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
4835eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public void setJustClicked(boolean justClicked) {
4845eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        mJustClicked = justClicked;
4855eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
4865eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
4875eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
4885eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * @return true if this notification has been clicked in this frame, false otherwise
4895eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
4905eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public boolean wasJustClicked() {
4915eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        return mJustClicked;
4925eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
4935eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
49498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    public void setChronometerRunning(boolean running) {
49598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        mLastChronometerRunning = running;
49698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPrivateLayout);
49798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPublicLayout);
49898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (mChildrenContainer != null) {
49998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
50098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                    mChildrenContainer.getNotificationChildren();
50198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
50298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
50398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                child.setChronometerRunning(running);
50498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
50598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
50698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
50798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
50898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunning(boolean running, NotificationContentView layout) {
50998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (layout != null) {
51098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            running = running || isPinned();
51198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View contractedChild = layout.getContractedChild();
51298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View expandedChild = layout.getExpandedChild();
51398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
51498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, contractedChild);
51598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, expandedChild);
51698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, headsUpChild);
51798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
51898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
51998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
52098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunningForChild(boolean running, View child) {
52198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (child != null) {
52298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View chronometer = child.findViewById(com.android.internal.R.id.chronometer);
52398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            if (chronometer instanceof Chronometer) {
52498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ((Chronometer) chronometer).setStarted(running);
52598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
52698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
52798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
52898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
529ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    public NotificationHeaderView getNotificationHeader() {
530ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        if (mNotificationHeader != null) {
531ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek            return mNotificationHeader;
5328d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        }
533ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        return mPrivateLayout.getNotificationHeader();
5348d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek    }
5358d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek
53634eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek    private NotificationHeaderView getVisibleNotificationHeader() {
53734eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        if (mNotificationHeader != null) {
53834eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek            return mNotificationHeader;
53934eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        }
54034eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        return getShowingLayout().getVisibleNotificationHeader();
54134eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek    }
54234eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek
543570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) {
544570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek        mOnExpandClickListener = onExpandClickListener;
545570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    }
546570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek
54731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    public void setHeadsUpManager(HeadsUpManager headsUpManager) {
54831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        mHeadsUpManager = headsUpManager;
54931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    }
55031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek
55101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    public void reInflateViews() {
55201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        initDimens();
55301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        if (mIsSummaryWithChildren) {
55401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            removeView(mNotificationHeader);
55501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mNotificationHeader = null;
55601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            recreateNotificationHeader();
55701af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            if (mChildrenContainer != null) {
55801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek                mChildrenContainer.reInflateViews();
55901af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            }
56001af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        }
56101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        if (mGuts != null) {
56201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            View oldGuts = mGuts;
56301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            int index = indexOfChild(oldGuts);
56401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            removeView(oldGuts);
56501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mGuts = (NotificationGuts) LayoutInflater.from(mContext).inflate(
56601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek                    R.layout.notification_guts, this, false);
56701af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mGuts.setVisibility(oldGuts.getVisibility());
56801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            addView(mGuts, index);
56901af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        }
5704b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mSettingsIconRow != null) {
5714b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            View oldSettings = mSettingsIconRow;
5724b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            int settingsIndex = indexOfChild(oldSettings);
5734b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            removeView(oldSettings);
5744b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRow = (NotificationSettingsIconRow) LayoutInflater.from(mContext).inflate(
5754b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                    R.layout.notification_settings_icon_row, this, false);
5764b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRow.setNotificationRowParent(ExpandableNotificationRow.this);
5773fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor            mSettingsIconRow.setAppName(mAppName);
5784b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRow.setVisibility(oldSettings.getVisibility());
5794b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            addView(mSettingsIconRow, settingsIndex);
5804b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
5814b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
582de33a4ad5696173942dca363339027c892927e8dSelim Cinek        mPrivateLayout.reInflateViews();
583de33a4ad5696173942dca363339027c892927e8dSelim Cinek        mPublicLayout.reInflateViews();
58401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    }
58501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek
586c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek    public void setContentBackground(int customBackgroundColor, boolean animate,
587c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek            NotificationContentView notificationContentView) {
588c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        if (getShowingLayout() == notificationContentView) {
589c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek            setTintColor(customBackgroundColor, animate);
590c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        }
591c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek    }
592c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek
5930bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos    public void closeRemoteInput() {
5940bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos        mPrivateLayout.closeRemoteInput();
5950bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos        mPublicLayout.closeRemoteInput();
5960bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos    }
5970bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos
598c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    /**
599c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek     * Set by how much the single line view should be indented.
600c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek     */
601c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    public void setSingleLineWidthIndention(int indention) {
602c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        mPrivateLayout.setSingleLineWidthIndention(indention);
603c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    }
604c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek
605c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    public int getNotificationColor() {
606c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        int color = getStatusBarNotification().getNotification().color;
607c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        if (color == Notification.COLOR_DEFAULT) {
608c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            return mContext.getColor(com.android.internal.R.color.notification_icon_default_color);
609c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        }
610c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        return color;
611c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    }
612c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek
613c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    public HybridNotificationView getSingleLineView() {
614c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        return mPrivateLayout.getSingleLineView();
615c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    }
616c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek
617f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek    public boolean isOnKeyguard() {
618f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek        return mOnKeyguard;
619f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek    }
620f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek
621c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek    public void removeAllChildren() {
622c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        List<ExpandableNotificationRow> notificationChildren
623c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek                = mChildrenContainer.getNotificationChildren();
624c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        ArrayList<ExpandableNotificationRow> clonedList = new ArrayList<>(notificationChildren);
625c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        for (int i = 0; i < clonedList.size(); i++) {
626c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            ExpandableNotificationRow row = clonedList.get(i);
627c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            mChildrenContainer.removeNotification(row);
628c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            mHeaderUtil.restoreNotificationHeader(row);
629c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            row.setIsChildInGroup(false, null);
630c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        }
631c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        onChildrenCountChanged();
632c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek    }
633c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek
63478403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public interface ExpansionLogger {
63578403d79739605511ea88b653564d81d7bf4bbbaChris Wren        public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
63678403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
6371685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
63851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
63951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        super(context, attrs);
6400e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager = FalsingManager.getInstance(context);
64101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        initDimens();
64201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    }
64301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek
64401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private void initDimens() {
645f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMinHeightLegacy = getFontScaledHeight(R.dimen.notification_min_height_legacy);
646f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMinHeight = getFontScaledHeight(R.dimen.notification_min_height);
647f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMaxHeight = getFontScaledHeight(R.dimen.notification_max_height);
648f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mMaxHeadsUpHeightLegacy = getFontScaledHeight(
64977019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek                R.dimen.notification_max_heads_up_height_legacy);
650f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mMaxHeadsUpHeight = getFontScaledHeight(R.dimen.notification_max_heads_up_height);
651f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    }
652f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek
653f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    /**
654f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     * @param dimenId the dimen to look up
655f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     * @return the font scaled dimen as if it were in sp but doesn't shrink sizes below dp
656f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     */
657f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    private int getFontScaledHeight(int dimenId) {
658f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        int dimensionPixelSize = getResources().getDimensionPixelSize(dimenId);
659f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        float factor = Math.max(1.0f, getResources().getDisplayMetrics().scaledDensity /
660f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek                getResources().getDisplayMetrics().density);
661f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        return (int) (dimensionPixelSize * factor);
66251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
66351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
664a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    /**
665a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     * Resets this view so it can be re-used for an updated notification.
666a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     */
66722f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer    @Override
668a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    public void reset() {
66922f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer        super.reset();
67078403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
671a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mExpandable = false;
672a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mHasUserChangedExpansion = false;
673a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mUserLocked = false;
674a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mShowingPublic = false;
675ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = false;
676ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = false;
677a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mIsSystemExpanded = false;
67883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        mOnKeyguard = false;
67951d94917c7dc53845701702bfd63f102a3a2dbc8Selim Cinek        mPublicLayout.reset();
68051d94917c7dc53845701702bfd63f102a3a2dbc8Selim Cinek        mPrivateLayout.reset();
68131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        resetHeight();
6824b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        resetTranslation();
68331094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        logExpansionEvent(false, wasExpanded);
68431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    }
68531094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek
68631094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public void resetHeight() {
687a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mMaxExpandHeight = 0;
6888d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mHeadsUpHeight = 0;
68931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        onHeightReset();
6906e28a678c7f9fe2cae5a51bfdbab3071a2d8d0baSelim Cinek        requestLayout();
691a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    }
692a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer
693251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    @Override
694251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    protected void onFinishInflate() {
695251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi        super.onFinishInflate();
696be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
697fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        mPublicLayout.setContainingNotification(this);
698be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
699eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.setExpandClickListener(mExpandClickListener);
700fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        mPrivateLayout.setContainingNotification(this);
701eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPublicLayout.setExpandClickListener(mExpandClickListener);
7024b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mSettingsIconRowStub = (ViewStub) findViewById(R.id.settings_icon_row_stub);
7034b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mSettingsIconRowStub.setOnInflateListener(new ViewStub.OnInflateListener() {
7044b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            @Override
7054b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            public void onInflate(ViewStub stub, View inflated) {
7064b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mSettingsIconRow = (NotificationSettingsIconRow) inflated;
7074b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mSettingsIconRow.setNotificationRowParent(ExpandableNotificationRow.this);
7083fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor                mSettingsIconRow.setAppName(mAppName);
7094b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
7104b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        });
711ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub = (ViewStub) findViewById(R.id.notification_guts_stub);
712ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub.setOnInflateListener(new ViewStub.OnInflateListener() {
713b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            @Override
714b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            public void onInflate(ViewStub stub, View inflated) {
715b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts = (NotificationGuts) inflated;
716b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setClipTopAmount(getClipTopAmount());
717b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setActualHeight(getActualHeight());
718ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek                mGutsStub = null;
719b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            }
720b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        });
721b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub = (ViewStub) findViewById(R.id.child_container_stub);
722b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub.setOnInflateListener(new ViewStub.OnInflateListener() {
723b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
724b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            @Override
725b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            public void onInflate(ViewStub stub, View inflated) {
726b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                mChildrenContainer = (NotificationChildrenContainer) inflated;
727388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek                mChildrenContainer.setNotificationParent(ExpandableNotificationRow.this);
728c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                mChildrenContainer.onNotificationUpdated();
7294b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mTranslateableViews.add(mChildrenContainer);
730b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            }
731b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        });
732863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek        mVetoButton = findViewById(R.id.veto);
7334b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
7344b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        // Add the views that we translate to reveal the gear
7354b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews = new ArrayList<View>();
7364b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        for (int i = 0; i < getChildCount(); i++) {
7374b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mTranslateableViews.add(getChildAt(i));
7384b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
7394b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        // Remove views that don't translate
7404b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews.remove(mVetoButton);
7414b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews.remove(mSettingsIconRowStub);
7424b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews.remove(mChildrenContainerStub);
7434b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        mTranslateableViews.remove(mGutsStub);
7444b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
7454b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
74634958fa272c9216db4002546c3efad692b3d7775Mady Mellor    private void setTranslationForOutline(float translationX) {
7474b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        setOutlineRect(false, translationX, getTop(), getRight() + translationX, getBottom());
7484b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
7494b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
7504b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public void resetTranslation() {
7514b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mTranslateableViews != null) {
7524b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            for (int i = 0; i < mTranslateableViews.size(); i++) {
7534b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mTranslateableViews.get(i).setTranslationX(0);
7544b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
7554b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            setTranslationForOutline(0);
7564b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
7574b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mSettingsIconRow != null) {
7584b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRow.resetState();
7594b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
7604b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
7614b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
7624b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public void animateTranslateNotification(final float leftTarget) {
7634b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mTranslateAnim != null) {
7644b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mTranslateAnim.cancel();
7654b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
76634958fa272c9216db4002546c3efad692b3d7775Mady Mellor        mTranslateAnim = (AnimatorSet) getTranslateViewAnimator(leftTarget,
76734958fa272c9216db4002546c3efad692b3d7775Mady Mellor                null /* updateListener */);
76834958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (mTranslateAnim != null) {
76934958fa272c9216db4002546c3efad692b3d7775Mady Mellor            mTranslateAnim.start();
77034958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
77134958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
77234958fa272c9216db4002546c3efad692b3d7775Mady Mellor
77334958fa272c9216db4002546c3efad692b3d7775Mady Mellor    @Override
77434958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public void setTranslation(float translationX) {
77534958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (areGutsExposed()) {
77634958fa272c9216db4002546c3efad692b3d7775Mady Mellor            // Don't translate if guts are showing.
77734958fa272c9216db4002546c3efad692b3d7775Mady Mellor            return;
77834958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
77934958fa272c9216db4002546c3efad692b3d7775Mady Mellor        // Translate the group of views
78034958fa272c9216db4002546c3efad692b3d7775Mady Mellor        for (int i = 0; i < mTranslateableViews.size(); i++) {
78134958fa272c9216db4002546c3efad692b3d7775Mady Mellor            if (mTranslateableViews.get(i) != null) {
78234958fa272c9216db4002546c3efad692b3d7775Mady Mellor                mTranslateableViews.get(i).setTranslationX(translationX);
78334958fa272c9216db4002546c3efad692b3d7775Mady Mellor            }
78434958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
78534958fa272c9216db4002546c3efad692b3d7775Mady Mellor        setTranslationForOutline(translationX);
78634958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (mSettingsIconRow != null) {
78734958fa272c9216db4002546c3efad692b3d7775Mady Mellor            mSettingsIconRow.updateSettingsIcons(translationX, getMeasuredWidth());
78834958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
78934958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
79034958fa272c9216db4002546c3efad692b3d7775Mady Mellor
79134958fa272c9216db4002546c3efad692b3d7775Mady Mellor    @Override
79234958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public float getTranslation() {
79334958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (mTranslateableViews != null && mTranslateableViews.size() > 0) {
79434958fa272c9216db4002546c3efad692b3d7775Mady Mellor            // All of the views in the list should have same translation, just use first one.
79534958fa272c9216db4002546c3efad692b3d7775Mady Mellor            return mTranslateableViews.get(0).getTranslationX();
79634958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
79734958fa272c9216db4002546c3efad692b3d7775Mady Mellor        return 0;
79834958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
79934958fa272c9216db4002546c3efad692b3d7775Mady Mellor
80034958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public Animator getTranslateViewAnimator(final float leftTarget,
80134958fa272c9216db4002546c3efad692b3d7775Mady Mellor            AnimatorUpdateListener listener) {
802723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor        if (mTranslateAnim != null) {
803723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor            mTranslateAnim.cancel();
804723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor        }
80534958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (areGutsExposed()) {
80634958fa272c9216db4002546c3efad692b3d7775Mady Mellor            // No translation if guts are exposed.
80734958fa272c9216db4002546c3efad692b3d7775Mady Mellor            return null;
80834958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
8094b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        AnimatorSet set = new AnimatorSet();
8104b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mTranslateableViews != null) {
8114b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            for (int i = 0; i < mTranslateableViews.size(); i++) {
8124b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                final View animView = mTranslateableViews.get(i);
8134b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                final ObjectAnimator translateAnim = ObjectAnimator.ofFloat(
8144b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        animView, "translationX", leftTarget);
8154b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                if (i == 0) {
8164b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                    translateAnim.addUpdateListener(new AnimatorUpdateListener() {
8174b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        @Override
8184b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        public void onAnimationUpdate(ValueAnimator animation) {
8194b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                            setTranslationForOutline((float) animation.getAnimatedValue());
82034958fa272c9216db4002546c3efad692b3d7775Mady Mellor                            if (mSettingsIconRow != null) {
82134958fa272c9216db4002546c3efad692b3d7775Mady Mellor                                mSettingsIconRow.updateSettingsIcons(
82234958fa272c9216db4002546c3efad692b3d7775Mady Mellor                                        (float) animation.getAnimatedValue(), getMeasuredWidth());
82334958fa272c9216db4002546c3efad692b3d7775Mady Mellor                            }
8244b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        }
8254b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                    });
82634958fa272c9216db4002546c3efad692b3d7775Mady Mellor                    if (listener != null) {
82734958fa272c9216db4002546c3efad692b3d7775Mady Mellor                        translateAnim.addUpdateListener(listener);
82834958fa272c9216db4002546c3efad692b3d7775Mady Mellor                    }
829723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                    translateAnim.addListener(new AnimatorListenerAdapter() {
830723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                        boolean cancelled = false;
831723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor
832723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                        @Override
833723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                        public void onAnimationCancel(Animator anim) {
834723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                            cancelled = true;
8354b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                        }
836723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor
837723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                        @Override
838723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                        public void onAnimationEnd(Animator anim) {
839723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                            if (!cancelled && mSettingsIconRow != null && leftTarget == 0) {
840723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                                mSettingsIconRow.resetState();
841723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                                mTranslateAnim = null;
842723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                            }
843723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                        }
844723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                    });
845723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                }
8464b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                set.play(translateAnim);
8474b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
8484b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
849723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor        mTranslateAnim = set;
85034958fa272c9216db4002546c3efad692b3d7775Mady Mellor        return set;
8514b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
8524b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
8534b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public float getSpaceForGear() {
8544b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mSettingsIconRow != null) {
8554b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            return mSettingsIconRow.getSpaceForGear();
8564b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
8574b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        return 0;
8584b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
8594b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
8604b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public NotificationSettingsIconRow getSettingsRow() {
8614b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mSettingsIconRow == null) {
8624b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mSettingsIconRowStub.inflate();
8634b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
8644b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        return mSettingsIconRow;
8654b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
8664b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
867ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public void inflateGuts() {
868ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        if (mGuts == null) {
869ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek            mGutsStub.inflate();
870ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        }
871ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
872ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
873da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private void updateChildrenVisibility() {
874d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        mPrivateLayout.setVisibility(!mShowingPublic && !mIsSummaryWithChildren ? VISIBLE
875d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                : INVISIBLE);
876ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek        if (mChildrenContainer != null) {
877ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek            mChildrenContainer.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
878ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek                    : INVISIBLE);
879ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek        }
880ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek        if (mNotificationHeader != null) {
881ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek            mNotificationHeader.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
882ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek                    : INVISIBLE);
883b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
884da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        // The limits might have changed if the view suddenly became a group or vice versa
885da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateLimits();
886b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
887b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
888fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    @Override
889a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
890a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        if (super.onRequestSendAccessibilityEventInternal(child, event)) {
891fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // Add a record for the entire layout since its content is somehow small.
892fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // The event comes from a leaf view that is interacted with.
893fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            AccessibilityEvent record = AccessibilityEvent.obtain();
894fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            onInitializeAccessibilityEvent(record);
895fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            dispatchPopulateAccessibilityEvent(record);
896fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            event.appendRecord(record);
897fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            return true;
898fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        }
899fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        return false;
900c5dc0d0cce373fbf292e13633c114a431d747167Jorim Jaggi    }
90151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
902e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    @Override
9034e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    public void setDark(boolean dark, boolean fade, long delay) {
9044e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        super.setDark(dark, fade, delay);
905e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        final NotificationContentView showing = getShowingLayout();
906e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        if (showing != null) {
9074e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            showing.setDark(dark, fade, delay);
908e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        }
9099c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek        if (mIsSummaryWithChildren) {
910c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            mChildrenContainer.setDark(dark, fade, delay);
9119c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek            mNotificationHeaderWrapper.setDark(dark, fade, delay);
9129c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek        }
913e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    }
914e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock
91551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isExpandable() {
916388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
917388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return !mChildrenExpanded;
918388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
91951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mExpandable;
92051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
92151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
92251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setExpandable(boolean expandable) {
92351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mExpandable = expandable;
924eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
92551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
92651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
9274ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    @Override
9284ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    public void setClipToActualHeight(boolean clipToActualHeight) {
929084c16b8b380e7ff0d38d9e2846db321f0214931Selim Cinek        super.setClipToActualHeight(clipToActualHeight || isUserLocked());
930084c16b8b380e7ff0d38d9e2846db321f0214931Selim Cinek        getShowingLayout().setClipToActualHeight(clipToActualHeight || isUserLocked());
9314ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    }
9324ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek
9331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
9341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the user has changed the expansion state
9351685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
9361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean hasUserChangedExpansion() {
9371685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mHasUserChangedExpansion;
9381685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
9391685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
94051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserExpanded() {
94151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserExpanded;
94251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
94351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
9441685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
9451685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the user
9461685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
9471685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param userExpanded whether the user wants this notification to be expanded
9481685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
94951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserExpanded(boolean userExpanded) {
950388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        setUserExpanded(userExpanded, false /* allowChildExpansion */);
951388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
952388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
953388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    /**
954388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * Set this notification to be expanded by the user
955388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     *
956388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param userExpanded whether the user wants this notification to be expanded
957388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param allowChildExpansion whether a call to this method allows expanding children
958388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     */
959388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) {
9600e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager.setNotificationExpanded();
961388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic && allowChildExpansion) {
962388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            mGroupManager.setGroupExpanded(mStatusBarNotification, userExpanded);
963388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return;
964388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
965a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        if (userExpanded && !mExpandable) return;
96678403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
9671685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mHasUserChangedExpansion = true;
96851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserExpanded = userExpanded;
96978403d79739605511ea88b653564d81d7bf4bbbaChris Wren        logExpansionEvent(true, wasExpanded);
97051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
97151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
972ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    public void resetUserExpansion() {
973ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mHasUserChangedExpansion = false;
974ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mUserExpanded = false;
975ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    }
976ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek
97751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserLocked() {
97851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserLocked;
97951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
98051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
98151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserLocked(boolean userLocked) {
98251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserLocked = userLocked;
9838f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek        mPrivateLayout.setUserExpanding(userLocked);
98442357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        if (mIsSummaryWithChildren) {
98542357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            mChildrenContainer.setUserLocked(userLocked);
98642357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        }
98751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
98851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
9891685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
9901685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return has the system set this notification to be expanded
9911685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
9921685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean isSystemExpanded() {
9931685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mIsSystemExpanded;
9941685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
9951685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
9961685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
9971685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the system.
9981685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
9991685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param expand whether the system wants this notification to be expanded.
10001685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
10011685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setSystemExpanded(boolean expand) {
100231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        if (expand != mIsSystemExpanded) {
100331094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
100431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            mIsSystemExpanded = expand;
1005b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            notifyHeightChanged(false /* needsAnimation */);
100631094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            logExpansionEvent(false, wasExpanded);
1007c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            if (mChildrenContainer != null) {
1008c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                mChildrenContainer.updateGroupOverflow();
1009c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            }
101031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
1011dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    }
1012dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
1013dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
101483bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * @param onKeyguard whether to prevent notification expansion
1015dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
101683bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public void setOnKeyguard(boolean onKeyguard) {
101783bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (onKeyguard != mOnKeyguard) {
101831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
101983bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mOnKeyguard = onKeyguard;
102031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            logExpansionEvent(false, wasExpanded);
102131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            if (wasExpanded != isExpanded()) {
1022c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                if (mIsSummaryWithChildren) {
1023c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                    mChildrenContainer.updateGroupOverflow();
1024c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                }
10254b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                notifyHeightChanged(false /* needsAnimation */);
102631094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            }
102731094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
10281685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
10291685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
10301685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
10310d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     * @return Can the underlying notification be cleared?
10320d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     */
10330d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    public boolean isClearable() {
1034a37774f098a5204947ff4b4787c4b753bb9016dbSelim Cinek        return mStatusBarNotification != null && mStatusBarNotification.isClearable();
10350d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
10360d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
10379cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    @Override
10389cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    public int getIntrinsicHeight() {
1039be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (isUserLocked()) {
1040be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            return getActualHeight();
1041be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
1042d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        if (mGuts != null && mGuts.areGutsExposed()) {
1043d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return mGuts.getHeight();
1044d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else if ((isChildInGroup() && !isGroupExpanded())) {
1045d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return mPrivateLayout.getMinHeight();
1046d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else if (mSensitive && mHideSensitiveForIntrinsicHeight) {
1047d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return getMinHeight();
104883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        } else if (mIsSummaryWithChildren && !mOnKeyguard) {
1049eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getIntrinsicHeight();
105060122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek        } else if (mIsHeadsUp) {
105131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            if (isPinned()) {
105231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                return getPinnedHeadsUpHeight(true /* atLeastMinHeight */);
105331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            } else if (isExpanded()) {
1054d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                return Math.max(getMaxExpandHeight(), mHeadsUpHeight);
10558d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            } else {
1056567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek                return Math.max(getCollapsedHeight(), mHeadsUpHeight);
10578d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            }
105831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (isExpanded()) {
105983bc78338437a460076a4b5778ded38440ac3501Selim Cinek            return getMaxExpandHeight();
1060d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else {
1061567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek            return getCollapsedHeight();
10621685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        }
1063b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
10641685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
1065eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    private boolean isGroupExpanded() {
1066eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mGroupManager.isGroupExpanded(mStatusBarNotification);
1067b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1068b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1069eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    /**
1070eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek     * @return whether this view has a header on the top of the content
1071eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek     */
1072eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    private boolean hasNotificationHeader() {
1073eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mIsSummaryWithChildren;
10741685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
10751685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
1076263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private void onChildrenCountChanged() {
10778fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        mIsSummaryWithChildren = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS
10782a7393410b6390831143dca198438a4e58bdf88aSelim Cinek                && mChildrenContainer != null && mChildrenContainer.getChildCount() > 0;
10798fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        if (mIsSummaryWithChildren) {
10808fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek            if (mNotificationHeader == null) {
1081eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                recreateNotificationHeader();
1082eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
1083263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        }
1084eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
1085ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        updateChildrenHeaderAppearance();
1086da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateChildrenVisibility();
1087263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
1088263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
10891685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
10901685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Check whether the view state is currently expanded. This is given by the system in {@link
10911685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * #setSystemExpanded(boolean)} and can be overridden by user expansion or
10921685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
10931685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * view can differ from this state, if layout params are modified from outside.
10941685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
10951685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the view state is currently expanded.
10961685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
109783bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public boolean isExpanded() {
1098e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek        return isExpanded(false /* allowOnKeyguard */);
1099e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek    }
1100e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek
1101e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek    public boolean isExpanded(boolean allowOnKeyguard) {
1102e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek        return (!mOnKeyguard || allowOnKeyguard)
1103b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                && (!hasUserChangedExpansion() && (isSystemExpanded() || isSystemChildExpanded())
1104b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                || isUserExpanded());
1105b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1106b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1107b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean isSystemChildExpanded() {
1108b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mIsSystemChildExpanded;
1109b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1110b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1111b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setSystemChildExpanded(boolean expanded) {
1112b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mIsSystemChildExpanded = expanded;
11131685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
11141685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
11151685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    @Override
11161685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
11171685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        super.onLayout(changed, left, top, right, bottom);
11188d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        updateMaxHeights();
11191685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
11201685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
11218d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private void updateMaxHeights() {
1122d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        int intrinsicBefore = getIntrinsicHeight();
11238d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View expandedChild = mPrivateLayout.getExpandedChild();
11248d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        if (expandedChild == null) {
11258d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            expandedChild = mPrivateLayout.getContractedChild();
11268d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
11278d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mMaxExpandHeight = expandedChild.getHeight();
11288d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View headsUpChild = mPrivateLayout.getHeadsUpChild();
11291f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        if (headsUpChild == null) {
11301f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek            headsUpChild = mPrivateLayout.getContractedChild();
11318d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
11321f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        mHeadsUpHeight = headsUpChild.getHeight();
1133d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
1134b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            notifyHeightChanged(false  /* needsAnimation */);
1135d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        }
1136d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek    }
1137d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek
1138fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    @Override
1139fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    public void notifyHeightChanged(boolean needsAnimation) {
1140fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        super.notifyHeightChanged(needsAnimation);
1141fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        getShowingLayout().requestSelectLayout(needsAnimation || isUserLocked());
1142fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    }
1143fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek
11443c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek    public void setSensitive(boolean sensitive, boolean hideSensitive) {
1145ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = sensitive;
11463c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek        mSensitiveHiddenInGeneral = hideSensitive;
1147ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1148ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
1149ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
115060122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek        mHideSensitiveForIntrinsicHeight = hideSensitive;
1151a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek        if (mIsSummaryWithChildren) {
1152a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
1153a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek                    mChildrenContainer.getNotificationChildren();
1154a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
1155a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
1156a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek                child.setHideSensitiveForIntrinsicHeight(hideSensitive);
1157a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek            }
1158a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek        }
1159ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1160ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
1161ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
1162ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            long duration) {
1163ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        boolean oldShowingPublic = mShowingPublic;
1164ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublic = mSensitive && hideSensitive;
1165ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
1166ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            return;
1167ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
1168a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
1169a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler        // bail out if no public version
11701685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        if (mPublicLayout.getChildCount() == 0) return;
1171a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
1172ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (!animated) {
1173ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.animate().cancel();
1174ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.animate().cancel();
1175ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setAlpha(1f);
1176ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.setAlpha(1f);
1177ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
1178d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            updateChildrenVisibility();
1179ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        } else {
1180ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            animateShowingPublic(delay, duration);
1181ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
1182c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        NotificationContentView showingLayout = getShowingLayout();
1183c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        showingLayout.updateBackgroundColor(animated);
1184eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
1185757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek        updateClearability();
1186ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = true;
1187ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1188ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
1189ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private void animateShowingPublic(long delay, long duration) {
1190d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] privateViews = mIsSummaryWithChildren ?
1191d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                new View[] {mChildrenContainer, mNotificationHeader}
1192d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                : new View[] {mPrivateLayout};
1193d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] publicViews = new View[] {mPublicLayout};
1194d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] hiddenChildren = mShowingPublic ? privateViews : publicViews;
1195d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] shownChildren = mShowingPublic ? publicViews : privateViews;
1196d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        for (final View hiddenView : hiddenChildren) {
1197d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.setVisibility(View.VISIBLE);
1198d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.animate().cancel();
1199d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.animate()
1200d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .alpha(0f)
1201d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setStartDelay(delay)
1202d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setDuration(duration)
1203d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .withEndAction(new Runnable() {
1204d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        @Override
1205d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        public void run() {
1206d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                            hiddenView.setVisibility(View.INVISIBLE);
1207d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        }
1208d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    });
1209d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        }
1210d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        for (View showView : shownChildren) {
1211d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.setVisibility(View.VISIBLE);
1212d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.setAlpha(0f);
1213d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.animate().cancel();
1214d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.animate()
1215d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .alpha(1f)
1216d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setStartDelay(delay)
1217d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setDuration(duration);
1218d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        }
12190d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
12200d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
12213776fe007550451bb237c705d333247eab2a291cSelim Cinek    public boolean mustStayOnScreen() {
12223776fe007550451bb237c705d333247eab2a291cSelim Cinek        return mIsHeadsUp;
12233776fe007550451bb237c705d333247eab2a291cSelim Cinek    }
12243776fe007550451bb237c705d333247eab2a291cSelim Cinek
1225757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek    private void updateClearability() {
12260d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        // public versions cannot be dismissed
12273c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek        mVetoButton.setVisibility(isClearable() && (!mShowingPublic
12283c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek                || !mSensitiveHiddenInGeneral) ? View.VISIBLE : View.GONE);
1229a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
1230251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi
1231b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setChildrenExpanded(boolean expanded, boolean animate) {
1232b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenExpanded = expanded;
12337b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek        if (mNotificationHeader != null) {
12347b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek            mNotificationHeader.setExpanded(expanded);
12357b83639c34cb8b52f915099973e0892c5fbfd674Selim Cinek        }
123683bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mChildrenContainer != null) {
123783bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mChildrenContainer.setChildrenExpanded(expanded);
123883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
1239b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1240b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1241b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public static void applyTint(View v, int color) {
1242b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        int alpha;
1243b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (color != 0) {
1244b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = COLORED_DIVIDER_ALPHA;
1245b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
1246b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            color = 0xff000000;
1247b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = DEFAULT_DIVIDER_ALPHA;
1248b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1249b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (v.getBackground() instanceof ColorDrawable) {
1250b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ColorDrawable background = (ColorDrawable) v.getBackground();
1251b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.mutate();
1252b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setColor(color);
1253b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setAlpha(alpha);
1254b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1255b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1256b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
12571685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public int getMaxExpandHeight() {
1258b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mMaxExpandHeight;
1259a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
1260584a7aa62c54bcbd654a6696d4fbb56e124874e7Jorim Jaggi
126134958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public boolean areGutsExposed() {
126234958fa272c9216db4002546c3efad692b3d7775Mady Mellor        return (mGuts != null && mGuts.areGutsExposed());
126334958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
126434958fa272c9216db4002546c3efad692b3d7775Mady Mellor
1265be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
12664222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public boolean isContentExpandable() {
12672f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
12682f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.isContentExpandable();
12694222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
12704222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
12714222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
1272560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    protected View getContentView() {
1273560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek        return getShowingLayout();
1274560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    }
1275560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek
1276560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    @Override
1277d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int height, boolean notifyListeners) {
1278b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        super.setActualHeight(height, notifyListeners);
1279b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor        if (mGuts != null && mGuts.areGutsExposed()) {
1280b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor            mGuts.setActualHeight(height);
1281b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor            return;
1282b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor        }
1283eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        int contentHeight = Math.max(getMinHeight(), height);
1284b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mPrivateLayout.setContentHeight(contentHeight);
1285b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mPublicLayout.setContentHeight(contentHeight);
128642357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        if (mIsSummaryWithChildren) {
128742357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            mChildrenContainer.setActualHeight(height);
128842357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        }
1289b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
1290b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setActualHeight(height);
1291b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
1292be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
1293be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
1294be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
1295b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public int getMaxContentHeight() {
129683bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1297eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getMaxContentHeight();
129883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
12992f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
13002f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.getMaxHeight();
1301be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
1302be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
1303be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
13044222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public int getMinHeight() {
130531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if (mIsHeadsUp && mHeadsUpManager.isTrackingHeadsUp()) {
130631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                return getPinnedHeadsUpHeight(false /* atLeastMinHeight */);
130731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mIsSummaryWithChildren && !isGroupExpanded() && !mShowingPublic) {
1308b55386d64aeb80f74ed21035d1e389d86be89db6Selim Cinek            return mChildrenContainer.getMinHeight();
130931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mIsHeadsUp) {
131031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return mHeadsUpHeight;
1311b55386d64aeb80f74ed21035d1e389d86be89db6Selim Cinek        }
1312816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
1313816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return showingLayout.getMinHeight();
1314816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    }
1315816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek
1316816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    @Override
1317567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek    public int getCollapsedHeight() {
13182c58461daf909fae5a2605f0ba63da3f9c897731Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1319567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek            return mChildrenContainer.getCollapsedHeight();
132083bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
1321816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return getMinHeight();
13224222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
13234222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
13244222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
1325be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
1326be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super.setClipTopAmount(clipTopAmount);
1327be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout.setClipTopAmount(clipTopAmount);
13282f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        mPublicLayout.setClipTopAmount(clipTopAmount);
1329b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
1330b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setClipTopAmount(clipTopAmount);
1331b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
1332be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
1333be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
1334eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    private void recreateNotificationHeader() {
1335eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(),
1336eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                getStatusBarNotification().getNotification());
1337eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        final RemoteViews header = builder.makeNotificationHeader();
1338eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        if (mNotificationHeader == null) {
1339eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            mNotificationHeader = (NotificationHeaderView) header.apply(getContext(), this);
1340eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            final View expandButton = mNotificationHeader.findViewById(
1341eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                    com.android.internal.R.id.expand_button);
1342eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            expandButton.setVisibility(VISIBLE);
1343eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            mNotificationHeader.setOnClickListener(mExpandClickListener);
13449c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek            mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(),
13459c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek                    mNotificationHeader);
1346b5a83613fe935cc60106746d311bab2acbce37faSelim Cinek            addView(mNotificationHeader, indexOfChild(mChildrenContainer) + 1);
13474b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mTranslateableViews.add(mNotificationHeader);
1348eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        } else {
1349eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            header.reapply(getContext(), mNotificationHeader);
13504ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek            mNotificationHeaderWrapper.notifyContentUpdated(mEntry.notification);
1351eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        }
1352ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        updateChildrenHeaderAppearance();
1353343e6e258ab6a9f647eabebaed05ce3acafd2ff1Selim Cinek    }
13547d447726e2cb9fae80db417012039828daab8fe7Selim Cinek
1355ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    public void updateChildrenHeaderAppearance() {
1356ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        if (mIsSummaryWithChildren) {
1357ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek            mHeaderUtil.updateChildrenHeaderAppearance();
1358ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        }
1359ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    }
1360ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek
136131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public boolean isMaxExpandHeightInitialized() {
136231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        return mMaxExpandHeight != 0;
13637d447726e2cb9fae80db417012039828daab8fe7Selim Cinek    }
13642f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek
136542357e030c095867b95e2e8a718649587c5ebf52Selim Cinek    public NotificationContentView getShowingLayout() {
13662f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return mShowingPublic ? mPublicLayout : mPrivateLayout;
13672f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    }
136878403d79739605511ea88b653564d81d7bf4bbbaChris Wren
136959ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    @Override
137059ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    public void setShowingLegacyBackground(boolean showing) {
137159ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi        super.setShowingLegacyBackground(showing);
137259ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi        mPrivateLayout.setShowingLegacyBackground(showing);
137359ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi        mPublicLayout.setShowingLegacyBackground(showing);
137459ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    }
137559ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi
1376a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    @Override
1377a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    protected void updateBackgroundTint() {
1378a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        super.updateBackgroundTint();
1379a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateNoBackgroundState();
1380a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        if (mIsSummaryWithChildren) {
1381a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
1382a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                    mChildrenContainer.getNotificationChildren();
1383a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
1384a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
1385a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                child.updateNoBackgroundState();
1386a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            }
1387a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        }
1388a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
1389a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
1390a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    private void updateNoBackgroundState() {
1391a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mShowNoBackground = isChildInGroup() && hasSameBgColor(mNotificationParent);
1392a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateBackground();
1393a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
1394a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
139578403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public void setExpansionLogger(ExpansionLogger logger, String key) {
139678403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLogger = logger;
139778403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLoggingKey = key;
139878403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
139978403d79739605511ea88b653564d81d7bf4bbbaChris Wren
14006183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    @Override
140142357e030c095867b95e2e8a718649587c5ebf52Selim Cinek    public float getIncreasedPaddingAmount() {
140242357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        if (mIsSummaryWithChildren) {
140342357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            if (isGroupExpanded()) {
140442357e030c095867b95e2e8a718649587c5ebf52Selim Cinek                return 1.0f;
140542357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            } else if (isUserLocked()) {
1406f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek                return mChildrenContainer.getGroupExpandFraction();
140742357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            }
140842357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        }
140942357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        return 0.0f;
141061633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek    }
141161633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek
141261633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek    @Override
14136183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    protected boolean disallowSingleClick(MotionEvent event) {
14146183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        float x = event.getX();
14156183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        float y = event.getY();
141634eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        NotificationHeaderView header = getVisibleNotificationHeader();
14176183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        if (header != null) {
1418a883351024f8dbdf8041c551f8a8987d9357dcd8Mady Mellor            return header.isInTouchRect(x - getTranslation(), y);
14196183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        }
14206183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        return super.disallowSingleClick(event);
14216183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    }
14226183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek
142378403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private void logExpansionEvent(boolean userAction, boolean wasExpanded) {
142478403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean nowExpanded = isExpanded();
142578403d79739605511ea88b653564d81d7bf4bbbaChris Wren        if (wasExpanded != nowExpanded && mLogger != null) {
142678403d79739605511ea88b653564d81d7bf4bbbaChris Wren            mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded) ;
142778403d79739605511ea88b653564d81d7bf4bbbaChris Wren        }
142878403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
1429570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek
1430570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    public interface OnExpandClickListener {
143131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        void onExpandClicked(NotificationData.Entry clickedEntry, boolean nowExpanded);
1432570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    }
143351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren}
1434