blob: e5512a3655b13209e947cdfa69e8889fb08e3f5e [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;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +020055 private NotificationActivator mActivator;
Selim Cinek1685e632014-04-08 02:27:49 +020056
Chris Wren51c75102013-07-16 20:49:17 -040057 public ExpandableNotificationRow(Context context, AttributeSet attrs) {
58 super(context, attrs);
59 }
60
Jorim Jaggi251957d2014-04-09 04:24:09 +020061 @Override
62 protected void onFinishInflate() {
63 super.onFinishInflate();
Jorim Jaggibe565df2014-04-28 17:51:23 +020064 mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
65 mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
Jorim Jaggi251957d2014-04-09 04:24:09 +020066
Jorim Jaggiecbab362014-04-23 16:13:15 +020067 mActivator = new NotificationActivator(this, this);
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
211 /**
212 * Sets the notification as dimmed, meaning that it will appear in a more gray variant.
213 */
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200214 @Override
215 public void setDimmed(boolean dimmed, boolean fade) {
216 super.setDimmed(dimmed, fade);
217 mActivator.setDimmed(dimmed, fade);
Jorim Jaggi251957d2014-04-09 04:24:09 +0200218 }
219
Selim Cinek1685e632014-04-08 02:27:49 +0200220 public int getMaxExpandHeight() {
Selim Cinek1685e632014-04-08 02:27:49 +0200221 return mMaxExpandHeight;
Chris Wren51c75102013-07-16 20:49:17 -0400222 }
Jorim Jaggi584a7aa2014-04-10 23:26:13 +0200223
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200224 public NotificationActivator getActivator() {
225 return mActivator;
226 }
227
Selim Cinek343e6e22014-04-11 21:23:30 +0200228 /**
229 * @return the potential height this view could expand in addition.
230 */
231 public int getExpandPotential() {
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200232 return getIntrinsicHeight() - getActualHeight();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200233 }
234
235 @Override
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200236 public boolean isContentExpandable() {
237 return mPrivateLayout.isContentExpandable();
238 }
239
240 @Override
Jorim Jaggibe565df2014-04-28 17:51:23 +0200241 public void setActualHeight(int height) {
242 mPrivateLayout.setActualHeight(height);
243 invalidate();
244 super.setActualHeight(height);
245 }
246
247 @Override
248 public int getMaxHeight() {
249 return mPrivateLayout.getMaxHeight();
250 }
251
252 @Override
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200253 public int getMinHeight() {
254 return mPrivateLayout.getMinHeight();
255 }
256
257 @Override
Jorim Jaggibe565df2014-04-28 17:51:23 +0200258 public void setClipTopAmount(int clipTopAmount) {
259 super.setClipTopAmount(clipTopAmount);
260 mPrivateLayout.setClipTopAmount(clipTopAmount);
261 }
262
263 public void notifyContentUpdated() {
264 mPrivateLayout.notifyContentUpdated();
Selim Cinek343e6e22014-04-11 21:23:30 +0200265 }
Chris Wren51c75102013-07-16 20:49:17 -0400266}