blob: 5bad60205dc68851a7b56747dcd7710473d73853 [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;
20import android.util.AttributeSet;
Dan Sandlera5e0f412014-01-23 15:11:54 -050021import android.view.View;
Jorim Jaggife40f7d2014-04-28 15:20:04 +020022import android.view.accessibility.AccessibilityEvent;
Chris Wren51c75102013-07-16 20:49:17 -040023
Dan Sandlera5e0f412014-01-23 15:11:54 -050024import com.android.systemui.R;
25
Jorim Jaggi4222d9a2014-04-23 16:13:15 +020026public class ExpandableNotificationRow extends ActivatableNotificationView {
Selim Cinek1685e632014-04-08 02:27:49 +020027 private int mRowMinHeight;
28 private int mRowMaxHeight;
Chris Wren51c75102013-07-16 20:49:17 -040029
Selim Cinek1685e632014-04-08 02:27:49 +020030 /** Does this row contain layouts that can adapt to row expansion */
Chris Wren51c75102013-07-16 20:49:17 -040031 private boolean mExpandable;
Selim Cinek1685e632014-04-08 02:27:49 +020032 /** Has the user actively changed the expansion state of this row */
33 private boolean mHasUserChangedExpansion;
34 /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
Chris Wren51c75102013-07-16 20:49:17 -040035 private boolean mUserExpanded;
Selim Cinek1685e632014-04-08 02:27:49 +020036 /** Is the user touching this row */
Chris Wren51c75102013-07-16 20:49:17 -040037 private boolean mUserLocked;
Selim Cinek1685e632014-04-08 02:27:49 +020038 /** Are we showing the "public" version */
Dan Sandlera5e0f412014-01-23 15:11:54 -050039 private boolean mShowingPublic;
Chris Wren51c75102013-07-16 20:49:17 -040040
Selim Cinek1685e632014-04-08 02:27:49 +020041 /**
42 * Is this notification expanded by the system. The expansion state can be overridden by the
43 * user expansion.
44 */
45 private boolean mIsSystemExpanded;
Jorim Jaggidce3c4c2014-04-29 23:12:24 +020046
47 /**
48 * Whether the notification expansion is disabled. This is the case on Keyguard.
49 */
50 private boolean mExpansionDisabled;
51
Jorim Jaggibe565df2014-04-28 17:51:23 +020052 private NotificationContentView mPublicLayout;
53 private NotificationContentView mPrivateLayout;
Selim Cinek1685e632014-04-08 02:27:49 +020054 private int mMaxExpandHeight;
Selim Cinekc27437b2014-05-14 10:23:33 +020055 private boolean mIsBelowSpeedBump;
Selim Cinek863834b2014-05-20 04:20:25 +020056 private View mVetoButton;
Selim Cinek1685e632014-04-08 02:27:49 +020057
Chris Wren51c75102013-07-16 20:49:17 -040058 public ExpandableNotificationRow(Context context, AttributeSet attrs) {
59 super(context, attrs);
60 }
61
Jorim Jaggi251957d2014-04-09 04:24:09 +020062 @Override
63 protected void onFinishInflate() {
64 super.onFinishInflate();
Jorim Jaggibe565df2014-04-28 17:51:23 +020065 mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
66 mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
Selim Cinek863834b2014-05-20 04:20:25 +020067 mVetoButton = findViewById(R.id.veto);
Jorim Jaggife40f7d2014-04-28 15:20:04 +020068 }
69
70 @Override
71 public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
72 if (super.onRequestSendAccessibilityEvent(child, event)) {
73 // Add a record for the entire layout since its content is somehow small.
74 // The event comes from a leaf view that is interacted with.
75 AccessibilityEvent record = AccessibilityEvent.obtain();
76 onInitializeAccessibilityEvent(record);
77 dispatchPopulateAccessibilityEvent(record);
78 event.appendRecord(record);
79 return true;
80 }
81 return false;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +020082 }
Chris Wren51c75102013-07-16 20:49:17 -040083
Selim Cinek1685e632014-04-08 02:27:49 +020084 public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
85 mRowMinHeight = rowMinHeight;
86 mRowMaxHeight = rowMaxHeight;
Chris Wren51c75102013-07-16 20:49:17 -040087 }
88
89 public boolean isExpandable() {
90 return mExpandable;
91 }
92
93 public void setExpandable(boolean expandable) {
94 mExpandable = expandable;
95 }
96
Selim Cinek1685e632014-04-08 02:27:49 +020097 /**
98 * @return whether the user has changed the expansion state
99 */
100 public boolean hasUserChangedExpansion() {
101 return mHasUserChangedExpansion;
102 }
103
Chris Wren51c75102013-07-16 20:49:17 -0400104 public boolean isUserExpanded() {
105 return mUserExpanded;
106 }
107
Selim Cinek1685e632014-04-08 02:27:49 +0200108 /**
109 * Set this notification to be expanded by the user
110 *
111 * @param userExpanded whether the user wants this notification to be expanded
112 */
Chris Wren51c75102013-07-16 20:49:17 -0400113 public void setUserExpanded(boolean userExpanded) {
Selim Cinek1685e632014-04-08 02:27:49 +0200114 mHasUserChangedExpansion = true;
Chris Wren51c75102013-07-16 20:49:17 -0400115 mUserExpanded = userExpanded;
116 }
117
118 public boolean isUserLocked() {
119 return mUserLocked;
120 }
121
122 public void setUserLocked(boolean userLocked) {
123 mUserLocked = userLocked;
124 }
125
Selim Cinek1685e632014-04-08 02:27:49 +0200126 /**
127 * @return has the system set this notification to be expanded
128 */
129 public boolean isSystemExpanded() {
130 return mIsSystemExpanded;
131 }
132
133 /**
134 * Set this notification to be expanded by the system.
135 *
136 * @param expand whether the system wants this notification to be expanded.
137 */
138 public void setSystemExpanded(boolean expand) {
139 mIsSystemExpanded = expand;
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200140 notifyHeightChanged();
Jorim Jaggidce3c4c2014-04-29 23:12:24 +0200141 }
142
143 /**
144 * @param expansionDisabled whether to prevent notification expansion
145 */
146 public void setExpansionDisabled(boolean expansionDisabled) {
147 mExpansionDisabled = expansionDisabled;
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200148 notifyHeightChanged();
Selim Cinek1685e632014-04-08 02:27:49 +0200149 }
150
151 /**
152 * Apply an expansion state to the layout.
Selim Cinek1685e632014-04-08 02:27:49 +0200153 */
Jorim Jaggidce3c4c2014-04-29 23:12:24 +0200154 public void applyExpansionToLayout() {
155 boolean expand = isExpanded();
Chris Wren51c75102013-07-16 20:49:17 -0400156 if (expand && mExpandable) {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200157 setActualHeight(mMaxExpandHeight);
Chris Wren51c75102013-07-16 20:49:17 -0400158 } else {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200159 setActualHeight(mRowMinHeight);
Chris Wren51c75102013-07-16 20:49:17 -0400160 }
Chris Wren51c75102013-07-16 20:49:17 -0400161 }
Dan Sandlera5e0f412014-01-23 15:11:54 -0500162
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200163 @Override
164 public int getIntrinsicHeight() {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200165 if (isUserLocked()) {
166 return getActualHeight();
167 }
Selim Cinek1685e632014-04-08 02:27:49 +0200168 boolean inExpansionState = isExpanded();
169 if (!inExpansionState) {
170 // not expanded, so we return the collapsed size
171 return mRowMinHeight;
172 }
173
174 return mShowingPublic ? mRowMinHeight : getMaxExpandHeight();
175 }
176
Selim Cinek1685e632014-04-08 02:27:49 +0200177 /**
178 * Check whether the view state is currently expanded. This is given by the system in {@link
179 * #setSystemExpanded(boolean)} and can be overridden by user expansion or
180 * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
181 * view can differ from this state, if layout params are modified from outside.
182 *
183 * @return whether the view state is currently expanded.
184 */
185 private boolean isExpanded() {
Jorim Jaggidce3c4c2014-04-29 23:12:24 +0200186 return !mExpansionDisabled
187 && (!hasUserChangedExpansion() && isSystemExpanded() || isUserExpanded());
Selim Cinek1685e632014-04-08 02:27:49 +0200188 }
189
190 @Override
191 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
192 super.onLayout(changed, left, top, right, bottom);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200193 boolean updateExpandHeight = mMaxExpandHeight == 0;
194 mMaxExpandHeight = mPrivateLayout.getMaxHeight();
195 if (updateExpandHeight) {
Jorim Jaggidce3c4c2014-04-29 23:12:24 +0200196 applyExpansionToLayout();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200197 }
Selim Cinek1685e632014-04-08 02:27:49 +0200198 }
199
Dan Sandlera5e0f412014-01-23 15:11:54 -0500200 public void setShowingPublic(boolean show) {
201 mShowingPublic = show;
Dan Sandlera5e0f412014-01-23 15:11:54 -0500202
203 // bail out if no public version
Selim Cinek1685e632014-04-08 02:27:49 +0200204 if (mPublicLayout.getChildCount() == 0) return;
Dan Sandlera5e0f412014-01-23 15:11:54 -0500205
206 // TODO: animation?
Selim Cinek1685e632014-04-08 02:27:49 +0200207 mPublicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
208 mPrivateLayout.setVisibility(show ? View.GONE : View.VISIBLE);
Dan Sandlera5e0f412014-01-23 15:11:54 -0500209 }
Jorim Jaggi251957d2014-04-09 04:24:09 +0200210
Selim Cinek1685e632014-04-08 02:27:49 +0200211 public int getMaxExpandHeight() {
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200212 return mShowingPublic ? mRowMinHeight : mMaxExpandHeight;
Chris Wren51c75102013-07-16 20:49:17 -0400213 }
Jorim Jaggi584a7aa2014-04-10 23:26:13 +0200214
Selim Cinek343e6e22014-04-11 21:23:30 +0200215 /**
216 * @return the potential height this view could expand in addition.
217 */
218 public int getExpandPotential() {
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200219 return getIntrinsicHeight() - getActualHeight();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200220 }
221
222 @Override
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200223 public boolean isContentExpandable() {
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200224 NotificationContentView showingLayout = getShowingLayout();
225 return showingLayout.isContentExpandable();
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200226 }
227
228 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200229 public void setActualHeight(int height, boolean notifyListeners) {
Selim Cinekc9c00ae2014-05-20 03:33:40 +0200230 mPrivateLayout.setActualHeight(height);
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200231 mPublicLayout.setActualHeight(height);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200232 invalidate();
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200233 super.setActualHeight(height, notifyListeners);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200234 }
235
236 @Override
237 public int getMaxHeight() {
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200238 NotificationContentView showingLayout = getShowingLayout();
239 return showingLayout.getMaxHeight();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200240 }
241
242 @Override
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200243 public int getMinHeight() {
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200244 NotificationContentView showingLayout = getShowingLayout();
245 return showingLayout.getMinHeight();
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200246 }
247
248 @Override
Jorim Jaggibe565df2014-04-28 17:51:23 +0200249 public void setClipTopAmount(int clipTopAmount) {
250 super.setClipTopAmount(clipTopAmount);
251 mPrivateLayout.setClipTopAmount(clipTopAmount);
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200252 mPublicLayout.setClipTopAmount(clipTopAmount);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200253 }
254
Selim Cinekc27437b2014-05-14 10:23:33 +0200255 public boolean isBelowSpeedBump() {
256 return mIsBelowSpeedBump;
257 }
258
259 public void setIsBelowSpeedBump(boolean isBelow) {
260 this.mIsBelowSpeedBump = isBelow;
261 }
262
Jorim Jaggibe565df2014-04-28 17:51:23 +0200263 public void notifyContentUpdated() {
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200264 mPublicLayout.notifyContentUpdated();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200265 mPrivateLayout.notifyContentUpdated();
Selim Cinek343e6e22014-04-11 21:23:30 +0200266 }
Selim Cinek7d447722014-06-10 15:51:59 +0200267
268 public boolean isShowingLayoutLayouted() {
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200269 NotificationContentView showingLayout = getShowingLayout();
Selim Cinek7d447722014-06-10 15:51:59 +0200270 return showingLayout.getWidth() != 0;
271 }
Selim Cinek2f0df8a2014-06-10 17:40:42 +0200272
273 private NotificationContentView getShowingLayout() {
274 return mShowingPublic ? mPublicLayout : mPrivateLayout;
275 }
Chris Wren51c75102013-07-16 20:49:17 -0400276}