blob: d0e9a999b13c593b2e4111ec91f3118bdbbfb019 [file] [log] [blame]
Kenny Root15a4d2f2010-03-11 18:20:12 -08001/*
2 * Copyright (C) 2008 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
Joe Onoratofd52b182010-11-10 18:00:52 -080017package com.android.systemui.statusbar.phone;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Daniel Sandler08d05e32012-08-08 16:39:54 -040019import android.app.ActivityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.content.Context;
Daniel Sandler1c1edaa2012-08-14 11:14:45 -040021import android.content.res.Resources;
Daniel Sandler5a8aefa2012-09-25 01:21:12 -040022import android.content.res.Resources.NotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.util.AttributeSet;
Chris Wren64161cc2012-12-17 16:49:30 -050024import android.util.EventLog;
John Spurlockcd686b52013-06-05 10:13:46 -040025import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.view.MotionEvent;
27import android.view.View;
Svetoslav Ganov6179ea32011-06-28 01:12:41 -070028import android.view.accessibility.AccessibilityEvent;
Chris Wren64161cc2012-12-17 16:49:30 -050029
30import com.android.systemui.EventLogTags;
Joe Onorato79de0c52010-05-26 17:03:26 -040031import com.android.systemui.R;
32
Daniel Sandler08d05e32012-08-08 16:39:54 -040033public class PhoneStatusBarView extends PanelBar {
Joe Onoratofd52b182010-11-10 18:00:52 -080034 private static final String TAG = "PhoneStatusBarView";
Daniel Sandler198a0302012-08-17 16:04:31 -040035 private static final boolean DEBUG = PhoneStatusBar.DEBUG;
Chris Wren64161cc2012-12-17 16:49:30 -050036 private static final boolean DEBUG_GESTURES = true;
Daniel Sandler198a0302012-08-17 16:04:31 -040037
Daniel Sandler08d05e32012-08-08 16:39:54 -040038 PhoneStatusBar mBar;
Daniel Sandler1c1edaa2012-08-14 11:14:45 -040039 int mScrimColor;
Daniel Sandler5a8aefa2012-09-25 01:21:12 -040040 float mSettingsPanelDragzoneFrac;
41 float mSettingsPanelDragzoneMin;
42
Chris Wrenb8ea2f52012-08-24 11:50:55 -040043 boolean mFullWidthNotifications;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -040044 PanelView mFadingPanel = null;
Casey Burkhardtbac221f2012-10-03 18:13:58 -070045 PanelView mLastFullyOpenedPanel = null;
Daniel Sandlercf591db2012-08-15 16:11:55 -040046 PanelView mNotificationPanel, mSettingsPanel;
Daniel Sandler67eab792012-10-02 17:08:23 -040047 private boolean mShouldFade;
John Spurlock7edfbca2013-09-14 11:58:55 -040048 private final PhoneStatusBarTransitions mBarTransitions;
Joe Onorato119a4012010-06-30 14:49:51 -040049
Joe Onoratofd52b182010-11-10 18:00:52 -080050 public PhoneStatusBarView(Context context, AttributeSet attrs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051 super(context, attrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052
Daniel Sandler1c1edaa2012-08-14 11:14:45 -040053 Resources res = getContext().getResources();
54 mScrimColor = res.getColor(R.color.notification_panel_scrim_color);
Daniel Sandler5a8aefa2012-09-25 01:21:12 -040055 mSettingsPanelDragzoneMin = res.getDimension(R.dimen.settings_panel_dragzone_min);
Chris Wrenb8ea2f52012-08-24 11:50:55 -040056 try {
Daniel Sandler5a8aefa2012-09-25 01:21:12 -040057 mSettingsPanelDragzoneFrac = res.getFraction(R.dimen.settings_panel_dragzone_fraction, 1, 1);
58 } catch (NotFoundException ex) {
59 mSettingsPanelDragzoneFrac = 0f;
Chris Wrenb8ea2f52012-08-24 11:50:55 -040060 }
Daniel Sandler5a8aefa2012-09-25 01:21:12 -040061 mFullWidthNotifications = mSettingsPanelDragzoneFrac <= 0f;
John Spurlock7edfbca2013-09-14 11:58:55 -040062 mBarTransitions = new PhoneStatusBarTransitions(this);
John Spurlocke932e302013-08-12 10:16:29 -040063 }
64
65 public BarTransitions getBarTransitions() {
66 return mBarTransitions;
Daniel Sandler1c1edaa2012-08-14 11:14:45 -040067 }
68
Daniel Sandlerefb0faf2012-10-10 14:15:34 -070069 public void setBar(PhoneStatusBar bar) {
70 mBar = bar;
71 }
72
73 public boolean hasFullWidthNotifications() {
74 return mFullWidthNotifications;
75 }
76
77 @Override
78 public void onAttachedToWindow() {
79 for (PanelView pv : mPanels) {
80 pv.setRubberbandingEnabled(!mFullWidthNotifications);
81 }
John Spurlocke6f0a712013-09-03 16:23:49 -040082 mBarTransitions.init();
Daniel Sandlerefb0faf2012-10-10 14:15:34 -070083 }
84
Daniel Sandler1c1edaa2012-08-14 11:14:45 -040085 @Override
Daniel Sandlercf591db2012-08-15 16:11:55 -040086 public void addPanel(PanelView pv) {
87 super.addPanel(pv);
88 if (pv.getId() == R.id.notification_panel) {
89 mNotificationPanel = pv;
90 } else if (pv.getId() == R.id.settings_panel){
91 mSettingsPanel = pv;
92 }
Daniel Sandlerefb0faf2012-10-10 14:15:34 -070093 pv.setRubberbandingEnabled(!mFullWidthNotifications);
Daniel Sandlercf591db2012-08-15 16:11:55 -040094 }
95
96 @Override
Daniel Sandler50508132012-08-16 14:10:53 -040097 public boolean panelsEnabled() {
John Spurlock97642182013-07-29 17:58:39 -040098 return mBar.panelsEnabled();
Daniel Sandler1e8feef2012-08-16 11:37:41 -040099 }
100
101 @Override
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700102 public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
103 if (super.onRequestSendAccessibilityEvent(child, event)) {
104 // The status bar is very small so augment the view that the user is touching
105 // with the content of the status bar a whole. This way an accessibility service
106 // may announce the current item as well as the entire content if appropriate.
107 AccessibilityEvent record = AccessibilityEvent.obtain();
108 onInitializeAccessibilityEvent(record);
109 dispatchPopulateAccessibilityEvent(record);
110 event.appendRecord(record);
111 return true;
112 }
113 return false;
114 }
Daniel Sandler08d05e32012-08-08 16:39:54 -0400115
116 @Override
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700117 public PanelView selectPanelForTouch(MotionEvent touch) {
118 final float x = touch.getX();
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700119 final boolean isLayoutRtl = isLayoutRtl();
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700120
Daniel Sandler5a8aefa2012-09-25 01:21:12 -0400121 if (mFullWidthNotifications) {
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700122 // No double swiping. If either panel is open, nothing else can be pulled down.
John Spurlock209bede2013-07-17 12:23:27 -0400123 return ((mSettingsPanel == null ? 0 : mSettingsPanel.getExpandedHeight())
124 + mNotificationPanel.getExpandedHeight() > 0)
125 ? null
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700126 : mNotificationPanel;
Daniel Sandler5a8aefa2012-09-25 01:21:12 -0400127 }
128
129 // We split the status bar into thirds: the left 2/3 are for notifications, and the
Daniel Sandlercf591db2012-08-15 16:11:55 -0400130 // right 1/3 for quick settings. If you pull the status bar down a second time you'll
131 // toggle panels no matter where you pull it down.
Daniel Sandler5a8aefa2012-09-25 01:21:12 -0400132
Daniel Sandler67eab792012-10-02 17:08:23 -0400133 final float w = getMeasuredWidth();
Daniel Sandler5a8aefa2012-09-25 01:21:12 -0400134 float region = (w * mSettingsPanelDragzoneFrac);
135
136 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -0400137 Log.v(TAG, String.format(
Daniel Sandler5a8aefa2012-09-25 01:21:12 -0400138 "w=%.1f frac=%.3f region=%.1f min=%.1f x=%.1f w-x=%.1f",
139 w, mSettingsPanelDragzoneFrac, region, mSettingsPanelDragzoneMin, x, (w-x)));
Daniel Sandlercf591db2012-08-15 16:11:55 -0400140 }
Daniel Sandler5a8aefa2012-09-25 01:21:12 -0400141
142 if (region < mSettingsPanelDragzoneMin) region = mSettingsPanelDragzoneMin;
143
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700144 final boolean showSettings = isLayoutRtl ? (x < region) : (w - region < x);
145 return showSettings ? mSettingsPanel : mNotificationPanel;
Daniel Sandlercf591db2012-08-15 16:11:55 -0400146 }
147
148 @Override
Daniel Sandler08d05e32012-08-08 16:39:54 -0400149 public void onPanelPeeked() {
150 super.onPanelPeeked();
John Spurlocka5baf892013-07-25 13:15:42 -0400151 mBar.makeExpandedVisible();
Daniel Sandler67eab792012-10-02 17:08:23 -0400152 }
153
154 @Override
155 public void startOpeningPanel(PanelView panel) {
156 super.startOpeningPanel(panel);
157 // we only want to start fading if this is the "first" or "last" panel,
158 // which is kind of tricky to determine
159 mShouldFade = (mFadingPanel == null || mFadingPanel.isFullyExpanded());
160 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -0400161 Log.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade);
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400162 }
Daniel Sandler67eab792012-10-02 17:08:23 -0400163 mFadingPanel = panel;
Daniel Sandler08d05e32012-08-08 16:39:54 -0400164 }
165
166 @Override
167 public void onAllPanelsCollapsed() {
168 super.onAllPanelsCollapsed();
Daniel Sandler6e2810b2012-10-17 09:40:09 -0400169 // give animations time to settle
170 mBar.makeExpandedInvisibleSoon();
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400171 mFadingPanel = null;
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700172 mLastFullyOpenedPanel = null;
John Spurlockc19418e32013-10-25 14:25:09 -0400173 if (mScrimColor != 0 && ActivityManager.isHighEndGfx()) {
174 mBar.mStatusBarWindow.setBackgroundColor(0);
175 }
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400176 }
177
178 @Override
179 public void onPanelFullyOpened(PanelView openPanel) {
Daniel Sandler750bb9b2012-10-03 16:24:00 -0400180 super.onPanelFullyOpened(openPanel);
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700181 if (openPanel != mLastFullyOpenedPanel) {
182 openPanel.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
183 }
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400184 mFadingPanel = openPanel;
Casey Burkhardtbac221f2012-10-03 18:13:58 -0700185 mLastFullyOpenedPanel = openPanel;
Daniel Sandler67eab792012-10-02 17:08:23 -0400186 mShouldFade = true; // now you own the fade, mister
Daniel Sandler08d05e32012-08-08 16:39:54 -0400187 }
188
189 @Override
190 public boolean onTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -0500191 boolean barConsumedEvent = mBar.interceptTouchEvent(event);
192
193 if (DEBUG_GESTURES) {
194 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
195 EventLog.writeEvent(EventLogTags.SYSUI_PANELBAR_TOUCH,
196 event.getActionMasked(), (int) event.getX(), (int) event.getY(),
197 barConsumedEvent ? 1 : 0);
198 }
199 }
200
201 return barConsumedEvent || super.onTouchEvent(event);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400202 }
203
204 @Override
205 public boolean onInterceptTouchEvent(MotionEvent event) {
206 return mBar.interceptTouchEvent(event) || super.onInterceptTouchEvent(event);
207 }
208
209 @Override
Daniel Sandler67eab792012-10-02 17:08:23 -0400210 public void panelExpansionChanged(PanelView panel, float frac) {
211 super.panelExpansionChanged(panel, frac);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400212
Daniel Sandler198a0302012-08-17 16:04:31 -0400213 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -0400214 Log.v(TAG, "panelExpansionChanged: f=" + frac);
Daniel Sandler198a0302012-08-17 16:04:31 -0400215 }
216
Daniel Sandler67eab792012-10-02 17:08:23 -0400217 if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx()) {
218 if (mShouldFade) {
219 frac = mPanelExpandedFractionSum; // don't judge me
Daniel Sandler3679bf52012-10-16 21:30:28 -0400220 // let's start this 20% of the way down the screen
221 frac = frac * 1.2f - 0.2f;
222 if (frac <= 0) {
223 mBar.mStatusBarWindow.setBackgroundColor(0);
224 } else {
225 // woo, special effects
226 final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
227 // attenuate background color alpha by k
228 final int color = (int) ((mScrimColor >>> 24) * k) << 24 | (mScrimColor & 0xFFFFFF);
229 mBar.mStatusBarWindow.setBackgroundColor(color);
230 }
Daniel Sandler67eab792012-10-02 17:08:23 -0400231 }
Daniel Sandler08d05e32012-08-08 16:39:54 -0400232 }
233
Daniel Sandler025e7cb2012-10-17 10:15:37 -0400234 // fade out the panel as it gets buried into the status bar to avoid overdrawing the
235 // status bar on the last frame of a close animation
236 final int H = mBar.getStatusBarHeight();
237 final float ph = panel.getExpandedHeight() + panel.getPaddingBottom();
238 float alpha = 1f;
239 if (ph < 2*H) {
240 if (ph < H) alpha = 0f;
241 else alpha = (ph - H) / H;
242 alpha = alpha * alpha; // get there faster
243 }
244 if (panel.getAlpha() != alpha) {
245 panel.setAlpha(alpha);
246 }
247
Chris Wren9afc50d2013-07-30 11:31:46 -0400248 mBar.animateHeadsUp(mNotificationPanel == panel, mPanelExpandedFractionSum);
249
Daniel Sandler08d05e32012-08-08 16:39:54 -0400250 mBar.updateCarrierLabelVisibility(false);
251 }
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700252}