blob: 7078f33b5af48625bdb08e73586f713c50ad9a68 [file] [log] [blame]
Chris Wren51c75102013-07-16 20:49:17 -04001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.statusbar;
18
19import android.content.Context;
Selim Cinekcab4a602014-09-03 14:47:57 +020020import android.graphics.drawable.AnimatedVectorDrawable;
21import android.graphics.drawable.AnimationDrawable;
Selim Cinekb5605e52015-02-20 18:21:41 +010022import android.graphics.drawable.ColorDrawable;
Selim Cinekcab4a602014-09-03 14:47:57 +020023import android.graphics.drawable.Drawable;
Jorim Jaggib1cd3c12014-09-08 19:55:17 +020024import android.service.notification.StatusBarNotification;
Chris Wren51c75102013-07-16 20:49:17 -040025import android.util.AttributeSet;
Selim Cinek1a521f32014-11-03 17:39:29 +010026import android.view.MotionEvent;
Dan Sandlera5e0f412014-01-23 15:11:54 -050027import android.view.View;
Jorim Jaggib1cd3c12014-09-08 19:55:17 +020028import android.view.ViewStub;
Jorim Jaggife40f7d2014-04-28 15:20:04 +020029import android.view.accessibility.AccessibilityEvent;
Selim Cinekb5605e52015-02-20 18:21:41 +010030import android.view.animation.LinearInterpolator;
Selim Cinek98713a42015-09-21 15:47:20 +020031import android.widget.Chronometer;
Selim Cinekcab4a602014-09-03 14:47:57 +020032import android.widget.ImageView;
Selim Cinekb5605e52015-02-20 18:21:41 +010033
Dan Sandlera5e0f412014-01-23 15:11:54 -050034import com.android.systemui.R;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070035import com.android.systemui.classifier.FalsingManager;
Selim Cinek8d6440d2015-10-22 13:00:05 -070036import com.android.systemui.statusbar.notification.NotificationHeaderView;
Selim Cinekb5605e52015-02-20 18:21:41 +010037import com.android.systemui.statusbar.phone.NotificationGroupManager;
Selim Cinekb5605e52015-02-20 18:21:41 +010038import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
39import com.android.systemui.statusbar.stack.StackScrollState;
40import com.android.systemui.statusbar.stack.StackStateAnimator;
41import com.android.systemui.statusbar.stack.StackViewState;
42
43import java.util.List;
Dan Sandlera5e0f412014-01-23 15:11:54 -050044
Jorim Jaggi4222d9a2014-04-23 16:13:15 +020045public class ExpandableNotificationRow extends ActivatableNotificationView {
Selim Cinekb5605e52015-02-20 18:21:41 +010046
47 private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
48 private static final int COLORED_DIVIDER_ALPHA = 0x7B;
49 private final LinearInterpolator mLinearInterpolator = new LinearInterpolator();
Selim Cinek1685e632014-04-08 02:27:49 +020050 private int mRowMinHeight;
Chris Wren51c75102013-07-16 20:49:17 -040051
Selim Cinek1685e632014-04-08 02:27:49 +020052 /** Does this row contain layouts that can adapt to row expansion */
Chris Wren51c75102013-07-16 20:49:17 -040053 private boolean mExpandable;
Selim Cinek1685e632014-04-08 02:27:49 +020054 /** Has the user actively changed the expansion state of this row */
55 private boolean mHasUserChangedExpansion;
56 /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
Chris Wren51c75102013-07-16 20:49:17 -040057 private boolean mUserExpanded;
Selim Cinek1685e632014-04-08 02:27:49 +020058 /** Is the user touching this row */
Chris Wren51c75102013-07-16 20:49:17 -040059 private boolean mUserLocked;
Selim Cinek1685e632014-04-08 02:27:49 +020060 /** Are we showing the "public" version */
Dan Sandlera5e0f412014-01-23 15:11:54 -050061 private boolean mShowingPublic;
Jorim Jaggiae441282014-08-01 02:45:18 +020062 private boolean mSensitive;
63 private boolean mShowingPublicInitialized;
Selim Cinek60122be2015-04-15 18:16:50 -070064 private boolean mHideSensitiveForIntrinsicHeight;
Chris Wren51c75102013-07-16 20:49:17 -040065
Selim Cinek1685e632014-04-08 02:27:49 +020066 /**
67 * Is this notification expanded by the system. The expansion state can be overridden by the
68 * user expansion.
69 */
70 private boolean mIsSystemExpanded;
Jorim Jaggidce3c4c2014-04-29 23:12:24 +020071
72 /**
Selim Cinek83bc7832015-10-22 13:26:54 -070073 * Whether the notification is on the keyguard and the expansion is disabled.
Jorim Jaggidce3c4c2014-04-29 23:12:24 +020074 */
Selim Cinek83bc7832015-10-22 13:26:54 -070075 private boolean mOnKeyguard;
Jorim Jaggidce3c4c2014-04-29 23:12:24 +020076
Jorim Jaggibe565df2014-04-28 17:51:23 +020077 private NotificationContentView mPublicLayout;
78 private NotificationContentView mPrivateLayout;
Selim Cinek1685e632014-04-08 02:27:49 +020079 private int mMaxExpandHeight;
Selim Cinek8d490d42015-04-10 00:05:50 -070080 private int mHeadsUpHeight;
Selim Cinek863834b2014-05-20 04:20:25 +020081 private View mVetoButton;
Dan Sandler0d3e62f2014-07-14 17:13:50 -040082 private boolean mClearable;
Chris Wren78403d72014-07-28 10:23:24 +010083 private ExpansionLogger mLogger;
84 private String mLoggingKey;
Selim Cineka5e211b2014-08-11 17:35:48 +020085 private boolean mWasReset;
Selim Cinek8d490d42015-04-10 00:05:50 -070086 private NotificationGuts mGuts;
Jorim Jaggib1cd3c12014-09-08 19:55:17 +020087 private StatusBarNotification mStatusBarNotification;
Selim Cinek1a521f32014-11-03 17:39:29 +010088 private boolean mIsHeadsUp;
Selim Cinek98713a42015-09-21 15:47:20 +020089 private boolean mLastChronometerRunning = true;
Selim Cinekeef84282015-10-30 16:28:00 -070090 private NotificationHeaderView mNotificationHeader;
91 private ViewStub mNotificationHeaderStub;
Selim Cinekb5605e52015-02-20 18:21:41 +010092 private ViewStub mChildrenContainerStub;
93 private NotificationGroupManager mGroupManager;
Selim Cinekb5605e52015-02-20 18:21:41 +010094 private boolean mChildrenExpanded;
Selim Cinek263398f2015-10-21 17:40:23 -070095 private boolean mIsSummaryWithChildren;
Selim Cinekb5605e52015-02-20 18:21:41 +010096 private NotificationChildrenContainer mChildrenContainer;
Selim Cinekab29aeb2015-02-20 18:18:32 +010097 private ViewStub mGutsStub;
Selim Cinekeef84282015-10-30 16:28:00 -070098 private boolean mHasNotificationHeader;
Selim Cinekb5605e52015-02-20 18:21:41 +010099 private boolean mIsSystemChildExpanded;
Selim Cinek684a4422015-04-15 16:18:39 -0700100 private boolean mIsPinned;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700101 private FalsingManager mFalsingManager;
Jorim Jaggib1cd3c12014-09-08 19:55:17 +0200102
Jorim Jaggi5eb67c22015-08-19 19:50:49 -0700103 private boolean mJustClicked;
Selim Cinekeef84282015-10-30 16:28:00 -0700104 private NotificationData.Entry mEntry;
Selim Cinek34d93b02015-10-22 12:30:38 -0700105 private boolean mShowNoBackground;
Selim Cinek263398f2015-10-21 17:40:23 -0700106 private boolean mChildInGroup;
Jorim Jaggi5eb67c22015-08-19 19:50:49 -0700107
Selim Cinek8d490d42015-04-10 00:05:50 -0700108 public NotificationContentView getPrivateLayout() {
109 return mPrivateLayout;
110 }
111
112 public NotificationContentView getPublicLayout() {
113 return mPublicLayout;
114 }
115
Selim Cinekcab4a602014-09-03 14:47:57 +0200116 public void setIconAnimationRunning(boolean running) {
117 setIconAnimationRunning(running, mPublicLayout);
118 setIconAnimationRunning(running, mPrivateLayout);
119 }
120
121 private void setIconAnimationRunning(boolean running, NotificationContentView layout) {
122 if (layout != null) {
123 View contractedChild = layout.getContractedChild();
124 View expandedChild = layout.getExpandedChild();
Selim Cinek8d490d42015-04-10 00:05:50 -0700125 View headsUpChild = layout.getHeadsUpChild();
Selim Cinekcab4a602014-09-03 14:47:57 +0200126 setIconAnimationRunningForChild(running, contractedChild);
127 setIconAnimationRunningForChild(running, expandedChild);
Selim Cinek8d490d42015-04-10 00:05:50 -0700128 setIconAnimationRunningForChild(running, headsUpChild);
Selim Cinekcab4a602014-09-03 14:47:57 +0200129 }
130 }
131
132 private void setIconAnimationRunningForChild(boolean running, View child) {
133 if (child != null) {
134 ImageView icon = (ImageView) child.findViewById(com.android.internal.R.id.icon);
135 setIconRunning(icon, running);
136 ImageView rightIcon = (ImageView) child.findViewById(
137 com.android.internal.R.id.right_icon);
138 setIconRunning(rightIcon, running);
139 }
140 }
141
142 private void setIconRunning(ImageView imageView, boolean running) {
143 if (imageView != null) {
144 Drawable drawable = imageView.getDrawable();
145 if (drawable instanceof AnimationDrawable) {
146 AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
147 if (running) {
148 animationDrawable.start();
149 } else {
150 animationDrawable.stop();
151 }
152 } else if (drawable instanceof AnimatedVectorDrawable) {
153 AnimatedVectorDrawable animationDrawable = (AnimatedVectorDrawable) drawable;
154 if (running) {
155 animationDrawable.start();
156 } else {
157 animationDrawable.stop();
158 }
159 }
160 }
161 }
162
Selim Cinekeef84282015-10-30 16:28:00 -0700163 private void setStatusBarNotification(StatusBarNotification statusBarNotification) {
Jorim Jaggib1cd3c12014-09-08 19:55:17 +0200164 mStatusBarNotification = statusBarNotification;
Selim Cinek83bc7832015-10-22 13:26:54 -0700165 mPrivateLayout.setStatusBarNotification(statusBarNotification);
Selim Cineka37774f2014-11-11 19:16:18 +0100166 updateVetoButton();
Selim Cinek263398f2015-10-21 17:40:23 -0700167 onChildrenCountChanged();
Jorim Jaggib1cd3c12014-09-08 19:55:17 +0200168 }
169
170 public StatusBarNotification getStatusBarNotification() {
171 return mStatusBarNotification;
172 }
173
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700174 public boolean isHeadsUp() {
175 return mIsHeadsUp;
176 }
177
Selim Cinek1a521f32014-11-03 17:39:29 +0100178 public void setHeadsUp(boolean isHeadsUp) {
Selim Cinekc80fdb12015-04-13 15:09:08 -0700179 int intrinsicBefore = getIntrinsicHeight();
Selim Cinek1a521f32014-11-03 17:39:29 +0100180 mIsHeadsUp = isHeadsUp;
Selim Cinek8d490d42015-04-10 00:05:50 -0700181 mPrivateLayout.setHeadsUp(isHeadsUp);
Selim Cinekc80fdb12015-04-13 15:09:08 -0700182 if (intrinsicBefore != getIntrinsicHeight()) {
183 notifyHeightChanged(false /* needsAnimation */);
184 }
Selim Cinek1a521f32014-11-03 17:39:29 +0100185 }
186
Selim Cinekb5605e52015-02-20 18:21:41 +0100187 public void setGroupManager(NotificationGroupManager groupManager) {
188 mGroupManager = groupManager;
Selim Cinek83bc7832015-10-22 13:26:54 -0700189 mPrivateLayout.setGroupManager(groupManager);
Selim Cinekb5605e52015-02-20 18:21:41 +0100190 }
191
192 public void addChildNotification(ExpandableNotificationRow row) {
193 addChildNotification(row, -1);
194 }
195
196 /**
197 * Add a child notification to this view.
198 *
199 * @param row the row to add
200 * @param childIndex the index to add it at, if -1 it will be added at the end
201 */
202 public void addChildNotification(ExpandableNotificationRow row, int childIndex) {
203 if (mChildrenContainer == null) {
204 mChildrenContainerStub.inflate();
205 }
206 mChildrenContainer.addNotification(row, childIndex);
Selim Cinek263398f2015-10-21 17:40:23 -0700207 onChildrenCountChanged();
208 row.setIsChildInGroup(true, this);
Selim Cinekb5605e52015-02-20 18:21:41 +0100209 }
210
211 public void removeChildNotification(ExpandableNotificationRow row) {
212 if (mChildrenContainer != null) {
213 mChildrenContainer.removeNotification(row);
214 }
Selim Cinek263398f2015-10-21 17:40:23 -0700215 onChildrenCountChanged();
216 row.setIsChildInGroup(false, null);
217 }
218
219 public boolean isChildInGroup() {
220 return mChildInGroup;
221 }
222
223 /**
224 * @param isChildInGroup Is this notification now in a group
225 * @param parent the new parent notification
226 */
227 public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {
228 mChildInGroup = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
Selim Cinek34d93b02015-10-22 12:30:38 -0700229 mShowNoBackground = mChildInGroup && hasSameBgColor(parent);
Selim Cinek83bc7832015-10-22 13:26:54 -0700230 mPrivateLayout.setIsChildInGroup(mShowNoBackground);
Selim Cinek34d93b02015-10-22 12:30:38 -0700231 updateBackground();
232 }
233
234 @Override
235 protected boolean shouldHideBackground() {
236 return super.shouldHideBackground() || mShowNoBackground;
Selim Cinek263398f2015-10-21 17:40:23 -0700237 }
238
239 @Override
240 public boolean isSummaryWithChildren() {
241 return mIsSummaryWithChildren;
Selim Cinekb5605e52015-02-20 18:21:41 +0100242 }
243
244 @Override
245 public boolean areChildrenExpanded() {
246 return mChildrenExpanded;
247 }
248
249 public List<ExpandableNotificationRow> getNotificationChildren() {
250 return mChildrenContainer == null ? null : mChildrenContainer.getNotificationChildren();
251 }
252
Selim Cinekeef84282015-10-30 16:28:00 -0700253 public int getNumberOfNotificationChildren() {
254 if (mChildrenContainer == null) {
255 return 0;
256 }
257 return mChildrenContainer.getNotificationChildren().size();
258 }
259
Selim Cinekb5605e52015-02-20 18:21:41 +0100260 /**
261 * Apply the order given in the list to the children.
262 *
263 * @param childOrder the new list order
264 * @return whether the list order has changed
265 */
266 public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder) {
267 return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder);
268 }
269
270 public void getChildrenStates(StackScrollState resultState) {
Selim Cinek83bc7832015-10-22 13:26:54 -0700271 if (mIsSummaryWithChildren) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100272 StackViewState parentState = resultState.getViewStateForView(this);
273 mChildrenContainer.getState(resultState, parentState);
274 }
275 }
276
277 public void applyChildrenState(StackScrollState state) {
Selim Cinek83bc7832015-10-22 13:26:54 -0700278 if (mIsSummaryWithChildren) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100279 mChildrenContainer.applyState(state);
280 }
281 }
282
283 public void prepareExpansionChanged(StackScrollState state) {
Selim Cinek83bc7832015-10-22 13:26:54 -0700284 if (mIsSummaryWithChildren) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100285 mChildrenContainer.prepareExpansionChanged(state);
286 }
287 }
288
289 public void startChildAnimation(StackScrollState finalState,
290 StackStateAnimator stateAnimator, boolean withDelays, long delay, long duration) {
Selim Cinek83bc7832015-10-22 13:26:54 -0700291 if (mIsSummaryWithChildren) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100292 mChildrenContainer.startAnimationToState(finalState, stateAnimator, withDelays, delay,
293 duration);
294 }
295 }
296
297 public ExpandableNotificationRow getViewAtPosition(float y) {
Selim Cinek83bc7832015-10-22 13:26:54 -0700298 if (!mIsSummaryWithChildren || !mChildrenExpanded) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100299 return this;
300 } else {
301 ExpandableNotificationRow view = mChildrenContainer.getViewAtPosition(y);
302 return view == null ? this : view;
303 }
304 }
305
Selim Cinekab29aeb2015-02-20 18:18:32 +0100306 public NotificationGuts getGuts() {
307 return mGuts;
308 }
309
Selim Cinek684a4422015-04-15 16:18:39 -0700310 /**
311 * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
312 * the notification will be rendered on top of the screen.
313 *
314 * @param pinned whether it is pinned
315 */
316 public void setPinned(boolean pinned) {
317 mIsPinned = pinned;
Selim Cinek98713a42015-09-21 15:47:20 +0200318 setChronometerRunning(mLastChronometerRunning);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700319 }
320
Selim Cinek684a4422015-04-15 16:18:39 -0700321 public boolean isPinned() {
322 return mIsPinned;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700323 }
324
325 public int getHeadsUpHeight() {
Selim Cinek8d490d42015-04-10 00:05:50 -0700326 return mHeadsUpHeight;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700327 }
328
Jorim Jaggi5eb67c22015-08-19 19:50:49 -0700329 /**
330 * Mark whether this notification was just clicked, i.e. the user has just clicked this
331 * notification in this frame.
332 */
333 public void setJustClicked(boolean justClicked) {
334 mJustClicked = justClicked;
335 }
336
337 /**
338 * @return true if this notification has been clicked in this frame, false otherwise
339 */
340 public boolean wasJustClicked() {
341 return mJustClicked;
342 }
343
Selim Cinek98713a42015-09-21 15:47:20 +0200344 public void setChronometerRunning(boolean running) {
345 mLastChronometerRunning = running;
346 setChronometerRunning(running, mPrivateLayout);
347 setChronometerRunning(running, mPublicLayout);
348 if (mChildrenContainer != null) {
349 List<ExpandableNotificationRow> notificationChildren =
350 mChildrenContainer.getNotificationChildren();
351 for (int i = 0; i < notificationChildren.size(); i++) {
352 ExpandableNotificationRow child = notificationChildren.get(i);
353 child.setChronometerRunning(running);
354 }
355 }
356 }
357
358 private void setChronometerRunning(boolean running, NotificationContentView layout) {
359 if (layout != null) {
360 running = running || isPinned();
361 View contractedChild = layout.getContractedChild();
362 View expandedChild = layout.getExpandedChild();
363 View headsUpChild = layout.getHeadsUpChild();
364 setChronometerRunningForChild(running, contractedChild);
365 setChronometerRunningForChild(running, expandedChild);
366 setChronometerRunningForChild(running, headsUpChild);
367 }
368 }
369
370 private void setChronometerRunningForChild(boolean running, View child) {
371 if (child != null) {
372 View chronometer = child.findViewById(com.android.internal.R.id.chronometer);
373 if (chronometer instanceof Chronometer) {
374 ((Chronometer) chronometer).setStarted(running);
375 }
376 }
377 }
378
Selim Cinekeef84282015-10-30 16:28:00 -0700379 public void setEntry(NotificationData.Entry entry) {
380 mEntry = entry;
381 setStatusBarNotification(entry.notification);
382 }
383
Selim Cinek8d6440d2015-10-22 13:00:05 -0700384 public CharSequence getSubText() {
385 Notification notification = mStatusBarNotification.getNotification();
386 CharSequence subText = notification.extras.getCharSequence(Notification.EXTRA_SUMMARY_TEXT);
387 if (subText == null) {
388 subText = notification.extras.getCharSequence(Notification.EXTRA_SUB_TEXT);
389 }
390 return subText;
391 }
392
393 public void setContentSubTextVisible(boolean visible) {
394 mPrivateLayout.setSubTextVisible(visible);
395 }
396
Chris Wren78403d72014-07-28 10:23:24 +0100397 public interface ExpansionLogger {
398 public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
399 }
Selim Cinek1685e632014-04-08 02:27:49 +0200400
Chris Wren51c75102013-07-16 20:49:17 -0400401 public ExpandableNotificationRow(Context context, AttributeSet attrs) {
402 super(context, attrs);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700403 mFalsingManager = FalsingManager.getInstance(context);
Chris Wren51c75102013-07-16 20:49:17 -0400404 }
405
Christoph Studera7fe6312014-06-27 19:32:44 +0200406 /**
407 * Resets this view so it can be re-used for an updated notification.
408 */
Christoph Studer22f2ee52014-07-29 22:57:21 +0200409 @Override
Christoph Studera7fe6312014-06-27 19:32:44 +0200410 public void reset() {
Christoph Studer22f2ee52014-07-29 22:57:21 +0200411 super.reset();
Christoph Studera7fe6312014-06-27 19:32:44 +0200412 mRowMinHeight = 0;
Chris Wren78403d72014-07-28 10:23:24 +0100413 final boolean wasExpanded = isExpanded();
Selim Cinek379ff8f2015-02-20 17:03:16 +0100414 mMaxViewHeight = 0;
Christoph Studera7fe6312014-06-27 19:32:44 +0200415 mExpandable = false;
416 mHasUserChangedExpansion = false;
417 mUserLocked = false;
418 mShowingPublic = false;
Jorim Jaggiae441282014-08-01 02:45:18 +0200419 mSensitive = false;
420 mShowingPublicInitialized = false;
Christoph Studera7fe6312014-06-27 19:32:44 +0200421 mIsSystemExpanded = false;
Selim Cinek83bc7832015-10-22 13:26:54 -0700422 mOnKeyguard = false;
Selim Cinek1a521f32014-11-03 17:39:29 +0100423 mPublicLayout.reset(mIsHeadsUp);
424 mPrivateLayout.reset(mIsHeadsUp);
Selim Cinek31094df2014-08-14 19:28:15 +0200425 resetHeight();
426 logExpansionEvent(false, wasExpanded);
427 }
428
429 public void resetHeight() {
Selim Cinek1a521f32014-11-03 17:39:29 +0100430 if (mIsHeadsUp) {
431 resetActualHeight();
432 }
Christoph Studera7fe6312014-06-27 19:32:44 +0200433 mMaxExpandHeight = 0;
Selim Cinek8d490d42015-04-10 00:05:50 -0700434 mHeadsUpHeight = 0;
Selim Cineka5e211b2014-08-11 17:35:48 +0200435 mWasReset = true;
Selim Cinek31094df2014-08-14 19:28:15 +0200436 onHeightReset();
Selim Cinek6e28a672014-09-05 14:43:28 +0200437 requestLayout();
Christoph Studera7fe6312014-06-27 19:32:44 +0200438 }
439
Jorim Jaggi251957d2014-04-09 04:24:09 +0200440 @Override
Selim Cinek1a521f32014-11-03 17:39:29 +0100441 protected boolean filterMotionEvent(MotionEvent event) {
442 return mIsHeadsUp || super.filterMotionEvent(event);
443 }
444
445 @Override
Jorim Jaggi251957d2014-04-09 04:24:09 +0200446 protected void onFinishInflate() {
447 super.onFinishInflate();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200448 mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
449 mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
Selim Cinekab29aeb2015-02-20 18:18:32 +0100450 mGutsStub = (ViewStub) findViewById(R.id.notification_guts_stub);
451 mGutsStub.setOnInflateListener(new ViewStub.OnInflateListener() {
Jorim Jaggib1cd3c12014-09-08 19:55:17 +0200452 @Override
453 public void onInflate(ViewStub stub, View inflated) {
454 mGuts = (NotificationGuts) inflated;
455 mGuts.setClipTopAmount(getClipTopAmount());
456 mGuts.setActualHeight(getActualHeight());
Selim Cinekab29aeb2015-02-20 18:18:32 +0100457 mGutsStub = null;
Jorim Jaggib1cd3c12014-09-08 19:55:17 +0200458 }
459 });
Selim Cinekeef84282015-10-30 16:28:00 -0700460 mNotificationHeaderStub = (ViewStub) findViewById(R.id.notification_header_stub);
461 mNotificationHeaderStub.setOnInflateListener(new ViewStub.OnInflateListener() {
Selim Cinekb5605e52015-02-20 18:21:41 +0100462 @Override
463 public void onInflate(ViewStub stub, View inflated) {
Selim Cinekeef84282015-10-30 16:28:00 -0700464 mNotificationHeader = (NotificationHeaderView) inflated;
465 mNotificationHeader.setGroupManager(mGroupManager);
466 mNotificationHeader.bind(mEntry);
Selim Cinekb5605e52015-02-20 18:21:41 +0100467 }
468 });
469 mChildrenContainerStub = (ViewStub) findViewById(R.id.child_container_stub);
470 mChildrenContainerStub.setOnInflateListener(new ViewStub.OnInflateListener() {
471
472 @Override
473 public void onInflate(ViewStub stub, View inflated) {
474 mChildrenContainer = (NotificationChildrenContainer) inflated;
Selim Cinekb5605e52015-02-20 18:21:41 +0100475 }
476 });
Selim Cinek863834b2014-05-20 04:20:25 +0200477 mVetoButton = findViewById(R.id.veto);
Jorim Jaggife40f7d2014-04-28 15:20:04 +0200478 }
479
Selim Cinekab29aeb2015-02-20 18:18:32 +0100480 public void inflateGuts() {
481 if (mGuts == null) {
482 mGutsStub.inflate();
483 }
484 }
485
Selim Cinekb5605e52015-02-20 18:21:41 +0100486 private void updateChildrenVisibility(boolean animated) {
487 if (mChildrenContainer == null) {
488 return;
489 }
Selim Cinekeef84282015-10-30 16:28:00 -0700490 mChildrenContainer.setVisibility(mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
491 mPrivateLayout.setVisibility(!mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
Selim Cinekb5605e52015-02-20 18:21:41 +0100492 }
493
Jorim Jaggife40f7d2014-04-28 15:20:04 +0200494 @Override
Alan Viverettea54956a2015-01-07 16:05:02 -0800495 public boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
496 if (super.onRequestSendAccessibilityEventInternal(child, event)) {
Jorim Jaggife40f7d2014-04-28 15:20:04 +0200497 // Add a record for the entire layout since its content is somehow small.
498 // The event comes from a leaf view that is interacted with.
499 AccessibilityEvent record = AccessibilityEvent.obtain();
500 onInitializeAccessibilityEvent(record);
501 dispatchPopulateAccessibilityEvent(record);
502 event.appendRecord(record);
503 return true;
504 }
505 return false;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200506 }
Chris Wren51c75102013-07-16 20:49:17 -0400507
John Spurlocke15452b2014-08-21 09:44:39 -0400508 @Override
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100509 public void setDark(boolean dark, boolean fade, long delay) {
510 super.setDark(dark, fade, delay);
John Spurlocke15452b2014-08-21 09:44:39 -0400511 final NotificationContentView showing = getShowingLayout();
512 if (showing != null) {
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100513 showing.setDark(dark, fade, delay);
John Spurlocke15452b2014-08-21 09:44:39 -0400514 }
515 }
516
Selim Cinek1685e632014-04-08 02:27:49 +0200517 public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
518 mRowMinHeight = rowMinHeight;
Selim Cinek379ff8f2015-02-20 17:03:16 +0100519 mMaxViewHeight = rowMaxHeight;
Chris Wren51c75102013-07-16 20:49:17 -0400520 }
521
522 public boolean isExpandable() {
523 return mExpandable;
524 }
525
526 public void setExpandable(boolean expandable) {
527 mExpandable = expandable;
528 }
529
Selim Cinek1685e632014-04-08 02:27:49 +0200530 /**
531 * @return whether the user has changed the expansion state
532 */
533 public boolean hasUserChangedExpansion() {
534 return mHasUserChangedExpansion;
535 }
536
Chris Wren51c75102013-07-16 20:49:17 -0400537 public boolean isUserExpanded() {
538 return mUserExpanded;
539 }
540
Selim Cinek1685e632014-04-08 02:27:49 +0200541 /**
542 * Set this notification to be expanded by the user
543 *
544 * @param userExpanded whether the user wants this notification to be expanded
545 */
Chris Wren51c75102013-07-16 20:49:17 -0400546 public void setUserExpanded(boolean userExpanded) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700547 mFalsingManager.setNotificationExpanded();
Christoph Studera7fe6312014-06-27 19:32:44 +0200548 if (userExpanded && !mExpandable) return;
Chris Wren78403d72014-07-28 10:23:24 +0100549 final boolean wasExpanded = isExpanded();
Selim Cinek1685e632014-04-08 02:27:49 +0200550 mHasUserChangedExpansion = true;
Chris Wren51c75102013-07-16 20:49:17 -0400551 mUserExpanded = userExpanded;
Chris Wren78403d72014-07-28 10:23:24 +0100552 logExpansionEvent(true, wasExpanded);
Chris Wren51c75102013-07-16 20:49:17 -0400553 }
554
Selim Cinekccd14fb2014-08-12 18:53:24 +0200555 public void resetUserExpansion() {
556 mHasUserChangedExpansion = false;
557 mUserExpanded = false;
558 }
559
Chris Wren51c75102013-07-16 20:49:17 -0400560 public boolean isUserLocked() {
561 return mUserLocked;
562 }
563
564 public void setUserLocked(boolean userLocked) {
565 mUserLocked = userLocked;
566 }
567
Selim Cinek1685e632014-04-08 02:27:49 +0200568 /**
569 * @return has the system set this notification to be expanded
570 */
571 public boolean isSystemExpanded() {
572 return mIsSystemExpanded;
573 }
574
575 /**
576 * Set this notification to be expanded by the system.
577 *
578 * @param expand whether the system wants this notification to be expanded.
579 */
580 public void setSystemExpanded(boolean expand) {
Selim Cinek31094df2014-08-14 19:28:15 +0200581 if (expand != mIsSystemExpanded) {
582 final boolean wasExpanded = isExpanded();
583 mIsSystemExpanded = expand;
Selim Cinekb5605e52015-02-20 18:21:41 +0100584 notifyHeightChanged(false /* needsAnimation */);
Selim Cinek31094df2014-08-14 19:28:15 +0200585 logExpansionEvent(false, wasExpanded);
Selim Cinek83bc7832015-10-22 13:26:54 -0700586 if (mChildrenContainer != null) {
587 mChildrenContainer.updateGroupOverflow();
588 }
Selim Cinek31094df2014-08-14 19:28:15 +0200589 }
Jorim Jaggidce3c4c2014-04-29 23:12:24 +0200590 }
591
592 /**
Selim Cinek83bc7832015-10-22 13:26:54 -0700593 * @param onKeyguard whether to prevent notification expansion
Jorim Jaggidce3c4c2014-04-29 23:12:24 +0200594 */
Selim Cinek83bc7832015-10-22 13:26:54 -0700595 public void setOnKeyguard(boolean onKeyguard) {
596 if (onKeyguard != mOnKeyguard) {
Selim Cinek31094df2014-08-14 19:28:15 +0200597 final boolean wasExpanded = isExpanded();
Selim Cinek83bc7832015-10-22 13:26:54 -0700598 mOnKeyguard = onKeyguard;
Selim Cinek31094df2014-08-14 19:28:15 +0200599 logExpansionEvent(false, wasExpanded);
600 if (wasExpanded != isExpanded()) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100601 notifyHeightChanged(false /* needsAnimation */);
Selim Cinek31094df2014-08-14 19:28:15 +0200602 }
603 }
Selim Cinek1685e632014-04-08 02:27:49 +0200604 }
605
606 /**
Dan Sandler0d3e62f2014-07-14 17:13:50 -0400607 * @return Can the underlying notification be cleared?
608 */
609 public boolean isClearable() {
Selim Cineka37774f2014-11-11 19:16:18 +0100610 return mStatusBarNotification != null && mStatusBarNotification.isClearable();
Dan Sandler0d3e62f2014-07-14 17:13:50 -0400611 }
612
613 /**
Selim Cinek1685e632014-04-08 02:27:49 +0200614 * Apply an expansion state to the layout.
Selim Cinek1685e632014-04-08 02:27:49 +0200615 */
Jorim Jaggidce3c4c2014-04-29 23:12:24 +0200616 public void applyExpansionToLayout() {
617 boolean expand = isExpanded();
Chris Wren51c75102013-07-16 20:49:17 -0400618 if (expand && mExpandable) {
Selim Cinekeef84282015-10-30 16:28:00 -0700619 setActualHeight(mMaxExpandHeight);
Chris Wren51c75102013-07-16 20:49:17 -0400620 } else {
Selim Cinekeef84282015-10-30 16:28:00 -0700621 setActualHeight(mRowMinHeight);
Chris Wren51c75102013-07-16 20:49:17 -0400622 }
Chris Wren51c75102013-07-16 20:49:17 -0400623 }
Dan Sandlera5e0f412014-01-23 15:11:54 -0500624
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200625 @Override
626 public int getIntrinsicHeight() {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200627 if (isUserLocked()) {
628 return getActualHeight();
629 }
Selim Cinek1685e632014-04-08 02:27:49 +0200630 boolean inExpansionState = isExpanded();
Selim Cinek60122be2015-04-15 18:16:50 -0700631 if (mSensitive && mHideSensitiveForIntrinsicHeight) {
632 return mRowMinHeight;
Selim Cinek83bc7832015-10-22 13:26:54 -0700633 } else if (mIsSummaryWithChildren && !mOnKeyguard) {
634 return mChildrenContainer.getIntrinsicHeight()
635 + mNotificationHeader.getHeight();
Selim Cinek60122be2015-04-15 18:16:50 -0700636 } else if (mIsHeadsUp) {
Selim Cinek8d490d42015-04-10 00:05:50 -0700637 if (inExpansionState) {
Selim Cinek83bc7832015-10-22 13:26:54 -0700638 return Math.max(mMaxExpandHeight, mHeadsUpHeight);
Selim Cinek8d490d42015-04-10 00:05:50 -0700639 } else {
Selim Cinek83bc7832015-10-22 13:26:54 -0700640 return Math.max(mRowMinHeight, mHeadsUpHeight);
Selim Cinek8d490d42015-04-10 00:05:50 -0700641 }
Selim Cinek83bc7832015-10-22 13:26:54 -0700642 } else if (!inExpansionState || (mChildInGroup && !isGroupExpanded())) {
643 return getMinHeight();
Selim Cinekb5605e52015-02-20 18:21:41 +0100644 } else {
Selim Cinek83bc7832015-10-22 13:26:54 -0700645 return getMaxExpandHeight();
Selim Cinek1685e632014-04-08 02:27:49 +0200646 }
Selim Cinekb5605e52015-02-20 18:21:41 +0100647 }
Selim Cinek1685e632014-04-08 02:27:49 +0200648
Selim Cinekeef84282015-10-30 16:28:00 -0700649 private boolean isGroupExpanded() {
650 return mGroupManager.isGroupExpanded(mStatusBarNotification);
Selim Cinekb5605e52015-02-20 18:21:41 +0100651 }
652
Selim Cinekeef84282015-10-30 16:28:00 -0700653 /**
654 * @return whether this view has a header on the top of the content
655 */
656 private boolean hasNotificationHeader() {
657 return mIsSummaryWithChildren;
Selim Cinek1685e632014-04-08 02:27:49 +0200658 }
659
Selim Cinek263398f2015-10-21 17:40:23 -0700660 private void onChildrenCountChanged() {
661 mIsSummaryWithChildren = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS
662 && mGroupManager.hasGroupChildren(mStatusBarNotification);
663 if (mIsSummaryWithChildren && mChildrenContainer == null) {
664 mChildrenContainerStub.inflate();
665 }
Selim Cinekeef84282015-10-30 16:28:00 -0700666 updateNotificationHeader();
Selim Cinek263398f2015-10-21 17:40:23 -0700667 updateChildrenVisibility(true);
668 }
669
Selim Cinek1685e632014-04-08 02:27:49 +0200670 /**
671 * Check whether the view state is currently expanded. This is given by the system in {@link
672 * #setSystemExpanded(boolean)} and can be overridden by user expansion or
673 * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
674 * view can differ from this state, if layout params are modified from outside.
675 *
676 * @return whether the view state is currently expanded.
677 */
Selim Cinek83bc7832015-10-22 13:26:54 -0700678 public boolean isExpanded() {
679 return !mOnKeyguard
Selim Cinekb5605e52015-02-20 18:21:41 +0100680 && (!hasUserChangedExpansion() && (isSystemExpanded() || isSystemChildExpanded())
681 || isUserExpanded());
682 }
683
684 private boolean isSystemChildExpanded() {
685 return mIsSystemChildExpanded;
686 }
687
688 public void setSystemChildExpanded(boolean expanded) {
689 mIsSystemChildExpanded = expanded;
Selim Cinek1685e632014-04-08 02:27:49 +0200690 }
691
692 @Override
693 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
694 super.onLayout(changed, left, top, right, bottom);
Selim Cineka5e211b2014-08-11 17:35:48 +0200695 boolean updateExpandHeight = mMaxExpandHeight == 0 && !mWasReset;
Selim Cinek8d490d42015-04-10 00:05:50 -0700696 updateMaxHeights();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200697 if (updateExpandHeight) {
Jorim Jaggidce3c4c2014-04-29 23:12:24 +0200698 applyExpansionToLayout();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200699 }
Selim Cineka5e211b2014-08-11 17:35:48 +0200700 mWasReset = false;
Selim Cinek1685e632014-04-08 02:27:49 +0200701 }
702
Selim Cinek8d490d42015-04-10 00:05:50 -0700703 private void updateMaxHeights() {
Selim Cinekd2319fb2014-09-01 19:41:54 +0200704 int intrinsicBefore = getIntrinsicHeight();
Selim Cinek8d490d42015-04-10 00:05:50 -0700705 View expandedChild = mPrivateLayout.getExpandedChild();
706 if (expandedChild == null) {
707 expandedChild = mPrivateLayout.getContractedChild();
708 }
709 mMaxExpandHeight = expandedChild.getHeight();
710 View headsUpChild = mPrivateLayout.getHeadsUpChild();
Selim Cinek1f3f5442015-04-10 17:54:46 -0700711 if (headsUpChild == null) {
712 headsUpChild = mPrivateLayout.getContractedChild();
Selim Cinek8d490d42015-04-10 00:05:50 -0700713 }
Selim Cinek1f3f5442015-04-10 17:54:46 -0700714 mHeadsUpHeight = headsUpChild.getHeight();
Selim Cinekd2319fb2014-09-01 19:41:54 +0200715 if (intrinsicBefore != getIntrinsicHeight()) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100716 notifyHeightChanged(false /* needsAnimation */);
Selim Cinekd2319fb2014-09-01 19:41:54 +0200717 }
718 }
719
Jorim Jaggiae441282014-08-01 02:45:18 +0200720 public void setSensitive(boolean sensitive) {
721 mSensitive = sensitive;
722 }
723
724 public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
Selim Cinek60122be2015-04-15 18:16:50 -0700725 mHideSensitiveForIntrinsicHeight = hideSensitive;
Jorim Jaggiae441282014-08-01 02:45:18 +0200726 }
727
728 public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
729 long duration) {
730 boolean oldShowingPublic = mShowingPublic;
731 mShowingPublic = mSensitive && hideSensitive;
732 if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
733 return;
734 }
Dan Sandlera5e0f412014-01-23 15:11:54 -0500735
736 // bail out if no public version
Selim Cinek1685e632014-04-08 02:27:49 +0200737 if (mPublicLayout.getChildCount() == 0) return;
Dan Sandlera5e0f412014-01-23 15:11:54 -0500738
Jorim Jaggiae441282014-08-01 02:45:18 +0200739 if (!animated) {
740 mPublicLayout.animate().cancel();
741 mPrivateLayout.animate().cancel();
742 mPublicLayout.setAlpha(1f);
743 mPrivateLayout.setAlpha(1f);
744 mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
Selim Cinek263398f2015-10-21 17:40:23 -0700745 mPrivateLayout.setVisibility(!mShowingPublic && !mIsSummaryWithChildren ? View.VISIBLE
746 : View.INVISIBLE);
Jorim Jaggiae441282014-08-01 02:45:18 +0200747 } else {
748 animateShowingPublic(delay, duration);
749 }
Dan Sandler0d3e62f2014-07-14 17:13:50 -0400750
751 updateVetoButton();
Jorim Jaggiae441282014-08-01 02:45:18 +0200752 mShowingPublicInitialized = true;
753 }
754
755 private void animateShowingPublic(long delay, long duration) {
756 final View source = mShowingPublic ? mPrivateLayout : mPublicLayout;
757 View target = mShowingPublic ? mPublicLayout : mPrivateLayout;
758 source.setVisibility(View.VISIBLE);
759 target.setVisibility(View.VISIBLE);
760 target.setAlpha(0f);
761 source.animate().cancel();
762 target.animate().cancel();
763 source.animate()
764 .alpha(0f)
Jorim Jaggiae441282014-08-01 02:45:18 +0200765 .setStartDelay(delay)
766 .setDuration(duration)
767 .withEndAction(new Runnable() {
768 @Override
769 public void run() {
770 source.setVisibility(View.INVISIBLE);
771 }
772 });
773 target.animate()
774 .alpha(1f)
Jorim Jaggiae441282014-08-01 02:45:18 +0200775 .setStartDelay(delay)
776 .setDuration(duration);
Dan Sandler0d3e62f2014-07-14 17:13:50 -0400777 }
778
779 private void updateVetoButton() {
780 // public versions cannot be dismissed
781 mVetoButton.setVisibility(isClearable() && !mShowingPublic ? View.VISIBLE : View.GONE);
Dan Sandlera5e0f412014-01-23 15:11:54 -0500782 }
Jorim Jaggi251957d2014-04-09 04:24:09 +0200783
Selim Cinekb5605e52015-02-20 18:21:41 +0100784 public void setChildrenExpanded(boolean expanded, boolean animate) {
785 mChildrenExpanded = expanded;
Selim Cinek83bc7832015-10-22 13:26:54 -0700786 if (mChildrenContainer != null) {
787 mChildrenContainer.setChildrenExpanded(expanded);
788 }
Selim Cinekb5605e52015-02-20 18:21:41 +0100789 }
790
Selim Cinekeef84282015-10-30 16:28:00 -0700791 public void updateNotificationHeader() {
792 boolean hasHeader = hasNotificationHeader();
793 if (hasHeader != mHasNotificationHeader) {
794 if (hasHeader) {
795 if (mNotificationHeader == null) {
796 mNotificationHeaderStub.inflate();
Selim Cinekb5605e52015-02-20 18:21:41 +0100797 }
Selim Cinekeef84282015-10-30 16:28:00 -0700798 mNotificationHeader.setVisibility(View.VISIBLE);
799 } else if (mNotificationHeader != null) {
800 mNotificationHeader.setVisibility(View.GONE);
Selim Cinekb5605e52015-02-20 18:21:41 +0100801 }
802 notifyHeightChanged(true /* needsAnimation */);
803 }
Selim Cinekeef84282015-10-30 16:28:00 -0700804 if (hasHeader) {
805 mNotificationHeader.bind(mEntry);
Selim Cinekb5605e52015-02-20 18:21:41 +0100806 }
Selim Cinekeef84282015-10-30 16:28:00 -0700807 mHasNotificationHeader = hasHeader;
Selim Cinekb5605e52015-02-20 18:21:41 +0100808 }
809
810 public static void applyTint(View v, int color) {
811 int alpha;
812 if (color != 0) {
813 alpha = COLORED_DIVIDER_ALPHA;
814 } else {
815 color = 0xff000000;
816 alpha = DEFAULT_DIVIDER_ALPHA;
817 }
818 if (v.getBackground() instanceof ColorDrawable) {
819 ColorDrawable background = (ColorDrawable) v.getBackground();
820 background.mutate();
821 background.setColor(color);
822 background.setAlpha(alpha);
823 }
824 }
825
Selim Cinek1685e632014-04-08 02:27:49 +0200826 public int getMaxExpandHeight() {
Selim Cinekb5605e52015-02-20 18:21:41 +0100827 return mMaxExpandHeight;
Chris Wren51c75102013-07-16 20:49:17 -0400828 }
Jorim Jaggi584a7aa2014-04-10 23:26:13 +0200829
Jorim Jaggibe565df2014-04-28 17:51:23 +0200830 @Override
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200831 public boolean isContentExpandable() {
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200832 NotificationContentView showingLayout = getShowingLayout();
833 return showingLayout.isContentExpandable();
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200834 }
835
836 @Override
Selim Cinek560e64d2015-06-09 19:58:11 -0700837 protected View getContentView() {
838 return getShowingLayout();
839 }
840
841 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200842 public void setActualHeight(int height, boolean notifyListeners) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100843 super.setActualHeight(height, notifyListeners);
Selim Cinekeef84282015-10-30 16:28:00 -0700844 int contentHeight = Math.max(getMinHeight(), height);
Selim Cinekb5605e52015-02-20 18:21:41 +0100845 mPrivateLayout.setContentHeight(contentHeight);
846 mPublicLayout.setContentHeight(contentHeight);
Jorim Jaggib1cd3c12014-09-08 19:55:17 +0200847 if (mGuts != null) {
848 mGuts.setActualHeight(height);
849 }
Jorim Jaggibe565df2014-04-28 17:51:23 +0200850 invalidate();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200851 }
852
853 @Override
Selim Cinekb5605e52015-02-20 18:21:41 +0100854 public int getMaxContentHeight() {
Selim Cinek83bc7832015-10-22 13:26:54 -0700855 if (mIsSummaryWithChildren && !mShowingPublic) {
856 return mChildrenContainer.getMaxContentHeight()
857 + mNotificationHeader.getHeight();
858 }
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200859 NotificationContentView showingLayout = getShowingLayout();
860 return showingLayout.getMaxHeight();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200861 }
862
863 @Override
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200864 public int getMinHeight() {
Selim Cinek83bc7832015-10-22 13:26:54 -0700865 if (mIsSummaryWithChildren && !mOnKeyguard) {
866 return mChildrenContainer.getMinHeight()
867 + mNotificationHeader.getHeight();
868 }
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200869 NotificationContentView showingLayout = getShowingLayout();
870 return showingLayout.getMinHeight();
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200871 }
872
873 @Override
Selim Cinek263398f2015-10-21 17:40:23 -0700874 protected boolean shouldLimitViewHeight() {
875 return !mIsSummaryWithChildren;
876 }
877
878 @Override
Jorim Jaggibe565df2014-04-28 17:51:23 +0200879 public void setClipTopAmount(int clipTopAmount) {
880 super.setClipTopAmount(clipTopAmount);
881 mPrivateLayout.setClipTopAmount(clipTopAmount);
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200882 mPublicLayout.setClipTopAmount(clipTopAmount);
Jorim Jaggib1cd3c12014-09-08 19:55:17 +0200883 if (mGuts != null) {
884 mGuts.setClipTopAmount(clipTopAmount);
885 }
Jorim Jaggibe565df2014-04-28 17:51:23 +0200886 }
887
888 public void notifyContentUpdated() {
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200889 mPublicLayout.notifyContentUpdated();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200890 mPrivateLayout.notifyContentUpdated();
Selim Cinek343e6e22014-04-11 21:23:30 +0200891 }
Selim Cinek7d447722014-06-10 15:51:59 +0200892
Selim Cinek31094df2014-08-14 19:28:15 +0200893 public boolean isMaxExpandHeightInitialized() {
894 return mMaxExpandHeight != 0;
Selim Cinek7d447722014-06-10 15:51:59 +0200895 }
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200896
897 private NotificationContentView getShowingLayout() {
898 return mShowingPublic ? mPublicLayout : mPrivateLayout;
899 }
Chris Wren78403d72014-07-28 10:23:24 +0100900
Jorim Jaggi59ec3042015-06-05 15:18:43 -0700901 @Override
902 public void setShowingLegacyBackground(boolean showing) {
903 super.setShowingLegacyBackground(showing);
904 mPrivateLayout.setShowingLegacyBackground(showing);
905 mPublicLayout.setShowingLegacyBackground(showing);
906 }
907
Chris Wren78403d72014-07-28 10:23:24 +0100908 public void setExpansionLogger(ExpansionLogger logger, String key) {
909 mLogger = logger;
910 mLoggingKey = key;
911 }
912
Chris Wren78403d72014-07-28 10:23:24 +0100913 private void logExpansionEvent(boolean userAction, boolean wasExpanded) {
914 final boolean nowExpanded = isExpanded();
915 if (wasExpanded != nowExpanded && mLogger != null) {
916 mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded) ;
917 }
918 }
Chris Wren51c75102013-07-16 20:49:17 -0400919}