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;
67a6ee4bd1bc9b892915cd94d4b0ea343ede5f7ebbSelim 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;
83cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupinimport java.util.function.BooleanSupplier;
84a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
8595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellorpublic class ExpandableNotificationRow extends ActivatableNotificationView
8695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        implements PluginListener<NotificationMenuRowPlugin> {
87b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
88b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
89b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private static final int COLORED_DIVIDER_ALPHA = 0x7B;
9095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    private static final int MENU_VIEW_INDEX = 0;
9195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
92035badd314a2130f47745c081e38f82c645f28afMady Mellor    public interface LayoutListener {
93035badd314a2130f47745c081e38f82c645f28afMady Mellor        public void onLayout();
94035badd314a2130f47745c081e38f82c645f28afMady Mellor    }
95035badd314a2130f47745c081e38f82c645f28afMady Mellor
96035badd314a2130f47745c081e38f82c645f28afMady Mellor    private LayoutListener mLayoutListener;
97cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    private boolean mDark;
9855a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    private boolean mLowPriorityStateUpdated;
991a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private final NotificationInflater mNotificationInflater;
1000242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    private int mIconTransformContentShift;
101875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    private int mIconTransformContentShiftNoIcon;
10201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMinHeightLegacy;
10301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mMaxHeadsUpHeightLegacy;
10401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mMaxHeadsUpHeight;
10587ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek    private int mMaxHeadsUpHeightIncreased;
10601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMinHeight;
1077d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek    private int mNotificationMinHeightLarge;
10801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private int mNotificationMaxHeight;
1090aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos    private int mNotificationAmbientHeight;
110b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    private int mIncreasedPaddingBetweenElements;
11151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1121685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Does this row contain layouts that can adapt to row expansion */
11351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mExpandable;
1141685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Has the user actively changed the expansion state of this row */
1151685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mHasUserChangedExpansion;
1161685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
11751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserExpanded;
11831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek
11931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    /**
12031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * Has this notification been expanded while it was pinned
12131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     */
12231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    private boolean mExpandedWhenPinned;
1231685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Is the user touching this row */
12451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    private boolean mUserLocked;
1251685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /** Are we showing the "public" version */
126a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    private boolean mShowingPublic;
127ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mSensitive;
1283c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek    private boolean mSensitiveHiddenInGeneral;
129ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private boolean mShowingPublicInitialized;
13060122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek    private boolean mHideSensitiveForIntrinsicHeight;
13151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1321685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
1331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Is this notification expanded by the system. The expansion state can be overridden by the
1341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * user expansion.
1351685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
1361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private boolean mIsSystemExpanded;
137dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
138dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
13983bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * Whether the notification is on the keyguard and the expansion is disabled.
140dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
14183bc78338437a460076a4b5778ded38440ac3501Selim Cinek    private boolean mOnKeyguard;
142dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
143b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    private Animator mTranslateAnim;
1444b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    private ArrayList<View> mTranslateableViews;
145be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPublicLayout;
146be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private NotificationContentView mPrivateLayout;
147eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos    private NotificationContentView[] mLayouts;
1481685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    private int mMaxExpandHeight;
1498d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private int mHeadsUpHeight;
1504bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek    private int mNotificationColor;
15178403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private ExpansionLogger mLogger;
15278403d79739605511ea88b653564d81d7bf4bbbaChris Wren    private String mLoggingKey;
1538d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private NotificationGuts mGuts;
154da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private NotificationData.Entry mEntry;
155b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    private StatusBarNotification mStatusBarNotification;
1563fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor    private String mAppName;
1571a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    private boolean mIsHeadsUp;
15898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private boolean mLastChronometerRunning = true;
159b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private ViewStub mChildrenContainerStub;
160b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationGroupManager mGroupManager;
161b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mChildrenExpanded;
162263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private boolean mIsSummaryWithChildren;
163b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private NotificationChildrenContainer mChildrenContainer;
16495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    private NotificationMenuRowPlugin mMenuRow;
165ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    private ViewStub mGutsStub;
166b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean mIsSystemChildExpanded;
167684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    private boolean mIsPinned;
1680e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski    private FalsingManager mFalsingManager;
1695cf1d0589a0045ee5f01802975f394847e891215Selim Cinek    private AboveShelfChangedListener mAboveShelfChangedListener;
17031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    private HeadsUpManager mHeadsUpManager;
171b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
1725eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    private boolean mJustClicked;
1735a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek    private boolean mIconAnimationRunning;
17434d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    private boolean mShowNoBackground;
175388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    private ExpandableNotificationRow mNotificationParent;
176570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    private OnExpandClickListener mOnExpandClickListener;
177b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    private boolean mGroupExpansionChanging;
178b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
1796bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen    /**
180cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin     * A supplier that returns true if keyguard is secure.
181cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin     */
182cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    private BooleanSupplier mSecureStateProvider;
183cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin
184cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    /**
1856bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     * Whether or not a notification that is not part of a group of notifications can be manually
1866bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     * expanded by the user.
1876bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     */
1886bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen    private boolean mEnableNonGroupedNotificationExpand;
1896bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen
1906bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen    /**
1916bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     * Whether or not to update the background of the header of the notification when its expanded.
1926bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     * If {@code true}, the header background will disappear when expanded.
1936bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen     */
1946bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen    private boolean mShowGroupBackgroundWhenExpanded;
1956bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen
196eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    private OnClickListener mExpandClickListener = new OnClickListener() {
197eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        @Override
198eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        public void onClick(View v) {
199414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            if (!mShowingPublic && (!mIsLowPriority || isExpanded())
200414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                    && mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
2011a5d8eadd56b435843dfbc1adf3779aa7286081bMady Mellor                mGroupExpansionChanging = true;
202698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                final boolean wasExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
203698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                boolean nowExpanded = mGroupManager.toggleGroupExpansion(mStatusBarNotification);
204698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                mOnExpandClickListener.onExpandClicked(mEntry, nowExpanded);
205698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER,
206698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                        nowExpanded);
207414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                onExpansionChanged(true /* userAction */, wasExpanded);
2086bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen            } else if (mEnableNonGroupedNotificationExpand) {
209e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                if (v.isAccessibilityFocused()) {
210e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                    mPrivateLayout.setFocusOnVisibilityChange();
211e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                }
21231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                boolean nowExpanded;
21331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                if (isPinned()) {
21431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    nowExpanded = !mExpandedWhenPinned;
21531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    mExpandedWhenPinned = nowExpanded;
21631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                } else {
21731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    nowExpanded = !isExpanded();
21831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                    setUserExpanded(nowExpanded);
21931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                }
220eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek                notifyHeightChanged(true);
22131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                mOnExpandClickListener.onExpandClicked(mEntry, nowExpanded);
222698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_EXPANDER,
223698b1706be196de41fc6bf03cf15971c82a11949Chris Wren                        nowExpanded);
224eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            }
225eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        }
226eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek    };
2271b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek    private boolean mForceUnlocked;
2283f19f60d654421eee5b35a92129081f08c977629Selim Cinek    private boolean mDismissed;
2293f19f60d654421eee5b35a92129081f08c977629Selim Cinek    private boolean mKeepInParent;
2303f19f60d654421eee5b35a92129081f08c977629Selim Cinek    private boolean mRemoved;
231b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    private static final Property<ExpandableNotificationRow, Float> TRANSLATE_CONTENT =
232b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            new FloatProperty<ExpandableNotificationRow>("translate") {
233b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                @Override
234b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                public void setValue(ExpandableNotificationRow object, float value) {
235b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                    object.setTranslation(value);
236b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                }
237b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
238b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                @Override
239b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                public Float get(ExpandableNotificationRow object) {
240b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                    return object.getTranslation();
241b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                }
242b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    };
243ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    private OnClickListener mOnClickListener;
24473cf02a0783e3857cae21fece9c292abcc9e1409Selim Cinek    private boolean mHeadsupDisappearRunning;
245e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    private View mChildAfterViewWhenDismissed;
246e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    private View mGroupParentWhenDismissed;
247e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    private boolean mRefocusOnDismiss;
2482b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    private float mContentTransformationAmount;
2490242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    private boolean mIconsVisible = true;
250d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    private boolean mAboveShelf;
2510aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos    private boolean mShowAmbient;
252875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    private boolean mIsLastChild;
253e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek    private Runnable mOnDismissRunnable;
2546743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek    private boolean mIsLowPriority;
255a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek    private boolean mIsColorized;
2567d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek    private boolean mUseIncreasedCollapsedHeight;
25787ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek    private boolean mUseIncreasedHeadsUpHeight;
258ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    private float mTranslationWhenRemoved;
259ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    private boolean mWasChildInGroupWhenRemoved;
2606f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    private int mNotificationColorAmbient;
261b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
26243c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
263b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public boolean isGroupExpansionChanging() {
264b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (isChildInGroup()) {
265b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            return mNotificationParent.isGroupExpansionChanging();
266b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
267b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        return mGroupExpansionChanging;
268b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
269b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
270b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public void setGroupExpansionChanging(boolean changing) {
271b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        mGroupExpansionChanging = changing;
272b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
2735eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
274599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos    @Override
275599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos    public void setActualHeightAnimating(boolean animating) {
276599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos        if (mPrivateLayout != null) {
277599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos            mPrivateLayout.setContentHeightAnimating(animating);
278599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos        }
279599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos    }
280599be34e6e3274e97512f3970a0d6edddedb8eb4Adrian Roos
2818d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPrivateLayout() {
2828d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPrivateLayout;
2838d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
2848d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
2858d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    public NotificationContentView getPublicLayout() {
2868d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        return mPublicLayout;
2878d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    }
2888d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek
289cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    public void setIconAnimationRunning(boolean running) {
290eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
291eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            setIconAnimationRunning(running, l);
292eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
2935a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        if (mIsSummaryWithChildren) {
294b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            setIconAnimationRunningForChild(running, mChildrenContainer.getHeaderView());
295414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            setIconAnimationRunningForChild(running, mChildrenContainer.getLowPriorityHeaderView());
2965a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            List<ExpandableNotificationRow> notificationChildren =
2975a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                    mChildrenContainer.getNotificationChildren();
2985a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
2995a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
3005a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek                child.setIconAnimationRunning(running);
3015a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            }
3025a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        }
3035a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        mIconAnimationRunning = running;
304cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
305cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
306cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunning(boolean running, NotificationContentView layout) {
307cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (layout != null) {
308cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View contractedChild = layout.getContractedChild();
309cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            View expandedChild = layout.getExpandedChild();
3108d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
311cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, contractedChild);
312cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconAnimationRunningForChild(running, expandedChild);
3138d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            setIconAnimationRunningForChild(running, headsUpChild);
314cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
315cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
316cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
317cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconAnimationRunningForChild(boolean running, View child) {
318cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (child != null) {
319cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView icon = (ImageView) child.findViewById(com.android.internal.R.id.icon);
320cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(icon, running);
321cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            ImageView rightIcon = (ImageView) child.findViewById(
322cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    com.android.internal.R.id.right_icon);
323cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            setIconRunning(rightIcon, running);
324cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
325cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
326cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
327cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    private void setIconRunning(ImageView imageView, boolean running) {
328cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        if (imageView != null) {
329cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            Drawable drawable = imageView.getDrawable();
330cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            if (drawable instanceof AnimationDrawable) {
331cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
332cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
333cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
334cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
335cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
336cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
337cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            } else if (drawable instanceof AnimatedVectorDrawable) {
338cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                AnimatedVectorDrawable animationDrawable = (AnimatedVectorDrawable) drawable;
339cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                if (running) {
340cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.start();
341cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                } else {
342cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                    animationDrawable.stop();
343cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek                }
344cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek            }
345cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek        }
346cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek    }
347cab4a60c485872848fc0fa3e65baaeb06d21a7d8Selim Cinek
3485ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    public void updateNotification(NotificationData.Entry entry) {
349da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        mEntry = entry;
350da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        mStatusBarNotification = entry.notification;
3511a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.inflateNotificationViews();
352c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
353c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
3545ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    public void onNotificationUpdated() {
355eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
356c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            l.onNotificationUpdated(mEntry);
357eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
358a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek        mIsColorized = mStatusBarNotification.getNotification().isColorized();
359757d879966fdbff1b67c9ec6fd4b6c75152b991aSelim Cinek        mShowingPublicInitialized = false;
3604bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek        updateNotificationColor();
3614c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor        if (mMenuRow != null) {
3624ab2820e6c668ae7c55b300f126bb9f70c202ba3Mady Mellor            mMenuRow.onNotificationUpdated(mStatusBarNotification);
3634c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor        }
3648fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        if (mIsSummaryWithChildren) {
365414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            mChildrenContainer.recreateNotificationHeader(mExpandClickListener);
366c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            mChildrenContainer.onNotificationUpdated();
3678fc93c90839e5d9dd52bca9dd97c198c0fe68af1Selim Cinek        }
3685a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        if (mIconAnimationRunning) {
3695a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek            setIconAnimationRunning(true);
3705a175d9d543c4438672990aa8a820bd1292bdd6aSelim Cinek        }
371ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        if (mNotificationParent != null) {
372ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek            mNotificationParent.updateChildrenHeaderAppearance();
373ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        }
374263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
375624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek        // The public layouts expand button is always visible
376624c02db7f1d24ec1e307530ff32d4fd5859feaeSelim Cinek        mPublicLayout.updateExpandButtons(true);
377da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateLimits();
3780242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek        updateIconVisibilities();
3796743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        updateShelfIconColor();
3806743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek    }
3816743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek
382b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin    @VisibleForTesting
383b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin    void updateShelfIconColor() {
3846743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        StatusBarIconView expandedIcon = mEntry.expandedIcon;
3856743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        boolean isPreL = Boolean.TRUE.equals(expandedIcon.getTag(R.id.icon_is_pre_L));
3866743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        boolean colorize = !isPreL || NotificationUtils.isGrayscale(expandedIcon,
3876743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek                NotificationColorUtil.getInstance(mContext));
388875ba9bd8ec0fa3d29fe27efcb3a20e53ce85f4fSelim Cinek        int color = StatusBarIconView.NO_COLOR;
3896743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        if (colorize) {
390b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin            NotificationHeaderView header = getVisibleNotificationHeader();
391b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin            if (header != null) {
392b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin                color = header.getOriginalIconColor();
393b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin            } else {
394b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin                color = mEntry.getContrastedColor(mContext, mIsLowPriority && !isExpanded(),
395b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin                        getBackgroundColorWithoutTint());
396b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin            }
3976743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        }
398875ba9bd8ec0fa3d29fe27efcb3a20e53ce85f4fSelim Cinek        expandedIcon.setStaticDrawableColor(color);
399da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    }
400da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek
4015cf1d0589a0045ee5f01802975f394847e891215Selim Cinek    public void setAboveShelfChangedListener(AboveShelfChangedListener aboveShelfChangedListener) {
4025cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        mAboveShelfChangedListener = aboveShelfChangedListener;
4035cf1d0589a0045ee5f01802975f394847e891215Selim Cinek    }
4045cf1d0589a0045ee5f01802975f394847e891215Selim Cinek
405cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    /**
406cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin     * Sets a supplier that can determine whether the keyguard is secure or not.
407cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin     * @param secureStateProvider A function that returns true if keyguard is secure.
408cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin     */
409cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    public void setSecureStateProvider(BooleanSupplier secureStateProvider) {
410cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin        mSecureStateProvider = secureStateProvider;
411cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    }
412cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin
4134705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek    @Override
4144705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek    public boolean isDimmable() {
4154705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek        if (!getShowingLayout().isDimmable()) {
4164705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek            return false;
4174705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek        }
4184705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek        return super.isDimmable();
4194705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek    }
4204705f29973a0640120e5803d14f5646c880d7cc5Selim Cinek
421da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private void updateLimits() {
422eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
423eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            updateLimitsForView(l);
424eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
425a1744872f4447dd370002a607c32776dffe519f5Selim Cinek    }
426a1744872f4447dd370002a607c32776dffe519f5Selim Cinek
427a1744872f4447dd370002a607c32776dffe519f5Selim Cinek    private void updateLimitsForView(NotificationContentView layout) {
428a1744872f4447dd370002a607c32776dffe519f5Selim Cinek        boolean customView = layout.getContractedChild().getId()
429da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek                != com.android.internal.R.id.status_bar_latest_event_content;
430da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
4317d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        int minHeight;
4327d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        if (customView && beforeN && !mIsSummaryWithChildren) {
4337d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek            minHeight = mNotificationMinHeightLegacy;
4347d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        } else if (mUseIncreasedCollapsedHeight && layout == mPrivateLayout) {
4357d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek            minHeight = mNotificationMinHeightLarge;
4367d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        } else {
4377d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek            minHeight = mNotificationMinHeight;
4387d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        }
439a1744872f4447dd370002a607c32776dffe519f5Selim Cinek        boolean headsUpCustom = layout.getHeadsUpChild() != null &&
440a1744872f4447dd370002a607c32776dffe519f5Selim Cinek                layout.getHeadsUpChild().getId()
441a1744872f4447dd370002a607c32776dffe519f5Selim Cinek                        != com.android.internal.R.id.status_bar_latest_event_content;
44287ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        int headsUpheight;
44387ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        if (headsUpCustom && beforeN) {
44487ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek            headsUpheight = mMaxHeadsUpHeightLegacy;
44587ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        } else if (mUseIncreasedHeadsUpHeight && layout == mPrivateLayout) {
44687ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek            headsUpheight = mMaxHeadsUpHeightIncreased;
44787ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        } else {
44887ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek            headsUpheight = mMaxHeadsUpHeight;
44987ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        }
4500aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos        layout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight,
4510aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos                mNotificationAmbientHeight);
452b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
453b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
454b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    public StatusBarNotification getStatusBarNotification() {
455b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        return mStatusBarNotification;
456b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi    }
457b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi
458281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    public NotificationData.Entry getEntry() {
459281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek        return mEntry;
460281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    }
461281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek
462b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    public boolean isHeadsUp() {
463b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek        return mIsHeadsUp;
464b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
465b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
4661a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    public void setHeadsUp(boolean isHeadsUp) {
4675cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        boolean wasAboveShelf = isAboveShelf();
468c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        int intrinsicBefore = getIntrinsicHeight();
4691a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek        mIsHeadsUp = isHeadsUp;
4708d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mPrivateLayout.setHeadsUp(isHeadsUp);
471b41b2f6fc2bcce6da6d6ae855a2a36cfa6f7f99dSelim Cinek        if (mIsSummaryWithChildren) {
472b41b2f6fc2bcce6da6d6ae855a2a36cfa6f7f99dSelim Cinek            // The overflow might change since we allow more lines as HUN.
473b41b2f6fc2bcce6da6d6ae855a2a36cfa6f7f99dSelim Cinek            mChildrenContainer.updateGroupOverflow();
474b41b2f6fc2bcce6da6d6ae855a2a36cfa6f7f99dSelim Cinek        }
475c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
476c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek            notifyHeightChanged(false  /* needsAnimation */);
477c80fdb11f55f4c1f3ca9b5cdc7035afa2a0b9e91Selim Cinek        }
478d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek        if (isHeadsUp) {
479d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek            setAboveShelf(true);
4805cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        } else if (isAboveShelf() != wasAboveShelf) {
4815cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
482d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek        }
4831a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek    }
4841a521f3ea841f6db9686bbec7f950a3883d075aaSelim Cinek
485b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setGroupManager(NotificationGroupManager groupManager) {
486b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mGroupManager = groupManager;
48783bc78338437a460076a4b5778ded38440ac3501Selim Cinek        mPrivateLayout.setGroupManager(groupManager);
488b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
489b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
490b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos    public void setRemoteInputController(RemoteInputController r) {
491b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos        mPrivateLayout.setRemoteInputController(r);
492b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos    }
493b88b1a1dbde3364cd92d6a69a41ef2d4e2877294Adrian Roos
4943fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor    public void setAppName(String appName) {
4953fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor        mAppName = appName;
49695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow != null && mMenuRow.getMenuView() != null) {
497761cde1173cdfbc058034ffb10283e5507ed0ed4Mady Mellor            mMenuRow.setAppName(mAppName);
4983fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor        }
4993fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor    }
5003fd273e6113fb1b8986314a03ab6d7e90efd0beaMady Mellor
501b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row) {
502b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        addChildNotification(row, -1);
503b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
504b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
505b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
506b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Add a child notification to this view.
507b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
508b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param row the row to add
509b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childIndex the index to add it at, if -1 it will be added at the end
510b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
511b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void addChildNotification(ExpandableNotificationRow row, int childIndex) {
512b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer == null) {
513b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainerStub.inflate();
514b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
515b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainer.addNotification(row, childIndex);
516263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
517263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(true, this);
518b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
519b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
520b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void removeChildNotification(ExpandableNotificationRow row) {
521b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (mChildrenContainer != null) {
522b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.removeNotification(row);
523b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
524263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        onChildrenCountChanged();
525263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        row.setIsChildInGroup(false, null);
526263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
527263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
52843c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
529263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isChildInGroup() {
530a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        return mNotificationParent != null;
531263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
532263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
533388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public ExpandableNotificationRow getNotificationParent() {
534388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        return mNotificationParent;
535388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
536388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
537263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    /**
538263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param isChildInGroup Is this notification now in a group
539263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     * @param parent the new parent notification
540263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek     */
541a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {;
5422a6ea9c2a1b52b0386270ec73e1e6d6a9b614a34Jason Monk        boolean childInGroup = StatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
543a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mNotificationParent = childInGroup ? parent : null;
544a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        mPrivateLayout.setIsChildInGroup(childInGroup);
5455ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek        mNotificationInflater.setIsChildInGroup(childInGroup);
546c7d65b4e9c784a8235424c30620bacd54cc0892eMady Mellor        resetBackgroundAlpha();
547b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        updateBackgroundForGroupState();
548ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        updateClickAndFocus();
549b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mNotificationParent != null) {
5509ce3285dc3a5da05d21b0b1c4628ea3bf86f6644Selim Cinek            setOverrideTintColor(NO_COLOR, 0.0f);
551b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mNotificationParent.updateBackgroundForGroupState();
552b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
553db16737031091160a3a7d080ac44ce2836402d74Selim Cinek        updateIconVisibilities();
55434d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    }
55534d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek
55634d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    @Override
5577210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    public boolean onTouchEvent(MotionEvent event) {
5587210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        if (event.getActionMasked() != MotionEvent.ACTION_DOWN
5597210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek                || !isChildInGroup() || isGroupExpanded()) {
5607210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek            return super.onTouchEvent(event);
5617210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        } else {
5627210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek            return false;
5637210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek        }
5647210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    }
5657210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek
5667210947e0d0e384fc34d61160c99adc2f36734e0Selim Cinek    @Override
567f062580d395a8c99631c104d6aec250f961152ddMady Mellor    protected boolean handleSlideBack() {
56895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow != null && mMenuRow.isMenuVisible()) {
569f062580d395a8c99631c104d6aec250f961152ddMady Mellor            animateTranslateNotification(0 /* targetLeft */);
570f062580d395a8c99631c104d6aec250f961152ddMady Mellor            return true;
571f062580d395a8c99631c104d6aec250f961152ddMady Mellor        }
572f062580d395a8c99631c104d6aec250f961152ddMady Mellor        return false;
573f062580d395a8c99631c104d6aec250f961152ddMady Mellor    }
574f062580d395a8c99631c104d6aec250f961152ddMady Mellor
575f062580d395a8c99631c104d6aec250f961152ddMady Mellor    @Override
57634d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek    protected boolean shouldHideBackground() {
57734d93b0985063090a9bad88a1b80e1b99bae3332Selim Cinek        return super.shouldHideBackground() || mShowNoBackground;
578263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
579263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
580263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    @Override
581263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    public boolean isSummaryWithChildren() {
582263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        return mIsSummaryWithChildren;
583b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
584b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
585b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    @Override
586b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public boolean areChildrenExpanded() {
587b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenExpanded;
588b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
589b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
590b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public List<ExpandableNotificationRow> getNotificationChildren() {
591b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mChildrenContainer == null ? null : mChildrenContainer.getNotificationChildren();
592b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
593b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
594eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    public int getNumberOfNotificationChildren() {
595eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        if (mChildrenContainer == null) {
596eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek            return 0;
597eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        }
598eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mChildrenContainer.getNotificationChildren().size();
599eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek    }
600eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek
601b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    /**
602b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * Apply the order given in the list to the children.
603b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     *
604b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @param childOrder the new list order
605a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek     * @param visualStabilityManager
606a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek     * @param callback the callback to invoked in case it is not allowed
607b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     * @return whether the list order has changed
608b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek     */
609a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek    public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
610a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek            VisualStabilityManager visualStabilityManager,
611a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek            VisualStabilityManager.Callback callback) {
612a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek        return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder,
613a7d4f82c05f1c6ea5dd92a4871711d380b01100aSelim Cinek                visualStabilityManager, callback);
614b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
615b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
616b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void getChildrenStates(StackScrollState resultState) {
61783bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
618bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            ExpandableViewState parentState = resultState.getViewStateForView(this);
619b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.getState(resultState, parentState);
620b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
621b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
622b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
623b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void applyChildrenState(StackScrollState state) {
62483bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
625b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.applyState(state);
626b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
627b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
628b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
629b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void prepareExpansionChanged(StackScrollState state) {
63083bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
631b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            mChildrenContainer.prepareExpansionChanged(state);
632b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
633b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
634b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
6350cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek    public void startChildAnimation(StackScrollState finalState, AnimationProperties properties) {
63683bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren) {
6370cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            mChildrenContainer.startAnimationToState(finalState, properties);
638b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
639b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
640b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
641b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public ExpandableNotificationRow getViewAtPosition(float y) {
64243d30f03f45f3f9ad3955f5c83f4d21f26891de6Selim Cinek        if (!mIsSummaryWithChildren || !mChildrenExpanded) {
643b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return this;
644b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
645b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ExpandableNotificationRow view = mChildrenContainer.getViewAtPosition(y);
646b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            return view == null ? this : view;
647b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
648b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
649b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
650ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public NotificationGuts getGuts() {
651ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        return mGuts;
652ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
653ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
654684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    /**
655684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
656684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * the notification will be rendered on top of the screen.
657684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     *
658684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     * @param pinned whether it is pinned
659684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek     */
660684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public void setPinned(boolean pinned) {
661def35a86530200958384191d43d321dbcda16e2aSelim Cinek        int intrinsicHeight = getIntrinsicHeight();
6625cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        boolean wasAboveShelf = isAboveShelf();
663684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        mIsPinned = pinned;
664def35a86530200958384191d43d321dbcda16e2aSelim Cinek        if (intrinsicHeight != getIntrinsicHeight()) {
665bb42b7dd4892a8ab99f2f702cad931235d1d463eSelim Cinek            notifyHeightChanged(false /* needsAnimation */);
666def35a86530200958384191d43d321dbcda16e2aSelim Cinek        }
66731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if (pinned) {
66831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            setIconAnimationRunning(true);
66931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            mExpandedWhenPinned = false;
67031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mExpandedWhenPinned) {
67131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            setUserExpanded(true);
67231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        }
67398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(mLastChronometerRunning);
6745cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        if (isAboveShelf() != wasAboveShelf) {
6755cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
6765cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        }
677b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
678b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
679684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek    public boolean isPinned() {
680684a442b812a5e95d813700ffa2fd17ca72048a7Selim Cinek        return mIsPinned;
681b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
682b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
683d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    @Override
684d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    public int getPinnedHeadsUpHeight() {
685d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek        return getPinnedHeadsUpHeight(true /* atLeastMinHeight */);
686d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    }
687d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek
68831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    /**
68931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * @param atLeastMinHeight should the value returned be at least the minimum height.
69031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     *                         Used to avoid cyclic calls
69131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     * @return the height of the heads up notification when pinned
69231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek     */
693d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    private int getPinnedHeadsUpHeight(boolean atLeastMinHeight) {
69477019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        if (mIsSummaryWithChildren) {
69577019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek            return mChildrenContainer.getIntrinsicHeight();
69677019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek        }
69731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        if(mExpandedWhenPinned) {
69831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return Math.max(getMaxExpandHeight(), mHeadsUpHeight);
69931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (atLeastMinHeight) {
700567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek            return Math.max(getCollapsedHeight(), mHeadsUpHeight);
70131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else {
70231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return mHeadsUpHeight;
70331aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        }
704b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek    }
705b8f09cf5533d458868a335ce334e4880b2b0788dSelim Cinek
7065eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
7075eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * Mark whether this notification was just clicked, i.e. the user has just clicked this
7085eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * notification in this frame.
7095eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
7105eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public void setJustClicked(boolean justClicked) {
7115eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        mJustClicked = justClicked;
7125eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
7135eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
7145eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    /**
7155eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     * @return true if this notification has been clicked in this frame, false otherwise
7165eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi     */
7175eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    public boolean wasJustClicked() {
7185eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi        return mJustClicked;
7195eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi    }
7205eb67c22489f5fda22770d1fc824e7a8013ec025Jorim Jaggi
72198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    public void setChronometerRunning(boolean running) {
72298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        mLastChronometerRunning = running;
72398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPrivateLayout);
72498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        setChronometerRunning(running, mPublicLayout);
72598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (mChildrenContainer != null) {
72698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
72798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                    mChildrenContainer.getNotificationChildren();
72898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
72998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
73098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                child.setChronometerRunning(running);
73198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
73298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
73398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
73498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
73598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunning(boolean running, NotificationContentView layout) {
73698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (layout != null) {
73798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            running = running || isPinned();
73898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View contractedChild = layout.getContractedChild();
73998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View expandedChild = layout.getExpandedChild();
74098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View headsUpChild = layout.getHeadsUpChild();
74198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, contractedChild);
74298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, expandedChild);
74398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            setChronometerRunningForChild(running, headsUpChild);
74498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
74598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
74698713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
74798713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    private void setChronometerRunningForChild(boolean running, View child) {
74898713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        if (child != null) {
74998713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            View chronometer = child.findViewById(com.android.internal.R.id.chronometer);
75098713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            if (chronometer instanceof Chronometer) {
75198713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek                ((Chronometer) chronometer).setStarted(running);
75298713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek            }
75398713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek        }
75498713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek    }
75598713a4fcf1061d3366b333c954fd7b8e9f12841Selim Cinek
756ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek    public NotificationHeaderView getNotificationHeader() {
757b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mIsSummaryWithChildren) {
758b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            return mChildrenContainer.getHeaderView();
7598d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek        }
760ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        return mPrivateLayout.getNotificationHeader();
7618d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek    }
7628d6440dbaba4310cb517ab2a725d75be1ef934f4Selim Cinek
763414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    /**
764414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek     * @return the currently visible notification header. This can be different from
765414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek     * {@link #getNotificationHeader()} in case it is a low-priority group.
766414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek     */
767414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    public NotificationHeaderView getVisibleNotificationHeader() {
768aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
769414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            return mChildrenContainer.getVisibleHeader();
77034eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        }
77134eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        return getShowingLayout().getVisibleNotificationHeader();
77234eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek    }
77334eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek
774b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek
775b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek    /**
776b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek     * @return the contracted notification header. This can be different from
777b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek     * {@link #getNotificationHeader()} and also {@link #getVisibleNotificationHeader()} and only
778b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek     * returns the contracted version.
779b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek     */
780b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek    public NotificationHeaderView getContractedNotificationHeader() {
781b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek        if (mIsSummaryWithChildren) {
782b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek            return mChildrenContainer.getHeaderView();
783b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek        }
784b26afa3e941dd000a2c5befa0481e9244f152b6eSelim Cinek        return mPrivateLayout.getContractedNotificationHeader();
78534eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek    }
78634eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek
787570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) {
788570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek        mOnExpandClickListener = onExpandClickListener;
789570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    }
790570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek
791ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    @Override
792ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    public void setOnClickListener(@Nullable OnClickListener l) {
793ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        super.setOnClickListener(l);
794ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        mOnClickListener = l;
795ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        updateClickAndFocus();
796ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    }
797ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek
798ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    private void updateClickAndFocus() {
799ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        boolean normalChild = !isChildInGroup() || isGroupExpanded();
800ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        boolean clickable = mOnClickListener != null && normalChild;
801ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        if (isFocusable() != normalChild) {
802ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek            setFocusable(normalChild);
803ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        }
804ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        if (isClickable() != clickable) {
805ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek            setClickable(clickable);
806ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        }
807ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek    }
808ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek
80931aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    public void setHeadsUpManager(HeadsUpManager headsUpManager) {
81031aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        mHeadsUpManager = headsUpManager;
81131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek    }
81231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek
81387d7945f0693d3ca943bfb6491d4eba3a8d7cc75Mady Mellor    public void setGutsView(MenuItem item) {
81495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mGuts != null && item.getGutsView() instanceof GutsContent) {
81595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            ((GutsContent) item.getGutsView()).setGutsParent(mGuts);
81695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            mGuts.setGutsContent((GutsContent) item.getGutsView());
81787d7945f0693d3ca943bfb6491d4eba3a8d7cc75Mady Mellor        }
81887d7945f0693d3ca943bfb6491d4eba3a8d7cc75Mady Mellor    }
81987d7945f0693d3ca943bfb6491d4eba3a8d7cc75Mady Mellor
82095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    @Override
82195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    protected void onAttachedToWindow() {
82295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        super.onAttachedToWindow();
82395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        Dependency.get(PluginManager.class).addPluginListener(this,
82495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor                NotificationMenuRowPlugin.class, false /* Allow multiple */);
82595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
82695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
82795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    @Override
82895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    protected void onDetachedFromWindow() {
82995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        super.onDetachedFromWindow();
83095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        Dependency.get(PluginManager.class).removePluginListener(this);
83195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
83295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
83395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    @Override
83495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    public void onPluginConnected(NotificationMenuRowPlugin plugin, Context pluginContext) {
83595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        boolean existed = mMenuRow.getMenuView() != null;
83695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (existed) {
83795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            removeView(mMenuRow.getMenuView());
83895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
83995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        mMenuRow = plugin;
84095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow.useDefaultMenuItems()) {
8414c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor            ArrayList<MenuItem> items = new ArrayList<>();
8424c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor            items.add(NotificationMenuRow.createInfoItem(mContext));
8434c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor            items.add(NotificationMenuRow.createSnoozeItem(mContext));
8444c19760b9131a67b379f9b7060c5830cb5beaad7Mady Mellor            mMenuRow.setMenuItems(items);
84595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
84695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (existed) {
84795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            createMenu();
84895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
84995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
85095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
85195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    @Override
85295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    public void onPluginDisconnected(NotificationMenuRowPlugin plugin) {
85395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        boolean existed = mMenuRow.getMenuView() != null;
85495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        mMenuRow = new NotificationMenuRow(mContext); // Back to default
85595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (existed) {
85695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            createMenu();
85795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
85895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
85995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
86095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    public NotificationMenuRowPlugin createMenu() {
86195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow.getMenuView() == null) {
8624ab2820e6c668ae7c55b300f126bb9f70c202ba3Mady Mellor            mMenuRow.createMenu(this, mStatusBarNotification);
86395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            mMenuRow.setAppName(mAppName);
86495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            FrameLayout.LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
86595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor                    LayoutParams.MATCH_PARENT);
86695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            addView(mMenuRow.getMenuView(), MENU_VIEW_INDEX, lp);
86795d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        }
86895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        return mMenuRow;
86995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
87095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
87195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    public NotificationMenuRowPlugin getProvider() {
87295d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        return mMenuRow;
87395d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor    }
87495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor
8759fe1ee7413d2d914cc24a1123a22dc5b16952b8fAnthony Chen    @Override
8761a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void onDensityOrFontScaleChanged() {
8779fe1ee7413d2d914cc24a1123a22dc5b16952b8fAnthony Chen        super.onDensityOrFontScaleChanged();
87801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        initDimens();
879ad4d158a78a56254b863757d46667144acc8b3f4Anthony Chen        initBackground();
880817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        // Let's update our childrencontainer. This is intentionally not guarded with
881817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        // mIsSummaryWithChildren since we might have had children but not anymore.
882817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        if (mChildrenContainer != null) {
883817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek            mChildrenContainer.reInflateViews(mExpandClickListener, mEntry.notification);
88401af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        }
88501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        if (mGuts != null) {
88601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            View oldGuts = mGuts;
88701af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            int index = indexOfChild(oldGuts);
88801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            removeView(oldGuts);
88901af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mGuts = (NotificationGuts) LayoutInflater.from(mContext).inflate(
89001af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek                    R.layout.notification_guts, this, false);
89101af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            mGuts.setVisibility(oldGuts.getVisibility());
89201af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek            addView(mGuts, index);
89301af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        }
89495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        View oldMenu = mMenuRow.getMenuView();
89595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (oldMenu != null) {
896761cde1173cdfbc058034ffb10283e5507ed0ed4Mady Mellor            int menuIndex = indexOfChild(oldMenu);
897761cde1173cdfbc058034ffb10283e5507ed0ed4Mady Mellor            removeView(oldMenu);
8984ab2820e6c668ae7c55b300f126bb9f70c202ba3Mady Mellor            mMenuRow.createMenu(ExpandableNotificationRow.this, mStatusBarNotification);
899761cde1173cdfbc058034ffb10283e5507ed0ed4Mady Mellor            mMenuRow.setAppName(mAppName);
90095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            addView(mMenuRow.getMenuView(), menuIndex);
9014b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
902eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
903eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.reInflateViews();
904eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
9051a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.onDensityOrFontScaleChanged();
9061a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        onNotificationUpdated();
90701af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    }
90801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek
9099d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor    @Override
9109d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor    public void onConfigurationChanged(Configuration newConfig) {
9119d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor        if (mMenuRow.getMenuView() != null) {
9129d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor            mMenuRow.onConfigurationChanged();
9139d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor        }
9149d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor    }
9159d03a5254f5c7ac00071d56b91ddc15a3d761ed6Mady Mellor
916c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek    public void setContentBackground(int customBackgroundColor, boolean animate,
917c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek            NotificationContentView notificationContentView) {
918c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        if (getShowingLayout() == notificationContentView) {
919c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek            setTintColor(customBackgroundColor, animate);
920c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        }
921c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek    }
922c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek
9230bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos    public void closeRemoteInput() {
924eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
925eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.closeRemoteInput();
926eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
9270bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos    }
9280bd8a4b29bf92a901855d889c53186383dd2c5e7Adrian Roos
929c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    /**
930c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek     * Set by how much the single line view should be indented.
931c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek     */
932c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    public void setSingleLineWidthIndention(int indention) {
933c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        mPrivateLayout.setSingleLineWidthIndention(indention);
934c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    }
935c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek
936c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    public int getNotificationColor() {
9374bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek        return mNotificationColor;
9384bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek    }
9394bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek
9404bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek    private void updateNotificationColor() {
9414bb593492ccf560382fac9ae533a7429cec53c94Selim Cinek        mNotificationColor = NotificationColorUtil.resolveContrastColor(mContext,
942ac5f02749a595d39711beb4a1defb01949eb548aSelim Cinek                getStatusBarNotification().getNotification().color,
943ac5f02749a595d39711beb4a1defb01949eb548aSelim Cinek                getBackgroundColorWithoutTint());
9446f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        mNotificationColorAmbient = NotificationColorUtil.resolveAmbientColor(mContext,
9456f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos                getStatusBarNotification().getNotification().color);
946c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    }
947c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek
948c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    public HybridNotificationView getSingleLineView() {
949c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek        return mPrivateLayout.getSingleLineView();
950c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek    }
951c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek
9526f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    public HybridNotificationView getAmbientSingleLineView() {
9536f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        return getShowingLayout().getAmbientSingleLineChild();
9546f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    }
9556f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos
956f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek    public boolean isOnKeyguard() {
957f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek        return mOnKeyguard;
958f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek    }
959f07d06212b08939809aa4128f153bd5179f81fc7Selim Cinek
960c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek    public void removeAllChildren() {
961c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        List<ExpandableNotificationRow> notificationChildren
962c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek                = mChildrenContainer.getNotificationChildren();
963c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        ArrayList<ExpandableNotificationRow> clonedList = new ArrayList<>(notificationChildren);
964c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        for (int i = 0; i < clonedList.size(); i++) {
965c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            ExpandableNotificationRow row = clonedList.get(i);
9663f19f60d654421eee5b35a92129081f08c977629Selim Cinek            if (row.keepInParent()) {
9673f19f60d654421eee5b35a92129081f08c977629Selim Cinek                continue;
9683f19f60d654421eee5b35a92129081f08c977629Selim Cinek            }
969c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            mChildrenContainer.removeNotification(row);
970c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek            row.setIsChildInGroup(false, null);
971c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        }
972c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek        onChildrenCountChanged();
973c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek    }
974c1e389dadc234827354b95bac98a9c7146ed301cSelim Cinek
9751b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek    public void setForceUnlocked(boolean forceUnlocked) {
9761b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek        mForceUnlocked = forceUnlocked;
9771b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek        if (mIsSummaryWithChildren) {
9781b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek            List<ExpandableNotificationRow> notificationChildren = getNotificationChildren();
9791b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek            for (ExpandableNotificationRow child : notificationChildren) {
9801b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek                child.setForceUnlocked(forceUnlocked);
9811b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek            }
9821b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek        }
9831b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek    }
9841b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek
985e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public void setDismissed(boolean dismissed, boolean fromAccessibility) {
9863f19f60d654421eee5b35a92129081f08c977629Selim Cinek        mDismissed = dismissed;
987e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        mGroupParentWhenDismissed = mNotificationParent;
988e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        mRefocusOnDismiss = fromAccessibility;
989e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        mChildAfterViewWhenDismissed = null;
990e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        if (isChildInGroup()) {
991e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
992e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                    mNotificationParent.getNotificationChildren();
993e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            int i = notificationChildren.indexOf(this);
994e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            if (i != -1 && i < notificationChildren.size() - 1) {
995e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                mChildAfterViewWhenDismissed = notificationChildren.get(i + 1);
996e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            }
997e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        }
9983f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
9993f19f60d654421eee5b35a92129081f08c977629Selim Cinek
10003f19f60d654421eee5b35a92129081f08c977629Selim Cinek    public boolean isDismissed() {
10013f19f60d654421eee5b35a92129081f08c977629Selim Cinek        return mDismissed;
10023f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
10033f19f60d654421eee5b35a92129081f08c977629Selim Cinek
10043f19f60d654421eee5b35a92129081f08c977629Selim Cinek    public boolean keepInParent() {
10053f19f60d654421eee5b35a92129081f08c977629Selim Cinek        return mKeepInParent;
10063f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
10073f19f60d654421eee5b35a92129081f08c977629Selim Cinek
10083f19f60d654421eee5b35a92129081f08c977629Selim Cinek    public void setKeepInParent(boolean keepInParent) {
10093f19f60d654421eee5b35a92129081f08c977629Selim Cinek        mKeepInParent = keepInParent;
10103f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
10113f19f60d654421eee5b35a92129081f08c977629Selim Cinek
10123f19f60d654421eee5b35a92129081f08c977629Selim Cinek    public boolean isRemoved() {
10133f19f60d654421eee5b35a92129081f08c977629Selim Cinek        return mRemoved;
10143f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
10153f19f60d654421eee5b35a92129081f08c977629Selim Cinek
1016d009ab1e2a57648cac9de93912964e2a36ae1762Adrian Roos    public void setRemoved() {
1017d009ab1e2a57648cac9de93912964e2a36ae1762Adrian Roos        mRemoved = true;
1018ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        mTranslationWhenRemoved = getTranslationY();
1019ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        mWasChildInGroupWhenRemoved = isChildInGroup();
1020ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        if (isChildInGroup()) {
1021ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek            mTranslationWhenRemoved += getNotificationParent().getTranslationY();
1022ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        }
1023d009ab1e2a57648cac9de93912964e2a36ae1762Adrian Roos        mPrivateLayout.setRemoved();
10243f19f60d654421eee5b35a92129081f08c977629Selim Cinek    }
10253f19f60d654421eee5b35a92129081f08c977629Selim Cinek
1026ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    public boolean wasChildInGroupWhenRemoved() {
1027ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        return mWasChildInGroupWhenRemoved;
1028ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    }
1029ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek
1030ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    public float getTranslationWhenRemoved() {
1031ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek        return mTranslationWhenRemoved;
1032ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek    }
1033ef8c2257045f73f0576c90c05c715c5f31ef81d8Selim Cinek
1034d13956475e97da9de83f6519eab514770118e7afSelim Cinek    public NotificationChildrenContainer getChildrenContainer() {
1035d13956475e97da9de83f6519eab514770118e7afSelim Cinek        return mChildrenContainer;
1036d13956475e97da9de83f6519eab514770118e7afSelim Cinek    }
1037d13956475e97da9de83f6519eab514770118e7afSelim Cinek
1038cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek    public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
10395cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        boolean wasAboveShelf = isAboveShelf();
1040cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek        mHeadsupDisappearRunning = headsUpAnimatingAway;
1041cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek        mPrivateLayout.setHeadsUpAnimatingAway(headsUpAnimatingAway);
10425cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        if (isAboveShelf() != wasAboveShelf) {
10435cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
10445cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        }
1045cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek    }
1046cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek
1047cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek    /**
1048cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek     * @return if the view was just heads upped and is now animating away. During such a time the
1049cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek     * layout needs to be kept consistent
1050cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek     */
1051cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek    public boolean isHeadsUpAnimatingAway() {
1052cafa87f91da77cd2bc7f4a18bd12f6b71df23b5cSelim Cinek        return mHeadsupDisappearRunning;
105373cf02a0783e3857cae21fece9c292abcc9e1409Selim Cinek    }
105473cf02a0783e3857cae21fece9c292abcc9e1409Selim Cinek
1055e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public View getChildAfterViewWhenDismissed() {
1056e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return mChildAfterViewWhenDismissed;
1057e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
1058e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
1059e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public View getGroupParentWhenDismissed() {
1060e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return mGroupParentWhenDismissed;
1061e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
1062e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
10639e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    public void performDismiss() {
1064e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek        if (mOnDismissRunnable != null) {
1065e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek            mOnDismissRunnable.run();
1066e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek        }
10679e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    }
10689e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek
1069e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek    public void setOnDismissRunnable(Runnable onDismissRunnable) {
1070e907911e63c979f36d4297aa9eefef1f194daecbSelim Cinek        mOnDismissRunnable = onDismissRunnable;
10719e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    }
10729e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek
1073281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    public View getNotificationIcon() {
1074414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        NotificationHeaderView notificationHeader = getVisibleNotificationHeader();
1075281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek        if (notificationHeader != null) {
1076281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek            return notificationHeader.getIcon();
1077281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek        }
1078281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek        return null;
1079281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    }
1080281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek
1081281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    /**
1082281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek     * @return whether the notification is currently showing a view with an icon.
1083281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek     */
1084281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    public boolean isShowingIcon() {
1085434180ce5155f0c405080698031f05e9eab3dd4cMady Mellor        if (areGutsExposed()) {
1086434180ce5155f0c405080698031f05e9eab3dd4cMady Mellor            return false;
1087434180ce5155f0c405080698031f05e9eab3dd4cMady Mellor        }
10882ffa02fcbb6359630a09e3d8617c514330ee31f1Selim Cinek        return getVisibleNotificationHeader() != null;
1089281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek    }
1090281c202784fe6eecab4cc535461f1b12c85b2cc0Selim Cinek
10910242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    /**
10920242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek     * Set how much this notification is transformed into an icon.
10930242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek     *
10942b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek     * @param contentTransformationAmount A value from 0 to 1 indicating how much we are transformed
10952b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek     *                                 to the content away
1096875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * @param isLastChild is this the last child in the list. If true, then the transformation is
1097875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     *                    different since it's content fades out.
10980242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek     */
10992b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    public void setContentTransformationAmount(float contentTransformationAmount,
11002b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            boolean isLastChild) {
1101875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        boolean changeTransformation = isLastChild != mIsLastChild;
11022b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        changeTransformation |= mContentTransformationAmount != contentTransformationAmount;
1103875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        mIsLastChild = isLastChild;
11042b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        mContentTransformationAmount = contentTransformationAmount;
1105875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        if (changeTransformation) {
1106875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            updateContentTransformation();
11072b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        }
11082b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    }
11092b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek
11102b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    /**
11112b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek     * Set the icons to be visible of this notification.
11122b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek     */
11132b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek    public void setIconsVisible(boolean iconsVisible) {
11142b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        if (iconsVisible != mIconsVisible) {
11152b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            mIconsVisible = iconsVisible;
11162b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            updateIconVisibilities();
11170242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek        }
11180242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    }
11190242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek
1120db16737031091160a3a7d080ac44ce2836402d74Selim Cinek    @Override
1121db16737031091160a3a7d080ac44ce2836402d74Selim Cinek    protected void onBelowSpeedBumpChanged() {
1122db16737031091160a3a7d080ac44ce2836402d74Selim Cinek        updateIconVisibilities();
1123db16737031091160a3a7d080ac44ce2836402d74Selim Cinek    }
1124db16737031091160a3a7d080ac44ce2836402d74Selim Cinek
1125875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    private void updateContentTransformation() {
1126875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        float contentAlpha;
11272b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        float translationY = -mContentTransformationAmount * mIconTransformContentShift;
1128875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        if (mIsLastChild) {
11292b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            contentAlpha = 1.0f - mContentTransformationAmount;
1130875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            contentAlpha = Math.min(contentAlpha / 0.5f, 1.0f);
11310242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek            contentAlpha = Interpolators.ALPHA_OUT.getInterpolation(contentAlpha);
1132875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            translationY *= 0.4f;
1133875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        } else {
1134875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            contentAlpha = 1.0f;
1135875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        }
1136eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
1137eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setAlpha(contentAlpha);
1138eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setTranslationY(translationY);
1139eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
1140875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        if (mChildrenContainer != null) {
1141875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            mChildrenContainer.setAlpha(contentAlpha);
1142875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            mChildrenContainer.setTranslationY(translationY);
1143875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            // TODO: handle children fade out better
11440242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek        }
11450242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    }
11460242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek
11470242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    private void updateIconVisibilities() {
114817e1b69523086a98189178fc7f2b23d74860c738Selim Cinek        boolean visible = isChildInGroup()
114917e1b69523086a98189178fc7f2b23d74860c738Selim Cinek                || (isBelowSpeedBump() && !NotificationShelf.SHOW_AMBIENT_ICONS)
115017e1b69523086a98189178fc7f2b23d74860c738Selim Cinek                || mIconsVisible;
1151eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
1152eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setIconsVisible(visible);
1153eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
1154db16737031091160a3a7d080ac44ce2836402d74Selim Cinek        if (mChildrenContainer != null) {
1155db16737031091160a3a7d080ac44ce2836402d74Selim Cinek            mChildrenContainer.setIconsVisible(visible);
11560242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek        }
11570242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek    }
11580242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek
1159875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    /**
1160875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * Get the relative top padding of a view relative to this view. This recursively walks up the
1161875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * hierarchy and does the corresponding measuring.
1162875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     *
1163875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * @param view the view to the the padding for. The requested view has to be a child of this
1164875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     *             notification.
1165875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * @return the toppadding
1166875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     */
1167875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    public int getRelativeTopPadding(View view) {
1168875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        int topPadding = 0;
1169875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        while (view.getParent() instanceof ViewGroup) {
1170875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            topPadding += view.getTop();
1171875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            view = (View) view.getParent();
1172875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            if (view instanceof ExpandableNotificationRow) {
1173875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek                return topPadding;
1174875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            }
1175875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        }
1176875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        return topPadding;
1177875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    }
1178875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek
1179a1d9790735a183578ad8789234b7defd67ed0866Selim Cinek    public float getContentTranslation() {
1180a1d9790735a183578ad8789234b7defd67ed0866Selim Cinek        return mPrivateLayout.getTranslationY();
1181a1d9790735a183578ad8789234b7defd67ed0866Selim Cinek    }
1182a1d9790735a183578ad8789234b7defd67ed0866Selim Cinek
11836743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek    public void setIsLowPriority(boolean isLowPriority) {
11846743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        mIsLowPriority = isLowPriority;
11856743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        mPrivateLayout.setIsLowPriority(isLowPriority);
11861a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.setIsLowPriority(mIsLowPriority);
11876743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        if (mChildrenContainer != null) {
11886743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek            mChildrenContainer.setIsLowPriority(isLowPriority);
11896743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek        }
11906743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek    }
11916743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek
119255a3e738a695d23982eb2e904f47a3435994a325Selim Cinek
119355a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    public void setLowPriorityStateUpdated(boolean lowPriorityStateUpdated) {
119455a3e738a695d23982eb2e904f47a3435994a325Selim Cinek        mLowPriorityStateUpdated = lowPriorityStateUpdated;
119555a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    }
119655a3e738a695d23982eb2e904f47a3435994a325Selim Cinek
119755a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    public boolean hasLowPriorityStateUpdated() {
119855a3e738a695d23982eb2e904f47a3435994a325Selim Cinek        return mLowPriorityStateUpdated;
119955a3e738a695d23982eb2e904f47a3435994a325Selim Cinek    }
120055a3e738a695d23982eb2e904f47a3435994a325Selim Cinek
1201414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    public boolean isLowPriority() {
1202414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        return mIsLowPriority;
1203414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    }
1204414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek
12057d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek    public void setUseIncreasedCollapsedHeight(boolean use) {
12067d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        mUseIncreasedCollapsedHeight = use;
12071a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.setUsesIncreasedHeight(use);
12087d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek    }
12097d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek
121087ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek    public void setUseIncreasedHeadsUpHeight(boolean use) {
121187ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        mUseIncreasedHeadsUpHeight = use;
12121a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.setUsesIncreasedHeadsUpHeight(use);
12131a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
12141a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
12151a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setRemoteViewClickHandler(RemoteViews.OnClickHandler remoteViewClickHandler) {
12161a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater.setRemoteViewClickHandler(remoteViewClickHandler);
121787ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek    }
121887ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek
12195ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    public void setInflationCallback(InflationCallback callback) {
12205ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek        mNotificationInflater.setInflationCallback(callback);
1221c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
1222c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
12231a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos    public void setNeedsRedaction(boolean needsRedaction) {
12241a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos        mNotificationInflater.setRedactAmbient(needsRedaction);
12251a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos    }
12261a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos
12275ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    @VisibleForTesting
12285ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    public NotificationInflater getNotificationInflater() {
12295ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek        return mNotificationInflater;
12305ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek    }
12315ba2254df1cb71355efb0a3831581e2f2babcdbeSelim Cinek
12326f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    public int getNotificationColorAmbient() {
12336f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        return mNotificationColorAmbient;
12346f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    }
12356f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos
123678403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public interface ExpansionLogger {
12376bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen        void logNotificationExpansion(String key, boolean userAction, boolean expanded);
123878403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
12391685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
124051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
124151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        super(context, attrs);
12420e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager = FalsingManager.getInstance(context);
12431a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mNotificationInflater = new NotificationInflater(this);
124495d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        mMenuRow = new NotificationMenuRow(mContext);
124501af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek        initDimens();
124601af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    }
124701af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek
124801af334b70c8ad47c8ce1f465e458863ebe9eae2Selim Cinek    private void initDimens() {
1249f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMinHeightLegacy = getFontScaledHeight(R.dimen.notification_min_height_legacy);
1250f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMinHeight = getFontScaledHeight(R.dimen.notification_min_height);
12517d1009b3bd3b69768f293eb73109c52b8da8ec8eSelim Cinek        mNotificationMinHeightLarge = getFontScaledHeight(
125287ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek                R.dimen.notification_min_height_increased);
1253f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mNotificationMaxHeight = getFontScaledHeight(R.dimen.notification_max_height);
12540aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos        mNotificationAmbientHeight = getFontScaledHeight(R.dimen.notification_ambient_height);
1255f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mMaxHeadsUpHeightLegacy = getFontScaledHeight(
125677019c72332cb31dd1cb713ea4c66e267e6cbf39Selim Cinek                R.dimen.notification_max_heads_up_height_legacy);
1257f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        mMaxHeadsUpHeight = getFontScaledHeight(R.dimen.notification_max_heads_up_height);
125887ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek        mMaxHeadsUpHeightIncreased = getFontScaledHeight(
125987ed69bd6b652c716364e05ba5bad6517eb005c8Selim Cinek                R.dimen.notification_max_heads_up_height_increased);
12606bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen
12617acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        Resources res = getResources();
12627acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        mIncreasedPaddingBetweenElements = res.getDimensionPixelSize(
12637acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                R.dimen.notification_divider_height_increased);
12647acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        mIconTransformContentShiftNoIcon = res.getDimensionPixelSize(
12650242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek                R.dimen.notification_icon_transform_content_shift);
12666bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen        mEnableNonGroupedNotificationExpand =
12676bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen                res.getBoolean(R.bool.config_enableNonGroupedNotificationExpand);
12686bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen        mShowGroupBackgroundWhenExpanded =
12696bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen                res.getBoolean(R.bool.config_showGroupNotificationBgWhenExpanded);
1270f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    }
1271f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek
1272f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    /**
1273f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     * @param dimenId the dimen to look up
1274f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     * @return the font scaled dimen as if it were in sp but doesn't shrink sizes below dp
1275f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek     */
1276f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek    private int getFontScaledHeight(int dimenId) {
1277f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        int dimensionPixelSize = getResources().getDimensionPixelSize(dimenId);
1278f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        float factor = Math.max(1.0f, getResources().getDisplayMetrics().scaledDensity /
1279f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek                getResources().getDisplayMetrics().density);
1280f619ffccd77c20702d45bd2bd63b626e41b08018Selim Cinek        return (int) (dimensionPixelSize * factor);
128151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
128251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1283a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    /**
1284a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     * Resets this view so it can be re-used for an updated notification.
1285a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer     */
1286a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    public void reset() {
1287ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = false;
128831094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        onHeightReset();
12896e28a678c7f9fe2cae5a51bfdbab3071a2d8d0baSelim Cinek        requestLayout();
1290a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer    }
1291a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer
1292251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    @Override
1293251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi    protected void onFinishInflate() {
1294251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi        super.onFinishInflate();
1295be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
1296be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
1297eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        mLayouts = new NotificationContentView[] {mPrivateLayout, mPublicLayout};
1298eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos
1299eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
1300eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setExpandClickListener(mExpandClickListener);
1301eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setContainingNotification(this);
1302eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
1303ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub = (ViewStub) findViewById(R.id.notification_guts_stub);
1304ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        mGutsStub.setOnInflateListener(new ViewStub.OnInflateListener() {
1305b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            @Override
1306b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            public void onInflate(ViewStub stub, View inflated) {
1307b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts = (NotificationGuts) inflated;
1308b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setClipTopAmount(getClipTopAmount());
1309b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi                mGuts.setActualHeight(getActualHeight());
1310ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek                mGutsStub = null;
1311b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            }
1312b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        });
1313b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub = (ViewStub) findViewById(R.id.child_container_stub);
1314b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenContainerStub.setOnInflateListener(new ViewStub.OnInflateListener() {
1315b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1316b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            @Override
1317b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            public void onInflate(ViewStub stub, View inflated) {
1318b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                mChildrenContainer = (NotificationChildrenContainer) inflated;
13196743c0bd52606444ce78316a7bbc51923a140a4aSelim Cinek                mChildrenContainer.setIsLowPriority(mIsLowPriority);
1320414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
1321c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                mChildrenContainer.onNotificationUpdated();
13227acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
13237acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                if (mShouldTranslateContents) {
13247acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                    mTranslateableViews.add(mChildrenContainer);
13257acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                }
1326b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            }
1327b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        });
13284b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
13297acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        if (mShouldTranslateContents) {
13307acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            // Add the views that we translate to reveal the menu
13317acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            mTranslateableViews = new ArrayList<>();
13327acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            for (int i = 0; i < getChildCount(); i++) {
13337acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                mTranslateableViews.add(getChildAt(i));
13347acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            }
13357acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            // Remove views that don't translate
13367acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            mTranslateableViews.remove(mChildrenContainerStub);
13377acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            mTranslateableViews.remove(mGutsStub);
13384b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
13394b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
13404b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
13414b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public void resetTranslation() {
134232c638a597dccbe4be600fd483060ee1466fdb04Mady Mellor        if (mTranslateAnim != null) {
134332c638a597dccbe4be600fd483060ee1466fdb04Mady Mellor            mTranslateAnim.cancel();
134432c638a597dccbe4be600fd483060ee1466fdb04Mady Mellor        }
13457acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
13467acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        if (!mShouldTranslateContents) {
13477acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            setTranslationX(0);
13487acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        } else if (mTranslateableViews != null) {
13494b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            for (int i = 0; i < mTranslateableViews.size(); i++) {
13504b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                mTranslateableViews.get(i).setTranslationX(0);
13514b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
13527acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            invalidateOutline();
13534b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
13547acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
135595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        mMenuRow.resetMenu();
13564b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
13574b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
13584b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    public void animateTranslateNotification(final float leftTarget) {
13594b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        if (mTranslateAnim != null) {
13604b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            mTranslateAnim.cancel();
13614b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        }
1362b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        mTranslateAnim = getTranslateViewAnimator(leftTarget, null /* updateListener */);
136334958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (mTranslateAnim != null) {
136434958fa272c9216db4002546c3efad692b3d7775Mady Mellor            mTranslateAnim.start();
136534958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
136634958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
136734958fa272c9216db4002546c3efad692b3d7775Mady Mellor
136834958fa272c9216db4002546c3efad692b3d7775Mady Mellor    @Override
136934958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public void setTranslation(float translationX) {
137034958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (areGutsExposed()) {
137134958fa272c9216db4002546c3efad692b3d7775Mady Mellor            // Don't translate if guts are showing.
137234958fa272c9216db4002546c3efad692b3d7775Mady Mellor            return;
137334958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
13747acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        if (!mShouldTranslateContents) {
13757acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            setTranslationX(translationX);
13767acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        } else if (mTranslateableViews != null) {
13777acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            // Translate the group of views
13787acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            for (int i = 0; i < mTranslateableViews.size(); i++) {
13797acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                if (mTranslateableViews.get(i) != null) {
13807acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                    mTranslateableViews.get(i).setTranslationX(translationX);
13817acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen                }
138234958fa272c9216db4002546c3efad692b3d7775Mady Mellor            }
13837acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            invalidateOutline();
138434958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
138595d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow.getMenuView() != null) {
138695d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            mMenuRow.onTranslationUpdate(translationX);
138734958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
138834958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
138934958fa272c9216db4002546c3efad692b3d7775Mady Mellor
139034958fa272c9216db4002546c3efad692b3d7775Mady Mellor    @Override
139134958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public float getTranslation() {
1392e04afcb935356320c4397985724b9f9573b57f25Anthony Chen        if (!mShouldTranslateContents) {
13937acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen            return getTranslationX();
13947acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen        }
13957acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
139634958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (mTranslateableViews != null && mTranslateableViews.size() > 0) {
139734958fa272c9216db4002546c3efad692b3d7775Mady Mellor            // All of the views in the list should have same translation, just use first one.
139834958fa272c9216db4002546c3efad692b3d7775Mady Mellor            return mTranslateableViews.get(0).getTranslationX();
139934958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
14007acbb778c48cd9df072c2610ecbdeb5f3255ba09Anthony Chen
140134958fa272c9216db4002546c3efad692b3d7775Mady Mellor        return 0;
140234958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
140334958fa272c9216db4002546c3efad692b3d7775Mady Mellor
140434958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public Animator getTranslateViewAnimator(final float leftTarget,
140534958fa272c9216db4002546c3efad692b3d7775Mady Mellor            AnimatorUpdateListener listener) {
1406723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor        if (mTranslateAnim != null) {
1407723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor            mTranslateAnim.cancel();
1408723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor        }
140934958fa272c9216db4002546c3efad692b3d7775Mady Mellor        if (areGutsExposed()) {
141034958fa272c9216db4002546c3efad692b3d7775Mady Mellor            // No translation if guts are exposed.
141134958fa272c9216db4002546c3efad692b3d7775Mady Mellor            return null;
141234958fa272c9216db4002546c3efad692b3d7775Mady Mellor        }
1413b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        final ObjectAnimator translateAnim = ObjectAnimator.ofFloat(this, TRANSLATE_CONTENT,
1414b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                leftTarget);
1415b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (listener != null) {
1416b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            translateAnim.addUpdateListener(listener);
1417b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
1418b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        translateAnim.addListener(new AnimatorListenerAdapter() {
1419b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            boolean cancelled = false;
1420723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor
1421b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            @Override
1422b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            public void onAnimationCancel(Animator anim) {
1423b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                cancelled = true;
1424b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            }
1425723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor
1426b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            @Override
1427b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            public void onAnimationEnd(Animator anim) {
142895d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor                if (!cancelled && leftTarget == 0) {
142995d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor                    mMenuRow.resetMenu();
1430b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                    mTranslateAnim = null;
1431723f1f996fd78f08e5e91ed57420bd431e11f903Mady Mellor                }
14324b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            }
1433b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        });
1434b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        mTranslateAnim = translateAnim;
1435b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        return translateAnim;
14364b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
14374b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
1438ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    public void inflateGuts() {
1439ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        if (mGuts == null) {
1440ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek            mGutsStub.inflate();
1441ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek        }
1442ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek    }
1443ab29aebf00a0ebd286a92d129f35c182b6888f3bSelim Cinek
1444da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek    private void updateChildrenVisibility() {
1445d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        mPrivateLayout.setVisibility(!mShowingPublic && !mIsSummaryWithChildren ? VISIBLE
1446d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                : INVISIBLE);
1447ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek        if (mChildrenContainer != null) {
1448ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek            mChildrenContainer.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
1449ef5127ea5f34f7a4c961021f6b691174bcb81d2eSelim Cinek                    : INVISIBLE);
1450b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1451da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        // The limits might have changed if the view suddenly became a group or vice versa
1452da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateLimits();
1453b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1454b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1455fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi    @Override
1456a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
1457a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        if (super.onRequestSendAccessibilityEventInternal(child, event)) {
1458fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // Add a record for the entire layout since its content is somehow small.
1459fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            // The event comes from a leaf view that is interacted with.
1460fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            AccessibilityEvent record = AccessibilityEvent.obtain();
1461fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            onInitializeAccessibilityEvent(record);
1462fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            dispatchPopulateAccessibilityEvent(record);
1463fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            event.appendRecord(record);
1464fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi            return true;
1465fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        }
1466fe40f7d13bfc1faa35c9a131ce4be5104cb8f6b9Jorim Jaggi        return false;
1467c5dc0d0cce373fbf292e13633c114a431d747167Jorim Jaggi    }
146851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1469e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    @Override
14704e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    public void setDark(boolean dark, boolean fade, long delay) {
14714e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        super.setDark(dark, fade, delay);
1472cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin        mDark = dark;
147328f90c78b213fb436b243126e8bc10c4f554bd1cAdrian Roos        if (!mIsHeadsUp) {
147428f90c78b213fb436b243126e8bc10c4f554bd1cAdrian Roos            // Only fade the showing view of the pulsing notification.
147528f90c78b213fb436b243126e8bc10c4f554bd1cAdrian Roos            fade = false;
147628f90c78b213fb436b243126e8bc10c4f554bd1cAdrian Roos        }
1477e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        final NotificationContentView showing = getShowingLayout();
1478e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        if (showing != null) {
14794e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            showing.setDark(dark, fade, delay);
1480e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock        }
14819c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek        if (mIsSummaryWithChildren) {
1482c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            mChildrenContainer.setDark(dark, fade, delay);
14839c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek        }
1484a7c69637f8fa7cc8c0e7ac7c4d73659730315841Selim Cinek        updateShelfIconColor();
1485e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock    }
1486e15452bb49d2531eee3086acb4763dd125f8053aJohn Spurlock
1487cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    /**
1488cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin     * Tap sounds should not be played when we're unlocking.
1489cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin     * Doing so would cause audio collision and the system would feel unpolished.
1490cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin     */
1491cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    @Override
1492cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    public boolean isSoundEffectsEnabled() {
1493cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin        final boolean mute = mDark && mSecureStateProvider != null &&
1494cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin                !mSecureStateProvider.getAsBoolean();
1495cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin        return !mute && super.isSoundEffectsEnabled();
1496cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin    }
1497cecc7c233a298f533f28ce7e2792026b3427680eLucas Dupin
149851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isExpandable() {
1499388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1500388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return !mChildrenExpanded;
1501388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
15026bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen        return mEnableNonGroupedNotificationExpand && mExpandable;
150351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
150451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
150551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setExpandable(boolean expandable) {
150651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mExpandable = expandable;
1507eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
150851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
150951c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
15104ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    @Override
15114ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    public void setClipToActualHeight(boolean clipToActualHeight) {
1512084c16b8b380e7ff0d38d9e2846db321f0214931Selim Cinek        super.setClipToActualHeight(clipToActualHeight || isUserLocked());
1513084c16b8b380e7ff0d38d9e2846db321f0214931Selim Cinek        getShowingLayout().setClipToActualHeight(clipToActualHeight || isUserLocked());
15144ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek    }
15154ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek
15161685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
15171685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the user has changed the expansion state
15181685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
15191685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean hasUserChangedExpansion() {
15201685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mHasUserChangedExpansion;
15211685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
15221685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
152351c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserExpanded() {
152451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        return mUserExpanded;
152551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
152651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
15271685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
15281685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the user
15291685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
15301685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param userExpanded whether the user wants this notification to be expanded
15311685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
153251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserExpanded(boolean userExpanded) {
1533388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        setUserExpanded(userExpanded, false /* allowChildExpansion */);
1534388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    }
1535388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek
1536388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    /**
1537388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * Set this notification to be expanded by the user
1538388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     *
1539388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param userExpanded whether the user wants this notification to be expanded
1540388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     * @param allowChildExpansion whether a call to this method allows expanding children
1541388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek     */
1542388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek    public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) {
15430e2ffbd48bbedf47deb7f6aed96bd07e2fc96f53Blazej Magnowski        mFalsingManager.setNotificationExpanded();
1544414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic && allowChildExpansion
1545414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                && !mChildrenContainer.showingAsLowPriority()) {
1546698b1706be196de41fc6bf03cf15971c82a11949Chris Wren            final boolean wasExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
1547388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            mGroupManager.setGroupExpanded(mStatusBarNotification, userExpanded);
1548414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            onExpansionChanged(true /* userAction */, wasExpanded);
1549388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek            return;
1550388df6dd3d07376ecd7446cae36e1486cd313171Selim Cinek        }
1551a7fe63190cc3f95af1830886edd80acef0c334e3Christoph Studer        if (userExpanded && !mExpandable) return;
155278403d79739605511ea88b653564d81d7bf4bbbaChris Wren        final boolean wasExpanded = isExpanded();
15531685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        mHasUserChangedExpansion = true;
155451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserExpanded = userExpanded;
1555414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        onExpansionChanged(true /* userAction */, wasExpanded);
15565d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        if (!wasExpanded && isExpanded()
15575d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek                && getActualHeight() != getIntrinsicHeight()) {
15585d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek            notifyHeightChanged(true /* needsAnimation */);
15595d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        }
156051c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
156151c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
1562ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    public void resetUserExpansion() {
1563414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        boolean changed = mUserExpanded;
1564ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mHasUserChangedExpansion = false;
1565ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek        mUserExpanded = false;
1566414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        if (changed && mIsSummaryWithChildren) {
1567414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            mChildrenContainer.onExpansionChanged();
1568414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        }
1569414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        updateShelfIconColor();
1570ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek    }
1571ccd14fbcfe613eae71f0e00c39f38e5125749389Selim Cinek
157251c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public boolean isUserLocked() {
15731b2a05eb00746756c4d37ad76d597d909019e56fSelim Cinek        return mUserLocked && !mForceUnlocked;
157451c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
157551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
157651c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    public void setUserLocked(boolean userLocked) {
157751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren        mUserLocked = userLocked;
15788f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek        mPrivateLayout.setUserExpanding(userLocked);
1579817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        // This is intentionally not guarded with mIsSummaryWithChildren since we might have had
1580817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        // children but not anymore.
1581817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        if (mChildrenContainer != null) {
158242357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            mChildrenContainer.setUserLocked(userLocked);
1583817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek            if (mIsSummaryWithChildren && (userLocked || !isGroupExpanded())) {
1584b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                updateBackgroundForGroupState();
1585b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            }
158642357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        }
158751c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren    }
158851c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren
15891685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
15901685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return has the system set this notification to be expanded
15911685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
15921685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public boolean isSystemExpanded() {
15931685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        return mIsSystemExpanded;
15941685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
15951685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
15961685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
15971685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Set this notification to be expanded by the system.
15981685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
15991685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @param expand whether the system wants this notification to be expanded.
16001685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
16011685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public void setSystemExpanded(boolean expand) {
160231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        if (expand != mIsSystemExpanded) {
160331094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
160431094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            mIsSystemExpanded = expand;
1605b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            notifyHeightChanged(false /* needsAnimation */);
1606414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            onExpansionChanged(false /* userAction */, wasExpanded);
1607ed6913b0ce99784188713975218dcff113a3d4a7Selim Cinek            if (mIsSummaryWithChildren) {
1608c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                mChildrenContainer.updateGroupOverflow();
1609c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek            }
161031094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
1611dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    }
1612dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi
1613dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi    /**
161483bc78338437a460076a4b5778ded38440ac3501Selim Cinek     * @param onKeyguard whether to prevent notification expansion
1615dce3c4cca5d4df4cc49c1a9f0537e2fecdbc45d2Jorim Jaggi     */
161683bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public void setOnKeyguard(boolean onKeyguard) {
161783bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (onKeyguard != mOnKeyguard) {
16185cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            boolean wasAboveShelf = isAboveShelf();
161931094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            final boolean wasExpanded = isExpanded();
162083bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mOnKeyguard = onKeyguard;
1621414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            onExpansionChanged(false /* userAction */, wasExpanded);
162231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            if (wasExpanded != isExpanded()) {
1623c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                if (mIsSummaryWithChildren) {
1624c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                    mChildrenContainer.updateGroupOverflow();
1625c897bd3e91ed442b0f32c3a5b9918e9e580b62b1Selim Cinek                }
16264b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor                notifyHeightChanged(false /* needsAnimation */);
162731094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek            }
16285cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            if (isAboveShelf() != wasAboveShelf) {
16295cf1d0589a0045ee5f01802975f394847e891215Selim Cinek                mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
16305cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            }
163131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        }
16321685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
16331685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
16341685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
16359e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     * @return Can the underlying notification be cleared? This can be different from whether the
16369e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     *         notification can be dismissed in case notifications are sensitive on the lockscreen.
16379e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     * @see #canViewBeDismissed()
16380d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler     */
16390d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    public boolean isClearable() {
1640506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        if (mStatusBarNotification == null || !mStatusBarNotification.isClearable()) {
1641506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek            return false;
1642506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        }
1643506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        if (mIsSummaryWithChildren) {
1644506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek            List<ExpandableNotificationRow> notificationChildren =
1645506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                    mChildrenContainer.getNotificationChildren();
1646506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
1647506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
1648506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                if (!child.isClearable()) {
1649506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                    return false;
1650506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek                }
1651506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek            }
1652506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        }
1653506deb69a744fe0fa704eda588c3a263b3f8fc2cSelim Cinek        return true;
16540d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
16550d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
16569cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    @Override
16579cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    public int getIntrinsicHeight() {
1658be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (isUserLocked()) {
1659be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            return getActualHeight();
1660be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
16614dd5006ff58c3b1ee5a2e0db343170e7cbd1b585Geoffrey Pitsch        if (mGuts != null && mGuts.isExposed()) {
1662e09fb7029ac29f337b8d3b9e564e5b994a9ed927Mady Mellor            return mGuts.getIntrinsicHeight();
1663d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else if ((isChildInGroup() && !isGroupExpanded())) {
1664d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return mPrivateLayout.getMinHeight();
1665d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else if (mSensitive && mHideSensitiveForIntrinsicHeight) {
1666d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            return getMinHeight();
16676f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        } else if (mIsSummaryWithChildren && (!mOnKeyguard || mShowAmbient)) {
1668eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getIntrinsicHeight();
16696f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        } else if (isHeadsUpAllowed() && (mIsHeadsUp || mHeadsupDisappearRunning)) {
167073cf02a0783e3857cae21fece9c292abcc9e1409Selim Cinek            if (isPinned() || mHeadsupDisappearRunning) {
167131aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                return getPinnedHeadsUpHeight(true /* atLeastMinHeight */);
167231aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            } else if (isExpanded()) {
1673d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                return Math.max(getMaxExpandHeight(), mHeadsUpHeight);
16748d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            } else {
1675567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek                return Math.max(getCollapsedHeight(), mHeadsUpHeight);
16768d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            }
167731aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (isExpanded()) {
167883bc78338437a460076a4b5778ded38440ac3501Selim Cinek            return getMaxExpandHeight();
1679d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        } else {
1680567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek            return getCollapsedHeight();
16811685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        }
1682b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
16831685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
16846f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    private boolean isHeadsUpAllowed() {
16856f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        return !mOnKeyguard && !mShowAmbient;
16866f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    }
16876f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos
168843c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
1689b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public boolean isGroupExpanded() {
1690eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        return mGroupManager.isGroupExpanded(mStatusBarNotification);
1691b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1692b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1693263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    private void onChildrenCountChanged() {
16942a6ea9c2a1b52b0386270ec73e1e6d6a9b614a34Jason Monk        mIsSummaryWithChildren = StatusBar.ENABLE_CHILD_NOTIFICATIONS
1695b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                && mChildrenContainer != null && mChildrenContainer.getNotificationChildCount() > 0;
1696b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() == null) {
1697414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            mChildrenContainer.recreateNotificationHeader(mExpandClickListener
1698414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            );
1699263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek        }
17006baed9e3a272b09e87f15801a389d7714d0b051fMady Mellor        getShowingLayout().updateBackgroundColor(false /* animate */);
1701eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
1702ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek        updateChildrenHeaderAppearance();
1703da42d65ea5a0eec7d1eaf48fee19ead419994b16Selim Cinek        updateChildrenVisibility();
1704263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek    }
1705263398f0175efc8bc8c965473f9565a693a0a0e0Selim Cinek
1706b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public void updateChildrenHeaderAppearance() {
1707ed6913b0ce99784188713975218dcff113a3d4a7Selim Cinek        if (mIsSummaryWithChildren) {
1708b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mChildrenContainer.updateChildrenHeaderAppearance();
1709b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
1710b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
1711b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
17121685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    /**
17131685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * Check whether the view state is currently expanded. This is given by the system in {@link
17141685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * #setSystemExpanded(boolean)} and can be overridden by user expansion or
17151685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
17161685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * view can differ from this state, if layout params are modified from outside.
17171685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     *
17181685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     * @return whether the view state is currently expanded.
17191685e634fb0b14033bd436af8d7174436699ffecSelim Cinek     */
172083bc78338437a460076a4b5778ded38440ac3501Selim Cinek    public boolean isExpanded() {
1721e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek        return isExpanded(false /* allowOnKeyguard */);
1722e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek    }
1723e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek
1724e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek    public boolean isExpanded(boolean allowOnKeyguard) {
1725e81b82ba252582753cb87ba424c82028b6e490ecSelim Cinek        return (!mOnKeyguard || allowOnKeyguard)
1726b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                && (!hasUserChangedExpansion() && (isSystemExpanded() || isSystemChildExpanded())
1727b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek                || isUserExpanded());
1728b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1729b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1730b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    private boolean isSystemChildExpanded() {
1731b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mIsSystemChildExpanded;
1732b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1733b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1734b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setSystemChildExpanded(boolean expanded) {
1735b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mIsSystemChildExpanded = expanded;
17361685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
17371685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
1738035badd314a2130f47745c081e38f82c645f28afMady Mellor    public void setLayoutListener(LayoutListener listener) {
1739035badd314a2130f47745c081e38f82c645f28afMady Mellor        mLayoutListener = listener;
1740035badd314a2130f47745c081e38f82c645f28afMady Mellor    }
1741035badd314a2130f47745c081e38f82c645f28afMady Mellor
1742035badd314a2130f47745c081e38f82c645f28afMady Mellor    public void removeListener() {
1743035badd314a2130f47745c081e38f82c645f28afMady Mellor        mLayoutListener = null;
1744035badd314a2130f47745c081e38f82c645f28afMady Mellor    }
1745035badd314a2130f47745c081e38f82c645f28afMady Mellor
17461685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    @Override
17471685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
17481685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        super.onLayout(changed, left, top, right, bottom);
17498d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        updateMaxHeights();
175095d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor        if (mMenuRow.getMenuView() != null) {
175195d743c38c919dd500d9dcacf9f998500d403d9eMady Mellor            mMenuRow.onHeightUpdate();
1752a6edc878293e49594a6aac7a0d0e41c7980ece07Mady Mellor        }
1753875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        updateContentShiftHeight();
1754035badd314a2130f47745c081e38f82c645f28afMady Mellor        if (mLayoutListener != null) {
1755035badd314a2130f47745c081e38f82c645f28afMady Mellor            mLayoutListener.onLayout();
1756035badd314a2130f47745c081e38f82c645f28afMady Mellor        }
1757875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    }
1758875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek
1759875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    /**
1760875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * Updates the content shift height such that the header is completely hidden when coming from
1761875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     * the top.
1762875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek     */
1763875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek    private void updateContentShiftHeight() {
1764414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        NotificationHeaderView notificationHeader = getVisibleNotificationHeader();
1765875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        if (notificationHeader != null) {
1766875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            CachingIconView icon = notificationHeader.getIcon();
1767875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            mIconTransformContentShift = getRelativeTopPadding(icon) + icon.getHeight();
1768875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        } else {
1769875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek            mIconTransformContentShift = mIconTransformContentShiftNoIcon;
1770875a3a11e2bfcb10d873cd9b4272bed1edf3fe93Selim Cinek        }
17711685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    }
17721685e634fb0b14033bd436af8d7174436699ffecSelim Cinek
17738d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek    private void updateMaxHeights() {
1774d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        int intrinsicBefore = getIntrinsicHeight();
17758d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View expandedChild = mPrivateLayout.getExpandedChild();
17768d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        if (expandedChild == null) {
17778d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek            expandedChild = mPrivateLayout.getContractedChild();
17788d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
17798d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        mMaxExpandHeight = expandedChild.getHeight();
17808d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        View headsUpChild = mPrivateLayout.getHeadsUpChild();
17811f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        if (headsUpChild == null) {
17821f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek            headsUpChild = mPrivateLayout.getContractedChild();
17838d490d427c0b0cc321ae61987bb3cfc1c23ff930Selim Cinek        }
17841f3f544f21cab3728f749ab66cd6859e9dfcf389Selim Cinek        mHeadsUpHeight = headsUpChild.getHeight();
1785d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        if (intrinsicBefore != getIntrinsicHeight()) {
1786bb42b7dd4892a8ab99f2f702cad931235d1d463eSelim Cinek            notifyHeightChanged(true  /* needsAnimation */);
1787d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek        }
1788d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek    }
1789d2319fbe6a53ac4c38ca02e4d8e32da86ed0994bSelim Cinek
1790fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    @Override
1791fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    public void notifyHeightChanged(boolean needsAnimation) {
1792fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        super.notifyHeightChanged(needsAnimation);
1793fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek        getShowingLayout().requestSelectLayout(needsAnimation || isUserLocked());
1794fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek    }
1795fa0a2d3d90fdde14784ec6351a0798bc21c2f126Selim Cinek
17963c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek    public void setSensitive(boolean sensitive, boolean hideSensitive) {
1797ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mSensitive = sensitive;
17983c76d509d362cf5086a63722ab41e04f5d539182Selim Cinek        mSensitiveHiddenInGeneral = hideSensitive;
1799ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1800ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
180143c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
1802ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
180360122be6747c4f79b96f6808158f8f7e7548b7d3Selim Cinek        mHideSensitiveForIntrinsicHeight = hideSensitive;
1804a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek        if (mIsSummaryWithChildren) {
1805a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
1806a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek                    mChildrenContainer.getNotificationChildren();
1807a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
1808a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
1809a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek                child.setHideSensitiveForIntrinsicHeight(hideSensitive);
1810a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek            }
1811a52f6a17efa944adc945a61788cc3beb54c569e7Selim Cinek        }
1812ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1813ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
181443c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
1815ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
1816ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            long duration) {
1817ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        boolean oldShowingPublic = mShowingPublic;
1818ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublic = mSensitive && hideSensitive;
1819ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
1820ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            return;
1821ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
1822a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
1823a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler        // bail out if no public version
18241685e634fb0b14033bd436af8d7174436699ffecSelim Cinek        if (mPublicLayout.getChildCount() == 0) return;
1825a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler
1826ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        if (!animated) {
1827ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.animate().cancel();
1828ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.animate().cancel();
1829a554c707386eb8a6c6fb3a2399f23b79a1c17f74Selim Cinek            if (mChildrenContainer != null) {
1830a554c707386eb8a6c6fb3a2399f23b79a1c17f74Selim Cinek                mChildrenContainer.animate().cancel();
1831a554c707386eb8a6c6fb3a2399f23b79a1c17f74Selim Cinek                mChildrenContainer.setAlpha(1f);
1832a554c707386eb8a6c6fb3a2399f23b79a1c17f74Selim Cinek            }
1833ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setAlpha(1f);
1834ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPrivateLayout.setAlpha(1f);
1835ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
1836d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            updateChildrenVisibility();
1837ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        } else {
1838ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi            animateShowingPublic(delay, duration);
1839ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        }
1840c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        NotificationContentView showingLayout = getShowingLayout();
1841c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek        showingLayout.updateBackgroundColor(animated);
1842eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek        mPrivateLayout.updateExpandButtons(isExpandable());
1843b6ed63b5670e64c853ad69bc2262c6ea88535f5dLucas Dupin        updateShelfIconColor();
1844e5726a20824c3cb2ff369207c8d75bfcdb814f69Adrian Roos        showingLayout.setDark(isDark(), false /* animate */, 0 /* delay */);
1845ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi        mShowingPublicInitialized = true;
1846ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    }
1847ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi
1848ae44128776410abd11bd06ae700db9cc4606a773Jorim Jaggi    private void animateShowingPublic(long delay, long duration) {
1849b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        View[] privateViews = mIsSummaryWithChildren
1850b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                ? new View[] {mChildrenContainer}
1851d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                : new View[] {mPrivateLayout};
1852d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] publicViews = new View[] {mPublicLayout};
1853d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] hiddenChildren = mShowingPublic ? privateViews : publicViews;
1854d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        View[] shownChildren = mShowingPublic ? publicViews : privateViews;
1855d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        for (final View hiddenView : hiddenChildren) {
1856d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.setVisibility(View.VISIBLE);
1857d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.animate().cancel();
1858d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            hiddenView.animate()
1859d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .alpha(0f)
1860d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setStartDelay(delay)
1861d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setDuration(duration)
1862d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .withEndAction(new Runnable() {
1863d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        @Override
1864d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        public void run() {
1865d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                            hiddenView.setVisibility(View.INVISIBLE);
1866d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                        }
1867d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    });
1868d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        }
1869d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        for (View showView : shownChildren) {
1870d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.setVisibility(View.VISIBLE);
1871d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.setAlpha(0f);
1872d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.animate().cancel();
1873d84a5930cca7add37e7e23305538d29959daf199Selim Cinek            showView.animate()
1874d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .alpha(1f)
1875d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setStartDelay(delay)
1876d84a5930cca7add37e7e23305538d29959daf199Selim Cinek                    .setDuration(duration);
1877d84a5930cca7add37e7e23305538d29959daf199Selim Cinek        }
18780d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler    }
18790d3e62f3e07a69f21c1b1dfa2c8c0fb8b6c95655Dan Sandler
188043c2cd1a4071e152e9f4aa9044b03a29cd5ada31Mady Mellor    @Override
18813776fe007550451bb237c705d333247eab2a291cSelim Cinek    public boolean mustStayOnScreen() {
18823776fe007550451bb237c705d333247eab2a291cSelim Cinek        return mIsHeadsUp;
18833776fe007550451bb237c705d333247eab2a291cSelim Cinek    }
18843776fe007550451bb237c705d333247eab2a291cSelim Cinek
18859e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    /**
18869e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     * @return Whether this view is allowed to be dismissed. Only valid for visible notifications as
18879e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     *         otherwise some state might not be updated. To request about the general clearability
18889e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     *         see {@link #isClearable()}.
18899e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek     */
18909e624e732aa5646c83d203587be9c2c4e94c9266Selim Cinek    public boolean canViewBeDismissed() {
1891e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return isClearable() && (!mShowingPublic || !mSensitiveHiddenInGeneral);
1892a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
1893251957d76e57eb6e5f8068b37346144e10e586a4Jorim Jaggi
1894cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai    public void makeActionsVisibile() {
1895cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai        setUserExpanded(true, true);
1896cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai        if (isChildInGroup()) {
1897cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai            mGroupManager.setGroupExpanded(mStatusBarNotification, true);
1898cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai        }
1899bb42b7dd4892a8ab99f2f702cad931235d1d463eSelim Cinek        notifyHeightChanged(false /* needsAnimation */);
1900cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai    }
1901cd35def3c35f04d7fd056590d4668b5ebbc80490Ricky Wai
1902b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public void setChildrenExpanded(boolean expanded, boolean animate) {
1903b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        mChildrenExpanded = expanded;
190483bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mChildrenContainer != null) {
190583bc78338437a460076a4b5778ded38440ac3501Selim Cinek            mChildrenContainer.setChildrenExpanded(expanded);
190683bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
19071a5d8eadd56b435843dfbc1adf3779aa7286081bMady Mellor        updateBackgroundForGroupState();
1908ddf1b399d85ca417301625a55b2a3c7acab2633cSelim Cinek        updateClickAndFocus();
1909b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1910b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
1911b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public static void applyTint(View v, int color) {
1912b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        int alpha;
1913b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (color != 0) {
1914b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = COLORED_DIVIDER_ALPHA;
1915b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        } else {
1916b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            color = 0xff000000;
1917b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            alpha = DEFAULT_DIVIDER_ALPHA;
1918b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1919b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        if (v.getBackground() instanceof ColorDrawable) {
1920b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            ColorDrawable background = (ColorDrawable) v.getBackground();
1921b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.mutate();
1922b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setColor(color);
1923b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek            background.setAlpha(alpha);
1924b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        }
1925b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    }
1926b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek
19271685e634fb0b14033bd436af8d7174436699ffecSelim Cinek    public int getMaxExpandHeight() {
1928b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        return mMaxExpandHeight;
1929a5e0f415d351ad1a9c0ffde8d93df91a2384591fDan Sandler    }
1930584a7aa62c54bcbd654a6696d4fbb56e124874e7Jorim Jaggi
193134958fa272c9216db4002546c3efad692b3d7775Mady Mellor    public boolean areGutsExposed() {
19324dd5006ff58c3b1ee5a2e0db343170e7cbd1b585Geoffrey Pitsch        return (mGuts != null && mGuts.isExposed());
193334958fa272c9216db4002546c3efad692b3d7775Mady Mellor    }
193434958fa272c9216db4002546c3efad692b3d7775Mady Mellor
1935be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
19364222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public boolean isContentExpandable() {
1937c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1938c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            return true;
1939c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        }
19402f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
19412f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.isContentExpandable();
19424222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
19434222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
19444222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
1945560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    protected View getContentView() {
1946aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
1947a5703187a9dba418f742fab0874a8f683b0bbb0eSelim Cinek            return mChildrenContainer;
1948a5703187a9dba418f742fab0874a8f683b0bbb0eSelim Cinek        }
1949560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek        return getShowingLayout();
1950560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    }
1951560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek
1952560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek    @Override
1953aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek    protected void onAppearAnimationFinished(boolean wasAppearing) {
1954aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        super.onAppearAnimationFinished(wasAppearing);
1955aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        if (wasAppearing) {
1956aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek            // During the animation the visible view might have changed, so let's make sure all
1957aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek            // alphas are reset
1958aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek            if (mChildrenContainer != null) {
1959aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek                mChildrenContainer.setAlpha(1.0f);
1960aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek                mChildrenContainer.setLayerType(LAYER_TYPE_NONE, null);
1961aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek            }
1962eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            for (NotificationContentView l : mLayouts) {
1963eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos                l.setAlpha(1.0f);
1964eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos                l.setLayerType(LAYER_TYPE_NONE, null);
1965eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            }
1966aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek        }
1967aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek    }
1968aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek
1969aa3901a5ee68a7256663daa88be92a5faa267c23Selim Cinek    @Override
1970b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public int getExtraBottomPadding() {
1971b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mIsSummaryWithChildren && isGroupExpanded()) {
1972b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            return mIncreasedPaddingBetweenElements;
1973b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
1974b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        return 0;
1975b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
1976b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
1977b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    @Override
1978d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int height, boolean notifyListeners) {
19794ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek        boolean changed = height != getActualHeight();
1980b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek        super.setActualHeight(height, notifyListeners);
19814ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek        if (changed && isRemoved()) {
19824ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            // TODO: remove this once we found the gfx bug for this.
19834ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            // This is a hack since a removed view sometimes would just stay blank. it occured
19844ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            // when sending yourself a message and then clicking on it.
19854ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            ViewGroup parent = (ViewGroup) getParent();
19864ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            if (parent != null) {
19874ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek                parent.invalidate();
19884ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek            }
19894ca6c63c96c23d47e9f35c333a2568a2f3feb9e6Selim Cinek        }
19904dd5006ff58c3b1ee5a2e0db343170e7cbd1b585Geoffrey Pitsch        if (mGuts != null && mGuts.isExposed()) {
1991b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor            mGuts.setActualHeight(height);
1992b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor            return;
1993b53bc276d6ec093817988a358b7c2a6c63ee0c48Mady Mellor        }
1994eef842851026a90b6a217d8bc423454fa48df4feSelim Cinek        int contentHeight = Math.max(getMinHeight(), height);
1995eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
1996eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setContentHeight(contentHeight);
1997eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
199842357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        if (mIsSummaryWithChildren) {
199942357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            mChildrenContainer.setActualHeight(height);
200042357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        }
2001b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
2002b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setActualHeight(height);
2003b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
200454540975a51c5433b4c77447acf1f6cb2b1e3562Mady Mellor        if (mMenuRow.getMenuView() != null) {
200554540975a51c5433b4c77447acf1f6cb2b1e3562Mady Mellor            mMenuRow.onHeightUpdate();
200654540975a51c5433b4c77447acf1f6cb2b1e3562Mady Mellor        }
2007be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
2008be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
2009be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
2010b5605e58cb8080c8c887b1885336b707596c8094Selim Cinek    public int getMaxContentHeight() {
201183bc78338437a460076a4b5778ded38440ac3501Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
2012eaa29ca6ff7a4c21a0729118d0e7c38750b9c93eSelim Cinek            return mChildrenContainer.getMaxContentHeight();
201383bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
20142f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
20152f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return showingLayout.getMaxHeight();
2016be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
2017be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
2018be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
2019eb3fc3d5407d6a15343133912fa74d86d322bac0Selim Cinek    public int getMinHeight(boolean ignoreTemporaryStates) {
2020eb3fc3d5407d6a15343133912fa74d86d322bac0Selim Cinek        if (!ignoreTemporaryStates && mGuts != null && mGuts.isExposed()) {
2021e09fb7029ac29f337b8d3b9e564e5b994a9ed927Mady Mellor            return mGuts.getIntrinsicHeight();
2022eb3fc3d5407d6a15343133912fa74d86d322bac0Selim Cinek        } else if (!ignoreTemporaryStates && isHeadsUpAllowed() && mIsHeadsUp
2023eb3fc3d5407d6a15343133912fa74d86d322bac0Selim Cinek                && mHeadsUpManager.isTrackingHeadsUp()) {
202431aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek                return getPinnedHeadsUpHeight(false /* atLeastMinHeight */);
202531aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        } else if (mIsSummaryWithChildren && !isGroupExpanded() && !mShowingPublic) {
2026b55386d64aeb80f74ed21035d1e389d86be89db6Selim Cinek            return mChildrenContainer.getMinHeight();
2027eb3fc3d5407d6a15343133912fa74d86d322bac0Selim Cinek        } else if (!ignoreTemporaryStates && isHeadsUpAllowed() && mIsHeadsUp) {
202831aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek            return mHeadsUpHeight;
2029b55386d64aeb80f74ed21035d1e389d86be89db6Selim Cinek        }
2030816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        NotificationContentView showingLayout = getShowingLayout();
2031816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return showingLayout.getMinHeight();
2032816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    }
2033816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek
2034816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek    @Override
2035567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek    public int getCollapsedHeight() {
20362c58461daf909fae5a2605f0ba63da3f9c897731Selim Cinek        if (mIsSummaryWithChildren && !mShowingPublic) {
2037567e845d99840a6e556595739a15e16132eb2f1eSelim Cinek            return mChildrenContainer.getCollapsedHeight();
203883bc78338437a460076a4b5778ded38440ac3501Selim Cinek        }
2039816c8e4735f975f4d8bffa1a5a37be6557424ea3Selim Cinek        return getMinHeight();
20404222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
20414222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
20424222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    @Override
2043be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
2044be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super.setClipTopAmount(clipTopAmount);
2045eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
2046eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            l.setClipTopAmount(clipTopAmount);
2047eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
2048b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        if (mGuts != null) {
2049b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi            mGuts.setClipTopAmount(clipTopAmount);
2050b1cd3c1945499721d7d1ce57bdda67695ffe936bJorim Jaggi        }
2051be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
2052be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
2053a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek    @Override
2054a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek    public void setClipBottomAmount(int clipBottomAmount) {
205565d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek        if (clipBottomAmount != mClipBottomAmount) {
205665d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            super.setClipBottomAmount(clipBottomAmount);
2057eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            for (NotificationContentView l : mLayouts) {
2058eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos                l.setClipBottomAmount(clipBottomAmount);
2059eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos            }
206065d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            if (mGuts != null) {
206165d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek                mGuts.setClipBottomAmount(clipBottomAmount);
206265d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            }
2063a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek        }
2064b3dadccbc5c7040260a51a3e17efcb74aeec6a11Selim Cinek        if (mChildrenContainer != null) {
206565d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            // We have to update this even if it hasn't changed, since the children locations can
206665d418ec8957fb1af03a8cc68aed90744a5848ffSelim Cinek            // have changed
2067b3dadccbc5c7040260a51a3e17efcb74aeec6a11Selim Cinek            mChildrenContainer.setClipBottomAmount(clipBottomAmount);
2068b3dadccbc5c7040260a51a3e17efcb74aeec6a11Selim Cinek        }
2069a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek    }
2070a686b2c9a91e2e6276676e5730339f7630e2f927Selim Cinek
207131094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek    public boolean isMaxExpandHeightInitialized() {
207231094df5c6e3cb3a4a4faacb091e35eea1f6a5deSelim Cinek        return mMaxExpandHeight != 0;
20737d447726e2cb9fae80db417012039828daab8fe7Selim Cinek    }
20742f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek
207542357e030c095867b95e2e8a718649587c5ebf52Selim Cinek    public NotificationContentView getShowingLayout() {
20762f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek        return mShowingPublic ? mPublicLayout : mPrivateLayout;
20772f0df8ae038dbb873bf2e11e1e13c75cf95b0198Selim Cinek    }
207878403d79739605511ea88b653564d81d7bf4bbbaChris Wren
20791a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setLegacy(boolean legacy) {
2080eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        for (NotificationContentView l : mLayouts) {
20811a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            l.setLegacy(legacy);
2082eb434ff5b7c9f3e1a601c623ce5af46322d28aa9Adrian Roos        }
208359ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi    }
208459ec304eaebf1bc4098d6feb6cca9039c8b70d3dJorim Jaggi
2085a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    @Override
2086a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    protected void updateBackgroundTint() {
2087a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        super.updateBackgroundTint();
2088b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        updateBackgroundForGroupState();
2089a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        if (mIsSummaryWithChildren) {
2090a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            List<ExpandableNotificationRow> notificationChildren =
2091a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                    mChildrenContainer.getNotificationChildren();
2092a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            for (int i = 0; i < notificationChildren.size(); i++) {
2093a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek                ExpandableNotificationRow child = notificationChildren.get(i);
2094b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                child.updateBackgroundForGroupState();
2095a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek            }
2096a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        }
2097a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
2098a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
2099b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    /**
2100b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor     * Called when a group has finished animating from collapsed or expanded state.
2101b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor     */
2102b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public void onFinishedExpansionChange() {
2103b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        mGroupExpansionChanging = false;
2104b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        updateBackgroundForGroupState();
2105b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    }
2106b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor
2107b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    /**
2108b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor     * Updates the parent and children backgrounds in a group based on the expansion state.
2109b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor     */
2110b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor    public void updateBackgroundForGroupState() {
2111b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        if (mIsSummaryWithChildren) {
2112b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            // Only when the group has finished expanding do we hide its background.
21136bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen            mShowNoBackground = !mShowGroupBackgroundWhenExpanded && isGroupExpanded()
21146bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen                    && !isGroupExpansionChanging() && !isUserLocked();
2115b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mChildrenContainer.updateHeaderForExpansion(mShowNoBackground);
2116b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            List<ExpandableNotificationRow> children = mChildrenContainer.getNotificationChildren();
2117b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            for (int i = 0; i < children.size(); i++) {
2118b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                children.get(i).updateBackgroundForGroupState();
2119b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            }
2120b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        } else if (isChildInGroup()) {
2121b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            final int childColor = getShowingLayout().getBackgroundColorForExpansionState();
2122b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            // Only show a background if the group is expanded OR if it is expanding / collapsing
21236bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen            // and has a custom background color.
2124b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            final boolean showBackground = isGroupExpanded()
2125b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor                    || ((mNotificationParent.isGroupExpansionChanging()
21266bf88a01d7811d9460e088e743882a02d6250b86Anthony Chen                    || mNotificationParent.isUserLocked()) && childColor != 0);
2127b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mShowNoBackground = !showBackground;
2128b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        } else {
2129b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            // Only children or parents ever need no background.
2130b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor            mShowNoBackground = false;
2131b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        }
2132b0a824687f56b6950338aad169d8d837f8ed657bMady Mellor        updateOutline();
2133a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek        updateBackground();
2134a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek    }
2135a6c6bfb61ba14b0467b73082d591c834576cddf4Selim Cinek
21364a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos    public int getPositionOfChild(ExpandableNotificationRow childRow) {
21374a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos        if (mIsSummaryWithChildren) {
21384a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos            return mChildrenContainer.getPositionInLinearLayout(childRow);
21394a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos        }
21404a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos        return 0;
21414a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos    }
21424a5796765041dcb45ce782fc7ec5866b89fe0df0Adrian Roos
214378403d79739605511ea88b653564d81d7bf4bbbaChris Wren    public void setExpansionLogger(ExpansionLogger logger, String key) {
214478403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLogger = logger;
214578403d79739605511ea88b653564d81d7bf4bbbaChris Wren        mLoggingKey = key;
214678403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
214778403d79739605511ea88b653564d81d7bf4bbbaChris Wren
21486abeeb91194818e1d19f75336b03d1e305af0842Chris Wren    public void onExpandedByGesture(boolean userExpanded) {
21496abeeb91194818e1d19f75336b03d1e305af0842Chris Wren        int event = MetricsEvent.ACTION_NOTIFICATION_GESTURE_EXPANDER;
21506abeeb91194818e1d19f75336b03d1e305af0842Chris Wren        if (mGroupManager.isSummaryOfGroup(getStatusBarNotification())) {
21516abeeb91194818e1d19f75336b03d1e305af0842Chris Wren            event = MetricsEvent.ACTION_NOTIFICATION_GROUP_GESTURE_EXPANDER;
21526abeeb91194818e1d19f75336b03d1e305af0842Chris Wren        }
21536abeeb91194818e1d19f75336b03d1e305af0842Chris Wren        MetricsLogger.action(mContext, event, userExpanded);
21546abeeb91194818e1d19f75336b03d1e305af0842Chris Wren    }
21556abeeb91194818e1d19f75336b03d1e305af0842Chris Wren
21566183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    @Override
215742357e030c095867b95e2e8a718649587c5ebf52Selim Cinek    public float getIncreasedPaddingAmount() {
215842357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        if (mIsSummaryWithChildren) {
215942357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            if (isGroupExpanded()) {
216042357e030c095867b95e2e8a718649587c5ebf52Selim Cinek                return 1.0f;
216142357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            } else if (isUserLocked()) {
2162414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                return mChildrenContainer.getIncreasedPaddingAmount();
216342357e030c095867b95e2e8a718649587c5ebf52Selim Cinek            }
216499104836083738f9e5e73ab4170879d91de6ba67Selim Cinek        } else if (isColorized() && (!mIsLowPriority || isExpanded())) {
2165a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek            return -1.0f;
216642357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        }
216742357e030c095867b95e2e8a718649587c5ebf52Selim Cinek        return 0.0f;
216861633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek    }
216961633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek
2170a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek    private boolean isColorized() {
217199104836083738f9e5e73ab4170879d91de6ba67Selim Cinek        return mIsColorized && mBgTint != NO_COLOR;
2172a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek    }
2173a7ed2c1aaa49f0f53507fa3b7e832dca15997a3bSelim Cinek
217461633a8db8dfdefa84b4444a7ae668d0e24f53e9Selim Cinek    @Override
21756183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    protected boolean disallowSingleClick(MotionEvent event) {
21766183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        float x = event.getX();
21776183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        float y = event.getY();
217834eda5ed70863320e41b6860a550ba6a4248c652Selim Cinek        NotificationHeaderView header = getVisibleNotificationHeader();
21795d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        if (header != null && header.isInTouchRect(x - getTranslation(), y)) {
21805d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek            return true;
21815d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        }
21825d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek        if ((!mIsSummaryWithChildren || mShowingPublic)
21835d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek                && getShowingLayout().disallowSingleClick(x, y)) {
21845d6ef8de1e2da541d1cf7c6603739289be4d593eSelim Cinek            return true;
21856183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        }
21866183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek        return super.disallowSingleClick(event);
21876183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek    }
21886183d12926a189b08cc3be8d9c78470617e63db0Selim Cinek
2189414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek    private void onExpansionChanged(boolean userAction, boolean wasExpanded) {
2190698b1706be196de41fc6bf03cf15971c82a11949Chris Wren        boolean nowExpanded = isExpanded();
2191414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        if (mIsSummaryWithChildren && (!mIsLowPriority || wasExpanded)) {
2192698b1706be196de41fc6bf03cf15971c82a11949Chris Wren            nowExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
2193698b1706be196de41fc6bf03cf15971c82a11949Chris Wren        }
2194414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek        if (nowExpanded != wasExpanded) {
2195414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            updateShelfIconColor();
2196414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            if (mLogger != null) {
2197414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded);
2198414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            }
2199414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            if (mIsSummaryWithChildren) {
2200414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek                mChildrenContainer.onExpansionChanged();
2201414ad33470789e9f9fc6c7b82ba684418ff5caa4Selim Cinek            }
220278403d79739605511ea88b653564d81d7bf4bbbaChris Wren        }
220378403d79739605511ea88b653564d81d7bf4bbbaChris Wren    }
2204570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek
2205e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    @Override
2206e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
2207e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        super.onInitializeAccessibilityNodeInfoInternal(info);
2208e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        if (canViewBeDismissed()) {
2209e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
2210e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        }
2211c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        boolean expandable = mShowingPublic;
2212c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        boolean isExpanded = false;
2213c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        if (!expandable) {
2214c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            if (mIsSummaryWithChildren) {
2215c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                expandable = true;
2216c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                if (!mIsLowPriority || isExpanded()) {
2217c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                    isExpanded = isGroupExpanded();
2218c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                }
2219c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            } else {
2220c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                expandable = mPrivateLayout.isContentExpandable();
2221c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                isExpanded = isExpanded();
2222c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            }
2223c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        }
2224c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        if (expandable) {
2225c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            if (isExpanded) {
2226c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
2227c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            } else {
2228c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
2229c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            }
2230c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek        }
2231e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
2232e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
2233e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    @Override
2234e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
2235e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        if (super.performAccessibilityActionInternal(action, arguments)) {
2236e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            return true;
2237e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        }
2238e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        switch (action) {
2239e9bad242f38bebadae481a22b647cc153f093070Selim Cinek            case AccessibilityNodeInfo.ACTION_DISMISS:
2240e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                NotificationStackScrollLayout.performDismiss(this, mGroupManager,
2241e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                        true /* fromAccessibility */);
2242e9bad242f38bebadae481a22b647cc153f093070Selim Cinek                return true;
2243c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            case AccessibilityNodeInfo.ACTION_COLLAPSE:
2244c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek            case AccessibilityNodeInfo.ACTION_EXPAND:
2245c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                mExpandClickListener.onClick(this);
2246c0ac4af13bb18a516e26d2ddb94723ef9f970393Selim Cinek                return true;
2247e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        }
2248e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return false;
2249e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
2250e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
2251e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    public boolean shouldRefocusOnDismiss() {
2252e9bad242f38bebadae481a22b647cc153f093070Selim Cinek        return mRefocusOnDismiss || isAccessibilityFocused();
2253e9bad242f38bebadae481a22b647cc153f093070Selim Cinek    }
2254e9bad242f38bebadae481a22b647cc153f093070Selim Cinek
2255570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    public interface OnExpandClickListener {
225631aada4ef4ff37f8cdc110b196c06918841647c7Selim Cinek        void onExpandClicked(NotificationData.Entry clickedEntry, boolean nowExpanded);
2257570981d5f1bcd0e5186cc02655254a0606b6ec14Selim Cinek    }
2258bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2259bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek    @Override
2260bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
2261bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        return new NotificationViewState(stackScrollState);
2262bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek    }
2263bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2264d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    @Override
2265d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    public boolean isAboveShelf() {
2266c8007c59758b166f262f1e9d8ec19c36bf37b607Selim Cinek        return !isOnKeyguard()
2267c8007c59758b166f262f1e9d8ec19c36bf37b607Selim Cinek                && (mIsPinned || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf));
2268d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    }
2269d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek
22700aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos    public void setShowAmbient(boolean showAmbient) {
22710aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos        if (showAmbient != mShowAmbient) {
22720aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos            mShowAmbient = showAmbient;
22736f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos            if (mChildrenContainer != null) {
22746f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos                mChildrenContainer.notifyShowAmbientChanged();
22756f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos            }
22760aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos            notifyHeightChanged(false /* needsAnimation */);
22770aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos        }
22780aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos    }
22790aac04ff79b43933742d5ebdd8d7a94751ff6309Adrian Roos
22806f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    public boolean isShowingAmbient() {
22816f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos        return mShowAmbient;
22826f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos    }
22836f6e159484f7a82d0a2f867060ac4b17241f45a0Adrian Roos
2284d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    public void setAboveShelf(boolean aboveShelf) {
22855cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        boolean wasAboveShelf = isAboveShelf();
2286d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek        mAboveShelf = aboveShelf;
22875cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        if (isAboveShelf() != wasAboveShelf) {
22885cf1d0589a0045ee5f01802975f394847e891215Selim Cinek            mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
22895cf1d0589a0045ee5f01802975f394847e891215Selim Cinek        }
2290d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek    }
2291d127d7923191c5023db423952d639f6ec8aa86ccSelim Cinek
2292d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek    public static class NotificationViewState extends ExpandableViewState {
2293bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2294bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        private final StackScrollState mOverallState;
22950242fbb9fdd7db0398a197d0e63d20dcac7cd916Selim Cinek
2296bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2297bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        private NotificationViewState(StackScrollState stackScrollState) {
2298bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            mOverallState = stackScrollState;
2299bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        }
2300bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek
2301bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        @Override
2302bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        public void applyToView(View view) {
2303bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            super.applyToView(view);
2304bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            if (view instanceof ExpandableNotificationRow) {
2305bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek                ExpandableNotificationRow row = (ExpandableNotificationRow) view;
2306bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek                row.applyChildrenState(mOverallState);
2307bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek            }
2308bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek        }
23090cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek
23100cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        @Override
23112b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek        protected void onYTranslationAnimationFinished(View view) {
23122b549f4bd436787bd2543812b24add2d8c5b53eeSelim Cinek            super.onYTranslationAnimationFinished(view);
2313d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek            if (view instanceof ExpandableNotificationRow) {
2314d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek                ExpandableNotificationRow row = (ExpandableNotificationRow) view;
2315d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek                if (row.isHeadsUpAnimatingAway()) {
2316d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek                    row.setHeadsUpAnimatingAway(false);
2317d4776a52b45a9f83f0c67f7e967c36ec9cb2c17aSelim Cinek                }
23180cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            }
23190cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        }
23200cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek
23210cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        @Override
23220cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        public void animateTo(View child, AnimationProperties properties) {
23230cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            super.animateTo(child, properties);
23240cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            if (child instanceof ExpandableNotificationRow) {
23250cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
23260cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek                row.startChildAnimation(mOverallState, properties);
23270cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek            }
23280cfbef45f037efe966a5f57af63a328f6fd5d989Selim Cinek        }
2329bbcebde5f47d070d82270a367bec2f375c55d359Selim Cinek    }
2330817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek
2331817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek    @VisibleForTesting
2332817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek    protected void setChildrenContainer(NotificationChildrenContainer childrenContainer) {
2333817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek        mChildrenContainer = childrenContainer;
2334817abe7ebbedf5d84e485a15addf626d6d065773Selim Cinek    }
233551c7510e493680b4aca1ed7695b35c52d2cd63ffChris Wren}
2336