Kenny Root | 15a4d2f | 2010-03-11 18:20:12 -0800 | [diff] [blame] | 1 | /* |
| 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 Onorato | fd52b18 | 2010-11-10 18:00:52 -0800 | [diff] [blame] | 17 | package com.android.systemui.statusbar.phone; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 18 | |
Daniel Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 19 | import android.app.ActivityManager; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 20 | import android.content.Context; |
Daniel Sandler | 1c1edaa | 2012-08-14 11:14:45 -0400 | [diff] [blame] | 21 | import android.content.res.Resources; |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 22 | import android.content.res.Resources.NotFoundException; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 23 | import android.util.AttributeSet; |
Chris Wren | 64161cc | 2012-12-17 16:49:30 -0500 | [diff] [blame] | 24 | import android.util.EventLog; |
John Spurlock | cd686b5 | 2013-06-05 10:13:46 -0400 | [diff] [blame] | 25 | import android.util.Log; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 26 | import android.view.MotionEvent; |
| 27 | import android.view.View; |
Svetoslav Ganov | 6179ea3 | 2011-06-28 01:12:41 -0700 | [diff] [blame] | 28 | import android.view.accessibility.AccessibilityEvent; |
Chris Wren | 64161cc | 2012-12-17 16:49:30 -0500 | [diff] [blame] | 29 | |
| 30 | import com.android.systemui.EventLogTags; |
Joe Onorato | 79de0c5 | 2010-05-26 17:03:26 -0400 | [diff] [blame] | 31 | import com.android.systemui.R; |
| 32 | |
Daniel Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 33 | public class PhoneStatusBarView extends PanelBar { |
Joe Onorato | fd52b18 | 2010-11-10 18:00:52 -0800 | [diff] [blame] | 34 | private static final String TAG = "PhoneStatusBarView"; |
Daniel Sandler | 198a030 | 2012-08-17 16:04:31 -0400 | [diff] [blame] | 35 | private static final boolean DEBUG = PhoneStatusBar.DEBUG; |
Chris Wren | 64161cc | 2012-12-17 16:49:30 -0500 | [diff] [blame] | 36 | private static final boolean DEBUG_GESTURES = true; |
Daniel Sandler | 198a030 | 2012-08-17 16:04:31 -0400 | [diff] [blame] | 37 | |
Daniel Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 38 | PhoneStatusBar mBar; |
Daniel Sandler | 1c1edaa | 2012-08-14 11:14:45 -0400 | [diff] [blame] | 39 | int mScrimColor; |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 40 | float mSettingsPanelDragzoneFrac; |
| 41 | float mSettingsPanelDragzoneMin; |
| 42 | |
Chris Wren | b8ea2f5 | 2012-08-24 11:50:55 -0400 | [diff] [blame] | 43 | boolean mFullWidthNotifications; |
Daniel Sandler | 8e72c9e | 2012-08-15 00:09:26 -0400 | [diff] [blame] | 44 | PanelView mFadingPanel = null; |
Casey Burkhardt | bac221f | 2012-10-03 18:13:58 -0700 | [diff] [blame] | 45 | PanelView mLastFullyOpenedPanel = null; |
Daniel Sandler | cf591db | 2012-08-15 16:11:55 -0400 | [diff] [blame] | 46 | PanelView mNotificationPanel, mSettingsPanel; |
Daniel Sandler | 67eab79 | 2012-10-02 17:08:23 -0400 | [diff] [blame] | 47 | private boolean mShouldFade; |
John Spurlock | 7edfbca | 2013-09-14 11:58:55 -0400 | [diff] [blame] | 48 | private final PhoneStatusBarTransitions mBarTransitions; |
Joe Onorato | 119a401 | 2010-06-30 14:49:51 -0400 | [diff] [blame] | 49 | |
Joe Onorato | fd52b18 | 2010-11-10 18:00:52 -0800 | [diff] [blame] | 50 | public PhoneStatusBarView(Context context, AttributeSet attrs) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 51 | super(context, attrs); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 52 | |
Daniel Sandler | 1c1edaa | 2012-08-14 11:14:45 -0400 | [diff] [blame] | 53 | Resources res = getContext().getResources(); |
| 54 | mScrimColor = res.getColor(R.color.notification_panel_scrim_color); |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 55 | mSettingsPanelDragzoneMin = res.getDimension(R.dimen.settings_panel_dragzone_min); |
Chris Wren | b8ea2f5 | 2012-08-24 11:50:55 -0400 | [diff] [blame] | 56 | try { |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 57 | mSettingsPanelDragzoneFrac = res.getFraction(R.dimen.settings_panel_dragzone_fraction, 1, 1); |
| 58 | } catch (NotFoundException ex) { |
| 59 | mSettingsPanelDragzoneFrac = 0f; |
Chris Wren | b8ea2f5 | 2012-08-24 11:50:55 -0400 | [diff] [blame] | 60 | } |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 61 | mFullWidthNotifications = mSettingsPanelDragzoneFrac <= 0f; |
John Spurlock | 7edfbca | 2013-09-14 11:58:55 -0400 | [diff] [blame] | 62 | mBarTransitions = new PhoneStatusBarTransitions(this); |
John Spurlock | e932e30 | 2013-08-12 10:16:29 -0400 | [diff] [blame] | 63 | } |
| 64 | |
| 65 | public BarTransitions getBarTransitions() { |
| 66 | return mBarTransitions; |
Daniel Sandler | 1c1edaa | 2012-08-14 11:14:45 -0400 | [diff] [blame] | 67 | } |
| 68 | |
Daniel Sandler | efb0faf | 2012-10-10 14:15:34 -0700 | [diff] [blame] | 69 | 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 Spurlock | e6f0a71 | 2013-09-03 16:23:49 -0400 | [diff] [blame] | 82 | mBarTransitions.init(); |
Daniel Sandler | efb0faf | 2012-10-10 14:15:34 -0700 | [diff] [blame] | 83 | } |
| 84 | |
Daniel Sandler | 1c1edaa | 2012-08-14 11:14:45 -0400 | [diff] [blame] | 85 | @Override |
Daniel Sandler | cf591db | 2012-08-15 16:11:55 -0400 | [diff] [blame] | 86 | 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 Sandler | efb0faf | 2012-10-10 14:15:34 -0700 | [diff] [blame] | 93 | pv.setRubberbandingEnabled(!mFullWidthNotifications); |
Daniel Sandler | cf591db | 2012-08-15 16:11:55 -0400 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | @Override |
Daniel Sandler | 5050813 | 2012-08-16 14:10:53 -0400 | [diff] [blame] | 97 | public boolean panelsEnabled() { |
John Spurlock | 9764218 | 2013-07-29 17:58:39 -0400 | [diff] [blame] | 98 | return mBar.panelsEnabled(); |
Daniel Sandler | 1e8feef | 2012-08-16 11:37:41 -0400 | [diff] [blame] | 99 | } |
| 100 | |
| 101 | @Override |
Svetoslav Ganov | 6179ea3 | 2011-06-28 01:12:41 -0700 | [diff] [blame] | 102 | 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 Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 115 | |
| 116 | @Override |
Daniel Sandler | efb0faf | 2012-10-10 14:15:34 -0700 | [diff] [blame] | 117 | public PanelView selectPanelForTouch(MotionEvent touch) { |
| 118 | final float x = touch.getX(); |
Fabrice Di Meglio | 8afcd14 | 2012-07-27 18:27:11 -0700 | [diff] [blame] | 119 | final boolean isLayoutRtl = isLayoutRtl(); |
Daniel Sandler | efb0faf | 2012-10-10 14:15:34 -0700 | [diff] [blame] | 120 | |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 121 | if (mFullWidthNotifications) { |
Daniel Sandler | efb0faf | 2012-10-10 14:15:34 -0700 | [diff] [blame] | 122 | // No double swiping. If either panel is open, nothing else can be pulled down. |
John Spurlock | 209bede | 2013-07-17 12:23:27 -0400 | [diff] [blame] | 123 | return ((mSettingsPanel == null ? 0 : mSettingsPanel.getExpandedHeight()) |
| 124 | + mNotificationPanel.getExpandedHeight() > 0) |
| 125 | ? null |
Daniel Sandler | efb0faf | 2012-10-10 14:15:34 -0700 | [diff] [blame] | 126 | : mNotificationPanel; |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 127 | } |
| 128 | |
| 129 | // We split the status bar into thirds: the left 2/3 are for notifications, and the |
Daniel Sandler | cf591db | 2012-08-15 16:11:55 -0400 | [diff] [blame] | 130 | // 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 Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 132 | |
Daniel Sandler | 67eab79 | 2012-10-02 17:08:23 -0400 | [diff] [blame] | 133 | final float w = getMeasuredWidth(); |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 134 | float region = (w * mSettingsPanelDragzoneFrac); |
| 135 | |
| 136 | if (DEBUG) { |
John Spurlock | cd686b5 | 2013-06-05 10:13:46 -0400 | [diff] [blame] | 137 | Log.v(TAG, String.format( |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 138 | "w=%.1f frac=%.3f region=%.1f min=%.1f x=%.1f w-x=%.1f", |
| 139 | w, mSettingsPanelDragzoneFrac, region, mSettingsPanelDragzoneMin, x, (w-x))); |
Daniel Sandler | cf591db | 2012-08-15 16:11:55 -0400 | [diff] [blame] | 140 | } |
Daniel Sandler | 5a8aefa | 2012-09-25 01:21:12 -0400 | [diff] [blame] | 141 | |
| 142 | if (region < mSettingsPanelDragzoneMin) region = mSettingsPanelDragzoneMin; |
| 143 | |
Fabrice Di Meglio | 8afcd14 | 2012-07-27 18:27:11 -0700 | [diff] [blame] | 144 | final boolean showSettings = isLayoutRtl ? (x < region) : (w - region < x); |
| 145 | return showSettings ? mSettingsPanel : mNotificationPanel; |
Daniel Sandler | cf591db | 2012-08-15 16:11:55 -0400 | [diff] [blame] | 146 | } |
| 147 | |
| 148 | @Override |
Daniel Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 149 | public void onPanelPeeked() { |
| 150 | super.onPanelPeeked(); |
John Spurlock | a5baf89 | 2013-07-25 13:15:42 -0400 | [diff] [blame] | 151 | mBar.makeExpandedVisible(); |
Daniel Sandler | 67eab79 | 2012-10-02 17:08:23 -0400 | [diff] [blame] | 152 | } |
| 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 Spurlock | cd686b5 | 2013-06-05 10:13:46 -0400 | [diff] [blame] | 161 | Log.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade); |
Daniel Sandler | 8e72c9e | 2012-08-15 00:09:26 -0400 | [diff] [blame] | 162 | } |
Daniel Sandler | 67eab79 | 2012-10-02 17:08:23 -0400 | [diff] [blame] | 163 | mFadingPanel = panel; |
Daniel Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 164 | } |
| 165 | |
| 166 | @Override |
| 167 | public void onAllPanelsCollapsed() { |
| 168 | super.onAllPanelsCollapsed(); |
Daniel Sandler | 6e2810b | 2012-10-17 09:40:09 -0400 | [diff] [blame] | 169 | // give animations time to settle |
| 170 | mBar.makeExpandedInvisibleSoon(); |
Daniel Sandler | 8e72c9e | 2012-08-15 00:09:26 -0400 | [diff] [blame] | 171 | mFadingPanel = null; |
Casey Burkhardt | bac221f | 2012-10-03 18:13:58 -0700 | [diff] [blame] | 172 | mLastFullyOpenedPanel = null; |
John Spurlock | ab847cf | 2014-01-15 14:13:59 -0500 | [diff] [blame] | 173 | if (mScrimColor != 0 && ActivityManager.isHighEndGfx() && mBar.mStatusBarWindow != null) { |
John Spurlock | c19418e3 | 2013-10-25 14:25:09 -0400 | [diff] [blame] | 174 | mBar.mStatusBarWindow.setBackgroundColor(0); |
| 175 | } |
Daniel Sandler | 8e72c9e | 2012-08-15 00:09:26 -0400 | [diff] [blame] | 176 | } |
| 177 | |
| 178 | @Override |
| 179 | public void onPanelFullyOpened(PanelView openPanel) { |
Daniel Sandler | 750bb9b | 2012-10-03 16:24:00 -0400 | [diff] [blame] | 180 | super.onPanelFullyOpened(openPanel); |
Casey Burkhardt | bac221f | 2012-10-03 18:13:58 -0700 | [diff] [blame] | 181 | if (openPanel != mLastFullyOpenedPanel) { |
| 182 | openPanel.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); |
| 183 | } |
Daniel Sandler | 8e72c9e | 2012-08-15 00:09:26 -0400 | [diff] [blame] | 184 | mFadingPanel = openPanel; |
Casey Burkhardt | bac221f | 2012-10-03 18:13:58 -0700 | [diff] [blame] | 185 | mLastFullyOpenedPanel = openPanel; |
Daniel Sandler | 67eab79 | 2012-10-02 17:08:23 -0400 | [diff] [blame] | 186 | mShouldFade = true; // now you own the fade, mister |
Daniel Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 187 | } |
| 188 | |
| 189 | @Override |
| 190 | public boolean onTouchEvent(MotionEvent event) { |
Chris Wren | 64161cc | 2012-12-17 16:49:30 -0500 | [diff] [blame] | 191 | 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 Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 202 | } |
| 203 | |
| 204 | @Override |
| 205 | public boolean onInterceptTouchEvent(MotionEvent event) { |
| 206 | return mBar.interceptTouchEvent(event) || super.onInterceptTouchEvent(event); |
| 207 | } |
| 208 | |
| 209 | @Override |
Daniel Sandler | 67eab79 | 2012-10-02 17:08:23 -0400 | [diff] [blame] | 210 | public void panelExpansionChanged(PanelView panel, float frac) { |
| 211 | super.panelExpansionChanged(panel, frac); |
Daniel Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 212 | |
Daniel Sandler | 198a030 | 2012-08-17 16:04:31 -0400 | [diff] [blame] | 213 | if (DEBUG) { |
John Spurlock | cd686b5 | 2013-06-05 10:13:46 -0400 | [diff] [blame] | 214 | Log.v(TAG, "panelExpansionChanged: f=" + frac); |
Daniel Sandler | 198a030 | 2012-08-17 16:04:31 -0400 | [diff] [blame] | 215 | } |
| 216 | |
John Spurlock | ab847cf | 2014-01-15 14:13:59 -0500 | [diff] [blame] | 217 | if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx() |
| 218 | && mBar.mStatusBarWindow != null) { |
Daniel Sandler | 67eab79 | 2012-10-02 17:08:23 -0400 | [diff] [blame] | 219 | if (mShouldFade) { |
| 220 | frac = mPanelExpandedFractionSum; // don't judge me |
Daniel Sandler | 3679bf5 | 2012-10-16 21:30:28 -0400 | [diff] [blame] | 221 | // let's start this 20% of the way down the screen |
| 222 | frac = frac * 1.2f - 0.2f; |
| 223 | if (frac <= 0) { |
| 224 | mBar.mStatusBarWindow.setBackgroundColor(0); |
| 225 | } else { |
| 226 | // woo, special effects |
| 227 | final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f)))); |
| 228 | // attenuate background color alpha by k |
| 229 | final int color = (int) ((mScrimColor >>> 24) * k) << 24 | (mScrimColor & 0xFFFFFF); |
| 230 | mBar.mStatusBarWindow.setBackgroundColor(color); |
| 231 | } |
Daniel Sandler | 67eab79 | 2012-10-02 17:08:23 -0400 | [diff] [blame] | 232 | } |
Daniel Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 233 | } |
| 234 | |
Daniel Sandler | 025e7cb | 2012-10-17 10:15:37 -0400 | [diff] [blame] | 235 | // fade out the panel as it gets buried into the status bar to avoid overdrawing the |
| 236 | // status bar on the last frame of a close animation |
| 237 | final int H = mBar.getStatusBarHeight(); |
| 238 | final float ph = panel.getExpandedHeight() + panel.getPaddingBottom(); |
| 239 | float alpha = 1f; |
| 240 | if (ph < 2*H) { |
| 241 | if (ph < H) alpha = 0f; |
| 242 | else alpha = (ph - H) / H; |
| 243 | alpha = alpha * alpha; // get there faster |
| 244 | } |
| 245 | if (panel.getAlpha() != alpha) { |
| 246 | panel.setAlpha(alpha); |
| 247 | } |
| 248 | |
Chris Wren | 9afc50d | 2013-07-30 11:31:46 -0400 | [diff] [blame] | 249 | mBar.animateHeadsUp(mNotificationPanel == panel, mPanelExpandedFractionSum); |
| 250 | |
Daniel Sandler | 08d05e3 | 2012-08-08 16:39:54 -0400 | [diff] [blame] | 251 | mBar.updateCarrierLabelVisibility(false); |
| 252 | } |
Svetoslav Ganov | 6179ea3 | 2011-06-28 01:12:41 -0700 | [diff] [blame] | 253 | } |