blob: 627b80f974d4f2e494484038153471fc71f62a82 [file] [log] [blame]
Daniel Sandler08d05e32012-08-08 16:39:54 -04001/*
2 * Copyright (C) 2012 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.phone;
18
19import android.content.Context;
20import android.util.AttributeSet;
Daniel Sandler040c2e42012-10-17 00:56:33 -040021import android.view.MotionEvent;
Daniel Sandler13522a22012-09-27 14:46:58 -040022import android.view.View;
Casey Burkhardt23b0a4e2013-04-29 12:18:32 -070023import android.view.accessibility.AccessibilityEvent;
Daniel Sandler13522a22012-09-27 14:46:58 -040024
Chet Haase4d179dc2012-08-22 07:14:42 -070025import com.android.systemui.R;
Jorim Jaggibe565df2014-04-28 17:51:23 +020026import com.android.systemui.statusbar.ExpandableView;
Daniel Sandler151f00d2012-10-02 22:33:08 -040027import com.android.systemui.statusbar.GestureRecorder;
Jorim Jaggiecbab362014-04-23 16:13:15 +020028import com.android.systemui.statusbar.StatusBarState;
Selim Cinekb6d85eb2014-03-28 20:21:01 +010029import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Daniel Sandler08d05e32012-08-08 16:39:54 -040030
Jorim Jaggibe565df2014-04-28 17:51:23 +020031public class NotificationPanelView extends PanelView implements
32 ExpandableView.OnHeightChangedListener {
Chris Wren64161cc2012-12-17 16:49:30 -050033 public static final boolean DEBUG_GESTURES = true;
Chet Haase4d179dc2012-08-22 07:14:42 -070034
Daniel Sandler040c2e42012-10-17 00:56:33 -040035 PhoneStatusBar mStatusBar;
John Spurlock73203eb2014-04-15 16:14:46 -040036 private View mHeader;
37 private View mKeyguardStatusView;
38
Selim Cinekb6d85eb2014-03-28 20:21:01 +010039 private NotificationStackScrollLayout mNotificationStackScroller;
John Spurlock73203eb2014-04-15 16:14:46 -040040 private boolean mTrackingSettings;
Jorim Jaggi8c1a44b2014-04-29 19:04:02 +020041 private int mNotificationTopPadding;
Jorim Jaggi98fb09c2014-05-01 22:40:56 +020042 private boolean mAnimateNextTopPaddingChange;
Chet Haase4d179dc2012-08-22 07:14:42 -070043
Daniel Sandler08d05e32012-08-08 16:39:54 -040044 public NotificationPanelView(Context context, AttributeSet attrs) {
45 super(context, attrs);
Daniel Sandler13522a22012-09-27 14:46:58 -040046 }
Chet Haase4d179dc2012-08-22 07:14:42 -070047
Daniel Sandler040c2e42012-10-17 00:56:33 -040048 public void setStatusBar(PhoneStatusBar bar) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +010049 if (mStatusBar != null) {
50 mStatusBar.setOnFlipRunnable(null);
51 }
Daniel Sandler040c2e42012-10-17 00:56:33 -040052 mStatusBar = bar;
Selim Cinekb6d85eb2014-03-28 20:21:01 +010053 if (bar != null) {
54 mStatusBar.setOnFlipRunnable(new Runnable() {
55 @Override
56 public void run() {
57 requestPanelHeightUpdate();
58 }
59 });
60 }
Daniel Sandler040c2e42012-10-17 00:56:33 -040061 }
62
Daniel Sandler13522a22012-09-27 14:46:58 -040063 @Override
64 protected void onFinishInflate() {
65 super.onFinishInflate();
66
John Spurlock73203eb2014-04-15 16:14:46 -040067 mHeader = findViewById(R.id.header);
68 mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
Selim Cinekb6d85eb2014-03-28 20:21:01 +010069 mNotificationStackScroller = (NotificationStackScrollLayout)
70 findViewById(R.id.notification_stack_scroller);
Jorim Jaggibe565df2014-04-28 17:51:23 +020071 mNotificationStackScroller.setOnHeightChangedListener(this);
Jorim Jaggi8c1a44b2014-04-29 19:04:02 +020072 mNotificationTopPadding = getResources().getDimensionPixelSize(
73 R.dimen.notifications_top_padding);
74 }
75
76 @Override
77 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
78 super.onLayout(changed, left, top, right, bottom);
79 int keyguardBottomMargin =
80 ((MarginLayoutParams) mKeyguardStatusView.getLayoutParams()).bottomMargin;
Jorim Jaggiecbab362014-04-23 16:13:15 +020081 mNotificationStackScroller.setTopPadding(mStatusBar.getBarState() == StatusBarState.KEYGUARD
Jorim Jaggi8c1a44b2014-04-29 19:04:02 +020082 ? mKeyguardStatusView.getBottom() + keyguardBottomMargin
Jorim Jaggi0dd68812014-05-01 19:17:37 +020083 : mHeader.getBottom() + mNotificationTopPadding,
Jorim Jaggi98fb09c2014-05-01 22:40:56 +020084 mAnimateNextTopPaddingChange);
85 mAnimateNextTopPaddingChange = false;
86 }
87
88 public void animateNextTopPaddingChange() {
89 mAnimateNextTopPaddingChange = true;
90 requestLayout();
Daniel Sandler08d05e32012-08-08 16:39:54 -040091 }
92
Daniel Sandler08d05e32012-08-08 16:39:54 -040093 @Override
94 public void fling(float vel, boolean always) {
Daniel Sandler151f00d2012-10-02 22:33:08 -040095 GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder();
96 if (gr != null) {
97 gr.tag(
98 "fling " + ((vel > 0) ? "open" : "closed"),
99 "notifications,v=" + vel);
100 }
Daniel Sandler08d05e32012-08-08 16:39:54 -0400101 super.fling(vel, always);
102 }
Chet Haase4d179dc2012-08-22 07:14:42 -0700103
Casey Burkhardt23b0a4e2013-04-29 12:18:32 -0700104 @Override
105 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
106 if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
107 event.getText()
108 .add(getContext().getString(R.string.accessibility_desc_notification_shade));
109 return true;
110 }
111
112 return super.dispatchPopulateAccessibilityEvent(event);
113 }
114
Daniel Sandler040c2e42012-10-17 00:56:33 -0400115 @Override
John Spurlock73203eb2014-04-15 16:14:46 -0400116 public boolean onInterceptTouchEvent(MotionEvent event) {
117 // intercept for quick settings
118 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Jorim Jaggiecbab362014-04-23 16:13:15 +0200119 final View target = mStatusBar.getBarState() == StatusBarState.KEYGUARD
120 ? mKeyguardStatusView
121 : mHeader;
John Spurlock73203eb2014-04-15 16:14:46 -0400122 final boolean inTarget = PhoneStatusBar.inBounds(target, event, true);
123 if (inTarget && !isInSettings()) {
124 mTrackingSettings = true;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200125 requestDisallowInterceptTouchEvent(true);
John Spurlock73203eb2014-04-15 16:14:46 -0400126 return true;
127 }
128 if (!inTarget && isInSettings()) {
129 mTrackingSettings = true;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200130 requestDisallowInterceptTouchEvent(true);
John Spurlock73203eb2014-04-15 16:14:46 -0400131 return true;
132 }
133 }
134 return super.onInterceptTouchEvent(event);
135 }
136
137 @Override
Daniel Sandler040c2e42012-10-17 00:56:33 -0400138 public boolean onTouchEvent(MotionEvent event) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100139 // TODO: Handle doublefinger swipe to notifications again. Look at history for a reference
140 // implementation.
John Spurlock73203eb2014-04-15 16:14:46 -0400141 if (mTrackingSettings) {
142 mStatusBar.onSettingsEvent(event);
143 if (event.getAction() == MotionEvent.ACTION_UP
144 || event.getAction() == MotionEvent.ACTION_CANCEL) {
145 mTrackingSettings = false;
146 }
147 return true;
148 }
149 if (isInSettings()) {
150 return true;
151 }
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100152 return super.onTouchEvent(event);
153 }
154
155 @Override
156 protected boolean isScrolledToBottom() {
157 if (!isInSettings()) {
158 return mNotificationStackScroller.isScrolledToBottom();
Chris Wren64161cc2012-12-17 16:49:30 -0500159 }
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100160 return super.isScrolledToBottom();
161 }
162
163 @Override
164 protected int getMaxPanelHeight() {
165 if (!isInSettings()) {
166 int maxPanelHeight = super.getMaxPanelHeight();
167 int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin();
168 return maxPanelHeight - emptyBottomMargin;
Daniel Sandler040c2e42012-10-17 00:56:33 -0400169 }
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100170 return super.getMaxPanelHeight();
171 }
172
173 private boolean isInSettings() {
174 return mStatusBar != null && mStatusBar.isFlippedToSettings();
175 }
176
177 @Override
178 protected void onHeightUpdated(float expandedHeight) {
Jorim Jaggi8c1a44b2014-04-29 19:04:02 +0200179 mNotificationStackScroller.setStackHeight(expandedHeight);
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100180 }
181
182 @Override
183 protected int getDesiredMeasureHeight() {
184 return mMaxPanelHeight;
Daniel Sandler040c2e42012-10-17 00:56:33 -0400185 }
Selim Cinek1685e632014-04-08 02:27:49 +0200186
187 @Override
188 protected void onExpandingStarted() {
189 super.onExpandingStarted();
190 mNotificationStackScroller.onExpansionStarted();
191 }
192
193 @Override
194 protected void onExpandingFinished() {
195 super.onExpandingFinished();
196 mNotificationStackScroller.onExpansionStopped();
197 }
Jorim Jaggibe565df2014-04-28 17:51:23 +0200198
199 @Override
200 public void onHeightChanged(ExpandableView view) {
201 requestPanelHeightUpdate();
202 }
Daniel Sandler08d05e32012-08-08 16:39:54 -0400203}