blob: b813e65736394dbebf54ceb123eaa9191f51f520 [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;
Jorim Jaggibe565df2014-04-28 17:51:23 +020020import android.graphics.Canvas;
Chris Wren51c75102013-07-16 20:49:17 -040021import android.util.AttributeSet;
Jorim Jaggibe565df2014-04-28 17:51:23 +020022import android.util.Log;
Dan Sandlera5e0f412014-01-23 15:11:54 -050023import android.view.View;
Jorim Jaggife40f7d2014-04-28 15:20:04 +020024import android.view.accessibility.AccessibilityEvent;
Chris Wren51c75102013-07-16 20:49:17 -040025
Dan Sandlera5e0f412014-01-23 15:11:54 -050026import com.android.systemui.R;
27
Jorim Jaggife40f7d2014-04-28 15:20:04 +020028public class ExpandableNotificationRow extends ActivatableNotificationView {
Selim Cinek1685e632014-04-08 02:27:49 +020029 private int mRowMinHeight;
30 private int mRowMaxHeight;
Chris Wren51c75102013-07-16 20:49:17 -040031
Selim Cinek1685e632014-04-08 02:27:49 +020032 /** Does this row contain layouts that can adapt to row expansion */
Chris Wren51c75102013-07-16 20:49:17 -040033 private boolean mExpandable;
Selim Cinek1685e632014-04-08 02:27:49 +020034 /** Has the user actively changed the expansion state of this row */
35 private boolean mHasUserChangedExpansion;
36 /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
Chris Wren51c75102013-07-16 20:49:17 -040037 private boolean mUserExpanded;
Selim Cinek1685e632014-04-08 02:27:49 +020038 /** Is the user touching this row */
Chris Wren51c75102013-07-16 20:49:17 -040039 private boolean mUserLocked;
Selim Cinek1685e632014-04-08 02:27:49 +020040 /** Are we showing the "public" version */
Dan Sandlera5e0f412014-01-23 15:11:54 -050041 private boolean mShowingPublic;
Chris Wren51c75102013-07-16 20:49:17 -040042
Selim Cinek1685e632014-04-08 02:27:49 +020043 /**
44 * Is this notification expanded by the system. The expansion state can be overridden by the
45 * user expansion.
46 */
47 private boolean mIsSystemExpanded;
Jorim Jaggibe565df2014-04-28 17:51:23 +020048 private NotificationContentView mPublicLayout;
49 private NotificationContentView mPrivateLayout;
Selim Cinek1685e632014-04-08 02:27:49 +020050 private int mMaxExpandHeight;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +020051 private NotificationActivator mActivator;
Selim Cinek1685e632014-04-08 02:27:49 +020052
Chris Wren51c75102013-07-16 20:49:17 -040053 public ExpandableNotificationRow(Context context, AttributeSet attrs) {
54 super(context, attrs);
55 }
56
Jorim Jaggi251957d2014-04-09 04:24:09 +020057 @Override
58 protected void onFinishInflate() {
59 super.onFinishInflate();
Jorim Jaggibe565df2014-04-28 17:51:23 +020060 mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
61 mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
Jorim Jaggi251957d2014-04-09 04:24:09 +020062
Jorim Jaggic5dc0d02014-04-15 15:42:55 +020063 mActivator = new NotificationActivator(this);
Jorim Jaggife40f7d2014-04-28 15:20:04 +020064 }
65
66 @Override
67 public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
68 if (super.onRequestSendAccessibilityEvent(child, event)) {
69 // Add a record for the entire layout since its content is somehow small.
70 // The event comes from a leaf view that is interacted with.
71 AccessibilityEvent record = AccessibilityEvent.obtain();
72 onInitializeAccessibilityEvent(record);
73 dispatchPopulateAccessibilityEvent(record);
74 event.appendRecord(record);
75 return true;
76 }
77 return false;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +020078 }
Chris Wren51c75102013-07-16 20:49:17 -040079
Selim Cinek1685e632014-04-08 02:27:49 +020080 public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
81 mRowMinHeight = rowMinHeight;
82 mRowMaxHeight = rowMaxHeight;
Chris Wren51c75102013-07-16 20:49:17 -040083 }
84
85 public boolean isExpandable() {
86 return mExpandable;
87 }
88
89 public void setExpandable(boolean expandable) {
90 mExpandable = expandable;
91 }
92
Selim Cinek1685e632014-04-08 02:27:49 +020093 /**
94 * @return whether the user has changed the expansion state
95 */
96 public boolean hasUserChangedExpansion() {
97 return mHasUserChangedExpansion;
98 }
99
Chris Wren51c75102013-07-16 20:49:17 -0400100 public boolean isUserExpanded() {
101 return mUserExpanded;
102 }
103
Selim Cinek1685e632014-04-08 02:27:49 +0200104 /**
105 * Set this notification to be expanded by the user
106 *
107 * @param userExpanded whether the user wants this notification to be expanded
108 */
Chris Wren51c75102013-07-16 20:49:17 -0400109 public void setUserExpanded(boolean userExpanded) {
Selim Cinek1685e632014-04-08 02:27:49 +0200110 mHasUserChangedExpansion = true;
Chris Wren51c75102013-07-16 20:49:17 -0400111 mUserExpanded = userExpanded;
112 }
113
114 public boolean isUserLocked() {
115 return mUserLocked;
116 }
117
118 public void setUserLocked(boolean userLocked) {
119 mUserLocked = userLocked;
120 }
121
Selim Cinek1685e632014-04-08 02:27:49 +0200122 /**
123 * @return has the system set this notification to be expanded
124 */
125 public boolean isSystemExpanded() {
126 return mIsSystemExpanded;
127 }
128
129 /**
130 * Set this notification to be expanded by the system.
131 *
132 * @param expand whether the system wants this notification to be expanded.
133 */
134 public void setSystemExpanded(boolean expand) {
135 mIsSystemExpanded = expand;
136 applyExpansionToLayout(expand);
137 }
138
139 /**
140 * Apply an expansion state to the layout.
141 *
142 * @param expand should the layout be in the expanded state
143 */
144 public void applyExpansionToLayout(boolean expand) {
Chris Wren51c75102013-07-16 20:49:17 -0400145 if (expand && mExpandable) {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200146 setActualHeight(mMaxExpandHeight);
Chris Wren51c75102013-07-16 20:49:17 -0400147 } else {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200148 setActualHeight(mRowMinHeight);
Chris Wren51c75102013-07-16 20:49:17 -0400149 }
Chris Wren51c75102013-07-16 20:49:17 -0400150 }
Dan Sandlera5e0f412014-01-23 15:11:54 -0500151
Selim Cinek1685e632014-04-08 02:27:49 +0200152 /**
153 * If {@link #isExpanded()} then this is the greatest possible height this view can
154 * get and otherwise it is {@link #mRowMinHeight}.
155 *
156 * @return the maximum allowed expansion height of this view.
157 */
158 public int getMaximumAllowedExpandHeight() {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200159 if (isUserLocked()) {
160 return getActualHeight();
161 }
Selim Cinek1685e632014-04-08 02:27:49 +0200162 boolean inExpansionState = isExpanded();
163 if (!inExpansionState) {
164 // not expanded, so we return the collapsed size
165 return mRowMinHeight;
166 }
167
168 return mShowingPublic ? mRowMinHeight : getMaxExpandHeight();
169 }
170
Selim Cinek1685e632014-04-08 02:27:49 +0200171 /**
172 * Check whether the view state is currently expanded. This is given by the system in {@link
173 * #setSystemExpanded(boolean)} and can be overridden by user expansion or
174 * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
175 * view can differ from this state, if layout params are modified from outside.
176 *
177 * @return whether the view state is currently expanded.
178 */
179 private boolean isExpanded() {
180 return !hasUserChangedExpansion() && isSystemExpanded() || isUserExpanded();
181 }
182
183 @Override
184 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
185 super.onLayout(changed, left, top, right, bottom);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200186 boolean updateExpandHeight = mMaxExpandHeight == 0;
187 mMaxExpandHeight = mPrivateLayout.getMaxHeight();
188 if (updateExpandHeight) {
189 applyExpansionToLayout(isExpanded());
190 }
Selim Cinek1685e632014-04-08 02:27:49 +0200191 }
192
Dan Sandlera5e0f412014-01-23 15:11:54 -0500193 public void setShowingPublic(boolean show) {
194 mShowingPublic = show;
Dan Sandlera5e0f412014-01-23 15:11:54 -0500195
196 // bail out if no public version
Selim Cinek1685e632014-04-08 02:27:49 +0200197 if (mPublicLayout.getChildCount() == 0) return;
Dan Sandlera5e0f412014-01-23 15:11:54 -0500198
199 // TODO: animation?
Selim Cinek1685e632014-04-08 02:27:49 +0200200 mPublicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
201 mPrivateLayout.setVisibility(show ? View.GONE : View.VISIBLE);
Dan Sandlera5e0f412014-01-23 15:11:54 -0500202 }
Jorim Jaggi251957d2014-04-09 04:24:09 +0200203
204 /**
205 * Sets the notification as dimmed, meaning that it will appear in a more gray variant.
206 */
207 public void setDimmed(boolean dimmed) {
Jorim Jaggife40f7d2014-04-28 15:20:04 +0200208 super.setDimmed(dimmed);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200209 mActivator.setDimmed(dimmed);
Jorim Jaggi251957d2014-04-09 04:24:09 +0200210 }
211
Selim Cinek1685e632014-04-08 02:27:49 +0200212 public int getMaxExpandHeight() {
Selim Cinek1685e632014-04-08 02:27:49 +0200213 return mMaxExpandHeight;
Chris Wren51c75102013-07-16 20:49:17 -0400214 }
Jorim Jaggi584a7aa2014-04-10 23:26:13 +0200215
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200216 public NotificationActivator getActivator() {
217 return mActivator;
218 }
219
Selim Cinek343e6e22014-04-11 21:23:30 +0200220 /**
221 * @return the potential height this view could expand in addition.
222 */
223 public int getExpandPotential() {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200224 return getMaximumAllowedExpandHeight() - getActualHeight();
225 }
226
227 @Override
228 public void setActualHeight(int height) {
229 mPrivateLayout.setActualHeight(height);
230 invalidate();
231 super.setActualHeight(height);
232 }
233
234 @Override
235 public int getMaxHeight() {
236 return mPrivateLayout.getMaxHeight();
237 }
238
239 @Override
240 public void setClipTopAmount(int clipTopAmount) {
241 super.setClipTopAmount(clipTopAmount);
242 mPrivateLayout.setClipTopAmount(clipTopAmount);
243 }
244
245 public void notifyContentUpdated() {
246 mPrivateLayout.notifyContentUpdated();
Selim Cinek343e6e22014-04-11 21:23:30 +0200247 }
Chris Wren51c75102013-07-16 20:49:17 -0400248}