ExpandableNotificationRow.java revision b26afa3e941dd000a2c5befa0481e9244f152b6e
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
195ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinekimport static com.android.systemui.statusbar.notification.NotificationInflater.InflationCallback;
20c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
214b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.Animator;
224b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.AnimatorListenerAdapter;
234b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.ObjectAnimator;
244b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport android.animation.ValueAnimator.AnimatorUpdateListener;
25ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinekimport android.annotation.Nullable;
2651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenimport android.content.Context;
277acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chenimport android.content.res.Resources;
289d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellorimport android.content.res.Configuration;
29cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.AnimatedVectorDrawable;
30cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.AnimationDrawable;
31b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport android.graphics.drawable.ColorDrawable;
32cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.graphics.drawable.Drawable;
33da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinekimport android.os.Build;
34e9bad242f38bebadae481a22b647cc153f093070Selim Cinekimport android.os.Bundle;
35b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggiimport android.service.notification.StatusBarNotification;
3651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wrenimport android.util.AttributeSet;
37b0a824687f56b6950338aad169d8d837f8ed657bMady Mellorimport android.util.FloatProperty;
38b0a824687f56b6950338aad169d8d837f8ed657bMady Mellorimport android.util.Property;
3901af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinekimport android.view.LayoutInflater;
406183d12926a189b08cc3be8d9c78470617e63db0Selim Cinekimport android.view.MotionEvent;
41eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinekimport android.view.NotificationHeaderView;
42a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport android.view.View;
43875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinekimport android.view.ViewGroup;
44b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggiimport android.view.ViewStub;
45fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggiimport android.view.accessibility.AccessibilityEvent;
46e9bad242f38bebadae481a22b647cc153f093070Selim Cinekimport android.view.accessibility.AccessibilityNodeInfo;
4798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinekimport android.widget.Chronometer;
4895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport android.widget.FrameLayout;
49cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinekimport android.widget.ImageView;
501a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.widget.RemoteViews;
51b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
525ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinekimport com.android.internal.annotations.VisibleForTesting;
53698b1706be196de41fc6bf03cf15971c82a11949Chris Wrenimport com.android.internal.logging.MetricsLogger;
54383db5ebcc3a4a615faf249bf4f126f42e80b82eTamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent;
554bb593492ccf560382fac9ae533a7429cec53c94Selim Cinekimport com.android.internal.util.NotificationColorUtil;
56875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinekimport com.android.internal.widget.CachingIconView;
5795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport com.android.systemui.Dependency;
580242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinekimport com.android.systemui.Interpolators;
59a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandlerimport com.android.systemui.R;
600e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowskiimport com.android.systemui.classifier.FalsingManager;
6195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport com.android.systemui.plugins.PluginListener;
6295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport com.android.systemui.plugins.PluginManager;
6395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
6495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
6595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorimport com.android.systemui.statusbar.NotificationGuts.GutsContent;
665cf1d0589a0045ee5f01802975f394847e891215Selim Cinekimport com.android.systemui.statusbar.notification.AboveShelfChangedListener;
675cf1d0589a0045ee5f01802975f394847e891215Selim Cinekimport com.android.systemui.statusbar.notification.AboveShelfObserver;
68c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinekimport com.android.systemui.statusbar.notification.HybridNotificationView;
691a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.notification.NotificationInflater;
706743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinekimport com.android.systemui.statusbar.notification.NotificationUtils;
71a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinekimport com.android.systemui.statusbar.notification.VisualStabilityManager;
72b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.phone.NotificationGroupManager;
732a6ea9c2a1b52b0386270ec73e1e6d6a9b614a34Jason Monkimport com.android.systemui.statusbar.phone.StatusBar;
7431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinekimport com.android.systemui.statusbar.policy.HeadsUpManager;
750cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinekimport com.android.systemui.statusbar.stack.AnimationProperties;
760cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinekimport com.android.systemui.statusbar.stack.ExpandableViewState;
77b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.NotificationChildrenContainer;
78e9bad242f38bebadae481a22b647cc153f093070Selim Cinekimport com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
79b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport com.android.systemui.statusbar.stack.StackScrollState;
80b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
814b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellorimport java.util.ArrayList;
82b5605e58cb8080c8c887b1885336b707596c8094Selim Cinekimport java.util.List;
83a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
8495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorpublic class ExpandableNotificationRow extends ActivatableNotificationView
8595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        implements PluginListener<NotificationMenuRowPlugin> {
86b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
87b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
88b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int COLORED_DIVIDER_ALPHA = 0x7B;
8995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    private static final int MENU_VIEW_INDEX = 0;
9095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
91035badd314a2130f47745c081e38f82c645f28afMady Mellor    public interface LayoutListener {
92035badd314a2130f47745c081e38f82c645f28afMady Mellor        public void onLayout();
93035badd314a2130f47745c081e38f82c645f28afMady Mellor    }
94035badd314a2130f47745c081e38f82c645f28afMady Mellor
95035badd314a2130f47745c081e38f82c645f28afMady Mellor    private LayoutListener mLayoutListener;
9655a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    private boolean mLowPriorityStateUpdated;
971a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private final NotificationInflater mNotificationInflater;
980242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    private int mIconTransformContentShift;
99875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    private int mIconTransformContentShiftNoIcon;
10001af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMinHeightLegacy;
10101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mMaxHeadsUpHeightLegacy;
10201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mMaxHeadsUpHeight;
10387ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek    private int mMaxHeadsUpHeightIncreased;
10401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMinHeight;
1057d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek    private int mNotificationMinHeightLarge;
10601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMaxHeight;
1070aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos    private int mNotificationAmbientHeight;
108b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    private int mIncreasedPaddingBetweenElements;
10951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1101685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Does this row contain layouts that can adapt to row expansion */
11151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mExpandable;
1121685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Has the user actively changed the expansion state of this row */
1131685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mHasUserChangedExpansion;
1141685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
11551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserExpanded;
11631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek
11731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    /**
11831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * Has this notification been expanded while it was pinned
11931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     */
12031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    private boolean mExpandedWhenPinned;
1211685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Is the user touching this row */
12251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserLocked;
1231685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Are we showing the "public" version */
124a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    private boolean mShowingPublic;
125ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mSensitive;
1263c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek    private boolean mSensitiveHiddenInGeneral;
127ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mShowingPublicInitialized;
12860122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek    private boolean mHideSensitiveForIntrinsicHeight;
12951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1301685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
1311685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Is this notification expanded by the system. The expansion state can be overridden by the
1321685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * user expansion.
1331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
1341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mIsSystemExpanded;
135dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
136dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
13783bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * Whether the notification is on the keyguard and the expansion is disabled.
138dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
13983bc78338437a460076a4b5778ded38440ac3501Selim Cinek    private boolean mOnKeyguard;
140dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
141b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    private Animator mTranslateAnim;
1424b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private ArrayList<View> mTranslateableViews;
143be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPublicLayout;
144be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPrivateLayout;
145eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos    private NotificationContentView[] mLayouts;
1461685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mMaxExpandHeight;
1478d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private int mHeadsUpHeight;
1484bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek    private int mNotificationColor;
14978403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private ExpansionLogger mLogger;
15078403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private String mLoggingKey;
1518d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private NotificationGuts mGuts;
152da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private NotificationData.Entry mEntry;
153b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    private StatusBarNotification mStatusBarNotification;
1543fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor    private String mAppName;
1551a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    private boolean mIsHeadsUp;
15698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private boolean mLastChronometerRunning = true;
157b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private ViewStub mChildrenContainerStub;
158b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationGroupManager mGroupManager;
159b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mChildrenExpanded;
160263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private boolean mIsSummaryWithChildren;
161b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationChildrenContainer mChildrenContainer;
16295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    private NotificationMenuRowPlugin mMenuRow;
163ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    private ViewStub mGutsStub;
164b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mIsSystemChildExpanded;
165684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    private boolean mIsPinned;
1660e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski    private FalsingManager mFalsingManager;
1675cf1d0589a0045ee5f01802975f394847e891215Selim Cinek    private AboveShelfChangedListener mAboveShelfChangedListener;
16831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    private HeadsUpManager mHeadsUpManager;
169b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
1705eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    private boolean mJustClicked;
1715a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek    private boolean mIconAnimationRunning;
17234d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    private boolean mShowNoBackground;
173388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    private ExpandableNotificationRow mNotificationParent;
174570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    private OnExpandClickListener mOnExpandClickListener;
175b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    private boolean mGroupExpansionChanging;
176b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
1776bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen    /**
1786bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     * Whether or not a notification that is not part of a group of notifications can be manually
1796bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     * expanded by the user.
1806bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     */
1816bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen    private boolean mEnableNonGroupedNotificationExpand;
1826bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen
1836bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen    /**
1846bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     * Whether or not to update the background of the header of the notification when its expanded.
1856bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     * If {@code true}, the header background will disappear when expanded.
1866bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     */
1876bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen    private boolean mShowGroupBackgroundWhenExpanded;
1886bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen
189eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    private OnClickListener mExpandClickListener = new OnClickListener() {
190eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        @Override
191eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        public void onClick(View v) {
192414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            if (!mShowingPublic && (!mIsLowPriority || isExpanded())
193414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                    && mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
1941a5d8eadd56b435843dfbc1adf3779aa7286081bMady Mellor                mGroupExpansionChanging = true;
195698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                final boolean wasExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
196698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                boolean nowExpanded = mGroupManager.toggleGroupExpansion(mStatusBarNotification);
197698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                mOnExpandClickListener.onExpandClicked(mEntry, nowExpanded);
198698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER,
199698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                        nowExpanded);
200414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                onExpansionChanged(true /* userAction */, wasExpanded);
2016bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen            } else if (mEnableNonGroupedNotificationExpand) {
202e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                if (v.isAccessibilityFocused()) {
203e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                    mPrivateLayout.setFocusOnVisibilityChange();
204e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                }
20531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                boolean nowExpanded;
20631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                if (isPinned()) {
20731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    nowExpanded = !mExpandedWhenPinned;
20831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    mExpandedWhenPinned = nowExpanded;
20931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                } else {
21031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    nowExpanded = !isExpanded();
21131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    setUserExpanded(nowExpanded);
21231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                }
213eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                notifyHeightChanged(true);
21431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                mOnExpandClickListener.onExpandClicked(mEntry, nowExpanded);
215698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_EXPANDER,
216698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                        nowExpanded);
217eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
218eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        }
219eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    };
2201b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek    private boolean mForceUnlocked;
2213f19f60d654421eee5b35a92129081f08c977629Selim Cinek    private boolean mDismissed;
2223f19f60d654421eee5b35a92129081f08c977629Selim Cinek    private boolean mKeepInParent;
2233f19f60d654421eee5b35a92129081f08c977629Selim Cinek    private boolean mRemoved;
224b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    private static final Property<ExpandableNotificationRow, Float> TRANSLATE_CONTENT =
225b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            new FloatProperty<ExpandableNotificationRow>("translate") {
226b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                @Override
227b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                public void setValue(ExpandableNotificationRow object, float value) {
228b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                    object.setTranslation(value);
229b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                }
230b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
231b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                @Override
232b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                public Float get(ExpandableNotificationRow object) {
233b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                    return object.getTranslation();
234b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                }
235b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    };
236ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    private OnClickListener mOnClickListener;
23773cf02a0783e3857cae21fece9c292abcc9e1409Selim Cinek    private boolean mHeadsupDisappearRunning;
238e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    private View mChildAfterViewWhenDismissed;
239e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    private View mGroupParentWhenDismissed;
240e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    private boolean mRefocusOnDismiss;
2412b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    private float mContentTransformationAmount;
2420242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    private boolean mIconsVisible = true;
243d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    private boolean mAboveShelf;
2440aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos    private boolean mShowAmbient;
245875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    private boolean mIsLastChild;
246e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek    private Runnable mOnDismissRunnable;
2476743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek    private boolean mIsLowPriority;
248a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek    private boolean mIsColorized;
2497d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek    private boolean mUseIncreasedCollapsedHeight;
25087ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek    private boolean mUseIncreasedHeadsUpHeight;
251ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    private float mTranslationWhenRemoved;
252ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    private boolean mWasChildInGroupWhenRemoved;
2536f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    private int mNotificationColorAmbient;
254b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
25543c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
256b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public boolean isGroupExpansionChanging() {
257b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (isChildInGroup()) {
258b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            return mNotificationParent.isGroupExpansionChanging();
259b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
260b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        return mGroupExpansionChanging;
261b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
262b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
263b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public void setGroupExpansionChanging(boolean changing) {
264b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        mGroupExpansionChanging = changing;
265b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
2665eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
267599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos    @Override
268599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos    public void setActualHeightAnimating(boolean animating) {
269599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos        if (mPrivateLayout != null) {
270599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos            mPrivateLayout.setContentHeightAnimating(animating);
271599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos        }
272599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos    }
273599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos
2748d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPrivateLayout() {
2758d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPrivateLayout;
2768d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
2778d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
2788d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPublicLayout() {
2798d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPublicLayout;
2808d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
2818d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
282cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    public void setIconAnimationRunning(boolean running) {
283eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
284eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            setIconAnimationRunning(running, l);
285eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
2865a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        if (mIsSummaryWithChildren) {
287b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            setIconAnimationRunningForChild(running, mChildrenContainer.getHeaderView());
288414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            setIconAnimationRunningForChild(running, mChildrenContainer.getLowPriorityHeaderView());
2895a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            List<ExpandableNotificationRow> notificationChildren =
2905a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                    mChildrenContainer.getNotificationChildren();
2915a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
2925a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
2935a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                child.setIconAnimationRunning(running);
2945a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            }
2955a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        }
2965a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        mIconAnimationRunning = running;
297cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
298cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
299cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunning(boolean running, NotificationContentView layout) {
300cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (layout != null) {
301cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View contractedChild = layout.getContractedChild();
302cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View expandedChild = layout.getExpandedChild();
3038d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
304cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, contractedChild);
305cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, expandedChild);
3068d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            setIconAnimationRunningForChild(running, headsUpChild);
307cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
308cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
309cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
310cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunningForChild(boolean running, View child) {
311cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (child != null) {
312cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView icon = (ImageView) child.findViewById(com.android.internal.R.id.icon);
313cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(icon, running);
314cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView rightIcon = (ImageView) child.findViewById(
315cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    com.android.internal.R.id.right_icon);
316cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(rightIcon, running);
317cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
318cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
319cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
320cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconRunning(ImageView imageView, boolean running) {
321cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (imageView != null) {
322cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            Drawable drawable = imageView.getDrawable();
323cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            if (drawable instanceof AnimationDrawable) {
324cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
325cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
326cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
327cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
328cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
329cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
330cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            } else if (drawable instanceof AnimatedVectorDrawable) {
331cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimatedVectorDrawable animationDrawable = (AnimatedVectorDrawable) drawable;
332cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
333cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
334cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
335cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
336cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
337cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            }
338cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
339cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
340cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
3415ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    public void updateNotification(NotificationData.Entry entry) {
342da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        mEntry = entry;
343da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        mStatusBarNotification = entry.notification;
3441a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.inflateNotificationViews();
345c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
346c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
3475ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    public void onNotificationUpdated() {
348eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
349c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            l.onNotificationUpdated(mEntry);
350eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
351a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek        mIsColorized = mStatusBarNotification.getNotification().isColorized();
352757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek        mShowingPublicInitialized = false;
3534bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek        updateNotificationColor();
3544c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor        if (mMenuRow != null) {
3554ab2820e6c668ae7c55b300f126bb9f70c202ba3Mady Mellor            mMenuRow.onNotificationUpdated(mStatusBarNotification);
3564c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor        }
3578fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        if (mIsSummaryWithChildren) {
358414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            mChildrenContainer.recreateNotificationHeader(mExpandClickListener);
359c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            mChildrenContainer.onNotificationUpdated();
3608fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        }
3615a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        if (mIconAnimationRunning) {
3625a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            setIconAnimationRunning(true);
3635a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        }
364ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        if (mNotificationParent != null) {
365ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek            mNotificationParent.updateChildrenHeaderAppearance();
366ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        }
367263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
368624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek        // The public layouts expand button is always visible
369624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek        mPublicLayout.updateExpandButtons(true);
370da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateLimits();
3710242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek        updateIconVisibilities();
3726743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        updateShelfIconColor();
3736743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek    }
3746743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek
375b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin    @VisibleForTesting
376b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin    void updateShelfIconColor() {
3776743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        StatusBarIconView expandedIcon = mEntry.expandedIcon;
3786743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        boolean isPreL = Boolean.TRUE.equals(expandedIcon.getTag(R.id.icon_is_pre_L));
3796743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        boolean colorize = !isPreL || NotificationUtils.isGrayscale(expandedIcon,
3806743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek                NotificationColorUtil.getInstance(mContext));
381875ba9bd8ec0fa3d29fe27efcb3a20e53ce85f4fSelim Cinek        int color = StatusBarIconView.NO_COLOR;
3826743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        if (colorize) {
383b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin            NotificationHeaderView header = getVisibleNotificationHeader();
384b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin            if (header != null) {
385b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin                color = header.getOriginalIconColor();
386b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin            } else {
387b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin                color = mEntry.getContrastedColor(mContext, mIsLowPriority && !isExpanded(),
388b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin                        getBackgroundColorWithoutTint());
389b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin            }
3906743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        }
391875ba9bd8ec0fa3d29fe27efcb3a20e53ce85f4fSelim Cinek        expandedIcon.setStaticDrawableColor(color);
392da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    }
393da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek
3945cf1d0589a0045ee5f01802975f394847e891215Selim Cinek    public void setAboveShelfChangedListener(AboveShelfChangedListener aboveShelfChangedListener) {
3955cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        mAboveShelfChangedListener = aboveShelfChangedListener;
3965cf1d0589a0045ee5f01802975f394847e891215Selim Cinek    }
3975cf1d0589a0045ee5f01802975f394847e891215Selim Cinek
3984705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek    @Override
3994705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek    public boolean isDimmable() {
4004705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek        if (!getShowingLayout().isDimmable()) {
4014705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek            return false;
4024705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek        }
4034705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek        return super.isDimmable();
4044705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek    }
4054705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek
406da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private void updateLimits() {
407eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
408eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            updateLimitsForView(l);
409eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
410a1744872f4447dd370002a607c32776dffe519f5Selim Cinek    }
411a1744872f4447dd370002a607c32776dffe519f5Selim Cinek
412a1744872f4447dd370002a607c32776dffe519f5Selim Cinek    private void updateLimitsForView(NotificationContentView layout) {
413a1744872f4447dd370002a607c32776dffe519f5Selim Cinek        boolean customView = layout.getContractedChild().getId()
414da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek                != com.android.internal.R.id.status_bar_latest_event_content;
415da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
4167d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        int minHeight;
4177d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        if (customView && beforeN && !mIsSummaryWithChildren) {
4187d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek            minHeight = mNotificationMinHeightLegacy;
4197d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        } else if (mUseIncreasedCollapsedHeight && layout == mPrivateLayout) {
4207d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek            minHeight = mNotificationMinHeightLarge;
4217d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        } else {
4227d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek            minHeight = mNotificationMinHeight;
4237d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        }
424a1744872f4447dd370002a607c32776dffe519f5Selim Cinek        boolean headsUpCustom = layout.getHeadsUpChild() != null &&
425a1744872f4447dd370002a607c32776dffe519f5Selim Cinek                layout.getHeadsUpChild().getId()
426a1744872f4447dd370002a607c32776dffe519f5Selim Cinek                        != com.android.internal.R.id.status_bar_latest_event_content;
42787ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        int headsUpheight;
42887ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        if (headsUpCustom && beforeN) {
42987ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek            headsUpheight = mMaxHeadsUpHeightLegacy;
43087ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        } else if (mUseIncreasedHeadsUpHeight && layout == mPrivateLayout) {
43187ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek            headsUpheight = mMaxHeadsUpHeightIncreased;
43287ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        } else {
43387ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek            headsUpheight = mMaxHeadsUpHeight;
43487ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        }
4350aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos        layout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight,
4360aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos                mNotificationAmbientHeight);
437b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
438b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
439b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    public StatusBarNotification getStatusBarNotification() {
440b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        return mStatusBarNotification;
441b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
442b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
443281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    public NotificationData.Entry getEntry() {
444281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek        return mEntry;
445281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    }
446281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek
447b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    public boolean isHeadsUp() {
448b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek        return mIsHeadsUp;
449b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
450b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
4511a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    public void setHeadsUp(boolean isHeadsUp) {
4525cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        boolean wasAboveShelf = isAboveShelf();
453c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        int intrinsicBefore = getIntrinsicHeight();
4541a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mIsHeadsUp = isHeadsUp;
4558d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mPrivateLayout.setHeadsUp(isHeadsUp);
456b41b2f6fc2bcce6da6d6ae855a2a36cfa6f7f99dSelim Cinek        if (mIsSummaryWithChildren) {
457b41b2f6fc2bcce6da6d6ae855a2a36cfa6f7f99dSelim Cinek            // The overflow might change since we allow more lines as HUN.
458b41b2f6fc2bcce6da6d6ae855a2a36cfa6f7f99dSelim Cinek            mChildrenContainer.updateGroupOverflow();
459b41b2f6fc2bcce6da6d6ae855a2a36cfa6f7f99dSelim Cinek        }
460c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
461c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek            notifyHeightChanged(false  /* needsAnimation */);
462c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        }
463d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek        if (isHeadsUp) {
464d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek            setAboveShelf(true);
4655cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        } else if (isAboveShelf() != wasAboveShelf) {
4665cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
467d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek        }
4681a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    }
4691a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek
470b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setGroupManager(NotificationGroupManager groupManager) {
471b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mGroupManager = groupManager;
47283bc78338437a460076a4b5778ded38440ac3501Selim Cinek        mPrivateLayout.setGroupManager(groupManager);
473b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
474b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
475b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos    public void setRemoteInputController(RemoteInputController r) {
476b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos        mPrivateLayout.setRemoteInputController(r);
477b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos    }
478b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos
4793fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor    public void setAppName(String appName) {
4803fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor        mAppName = appName;
48195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow != null && mMenuRow.getMenuView() != null) {
482761cde1173cdfbc058034ffb10283e5507ed0ed4Mady Mellor            mMenuRow.setAppName(mAppName);
4833fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor        }
4843fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor    }
4853fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor
486b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row) {
487b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        addChildNotification(row, -1);
488b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
489b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
490b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
491b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Add a child notification to this view.
492b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
493b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param row the row to add
494b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childIndex the index to add it at, if -1 it will be added at the end
495b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
496b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row, int childIndex) {
497b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer == null) {
498b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainerStub.inflate();
499b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
500b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainer.addNotification(row, childIndex);
501263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
502263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(true, this);
503b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
504b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
505b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void removeChildNotification(ExpandableNotificationRow row) {
506b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer != null) {
507b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.removeNotification(row);
508b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
509263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
510263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(false, null);
511263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
512263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
51343c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
514263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isChildInGroup() {
515a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        return mNotificationParent != null;
516263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
517263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
518388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public ExpandableNotificationRow getNotificationParent() {
519388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        return mNotificationParent;
520388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
521388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
522263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    /**
523263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param isChildInGroup Is this notification now in a group
524263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param parent the new parent notification
525263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     */
526a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {;
5272a6ea9c2a1b52b0386270ec73e1e6d6a9b614a34Jason Monk        boolean childInGroup = StatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
528a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mNotificationParent = childInGroup ? parent : null;
529a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mPrivateLayout.setIsChildInGroup(childInGroup);
5305ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek        mNotificationInflater.setIsChildInGroup(childInGroup);
531c7d65b4e9c784a8235424c30620bacd54cc0892eMady Mellor        resetBackgroundAlpha();
532b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        updateBackgroundForGroupState();
533ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        updateClickAndFocus();
534b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mNotificationParent != null) {
5359ce3285dc3a5da05d21b0b1c4628ea3bf86f6644Selim Cinek            setOverrideTintColor(NO_COLOR, 0.0f);
536b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mNotificationParent.updateBackgroundForGroupState();
537b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
538db16737031091160a3a7d080ac44ce2836402d74Selim Cinek        updateIconVisibilities();
53934d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    }
54034d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek
54134d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    @Override
5427210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    public boolean onTouchEvent(MotionEvent event) {
5437210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        if (event.getActionMasked() != MotionEvent.ACTION_DOWN
5447210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek                || !isChildInGroup() || isGroupExpanded()) {
5457210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek            return super.onTouchEvent(event);
5467210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        } else {
5477210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek            return false;
5487210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        }
5497210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    }
5507210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek
5517210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    @Override
552f062580d395a8c99631c104d6aec250f961152ddMady Mellor    protected boolean handleSlideBack() {
55395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow != null && mMenuRow.isMenuVisible()) {
554f062580d395a8c99631c104d6aec250f961152ddMady Mellor            animateTranslateNotification(0 /* targetLeft */);
555f062580d395a8c99631c104d6aec250f961152ddMady Mellor            return true;
556f062580d395a8c99631c104d6aec250f961152ddMady Mellor        }
557f062580d395a8c99631c104d6aec250f961152ddMady Mellor        return false;
558f062580d395a8c99631c104d6aec250f961152ddMady Mellor    }
559f062580d395a8c99631c104d6aec250f961152ddMady Mellor
560f062580d395a8c99631c104d6aec250f961152ddMady Mellor    @Override
56134d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    protected boolean shouldHideBackground() {
56234d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek        return super.shouldHideBackground() || mShowNoBackground;
563263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
564263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
565263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    @Override
566263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isSummaryWithChildren() {
567263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        return mIsSummaryWithChildren;
568b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
569b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
570b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    @Override
571b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public boolean areChildrenExpanded() {
572b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenExpanded;
573b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
574b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
575b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public List<ExpandableNotificationRow> getNotificationChildren() {
576b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenContainer == null ? null : mChildrenContainer.getNotificationChildren();
577b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
578b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
579eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    public int getNumberOfNotificationChildren() {
580eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        if (mChildrenContainer == null) {
581eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek            return 0;
582eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        }
583eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mChildrenContainer.getNotificationChildren().size();
584eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    }
585eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek
586b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
587b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Apply the order given in the list to the children.
588b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
589b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childOrder the new list order
590a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek     * @param visualStabilityManager
591a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek     * @param callback the callback to invoked in case it is not allowed
592b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @return whether the list order has changed
593b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
594a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek    public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
595a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek            VisualStabilityManager visualStabilityManager,
596a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek            VisualStabilityManager.Callback callback) {
597a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek        return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder,
598a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek                visualStabilityManager, callback);
599b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
600b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
601b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void getChildrenStates(StackScrollState resultState) {
60283bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
603bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            ExpandableViewState parentState = resultState.getViewStateForView(this);
604b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.getState(resultState, parentState);
605b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
606b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
607b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
608b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void applyChildrenState(StackScrollState state) {
60983bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
610b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.applyState(state);
611b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
612b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
613b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
614b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void prepareExpansionChanged(StackScrollState state) {
61583bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
616b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.prepareExpansionChanged(state);
617b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
618b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
619b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
6200cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek    public void startChildAnimation(StackScrollState finalState, AnimationProperties properties) {
62183bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
6220cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            mChildrenContainer.startAnimationToState(finalState, properties);
623b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
624b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
625b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
626b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public ExpandableNotificationRow getViewAtPosition(float y) {
62743d30f03f45f3f9ad3955f5c83f4d21f26891de6Selim Cinek        if (!mIsSummaryWithChildren || !mChildrenExpanded) {
628b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return this;
629b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
630b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ExpandableNotificationRow view = mChildrenContainer.getViewAtPosition(y);
631b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return view == null ? this : view;
632b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
633b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
634b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
635ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public NotificationGuts getGuts() {
636ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        return mGuts;
637ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
638ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
639684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    /**
640684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
641684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * the notification will be rendered on top of the screen.
642684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     *
643684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * @param pinned whether it is pinned
644684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     */
645684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public void setPinned(boolean pinned) {
646def35a86530200958384191d43d321dbcda16e2aSelim Cinek        int intrinsicHeight = getIntrinsicHeight();
6475cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        boolean wasAboveShelf = isAboveShelf();
648684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        mIsPinned = pinned;
649def35a86530200958384191d43d321dbcda16e2aSelim Cinek        if (intrinsicHeight != getIntrinsicHeight()) {
650bb42b7dd4892a8ab99f2f702cad931235d1d463eSelim Cinek            notifyHeightChanged(false /* needsAnimation */);
651def35a86530200958384191d43d321dbcda16e2aSelim Cinek        }
65231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if (pinned) {
65331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            setIconAnimationRunning(true);
65431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            mExpandedWhenPinned = false;
65531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mExpandedWhenPinned) {
65631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            setUserExpanded(true);
65731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        }
65898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(mLastChronometerRunning);
6595cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        if (isAboveShelf() != wasAboveShelf) {
6605cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
6615cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        }
662b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
663b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
664684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public boolean isPinned() {
665684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        return mIsPinned;
666b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
667b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
668d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    @Override
669d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    public int getPinnedHeadsUpHeight() {
670d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek        return getPinnedHeadsUpHeight(true /* atLeastMinHeight */);
671d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    }
672d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek
67331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    /**
67431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * @param atLeastMinHeight should the value returned be at least the minimum height.
67531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     *                         Used to avoid cyclic calls
67631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * @return the height of the heads up notification when pinned
67731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     */
678d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    private int getPinnedHeadsUpHeight(boolean atLeastMinHeight) {
67977019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        if (mIsSummaryWithChildren) {
68077019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek            return mChildrenContainer.getIntrinsicHeight();
68177019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        }
68231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if(mExpandedWhenPinned) {
68331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return Math.max(getMaxExpandHeight(), mHeadsUpHeight);
68431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (atLeastMinHeight) {
685567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek            return Math.max(getCollapsedHeight(), mHeadsUpHeight);
68631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else {
68731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return mHeadsUpHeight;
68831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        }
689b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
690b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
6915eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
6925eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * Mark whether this notification was just clicked, i.e. the user has just clicked this
6935eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * notification in this frame.
6945eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
6955eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public void setJustClicked(boolean justClicked) {
6965eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        mJustClicked = justClicked;
6975eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
6985eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
6995eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
7005eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * @return true if this notification has been clicked in this frame, false otherwise
7015eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
7025eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public boolean wasJustClicked() {
7035eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        return mJustClicked;
7045eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
7055eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
70698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    public void setChronometerRunning(boolean running) {
70798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        mLastChronometerRunning = running;
70898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPrivateLayout);
70998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPublicLayout);
71098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (mChildrenContainer != null) {
71198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
71298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                    mChildrenContainer.getNotificationChildren();
71398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
71498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
71598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                child.setChronometerRunning(running);
71698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
71798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
71898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
71998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
72098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunning(boolean running, NotificationContentView layout) {
72198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (layout != null) {
72298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            running = running || isPinned();
72398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View contractedChild = layout.getContractedChild();
72498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View expandedChild = layout.getExpandedChild();
72598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
72698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, contractedChild);
72798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, expandedChild);
72898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, headsUpChild);
72998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
73098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
73198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
73298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunningForChild(boolean running, View child) {
73398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (child != null) {
73498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View chronometer = child.findViewById(com.android.internal.R.id.chronometer);
73598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            if (chronometer instanceof Chronometer) {
73698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ((Chronometer) chronometer).setStarted(running);
73798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
73898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
73998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
74098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
741ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    public NotificationHeaderView getNotificationHeader() {
742b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mIsSummaryWithChildren) {
743b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            return mChildrenContainer.getHeaderView();
7448d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        }
745ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        return mPrivateLayout.getNotificationHeader();
7468d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek    }
7478d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek
748414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    /**
749414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek     * @return the currently visible notification header. This can be different from
750414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek     * {@link #getNotificationHeader()} in case it is a low-priority group.
751414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek     */
752414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    public NotificationHeaderView getVisibleNotificationHeader() {
753aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
754414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            return mChildrenContainer.getVisibleHeader();
75534eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        }
75634eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        return getShowingLayout().getVisibleNotificationHeader();
757b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek    }
758b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek
759b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek
760b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek    /**
761b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek     * @return the contracted notification header. This can be different from
762b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek     * {@link #getNotificationHeader()} and also {@link #getVisibleNotificationHeader()} and only
763b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek     * returns the contracted version.
764b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek     */
765b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek    public NotificationHeaderView getContractedNotificationHeader() {
766b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek        if (mIsSummaryWithChildren) {
767b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek            return mChildrenContainer.getHeaderView();
768b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek        }
769b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek        return mPrivateLayout.getContractedNotificationHeader();
77034eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek    }
77134eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek
772570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) {
773570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek        mOnExpandClickListener = onExpandClickListener;
774570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    }
775570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek
776ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    @Override
777ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    public void setOnClickListener(@Nullable OnClickListener l) {
778ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        super.setOnClickListener(l);
779ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        mOnClickListener = l;
780ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        updateClickAndFocus();
781ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    }
782ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek
783ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    private void updateClickAndFocus() {
784ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        boolean normalChild = !isChildInGroup() || isGroupExpanded();
785ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        boolean clickable = mOnClickListener != null && normalChild;
786ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        if (isFocusable() != normalChild) {
787ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek            setFocusable(normalChild);
788ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        }
789ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        if (isClickable() != clickable) {
790ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek            setClickable(clickable);
791ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        }
792ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    }
793ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek
79431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    public void setHeadsUpManager(HeadsUpManager headsUpManager) {
79531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        mHeadsUpManager = headsUpManager;
79631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    }
79731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek
79887d7945f0693d3ca943bfb6491d4eba3a8d7cc75Mady Mellor    public void setGutsView(MenuItem item) {
79995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mGuts != null && item.getGutsView() instanceof GutsContent) {
80095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            ((GutsContent) item.getGutsView()).setGutsParent(mGuts);
80195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            mGuts.setGutsContent((GutsContent) item.getGutsView());
80287d7945f0693d3ca943bfb6491d4eba3a8d7cc75Mady Mellor        }
80387d7945f0693d3ca943bfb6491d4eba3a8d7cc75Mady Mellor    }
80487d7945f0693d3ca943bfb6491d4eba3a8d7cc75Mady Mellor
80595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    @Override
80695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    protected void onAttachedToWindow() {
80795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        super.onAttachedToWindow();
80895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        Dependency.get(PluginManager.class).addPluginListener(this,
80995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor                NotificationMenuRowPlugin.class, false /* Allow multiple */);
81095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
81195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
81295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    @Override
81395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    protected void onDetachedFromWindow() {
81495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        super.onDetachedFromWindow();
81595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        Dependency.get(PluginManager.class).removePluginListener(this);
81695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
81795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
81895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    @Override
81995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    public void onPluginConnected(NotificationMenuRowPlugin plugin, Context pluginContext) {
82095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        boolean existed = mMenuRow.getMenuView() != null;
82195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (existed) {
82295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            removeView(mMenuRow.getMenuView());
82395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
82495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        mMenuRow = plugin;
82595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow.useDefaultMenuItems()) {
8264c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor            ArrayList<MenuItem> items = new ArrayList<>();
8274c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor            items.add(NotificationMenuRow.createInfoItem(mContext));
8284c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor            items.add(NotificationMenuRow.createSnoozeItem(mContext));
8294c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor            mMenuRow.setMenuItems(items);
83095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
83195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (existed) {
83295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            createMenu();
83395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
83495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
83595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
83695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    @Override
83795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    public void onPluginDisconnected(NotificationMenuRowPlugin plugin) {
83895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        boolean existed = mMenuRow.getMenuView() != null;
83995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        mMenuRow = new NotificationMenuRow(mContext); // Back to default
84095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (existed) {
84195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            createMenu();
84295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
84395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
84495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
84595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    public NotificationMenuRowPlugin createMenu() {
84695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow.getMenuView() == null) {
8474ab2820e6c668ae7c55b300f126bb9f70c202ba3Mady Mellor            mMenuRow.createMenu(this, mStatusBarNotification);
84895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            mMenuRow.setAppName(mAppName);
84995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            FrameLayout.LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
85095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor                    LayoutParams.MATCH_PARENT);
85195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            addView(mMenuRow.getMenuView(), MENU_VIEW_INDEX, lp);
85295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
85395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        return mMenuRow;
85495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
85595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
85695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    public NotificationMenuRowPlugin getProvider() {
85795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        return mMenuRow;
85895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
85995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
8609fe1ee7413d2d914cc24a1123a22dc5b16952b8fAnthony Chen    @Override
8611a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void onDensityOrFontScaleChanged() {
8629fe1ee7413d2d914cc24a1123a22dc5b16952b8fAnthony Chen        super.onDensityOrFontScaleChanged();
86301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        initDimens();
864817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        // Let's update our childrencontainer. This is intentionally not guarded with
865817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        // mIsSummaryWithChildren since we might have had children but not anymore.
866817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        if (mChildrenContainer != null) {
867817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek            mChildrenContainer.reInflateViews(mExpandClickListener, mEntry.notification);
86801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        }
86901af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        if (mGuts != null) {
87001af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            View oldGuts = mGuts;
87101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            int index = indexOfChild(oldGuts);
87201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            removeView(oldGuts);
87301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mGuts = (NotificationGuts) LayoutInflater.from(mContext).inflate(
87401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek                    R.layout.notification_guts, this, false);
87501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mGuts.setVisibility(oldGuts.getVisibility());
87601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            addView(mGuts, index);
87701af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        }
87895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        View oldMenu = mMenuRow.getMenuView();
87995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (oldMenu != null) {
880761cde1173cdfbc058034ffb10283e5507ed0ed4Mady Mellor            int menuIndex = indexOfChild(oldMenu);
881761cde1173cdfbc058034ffb10283e5507ed0ed4Mady Mellor            removeView(oldMenu);
8824ab2820e6c668ae7c55b300f126bb9f70c202ba3Mady Mellor            mMenuRow.createMenu(ExpandableNotificationRow.this, mStatusBarNotification);
883761cde1173cdfbc058034ffb10283e5507ed0ed4Mady Mellor            mMenuRow.setAppName(mAppName);
88495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            addView(mMenuRow.getMenuView(), menuIndex);
8854b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
886eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
887eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.reInflateViews();
888eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
8891a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.onDensityOrFontScaleChanged();
8901a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        onNotificationUpdated();
89101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    }
89201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek
8939d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor    @Override
8949d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor    public void onConfigurationChanged(Configuration newConfig) {
8959d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor        if (mMenuRow.getMenuView() != null) {
8969d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor            mMenuRow.onConfigurationChanged();
8979d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor        }
8989d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor    }
8999d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor
900c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek    public void setContentBackground(int customBackgroundColor, boolean animate,
901c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek            NotificationContentView notificationContentView) {
902c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        if (getShowingLayout() == notificationContentView) {
903c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek            setTintColor(customBackgroundColor, animate);
904c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        }
905c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek    }
906c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek
9070bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos    public void closeRemoteInput() {
908eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
909eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.closeRemoteInput();
910eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
9110bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos    }
9120bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos
913c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    /**
914c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek     * Set by how much the single line view should be indented.
915c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek     */
916c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    public void setSingleLineWidthIndention(int indention) {
917c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        mPrivateLayout.setSingleLineWidthIndention(indention);
918c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    }
919c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek
920c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    public int getNotificationColor() {
9214bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek        return mNotificationColor;
9224bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek    }
9234bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek
9244bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek    private void updateNotificationColor() {
9254bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek        mNotificationColor = NotificationColorUtil.resolveContrastColor(mContext,
926ac5f02749a595d39711beb4a1defb01949eb548aSelim Cinek                getStatusBarNotification().getNotification().color,
927ac5f02749a595d39711beb4a1defb01949eb548aSelim Cinek                getBackgroundColorWithoutTint());
9286f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        mNotificationColorAmbient = NotificationColorUtil.resolveAmbientColor(mContext,
9296f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos                getStatusBarNotification().getNotification().color);
930c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    }
931c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek
932c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    public HybridNotificationView getSingleLineView() {
933c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        return mPrivateLayout.getSingleLineView();
934c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    }
935c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek
9366f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    public HybridNotificationView getAmbientSingleLineView() {
9376f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        return getShowingLayout().getAmbientSingleLineChild();
9386f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    }
9396f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos
940f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek    public boolean isOnKeyguard() {
941f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek        return mOnKeyguard;
942f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek    }
943f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek
944c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek    public void removeAllChildren() {
945c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        List<ExpandableNotificationRow> notificationChildren
946c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek                = mChildrenContainer.getNotificationChildren();
947c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        ArrayList<ExpandableNotificationRow> clonedList = new ArrayList<>(notificationChildren);
948c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        for (int i = 0; i < clonedList.size(); i++) {
949c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            ExpandableNotificationRow row = clonedList.get(i);
9503f19f60d654421eee5b35a92129081f08c977629Selim Cinek            if (row.keepInParent()) {
9513f19f60d654421eee5b35a92129081f08c977629Selim Cinek                continue;
9523f19f60d654421eee5b35a92129081f08c977629Selim Cinek            }
953c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            mChildrenContainer.removeNotification(row);
954c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            row.setIsChildInGroup(false, null);
955c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        }
956c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        onChildrenCountChanged();
957c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek    }
958c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek
9591b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek    public void setForceUnlocked(boolean forceUnlocked) {
9601b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek        mForceUnlocked = forceUnlocked;
9611b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek        if (mIsSummaryWithChildren) {
9621b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek            List<ExpandableNotificationRow> notificationChildren = getNotificationChildren();
9631b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek            for (ExpandableNotificationRow child : notificationChildren) {
9641b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek                child.setForceUnlocked(forceUnlocked);
9651b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek            }
9661b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek        }
9671b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek    }
9681b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek
969e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public void setDismissed(boolean dismissed, boolean fromAccessibility) {
9703f19f60d654421eee5b35a92129081f08c977629Selim Cinek        mDismissed = dismissed;
971e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        mGroupParentWhenDismissed = mNotificationParent;
972e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        mRefocusOnDismiss = fromAccessibility;
973e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        mChildAfterViewWhenDismissed = null;
974e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        if (isChildInGroup()) {
975e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
976e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                    mNotificationParent.getNotificationChildren();
977e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            int i = notificationChildren.indexOf(this);
978e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            if (i != -1 && i < notificationChildren.size() - 1) {
979e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                mChildAfterViewWhenDismissed = notificationChildren.get(i + 1);
980e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            }
981e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        }
9823f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
9833f19f60d654421eee5b35a92129081f08c977629Selim Cinek
9843f19f60d654421eee5b35a92129081f08c977629Selim Cinek    public boolean isDismissed() {
9853f19f60d654421eee5b35a92129081f08c977629Selim Cinek        return mDismissed;
9863f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
9873f19f60d654421eee5b35a92129081f08c977629Selim Cinek
9883f19f60d654421eee5b35a92129081f08c977629Selim Cinek    public boolean keepInParent() {
9893f19f60d654421eee5b35a92129081f08c977629Selim Cinek        return mKeepInParent;
9903f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
9913f19f60d654421eee5b35a92129081f08c977629Selim Cinek
9923f19f60d654421eee5b35a92129081f08c977629Selim Cinek    public void setKeepInParent(boolean keepInParent) {
9933f19f60d654421eee5b35a92129081f08c977629Selim Cinek        mKeepInParent = keepInParent;
9943f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
9953f19f60d654421eee5b35a92129081f08c977629Selim Cinek
9963f19f60d654421eee5b35a92129081f08c977629Selim Cinek    public boolean isRemoved() {
9973f19f60d654421eee5b35a92129081f08c977629Selim Cinek        return mRemoved;
9983f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
9993f19f60d654421eee5b35a92129081f08c977629Selim Cinek
1000d009ab1e2a57648cac9de93912964e2a36ae1762Adrian Roos    public void setRemoved() {
1001d009ab1e2a57648cac9de93912964e2a36ae1762Adrian Roos        mRemoved = true;
1002ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        mTranslationWhenRemoved = getTranslationY();
1003ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        mWasChildInGroupWhenRemoved = isChildInGroup();
1004ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        if (isChildInGroup()) {
1005ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek            mTranslationWhenRemoved += getNotificationParent().getTranslationY();
1006ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        }
1007d009ab1e2a57648cac9de93912964e2a36ae1762Adrian Roos        mPrivateLayout.setRemoved();
10083f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
10093f19f60d654421eee5b35a92129081f08c977629Selim Cinek
1010ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    public boolean wasChildInGroupWhenRemoved() {
1011ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        return mWasChildInGroupWhenRemoved;
1012ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    }
1013ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek
1014ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    public float getTranslationWhenRemoved() {
1015ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        return mTranslationWhenRemoved;
1016ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    }
1017ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek
1018d13956475e97da9de83f6519eab514770118e7afSelim Cinek    public NotificationChildrenContainer getChildrenContainer() {
1019d13956475e97da9de83f6519eab514770118e7afSelim Cinek        return mChildrenContainer;
1020d13956475e97da9de83f6519eab514770118e7afSelim Cinek    }
1021d13956475e97da9de83f6519eab514770118e7afSelim Cinek
1022cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek    public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
10235cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        boolean wasAboveShelf = isAboveShelf();
1024cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek        mHeadsupDisappearRunning = headsUpAnimatingAway;
1025cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek        mPrivateLayout.setHeadsUpAnimatingAway(headsUpAnimatingAway);
10265cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        if (isAboveShelf() != wasAboveShelf) {
10275cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
10285cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        }
1029cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek    }
1030cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek
1031cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek    /**
1032cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek     * @return if the view was just heads upped and is now animating away. During such a time the
1033cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek     * layout needs to be kept consistent
1034cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek     */
1035cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek    public boolean isHeadsUpAnimatingAway() {
1036cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek        return mHeadsupDisappearRunning;
103773cf02a0783e3857cae21fece9c292abcc9e1409Selim Cinek    }
103873cf02a0783e3857cae21fece9c292abcc9e1409Selim Cinek
1039e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public View getChildAfterViewWhenDismissed() {
1040e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return mChildAfterViewWhenDismissed;
1041e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
1042e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
1043e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public View getGroupParentWhenDismissed() {
1044e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return mGroupParentWhenDismissed;
1045e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
1046e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
10479e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    public void performDismiss() {
1048e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek        if (mOnDismissRunnable != null) {
1049e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek            mOnDismissRunnable.run();
1050e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek        }
10519e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    }
10529e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek
1053e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek    public void setOnDismissRunnable(Runnable onDismissRunnable) {
1054e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek        mOnDismissRunnable = onDismissRunnable;
10559e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    }
10569e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek
1057281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    public View getNotificationIcon() {
1058414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        NotificationHeaderView notificationHeader = getVisibleNotificationHeader();
1059281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek        if (notificationHeader != null) {
1060281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek            return notificationHeader.getIcon();
1061281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek        }
1062281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek        return null;
1063281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    }
1064281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek
1065281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    /**
1066281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek     * @return whether the notification is currently showing a view with an icon.
1067281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek     */
1068281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    public boolean isShowingIcon() {
1069434180ce5155f0c405080698031f05e9eab3dd4cMady Mellor        if (areGutsExposed()) {
1070434180ce5155f0c405080698031f05e9eab3dd4cMady Mellor            return false;
1071434180ce5155f0c405080698031f05e9eab3dd4cMady Mellor        }
10722ffa02fcbb6359630a09e3d8617c514330ee31f1Selim Cinek        return getVisibleNotificationHeader() != null;
1073281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    }
1074281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek
10750242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    /**
10760242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek     * Set how much this notification is transformed into an icon.
10770242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek     *
10782b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek     * @param contentTransformationAmount A value from 0 to 1 indicating how much we are transformed
10792b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek     *                                 to the content away
1080875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * @param isLastChild is this the last child in the list. If true, then the transformation is
1081875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     *                    different since it's content fades out.
10820242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek     */
10832b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    public void setContentTransformationAmount(float contentTransformationAmount,
10842b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            boolean isLastChild) {
1085875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        boolean changeTransformation = isLastChild != mIsLastChild;
10862b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        changeTransformation |= mContentTransformationAmount != contentTransformationAmount;
1087875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        mIsLastChild = isLastChild;
10882b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        mContentTransformationAmount = contentTransformationAmount;
1089875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        if (changeTransformation) {
1090875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            updateContentTransformation();
10912b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        }
10922b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    }
10932b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek
10942b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    /**
10952b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek     * Set the icons to be visible of this notification.
10962b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek     */
10972b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    public void setIconsVisible(boolean iconsVisible) {
10982b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        if (iconsVisible != mIconsVisible) {
10992b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            mIconsVisible = iconsVisible;
11002b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            updateIconVisibilities();
11010242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek        }
11020242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    }
11030242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek
1104db16737031091160a3a7d080ac44ce2836402d74Selim Cinek    @Override
1105db16737031091160a3a7d080ac44ce2836402d74Selim Cinek    protected void onBelowSpeedBumpChanged() {
1106db16737031091160a3a7d080ac44ce2836402d74Selim Cinek        updateIconVisibilities();
1107db16737031091160a3a7d080ac44ce2836402d74Selim Cinek    }
1108db16737031091160a3a7d080ac44ce2836402d74Selim Cinek
1109875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    private void updateContentTransformation() {
1110875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        float contentAlpha;
11112b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        float translationY = -mContentTransformationAmount * mIconTransformContentShift;
1112875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        if (mIsLastChild) {
11132b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            contentAlpha = 1.0f - mContentTransformationAmount;
1114875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            contentAlpha = Math.min(contentAlpha / 0.5f, 1.0f);
11150242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek            contentAlpha = Interpolators.ALPHA_OUT.getInterpolation(contentAlpha);
1116875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            translationY *= 0.4f;
1117875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        } else {
1118875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            contentAlpha = 1.0f;
1119875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        }
1120eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
1121eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setAlpha(contentAlpha);
1122eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setTranslationY(translationY);
1123eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
1124875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        if (mChildrenContainer != null) {
1125875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            mChildrenContainer.setAlpha(contentAlpha);
1126875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            mChildrenContainer.setTranslationY(translationY);
1127875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            // TODO: handle children fade out better
11280242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek        }
11290242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    }
11300242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek
11310242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    private void updateIconVisibilities() {
113217e1b69523086a98189178fc7f2b23d74860c738Selim Cinek        boolean visible = isChildInGroup()
113317e1b69523086a98189178fc7f2b23d74860c738Selim Cinek                || (isBelowSpeedBump() && !NotificationShelf.SHOW_AMBIENT_ICONS)
113417e1b69523086a98189178fc7f2b23d74860c738Selim Cinek                || mIconsVisible;
1135eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
1136eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setIconsVisible(visible);
1137eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
1138db16737031091160a3a7d080ac44ce2836402d74Selim Cinek        if (mChildrenContainer != null) {
1139db16737031091160a3a7d080ac44ce2836402d74Selim Cinek            mChildrenContainer.setIconsVisible(visible);
11400242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek        }
11410242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    }
11420242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek
1143875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    /**
1144875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * Get the relative top padding of a view relative to this view. This recursively walks up the
1145875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * hierarchy and does the corresponding measuring.
1146875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     *
1147875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * @param view the view to the the padding for. The requested view has to be a child of this
1148875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     *             notification.
1149875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * @return the toppadding
1150875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     */
1151875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    public int getRelativeTopPadding(View view) {
1152875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        int topPadding = 0;
1153875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        while (view.getParent() instanceof ViewGroup) {
1154875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            topPadding += view.getTop();
1155875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            view = (View) view.getParent();
1156875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            if (view instanceof ExpandableNotificationRow) {
1157875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek                return topPadding;
1158875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            }
1159875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        }
1160875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        return topPadding;
1161875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    }
1162875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek
1163a1d9790735a183578ad8789234b7defd67ed0866Selim Cinek    public float getContentTranslation() {
1164a1d9790735a183578ad8789234b7defd67ed0866Selim Cinek        return mPrivateLayout.getTranslationY();
1165a1d9790735a183578ad8789234b7defd67ed0866Selim Cinek    }
1166a1d9790735a183578ad8789234b7defd67ed0866Selim Cinek
11676743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek    public void setIsLowPriority(boolean isLowPriority) {
11686743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        mIsLowPriority = isLowPriority;
11696743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        mPrivateLayout.setIsLowPriority(isLowPriority);
11701a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.setIsLowPriority(mIsLowPriority);
11716743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        if (mChildrenContainer != null) {
11726743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek            mChildrenContainer.setIsLowPriority(isLowPriority);
11736743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        }
11746743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek    }
11756743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek
117655a3e738a695d23982eb2e904f47a3435994a325Selim Cinek
117755a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    public void setLowPriorityStateUpdated(boolean lowPriorityStateUpdated) {
117855a3e738a695d23982eb2e904f47a3435994a325Selim Cinek        mLowPriorityStateUpdated = lowPriorityStateUpdated;
117955a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    }
118055a3e738a695d23982eb2e904f47a3435994a325Selim Cinek
118155a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    public boolean hasLowPriorityStateUpdated() {
118255a3e738a695d23982eb2e904f47a3435994a325Selim Cinek        return mLowPriorityStateUpdated;
118355a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    }
118455a3e738a695d23982eb2e904f47a3435994a325Selim Cinek
1185414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    public boolean isLowPriority() {
1186414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        return mIsLowPriority;
1187414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    }
1188414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek
11897d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek    public void setUseIncreasedCollapsedHeight(boolean use) {
11907d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        mUseIncreasedCollapsedHeight = use;
11911a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.setUsesIncreasedHeight(use);
11927d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek    }
11937d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek
119487ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek    public void setUseIncreasedHeadsUpHeight(boolean use) {
119587ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        mUseIncreasedHeadsUpHeight = use;
11961a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.setUsesIncreasedHeadsUpHeight(use);
11971a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
11981a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
11991a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setRemoteViewClickHandler(RemoteViews.OnClickHandler remoteViewClickHandler) {
12001a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.setRemoteViewClickHandler(remoteViewClickHandler);
120187ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek    }
120287ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek
12035ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    public void setInflationCallback(InflationCallback callback) {
12045ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek        mNotificationInflater.setInflationCallback(callback);
1205c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
1206c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
12071a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos    public void setNeedsRedaction(boolean needsRedaction) {
12081a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos        mNotificationInflater.setRedactAmbient(needsRedaction);
12091a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos    }
12101a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos
12115ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    @VisibleForTesting
12125ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    public NotificationInflater getNotificationInflater() {
12135ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek        return mNotificationInflater;
12145ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    }
12155ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek
12166f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    public int getNotificationColorAmbient() {
12176f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        return mNotificationColorAmbient;
12186f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    }
12196f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos
122078403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public interface ExpansionLogger {
12216bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen        void logNotificationExpansion(String key, boolean userAction, boolean expanded);
122278403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
12231685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
122451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
122551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        super(context, attrs);
12260e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager = FalsingManager.getInstance(context);
12271a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater = new NotificationInflater(this);
122895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        mMenuRow = new NotificationMenuRow(mContext);
122901af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        initDimens();
123001af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    }
123101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek
123201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private void initDimens() {
1233f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMinHeightLegacy = getFontScaledHeight(R.dimen.notification_min_height_legacy);
1234f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMinHeight = getFontScaledHeight(R.dimen.notification_min_height);
12357d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        mNotificationMinHeightLarge = getFontScaledHeight(
123687ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek                R.dimen.notification_min_height_increased);
1237f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMaxHeight = getFontScaledHeight(R.dimen.notification_max_height);
12380aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos        mNotificationAmbientHeight = getFontScaledHeight(R.dimen.notification_ambient_height);
1239f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mMaxHeadsUpHeightLegacy = getFontScaledHeight(
124077019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek                R.dimen.notification_max_heads_up_height_legacy);
1241f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mMaxHeadsUpHeight = getFontScaledHeight(R.dimen.notification_max_heads_up_height);
124287ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        mMaxHeadsUpHeightIncreased = getFontScaledHeight(
124387ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek                R.dimen.notification_max_heads_up_height_increased);
12446bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen
12457acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        Resources res = getResources();
12467acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        mIncreasedPaddingBetweenElements = res.getDimensionPixelSize(
12477acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                R.dimen.notification_divider_height_increased);
12487acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        mIconTransformContentShiftNoIcon = res.getDimensionPixelSize(
12490242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek                R.dimen.notification_icon_transform_content_shift);
12506bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen        mEnableNonGroupedNotificationExpand =
12516bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen                res.getBoolean(R.bool.config_enableNonGroupedNotificationExpand);
12526bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen        mShowGroupBackgroundWhenExpanded =
12536bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen                res.getBoolean(R.bool.config_showGroupNotificationBgWhenExpanded);
1254f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    }
1255f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek
1256f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    /**
1257f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     * @param dimenId the dimen to look up
1258f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     * @return the font scaled dimen as if it were in sp but doesn't shrink sizes below dp
1259f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     */
1260f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    private int getFontScaledHeight(int dimenId) {
1261f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        int dimensionPixelSize = getResources().getDimensionPixelSize(dimenId);
1262f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        float factor = Math.max(1.0f, getResources().getDisplayMetrics().scaledDensity /
1263f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek                getResources().getDisplayMetrics().density);
1264f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        return (int) (dimensionPixelSize * factor);
126551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
126651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1267a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    /**
1268a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     * Resets this view so it can be re-used for an updated notification.
1269a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     */
1270a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    public void reset() {
1271ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = false;
127231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        onHeightReset();
12736e28a678c7f9fe2cae5a51bfdbab3071a2d8d0baSelim Cinek        requestLayout();
1274a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    }
1275a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer
1276251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    @Override
1277251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    protected void onFinishInflate() {
1278251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi        super.onFinishInflate();
1279be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
1280be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
1281eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        mLayouts = new NotificationContentView[] {mPrivateLayout, mPublicLayout};
1282eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos
1283eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
1284eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setExpandClickListener(mExpandClickListener);
1285eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setContainingNotification(this);
1286eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
1287ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub = (ViewStub) findViewById(R.id.notification_guts_stub);
1288ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub.setOnInflateListener(new ViewStub.OnInflateListener() {
1289b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            @Override
1290b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            public void onInflate(ViewStub stub, View inflated) {
1291b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts = (NotificationGuts) inflated;
1292b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setClipTopAmount(getClipTopAmount());
1293b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setActualHeight(getActualHeight());
1294ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek                mGutsStub = null;
1295b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            }
1296b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        });
1297b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub = (ViewStub) findViewById(R.id.child_container_stub);
1298b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub.setOnInflateListener(new ViewStub.OnInflateListener() {
1299b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1300b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            @Override
1301b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            public void onInflate(ViewStub stub, View inflated) {
1302b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                mChildrenContainer = (NotificationChildrenContainer) inflated;
13036743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek                mChildrenContainer.setIsLowPriority(mIsLowPriority);
1304414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
1305c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                mChildrenContainer.onNotificationUpdated();
13067acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
13077acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                if (mShouldTranslateContents) {
13087acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                    mTranslateableViews.add(mChildrenContainer);
13097acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                }
1310b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            }
1311b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        });
13124b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
13137acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        if (mShouldTranslateContents) {
13147acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            // Add the views that we translate to reveal the menu
13157acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            mTranslateableViews = new ArrayList<>();
13167acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            for (int i = 0; i < getChildCount(); i++) {
13177acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                mTranslateableViews.add(getChildAt(i));
13187acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            }
13197acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            // Remove views that don't translate
13207acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            mTranslateableViews.remove(mChildrenContainerStub);
13217acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            mTranslateableViews.remove(mGutsStub);
13224b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
13234b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
13244b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
13254b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public void resetTranslation() {
132632c638a597dccbe4be600fd483060ee1466fdb04Mady Mellor        if (mTranslateAnim != null) {
132732c638a597dccbe4be600fd483060ee1466fdb04Mady Mellor            mTranslateAnim.cancel();
132832c638a597dccbe4be600fd483060ee1466fdb04Mady Mellor        }
13297acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
13307acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        if (!mShouldTranslateContents) {
13317acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            setTranslationX(0);
13327acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        } else if (mTranslateableViews != null) {
13334b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            for (int i = 0; i < mTranslateableViews.size(); i++) {
13344b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mTranslateableViews.get(i).setTranslationX(0);
13354b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
13367acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            invalidateOutline();
13374b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
13387acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
133995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        mMenuRow.resetMenu();
13404b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
13414b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
13424b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public void animateTranslateNotification(final float leftTarget) {
13434b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mTranslateAnim != null) {
13444b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mTranslateAnim.cancel();
13454b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
1346b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        mTranslateAnim = getTranslateViewAnimator(leftTarget, null /* updateListener */);
134734958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (mTranslateAnim != null) {
134834958fa272c9216db4002546c3efad692b3d7775Mady Mellor            mTranslateAnim.start();
134934958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
135034958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
135134958fa272c9216db4002546c3efad692b3d7775Mady Mellor
135234958fa272c9216db4002546c3efad692b3d7775Mady Mellor    @Override
135334958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public void setTranslation(float translationX) {
135434958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (areGutsExposed()) {
135534958fa272c9216db4002546c3efad692b3d7775Mady Mellor            // Don't translate if guts are showing.
135634958fa272c9216db4002546c3efad692b3d7775Mady Mellor            return;
135734958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
13587acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        if (!mShouldTranslateContents) {
13597acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            setTranslationX(translationX);
13607acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        } else if (mTranslateableViews != null) {
13617acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            // Translate the group of views
13627acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            for (int i = 0; i < mTranslateableViews.size(); i++) {
13637acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                if (mTranslateableViews.get(i) != null) {
13647acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                    mTranslateableViews.get(i).setTranslationX(translationX);
13657acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                }
136634958fa272c9216db4002546c3efad692b3d7775Mady Mellor            }
13677acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            invalidateOutline();
136834958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
136995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow.getMenuView() != null) {
137095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            mMenuRow.onTranslationUpdate(translationX);
137134958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
137234958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
137334958fa272c9216db4002546c3efad692b3d7775Mady Mellor
137434958fa272c9216db4002546c3efad692b3d7775Mady Mellor    @Override
137534958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public float getTranslation() {
1376e04afcb935356320c4397985724b9f9573b57f25Anthony Chen        if (!mShouldTranslateContents) {
13777acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            return getTranslationX();
13787acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        }
13797acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
138034958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (mTranslateableViews != null && mTranslateableViews.size() > 0) {
138134958fa272c9216db4002546c3efad692b3d7775Mady Mellor            // All of the views in the list should have same translation, just use first one.
138234958fa272c9216db4002546c3efad692b3d7775Mady Mellor            return mTranslateableViews.get(0).getTranslationX();
138334958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
13847acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
138534958fa272c9216db4002546c3efad692b3d7775Mady Mellor        return 0;
138634958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
138734958fa272c9216db4002546c3efad692b3d7775Mady Mellor
138834958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public Animator getTranslateViewAnimator(final float leftTarget,
138934958fa272c9216db4002546c3efad692b3d7775Mady Mellor            AnimatorUpdateListener listener) {
1390723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor        if (mTranslateAnim != null) {
1391723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor            mTranslateAnim.cancel();
1392723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor        }
139334958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (areGutsExposed()) {
139434958fa272c9216db4002546c3efad692b3d7775Mady Mellor            // No translation if guts are exposed.
139534958fa272c9216db4002546c3efad692b3d7775Mady Mellor            return null;
139634958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
1397b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        final ObjectAnimator translateAnim = ObjectAnimator.ofFloat(this, TRANSLATE_CONTENT,
1398b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                leftTarget);
1399b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (listener != null) {
1400b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            translateAnim.addUpdateListener(listener);
1401b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
1402b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        translateAnim.addListener(new AnimatorListenerAdapter() {
1403b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            boolean cancelled = false;
1404723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor
1405b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            @Override
1406b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            public void onAnimationCancel(Animator anim) {
1407b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                cancelled = true;
1408b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            }
1409723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor
1410b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            @Override
1411b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            public void onAnimationEnd(Animator anim) {
141295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor                if (!cancelled && leftTarget == 0) {
141395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor                    mMenuRow.resetMenu();
1414b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                    mTranslateAnim = null;
1415723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                }
14164b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
1417b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        });
1418b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        mTranslateAnim = translateAnim;
1419b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        return translateAnim;
14204b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
14214b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
1422ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public void inflateGuts() {
1423ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        if (mGuts == null) {
1424ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek            mGutsStub.inflate();
1425ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        }
1426ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
1427ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
1428da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private void updateChildrenVisibility() {
1429d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        mPrivateLayout.setVisibility(!mShowingPublic && !mIsSummaryWithChildren ? VISIBLE
1430d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                : INVISIBLE);
1431ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek        if (mChildrenContainer != null) {
1432ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek            mChildrenContainer.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
1433ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek                    : INVISIBLE);
1434b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1435da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        // The limits might have changed if the view suddenly became a group or vice versa
1436da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateLimits();
1437b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1438b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1439fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    @Override
1440a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
1441a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        if (super.onRequestSendAccessibilityEventInternal(child, event)) {
1442fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // Add a record for the entire layout since its content is somehow small.
1443fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // The event comes from a leaf view that is interacted with.
1444fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            AccessibilityEvent record = AccessibilityEvent.obtain();
1445fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            onInitializeAccessibilityEvent(record);
1446fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            dispatchPopulateAccessibilityEvent(record);
1447fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            event.appendRecord(record);
1448fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            return true;
1449fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        }
1450fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        return false;
1451c5dc0d0cce373fbf292e13633c114a431d747167Jorim Jaggi    }
145251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1453e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    @Override
14544e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    public void setDark(boolean dark, boolean fade, long delay) {
14554e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        super.setDark(dark, fade, delay);
145628f90c78b213fb436b243126e8bc10c4f554bd1cAdrian Roos        if (!mIsHeadsUp) {
145728f90c78b213fb436b243126e8bc10c4f554bd1cAdrian Roos            // Only fade the showing view of the pulsing notification.
145828f90c78b213fb436b243126e8bc10c4f554bd1cAdrian Roos            fade = false;
145928f90c78b213fb436b243126e8bc10c4f554bd1cAdrian Roos        }
1460e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        final NotificationContentView showing = getShowingLayout();
1461e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        if (showing != null) {
14624e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            showing.setDark(dark, fade, delay);
1463e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        }
14649c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek        if (mIsSummaryWithChildren) {
1465c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            mChildrenContainer.setDark(dark, fade, delay);
14669c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek        }
1467a7c69637f8fa7cc8c0e7ac7c4d73659730315841Selim Cinek        updateShelfIconColor();
1468e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    }
1469e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock
147051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isExpandable() {
1471388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1472388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return !mChildrenExpanded;
1473388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
14746bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen        return mEnableNonGroupedNotificationExpand && mExpandable;
147551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
147651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
147751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setExpandable(boolean expandable) {
147851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mExpandable = expandable;
1479eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
148051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
148151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
14824ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    @Override
14834ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    public void setClipToActualHeight(boolean clipToActualHeight) {
1484084c16b8b380e7ff0d38d9e2846db321f0214931Selim Cinek        super.setClipToActualHeight(clipToActualHeight || isUserLocked());
1485084c16b8b380e7ff0d38d9e2846db321f0214931Selim Cinek        getShowingLayout().setClipToActualHeight(clipToActualHeight || isUserLocked());
14864ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    }
14874ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek
14881685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
14891685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the user has changed the expansion state
14901685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
14911685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean hasUserChangedExpansion() {
14921685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mHasUserChangedExpansion;
14931685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
14941685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
149551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserExpanded() {
149651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserExpanded;
149751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
149851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
14991685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
15001685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the user
15011685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
15021685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param userExpanded whether the user wants this notification to be expanded
15031685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
150451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserExpanded(boolean userExpanded) {
1505388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        setUserExpanded(userExpanded, false /* allowChildExpansion */);
1506388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
1507388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
1508388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    /**
1509388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * Set this notification to be expanded by the user
1510388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     *
1511388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param userExpanded whether the user wants this notification to be expanded
1512388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param allowChildExpansion whether a call to this method allows expanding children
1513388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     */
1514388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) {
15150e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager.setNotificationExpanded();
1516414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic && allowChildExpansion
1517414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                && !mChildrenContainer.showingAsLowPriority()) {
1518698b1706be196de41fc6bf03cf15971c82a11949Chris Wren            final boolean wasExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
1519388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            mGroupManager.setGroupExpanded(mStatusBarNotification, userExpanded);
1520414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            onExpansionChanged(true /* userAction */, wasExpanded);
1521388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return;
1522388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
1523a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        if (userExpanded && !mExpandable) return;
152478403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
15251685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mHasUserChangedExpansion = true;
152651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserExpanded = userExpanded;
1527414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        onExpansionChanged(true /* userAction */, wasExpanded);
15285d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        if (!wasExpanded && isExpanded()
15295d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek                && getActualHeight() != getIntrinsicHeight()) {
15305d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek            notifyHeightChanged(true /* needsAnimation */);
15315d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        }
153251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
153351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1534ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    public void resetUserExpansion() {
1535414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        boolean changed = mUserExpanded;
1536ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mHasUserChangedExpansion = false;
1537ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mUserExpanded = false;
1538414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        if (changed && mIsSummaryWithChildren) {
1539414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            mChildrenContainer.onExpansionChanged();
1540414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        }
1541414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        updateShelfIconColor();
1542ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    }
1543ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek
154451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserLocked() {
15451b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek        return mUserLocked && !mForceUnlocked;
154651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
154751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
154851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserLocked(boolean userLocked) {
154951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserLocked = userLocked;
15508f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek        mPrivateLayout.setUserExpanding(userLocked);
1551817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        // This is intentionally not guarded with mIsSummaryWithChildren since we might have had
1552817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        // children but not anymore.
1553817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        if (mChildrenContainer != null) {
155442357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            mChildrenContainer.setUserLocked(userLocked);
1555817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek            if (mIsSummaryWithChildren && (userLocked || !isGroupExpanded())) {
1556b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                updateBackgroundForGroupState();
1557b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            }
155842357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        }
155951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
156051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
15611685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
15621685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return has the system set this notification to be expanded
15631685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
15641685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean isSystemExpanded() {
15651685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mIsSystemExpanded;
15661685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
15671685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
15681685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
15691685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the system.
15701685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
15711685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param expand whether the system wants this notification to be expanded.
15721685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
15731685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setSystemExpanded(boolean expand) {
157431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        if (expand != mIsSystemExpanded) {
157531094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
157631094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            mIsSystemExpanded = expand;
1577b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            notifyHeightChanged(false /* needsAnimation */);
1578414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            onExpansionChanged(false /* userAction */, wasExpanded);
1579ed6913b0ce99784188713975218dcff113a3d4a7Selim Cinek            if (mIsSummaryWithChildren) {
1580c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                mChildrenContainer.updateGroupOverflow();
1581c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            }
158231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
1583dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    }
1584dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
1585dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
158683bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * @param onKeyguard whether to prevent notification expansion
1587dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
158883bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public void setOnKeyguard(boolean onKeyguard) {
158983bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (onKeyguard != mOnKeyguard) {
15905cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            boolean wasAboveShelf = isAboveShelf();
159131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
159283bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mOnKeyguard = onKeyguard;
1593414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            onExpansionChanged(false /* userAction */, wasExpanded);
159431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            if (wasExpanded != isExpanded()) {
1595c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                if (mIsSummaryWithChildren) {
1596c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                    mChildrenContainer.updateGroupOverflow();
1597c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                }
15984b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                notifyHeightChanged(false /* needsAnimation */);
159931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            }
16005cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            if (isAboveShelf() != wasAboveShelf) {
16015cf1d0589a0045ee5f01802975f394847e891215Selim Cinek                mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
16025cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            }
160331094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
16041685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
16051685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
16061685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
16079e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     * @return Can the underlying notification be cleared? This can be different from whether the
16089e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     *         notification can be dismissed in case notifications are sensitive on the lockscreen.
16099e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     * @see #canViewBeDismissed()
16100d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     */
16110d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    public boolean isClearable() {
1612506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        if (mStatusBarNotification == null || !mStatusBarNotification.isClearable()) {
1613506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek            return false;
1614506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        }
1615506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        if (mIsSummaryWithChildren) {
1616506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek            List<ExpandableNotificationRow> notificationChildren =
1617506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                    mChildrenContainer.getNotificationChildren();
1618506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
1619506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
1620506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                if (!child.isClearable()) {
1621506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                    return false;
1622506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                }
1623506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek            }
1624506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        }
1625506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        return true;
16260d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
16270d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
16289cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    @Override
16299cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    public int getIntrinsicHeight() {
1630be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (isUserLocked()) {
1631be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            return getActualHeight();
1632be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
16334dd5006ff58c3b1ee5a2e0db343170e7cbd1b585Geoffrey Pitsch        if (mGuts != null && mGuts.isExposed()) {
1634e09fb7029ac29f337b8d3b9e564e5b994a9ed927Mady Mellor            return mGuts.getIntrinsicHeight();
1635d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else if ((isChildInGroup() && !isGroupExpanded())) {
1636d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return mPrivateLayout.getMinHeight();
1637d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else if (mSensitive && mHideSensitiveForIntrinsicHeight) {
1638d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return getMinHeight();
16396f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        } else if (mIsSummaryWithChildren && (!mOnKeyguard || mShowAmbient)) {
1640eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getIntrinsicHeight();
16416f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        } else if (isHeadsUpAllowed() && (mIsHeadsUp || mHeadsupDisappearRunning)) {
164273cf02a0783e3857cae21fece9c292abcc9e1409Selim Cinek            if (isPinned() || mHeadsupDisappearRunning) {
164331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                return getPinnedHeadsUpHeight(true /* atLeastMinHeight */);
164431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            } else if (isExpanded()) {
1645d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                return Math.max(getMaxExpandHeight(), mHeadsUpHeight);
16468d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            } else {
1647567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek                return Math.max(getCollapsedHeight(), mHeadsUpHeight);
16488d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            }
164931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (isExpanded()) {
165083bc78338437a460076a4b5778ded38440ac3501Selim Cinek            return getMaxExpandHeight();
1651d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else {
1652567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek            return getCollapsedHeight();
16531685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        }
1654b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
16551685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
16566f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    private boolean isHeadsUpAllowed() {
16576f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        return !mOnKeyguard && !mShowAmbient;
16586f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    }
16596f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos
166043c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
1661b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public boolean isGroupExpanded() {
1662eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mGroupManager.isGroupExpanded(mStatusBarNotification);
1663b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1664b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1665263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private void onChildrenCountChanged() {
16662a6ea9c2a1b52b0386270ec73e1e6d6a9b614a34Jason Monk        mIsSummaryWithChildren = StatusBar.ENABLE_CHILD_NOTIFICATIONS
1667b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                && mChildrenContainer != null && mChildrenContainer.getNotificationChildCount() > 0;
1668b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() == null) {
1669414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            mChildrenContainer.recreateNotificationHeader(mExpandClickListener
1670414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            );
1671263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        }
16726baed9e3a272b09e87f15801a389d7714d0b051fMady Mellor        getShowingLayout().updateBackgroundColor(false /* animate */);
1673eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
1674ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        updateChildrenHeaderAppearance();
1675da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateChildrenVisibility();
1676263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
1677263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
1678b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public void updateChildrenHeaderAppearance() {
1679ed6913b0ce99784188713975218dcff113a3d4a7Selim Cinek        if (mIsSummaryWithChildren) {
1680b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mChildrenContainer.updateChildrenHeaderAppearance();
1681b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
1682b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
1683b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
16841685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
16851685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Check whether the view state is currently expanded. This is given by the system in {@link
16861685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * #setSystemExpanded(boolean)} and can be overridden by user expansion or
16871685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
16881685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * view can differ from this state, if layout params are modified from outside.
16891685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
16901685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the view state is currently expanded.
16911685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
169283bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public boolean isExpanded() {
1693e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek        return isExpanded(false /* allowOnKeyguard */);
1694e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek    }
1695e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek
1696e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek    public boolean isExpanded(boolean allowOnKeyguard) {
1697e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek        return (!mOnKeyguard || allowOnKeyguard)
1698b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                && (!hasUserChangedExpansion() && (isSystemExpanded() || isSystemChildExpanded())
1699b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                || isUserExpanded());
1700b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1701b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1702b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean isSystemChildExpanded() {
1703b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mIsSystemChildExpanded;
1704b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1705b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1706b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setSystemChildExpanded(boolean expanded) {
1707b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mIsSystemChildExpanded = expanded;
17081685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
17091685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
1710035badd314a2130f47745c081e38f82c645f28afMady Mellor    public void setLayoutListener(LayoutListener listener) {
1711035badd314a2130f47745c081e38f82c645f28afMady Mellor        mLayoutListener = listener;
1712035badd314a2130f47745c081e38f82c645f28afMady Mellor    }
1713035badd314a2130f47745c081e38f82c645f28afMady Mellor
1714035badd314a2130f47745c081e38f82c645f28afMady Mellor    public void removeListener() {
1715035badd314a2130f47745c081e38f82c645f28afMady Mellor        mLayoutListener = null;
1716035badd314a2130f47745c081e38f82c645f28afMady Mellor    }
1717035badd314a2130f47745c081e38f82c645f28afMady Mellor
17181685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    @Override
17191685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
17201685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        super.onLayout(changed, left, top, right, bottom);
17218d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        updateMaxHeights();
172295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow.getMenuView() != null) {
172395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            mMenuRow.onHeightUpdate();
1724a6edc878293e49594a6aac7a0d0e41c7980ece07Mady Mellor        }
1725875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        updateContentShiftHeight();
1726035badd314a2130f47745c081e38f82c645f28afMady Mellor        if (mLayoutListener != null) {
1727035badd314a2130f47745c081e38f82c645f28afMady Mellor            mLayoutListener.onLayout();
1728035badd314a2130f47745c081e38f82c645f28afMady Mellor        }
1729875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    }
1730875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek
1731875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    /**
1732875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * Updates the content shift height such that the header is completely hidden when coming from
1733875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * the top.
1734875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     */
1735875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    private void updateContentShiftHeight() {
1736414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        NotificationHeaderView notificationHeader = getVisibleNotificationHeader();
1737875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        if (notificationHeader != null) {
1738875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            CachingIconView icon = notificationHeader.getIcon();
1739875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            mIconTransformContentShift = getRelativeTopPadding(icon) + icon.getHeight();
1740875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        } else {
1741875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            mIconTransformContentShift = mIconTransformContentShiftNoIcon;
1742875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        }
17431685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
17441685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
17458d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private void updateMaxHeights() {
1746d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        int intrinsicBefore = getIntrinsicHeight();
17478d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View expandedChild = mPrivateLayout.getExpandedChild();
17488d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        if (expandedChild == null) {
17498d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            expandedChild = mPrivateLayout.getContractedChild();
17508d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
17518d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mMaxExpandHeight = expandedChild.getHeight();
17528d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View headsUpChild = mPrivateLayout.getHeadsUpChild();
17531f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        if (headsUpChild == null) {
17541f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek            headsUpChild = mPrivateLayout.getContractedChild();
17558d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
17561f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        mHeadsUpHeight = headsUpChild.getHeight();
1757d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
1758bb42b7dd4892a8ab99f2f702cad931235d1d463eSelim Cinek            notifyHeightChanged(true  /* needsAnimation */);
1759d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        }
1760d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek    }
1761d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek
1762fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    @Override
1763fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    public void notifyHeightChanged(boolean needsAnimation) {
1764fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        super.notifyHeightChanged(needsAnimation);
1765fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        getShowingLayout().requestSelectLayout(needsAnimation || isUserLocked());
1766fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    }
1767fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek
17683c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek    public void setSensitive(boolean sensitive, boolean hideSensitive) {
1769ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = sensitive;
17703c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek        mSensitiveHiddenInGeneral = hideSensitive;
1771ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1772ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
177343c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
1774ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
177560122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek        mHideSensitiveForIntrinsicHeight = hideSensitive;
1776a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek        if (mIsSummaryWithChildren) {
1777a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
1778a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek                    mChildrenContainer.getNotificationChildren();
1779a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
1780a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
1781a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek                child.setHideSensitiveForIntrinsicHeight(hideSensitive);
1782a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek            }
1783a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek        }
1784ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1785ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
178643c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
1787ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
1788ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            long duration) {
1789ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        boolean oldShowingPublic = mShowingPublic;
1790ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublic = mSensitive && hideSensitive;
1791ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
1792ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            return;
1793ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
1794a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
1795a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler        // bail out if no public version
17961685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        if (mPublicLayout.getChildCount() == 0) return;
1797a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
1798ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (!animated) {
1799ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.animate().cancel();
1800ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.animate().cancel();
1801a554c707386eb8a6c6fb3a2399f23b79a1c17f74Selim Cinek            if (mChildrenContainer != null) {
1802a554c707386eb8a6c6fb3a2399f23b79a1c17f74Selim Cinek                mChildrenContainer.animate().cancel();
1803a554c707386eb8a6c6fb3a2399f23b79a1c17f74Selim Cinek                mChildrenContainer.setAlpha(1f);
1804a554c707386eb8a6c6fb3a2399f23b79a1c17f74Selim Cinek            }
1805ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setAlpha(1f);
1806ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.setAlpha(1f);
1807ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
1808d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            updateChildrenVisibility();
1809ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        } else {
1810ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            animateShowingPublic(delay, duration);
1811ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
1812c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        NotificationContentView showingLayout = getShowingLayout();
1813c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        showingLayout.updateBackgroundColor(animated);
1814eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
1815b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin        updateShelfIconColor();
1816e5726a20824c3cb2ff369207c8d75bfcdb814f69Adrian Roos        showingLayout.setDark(isDark(), false /* animate */, 0 /* delay */);
1817ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = true;
1818ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1819ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
1820ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private void animateShowingPublic(long delay, long duration) {
1821b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        View[] privateViews = mIsSummaryWithChildren
1822b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                ? new View[] {mChildrenContainer}
1823d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                : new View[] {mPrivateLayout};
1824d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] publicViews = new View[] {mPublicLayout};
1825d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] hiddenChildren = mShowingPublic ? privateViews : publicViews;
1826d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] shownChildren = mShowingPublic ? publicViews : privateViews;
1827d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        for (final View hiddenView : hiddenChildren) {
1828d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.setVisibility(View.VISIBLE);
1829d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.animate().cancel();
1830d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.animate()
1831d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .alpha(0f)
1832d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setStartDelay(delay)
1833d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setDuration(duration)
1834d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .withEndAction(new Runnable() {
1835d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        @Override
1836d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        public void run() {
1837d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                            hiddenView.setVisibility(View.INVISIBLE);
1838d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        }
1839d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    });
1840d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        }
1841d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        for (View showView : shownChildren) {
1842d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.setVisibility(View.VISIBLE);
1843d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.setAlpha(0f);
1844d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.animate().cancel();
1845d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.animate()
1846d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .alpha(1f)
1847d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setStartDelay(delay)
1848d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setDuration(duration);
1849d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        }
18500d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
18510d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
185243c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
18533776fe007550451bb237c705d333247eab2a291cSelim Cinek    public boolean mustStayOnScreen() {
18543776fe007550451bb237c705d333247eab2a291cSelim Cinek        return mIsHeadsUp;
18553776fe007550451bb237c705d333247eab2a291cSelim Cinek    }
18563776fe007550451bb237c705d333247eab2a291cSelim Cinek
18579e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    /**
18589e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     * @return Whether this view is allowed to be dismissed. Only valid for visible notifications as
18599e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     *         otherwise some state might not be updated. To request about the general clearability
18609e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     *         see {@link #isClearable()}.
18619e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     */
18629e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    public boolean canViewBeDismissed() {
1863e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return isClearable() && (!mShowingPublic || !mSensitiveHiddenInGeneral);
1864a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
1865251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi
1866cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai    public void makeActionsVisibile() {
1867cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai        setUserExpanded(true, true);
1868cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai        if (isChildInGroup()) {
1869cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai            mGroupManager.setGroupExpanded(mStatusBarNotification, true);
1870cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai        }
1871bb42b7dd4892a8ab99f2f702cad931235d1d463eSelim Cinek        notifyHeightChanged(false /* needsAnimation */);
1872cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai    }
1873cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai
1874b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setChildrenExpanded(boolean expanded, boolean animate) {
1875b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenExpanded = expanded;
187683bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mChildrenContainer != null) {
187783bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mChildrenContainer.setChildrenExpanded(expanded);
187883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
18791a5d8eadd56b435843dfbc1adf3779aa7286081bMady Mellor        updateBackgroundForGroupState();
1880ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        updateClickAndFocus();
1881b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1882b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1883b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public static void applyTint(View v, int color) {
1884b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        int alpha;
1885b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (color != 0) {
1886b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = COLORED_DIVIDER_ALPHA;
1887b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
1888b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            color = 0xff000000;
1889b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = DEFAULT_DIVIDER_ALPHA;
1890b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1891b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (v.getBackground() instanceof ColorDrawable) {
1892b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ColorDrawable background = (ColorDrawable) v.getBackground();
1893b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.mutate();
1894b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setColor(color);
1895b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setAlpha(alpha);
1896b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1897b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1898b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
18991685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public int getMaxExpandHeight() {
1900b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mMaxExpandHeight;
1901a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
1902584a7aa62c54bcbd654a6696d4fbb56e124874e7Jorim Jaggi
190334958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public boolean areGutsExposed() {
19044dd5006ff58c3b1ee5a2e0db343170e7cbd1b585Geoffrey Pitsch        return (mGuts != null && mGuts.isExposed());
190534958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
190634958fa272c9216db4002546c3efad692b3d7775Mady Mellor
1907be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
19084222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public boolean isContentExpandable() {
1909c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1910c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            return true;
1911c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        }
19122f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
19132f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.isContentExpandable();
19144222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
19154222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
19164222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
1917560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    protected View getContentView() {
1918aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1919a5703187a9dba418f742fab0874a8f683b0bbb0eSelim Cinek            return mChildrenContainer;
1920a5703187a9dba418f742fab0874a8f683b0bbb0eSelim Cinek        }
1921560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek        return getShowingLayout();
1922560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    }
1923560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek
1924560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    @Override
1925aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek    protected void onAppearAnimationFinished(boolean wasAppearing) {
1926aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        super.onAppearAnimationFinished(wasAppearing);
1927aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        if (wasAppearing) {
1928aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek            // During the animation the visible view might have changed, so let's make sure all
1929aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek            // alphas are reset
1930aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek            if (mChildrenContainer != null) {
1931aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek                mChildrenContainer.setAlpha(1.0f);
1932aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek                mChildrenContainer.setLayerType(LAYER_TYPE_NONE, null);
1933aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek            }
1934eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            for (NotificationContentView l : mLayouts) {
1935eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos                l.setAlpha(1.0f);
1936eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos                l.setLayerType(LAYER_TYPE_NONE, null);
1937eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            }
1938aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        }
1939aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek    }
1940aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek
1941aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek    @Override
1942b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public int getExtraBottomPadding() {
1943b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mIsSummaryWithChildren && isGroupExpanded()) {
1944b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            return mIncreasedPaddingBetweenElements;
1945b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
1946b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        return 0;
1947b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
1948b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
1949b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    @Override
1950d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int height, boolean notifyListeners) {
19514ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek        boolean changed = height != getActualHeight();
1952b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        super.setActualHeight(height, notifyListeners);
19534ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek        if (changed && isRemoved()) {
19544ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            // TODO: remove this once we found the gfx bug for this.
19554ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            // This is a hack since a removed view sometimes would just stay blank. it occured
19564ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            // when sending yourself a message and then clicking on it.
19574ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            ViewGroup parent = (ViewGroup) getParent();
19584ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            if (parent != null) {
19594ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek                parent.invalidate();
19604ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            }
19614ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek        }
19624dd5006ff58c3b1ee5a2e0db343170e7cbd1b585Geoffrey Pitsch        if (mGuts != null && mGuts.isExposed()) {
1963b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor            mGuts.setActualHeight(height);
1964b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor            return;
1965b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor        }
1966eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        int contentHeight = Math.max(getMinHeight(), height);
1967eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
1968eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setContentHeight(contentHeight);
1969eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
197042357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        if (mIsSummaryWithChildren) {
197142357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            mChildrenContainer.setActualHeight(height);
197242357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        }
1973b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
1974b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setActualHeight(height);
1975b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
1976be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
1977be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
1978be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
1979b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public int getMaxContentHeight() {
198083bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1981eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getMaxContentHeight();
198283bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
19832f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
19842f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.getMaxHeight();
1985be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
1986be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
1987be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
19884222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public int getMinHeight() {
1989e09fb7029ac29f337b8d3b9e564e5b994a9ed927Mady Mellor        if (mGuts != null && mGuts.isExposed()) {
1990e09fb7029ac29f337b8d3b9e564e5b994a9ed927Mady Mellor            return mGuts.getIntrinsicHeight();
19916f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        } else if (isHeadsUpAllowed() && mIsHeadsUp && mHeadsUpManager.isTrackingHeadsUp()) {
199231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                return getPinnedHeadsUpHeight(false /* atLeastMinHeight */);
199331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mIsSummaryWithChildren && !isGroupExpanded() && !mShowingPublic) {
1994b55386d64aeb80f74ed21035d1e389d86be89db6Selim Cinek            return mChildrenContainer.getMinHeight();
19956f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        } else if (isHeadsUpAllowed() && mIsHeadsUp) {
199631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return mHeadsUpHeight;
1997b55386d64aeb80f74ed21035d1e389d86be89db6Selim Cinek        }
1998816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
1999816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return showingLayout.getMinHeight();
2000816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    }
2001816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek
2002816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    @Override
2003567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek    public int getCollapsedHeight() {
20042c58461daf909fae5a2605f0ba63da3f9c897731Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
2005567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek            return mChildrenContainer.getCollapsedHeight();
200683bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
2007816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return getMinHeight();
20084222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
20094222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
20104222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
2011be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
2012be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super.setClipTopAmount(clipTopAmount);
2013eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
2014eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setClipTopAmount(clipTopAmount);
2015eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
2016b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
2017b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setClipTopAmount(clipTopAmount);
2018b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
2019be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
2020be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
2021a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek    @Override
2022a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek    public void setClipBottomAmount(int clipBottomAmount) {
202365d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek        if (clipBottomAmount != mClipBottomAmount) {
202465d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            super.setClipBottomAmount(clipBottomAmount);
2025eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            for (NotificationContentView l : mLayouts) {
2026eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos                l.setClipBottomAmount(clipBottomAmount);
2027eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            }
202865d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            if (mGuts != null) {
202965d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek                mGuts.setClipBottomAmount(clipBottomAmount);
203065d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            }
2031a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek        }
2032b3dadccbc5c7040260a51a3e17efcb74aeec6a11Selim Cinek        if (mChildrenContainer != null) {
203365d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            // We have to update this even if it hasn't changed, since the children locations can
203465d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            // have changed
2035b3dadccbc5c7040260a51a3e17efcb74aeec6a11Selim Cinek            mChildrenContainer.setClipBottomAmount(clipBottomAmount);
2036b3dadccbc5c7040260a51a3e17efcb74aeec6a11Selim Cinek        }
2037a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek    }
2038a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek
203931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public boolean isMaxExpandHeightInitialized() {
204031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        return mMaxExpandHeight != 0;
20417d447726e2cb9fae80db417012039828daab8fe7Selim Cinek    }
20422f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek
204342357e030c095867b95e2e8a718649587c5ebf52Selim Cinek    public NotificationContentView getShowingLayout() {
20442f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return mShowingPublic ? mPublicLayout : mPrivateLayout;
20452f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    }
204678403d79739605511ea88b653564d81d7bf4bbbaChris Wren
20471a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setLegacy(boolean legacy) {
2048eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
20491a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            l.setLegacy(legacy);
2050eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
205159ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    }
205259ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi
2053a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    @Override
2054a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    protected void updateBackgroundTint() {
2055a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        super.updateBackgroundTint();
2056b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        updateBackgroundForGroupState();
2057a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        if (mIsSummaryWithChildren) {
2058a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
2059a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                    mChildrenContainer.getNotificationChildren();
2060a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
2061a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
2062b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                child.updateBackgroundForGroupState();
2063a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            }
2064a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        }
2065a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
2066a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
2067b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    /**
2068b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor     * Called when a group has finished animating from collapsed or expanded state.
2069b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor     */
2070b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public void onFinishedExpansionChange() {
2071b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        mGroupExpansionChanging = false;
2072b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        updateBackgroundForGroupState();
2073b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
2074b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
2075b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    /**
2076b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor     * Updates the parent and children backgrounds in a group based on the expansion state.
2077b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor     */
2078b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public void updateBackgroundForGroupState() {
2079b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mIsSummaryWithChildren) {
2080b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            // Only when the group has finished expanding do we hide its background.
20816bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen            mShowNoBackground = !mShowGroupBackgroundWhenExpanded && isGroupExpanded()
20826bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen                    && !isGroupExpansionChanging() && !isUserLocked();
2083b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mChildrenContainer.updateHeaderForExpansion(mShowNoBackground);
2084b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            List<ExpandableNotificationRow> children = mChildrenContainer.getNotificationChildren();
2085b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            for (int i = 0; i < children.size(); i++) {
2086b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                children.get(i).updateBackgroundForGroupState();
2087b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            }
2088b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        } else if (isChildInGroup()) {
2089b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            final int childColor = getShowingLayout().getBackgroundColorForExpansionState();
2090b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            // Only show a background if the group is expanded OR if it is expanding / collapsing
20916bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen            // and has a custom background color.
2092b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            final boolean showBackground = isGroupExpanded()
2093b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                    || ((mNotificationParent.isGroupExpansionChanging()
20946bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen                    || mNotificationParent.isUserLocked()) && childColor != 0);
2095b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mShowNoBackground = !showBackground;
2096b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        } else {
2097b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            // Only children or parents ever need no background.
2098b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mShowNoBackground = false;
2099b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
2100b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        updateOutline();
2101a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateBackground();
2102a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
2103a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
21044a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos    public int getPositionOfChild(ExpandableNotificationRow childRow) {
21054a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos        if (mIsSummaryWithChildren) {
21064a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos            return mChildrenContainer.getPositionInLinearLayout(childRow);
21074a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos        }
21084a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos        return 0;
21094a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos    }
21104a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos
211178403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public void setExpansionLogger(ExpansionLogger logger, String key) {
211278403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLogger = logger;
211378403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLoggingKey = key;
211478403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
211578403d79739605511ea88b653564d81d7bf4bbbaChris Wren
21166abeeb91194818e1d19f75336b03d1e305af0842Chris Wren    public void onExpandedByGesture(boolean userExpanded) {
21176abeeb91194818e1d19f75336b03d1e305af0842Chris Wren        int event = MetricsEvent.ACTION_NOTIFICATION_GESTURE_EXPANDER;
21186abeeb91194818e1d19f75336b03d1e305af0842Chris Wren        if (mGroupManager.isSummaryOfGroup(getStatusBarNotification())) {
21196abeeb91194818e1d19f75336b03d1e305af0842Chris Wren            event = MetricsEvent.ACTION_NOTIFICATION_GROUP_GESTURE_EXPANDER;
21206abeeb91194818e1d19f75336b03d1e305af0842Chris Wren        }
21216abeeb91194818e1d19f75336b03d1e305af0842Chris Wren        MetricsLogger.action(mContext, event, userExpanded);
21226abeeb91194818e1d19f75336b03d1e305af0842Chris Wren    }
21236abeeb91194818e1d19f75336b03d1e305af0842Chris Wren
21246183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    @Override
212542357e030c095867b95e2e8a718649587c5ebf52Selim Cinek    public float getIncreasedPaddingAmount() {
212642357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        if (mIsSummaryWithChildren) {
212742357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            if (isGroupExpanded()) {
212842357e030c095867b95e2e8a718649587c5ebf52Selim Cinek                return 1.0f;
212942357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            } else if (isUserLocked()) {
2130414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                return mChildrenContainer.getIncreasedPaddingAmount();
213142357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            }
213299104836083738f9e5e73ab4170879d91de6ba67Selim Cinek        } else if (isColorized() && (!mIsLowPriority || isExpanded())) {
2133a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek            return -1.0f;
213442357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        }
213542357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        return 0.0f;
213661633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek    }
213761633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek
2138a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek    private boolean isColorized() {
213999104836083738f9e5e73ab4170879d91de6ba67Selim Cinek        return mIsColorized && mBgTint != NO_COLOR;
2140a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek    }
2141a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek
214261633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek    @Override
21436183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    protected boolean disallowSingleClick(MotionEvent event) {
21446183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        float x = event.getX();
21456183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        float y = event.getY();
214634eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        NotificationHeaderView header = getVisibleNotificationHeader();
21475d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        if (header != null && header.isInTouchRect(x - getTranslation(), y)) {
21485d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek            return true;
21495d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        }
21505d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        if ((!mIsSummaryWithChildren || mShowingPublic)
21515d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek                && getShowingLayout().disallowSingleClick(x, y)) {
21525d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek            return true;
21536183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        }
21546183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        return super.disallowSingleClick(event);
21556183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    }
21566183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek
2157414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    private void onExpansionChanged(boolean userAction, boolean wasExpanded) {
2158698b1706be196de41fc6bf03cf15971c82a11949Chris Wren        boolean nowExpanded = isExpanded();
2159414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        if (mIsSummaryWithChildren && (!mIsLowPriority || wasExpanded)) {
2160698b1706be196de41fc6bf03cf15971c82a11949Chris Wren            nowExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
2161698b1706be196de41fc6bf03cf15971c82a11949Chris Wren        }
2162414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        if (nowExpanded != wasExpanded) {
2163414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            updateShelfIconColor();
2164414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            if (mLogger != null) {
2165414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded);
2166414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            }
2167414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            if (mIsSummaryWithChildren) {
2168414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                mChildrenContainer.onExpansionChanged();
2169414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            }
217078403d79739605511ea88b653564d81d7bf4bbbaChris Wren        }
217178403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
2172570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek
2173e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    @Override
2174e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
2175e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        super.onInitializeAccessibilityNodeInfoInternal(info);
2176e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        if (canViewBeDismissed()) {
2177e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
2178e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        }
2179c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        boolean expandable = mShowingPublic;
2180c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        boolean isExpanded = false;
2181c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        if (!expandable) {
2182c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            if (mIsSummaryWithChildren) {
2183c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                expandable = true;
2184c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                if (!mIsLowPriority || isExpanded()) {
2185c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                    isExpanded = isGroupExpanded();
2186c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                }
2187c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            } else {
2188c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                expandable = mPrivateLayout.isContentExpandable();
2189c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                isExpanded = isExpanded();
2190c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            }
2191c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        }
2192c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        if (expandable) {
2193c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            if (isExpanded) {
2194c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
2195c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            } else {
2196c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
2197c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            }
2198c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        }
2199e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
2200e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
2201e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    @Override
2202e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
2203e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        if (super.performAccessibilityActionInternal(action, arguments)) {
2204e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            return true;
2205e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        }
2206e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        switch (action) {
2207e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            case AccessibilityNodeInfo.ACTION_DISMISS:
2208e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                NotificationStackScrollLayout.performDismiss(this, mGroupManager,
2209e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                        true /* fromAccessibility */);
2210e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                return true;
2211c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            case AccessibilityNodeInfo.ACTION_COLLAPSE:
2212c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            case AccessibilityNodeInfo.ACTION_EXPAND:
2213c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                mExpandClickListener.onClick(this);
2214c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                return true;
2215e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        }
2216e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return false;
2217e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
2218e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
2219e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public boolean shouldRefocusOnDismiss() {
2220e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return mRefocusOnDismiss || isAccessibilityFocused();
2221e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
2222e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
2223570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    public interface OnExpandClickListener {
222431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        void onExpandClicked(NotificationData.Entry clickedEntry, boolean nowExpanded);
2225570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    }
2226bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2227bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek    @Override
2228bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
2229bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        return new NotificationViewState(stackScrollState);
2230bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek    }
2231bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2232d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    @Override
2233d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    public boolean isAboveShelf() {
2234c8007c59758b166f262f1e9d8ec19c36bf37b607Selim Cinek        return !isOnKeyguard()
2235c8007c59758b166f262f1e9d8ec19c36bf37b607Selim Cinek                && (mIsPinned || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf));
2236d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    }
2237d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek
22380aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos    public void setShowAmbient(boolean showAmbient) {
22390aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos        if (showAmbient != mShowAmbient) {
22400aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos            mShowAmbient = showAmbient;
22416f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos            if (mChildrenContainer != null) {
22426f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos                mChildrenContainer.notifyShowAmbientChanged();
22436f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos            }
22440aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos            notifyHeightChanged(false /* needsAnimation */);
22450aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos        }
22460aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos    }
22470aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos
22486f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    public boolean isShowingAmbient() {
22496f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        return mShowAmbient;
22506f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    }
22516f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos
2252d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    public void setAboveShelf(boolean aboveShelf) {
22535cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        boolean wasAboveShelf = isAboveShelf();
2254d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek        mAboveShelf = aboveShelf;
22555cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        if (isAboveShelf() != wasAboveShelf) {
22565cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
22575cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        }
2258d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    }
2259d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek
2260d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek    public static class NotificationViewState extends ExpandableViewState {
2261bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2262bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        private final StackScrollState mOverallState;
22630242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek
2264bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2265bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        private NotificationViewState(StackScrollState stackScrollState) {
2266bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            mOverallState = stackScrollState;
2267bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        }
2268bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2269bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        @Override
2270bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        public void applyToView(View view) {
2271bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            super.applyToView(view);
2272bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            if (view instanceof ExpandableNotificationRow) {
2273bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek                ExpandableNotificationRow row = (ExpandableNotificationRow) view;
2274bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek                row.applyChildrenState(mOverallState);
2275bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            }
2276bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        }
22770cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek
22780cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        @Override
22792b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        protected void onYTranslationAnimationFinished(View view) {
22802b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            super.onYTranslationAnimationFinished(view);
2281d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek            if (view instanceof ExpandableNotificationRow) {
2282d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek                ExpandableNotificationRow row = (ExpandableNotificationRow) view;
2283d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek                if (row.isHeadsUpAnimatingAway()) {
2284d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek                    row.setHeadsUpAnimatingAway(false);
2285d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek                }
22860cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            }
22870cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        }
22880cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek
22890cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        @Override
22900cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        public void animateTo(View child, AnimationProperties properties) {
22910cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            super.animateTo(child, properties);
22920cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            if (child instanceof ExpandableNotificationRow) {
22930cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
22940cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek                row.startChildAnimation(mOverallState, properties);
22950cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            }
22960cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        }
2297bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek    }
2298817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek
2299817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek    @VisibleForTesting
2300817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek    protected void setChildrenContainer(NotificationChildrenContainer childrenContainer) {
2301817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        mChildrenContainer = childrenContainer;
2302817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek    }
230351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren}
2304