ExpandableNotificationRow.java revision 78403d79739605511ea88b653564d81d7bf4bbba
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;
2051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenimport android.util.AttributeSet;
21a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport android.view.View;
22fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggiimport android.view.accessibility.AccessibilityEvent;
2351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
24a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport com.android.systemui.R;
25a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
264222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggipublic class ExpandableNotificationRow extends ActivatableNotificationView {
271685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mRowMinHeight;
281685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mRowMaxHeight;
2951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
301685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Does this row contain layouts that can adapt to row expansion */
3151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mExpandable;
321685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Has the user actively changed the expansion state of this row */
331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mHasUserChangedExpansion;
341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
3551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserExpanded;
361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Is the user touching this row */
3751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserLocked;
381685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Are we showing the "public" version */
39a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    private boolean mShowingPublic;
4051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
411685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
421685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Is this notification expanded by the system. The expansion state can be overridden by the
431685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * user expansion.
441685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
451685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mIsSystemExpanded;
46dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
47dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
48dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     * Whether the notification expansion is disabled. This is the case on Keyguard.
49dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
50dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    private boolean mExpansionDisabled;
51dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
52be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPublicLayout;
53be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPrivateLayout;
541685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mMaxExpandHeight;
55863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek    private View mVetoButton;
560d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    private boolean mClearable;
5778403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private ExpansionLogger mLogger;
5878403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private String mLoggingKey;
5978403d79739605511ea88b653564d81d7bf4bbbaChris Wren
6078403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public interface ExpansionLogger {
6178403d79739605511ea88b653564d81d7bf4bbbaChris Wren        public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
6278403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
631685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
6451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
6551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        super(context, attrs);
6651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
6751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
68a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    /**
69a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     * Resets this view so it can be re-used for an updated notification.
70a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     */
7122f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer    @Override
72a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    public void reset() {
7322f2ee567dd1b1a42432251229bcb2f05c1c4700Christoph Studer        super.reset();
74a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mRowMinHeight = 0;
7578403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
76a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mRowMaxHeight = 0;
77a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mExpandable = false;
78a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mHasUserChangedExpansion = false;
79a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mUserLocked = false;
80a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mShowingPublic = false;
81a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mIsSystemExpanded = false;
82a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mExpansionDisabled = false;
83a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mPublicLayout.reset();
84a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mPrivateLayout.reset();
85a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        mMaxExpandHeight = 0;
8678403d79739605511ea88b653564d81d7bf4bbbaChris Wren        logExpansionEvent(false, wasExpanded);
87a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    }
88a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer
89251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    @Override
90251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    protected void onFinishInflate() {
91251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi        super.onFinishInflate();
92be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
93be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
94863834bd96bdebcf21f4c4a7d8285d4858c061e4Selim Cinek        mVetoButton = findViewById(R.id.veto);
95fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    }
96fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi
97fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    @Override
98fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
99fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        if (super.onRequestSendAccessibilityEvent(child, event)) {
100fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // Add a record for the entire layout since its content is somehow small.
101fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // The event comes from a leaf view that is interacted with.
102fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            AccessibilityEvent record = AccessibilityEvent.obtain();
103fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            onInitializeAccessibilityEvent(record);
104fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            dispatchPopulateAccessibilityEvent(record);
105fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            event.appendRecord(record);
106fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            return true;
107fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        }
108fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        return false;
109c5dc0d0cce373fbf292e13633c114a431d747167Jorim Jaggi    }
11051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1111685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
1121685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mRowMinHeight = rowMinHeight;
1131685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mRowMaxHeight = rowMaxHeight;
11451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
11551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
11651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isExpandable() {
11751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mExpandable;
11851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
11951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
12051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setExpandable(boolean expandable) {
12151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mExpandable = expandable;
12251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
12351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1241685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
1251685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the user has changed the expansion state
1261685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
1271685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean hasUserChangedExpansion() {
1281685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mHasUserChangedExpansion;
1291685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
1301685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
13151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserExpanded() {
13251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserExpanded;
13351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
13451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1351685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
1361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the user
1371685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
1381685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param userExpanded whether the user wants this notification to be expanded
1391685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
14051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserExpanded(boolean userExpanded) {
141a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        if (userExpanded && !mExpandable) return;
14278403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
1431685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mHasUserChangedExpansion = true;
14451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserExpanded = userExpanded;
14578403d79739605511ea88b653564d81d7bf4bbbaChris Wren        logExpansionEvent(true, wasExpanded);
14651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
14751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
14851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserLocked() {
14951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserLocked;
15051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
15151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
15251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserLocked(boolean userLocked) {
15351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserLocked = userLocked;
15451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
15551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1561685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
1571685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return has the system set this notification to be expanded
1581685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
1591685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean isSystemExpanded() {
1601685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mIsSystemExpanded;
1611685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
1621685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
1631685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
1641685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the system.
1651685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
1661685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param expand whether the system wants this notification to be expanded.
1671685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
1681685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setSystemExpanded(boolean expand) {
16978403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
1701685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mIsSystemExpanded = expand;
1719cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi        notifyHeightChanged();
17278403d79739605511ea88b653564d81d7bf4bbbaChris Wren        logExpansionEvent(false, wasExpanded);
173dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    }
174dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
175dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
176dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     * @param expansionDisabled whether to prevent notification expansion
177dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
178dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    public void setExpansionDisabled(boolean expansionDisabled) {
17978403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
180dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi        mExpansionDisabled = expansionDisabled;
18178403d79739605511ea88b653564d81d7bf4bbbaChris Wren        logExpansionEvent(false, wasExpanded);
1829cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi        notifyHeightChanged();
1831685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
1841685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
1851685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
1860d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     * @return Can the underlying notification be cleared?
1870d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     */
1880d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    public boolean isClearable() {
1890d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        return mClearable;
1900d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
1910d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
1920d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    /**
1930d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     * Set whether the notification can be cleared.
1940d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     *
1950d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     * @param clearable
1960d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     */
1970d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    public void setClearable(boolean clearable) {
1980d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        mClearable = clearable;
1990d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        updateVetoButton();
2000d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
2010d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
2020d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    /**
2031685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Apply an expansion state to the layout.
2041685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
205dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    public void applyExpansionToLayout() {
206dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi        boolean expand = isExpanded();
20751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        if (expand && mExpandable) {
208be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            setActualHeight(mMaxExpandHeight);
20951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        } else {
210be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            setActualHeight(mRowMinHeight);
21151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        }
21251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
213a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
2149cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    @Override
2159cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    public int getIntrinsicHeight() {
216be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (isUserLocked()) {
217be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            return getActualHeight();
218be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
2191685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        boolean inExpansionState = isExpanded();
2201685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        if (!inExpansionState) {
2211685e634fb0b14033bd436af8d7174436699ffecSelim Cinek            // not expanded, so we return the collapsed size
2221685e634fb0b14033bd436af8d7174436699ffecSelim Cinek            return mRowMinHeight;
2231685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        }
2241685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
2251685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mShowingPublic ? mRowMinHeight : getMaxExpandHeight();
2261685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
2271685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
2281685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
2291685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Check whether the view state is currently expanded. This is given by the system in {@link
2301685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * #setSystemExpanded(boolean)} and can be overridden by user expansion or
2311685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
2321685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * view can differ from this state, if layout params are modified from outside.
2331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
2341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the view state is currently expanded.
2351685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
2361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean isExpanded() {
237dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi        return !mExpansionDisabled
238dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi                && (!hasUserChangedExpansion() && isSystemExpanded() || isUserExpanded());
2391685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
2401685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
2411685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    @Override
2421685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
2431685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        super.onLayout(changed, left, top, right, bottom);
244be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        boolean updateExpandHeight = mMaxExpandHeight == 0;
245be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mMaxExpandHeight = mPrivateLayout.getMaxHeight();
246be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (updateExpandHeight) {
247dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi            applyExpansionToLayout();
248be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
2491685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
2501685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
251a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    public void setShowingPublic(boolean show) {
252a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler        mShowingPublic = show;
253a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
254a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler        // bail out if no public version
2551685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        if (mPublicLayout.getChildCount() == 0) return;
256a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
257a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler        // TODO: animation?
2581685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mPublicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
2591685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mPrivateLayout.setVisibility(show ? View.GONE : View.VISIBLE);
2600d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
2610d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        updateVetoButton();
2620d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
2630d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
2640d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    private void updateVetoButton() {
2650d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        // public versions cannot be dismissed
2660d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler        mVetoButton.setVisibility(isClearable() && !mShowingPublic ? View.VISIBLE : View.GONE);
267a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
268251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi
2691685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public int getMaxExpandHeight() {
2702f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return mShowingPublic ? mRowMinHeight : mMaxExpandHeight;
271a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
272584a7aa62c54bcbd654a6696d4fbb56e124874e7Jorim Jaggi
273be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
2744222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public boolean isContentExpandable() {
2752f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
2762f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.isContentExpandable();
2774222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
2784222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
2794222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
280d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int height, boolean notifyListeners) {
281c9c00ae2fa5fb787e9f12705f8cd8de445ecde4bSelim Cinek        mPrivateLayout.setActualHeight(height);
2822f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        mPublicLayout.setActualHeight(height);
283be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        invalidate();
284d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi        super.setActualHeight(height, notifyListeners);
285be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
286be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
287be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
288be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public int getMaxHeight() {
2892f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
2902f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.getMaxHeight();
291be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
292be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
293be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
2944222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public int getMinHeight() {
2952f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
2962f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.getMinHeight();
2974222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
2984222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
2994222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
300be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
301be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super.setClipTopAmount(clipTopAmount);
302be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout.setClipTopAmount(clipTopAmount);
3032f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        mPublicLayout.setClipTopAmount(clipTopAmount);
304be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
305be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
306be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void notifyContentUpdated() {
3072f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        mPublicLayout.notifyContentUpdated();
308be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout.notifyContentUpdated();
309343e6e258ab6a9f647eabebaed05ce3acafd2ff1Selim Cinek    }
3107d447726e2cb9fae80db417012039828daab8fe7Selim Cinek
3117d447726e2cb9fae80db417012039828daab8fe7Selim Cinek    public boolean isShowingLayoutLayouted() {
3122f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
3137d447726e2cb9fae80db417012039828daab8fe7Selim Cinek        return showingLayout.getWidth() != 0;
3147d447726e2cb9fae80db417012039828daab8fe7Selim Cinek    }
3152f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek
3162f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    private NotificationContentView getShowingLayout() {
3172f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return mShowingPublic ? mPublicLayout : mPrivateLayout;
3182f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    }
31978403d79739605511ea88b653564d81d7bf4bbbaChris Wren
32078403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public void setExpansionLogger(ExpansionLogger logger, String key) {
32178403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLogger = logger;
32278403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLoggingKey = key;
32378403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
32478403d79739605511ea88b653564d81d7bf4bbbaChris Wren
32578403d79739605511ea88b653564d81d7bf4bbbaChris Wren
32678403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private void logExpansionEvent(boolean userAction, boolean wasExpanded) {
32778403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean nowExpanded = isExpanded();
32878403d79739605511ea88b653564d81d7bf4bbbaChris Wren        if (wasExpanded != nowExpanded && mLogger != null) {
32978403d79739605511ea88b653564d81d7bf4bbbaChris Wren            mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded) ;
33078403d79739605511ea88b653564d81d7bf4bbbaChris Wren        }
33178403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
33251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren}
333