ExpandableNotificationRow.java revision 1a521f3ea841f6db9686bbec7f950a3883d075aa
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
1951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenimport android.content.Context;
20cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.AnimatedVectorDrawable;
21cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.AnimationDrawable;
22cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.Drawable;
23b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggiimport android.service.notification.StatusBarNotification;
2451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenimport android.util.AttributeSet;
251a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinekimport android.view.MotionEvent;
26a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport android.view.View;
27b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggiimport android.view.ViewStub;
28fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggiimport android.view.accessibility.AccessibilityEvent;
29cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.widget.ImageView;
30a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport com.android.systemui.R;
31a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
324222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggipublic class ExpandableNotificationRow extends ActivatableNotificationView {
331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mRowMinHeight;
341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mRowMaxHeight;
3551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Does this row contain layouts that can adapt to row expansion */
3751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mExpandable;
381685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Has the user actively changed the expansion state of this row */
391685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mHasUserChangedExpansion;
401685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
4151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserExpanded;
421685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Is the user touching this row */
4351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserLocked;
441685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Are we showing the "public" version */
45a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    private boolean mShowingPublic;
46ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mSensitive;
47ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mShowingPublicInitialized;
48ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mShowingPublicForIntrinsicHeight;
4951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
501685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
511685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Is this notification expanded by the system. The expansion state can be overridden by the
521685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * user expansion.
531685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
541685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mIsSystemExpanded;
55dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
56dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
57dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     * Whether the notification expansion is disabled. This is the case on Keyguard.
58dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
59dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    private boolean mExpansionDisabled;
60dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
61be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPublicLayout;
62be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPrivateLayout;
631685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mMaxExpandHeight;
64863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek    private View mVetoButton;
650d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    private boolean mClearable;
6678403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private ExpansionLogger mLogger;
6778403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private String mLoggingKey;
68a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek    private boolean mWasReset;
69024ca598dd4b38b389251c138f4ef9882d4b68b0Selim Cinek    private NotificationGuts mGuts;
7078403d79739605511ea88b653564d81d7bf4bbbaChris Wren
71b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    private StatusBarNotification mStatusBarNotification;
721a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    private boolean mIsHeadsUp;
73b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
74cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    public void setIconAnimationRunning(boolean running) {
75cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        setIconAnimationRunning(running, mPublicLayout);
76cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        setIconAnimationRunning(running, mPrivateLayout);
77cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
78cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
79cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunning(boolean running, NotificationContentView layout) {
80cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (layout != null) {
81cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View contractedChild = layout.getContractedChild();
82cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View expandedChild = layout.getExpandedChild();
83cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, contractedChild);
84cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, expandedChild);
85cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
86cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
87cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
88cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunningForChild(boolean running, View child) {
89cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (child != null) {
90cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView icon = (ImageView) child.findViewById(com.android.internal.R.id.icon);
91cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(icon, running);
92cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView rightIcon = (ImageView) child.findViewById(
93cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    com.android.internal.R.id.right_icon);
94cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(rightIcon, running);
95cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
96cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
97cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
98cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconRunning(ImageView imageView, boolean running) {
99cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (imageView != null) {
100cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            Drawable drawable = imageView.getDrawable();
101cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            if (drawable instanceof AnimationDrawable) {
102cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
103cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
104cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
105cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
106cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
107cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
108cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            } else if (drawable instanceof AnimatedVectorDrawable) {
109cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimatedVectorDrawable animationDrawable = (AnimatedVectorDrawable) drawable;
110cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
111cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
112cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
113cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
114cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
115cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            }
116cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
117cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
118cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
119b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    public void setStatusBarNotification(StatusBarNotification statusBarNotification) {
120b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        mStatusBarNotification = statusBarNotification;
121b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
122b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
123b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    public StatusBarNotification getStatusBarNotification() {
124b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        return mStatusBarNotification;
125b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
126b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
1271a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    public void setHeadsUp(boolean isHeadsUp) {
1281a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mIsHeadsUp = isHeadsUp;
1291a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    }
1301a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek
13178403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public interface ExpansionLogger {
13278403d79739605511ea88b653564d81d7bf4bbbaChris Wren        public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
13378403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
1341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
13551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
13651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        super(context, attrs);
13751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
13851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
139a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    /**
140a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     * Resets this view so it can be re-used for an updated notification.
141a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     */
14222f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer    @Override
143a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    public void reset() {
14422f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer        super.reset();
145a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mRowMinHeight = 0;
14678403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
147a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mRowMaxHeight = 0;
148a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mExpandable = false;
149a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mHasUserChangedExpansion = false;
150a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mUserLocked = false;
151a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mShowingPublic = false;
152ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = false;
153ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = false;
154a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mIsSystemExpanded = false;
155a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mExpansionDisabled = false;
1561a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mPublicLayout.reset(mIsHeadsUp);
1571a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mPrivateLayout.reset(mIsHeadsUp);
15831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        resetHeight();
15931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        logExpansionEvent(false, wasExpanded);
16031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    }
16131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek
16231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public void resetHeight() {
1631a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        if (mIsHeadsUp) {
1641a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek            resetActualHeight();
1651a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        }
166a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mMaxExpandHeight = 0;
167a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek        mWasReset = true;
16831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        onHeightReset();
1696e28a678c7f9fe2cae5a51bfdbab3071a2d8d0baSelim Cinek        requestLayout();
170a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    }
171a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer
172251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    @Override
1731a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    protected boolean filterMotionEvent(MotionEvent event) {
1741a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        return mIsHeadsUp || super.filterMotionEvent(event);
1751a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    }
1761a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek
1771a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    @Override
178251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    protected void onFinishInflate() {
179251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi        super.onFinishInflate();
180be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
181be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
182b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        ViewStub gutsStub = (ViewStub) findViewById(R.id.notification_guts_stub);
183b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        gutsStub.setOnInflateListener(new ViewStub.OnInflateListener() {
184b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            @Override
185b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            public void onInflate(ViewStub stub, View inflated) {
186b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts = (NotificationGuts) inflated;
187b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setClipTopAmount(getClipTopAmount());
188b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setActualHeight(getActualHeight());
189b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            }
190b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        });
191863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek        mVetoButton = findViewById(R.id.veto);
192fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    }
193fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi
194fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    @Override
195fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
196fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        if (super.onRequestSendAccessibilityEvent(child, event)) {
197fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // Add a record for the entire layout since its content is somehow small.
198fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // The event comes from a leaf view that is interacted with.
199fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            AccessibilityEvent record = AccessibilityEvent.obtain();
200fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            onInitializeAccessibilityEvent(record);
201fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            dispatchPopulateAccessibilityEvent(record);
202fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            event.appendRecord(record);
203fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            return true;
204fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        }
205fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        return false;
206c5dc0d0cce373fbf292e13633c114a431d747167Jorim Jaggi    }
20751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
208e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    @Override
209e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    public void setDark(boolean dark, boolean fade) {
210e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        super.setDark(dark, fade);
211e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        final NotificationContentView showing = getShowingLayout();
212e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        if (showing != null) {
213e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock            showing.setDark(dark, fade);
214e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        }
215e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    }
216e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock
2171685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
2181685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mRowMinHeight = rowMinHeight;
2191685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mRowMaxHeight = rowMaxHeight;
22051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
22151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
22251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isExpandable() {
22351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mExpandable;
22451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
22551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
22651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setExpandable(boolean expandable) {
22751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mExpandable = expandable;
22851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
22951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
2301685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
2311685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the user has changed the expansion state
2321685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
2331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean hasUserChangedExpansion() {
2341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mHasUserChangedExpansion;
2351685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
2361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
23751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserExpanded() {
23851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserExpanded;
23951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
24051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
2411685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
2421685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the user
2431685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
2441685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param userExpanded whether the user wants this notification to be expanded
2451685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
24651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserExpanded(boolean userExpanded) {
247a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        if (userExpanded && !mExpandable) return;
24878403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
2491685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mHasUserChangedExpansion = true;
25051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserExpanded = userExpanded;
25178403d79739605511ea88b653564d81d7bf4bbbaChris Wren        logExpansionEvent(true, wasExpanded);
25251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
25351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
254ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    public void resetUserExpansion() {
255ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mHasUserChangedExpansion = false;
256ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mUserExpanded = false;
257ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    }
258ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek
25951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserLocked() {
26051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserLocked;
26151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
26251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
26351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserLocked(boolean userLocked) {
26451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserLocked = userLocked;
26551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
26651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
2671685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
2681685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return has the system set this notification to be expanded
2691685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
2701685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean isSystemExpanded() {
2711685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mIsSystemExpanded;
2721685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
2731685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
2741685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
2751685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the system.
2761685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
2771685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param expand whether the system wants this notification to be expanded.
2781685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
2791685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setSystemExpanded(boolean expand) {
28031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        if (expand != mIsSystemExpanded) {
28131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
28231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            mIsSystemExpanded = expand;
28331094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            notifyHeightChanged();
28431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            logExpansionEvent(false, wasExpanded);
28531094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
286dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    }
287dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
288dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
289dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     * @param expansionDisabled whether to prevent notification expansion
290dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
291dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    public void setExpansionDisabled(boolean expansionDisabled) {
29231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        if (expansionDisabled != mExpansionDisabled) {
29331094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
29431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            mExpansionDisabled = expansionDisabled;
29531094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            logExpansionEvent(false, wasExpanded);
29631094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            if (wasExpanded != isExpanded()) {
29731094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek                notifyHeightChanged();
29831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            }
29931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
3001685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
3011685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
3021685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
3030d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     * @return Can the underlying notification be cleared?
3040d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     */
3050d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    public boolean isClearable() {
3060d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        return mClearable;
3070d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
3080d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
3090d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    /**
3100d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     * Set whether the notification can be cleared.
3110d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     *
3120d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     * @param clearable
3130d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     */
3140d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    public void setClearable(boolean clearable) {
3150d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        mClearable = clearable;
3160d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        updateVetoButton();
3170d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
3180d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
3190d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    /**
3201685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Apply an expansion state to the layout.
3211685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
322dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    public void applyExpansionToLayout() {
323dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi        boolean expand = isExpanded();
32451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        if (expand && mExpandable) {
325be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            setActualHeight(mMaxExpandHeight);
32651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        } else {
327be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            setActualHeight(mRowMinHeight);
32851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        }
32951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
330a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
3319cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    @Override
3329cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    public int getIntrinsicHeight() {
333be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (isUserLocked()) {
334be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            return getActualHeight();
335be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
3361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        boolean inExpansionState = isExpanded();
3371685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        if (!inExpansionState) {
3381685e634fb0b14033bd436af8d7174436699ffecSelim Cinek            // not expanded, so we return the collapsed size
3391685e634fb0b14033bd436af8d7174436699ffecSelim Cinek            return mRowMinHeight;
3401685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        }
3411685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
342ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        return mShowingPublicForIntrinsicHeight ? mRowMinHeight : getMaxExpandHeight();
3431685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
3441685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
3451685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
3461685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Check whether the view state is currently expanded. This is given by the system in {@link
3471685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * #setSystemExpanded(boolean)} and can be overridden by user expansion or
3481685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
3491685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * view can differ from this state, if layout params are modified from outside.
3501685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
3511685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the view state is currently expanded.
3521685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
3531685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean isExpanded() {
354dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi        return !mExpansionDisabled
355dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi                && (!hasUserChangedExpansion() && isSystemExpanded() || isUserExpanded());
3561685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
3571685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
3581685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    @Override
3591685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
3601685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        super.onLayout(changed, left, top, right, bottom);
361a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek        boolean updateExpandHeight = mMaxExpandHeight == 0 && !mWasReset;
362d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        updateMaxExpandHeight();
363be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (updateExpandHeight) {
364dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi            applyExpansionToLayout();
365be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
366a5e211b1f2a8d055b369dadc464dc5d5bc3dd9c1Selim Cinek        mWasReset = false;
3671685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
3681685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
369d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek    private void updateMaxExpandHeight() {
370d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        int intrinsicBefore = getIntrinsicHeight();
371d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        mMaxExpandHeight = mPrivateLayout.getMaxHeight();
372d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
373d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek            notifyHeightChanged();
374d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        }
375d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek    }
376d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek
377ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setSensitive(boolean sensitive) {
378ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = sensitive;
379ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
380ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
381ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
382ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicForIntrinsicHeight = mSensitive && hideSensitive;
383ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
384ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
385ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
386ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            long duration) {
387ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        boolean oldShowingPublic = mShowingPublic;
388ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublic = mSensitive && hideSensitive;
389ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
390ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            return;
391ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
392a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
393a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler        // bail out if no public version
3941685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        if (mPublicLayout.getChildCount() == 0) return;
395a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
396ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (!animated) {
397ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.animate().cancel();
398ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.animate().cancel();
399ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setAlpha(1f);
400ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.setAlpha(1f);
401ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
402ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.setVisibility(mShowingPublic ? View.INVISIBLE : View.VISIBLE);
403ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        } else {
404ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            animateShowingPublic(delay, duration);
405ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
4060d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
4070d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        updateVetoButton();
408ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = true;
409ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
410ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
411ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private void animateShowingPublic(long delay, long duration) {
412ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        final View source = mShowingPublic ? mPrivateLayout : mPublicLayout;
413ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        View target = mShowingPublic ? mPublicLayout : mPrivateLayout;
414ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        source.setVisibility(View.VISIBLE);
415ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        target.setVisibility(View.VISIBLE);
416ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        target.setAlpha(0f);
417ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        source.animate().cancel();
418ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        target.animate().cancel();
419ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        source.animate()
420ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .alpha(0f)
421ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .setStartDelay(delay)
422ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .setDuration(duration)
423ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .withEndAction(new Runnable() {
424ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                    @Override
425ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                    public void run() {
426ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                        source.setVisibility(View.INVISIBLE);
427ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                    }
428ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                });
429ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        target.animate()
430ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .alpha(1f)
431ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .setStartDelay(delay)
432ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi                .setDuration(duration);
4330d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
4340d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
4350d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    private void updateVetoButton() {
4360d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        // public versions cannot be dismissed
4370d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        mVetoButton.setVisibility(isClearable() && !mShowingPublic ? View.VISIBLE : View.GONE);
438a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
439251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi
4401685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public int getMaxExpandHeight() {
441ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        return mShowingPublicForIntrinsicHeight ? mRowMinHeight : mMaxExpandHeight;
442a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
443584a7aa62c54bcbd654a6696d4fbb56e124874e7Jorim Jaggi
444be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
4454222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public boolean isContentExpandable() {
4462f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
4472f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.isContentExpandable();
4484222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
4494222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
4504222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
451d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int height, boolean notifyListeners) {
452c9c00ae2fa5fb787e9f12705f8cd8de445ecde4bSelim Cinek        mPrivateLayout.setActualHeight(height);
4532f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        mPublicLayout.setActualHeight(height);
454b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
455b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setActualHeight(height);
456b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
457be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        invalidate();
458d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi        super.setActualHeight(height, notifyListeners);
459be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
460be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
461be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
462be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public int getMaxHeight() {
4632f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
4642f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.getMaxHeight();
465be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
466be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
467be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
4684222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public int getMinHeight() {
4692f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
4702f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.getMinHeight();
4714222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
4724222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
4734222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
474be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
475be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super.setClipTopAmount(clipTopAmount);
476be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout.setClipTopAmount(clipTopAmount);
4772f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        mPublicLayout.setClipTopAmount(clipTopAmount);
478b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
479b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setClipTopAmount(clipTopAmount);
480b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
481be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
482be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
483be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void notifyContentUpdated() {
4842f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        mPublicLayout.notifyContentUpdated();
485be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout.notifyContentUpdated();
486343e6e258ab6a9f647eabebaed05ce3acafd2ff1Selim Cinek    }
4877d447726e2cb9fae80db417012039828daab8fe7Selim Cinek
48831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public boolean isMaxExpandHeightInitialized() {
48931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        return mMaxExpandHeight != 0;
4907d447726e2cb9fae80db417012039828daab8fe7Selim Cinek    }
4912f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek
4922f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    private NotificationContentView getShowingLayout() {
4932f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return mShowingPublic ? mPublicLayout : mPrivateLayout;
4942f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    }
49578403d79739605511ea88b653564d81d7bf4bbbaChris Wren
49678403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public void setExpansionLogger(ExpansionLogger logger, String key) {
49778403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLogger = logger;
49878403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLoggingKey = key;
49978403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
50078403d79739605511ea88b653564d81d7bf4bbbaChris Wren
50178403d79739605511ea88b653564d81d7bf4bbbaChris Wren
50278403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private void logExpansionEvent(boolean userAction, boolean wasExpanded) {
50378403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean nowExpanded = isExpanded();
50478403d79739605511ea88b653564d81d7bf4bbbaChris Wren        if (wasExpanded != nowExpanded && mLogger != null) {
50578403d79739605511ea88b653564d81d7bf4bbbaChris Wren            mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded) ;
50678403d79739605511ea88b653564d81d7bf4bbbaChris Wren        }
50778403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
50851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren}
509