blob: 44e7dacb01dffeae013d0f6f4248016a5f4d9640 [file] [log] [blame]
Joe Onorato808182d2010-07-09 18:52:06 -04001/*
2 * Copyright (C) 2010 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;
Joe Onorato808182d2010-07-09 18:52:06 -040018
John Spurlockd4e65752013-08-28 14:17:09 -040019import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
John Spurlock7edfbca2013-09-14 11:58:55 -040020import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
John Spurlockd4e65752013-08-28 14:17:09 -040021import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
John Spurlock0ec64c62013-08-26 15:37:58 -040022import static android.app.StatusBarManager.windowStateToString;
John Spurlock3b139a92013-08-17 17:18:08 -040023import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
John Spurlock89835dd2013-08-16 15:06:51 -040024import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
John Spurlockbd957402013-10-03 11:38:39 -040025import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
John Spurlock7edfbca2013-09-14 11:58:55 -040026import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
John Spurlocke932e302013-08-12 10:16:29 -040027
Daniel Sandlerd7e96862012-04-26 01:10:29 -040028import android.animation.Animator;
29import android.animation.AnimatorListenerAdapter;
Daniel Sandler0761e4c2011-08-11 00:19:49 -040030import android.animation.ObjectAnimator;
Daniel Sandler101784e2012-10-15 13:39:38 -040031import android.animation.TimeInterpolator;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070032import android.app.ActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040033import android.app.ActivityManagerNative;
Joe Onorato808182d2010-07-09 18:52:06 -040034import android.app.Notification;
35import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040036import android.app.StatusBarManager;
37import android.content.BroadcastReceiver;
38import android.content.Context;
39import android.content.Intent;
40import android.content.IntentFilter;
Daniel Sandler777dcde2013-09-30 10:21:45 -040041import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070042import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040043import android.database.ContentObserver;
Romain Guy648342f2012-05-25 10:44:45 -070044import android.graphics.Canvas;
45import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040046import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040047import android.graphics.Point;
Romain Guy648342f2012-05-25 10:44:45 -070048import android.graphics.PorterDuff;
Joe Onorato808182d2010-07-09 18:52:06 -040049import android.graphics.Rect;
Romain Guy648342f2012-05-25 10:44:45 -070050import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070051import android.inputmethodservice.InputMethodService;
John Spurlock3c875662013-08-31 15:07:25 -040052import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040053import android.os.Handler;
Joe Onorato808182d2010-07-09 18:52:06 -040054import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040055import android.os.Message;
John Spurlock56d007b2013-10-28 18:40:56 -040056import android.os.PowerManager;
Michael Jurka7f2668c2012-03-27 07:49:52 -070057import android.os.RemoteException;
Joe Onorato808182d2010-07-09 18:52:06 -040058import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070059import android.os.UserHandle;
Daniel Sandlerd3090562011-08-09 00:28:44 -040060import android.provider.Settings;
John Spurlockde84f0e2013-06-12 12:41:00 -040061import android.service.notification.StatusBarNotification;
Daniel Sandler36412a72011-08-04 09:35:13 -040062import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -050063import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -040064import android.util.Log;
65import android.view.Display;
66import android.view.Gravity;
Joe Onorato808182d2010-07-09 18:52:06 -040067import android.view.MotionEvent;
68import android.view.VelocityTracker;
69import android.view.View;
70import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -070071import android.view.ViewGroup.LayoutParams;
Daniel Sandler101784e2012-10-15 13:39:38 -040072import android.view.ViewPropertyAnimator;
Daniel Sandlerb17a7262012-10-05 14:32:50 -040073import android.view.ViewStub;
Joe Onorato808182d2010-07-09 18:52:06 -040074import android.view.WindowManager;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040075import android.view.animation.AccelerateInterpolator;
Joe Onorato808182d2010-07-09 18:52:06 -040076import android.view.animation.Animation;
77import android.view.animation.AnimationUtils;
Daniel Sandler67e7d902012-06-06 16:32:21 -040078import android.view.animation.DecelerateInterpolator;
Daniel Sandler21b274e2012-05-02 15:07:51 -040079import android.widget.FrameLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040080import android.widget.ImageView;
81import android.widget.LinearLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040082import android.widget.ScrollView;
83import android.widget.TextView;
John Spurlock34e13d92013-08-10 06:52:28 -040084
Joe Onorato808182d2010-07-09 18:52:06 -040085import com.android.internal.statusbar.StatusBarIcon;
John Spurlock3c875662013-08-31 15:07:25 -040086import com.android.systemui.DemoMode;
Chris Wren64161cc2012-12-17 16:49:30 -050087import com.android.systemui.EventLogTags;
Joe Onorato808182d2010-07-09 18:52:06 -040088import com.android.systemui.R;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -050089import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -070090import com.android.systemui.statusbar.CommandQueue;
Daniel Sandler33805342012-07-23 15:45:12 -040091import com.android.systemui.statusbar.GestureRecorder;
Michael Jurka7f2668c2012-03-27 07:49:52 -070092import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -040093import com.android.systemui.statusbar.NotificationData.Entry;
Christian Robertson2e347422011-08-11 14:01:04 -070094import com.android.systemui.statusbar.SignalClusterView;
Michael Jurka7f2668c2012-03-27 07:49:52 -070095import com.android.systemui.statusbar.StatusBarIconView;
Daniel Sandler2b697352011-07-22 16:23:09 -040096import com.android.systemui.statusbar.policy.BatteryController;
Winson Chungd63c59782012-09-05 17:34:41 -070097import com.android.systemui.statusbar.policy.BluetoothController;
Michael Jurka7f2668c2012-03-27 07:49:52 -070098import com.android.systemui.statusbar.policy.DateView;
Chris Wren157026f2013-06-28 16:54:01 -040099import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
Daniel Sandler2b697352011-07-22 16:23:09 -0400100import com.android.systemui.statusbar.policy.LocationController;
101import com.android.systemui.statusbar.policy.NetworkController;
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400102import com.android.systemui.statusbar.policy.NotificationRowLayout;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700103import com.android.systemui.statusbar.policy.OnSizeChangedListener;
John Spurlockde84f0e2013-06-12 12:41:00 -0400104import com.android.systemui.statusbar.policy.RotationLockController;
Joe Onorato808182d2010-07-09 18:52:06 -0400105
Daniel Sandler6a858c32012-03-12 14:38:58 -0400106import java.io.FileDescriptor;
107import java.io.PrintWriter;
108import java.util.ArrayList;
109
John Spurlock3c875662013-08-31 15:07:25 -0400110public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
Joe Onoratofd52b182010-11-10 18:00:52 -0800111 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400112 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400113 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400114 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400115 public static final boolean DEBUG_GESTURES = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400116
John Spurlock342cad72013-10-08 09:36:50 -0400117 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400118
Daniel Sandler040c2e42012-10-17 00:56:33 -0400119 public static final boolean SETTINGS_DRAG_SHORTCUT = true;
120
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400121 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400122 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400123
Joe Onorato808182d2010-07-09 18:52:06 -0400124 public static final String ACTION_STATUSBAR_START
125 = "com.android.internal.policy.statusbar.START";
126
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400127 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400128 private static final int MSG_CLOSE_PANELS = 1001;
129 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700130 // 1020-1030 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400131
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400132 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
133
Daniel Sandler58b173b2012-05-03 11:25:29 -0400134 private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
135 private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
136
John Spurlocke1f366f2013-08-05 12:22:40 -0400137 private static final int STATUS_OR_NAV_TRANSIENT =
138 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400139 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400140
Daniel Sandlerdc940ea2011-08-25 14:35:53 -0700141 // fling gesture tuning parameters, scaled to display density
142 private float mSelfExpandVelocityPx; // classic value: 2000px/s
143 private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
144 private float mFlingExpandMinVelocityPx; // classic value: 200px/s
145 private float mFlingCollapseMinVelocityPx; // classic value: 200px/s
146 private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1)
147 private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
148 private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s
149
150 private float mExpandAccelPx; // classic value: 2000px/s/s
151 private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
152
John Spurlock209bede2013-07-17 12:23:27 -0400153 private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little
Daniel Sandlere5011a32012-06-11 16:07:52 -0400154 // faster than mSelfCollapseVelocityPx)
155
Joe Onoratofd52b182010-11-10 18:00:52 -0800156 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400157
Daniel Sandler2b697352011-07-22 16:23:09 -0400158 // These are no longer handled by the policy, because we need custom strategies for them
Winson Chungd63c59782012-09-05 17:34:41 -0700159 BluetoothController mBluetoothController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400160 BatteryController mBatteryController;
161 LocationController mLocationController;
162 NetworkController mNetworkController;
Svetoslav79578b22013-04-29 16:55:57 -0700163 RotationLockController mRotationLockController;
Jim Miller5e6af442011-12-02 18:24:26 -0800164
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400165 int mNaturalBarHeight = -1;
166 int mIconSize = -1;
167 int mIconHPadding = -1;
Joe Onorato808182d2010-07-09 18:52:06 -0400168 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400169 Point mCurrentDisplaySize = new Point();
Chris Wren9afc50d2013-07-30 11:31:46 -0400170 private float mHeadsUpVerticalOffset;
171 private int[] mPilePosition = new int[2];
Joe Onorato808182d2010-07-09 18:52:06 -0400172
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400173 StatusBarWindowView mStatusBarWindow;
Joe Onoratofd52b182010-11-10 18:00:52 -0800174 PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400175 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandlera310af82012-04-24 01:20:13 -0400176
Joe Onorato808182d2010-07-09 18:52:06 -0400177 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400178 Object mQueueLock = new Object();
179
Daniel Sandler173bae22012-09-25 14:37:42 -0400180 // viewgroup containing the normal contents of the statusbar
181 LinearLayout mStatusBarContents;
John Spurlock209bede2013-07-17 12:23:27 -0400182
Daniel Sandler173bae22012-09-25 14:37:42 -0400183 // right-hand icons
184 LinearLayout mSystemIconArea;
John Spurlock209bede2013-07-17 12:23:27 -0400185
186 // left-hand icons
Joe Onorato808182d2010-07-09 18:52:06 -0400187 LinearLayout mStatusIcons;
Daniel Sandler173bae22012-09-25 14:37:42 -0400188 // the icons themselves
189 IconMerger mNotificationIcons;
190 // [+>
191 View mMoreIcon;
Joe Onorato808182d2010-07-09 18:52:06 -0400192
193 // expanded notifications
Daniel Sandler040c2e42012-10-17 00:56:33 -0400194 NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400195 ScrollView mScrollView;
Joe Onorato808182d2010-07-09 18:52:06 -0400196 View mExpandedContents;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400197 int mNotificationPanelGravity;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400198 int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx;
Daniel Sandlere680f542012-09-28 12:22:27 -0400199 float mNotificationPanelMinHeightFrac;
Daniel Sandler66d92f82012-06-13 13:36:52 -0400200 boolean mNotificationPanelIsFullScreenWidth;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400201 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400202
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400203 // settings
Daniel Sandler101784e2012-10-15 13:39:38 -0400204 QuickSettings mQS;
205 boolean mHasSettingsPanel, mHasFlipSettings;
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400206 SettingsPanelView mSettingsPanel;
Daniel Sandler101784e2012-10-15 13:39:38 -0400207 View mFlipSettingsView;
208 QuickSettingsContainerView mSettingsContainer;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400209 int mSettingsPanelGravity;
210
Joe Onorato808182d2010-07-09 18:52:06 -0400211 // top bar
Daniel Sandler3679bf52012-10-16 21:30:28 -0400212 View mNotificationPanelHeader;
John Spurlock209bede2013-07-17 12:23:27 -0400213 View mDateTimeView;
Daniel Sandler1347c302011-08-01 16:47:53 -0400214 View mClearButton;
Daniel Sandler101784e2012-10-15 13:39:38 -0400215 ImageView mSettingsButton, mNotificationButton;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400216
Daniel Sandler3d32a242012-06-05 13:44:14 -0400217 // carrier/wifi label
218 private TextView mCarrierLabel;
219 private boolean mCarrierLabelVisible = false;
220 private int mCarrierLabelHeight;
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400221 private TextView mEmergencyCallLabel;
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400222 private int mNotificationHeaderHeight;
223
224 private boolean mShowCarrierInPanel = false;
Daniel Sandler3d32a242012-06-05 13:44:14 -0400225
Joe Onorato808182d2010-07-09 18:52:06 -0400226 // position
227 int[] mPositionTmp = new int[2];
Joe Onorato808182d2010-07-09 18:52:06 -0400228 boolean mExpandedVisible;
229
230 // the date view
231 DateView mDateView;
232
Chris Wren157026f2013-06-28 16:54:01 -0400233 // for heads up notifications
234 private HeadsUpNotificationView mHeadsUpNotificationView;
Chris Wren51c75102013-07-16 20:49:17 -0400235 private int mHeadsUpNotificationDecay;
Joe Onorato808182d2010-07-09 18:52:06 -0400236
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400237 // on-screen navigation buttons
Daniel Sandler0129b312011-05-11 11:54:11 -0400238 private NavigationBarView mNavigationBarView = null;
John Spurlockd4e65752013-08-28 14:17:09 -0400239 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400240
Joe Onorato808182d2010-07-09 18:52:06 -0400241 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400242 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400243
244 // ticker
245 private Ticker mTicker;
246 private View mTickerView;
247 private boolean mTicking;
248
249 // Tracking finger for opening/closing.
250 int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
251 boolean mTracking;
252 VelocityTracker mVelocityTracker;
253
Joe Onorato808182d2010-07-09 18:52:06 -0400254 int[] mAbsPos = new int[2];
Chet Haase2f2022a2011-10-11 06:41:59 -0700255 Runnable mPostCollapseCleanup = null;
256
Joe Onorato808182d2010-07-09 18:52:06 -0400257 // for disabling the status bar
258 int mDisabled = 0;
259
Daniel Sandler60ee2562011-07-22 12:34:33 -0400260 // tracking calls to View.setSystemUiVisibility()
261 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
262
Daniel Sandler36412a72011-08-04 09:35:13 -0400263 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700264
Daniel Sandler33805342012-07-23 15:45:12 -0400265 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400266 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400267 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400268 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400269
Daniel Sandler328310c2011-09-23 15:56:52 -0400270 private int mNavigationIconHints = 0;
Romain Guyf7f16f72012-05-24 19:13:56 -0700271 private final Animator.AnimatorListener mMakeIconsInvisible = new AnimatorListenerAdapter() {
272 @Override
273 public void onAnimationEnd(Animator animation) {
Daniel Sandler67e7d902012-06-06 16:32:21 -0400274 // double-check to avoid races
Daniel Sandler173bae22012-09-25 14:37:42 -0400275 if (mStatusBarContents.getAlpha() == 0) {
John Spurlockcd686b52013-06-05 10:13:46 -0400276 if (DEBUG) Log.d(TAG, "makeIconsInvisible");
Daniel Sandler173bae22012-09-25 14:37:42 -0400277 mStatusBarContents.setVisibility(View.INVISIBLE);
Daniel Sandler67e7d902012-06-06 16:32:21 -0400278 }
Romain Guyf7f16f72012-05-24 19:13:56 -0700279 }
280 };
Daniel Sandler328310c2011-09-23 15:56:52 -0400281
John Spurlock919adac2012-10-02 16:41:12 -0400282 // ensure quick settings is disabled until the current user makes it through the setup wizard
283 private boolean mUserSetup = false;
284 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
285 @Override
286 public void onChange(boolean selfChange) {
287 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
288 mContext.getContentResolver(),
289 Settings.Secure.USER_SETUP_COMPLETE,
290 0 /*default */,
291 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400292 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400293 "selfChange=%s userSetup=%s mUserSetup=%s",
294 selfChange, userSetup, mUserSetup));
Daniel Sandlera8ef3b02012-11-29 15:52:39 -0500295 if (mSettingsButton != null && mHasFlipSettings) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400296 mSettingsButton.setVisibility(userSetup ? View.VISIBLE : View.INVISIBLE);
297 }
298 if (mSettingsPanel != null) {
John Spurlocke4e8c562012-10-04 09:55:01 -0400299 mSettingsPanel.setEnabled(userSetup);
Daniel Sandler101784e2012-10-15 13:39:38 -0400300 }
John Spurlock919adac2012-10-02 16:41:12 -0400301 if (userSetup != mUserSetup) {
302 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400303 if (!mUserSetup && mStatusBarView != null)
304 animateCollapseQuickSettings();
305 }
306 }
307 };
308
Chris Wrenf6e83f42013-09-11 14:02:59 -0400309 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
310 @Override
311 public void onChange(boolean selfChange) {
312 boolean wasUsing = mUseHeadsUp;
313 mUseHeadsUp = ENABLE_HEADS_UP && 0 != Settings.Global.getInt(
314 mContext.getContentResolver(), SETTING_HEADS_UP, 0);
315 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
316 if (wasUsing != mUseHeadsUp) {
317 if (!mUseHeadsUp) {
318 Log.d(TAG, "dismissing any existing heads up notification on disable event");
319 mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
320 removeHeadsUpView();
321 } else {
322 addHeadsUpView();
323 }
324 }
325 }
326 };
327
John Spurlockcfc359a2013-09-05 10:42:03 -0400328 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400329 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400330 private int mStatusBarMode;
331 private int mNavigationBarMode;
John Spurlock8c520422013-09-19 12:23:35 -0400332 private Boolean mScreenOn;
John Spurlock32beb2c2013-03-11 10:16:47 -0400333
334 private final Runnable mAutohide = new Runnable() {
335 @Override
336 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400337 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400338 if (mSystemUiVisibility != requested) {
339 notifyUiVisibilityChanged(requested);
340 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400341 }};
342
Joe Onorato808182d2010-07-09 18:52:06 -0400343 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400344 public void start() {
345 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
346 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400347 updateDisplaySize();
Joe Onorato808182d2010-07-09 18:52:06 -0400348
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500349 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400350
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400351 addNavigationBar();
352
Joe Onorato808182d2010-07-09 18:52:06 -0400353 // Lastly, call to the icon policy to install/update all the icons.
Joe Onoratofd52b182010-11-10 18:00:52 -0800354 mIconPolicy = new PhoneStatusBarPolicy(mContext);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400355
356 mHeadsUpObserver.onChange(true); // set up
357 if (ENABLE_HEADS_UP) {
358 mContext.getContentResolver().registerContentObserver(
359 Settings.Global.getUriFor(SETTING_HEADS_UP), true,
360 mHeadsUpObserver);
361 }
Joe Onorato808182d2010-07-09 18:52:06 -0400362 }
363
364 // ================================================================================
365 // Constructing the view
366 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700367 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400368 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400369
370 Resources res = context.getResources();
371
Daniel Sandler6e8db882011-10-26 15:40:51 -0400372 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400373 loadDimens();
Joe Onorato808182d2010-07-09 18:52:06 -0400374
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700375 mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
376
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400377 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
Daniel Sandlera310af82012-04-24 01:20:13 -0400378 R.layout.super_status_bar, null);
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400379 mStatusBarWindow.mService = this;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400380 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
381 @Override
382 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400383 checkUserAutohide(v, event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400384 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500385 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400386 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400387 }
388 }
Chris Wren5de6e942012-05-16 14:22:21 -0400389 return mStatusBarWindow.onTouchEvent(event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400390 }});
391
Daniel Sandlera310af82012-04-24 01:20:13 -0400392 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400393 mStatusBarView.setBar(this);
John Spurlock209bede2013-07-17 12:23:27 -0400394
Daniel Sandler08d05e32012-08-08 16:39:54 -0400395 PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
396 mStatusBarView.setPanelHolder(holder);
397
Daniel Sandler040c2e42012-10-17 00:56:33 -0400398 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(R.id.notification_panel);
399 mNotificationPanel.setStatusBar(this);
Daniel Sandler66d92f82012-06-13 13:36:52 -0400400 mNotificationPanelIsFullScreenWidth =
401 (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
Joe Onorato808182d2010-07-09 18:52:06 -0400402
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700403 // make the header non-responsive to clicks
404 mNotificationPanel.findViewById(R.id.header).setOnTouchListener(
405 new View.OnTouchListener() {
406 @Override
407 public boolean onTouch(View v, MotionEvent event) {
408 return true; // e eats everything
409 }
410 });
411
Jeff Brown98365d72012-08-19 20:30:52 -0700412 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700413 mStatusBarWindow.setBackground(null);
Romain Guy648342f2012-05-25 10:44:45 -0700414 mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
415 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700416 }
Chris Wren157026f2013-06-28 16:54:01 -0400417 if (ENABLE_HEADS_UP) {
418 mHeadsUpNotificationView =
419 (HeadsUpNotificationView) View.inflate(context, R.layout.heads_up, null);
420 mHeadsUpNotificationView.setVisibility(View.GONE);
421 mHeadsUpNotificationView.setBar(this);
Daniel Sandler6b318802012-04-13 14:05:19 -0400422 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400423 if (MULTIUSER_DEBUG) {
424 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info);
425 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
426 }
Joe Onorato808182d2010-07-09 18:52:06 -0400427
John Spurlockd5ef5462012-06-13 11:19:51 -0400428 updateShowSearchHoldoff();
429
Daniel Sandler0129b312011-05-11 11:54:11 -0400430 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700431 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400432 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400433 if (showNav) {
Jim Miller5e6af442011-12-02 18:24:26 -0800434 mNavigationBarView =
Daniel Sandler0129b312011-05-11 11:54:11 -0400435 (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400436
Daniel Sandler6da2b762011-09-14 16:04:59 -0400437 mNavigationBarView.setDisabledFlags(mDisabled);
Jim Millere898ac52012-04-06 17:10:57 -0700438 mNavigationBarView.setBar(this);
John Spurlock9deaa282013-07-25 13:03:47 -0400439 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
440 @Override
441 public boolean onTouch(View v, MotionEvent event) {
442 checkUserAutohide(v, event);
443 return false;
444 }});
Daniel Sandler0129b312011-05-11 11:54:11 -0400445 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400446 } catch (RemoteException ex) {
447 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400448 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400449
Joe Onorato808182d2010-07-09 18:52:06 -0400450 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400451 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400452
453 mSystemIconArea = (LinearLayout) mStatusBarView.findViewById(R.id.system_icon_area);
Daniel Sandlera310af82012-04-24 01:20:13 -0400454 mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons);
455 mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
Mats H Carlssoncd231432012-10-10 13:37:38 +0200456 mMoreIcon = mStatusBarView.findViewById(R.id.moreIcon);
Daniel Sandler05e24142011-11-10 11:56:49 -0500457 mNotificationIcons.setOverflowIndicator(mMoreIcon);
Daniel Sandler173bae22012-09-25 14:37:42 -0400458 mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
Daniel Sandlera310af82012-04-24 01:20:13 -0400459 mTickerView = mStatusBarView.findViewById(R.id.ticker);
Joe Onorato808182d2010-07-09 18:52:06 -0400460
Daniel Sandlera310af82012-04-24 01:20:13 -0400461 mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems);
Daniel Sandlere5011a32012-06-11 16:07:52 -0400462 mPile.setLayoutTransitionsEnabled(false);
Daniel Sandlerf7a19562012-04-04 14:04:21 -0400463 mPile.setLongPressListener(getNotificationLongClicker());
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400464 mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
Daniel Sandlerd7141482011-08-18 15:14:52 -0400465
Daniel Sandler3679bf52012-10-16 21:30:28 -0400466 mNotificationPanelHeader = mStatusBarWindow.findViewById(R.id.header);
467
Daniel Sandlera310af82012-04-24 01:20:13 -0400468 mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button);
Joe Onorato808182d2010-07-09 18:52:06 -0400469 mClearButton.setOnClickListener(mClearButtonListener);
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400470 mClearButton.setAlpha(0f);
Romain Guy8900e632012-05-25 12:08:39 -0700471 mClearButton.setVisibility(View.INVISIBLE);
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400472 mClearButton.setEnabled(false);
Daniel Sandlera310af82012-04-24 01:20:13 -0400473 mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400474
475 mHasSettingsPanel = res.getBoolean(R.bool.config_hasSettingsPanel);
Daniel Sandler101784e2012-10-15 13:39:38 -0400476 mHasFlipSettings = res.getBoolean(R.bool.config_hasFlipSettingsPanel);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400477
Daniel Sandler3679bf52012-10-16 21:30:28 -0400478 mDateTimeView = mNotificationPanelHeader.findViewById(R.id.datetime);
Daniel Sandler458d5e12013-02-21 15:12:49 -0500479 if (mDateTimeView != null) {
Daniel Sandler3679bf52012-10-16 21:30:28 -0400480 mDateTimeView.setOnClickListener(mClockClickListener);
481 mDateTimeView.setEnabled(true);
482 }
483
Daniel Sandlere111ad32012-10-13 15:17:45 -0400484 mSettingsButton = (ImageView) mStatusBarWindow.findViewById(R.id.settings_button);
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400485 if (mSettingsButton != null) {
Daniel Sandlere111ad32012-10-13 15:17:45 -0400486 mSettingsButton.setOnClickListener(mSettingsButtonListener);
487 if (mHasSettingsPanel) {
488 if (mStatusBarView.hasFullWidthNotifications()) {
489 // the settings panel is hiding behind this button
490 mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
491 mSettingsButton.setVisibility(View.VISIBLE);
492 } else {
493 // there is a settings panel, but it's on the other side of the (large) screen
Daniel Sandler7382a022012-10-22 14:36:50 -0400494 final View buttonHolder = mStatusBarWindow.findViewById(
495 R.id.settings_button_holder);
496 if (buttonHolder != null) {
497 buttonHolder.setVisibility(View.GONE);
498 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400499 }
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700500 } else {
Daniel Sandlere111ad32012-10-13 15:17:45 -0400501 // no settings panel, go straight to settings
502 mSettingsButton.setVisibility(View.VISIBLE);
503 mSettingsButton.setImageResource(R.drawable.ic_notify_settings);
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700504 }
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400505 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400506 if (mHasFlipSettings) {
507 mNotificationButton = (ImageView) mStatusBarWindow.findViewById(R.id.notification_button);
508 if (mNotificationButton != null) {
509 mNotificationButton.setOnClickListener(mNotificationButtonListener);
510 }
511 }
512
Daniel Sandlera310af82012-04-24 01:20:13 -0400513 mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll);
Daniel Sandler079b33d2012-03-02 16:29:41 -0500514 mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
Daniel Sandler3679bf52012-10-16 21:30:28 -0400515 if (!mNotificationPanelIsFullScreenWidth) {
516 mScrollView.setSystemUiVisibility(
Daniel Sandler3679bf52012-10-16 21:30:28 -0400517 View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
518 View.STATUS_BAR_DISABLE_CLOCK);
519 }
Joe Onorato808182d2010-07-09 18:52:06 -0400520
Daniel Sandlera310af82012-04-24 01:20:13 -0400521 mTicker = new MyTicker(context, mStatusBarView);
Joe Onorato808182d2010-07-09 18:52:06 -0400522
Daniel Sandlera310af82012-04-24 01:20:13 -0400523 TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText);
Joe Onorato808182d2010-07-09 18:52:06 -0400524 tickerView.mTicker = mTicker;
525
Joe Onorato808182d2010-07-09 18:52:06 -0400526 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
527
Joe Onorato808182d2010-07-09 18:52:06 -0400528 // set the inital view visibility
529 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400530
Daniel Sandler2b697352011-07-22 16:23:09 -0400531 // Other icons
532 mLocationController = new LocationController(mContext); // will post a notification
533 mBatteryController = new BatteryController(mContext);
Daniel Sandler2b697352011-07-22 16:23:09 -0400534 mNetworkController = new NetworkController(mContext);
Winson Chungd63c59782012-09-05 17:34:41 -0700535 mBluetoothController = new BluetoothController(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500536 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)
537 || QuickSettings.DEBUG_GONE_TILES) {
538 mRotationLockController = new RotationLockController(mContext);
539 }
Jim Miller5e6af442011-12-02 18:24:26 -0800540 final SignalClusterView signalCluster =
Daniel Sandlera310af82012-04-24 01:20:13 -0400541 (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
Daniel Sandler3d32a242012-06-05 13:44:14 -0400542
Winson Chungd63c59782012-09-05 17:34:41 -0700543
Christian Robertson2e347422011-08-11 14:01:04 -0700544 mNetworkController.addSignalCluster(signalCluster);
Daniel Sandler28f89d42011-08-15 14:04:15 -0400545 signalCluster.setNetworkController(mNetworkController);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400546
Daniel Sandler8b268d42013-05-28 16:17:13 -0400547 final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
548 if (isAPhone) {
549 mEmergencyCallLabel =
550 (TextView) mStatusBarWindow.findViewById(R.id.emergency_calls_only);
551 if (mEmergencyCallLabel != null) {
552 mNetworkController.addEmergencyLabelView(mEmergencyCallLabel);
553 mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() {
554 public void onClick(View v) { }});
555 mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
556 @Override
557 public void onLayoutChange(View v, int left, int top, int right, int bottom,
558 int oldLeft, int oldTop, int oldRight, int oldBottom) {
559 updateCarrierLabelVisibility(false);
560 }});
561 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400562 }
563
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400564 mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
565 mShowCarrierInPanel = (mCarrierLabel != null);
John Spurlockcd686b52013-06-05 10:13:46 -0400566 if (DEBUG) Log.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400567 if (mShowCarrierInPanel) {
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400568 mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
569
Daniel Sandler67234c42012-06-15 13:17:39 -0400570 // for mobile devices, we always show mobile connection info here (SPN/PLMN)
571 // for other devices, we show whatever network is connected
Daniel Sandler18ac7822012-06-11 16:07:18 -0400572 if (mNetworkController.hasMobileDataFeature()) {
573 mNetworkController.addMobileLabelView(mCarrierLabel);
574 } else {
Daniel Sandler67234c42012-06-15 13:17:39 -0400575 mNetworkController.addCombinedLabelView(mCarrierLabel);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400576 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400577
578 // set up the dynamic hide/show of the label
579 mPile.setOnSizeChangedListener(new OnSizeChangedListener() {
580 @Override
581 public void onSizeChanged(View view, int w, int h, int oldw, int oldh) {
582 updateCarrierLabelVisibility(false);
583 }
584 });
Daniel Sandler3d32a242012-06-05 13:44:14 -0400585 }
586
Daniel Sandlere111ad32012-10-13 15:17:45 -0400587 // Quick Settings (where available, some restrictions apply)
588 if (mHasSettingsPanel) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400589 // first, figure out where quick settings should be inflated
590 final View settings_stub;
591 if (mHasFlipSettings) {
592 // a version of quick settings that flips around behind the notifications
593 settings_stub = mStatusBarWindow.findViewById(R.id.flip_settings_stub);
594 if (settings_stub != null) {
595 mFlipSettingsView = ((ViewStub)settings_stub).inflate();
596 mFlipSettingsView.setVisibility(View.GONE);
597 mFlipSettingsView.setVerticalScrollBarEnabled(false);
598 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400599 } else {
Daniel Sandler101784e2012-10-15 13:39:38 -0400600 // full quick settings panel
601 settings_stub = mStatusBarWindow.findViewById(R.id.quick_settings_stub);
602 if (settings_stub != null) {
603 mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate();
604 } else {
605 mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
606 }
607
608 if (mSettingsPanel != null) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400609 if (!ActivityManager.isHighEndGfx()) {
610 mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
611 R.color.notification_panel_solid_background)));
612 }
613 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400614 }
615
Daniel Sandler101784e2012-10-15 13:39:38 -0400616 // wherever you find it, Quick Settings needs a container to survive
617 mSettingsContainer = (QuickSettingsContainerView)
618 mStatusBarWindow.findViewById(R.id.quick_settings_container);
619 if (mSettingsContainer != null) {
620 mQS = new QuickSettings(mContext, mSettingsContainer);
Daniel Sandler3679bf52012-10-16 21:30:28 -0400621 if (!mNotificationPanelIsFullScreenWidth) {
622 mSettingsContainer.setSystemUiVisibility(
Dan Sandlera5e0f412014-01-23 15:11:54 -0500623 View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS
Daniel Sandler3679bf52012-10-16 21:30:28 -0400624 | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
625 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400626 if (mSettingsPanel != null) {
627 mSettingsPanel.setQuickSettings(mQS);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400628 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400629 mQS.setService(this);
Daniel Sandlerfe3376b2012-10-16 19:54:02 -0400630 mQS.setBar(mStatusBarView);
Daniel Sandler101784e2012-10-15 13:39:38 -0400631 mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
Svetoslav79578b22013-04-29 16:55:57 -0700632 mLocationController, mRotationLockController);
Daniel Sandler101784e2012-10-15 13:39:38 -0400633 } else {
634 mQS = null; // fly away, be free
Daniel Sandlere111ad32012-10-13 15:17:45 -0400635 }
Siva Velusamy537421b2012-09-14 14:45:02 -0700636 }
637
John Spurlock56d007b2013-10-28 18:40:56 -0400638 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
639 mBroadcastReceiver.onReceive(mContext,
640 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
641
Joe Onorato808182d2010-07-09 18:52:06 -0400642 // receive broadcasts
643 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400644 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
645 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400646 filter.addAction(Intent.ACTION_SCREEN_ON);
John Spurlock3c875662013-08-31 15:07:25 -0400647 filter.addAction(ACTION_DEMO);
Joe Onorato808182d2010-07-09 18:52:06 -0400648 context.registerReceiver(mBroadcastReceiver, filter);
649
John Spurlock919adac2012-10-02 16:41:12 -0400650 // listen for USER_SETUP_COMPLETE setting (per-user)
651 resetUserSetupObserver();
652
Daniel Sandlera310af82012-04-24 01:20:13 -0400653 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400654 }
655
Michael Jurka7f2668c2012-03-27 07:49:52 -0700656 @Override
Jim Millerad178a42013-10-08 20:03:38 -0700657 protected void onShowSearchPanel() {
658 if (mNavigationBarView != null) {
John Spurlock56d007b2013-10-28 18:40:56 -0400659 mNavigationBarView.getBarTransitions().setContentVisible(false);
Jim Millerad178a42013-10-08 20:03:38 -0700660 }
661 }
662
663 @Override
664 protected void onHideSearchPanel() {
665 if (mNavigationBarView != null) {
John Spurlock56d007b2013-10-28 18:40:56 -0400666 mNavigationBarView.getBarTransitions().setContentVisible(true);
Jim Millerad178a42013-10-08 20:03:38 -0700667 }
668 }
669
670 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -0700671 protected View getStatusBarView() {
672 return mStatusBarView;
673 }
674
675 @Override
Jim Millere898ac52012-04-06 17:10:57 -0700676 protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
677 boolean opaque = false;
678 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
679 LayoutParams.MATCH_PARENT,
680 LayoutParams.MATCH_PARENT,
681 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
682 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
683 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
684 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
685 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
Jeff Brown98365d72012-08-19 20:30:52 -0700686 if (ActivityManager.isHighEndGfx()) {
Jim Millere898ac52012-04-06 17:10:57 -0700687 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Jim Millere898ac52012-04-06 17:10:57 -0700688 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700689 lp.gravity = Gravity.BOTTOM | Gravity.START;
Jim Millere898ac52012-04-06 17:10:57 -0700690 lp.setTitle("SearchPanel");
691 // TODO: Define custom animation for Search panel
692 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
693 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
694 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
695 return lp;
696 }
697
Jim Millere898ac52012-04-06 17:10:57 -0700698 @Override
699 protected void updateSearchPanel() {
700 super.updateSearchPanel();
John Spurlockf6b63972013-08-27 16:08:28 -0400701 if (mNavigationBarView != null) {
702 mNavigationBarView.setDelegateView(mSearchPanelView);
703 }
Jim Millere898ac52012-04-06 17:10:57 -0700704 }
705
706 @Override
707 public void showSearchPanel() {
Jim Millerb490c3e2012-05-31 13:34:16 -0700708 super.showSearchPanel();
John Spurlock7a733442012-11-08 09:08:14 -0500709 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlerd5483c32012-10-19 16:44:15 -0400710
711 // we want to freeze the sysui state wherever it is
712 mSearchPanelView.setSystemUiVisibility(mSystemUiVisibility);
713
John Spurlockf6b63972013-08-27 16:08:28 -0400714 if (mNavigationBarView != null) {
715 WindowManager.LayoutParams lp =
716 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
717 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
718 mWindowManager.updateViewLayout(mNavigationBarView, lp);
719 }
Jim Millere898ac52012-04-06 17:10:57 -0700720 }
721
722 @Override
723 public void hideSearchPanel() {
724 super.hideSearchPanel();
John Spurlockf6b63972013-08-27 16:08:28 -0400725 if (mNavigationBarView != null) {
726 WindowManager.LayoutParams lp =
727 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
728 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
729 mWindowManager.updateViewLayout(mNavigationBarView, lp);
730 }
Jim Millere898ac52012-04-06 17:10:57 -0700731 }
732
Joe Onorato808182d2010-07-09 18:52:06 -0400733 protected int getStatusBarGravity() {
734 return Gravity.TOP | Gravity.FILL_HORIZONTAL;
735 }
736
Joe Onoratodc100302011-01-11 17:07:41 -0800737 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -0400738 if (mNaturalBarHeight < 0) {
739 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -0700740 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -0400741 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
742 }
743 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -0800744 }
745
Daniel Sandler5c8da942011-06-28 00:29:04 -0400746 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
747 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -0400748 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400749 toggleRecentApps();
750 }
751 };
Chris Wren0c8275b2012-05-08 13:36:48 -0400752
Jim Miller9a720f52012-05-30 03:19:43 -0700753 private int mShowSearchHoldoff = 0;
754 private Runnable mShowSearchPanel = new Runnable() {
755 public void run() {
756 showSearchPanel();
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400757 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700758 }
759 };
760
Jim Millere898ac52012-04-06 17:10:57 -0700761 View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
762 public boolean onTouch(View v, MotionEvent event) {
763 switch(event.getAction()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700764 case MotionEvent.ACTION_DOWN:
Daniel Sandlerd5483c32012-10-19 16:44:15 -0400765 if (!shouldDisableNavbarGestures()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700766 mHandler.removeCallbacks(mShowSearchPanel);
767 mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
768 }
769 break;
770
771 case MotionEvent.ACTION_UP:
772 case MotionEvent.ACTION_CANCEL:
773 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400774 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700775 break;
776 }
777 return false;
Jim Millere898ac52012-04-06 17:10:57 -0700778 }
779 };
Daniel Sandler5c8da942011-06-28 00:29:04 -0400780
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400781 private void awakenDreams() {
782 if (mDreamManager != null) {
783 try {
784 mDreamManager.awaken();
785 } catch (RemoteException e) {
786 // fine, stay asleep then
787 }
788 }
789 }
790
Michael Jurka412cba82011-10-17 09:05:00 -0700791 private void prepareNavigationBarView() {
792 mNavigationBarView.reorient();
793
794 mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
Michael Jurka80343f62012-10-18 13:13:46 +0200795 mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
Jim Miller998bb762012-05-21 13:37:27 -0700796 mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
Daniel Sandler207d5482012-11-06 16:23:43 -0500797 mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
Jim Millere898ac52012-04-06 17:10:57 -0700798 updateSearchPanel();
Michael Jurka412cba82011-10-17 09:05:00 -0700799 }
800
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400801 // For small-screen devices (read: phones) that lack hardware navigation buttons
802 private void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -0400803 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -0400804 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700805
Michael Jurka412cba82011-10-17 09:05:00 -0700806 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400807
Jeff Brown98365d72012-08-19 20:30:52 -0700808 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400809 }
810
811 private void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -0400812 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700813
Michael Jurka412cba82011-10-17 09:05:00 -0700814 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400815
Jeff Brown98365d72012-08-19 20:30:52 -0700816 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400817 }
818
John Spurlock1bbd49d2012-10-19 11:09:32 -0400819 private void notifyNavigationBarScreenOn(boolean screenOn) {
820 if (mNavigationBarView == null) return;
821 mNavigationBarView.notifyScreenOn(screenOn);
822 }
823
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400824 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400825 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -0700826 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400827 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
828 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400829 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
830 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -0700831 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -0400832 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -0700833 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
John Spurlockad3e6cb2013-04-30 08:47:43 -0400834 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700835 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -0700836 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700837 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
838 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400839
840 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400841 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400842 return lp;
843 }
844
Chris Wren157026f2013-06-28 16:54:01 -0400845 private void addHeadsUpView() {
Joe Onorato808182d2010-07-09 18:52:06 -0400846 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Chris Wren0f2aa682013-08-02 12:03:02 -0400847 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
Chris Wren9afc50d2013-07-30 11:31:46 -0400848 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
Joe Onorato808182d2010-07-09 18:52:06 -0400849 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
850 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
851 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
852 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Jeff Brown46e75292010-11-10 16:53:45 -0800853 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
854 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Joe Onorato808182d2010-07-09 18:52:06 -0400855 PixelFormat.TRANSLUCENT);
Chris Wren51c75102013-07-16 20:49:17 -0400856 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Chris Wren0f2aa682013-08-02 12:03:02 -0400857 lp.gravity = Gravity.TOP;
858 lp.y = getStatusBarHeight();
Chris Wren157026f2013-06-28 16:54:01 -0400859 lp.setTitle("Heads Up");
Dianne Hackborn59aed382011-08-02 17:31:44 -0700860 lp.packageName = mContext.getPackageName();
Chris Wren157026f2013-06-28 16:54:01 -0400861 lp.windowAnimations = R.style.Animation_StatusBar_HeadsUp;
Joe Onorato808182d2010-07-09 18:52:06 -0400862
Chris Wren157026f2013-06-28 16:54:01 -0400863 mWindowManager.addView(mHeadsUpNotificationView, lp);
Joe Onorato808182d2010-07-09 18:52:06 -0400864 }
865
Chris Wrenf6e83f42013-09-11 14:02:59 -0400866 private void removeHeadsUpView() {
867 mWindowManager.removeView(mHeadsUpNotificationView);
868 }
869
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -0800870 public void refreshAllStatusBarIcons() {
Fabrice Di Meglioc0cea0f2013-01-11 16:18:00 -0800871 refreshAllIconsForLayout(mStatusIcons);
872 refreshAllIconsForLayout(mNotificationIcons);
873 }
874
875 private void refreshAllIconsForLayout(LinearLayout ll) {
876 final int count = ll.getChildCount();
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -0800877 for (int n = 0; n < count; n++) {
Fabrice Di Meglioc0cea0f2013-01-11 16:18:00 -0800878 View child = ll.getChildAt(n);
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -0800879 if (child instanceof StatusBarIconView) {
880 ((StatusBarIconView) child).updateDrawable();
881 }
882 }
883 }
884
Joe Onorato808182d2010-07-09 18:52:06 -0400885 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
John Spurlockcd686b52013-06-05 10:13:46 -0400886 if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
Joe Onorato808182d2010-07-09 18:52:06 -0400887 + " icon=" + icon);
John Spurlocke6f0a712013-09-03 16:23:49 -0400888 StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400889 view.set(icon);
890 mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
891 }
892
893 public void updateIcon(String slot, int index, int viewIndex,
894 StatusBarIcon old, StatusBarIcon icon) {
John Spurlockcd686b52013-06-05 10:13:46 -0400895 if (SPEW) Log.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
Joe Onorato808182d2010-07-09 18:52:06 -0400896 + " old=" + old + " icon=" + icon);
897 StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
898 view.set(icon);
899 }
900
901 public void removeIcon(String slot, int index, int viewIndex) {
John Spurlockcd686b52013-06-05 10:13:46 -0400902 if (SPEW) Log.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
Joe Onorato808182d2010-07-09 18:52:06 -0400903 mStatusIcons.removeViewAt(viewIndex);
904 }
905
906 public void addNotification(IBinder key, StatusBarNotification notification) {
John Spurlockcd686b52013-06-05 10:13:46 -0400907 if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore());
Chris Wrenf0048ce2013-08-07 16:43:43 -0400908 Entry shadeEntry = createNotificationViews(key, notification);
909 if (shadeEntry == null) {
910 return;
911 }
Chris Wren157026f2013-06-28 16:54:01 -0400912 if (mUseHeadsUp && shouldInterrupt(notification)) {
913 if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
Chris Wrend4db6cb2013-08-07 16:05:23 -0400914 Entry interruptionCandidate = new Entry(key, notification, null);
915 if (inflateViews(interruptionCandidate, mHeadsUpNotificationView.getHolder())) {
916 mInterruptingNotificationTime = System.currentTimeMillis();
917 mInterruptingNotificationEntry = interruptionCandidate;
Chris Wrenf0048ce2013-08-07 16:43:43 -0400918 shadeEntry.setInterruption();
Joe Onorato808182d2010-07-09 18:52:06 -0400919
Chris Wrend4db6cb2013-08-07 16:05:23 -0400920 // 1. Populate mHeadsUpNotificationView
Chris Wren51c75102013-07-16 20:49:17 -0400921 mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
Chris Wrend4db6cb2013-08-07 16:05:23 -0400922
Chris Wren157026f2013-06-28 16:54:01 -0400923 // 2. Animate mHeadsUpNotificationView in
924 mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
Joe Onorato808182d2010-07-09 18:52:06 -0400925
Chris Wren51c75102013-07-16 20:49:17 -0400926 // 3. Set alarm to age the notification off
927 resetHeadsUpDecayTimer();
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400928 }
Chris Wren157026f2013-06-28 16:54:01 -0400929 } else if (notification.getNotification().fullScreenIntent != null) {
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -0400930 // Stop screensaver if the notification has a full-screen intent.
931 // (like an incoming phone call)
932 awakenDreams();
933
Joe Onorato808182d2010-07-09 18:52:06 -0400934 // not immersive & a full-screen alert should be shown
John Spurlockcd686b52013-06-05 10:13:46 -0400935 if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
Joe Onorato808182d2010-07-09 18:52:06 -0400936 try {
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400937 notification.getNotification().fullScreenIntent.send();
Joe Onorato808182d2010-07-09 18:52:06 -0400938 } catch (PendingIntent.CanceledException e) {
939 }
940 } else {
941 // usual case: status bar visible & not immersive
942
Chris Wren157026f2013-06-28 16:54:01 -0400943 // show the ticker if there isn't already a heads up
Chris Wren51c75102013-07-16 20:49:17 -0400944 if (mInterruptingNotificationEntry == null) {
Chris Wren0c8275b2012-05-08 13:36:48 -0400945 tick(null, notification, true);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400946 }
Joe Onorato808182d2010-07-09 18:52:06 -0400947 }
Chris Wrenf0048ce2013-08-07 16:43:43 -0400948 addNotificationViews(shadeEntry);
Joe Onorato808182d2010-07-09 18:52:06 -0400949 // Recalculate the position of the sliding windows and the titles.
950 setAreThereNotifications();
951 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
952 }
953
Chris Wren51c75102013-07-16 20:49:17 -0400954 @Override
955 public void resetHeadsUpDecayTimer() {
Chris Wreneda110f2013-07-25 15:31:59 -0400956 if (mUseHeadsUp && mHeadsUpNotificationDecay > 0
Chris Wren6d15a362013-08-20 18:46:29 -0400957 && mHeadsUpNotificationView.isClearable()) {
958 mHandler.removeMessages(MSG_HIDE_HEADS_UP);
Chris Wren51c75102013-07-16 20:49:17 -0400959 mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay);
960 }
961 }
962
Joe Onorato808182d2010-07-09 18:52:06 -0400963 public void removeNotification(IBinder key) {
Joe Onorato808182d2010-07-09 18:52:06 -0400964 StatusBarNotification old = removeNotificationViews(key);
John Spurlockcd686b52013-06-05 10:13:46 -0400965 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -0400966
967 if (old != null) {
968 // Cancel the ticker if it's still running
969 mTicker.removeEntry(old);
970
971 // Recalculate the position of the sliding windows and the titles.
Joe Onorato808182d2010-07-09 18:52:06 -0400972 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Jim Millere898ac52012-04-06 17:10:57 -0700973
Chris Wren51c75102013-07-16 20:49:17 -0400974 if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
975 && old == mInterruptingNotificationEntry.notification) {
Chris Wren157026f2013-06-28 16:54:01 -0400976 mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400977 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400978
John Spurlock1caf7eb2013-08-07 18:06:18 -0400979 if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0
John Spurlocka4b70af2013-08-17 14:05:49 -0400980 && !mNotificationPanel.isTracking()) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400981 animateCollapsePanels();
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400982 }
Joe Onorato808182d2010-07-09 18:52:06 -0400983 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400984
985 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400986 }
987
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700988 @Override
989 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700990 if (mNavigationBarView != null) {
991 mNavigationBarView.setLayoutDirection(layoutDirection);
992 }
993
994 if (mClearButton != null && mClearButton instanceof ImageView) {
995 // Force asset reloading
996 ((ImageView)mClearButton).setImageDrawable(null);
997 ((ImageView)mClearButton).setImageResource(R.drawable.ic_notify_clear);
998 }
999
1000 if (mSettingsButton != null) {
1001 // Force asset reloading
1002 mSettingsButton.setImageDrawable(null);
1003 mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
1004 }
1005
1006 if (mNotificationButton != null) {
1007 // Force asset reloading
1008 mNotificationButton.setImageDrawable(null);
1009 mNotificationButton.setImageResource(R.drawable.ic_notifications);
1010 }
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -08001011
1012 refreshAllStatusBarIcons();
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001013 }
1014
John Spurlockd5ef5462012-06-13 11:19:51 -04001015 private void updateShowSearchHoldoff() {
1016 mShowSearchHoldoff = mContext.getResources().getInteger(
1017 R.integer.config_show_search_delay);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001018 }
1019
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001020 private void loadNotificationShade() {
Daniel Sandler26cda272012-05-22 15:44:08 -04001021 if (mPile == null) return;
1022
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001023 int N = mNotificationData.size();
1024
1025 ArrayList<View> toShow = new ArrayList<View>();
1026
Daniel Sandler26cda272012-05-22 15:44:08 -04001027 final boolean provisioned = isDeviceProvisioned();
1028 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001029 for (int i=0; i<N; i++) {
Daniel Sandler26cda272012-05-22 15:44:08 -04001030 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001031 if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
1032 if (!notificationIsForCurrentUser(ent.notification)) continue;
Dan Sandlera5e0f412014-01-23 15:11:54 -05001033 final int vis = ent.notification.getNotification().visibility;
1034 if (vis != Notification.VISIBILITY_SECRET) {
1035 // when isPublicMode() we show the public form of VISIBILITY_PRIVATE notifications
1036 ent.row.setShowingPublic(isPublicMode() && vis == Notification.VISIBILITY_PRIVATE);
1037 toShow.add(ent.row);
1038 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001039 }
1040
1041 ArrayList<View> toRemove = new ArrayList<View>();
1042 for (int i=0; i<mPile.getChildCount(); i++) {
1043 View child = mPile.getChildAt(i);
1044 if (!toShow.contains(child)) {
1045 toRemove.add(child);
Joe Onorato808182d2010-07-09 18:52:06 -04001046 }
1047 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001048
1049 for (View remove : toRemove) {
1050 mPile.removeView(remove);
1051 }
1052
1053 for (int i=0; i<toShow.size(); i++) {
1054 View v = toShow.get(i);
1055 if (v.getParent() == null) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001056 mPile.addView(v, i);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001057 }
1058 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001059
Daniel Sandler6e5fe432012-09-16 15:34:36 -04001060 if (mSettingsButton != null) {
1061 mSettingsButton.setEnabled(isDeviceProvisioned());
1062 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001063 }
1064
Chris Wren0c8275b2012-05-08 13:36:48 -04001065 @Override
1066 protected void updateNotificationIcons() {
Daniel Sandler26cda272012-05-22 15:44:08 -04001067 if (mNotificationIcons == null) return;
1068
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001069 loadNotificationShade();
1070
1071 final LinearLayout.LayoutParams params
1072 = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
1073
1074 int N = mNotificationData.size();
1075
1076 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001077 Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001078 }
1079
1080 ArrayList<View> toShow = new ArrayList<View>();
1081
Daniel Sandler26cda272012-05-22 15:44:08 -04001082 final boolean provisioned = isDeviceProvisioned();
1083 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001084 for (int i=0; i<N; i++) {
Daniel Sandler58b173b2012-05-03 11:25:29 -04001085 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -04001086 if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001087 || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
1088 if (!notificationIsForCurrentUser(ent.notification)) continue;
Dan Sandlera5e0f412014-01-23 15:11:54 -05001089 if (isPublicMode()
1090 && ent.notification.getNotification().visibility
1091 == Notification.VISIBILITY_SECRET) {
1092 // in "public" mode (atop a secure keyguard), secret notifs are totally hidden
1093 continue;
1094 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001095 toShow.add(ent.icon);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001096 }
1097
1098 ArrayList<View> toRemove = new ArrayList<View>();
1099 for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
1100 View child = mNotificationIcons.getChildAt(i);
1101 if (!toShow.contains(child)) {
1102 toRemove.add(child);
1103 }
1104 }
1105
1106 for (View remove : toRemove) {
1107 mNotificationIcons.removeView(remove);
1108 }
1109
1110 for (int i=0; i<toShow.size(); i++) {
1111 View v = toShow.get(i);
1112 if (v.getParent() == null) {
1113 mNotificationIcons.addView(v, i, params);
1114 }
1115 }
1116 }
1117
Daniel Sandlere5011a32012-06-11 16:07:52 -04001118 protected void updateCarrierLabelVisibility(boolean force) {
Daniel Sandlerbf526d12012-09-04 22:56:44 -04001119 if (!mShowCarrierInPanel) return;
John Spurlock209bede2013-07-17 12:23:27 -04001120 // The idea here is to only show the carrier label when there is enough room to see it,
Daniel Sandler3d32a242012-06-05 13:44:14 -04001121 // i.e. when there aren't enough notifications to fill the panel.
Chris Wren6d15a362013-08-20 18:46:29 -04001122 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001123 Log.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
Daniel Sandler3d32a242012-06-05 13:44:14 -04001124 mPile.getHeight(), mScrollView.getHeight(), mCarrierLabelHeight));
1125 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -04001126
1127 final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
1128 final boolean makeVisible =
1129 !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
Daniel Sandler101784e2012-10-15 13:39:38 -04001130 && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight)
1131 && mScrollView.getVisibility() == View.VISIBLE;
John Spurlock209bede2013-07-17 12:23:27 -04001132
Daniel Sandlere5011a32012-06-11 16:07:52 -04001133 if (force || mCarrierLabelVisible != makeVisible) {
Daniel Sandler3d32a242012-06-05 13:44:14 -04001134 mCarrierLabelVisible = makeVisible;
1135 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001136 Log.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
Daniel Sandler3d32a242012-06-05 13:44:14 -04001137 }
1138 mCarrierLabel.animate().cancel();
1139 if (makeVisible) {
1140 mCarrierLabel.setVisibility(View.VISIBLE);
1141 }
1142 mCarrierLabel.animate()
1143 .alpha(makeVisible ? 1f : 0f)
1144 //.setStartDelay(makeVisible ? 500 : 0)
1145 //.setDuration(makeVisible ? 750 : 100)
1146 .setDuration(150)
1147 .setListener(makeVisible ? null : new AnimatorListenerAdapter() {
1148 @Override
1149 public void onAnimationEnd(Animator animation) {
1150 if (!mCarrierLabelVisible) { // race
1151 mCarrierLabel.setVisibility(View.INVISIBLE);
1152 mCarrierLabel.setAlpha(0f);
1153 }
1154 }
1155 })
1156 .start();
1157 }
1158 }
1159
Chris Wren0c8275b2012-05-08 13:36:48 -04001160 @Override
1161 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001162 final boolean any = mNotificationData.size() > 0;
Joe Onorato808182d2010-07-09 18:52:06 -04001163
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001164 final boolean clearable = any && mNotificationData.hasClearableItems();
1165
Chris Wren6d15a362013-08-20 18:46:29 -04001166 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001167 Log.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001168 + " any=" + any + " clearable=" + clearable);
1169 }
1170
John Spurlock209bede2013-07-17 12:23:27 -04001171 if (mHasFlipSettings
1172 && mFlipSettingsView != null
Daniel Sandlerf249efc2012-10-17 16:42:36 -04001173 && mFlipSettingsView.getVisibility() == View.VISIBLE
1174 && mScrollView.getVisibility() != View.VISIBLE) {
1175 // the flip settings panel is unequivocally showing; we should not be shown
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001176 mClearButton.setVisibility(View.INVISIBLE);
1177 } else if (mClearButton.isShown()) {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001178 if (clearable != (mClearButton.getAlpha() == 1.0f)) {
Romain Guy8900e632012-05-25 12:08:39 -07001179 ObjectAnimator clearAnimation = ObjectAnimator.ofFloat(
1180 mClearButton, "alpha", clearable ? 1.0f : 0.0f).setDuration(250);
1181 clearAnimation.addListener(new AnimatorListenerAdapter() {
1182 @Override
1183 public void onAnimationEnd(Animator animation) {
1184 if (mClearButton.getAlpha() <= 0.0f) {
1185 mClearButton.setVisibility(View.INVISIBLE);
1186 }
1187 }
1188
1189 @Override
1190 public void onAnimationStart(Animator animation) {
1191 if (mClearButton.getAlpha() <= 0.0f) {
1192 mClearButton.setVisibility(View.VISIBLE);
1193 }
1194 }
1195 });
1196 clearAnimation.start();
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001197 }
1198 } else {
1199 mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
Romain Guy8900e632012-05-25 12:08:39 -07001200 mClearButton.setVisibility(clearable ? View.VISIBLE : View.INVISIBLE);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001201 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001202 mClearButton.setEnabled(clearable);
Romain Guy8900e632012-05-25 12:08:39 -07001203
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001204 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
1205 final boolean showDot = (any&&!areLightsOn());
1206 if (showDot != (nlo.getAlpha() == 1.0f)) {
1207 if (showDot) {
1208 nlo.setAlpha(0f);
1209 nlo.setVisibility(View.VISIBLE);
1210 }
1211 nlo.animate()
1212 .alpha(showDot?1:0)
1213 .setDuration(showDot?750:250)
1214 .setInterpolator(new AccelerateInterpolator(2.0f))
1215 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1216 @Override
1217 public void onAnimationEnd(Animator _a) {
1218 nlo.setVisibility(View.GONE);
1219 }
1220 })
1221 .start();
1222 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001223
Daniel Sandlere5011a32012-06-11 16:07:52 -04001224 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001225 }
1226
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001227 public void showClock(boolean show) {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001228 if (mStatusBarView == null) return;
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001229 View clock = mStatusBarView.findViewById(R.id.clock);
1230 if (clock != null) {
1231 clock.setVisibility(show ? View.VISIBLE : View.GONE);
1232 }
1233 }
Joe Onorato808182d2010-07-09 18:52:06 -04001234
1235 /**
1236 * State is one or more of the DISABLE constants from StatusBarManager.
1237 */
1238 public void disable(int state) {
1239 final int old = mDisabled;
1240 final int diff = state ^ old;
1241 mDisabled = state;
1242
Daniel Sandlere21f2882011-08-18 10:14:59 -04001243 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001244 Log.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
Daniel Sandlere21f2882011-08-18 10:14:59 -04001245 old, state, diff));
1246 }
1247
Daniel Sandler6da2b762011-09-14 16:04:59 -04001248 StringBuilder flagdbg = new StringBuilder();
1249 flagdbg.append("disable: < ");
1250 flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
1251 flagdbg.append(((diff & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
1252 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
1253 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
1254 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
1255 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
Dan Sandlera5e0f412014-01-23 15:11:54 -05001256 flagdbg.append(((state & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) ? "PRIVATE" : "private");
1257 flagdbg.append(((diff & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001258 flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
1259 flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001260 flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
1261 flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
Daniel Sandlerdba93562011-10-06 16:39:58 -04001262 flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
1263 flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
1264 flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
1265 flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001266 flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
1267 flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001268 flagdbg.append(((state & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
1269 flagdbg.append(((diff & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001270 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04001271 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07001272
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001273 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001274 mSystemIconArea.animate().cancel();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001275 if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001276 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001277 .alpha(0f)
1278 .translationY(mNaturalBarHeight*0.5f)
Daniel Sandler67e7d902012-06-06 16:32:21 -04001279 .setDuration(175)
1280 .setInterpolator(new DecelerateInterpolator(1.5f))
1281 .setListener(mMakeIconsInvisible)
1282 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001283 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001284 mSystemIconArea.setVisibility(View.VISIBLE);
1285 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001286 .alpha(1f)
1287 .translationY(0)
1288 .setStartDelay(0)
1289 .setInterpolator(new DecelerateInterpolator(1.5f))
1290 .setDuration(175)
1291 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001292 }
1293 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04001294
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001295 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
1296 boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
1297 showClock(show);
1298 }
Joe Onorato808182d2010-07-09 18:52:06 -04001299 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1300 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001301 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04001302 }
1303 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001304
Jim Miller5e6af442011-12-02 18:24:26 -08001305 if ((diff & (StatusBarManager.DISABLE_HOME
1306 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001307 | StatusBarManager.DISABLE_BACK
1308 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04001309 // the nav bar will take care of these
Daniel Sandlerd9283b902011-09-14 21:42:00 -04001310 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001311
Daniel Sandlerdba93562011-10-06 16:39:58 -04001312 if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04001313 // close recents if it's visible
1314 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1315 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1316 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001317 }
1318
Joe Onorato808182d2010-07-09 18:52:06 -04001319 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1320 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Joe Onorato808182d2010-07-09 18:52:06 -04001321 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001322 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001323 }
Daniel Sandler173bae22012-09-25 14:37:42 -04001324
1325 mNotificationIcons.animate()
1326 .alpha(0f)
1327 .translationY(mNaturalBarHeight*0.5f)
1328 .setDuration(175)
1329 .setInterpolator(new DecelerateInterpolator(1.5f))
1330 .setListener(mMakeIconsInvisible)
1331 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001332 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001333 mNotificationIcons.setVisibility(View.VISIBLE);
1334 mNotificationIcons.animate()
1335 .alpha(1f)
1336 .translationY(0)
1337 .setStartDelay(0)
1338 .setInterpolator(new DecelerateInterpolator(1.5f))
1339 .setDuration(175)
1340 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001341 }
Dan Sandlera5e0f412014-01-23 15:11:54 -05001342 } else if ((diff & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) {
1343 if ((state & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) {
1344 // we are outside a secure keyguard, so we need to switch to "public" mode
1345 setPublicMode(true);
1346 } else {
1347 // user has authenticated the device; full notifications may be shown
1348 setPublicMode(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001349 }
Dan Sandlera5e0f412014-01-23 15:11:54 -05001350 updateNotificationIcons();
Joe Onorato808182d2010-07-09 18:52:06 -04001351 }
1352 }
1353
Michael Jurka7f2668c2012-03-27 07:49:52 -07001354 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07001355 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001356 return new PhoneStatusBar.H();
1357 }
1358
Joe Onorato808182d2010-07-09 18:52:06 -04001359 /**
1360 * All changes to the status bar and notifications funnel through here and are batched.
1361 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07001362 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04001363 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001364 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04001365 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001366 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04001367 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001368 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04001369 case MSG_OPEN_SETTINGS_PANEL:
1370 animateExpandSettingsPanel();
1371 break;
1372 case MSG_CLOSE_PANELS:
1373 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001374 break;
Chris Wren157026f2013-06-28 16:54:01 -04001375 case MSG_SHOW_HEADS_UP:
1376 setHeadsUpVisibility(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001377 break;
Chris Wren157026f2013-06-28 16:54:01 -04001378 case MSG_HIDE_HEADS_UP:
1379 setHeadsUpVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001380 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04001381 case MSG_ESCALATE_HEADS_UP:
1382 escalateHeadsUp();
1383 setHeadsUpVisibility(false);
Chris Wrene97f90b2013-08-07 17:39:35 -04001384 break;
1385 }
1386 }
1387 }
1388
1389 /** if the interrupting notification had a fullscreen intent, fire it now. */
1390 private void escalateHeadsUp() {
1391 if (mInterruptingNotificationEntry != null) {
1392 final StatusBarNotification sbn = mInterruptingNotificationEntry.notification;
1393 final Notification notification = sbn.getNotification();
1394 if (notification.fullScreenIntent != null) {
1395 if (DEBUG)
1396 Log.d(TAG, "converting a heads up to fullScreen");
1397 try {
1398 notification.fullScreenIntent.send();
1399 } catch (PendingIntent.CanceledException e) {
1400 }
Joe Onorato808182d2010-07-09 18:52:06 -04001401 }
1402 }
1403 }
1404
Daniel Sandler040c2e42012-10-17 00:56:33 -04001405 public Handler getHandler() {
1406 return mHandler;
1407 }
1408
Joe Onorato808182d2010-07-09 18:52:06 -04001409 View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
1410 public void onFocusChange(View v, boolean hasFocus) {
1411 // Because 'v' is a ViewGroup, all its children will be (un)selected
1412 // too, which allows marqueeing to work.
1413 v.setSelected(hasFocus);
1414 }
1415 };
1416
John Spurlock97642182013-07-29 17:58:39 -04001417 boolean panelsEnabled() {
John Spurlock79ec2a12013-09-11 09:28:49 -04001418 return (mDisabled & StatusBarManager.DISABLE_EXPAND) == 0;
John Spurlock97642182013-07-29 17:58:39 -04001419 }
1420
John Spurlocka5baf892013-07-25 13:15:42 -04001421 void makeExpandedVisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04001422 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04001423 if (mExpandedVisible || !panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04001424 return;
1425 }
Jim Millera073e572012-05-23 17:03:27 -07001426
Joe Onorato808182d2010-07-09 18:52:06 -04001427 mExpandedVisible = true;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001428 mPile.setLayoutTransitionsEnabled(true);
John Spurlockd5ef5462012-06-13 11:19:51 -04001429 if (mNavigationBarView != null)
1430 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001431
Daniel Sandlere5011a32012-06-11 16:07:52 -04001432 updateCarrierLabelVisibility(true);
Daniel Sandler3d32a242012-06-05 13:44:14 -04001433
Joe Onorato808182d2010-07-09 18:52:06 -04001434 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Daniel Sandlera310af82012-04-24 01:20:13 -04001435
1436 // Expand the window to encompass the full screen in anticipation of the drag.
1437 // This is only possible to do atomically because the status bar is at the top of the screen!
1438 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001439 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1440 lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Daniel Sandler21b274e2012-05-02 15:07:51 -04001441 lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
Jeff Brown98365d72012-08-19 20:30:52 -07001442 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Daniel Sandlera310af82012-04-24 01:20:13 -04001443
1444 visibilityChanged(true);
John Spurlock32beb2c2013-03-11 10:16:47 -04001445
John Spurlockcfc359a2013-09-05 10:42:03 -04001446 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
Joe Onorato808182d2010-07-09 18:52:06 -04001447 }
1448
John Spurlock37d608d2013-09-15 09:07:51 -04001449 private void releaseFocus() {
John Spurlockab847cf2014-01-15 14:13:59 -05001450 if (mStatusBarWindow == null) return;
John Spurlock37d608d2013-09-15 09:07:51 -04001451 WindowManager.LayoutParams lp =
1452 (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
1453 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1454 lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
1455 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
1456 }
1457
Daniel Sandler11cf1782012-09-27 14:03:08 -04001458 public void animateCollapsePanels() {
1459 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001460 }
1461
Daniel Sandler11cf1782012-09-27 14:03:08 -04001462 public void animateCollapsePanels(int flags) {
Joe Onorato808182d2010-07-09 18:52:06 -04001463 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001464 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04001465 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07001466 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04001467 }
1468
John Spurlock37d608d2013-09-15 09:07:51 -04001469 // release focus immediately to kick off focus change transition
1470 releaseFocus();
1471
Jim Miller9a720f52012-05-30 03:19:43 -07001472 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Michael Jurka3b1fc472011-06-13 10:54:40 -07001473 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1474 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1475 }
Jim Miller9a720f52012-05-30 03:19:43 -07001476
1477 if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
1478 mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
1479 mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
1480 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07001481
John Spurlockab847cf2014-01-15 14:13:59 -05001482 if (mStatusBarWindow != null) {
1483 mStatusBarWindow.cancelExpandHelper();
1484 mStatusBarView.collapseAllPanels(true);
1485 }
Joe Onorato808182d2010-07-09 18:52:06 -04001486 }
1487
Daniel Sandler101784e2012-10-15 13:39:38 -04001488 public ViewPropertyAnimator setVisibilityWhenDone(
1489 final ViewPropertyAnimator a, final View v, final int vis) {
1490 a.setListener(new AnimatorListenerAdapter() {
1491 @Override
1492 public void onAnimationEnd(Animator animation) {
1493 v.setVisibility(vis);
1494 a.setListener(null); // oneshot
1495 }
1496 });
1497 return a;
1498 }
1499
1500 public Animator setVisibilityWhenDone(
1501 final Animator a, final View v, final int vis) {
1502 a.addListener(new AnimatorListenerAdapter() {
1503 @Override
1504 public void onAnimationEnd(Animator animation) {
1505 v.setVisibility(vis);
1506 }
1507 });
1508 return a;
1509 }
1510
1511 public Animator interpolator(TimeInterpolator ti, Animator a) {
1512 a.setInterpolator(ti);
1513 return a;
1514 }
1515
1516 public Animator startDelay(int d, Animator a) {
1517 a.setStartDelay(d);
1518 return a;
1519 }
John Spurlock209bede2013-07-17 12:23:27 -04001520
Daniel Sandler101784e2012-10-15 13:39:38 -04001521 public Animator start(Animator a) {
1522 a.start();
1523 return a;
1524 }
1525
1526 final TimeInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
1527 final TimeInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
1528 final int FLIP_DURATION_OUT = 125;
1529 final int FLIP_DURATION_IN = 225;
1530 final int FLIP_DURATION = (FLIP_DURATION_IN + FLIP_DURATION_OUT);
1531
1532 Animator mScrollViewAnim, mFlipSettingsViewAnim, mNotificationButtonAnim,
1533 mSettingsButtonAnim, mClearButtonAnim;
1534
Daniel Sandler08d05e32012-08-08 16:39:54 -04001535 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001536 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04001537 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04001538 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04001539 return ;
1540 }
Joe Onorato808182d2010-07-09 18:52:06 -04001541
Daniel Sandler08d05e32012-08-08 16:39:54 -04001542 mNotificationPanel.expand();
Daniel Sandler040c2e42012-10-17 00:56:33 -04001543 if (mHasFlipSettings && mScrollView.getVisibility() != View.VISIBLE) {
1544 flipToNotifications();
Daniel Sandler101784e2012-10-15 13:39:38 -04001545 }
Joe Onorato808182d2010-07-09 18:52:06 -04001546
1547 if (false) postStartTracing();
1548 }
1549
Daniel Sandler040c2e42012-10-17 00:56:33 -04001550 public void flipToNotifications() {
1551 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1552 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1553 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1554 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1555 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1556
1557 mScrollView.setVisibility(View.VISIBLE);
1558 mScrollViewAnim = start(
1559 startDelay(FLIP_DURATION_OUT,
1560 interpolator(mDecelerateInterpolator,
1561 ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f, 1f)
1562 .setDuration(FLIP_DURATION_IN)
1563 )));
1564 mFlipSettingsViewAnim = start(
1565 setVisibilityWhenDone(
1566 interpolator(mAccelerateInterpolator,
1567 ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f, 0f)
1568 )
1569 .setDuration(FLIP_DURATION_OUT),
1570 mFlipSettingsView, View.INVISIBLE));
1571 mNotificationButtonAnim = start(
1572 setVisibilityWhenDone(
1573 ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
1574 .setDuration(FLIP_DURATION),
1575 mNotificationButton, View.INVISIBLE));
1576 mSettingsButton.setVisibility(View.VISIBLE);
1577 mSettingsButtonAnim = start(
1578 ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
1579 .setDuration(FLIP_DURATION));
1580 mClearButton.setVisibility(View.VISIBLE);
1581 mClearButton.setAlpha(0f);
1582 setAreThereNotifications(); // this will show/hide the button as necessary
1583 mNotificationPanel.postDelayed(new Runnable() {
1584 public void run() {
1585 updateCarrierLabelVisibility(false);
1586 }
1587 }, FLIP_DURATION - 150);
1588 }
1589
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001590 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001591 public void animateExpandSettingsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04001592 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04001593 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001594 return;
1595 }
1596
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001597 // Settings are not available in setup
1598 if (!mUserSetup) return;
1599
Daniel Sandler101784e2012-10-15 13:39:38 -04001600 if (mHasFlipSettings) {
1601 mNotificationPanel.expand();
1602 if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
Daniel Sandler040c2e42012-10-17 00:56:33 -04001603 flipToSettings();
Daniel Sandler101784e2012-10-15 13:39:38 -04001604 }
1605 } else if (mSettingsPanel != null) {
1606 mSettingsPanel.expand();
1607 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001608
1609 if (false) postStartTracing();
1610 }
1611
Daniel Sandler040c2e42012-10-17 00:56:33 -04001612 public void switchToSettings() {
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001613 // Settings are not available in setup
1614 if (!mUserSetup) return;
1615
Daniel Sandler040c2e42012-10-17 00:56:33 -04001616 mFlipSettingsView.setScaleX(1f);
1617 mFlipSettingsView.setVisibility(View.VISIBLE);
1618 mSettingsButton.setVisibility(View.GONE);
1619 mScrollView.setVisibility(View.GONE);
Daniel Sandler720a34d2012-10-18 11:44:04 -04001620 mScrollView.setScaleX(0f);
Daniel Sandler040c2e42012-10-17 00:56:33 -04001621 mNotificationButton.setVisibility(View.VISIBLE);
1622 mNotificationButton.setAlpha(1f);
1623 mClearButton.setVisibility(View.GONE);
1624 }
1625
1626 public void flipToSettings() {
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001627 // Settings are not available in setup
1628 if (!mUserSetup) return;
1629
Daniel Sandler040c2e42012-10-17 00:56:33 -04001630 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1631 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1632 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1633 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1634 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1635
1636 mFlipSettingsView.setVisibility(View.VISIBLE);
1637 mFlipSettingsView.setScaleX(0f);
1638 mFlipSettingsViewAnim = start(
1639 startDelay(FLIP_DURATION_OUT,
1640 interpolator(mDecelerateInterpolator,
1641 ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f, 1f)
1642 .setDuration(FLIP_DURATION_IN)
1643 )));
1644 mScrollViewAnim = start(
1645 setVisibilityWhenDone(
1646 interpolator(mAccelerateInterpolator,
1647 ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f)
1648 )
John Spurlock209bede2013-07-17 12:23:27 -04001649 .setDuration(FLIP_DURATION_OUT),
Daniel Sandler040c2e42012-10-17 00:56:33 -04001650 mScrollView, View.INVISIBLE));
1651 mSettingsButtonAnim = start(
1652 setVisibilityWhenDone(
1653 ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
1654 .setDuration(FLIP_DURATION),
1655 mScrollView, View.INVISIBLE));
1656 mNotificationButton.setVisibility(View.VISIBLE);
1657 mNotificationButtonAnim = start(
1658 ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
1659 .setDuration(FLIP_DURATION));
1660 mClearButtonAnim = start(
1661 setVisibilityWhenDone(
1662 ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
1663 .setDuration(FLIP_DURATION),
1664 mClearButton, View.INVISIBLE));
1665 mNotificationPanel.postDelayed(new Runnable() {
1666 public void run() {
1667 updateCarrierLabelVisibility(false);
1668 }
1669 }, FLIP_DURATION - 150);
1670 }
1671
1672 public void flipPanels() {
1673 if (mHasFlipSettings) {
1674 if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
1675 flipToSettings();
1676 } else {
1677 flipToNotifications();
1678 }
1679 }
1680 }
1681
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001682 public void animateCollapseQuickSettings() {
1683 mStatusBarView.collapseAllPanels(true);
1684 }
1685
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001686 void makeExpandedInvisibleSoon() {
1687 mHandler.postDelayed(new Runnable() { public void run() { makeExpandedInvisible(); }}, 50);
1688 }
1689
Daniel Sandler08d05e32012-08-08 16:39:54 -04001690 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04001691 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04001692 + " mExpandedVisible=" + mExpandedVisible);
1693
John Spurlockab847cf2014-01-15 14:13:59 -05001694 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04001695 return;
1696 }
Daniel Sandlered930e52012-07-03 14:31:22 -04001697
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04001698 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
1699 mStatusBarView.collapseAllPanels(/*animate=*/ false);
Daniel Sandlered930e52012-07-03 14:31:22 -04001700
Daniel Sandler040c2e42012-10-17 00:56:33 -04001701 if (mHasFlipSettings) {
1702 // reset things to their proper state
Daniel Sandler50bc4f52012-10-22 14:47:55 -04001703 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1704 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1705 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1706 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1707 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1708
Daniel Sandler040c2e42012-10-17 00:56:33 -04001709 mScrollView.setScaleX(1f);
1710 mScrollView.setVisibility(View.VISIBLE);
1711 mSettingsButton.setAlpha(1f);
1712 mSettingsButton.setVisibility(View.VISIBLE);
1713 mNotificationPanel.setVisibility(View.GONE);
1714 mFlipSettingsView.setVisibility(View.GONE);
1715 mNotificationButton.setVisibility(View.GONE);
1716 setAreThereNotifications(); // show the clear button
1717 }
1718
Joe Onorato808182d2010-07-09 18:52:06 -04001719 mExpandedVisible = false;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001720 mPile.setLayoutTransitionsEnabled(false);
John Spurlockd5ef5462012-06-13 11:19:51 -04001721 if (mNavigationBarView != null)
1722 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001723 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04001724
1725 // Shrink the window to the size of the status bar only
1726 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
1727 lp.height = getStatusBarHeight();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001728 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1729 lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jeff Brown98365d72012-08-19 20:30:52 -07001730 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04001731
1732 if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
1733 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1734 }
Joe Onorato808182d2010-07-09 18:52:06 -04001735
Daniel Sandler469e96e2012-05-04 15:56:19 -04001736 // Close any "App info" popups that might have snuck on-screen
1737 dismissPopups();
1738
Chet Haase2f2022a2011-10-11 06:41:59 -07001739 if (mPostCollapseCleanup != null) {
1740 mPostCollapseCleanup.run();
1741 mPostCollapseCleanup = null;
1742 }
John Spurlock32beb2c2013-03-11 10:16:47 -04001743
John Spurlockcfc359a2013-09-05 10:42:03 -04001744 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Joe Onorato808182d2010-07-09 18:52:06 -04001745 }
1746
Romain Guy54ab3472012-06-14 12:52:53 -07001747 /**
1748 * Enables or disables layers on the children of the notifications pile.
John Spurlock209bede2013-07-17 12:23:27 -04001749 *
Romain Guy54ab3472012-06-14 12:52:53 -07001750 * When layers are enabled, this method attempts to enable layers for the minimal
1751 * number of children. Only children visible when the notification area is fully
1752 * expanded will receive a layer. The technique used in this method might cause
1753 * more children than necessary to get a layer (at most one extra child with the
1754 * current UI.)
John Spurlock209bede2013-07-17 12:23:27 -04001755 *
Romain Guy54ab3472012-06-14 12:52:53 -07001756 * @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE}
1757 */
1758 private void setPileLayers(int layerType) {
1759 final int count = mPile.getChildCount();
1760
1761 switch (layerType) {
1762 case View.LAYER_TYPE_NONE:
1763 for (int i = 0; i < count; i++) {
1764 mPile.getChildAt(i).setLayerType(layerType, null);
1765 }
1766 break;
1767 case View.LAYER_TYPE_HARDWARE:
John Spurlock209bede2013-07-17 12:23:27 -04001768 final int[] location = new int[2];
Romain Guy54ab3472012-06-14 12:52:53 -07001769 mNotificationPanel.getLocationInWindow(location);
1770
1771 final int left = location[0];
1772 final int top = location[1];
1773 final int right = left + mNotificationPanel.getWidth();
1774 final int bottom = top + getExpandedViewMaxHeight();
1775
1776 final Rect childBounds = new Rect();
1777
1778 for (int i = 0; i < count; i++) {
1779 final View view = mPile.getChildAt(i);
1780 view.getLocationInWindow(location);
1781
1782 childBounds.set(location[0], location[1],
1783 location[0] + view.getWidth(), location[1] + view.getHeight());
1784
1785 if (childBounds.intersects(left, top, right, bottom)) {
1786 view.setLayerType(layerType, null);
1787 }
1788 }
1789
1790 break;
1791 }
1792 }
1793
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001794 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05001795 if (DEBUG_GESTURES) {
1796 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
1797 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
1798 event.getActionMasked(), (int) event.getX(), (int) event.getY(), mDisabled);
1799 }
1800
1801 }
1802
Joe Onorato808182d2010-07-09 18:52:06 -04001803 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001804 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
John Spurlock804df702012-06-01 15:34:27 -04001805 + mDisabled + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001806 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001807 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04001808 Log.d(TAG, String.format(
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001809 "panel: %s at (%f, %f) mDisabled=0x%08x",
1810 MotionEvent.actionToString(event.getAction()),
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001811 event.getRawX(), event.getRawY(), mDisabled));
1812 }
Joe Onorato808182d2010-07-09 18:52:06 -04001813 }
1814
Daniel Sandler151f00d2012-10-02 22:33:08 -04001815 if (DEBUG_GESTURES) {
1816 mGestureRec.add(event);
1817 }
Daniel Sandler33805342012-07-23 15:45:12 -04001818
John Spurlock686820a2013-09-03 14:44:16 -04001819 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04001820 final boolean upOrCancel =
1821 event.getAction() == MotionEvent.ACTION_UP ||
1822 event.getAction() == MotionEvent.ACTION_CANCEL;
1823 if (upOrCancel && !mExpandedVisible) {
1824 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
1825 } else {
1826 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
1827 }
John Spurlock686820a2013-09-03 14:44:16 -04001828 }
Joe Onorato808182d2010-07-09 18:52:06 -04001829 return false;
1830 }
1831
Daniel Sandler08d05e32012-08-08 16:39:54 -04001832 public GestureRecorder getGestureRecorder() {
1833 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07001834 }
1835
John Spurlock56d007b2013-10-28 18:40:56 -04001836 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04001837 if (hints == mNavigationIconHints) return;
1838
1839 mNavigationIconHints = hints;
1840
1841 if (mNavigationBarView != null) {
1842 mNavigationBarView.setNavigationIconHints(hints);
1843 }
John Spurlockd4e65752013-08-28 14:17:09 -04001844 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04001845 }
1846
1847 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04001848 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04001849 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04001850 if (mStatusBarWindow != null
1851 && window == StatusBarManager.WINDOW_STATUS_BAR
1852 && mStatusBarWindowState != state) {
1853 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04001854 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
John Spurlock5b9145b2013-08-20 15:13:47 -04001855 if (!showing) {
John Spurlock97642182013-07-29 17:58:39 -04001856 mStatusBarView.collapseAllPanels(false);
John Spurlock97642182013-07-29 17:58:39 -04001857 }
1858 }
1859 if (mNavigationBarView != null
1860 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
1861 && mNavigationBarWindowState != state) {
1862 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04001863 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04001864 }
1865 }
1866
John Spurlock97642182013-07-29 17:58:39 -04001867 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001868 public void setSystemUiVisibility(int vis, int mask) {
1869 final int oldVal = mSystemUiVisibility;
1870 final int newVal = (oldVal&~mask) | (vis&mask);
1871 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04001872 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04001873 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
1874 Integer.toHexString(vis), Integer.toHexString(mask),
1875 Integer.toHexString(oldVal), Integer.toHexString(newVal),
1876 Integer.toHexString(diff)));
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001877 if (diff != 0) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001878 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04001879
John Spurlocke1f366f2013-08-05 12:22:40 -04001880 // update low profile
1881 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
1882 final boolean lightsOut = (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001883 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001884 animateCollapsePanels();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001885 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001886 haltTicker();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001887 }
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001888 }
Jim Millera073e572012-05-23 17:03:27 -07001889
John Spurlock7edfbca2013-09-14 11:58:55 -04001890 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04001891 }
1892
John Spurlocke1f366f2013-08-05 12:22:40 -04001893 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04001894 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04001895 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04001896
1897 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04001898 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04001899 oldVal, newVal, mNavigationBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04001900 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT);
John Spurlockd4e65752013-08-28 14:17:09 -04001901 final boolean sbModeChanged = sbMode != -1;
1902 final boolean nbModeChanged = nbMode != -1;
1903 boolean checkBarModes = false;
1904 if (sbModeChanged && sbMode != mStatusBarMode) {
1905 mStatusBarMode = sbMode;
1906 checkBarModes = true;
1907 }
1908 if (nbModeChanged && nbMode != mNavigationBarMode) {
1909 mNavigationBarMode = nbMode;
1910 checkBarModes = true;
1911 }
1912 if (checkBarModes) {
1913 checkBarModes();
1914 }
1915 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04001916 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05001917 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04001918 scheduleAutohide();
1919 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04001920 cancelAutohide();
1921 }
1922 }
John Spurlocke1f366f2013-08-05 12:22:40 -04001923
John Spurlock5b9145b2013-08-20 15:13:47 -04001924 // ready to unhide
1925 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
1926 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
1927 }
1928 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
1929 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
1930 }
1931
John Spurlocke1f366f2013-08-05 12:22:40 -04001932 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04001933 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04001934 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001935 }
1936
John Spurlockd4e65752013-08-28 14:17:09 -04001937 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
John Spurlockbd957402013-10-03 11:38:39 -04001938 int transientFlag, int translucentFlag) {
1939 final int oldMode = barMode(oldVis, transientFlag, translucentFlag);
1940 final int newMode = barMode(newVis, transientFlag, translucentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04001941 if (oldMode == newMode) {
1942 return -1; // no mode change
1943 }
John Spurlocke1f366f2013-08-05 12:22:40 -04001944 return newMode;
1945 }
1946
John Spurlockbd957402013-10-03 11:38:39 -04001947 private int barMode(int vis, int transientFlag, int translucentFlag) {
John Spurlock89835dd2013-08-16 15:06:51 -04001948 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04001949 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
John Spurlock7edfbca2013-09-14 11:58:55 -04001950 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04001951 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04001952 }
1953
John Spurlockd4e65752013-08-28 14:17:09 -04001954 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04001955 if (mDemoMode) return;
John Spurlock3d7e0952013-10-13 13:34:21 -04001956 int sbMode = mStatusBarMode;
1957 if (panelsEnabled() && (mInteractingWindows & StatusBarManager.WINDOW_STATUS_BAR) != 0) {
1958 // if panels are expandable, force the status bar opaque on any interaction
1959 sbMode = MODE_OPAQUE;
1960 }
1961 checkBarMode(sbMode, mStatusBarWindowState, mStatusBarView.getBarTransitions());
John Spurlockd4e65752013-08-28 14:17:09 -04001962 if (mNavigationBarView != null) {
1963 checkBarMode(mNavigationBarMode,
1964 mNavigationBarWindowState, mNavigationBarView.getBarTransitions());
1965 }
1966 }
1967
1968 private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
John Spurlock8c520422013-09-19 12:23:35 -04001969 final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN;
John Spurlockc68d5772013-10-08 11:47:58 -04001970 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04001971 }
1972
John Spurlock42197262013-10-21 09:32:25 -04001973 private void finishBarAnimations() {
1974 mStatusBarView.getBarTransitions().finishAnimations();
1975 if (mNavigationBarView != null) {
1976 mNavigationBarView.getBarTransitions().finishAnimations();
1977 }
1978 }
1979
John Spurlockd4e65752013-08-28 14:17:09 -04001980 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04001981 @Override
1982 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04001983 checkBarModes();
John Spurlock5b9145b2013-08-20 15:13:47 -04001984 }};
1985
John Spurlockad3e6cb2013-04-30 08:47:43 -04001986 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04001987 public void setInteracting(int barWindow, boolean interacting) {
1988 mInteractingWindows = interacting
1989 ? (mInteractingWindows | barWindow)
1990 : (mInteractingWindows & ~barWindow);
1991 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04001992 suspendAutohide();
1993 } else {
1994 resumeSuspendedAutohide();
1995 }
1996 checkBarModes();
1997 }
1998
1999 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04002000 if (mAutohideSuspended) {
2001 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04002002 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04002003 }
2004 }
2005
John Spurlockd4e65752013-08-28 14:17:09 -04002006 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04002007 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04002008 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04002009 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04002010 }
2011
2012 private void cancelAutohide() {
2013 mAutohideSuspended = false;
2014 mHandler.removeCallbacks(mAutohide);
2015 }
2016
2017 private void scheduleAutohide() {
2018 cancelAutohide();
2019 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
2020 }
2021
John Spurlock9deaa282013-07-25 13:03:47 -04002022 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002023 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04002024 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
2025 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
2026 ) {
2027 userAutohide();
2028 }
2029 }
2030
2031 private void userAutohide() {
2032 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04002033 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04002034 }
2035
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002036 private boolean areLightsOn() {
2037 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
2038 }
Jim Millera073e572012-05-23 17:03:27 -07002039
Daniel Sandler60ee2562011-07-22 12:34:33 -04002040 public void setLightsOn(boolean on) {
2041 Log.v(TAG, "setLightsOn(" + on + ")");
2042 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002043 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002044 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002045 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002046 }
2047 }
2048
John Spurlock32beb2c2013-03-11 10:16:47 -04002049 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002050 try {
John Spurlock32beb2c2013-03-11 10:16:47 -04002051 mWindowManagerService.statusBarVisibilityChanged(vis);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002052 } catch (RemoteException ex) {
2053 }
Joe Onorato93056472010-09-10 10:30:46 -04002054 }
2055
Daniel Sandler5c8da942011-06-28 00:29:04 -04002056 public void topAppWindowChanged(boolean showMenu) {
2057 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002058 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04002059 }
2060 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04002061 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04002062 }
2063
2064 // See above re: lights-out policy for legacy apps.
2065 if (showMenu) setLightsOn(true);
2066 }
2067
Daniel Sandler328310c2011-09-23 15:56:52 -04002068 @Override
2069 public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
2070 boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
2071 || ((vis & InputMethodService.IME_VISIBLE) != 0);
2072
John Spurlock56d007b2013-10-28 18:40:56 -04002073 setNavigationIconHints(
John Spurlockd4e65752013-08-28 14:17:09 -04002074 altBack ? (mNavigationIconHints | NAVIGATION_HINT_BACK_ALT)
2075 : (mNavigationIconHints & ~NAVIGATION_HINT_BACK_ALT));
Daniel Sandler101784e2012-10-15 13:39:38 -04002076 if (mQS != null) mQS.setImeWindowStatus(vis > 0);
Daniel Sandler328310c2011-09-23 15:56:52 -04002077 }
2078
Jeff Brown2992ea72011-01-28 22:04:14 -08002079 @Override
Winson Chung43229d72012-09-12 18:04:18 -07002080 public void setHardKeyboardStatus(boolean available, boolean enabled) {}
Daniel Sandlere02d8082010-10-08 15:13:22 -04002081
Chris Wren0c8275b2012-05-08 13:36:48 -04002082 @Override
2083 protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002084 // no ticking in lights-out mode
2085 if (!areLightsOn()) return;
Jim Millera073e572012-05-23 17:03:27 -07002086
Daniel Sandler26cda272012-05-22 15:44:08 -04002087 // no ticking in Setup
2088 if (!isDeviceProvisioned()) return;
2089
John Spurlock61e36832012-09-10 09:43:27 -04002090 // not for you
2091 if (!notificationIsForCurrentUser(n)) return;
2092
Joe Onorato808182d2010-07-09 18:52:06 -04002093 // Show the ticker if one is requested. Also don't do this
2094 // until status bar window is attached to the window manager,
2095 // because... well, what's the point otherwise? And trying to
2096 // run a ticker without being attached will crash!
John Spurlockab847cf2014-01-15 14:13:59 -05002097 if (n.getNotification().tickerText != null && mStatusBarWindow != null
2098 && mStatusBarWindow.getWindowToken() != null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002099 if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
2100 | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
2101 mTicker.addEntry(n);
2102 }
2103 }
2104 }
2105
Joe Onorato808182d2010-07-09 18:52:06 -04002106 private class MyTicker extends Ticker {
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002107 MyTicker(Context context, View sb) {
Joe Onorato808182d2010-07-09 18:52:06 -04002108 super(context, sb);
2109 }
2110
2111 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002112 public void tickerStarting() {
Joe Onorato808182d2010-07-09 18:52:06 -04002113 mTicking = true;
Daniel Sandler173bae22012-09-25 14:37:42 -04002114 mStatusBarContents.setVisibility(View.GONE);
Joe Onorato808182d2010-07-09 18:52:06 -04002115 mTickerView.setVisibility(View.VISIBLE);
2116 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
Daniel Sandler173bae22012-09-25 14:37:42 -04002117 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
Joe Onorato808182d2010-07-09 18:52:06 -04002118 }
2119
2120 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002121 public void tickerDone() {
Daniel Sandler173bae22012-09-25 14:37:42 -04002122 mStatusBarContents.setVisibility(View.VISIBLE);
Joe Onorato808182d2010-07-09 18:52:06 -04002123 mTickerView.setVisibility(View.GONE);
Daniel Sandler173bae22012-09-25 14:37:42 -04002124 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
Joe Onorato808182d2010-07-09 18:52:06 -04002125 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
2126 mTickingDoneListener));
Joe Onorato808182d2010-07-09 18:52:06 -04002127 }
2128
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002129 public void tickerHalting() {
John Spurlock26a08ac2013-11-08 16:56:54 -05002130 if (mStatusBarContents.getVisibility() != View.VISIBLE) {
2131 mStatusBarContents.setVisibility(View.VISIBLE);
2132 mStatusBarContents
2133 .startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
2134 }
Joe Onorato808182d2010-07-09 18:52:06 -04002135 mTickerView.setVisibility(View.GONE);
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04002136 // we do not animate the ticker away at this point, just get rid of it (b/6992707)
Joe Onorato808182d2010-07-09 18:52:06 -04002137 }
2138 }
2139
2140 Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
2141 public void onAnimationEnd(Animation animation) {
2142 mTicking = false;
2143 }
2144 public void onAnimationRepeat(Animation animation) {
2145 }
2146 public void onAnimationStart(Animation animation) {
2147 }
2148 };
2149
2150 private Animation loadAnim(int id, Animation.AnimationListener listener) {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002151 Animation anim = AnimationUtils.loadAnimation(mContext, id);
Joe Onorato808182d2010-07-09 18:52:06 -04002152 if (listener != null) {
2153 anim.setAnimationListener(listener);
2154 }
2155 return anim;
2156 }
2157
Daniel Sandler48852952011-12-01 14:34:23 -05002158 public static String viewInfo(View v) {
2159 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
2160 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04002161 }
2162
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002163 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04002164 synchronized (mQueueLock) {
2165 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002166 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04002167 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04002168 pw.println(" mTicking=" + mTicking);
2169 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04002170 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002171 pw.println(" mPile: " + viewInfo(mPile));
Joe Onorato808182d2010-07-09 18:52:06 -04002172 pw.println(" mTickerView: " + viewInfo(mTickerView));
2173 pw.println(" mScrollView: " + viewInfo(mScrollView)
2174 + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04002175 }
Joe Onorato808182d2010-07-09 18:52:06 -04002176
John Spurlockcfc359a2013-09-05 10:42:03 -04002177 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04002178 pw.print(" mStatusBarWindowState=");
2179 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002180 pw.print(" mStatusBarMode=");
2181 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002182 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
2183 if (mNavigationBarView != null) {
2184 pw.print(" mNavigationBarWindowState=");
2185 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002186 pw.print(" mNavigationBarMode=");
2187 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002188 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
2189 }
2190
Daniel Sandler48852952011-12-01 14:34:23 -05002191 pw.print(" mNavigationBarView=");
2192 if (mNavigationBarView == null) {
2193 pw.println("null");
2194 } else {
2195 mNavigationBarView.dump(fd, pw, args);
2196 }
2197
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002198 pw.println(" Panels: ");
2199 if (mNotificationPanel != null) {
2200 pw.println(" mNotificationPanel=" +
2201 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
2202 pw.print (" ");
2203 mNotificationPanel.dump(fd, pw, args);
2204 }
2205 if (mSettingsPanel != null) {
2206 pw.println(" mSettingsPanel=" +
2207 mSettingsPanel + " params=" + mSettingsPanel.getLayoutParams().debug(""));
2208 pw.print (" ");
2209 mSettingsPanel.dump(fd, pw, args);
2210 }
2211
Daniel Sandler7579bca2011-08-18 15:47:26 -04002212 if (DUMPTRUCK) {
2213 synchronized (mNotificationData) {
2214 int N = mNotificationData.size();
2215 pw.println(" notification icons: " + N);
2216 for (int i=0; i<N; i++) {
2217 NotificationData.Entry e = mNotificationData.get(i);
2218 pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
2219 StatusBarNotification n = e.notification;
Daniel Sandler4f91efd2013-04-25 16:38:41 -04002220 pw.println(" pkg=" + n.getPackageName() + " id=" + n.getId() + " score=" + n.getScore());
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -04002221 pw.println(" notification=" + n.getNotification());
2222 pw.println(" tickerText=\"" + n.getNotification().tickerText + "\"");
Daniel Sandler7579bca2011-08-18 15:47:26 -04002223 }
2224 }
2225
2226 int N = mStatusIcons.getChildCount();
2227 pw.println(" system icons: " + N);
2228 for (int i=0; i<N; i++) {
2229 StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
2230 pw.println(" [" + i + "] icon=" + ic);
2231 }
Jim Miller5e6af442011-12-02 18:24:26 -08002232
Daniel Sandler89d97132011-09-08 15:31:57 -04002233 if (false) {
2234 pw.println("see the logcat for a dump of the views we have created.");
2235 // must happen on ui thread
2236 mHandler.post(new Runnable() {
2237 public void run() {
2238 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04002239 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04002240 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002241 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002242 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002243 }
2244 });
2245 }
Joe Onorato808182d2010-07-09 18:52:06 -04002246 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002247
Daniel Sandler151f00d2012-10-02 22:33:08 -04002248 if (DEBUG_GESTURES) {
2249 pw.print(" status bar gestures: ");
2250 mGestureRec.dump(fd, pw, args);
2251 }
Daniel Sandler33805342012-07-23 15:45:12 -04002252
Daniel Sandler89d97132011-09-08 15:31:57 -04002253 mNetworkController.dump(fd, pw, args);
Joe Onorato808182d2010-07-09 18:52:06 -04002254 }
2255
John Spurlock0ec64c62013-08-26 15:37:58 -04002256 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
2257 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
2258 pw.println(BarTransitions.modeToString(transitions.getMode()));
2259 }
2260
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002261 @Override
2262 public void createAndAddWindows() {
2263 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04002264 }
Jim Millere898ac52012-04-06 17:10:57 -07002265
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002266 private void addStatusBarWindow() {
2267 // Put up the view
2268 final int height = getStatusBarHeight();
Joe Onorato808182d2010-07-09 18:52:06 -04002269
Daniel Sandlera310af82012-04-24 01:20:13 -04002270 // Now that the status bar window encompasses the sliding panel and its
2271 // translucent backdrop, the entire thing is made TRANSLUCENT and is
2272 // hardware-accelerated.
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002273 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
2274 ViewGroup.LayoutParams.MATCH_PARENT,
2275 height,
2276 WindowManager.LayoutParams.TYPE_STATUS_BAR,
2277 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
2278 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
John Spurlock9deaa282013-07-25 13:03:47 -04002279 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
2280 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
Daniel Sandlera310af82012-04-24 01:20:13 -04002281 PixelFormat.TRANSLUCENT);
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002282
Romain Guy0901fda2012-05-22 21:10:57 -07002283 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002284
2285 lp.gravity = getStatusBarGravity();
2286 lp.setTitle("StatusBar");
2287 lp.packageName = mContext.getPackageName();
Jim Millere898ac52012-04-06 17:10:57 -07002288
Daniel Sandlera310af82012-04-24 01:20:13 -04002289 makeStatusBarView();
Jeff Brown98365d72012-08-19 20:30:52 -07002290 mWindowManager.addView(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04002291 }
2292
Joe Onorato808182d2010-07-09 18:52:06 -04002293 void setNotificationIconVisibility(boolean visible, int anim) {
2294 int old = mNotificationIcons.getVisibility();
2295 int v = visible ? View.VISIBLE : View.INVISIBLE;
2296 if (old != v) {
2297 mNotificationIcons.setVisibility(v);
2298 mNotificationIcons.startAnimation(loadAnim(anim, null));
2299 }
2300 }
2301
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002302 void updateExpandedInvisiblePosition() {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002303 mTrackingPosition = -mDisplayMetrics.heightPixels;
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002304 }
2305
Daniel Sandler1fac1fd2012-04-30 12:07:30 -04002306 static final float saturate(float a) {
2307 return a < 0f ? 0f : (a > 1f ? 1f : a);
2308 }
2309
Chris Wren8fd12652012-05-09 21:25:57 -04002310 @Override
2311 protected int getExpandedViewMaxHeight() {
Daniel Sandler21b274e2012-05-02 15:07:51 -04002312 return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx;
2313 }
2314
Chris Wren0c8275b2012-05-08 13:36:48 -04002315 @Override
Daniel Sandler08d05e32012-08-08 16:39:54 -04002316 public void updateExpandedViewPos(int thingy) {
Chris Wren6d15a362013-08-20 18:46:29 -04002317 if (SPEW) Log.v(TAG, "updateExpandedViewPos");
Daniel Sandlere680f542012-09-28 12:22:27 -04002318
2319 // on larger devices, the notification panel is propped open a bit
2320 mNotificationPanel.setMinimumHeight(
2321 (int)(mNotificationPanelMinHeightFrac * mCurrentDisplaySize.y));
2322
Daniel Sandler21b274e2012-05-02 15:07:51 -04002323 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams();
Daniel Sandler21b274e2012-05-02 15:07:51 -04002324 lp.gravity = mNotificationPanelGravity;
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002325 lp.setMarginStart(mNotificationPanelMarginPx);
Daniel Sandler21b274e2012-05-02 15:07:51 -04002326 mNotificationPanel.setLayoutParams(lp);
Daniel Sandlere680f542012-09-28 12:22:27 -04002327
Daniel Sandlere111ad32012-10-13 15:17:45 -04002328 if (mSettingsPanel != null) {
2329 lp = (FrameLayout.LayoutParams) mSettingsPanel.getLayoutParams();
2330 lp.gravity = mSettingsPanelGravity;
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002331 lp.setMarginEnd(mNotificationPanelMarginPx);
Daniel Sandlere111ad32012-10-13 15:17:45 -04002332 mSettingsPanel.setLayoutParams(lp);
2333 }
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002334
Chris Wren0f2aa682013-08-02 12:03:02 -04002335 if (ENABLE_HEADS_UP && mHeadsUpNotificationView != null) {
2336 mHeadsUpNotificationView.setMargin(mNotificationPanelMarginPx);
Chris Wren9afc50d2013-07-30 11:31:46 -04002337 mPile.getLocationOnScreen(mPilePosition);
2338 mHeadsUpVerticalOffset = mPilePosition[1] - mNaturalBarHeight;
Chris Wren0f2aa682013-08-02 12:03:02 -04002339 }
2340
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002341 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002342 }
2343
Daniel Sandler747a9e92012-08-10 16:39:19 -04002344 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002345 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04002346 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002347 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04002348 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04002349 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04002350 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2351 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002352 }
2353
Joe Onorato808182d2010-07-09 18:52:06 -04002354 private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
2355 public void onClick(View v) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002356 synchronized (mNotificationData) {
Chet Haase2f2022a2011-10-11 06:41:59 -07002357 // animate-swipe all dismissable notifications, then animate the shade closed
2358 int numChildren = mPile.getChildCount();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002359
Chet Haase2f2022a2011-10-11 06:41:59 -07002360 int scrollTop = mScrollView.getScrollY();
2361 int scrollBottom = scrollTop + mScrollView.getHeight();
2362 final ArrayList<View> snapshot = new ArrayList<View>(numChildren);
2363 for (int i=0; i<numChildren; i++) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002364 final View child = mPile.getChildAt(i);
Chet Haase2f2022a2011-10-11 06:41:59 -07002365 if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop &&
2366 child.getTop() < scrollBottom) {
2367 snapshot.add(child);
2368 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002369 }
Craig Mautner93a035c2012-04-09 15:23:59 -07002370 if (snapshot.isEmpty()) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002371 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Craig Mautner93a035c2012-04-09 15:23:59 -07002372 return;
2373 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002374 new Thread(new Runnable() {
2375 @Override
2376 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07002377 // Decrease the delay for every row we animate to give the sense of
2378 // accelerating the swipes
2379 final int ROW_DELAY_DECREMENT = 10;
2380 int currentDelay = 140;
2381 int totalDelay = 0;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002382
Chet Haase2f2022a2011-10-11 06:41:59 -07002383 // Set the shade-animating state to avoid doing other work during
2384 // all of these animations. In particular, avoid layout and
2385 // redrawing when collapsing the shade.
2386 mPile.setViewRemoval(false);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002387
Chet Haase2f2022a2011-10-11 06:41:59 -07002388 mPostCollapseCleanup = new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07002389 @Override
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002390 public void run() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002391 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002392 Log.v(TAG, "running post-collapse cleanup");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002393 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002394 try {
Chet Haase2f2022a2011-10-11 06:41:59 -07002395 mPile.setViewRemoval(true);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002396 mBarService.onClearAllNotifications();
Chet Haase2f2022a2011-10-11 06:41:59 -07002397 } catch (Exception ex) { }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002398 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002399 };
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002400
Chet Haase2f2022a2011-10-11 06:41:59 -07002401 View sampleView = snapshot.get(0);
2402 int width = sampleView.getWidth();
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002403 final int dir = sampleView.isLayoutRtl() ? -1 : +1;
2404 final int velocity = dir * width * 8; // 1000/8 = 125 ms duration
Craig Mautner93a035c2012-04-09 15:23:59 -07002405 for (final View _v : snapshot) {
Chet Haase2f2022a2011-10-11 06:41:59 -07002406 mHandler.postDelayed(new Runnable() {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002407 @Override
2408 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07002409 mPile.dismissRowAnimated(_v, velocity);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002410 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002411 }, totalDelay);
2412 currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT);
2413 totalDelay += currentDelay;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002414 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002415 // Delay the collapse animation until after all swipe animations have
2416 // finished. Provide some buffer because there may be some extra delay
2417 // before actually starting each swipe animation. Ideally, we'd
2418 // synchronize the end of those animations with the start of the collaps
2419 // exactly.
2420 mHandler.postDelayed(new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07002421 @Override
Chet Haase2f2022a2011-10-11 06:41:59 -07002422 public void run() {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002423 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Chet Haase2f2022a2011-10-11 06:41:59 -07002424 }
2425 }, totalDelay + 225);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002426 }
2427 }).start();
Joe Onorato808182d2010-07-09 18:52:06 -04002428 }
Joe Onorato808182d2010-07-09 18:52:06 -04002429 }
2430 };
2431
Daniel Sandler3679bf52012-10-16 21:30:28 -04002432 public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
2433 if (onlyProvisioned && !isDeviceProvisioned()) return;
2434 try {
2435 // Dismiss the lock screen when Settings starts.
2436 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
2437 } catch (RemoteException e) {
2438 }
2439 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2440 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
2441 animateCollapsePanels();
2442 }
2443
Daniel Sandlerd3090562011-08-09 00:28:44 -04002444 private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
2445 public void onClick(View v) {
Daniel Sandlere111ad32012-10-13 15:17:45 -04002446 if (mHasSettingsPanel) {
2447 animateExpandSettingsPanel();
2448 } else {
Daniel Sandler3679bf52012-10-16 21:30:28 -04002449 startActivityDismissingKeyguard(
2450 new Intent(android.provider.Settings.ACTION_SETTINGS), true);
Daniel Sandlere111ad32012-10-13 15:17:45 -04002451 }
Daniel Sandlerd3090562011-08-09 00:28:44 -04002452 }
2453 };
2454
Daniel Sandler3679bf52012-10-16 21:30:28 -04002455 private View.OnClickListener mClockClickListener = new View.OnClickListener() {
2456 public void onClick(View v) {
2457 startActivityDismissingKeyguard(
2458 new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone
2459 }
2460 };
2461
Daniel Sandler101784e2012-10-15 13:39:38 -04002462 private View.OnClickListener mNotificationButtonListener = new View.OnClickListener() {
2463 public void onClick(View v) {
2464 animateExpandNotificationsPanel();
2465 }
2466 };
2467
Joe Onorato808182d2010-07-09 18:52:06 -04002468 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2469 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04002470 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04002471 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04002472 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Jim Miller9a720f52012-05-30 03:19:43 -07002473 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002474 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Daniel Sandleredbdd3a2011-06-21 12:57:08 -04002475 String reason = intent.getStringExtra("reason");
Jim Miller9a720f52012-05-30 03:19:43 -07002476 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
2477 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002478 }
2479 }
Daniel Sandler11cf1782012-09-27 14:03:08 -04002480 animateCollapsePanels(flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002481 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002482 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002483 mScreenOn = false;
Daniel Sandlered930e52012-07-03 14:31:22 -04002484 // no waiting!
Daniel Sandler08d05e32012-08-08 16:39:54 -04002485 makeExpandedInvisible();
John Spurlock1bbd49d2012-10-19 11:09:32 -04002486 notifyNavigationBarScreenOn(false);
Chris Wrene97f90b2013-08-07 17:39:35 -04002487 notifyHeadsUpScreenOn(false);
John Spurlock42197262013-10-21 09:32:25 -04002488 finishBarAnimations();
Daniel Sandlered930e52012-07-03 14:31:22 -04002489 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002490 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002491 mScreenOn = true;
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002492 // work around problem where mDisplay.getRotation() is not stable while screen is off (bug 7086018)
2493 repositionNavigationBar();
John Spurlock1bbd49d2012-10-19 11:09:32 -04002494 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002495 }
John Spurlock3c875662013-08-31 15:07:25 -04002496 else if (ACTION_DEMO.equals(action)) {
2497 Bundle bundle = intent.getExtras();
2498 if (bundle != null) {
2499 String command = bundle.getString("command", "").trim().toLowerCase();
2500 if (command.length() > 0) {
2501 try {
2502 dispatchDemoCommand(command, bundle);
2503 } catch (Throwable t) {
2504 Log.w(TAG, "Error running demo command, intent=" + intent, t);
2505 }
2506 }
2507 }
2508 }
Joe Onorato808182d2010-07-09 18:52:06 -04002509 }
2510 };
2511
Daniel Sandler777dcde2013-09-30 10:21:45 -04002512 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
2513 @Override
2514 protected void onConfigurationChanged(Configuration newConfig) {
2515 super.onConfigurationChanged(newConfig); // calls refreshLayout
2516
2517 if (DEBUG) {
2518 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
2519 }
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002520 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04002521
2522 updateResources();
2523 repositionNavigationBar();
2524 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
2525 updateShowSearchHoldoff();
2526 }
2527
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002528 @Override
2529 public void userSwitched(int newUserId) {
2530 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002531 animateCollapsePanels();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002532 updateNotificationIcons();
John Spurlock919adac2012-10-02 16:41:12 -04002533 resetUserSetupObserver();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002534 }
John Spurlock919adac2012-10-02 16:41:12 -04002535
2536 private void resetUserSetupObserver() {
2537 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
2538 mUserSetupObserver.onChange(false);
2539 mContext.getContentResolver().registerContentObserver(
2540 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
2541 mUserSetupObserver,
2542 mCurrentUserId);
2543 }
2544
Chris Wren157026f2013-06-28 16:54:01 -04002545 private void setHeadsUpVisibility(boolean vis) {
2546 if (!ENABLE_HEADS_UP) return;
2547 if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
2548 mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
Chris Wrene03f4e12013-08-08 16:48:48 -04002549 if (!vis) {
2550 if (DEBUG) Log.d(TAG, "setting heads up entry to null");
2551 mInterruptingNotificationEntry = null;
2552 }
Joe Onorato808182d2010-07-09 18:52:06 -04002553 }
2554
Chris Wren9afc50d2013-07-30 11:31:46 -04002555 public void animateHeadsUp(boolean animateInto, float frac) {
2556 if (!ENABLE_HEADS_UP || mHeadsUpNotificationView == null) return;
2557 frac = frac / 0.4f;
2558 frac = frac < 1.0f ? frac : 1.0f;
2559 float alpha = 1.0f - frac;
2560 float offset = mHeadsUpVerticalOffset * frac;
2561 offset = animateInto ? offset : 0f;
2562 mHeadsUpNotificationView.setAlpha(alpha);
2563 mHeadsUpNotificationView.setY(offset);
2564 }
2565
Chris Wren51c75102013-07-16 20:49:17 -04002566 public void onHeadsUpDismissed() {
2567 if (mInterruptingNotificationEntry == null) return;
Chris Wren6d15a362013-08-20 18:46:29 -04002568 mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
2569 if (mHeadsUpNotificationView.isClearable()) {
2570 try {
2571 mBarService.onNotificationClear(
2572 mInterruptingNotificationEntry.notification.getPackageName(),
2573 mInterruptingNotificationEntry.notification.getTag(),
2574 mInterruptingNotificationEntry.notification.getId());
2575 } catch (android.os.RemoteException ex) {
2576 // oh well
2577 }
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04002578 }
2579 }
Jim Millere898ac52012-04-06 17:10:57 -07002580
Joe Onorato808182d2010-07-09 18:52:06 -04002581 /**
2582 * Reload some of our resources when the configuration changes.
2583 *
2584 * We don't reload everything when the configuration changes -- we probably
2585 * should, but getting that smooth is tough. Someday we'll fix that. In the
2586 * meantime, just update the things that we know change.
2587 */
2588 void updateResources() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002589 final Context context = mContext;
2590 final Resources res = context.getResources();
Joe Onorato808182d2010-07-09 18:52:06 -04002591
Daniel Sandler1347c302011-08-01 16:47:53 -04002592 if (mClearButton instanceof TextView) {
2593 ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
2594 }
Winson Chungd63c59782012-09-05 17:34:41 -07002595
2596 // Update the QuickSettings container
Daniel Sandler101784e2012-10-15 13:39:38 -04002597 if (mQS != null) mQS.updateResources();
Winson Chungd63c59782012-09-05 17:34:41 -07002598
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002599 loadDimens();
2600 }
Jim Miller5e6af442011-12-02 18:24:26 -08002601
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002602 protected void loadDimens() {
2603 final Resources res = mContext.getResources();
2604
2605 mNaturalBarHeight = res.getDimensionPixelSize(
2606 com.android.internal.R.dimen.status_bar_height);
2607
2608 int newIconSize = res.getDimensionPixelSize(
2609 com.android.internal.R.dimen.status_bar_icon_size);
2610 int newIconHPadding = res.getDimensionPixelSize(
2611 R.dimen.status_bar_icon_padding);
2612
2613 if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
John Spurlockcd686b52013-06-05 10:13:46 -04002614// Log.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002615 mIconHPadding = newIconHPadding;
2616 mIconSize = newIconSize;
2617 //reloadAllNotificationIcons(); // reload the tray
2618 }
2619
Joe Onorato808182d2010-07-09 18:52:06 -04002620 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
2621
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002622 mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
2623 mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
2624 mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
2625 mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
2626
2627 mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
2628 mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
2629
2630 mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
2631 mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
2632
2633 mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
Jim Millera073e572012-05-23 17:03:27 -07002634
Daniel Sandlere5011a32012-06-11 16:07:52 -04002635 mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity);
2636
Daniel Sandler21b274e2012-05-02 15:07:51 -04002637 mNotificationPanelMarginBottomPx
2638 = (int) res.getDimension(R.dimen.notification_panel_margin_bottom);
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002639 mNotificationPanelMarginPx
Daniel Sandler21b274e2012-05-02 15:07:51 -04002640 = (int) res.getDimension(R.dimen.notification_panel_margin_left);
2641 mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
2642 if (mNotificationPanelGravity <= 0) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002643 mNotificationPanelGravity = Gravity.START | Gravity.TOP;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002644 }
2645 mSettingsPanelGravity = res.getInteger(R.integer.settings_panel_layout_gravity);
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002646 Log.d(TAG, "mSettingsPanelGravity = " + mSettingsPanelGravity);
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002647 if (mSettingsPanelGravity <= 0) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002648 mSettingsPanelGravity = Gravity.END | Gravity.TOP;
Daniel Sandler21b274e2012-05-02 15:07:51 -04002649 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04002650
2651 mCarrierLabelHeight = res.getDimensionPixelSize(R.dimen.carrier_label_height);
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002652 mNotificationHeaderHeight = res.getDimensionPixelSize(R.dimen.notification_panel_header_height);
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002653
Daniel Sandlere680f542012-09-28 12:22:27 -04002654 mNotificationPanelMinHeightFrac = res.getFraction(R.dimen.notification_panel_min_height_frac, 1, 1);
2655 if (mNotificationPanelMinHeightFrac < 0f || mNotificationPanelMinHeightFrac > 1f) {
2656 mNotificationPanelMinHeightFrac = 0f;
John Spurlock804df702012-06-01 15:34:27 -04002657 }
Daniel Sandlere680f542012-09-28 12:22:27 -04002658
Chris Wren51c75102013-07-16 20:49:17 -04002659 mHeadsUpNotificationDecay = res.getInteger(R.integer.heads_up_notification_decay);
2660 mRowHeight = res.getDimensionPixelSize(R.dimen.notification_row_min_height);
2661
John Spurlockcd686b52013-06-05 10:13:46 -04002662 if (false) Log.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04002663 }
2664
Joe Onorato808182d2010-07-09 18:52:06 -04002665 //
2666 // tracing
2667 //
2668
2669 void postStartTracing() {
2670 mHandler.postDelayed(mStartTracing, 3000);
2671 }
2672
2673 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002674 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
2675 Context.VIBRATOR_SERVICE);
Joe Onorato808182d2010-07-09 18:52:06 -04002676 vib.vibrate(250);
2677 }
2678
2679 Runnable mStartTracing = new Runnable() {
2680 public void run() {
2681 vibrate();
2682 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04002683 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002684 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2685 mHandler.postDelayed(mStopTracing, 10000);
2686 }
2687 };
2688
2689 Runnable mStopTracing = new Runnable() {
2690 public void run() {
2691 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04002692 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002693 vibrate();
2694 }
2695 };
Chris Wren0c8275b2012-05-08 13:36:48 -04002696
2697 @Override
2698 protected void haltTicker() {
2699 mTicker.halt();
2700 }
Jim Miller670d9dd2012-05-12 13:28:26 -07002701
2702 @Override
Jim Millerb4238e02012-05-14 15:26:20 -07002703 protected boolean shouldDisableNavbarGestures() {
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002704 return !isDeviceProvisioned()
2705 || mExpandedVisible
2706 || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07002707 }
Joe Onorato808182d2010-07-09 18:52:06 -04002708
Romain Guy648342f2012-05-25 10:44:45 -07002709 private static class FastColorDrawable extends Drawable {
2710 private final int mColor;
2711
2712 public FastColorDrawable(int color) {
2713 mColor = 0xff000000 | color;
2714 }
2715
2716 @Override
2717 public void draw(Canvas canvas) {
2718 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
2719 }
2720
2721 @Override
2722 public void setAlpha(int alpha) {
2723 }
2724
2725 @Override
2726 public void setColorFilter(ColorFilter cf) {
2727 }
2728
2729 @Override
2730 public int getOpacity() {
2731 return PixelFormat.OPAQUE;
2732 }
2733
2734 @Override
2735 public void setBounds(int left, int top, int right, int bottom) {
2736 }
2737
2738 @Override
2739 public void setBounds(Rect bounds) {
2740 }
2741 }
John Spurlock5c454122013-06-17 07:35:46 -04002742
2743 @Override
2744 public void destroy() {
2745 super.destroy();
2746 if (mStatusBarWindow != null) {
2747 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05002748 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04002749 }
2750 if (mNavigationBarView != null) {
2751 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05002752 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04002753 }
2754 mContext.unregisterReceiver(mBroadcastReceiver);
2755 }
John Spurlock3c875662013-08-31 15:07:25 -04002756
2757 private boolean mDemoModeAllowed;
2758 private boolean mDemoMode;
2759 private DemoStatusIcons mDemoStatusIcons;
2760
2761 @Override
2762 public void dispatchDemoCommand(String command, Bundle args) {
2763 if (!mDemoModeAllowed) {
2764 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
2765 "sysui_demo_allowed", 0) != 0;
2766 }
2767 if (!mDemoModeAllowed) return;
2768 if (command.equals(COMMAND_ENTER)) {
2769 mDemoMode = true;
2770 } else if (command.equals(COMMAND_EXIT)) {
2771 mDemoMode = false;
2772 checkBarModes();
2773 } else if (!mDemoMode) {
2774 // automatically enter demo mode on first demo command
2775 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
2776 }
2777 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
2778 if (modeChange || command.equals(COMMAND_CLOCK)) {
2779 dispatchDemoCommandToView(command, args, R.id.clock);
2780 }
2781 if (modeChange || command.equals(COMMAND_BATTERY)) {
2782 dispatchDemoCommandToView(command, args, R.id.battery);
2783 }
2784 if (modeChange || command.equals(COMMAND_STATUS)) {
2785 if (mDemoStatusIcons == null) {
2786 mDemoStatusIcons = new DemoStatusIcons(mStatusIcons, mIconSize);
2787 }
2788 mDemoStatusIcons.dispatchDemoCommand(command, args);
2789 }
2790 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
2791 mNetworkController.dispatchDemoCommand(command, args);
2792 }
John Spurlock7f42fc52014-01-14 16:20:39 -05002793 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
2794 View notifications = mStatusBarView == null ? null
2795 : mStatusBarView.findViewById(R.id.notification_icon_area);
2796 if (notifications != null) {
2797 String visible = args.getString("visible");
2798 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
2799 notifications.setVisibility(vis);
2800 }
2801 }
John Spurlock3c875662013-08-31 15:07:25 -04002802 if (command.equals(COMMAND_BARS)) {
2803 String mode = args.getString("mode");
2804 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04002805 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04002806 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
2807 -1;
2808 if (barMode != -1) {
2809 boolean animate = true;
2810 if (mStatusBarView != null) {
2811 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
2812 }
2813 if (mNavigationBarView != null) {
2814 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
2815 }
2816 }
2817 }
2818 }
2819
2820 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
2821 if (mStatusBarView == null) return;
2822 View v = mStatusBarView.findViewById(id);
2823 if (v instanceof DemoMode) {
2824 ((DemoMode)v).dispatchDemoCommand(command, args);
2825 }
2826 }
Romain Guy648342f2012-05-25 10:44:45 -07002827}