blob: bbac4efcbd20973ab338635f06017e4f4d192875 [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(
517 View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER |
518 View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
519 View.STATUS_BAR_DISABLE_CLOCK);
520 }
Joe Onorato808182d2010-07-09 18:52:06 -0400521
Daniel Sandlera310af82012-04-24 01:20:13 -0400522 mTicker = new MyTicker(context, mStatusBarView);
Joe Onorato808182d2010-07-09 18:52:06 -0400523
Daniel Sandlera310af82012-04-24 01:20:13 -0400524 TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText);
Joe Onorato808182d2010-07-09 18:52:06 -0400525 tickerView.mTicker = mTicker;
526
Joe Onorato808182d2010-07-09 18:52:06 -0400527 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
528
Joe Onorato808182d2010-07-09 18:52:06 -0400529 // set the inital view visibility
530 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400531
Daniel Sandler2b697352011-07-22 16:23:09 -0400532 // Other icons
533 mLocationController = new LocationController(mContext); // will post a notification
534 mBatteryController = new BatteryController(mContext);
Daniel Sandler2b697352011-07-22 16:23:09 -0400535 mNetworkController = new NetworkController(mContext);
Winson Chungd63c59782012-09-05 17:34:41 -0700536 mBluetoothController = new BluetoothController(mContext);
Svetoslav79578b22013-04-29 16:55:57 -0700537 mRotationLockController = new RotationLockController(mContext);
Jim Miller5e6af442011-12-02 18:24:26 -0800538 final SignalClusterView signalCluster =
Daniel Sandlera310af82012-04-24 01:20:13 -0400539 (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
Daniel Sandler3d32a242012-06-05 13:44:14 -0400540
Winson Chungd63c59782012-09-05 17:34:41 -0700541
Christian Robertson2e347422011-08-11 14:01:04 -0700542 mNetworkController.addSignalCluster(signalCluster);
Daniel Sandler28f89d42011-08-15 14:04:15 -0400543 signalCluster.setNetworkController(mNetworkController);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400544
Daniel Sandler8b268d42013-05-28 16:17:13 -0400545 final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
546 if (isAPhone) {
547 mEmergencyCallLabel =
548 (TextView) mStatusBarWindow.findViewById(R.id.emergency_calls_only);
549 if (mEmergencyCallLabel != null) {
550 mNetworkController.addEmergencyLabelView(mEmergencyCallLabel);
551 mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() {
552 public void onClick(View v) { }});
553 mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
554 @Override
555 public void onLayoutChange(View v, int left, int top, int right, int bottom,
556 int oldLeft, int oldTop, int oldRight, int oldBottom) {
557 updateCarrierLabelVisibility(false);
558 }});
559 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400560 }
561
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400562 mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
563 mShowCarrierInPanel = (mCarrierLabel != null);
John Spurlockcd686b52013-06-05 10:13:46 -0400564 if (DEBUG) Log.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400565 if (mShowCarrierInPanel) {
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400566 mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
567
Daniel Sandler67234c42012-06-15 13:17:39 -0400568 // for mobile devices, we always show mobile connection info here (SPN/PLMN)
569 // for other devices, we show whatever network is connected
Daniel Sandler18ac7822012-06-11 16:07:18 -0400570 if (mNetworkController.hasMobileDataFeature()) {
571 mNetworkController.addMobileLabelView(mCarrierLabel);
572 } else {
Daniel Sandler67234c42012-06-15 13:17:39 -0400573 mNetworkController.addCombinedLabelView(mCarrierLabel);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400574 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400575
576 // set up the dynamic hide/show of the label
577 mPile.setOnSizeChangedListener(new OnSizeChangedListener() {
578 @Override
579 public void onSizeChanged(View view, int w, int h, int oldw, int oldh) {
580 updateCarrierLabelVisibility(false);
581 }
582 });
Daniel Sandler3d32a242012-06-05 13:44:14 -0400583 }
584
Daniel Sandlere111ad32012-10-13 15:17:45 -0400585 // Quick Settings (where available, some restrictions apply)
586 if (mHasSettingsPanel) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400587 // first, figure out where quick settings should be inflated
588 final View settings_stub;
589 if (mHasFlipSettings) {
590 // a version of quick settings that flips around behind the notifications
591 settings_stub = mStatusBarWindow.findViewById(R.id.flip_settings_stub);
592 if (settings_stub != null) {
593 mFlipSettingsView = ((ViewStub)settings_stub).inflate();
594 mFlipSettingsView.setVisibility(View.GONE);
595 mFlipSettingsView.setVerticalScrollBarEnabled(false);
596 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400597 } else {
Daniel Sandler101784e2012-10-15 13:39:38 -0400598 // full quick settings panel
599 settings_stub = mStatusBarWindow.findViewById(R.id.quick_settings_stub);
600 if (settings_stub != null) {
601 mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate();
602 } else {
603 mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
604 }
605
606 if (mSettingsPanel != null) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400607 if (!ActivityManager.isHighEndGfx()) {
608 mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
609 R.color.notification_panel_solid_background)));
610 }
611 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400612 }
613
Daniel Sandler101784e2012-10-15 13:39:38 -0400614 // wherever you find it, Quick Settings needs a container to survive
615 mSettingsContainer = (QuickSettingsContainerView)
616 mStatusBarWindow.findViewById(R.id.quick_settings_container);
617 if (mSettingsContainer != null) {
618 mQS = new QuickSettings(mContext, mSettingsContainer);
Daniel Sandler3679bf52012-10-16 21:30:28 -0400619 if (!mNotificationPanelIsFullScreenWidth) {
620 mSettingsContainer.setSystemUiVisibility(
621 View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
622 | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
623 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400624 if (mSettingsPanel != null) {
625 mSettingsPanel.setQuickSettings(mQS);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400626 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400627 mQS.setService(this);
Daniel Sandlerfe3376b2012-10-16 19:54:02 -0400628 mQS.setBar(mStatusBarView);
Daniel Sandler101784e2012-10-15 13:39:38 -0400629 mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
Svetoslav79578b22013-04-29 16:55:57 -0700630 mLocationController, mRotationLockController);
Daniel Sandler101784e2012-10-15 13:39:38 -0400631 } else {
632 mQS = null; // fly away, be free
Daniel Sandlere111ad32012-10-13 15:17:45 -0400633 }
Siva Velusamy537421b2012-09-14 14:45:02 -0700634 }
635
John Spurlock56d007b2013-10-28 18:40:56 -0400636 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
637 mBroadcastReceiver.onReceive(mContext,
638 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
639
Joe Onorato808182d2010-07-09 18:52:06 -0400640 // receive broadcasts
641 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400642 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
643 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400644 filter.addAction(Intent.ACTION_SCREEN_ON);
John Spurlock3c875662013-08-31 15:07:25 -0400645 filter.addAction(ACTION_DEMO);
Joe Onorato808182d2010-07-09 18:52:06 -0400646 context.registerReceiver(mBroadcastReceiver, filter);
647
John Spurlock919adac2012-10-02 16:41:12 -0400648 // listen for USER_SETUP_COMPLETE setting (per-user)
649 resetUserSetupObserver();
650
Daniel Sandlera310af82012-04-24 01:20:13 -0400651 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400652 }
653
Michael Jurka7f2668c2012-03-27 07:49:52 -0700654 @Override
Jim Millerad178a42013-10-08 20:03:38 -0700655 protected void onShowSearchPanel() {
656 if (mNavigationBarView != null) {
John Spurlock56d007b2013-10-28 18:40:56 -0400657 mNavigationBarView.getBarTransitions().setContentVisible(false);
Jim Millerad178a42013-10-08 20:03:38 -0700658 }
659 }
660
661 @Override
662 protected void onHideSearchPanel() {
663 if (mNavigationBarView != null) {
John Spurlock56d007b2013-10-28 18:40:56 -0400664 mNavigationBarView.getBarTransitions().setContentVisible(true);
Jim Millerad178a42013-10-08 20:03:38 -0700665 }
666 }
667
668 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -0700669 protected View getStatusBarView() {
670 return mStatusBarView;
671 }
672
673 @Override
Jim Millere898ac52012-04-06 17:10:57 -0700674 protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
675 boolean opaque = false;
676 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
677 LayoutParams.MATCH_PARENT,
678 LayoutParams.MATCH_PARENT,
679 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
680 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
681 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
682 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
683 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
Jeff Brown98365d72012-08-19 20:30:52 -0700684 if (ActivityManager.isHighEndGfx()) {
Jim Millere898ac52012-04-06 17:10:57 -0700685 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Jim Millere898ac52012-04-06 17:10:57 -0700686 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700687 lp.gravity = Gravity.BOTTOM | Gravity.START;
Jim Millere898ac52012-04-06 17:10:57 -0700688 lp.setTitle("SearchPanel");
689 // TODO: Define custom animation for Search panel
690 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
691 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
692 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
693 return lp;
694 }
695
Jim Millere898ac52012-04-06 17:10:57 -0700696 @Override
697 protected void updateSearchPanel() {
698 super.updateSearchPanel();
John Spurlockf6b63972013-08-27 16:08:28 -0400699 if (mNavigationBarView != null) {
700 mNavigationBarView.setDelegateView(mSearchPanelView);
701 }
Jim Millere898ac52012-04-06 17:10:57 -0700702 }
703
704 @Override
705 public void showSearchPanel() {
Jim Millerb490c3e2012-05-31 13:34:16 -0700706 super.showSearchPanel();
John Spurlock7a733442012-11-08 09:08:14 -0500707 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlerd5483c32012-10-19 16:44:15 -0400708
709 // we want to freeze the sysui state wherever it is
710 mSearchPanelView.setSystemUiVisibility(mSystemUiVisibility);
711
John Spurlockf6b63972013-08-27 16:08:28 -0400712 if (mNavigationBarView != null) {
713 WindowManager.LayoutParams lp =
714 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
715 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
716 mWindowManager.updateViewLayout(mNavigationBarView, lp);
717 }
Jim Millere898ac52012-04-06 17:10:57 -0700718 }
719
720 @Override
721 public void hideSearchPanel() {
722 super.hideSearchPanel();
John Spurlockf6b63972013-08-27 16:08:28 -0400723 if (mNavigationBarView != null) {
724 WindowManager.LayoutParams lp =
725 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
726 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
727 mWindowManager.updateViewLayout(mNavigationBarView, lp);
728 }
Jim Millere898ac52012-04-06 17:10:57 -0700729 }
730
Joe Onorato808182d2010-07-09 18:52:06 -0400731 protected int getStatusBarGravity() {
732 return Gravity.TOP | Gravity.FILL_HORIZONTAL;
733 }
734
Joe Onoratodc100302011-01-11 17:07:41 -0800735 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -0400736 if (mNaturalBarHeight < 0) {
737 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -0700738 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -0400739 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
740 }
741 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -0800742 }
743
Daniel Sandler5c8da942011-06-28 00:29:04 -0400744 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
745 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -0400746 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400747 toggleRecentApps();
748 }
749 };
Chris Wren0c8275b2012-05-08 13:36:48 -0400750
Jim Miller9a720f52012-05-30 03:19:43 -0700751 private int mShowSearchHoldoff = 0;
752 private Runnable mShowSearchPanel = new Runnable() {
753 public void run() {
754 showSearchPanel();
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400755 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700756 }
757 };
758
Jim Millere898ac52012-04-06 17:10:57 -0700759 View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
760 public boolean onTouch(View v, MotionEvent event) {
761 switch(event.getAction()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700762 case MotionEvent.ACTION_DOWN:
Daniel Sandlerd5483c32012-10-19 16:44:15 -0400763 if (!shouldDisableNavbarGestures()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700764 mHandler.removeCallbacks(mShowSearchPanel);
765 mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
766 }
767 break;
768
769 case MotionEvent.ACTION_UP:
770 case MotionEvent.ACTION_CANCEL:
771 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400772 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700773 break;
774 }
775 return false;
Jim Millere898ac52012-04-06 17:10:57 -0700776 }
777 };
Daniel Sandler5c8da942011-06-28 00:29:04 -0400778
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400779 private void awakenDreams() {
780 if (mDreamManager != null) {
781 try {
782 mDreamManager.awaken();
783 } catch (RemoteException e) {
784 // fine, stay asleep then
785 }
786 }
787 }
788
Michael Jurka412cba82011-10-17 09:05:00 -0700789 private void prepareNavigationBarView() {
790 mNavigationBarView.reorient();
791
792 mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
Michael Jurka80343f62012-10-18 13:13:46 +0200793 mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
Jim Miller998bb762012-05-21 13:37:27 -0700794 mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
Daniel Sandler207d5482012-11-06 16:23:43 -0500795 mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
Jim Millere898ac52012-04-06 17:10:57 -0700796 updateSearchPanel();
Michael Jurka412cba82011-10-17 09:05:00 -0700797 }
798
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400799 // For small-screen devices (read: phones) that lack hardware navigation buttons
800 private void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -0400801 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -0400802 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700803
Michael Jurka412cba82011-10-17 09:05:00 -0700804 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400805
Jeff Brown98365d72012-08-19 20:30:52 -0700806 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400807 }
808
809 private void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -0400810 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700811
Michael Jurka412cba82011-10-17 09:05:00 -0700812 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400813
Jeff Brown98365d72012-08-19 20:30:52 -0700814 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400815 }
816
John Spurlock1bbd49d2012-10-19 11:09:32 -0400817 private void notifyNavigationBarScreenOn(boolean screenOn) {
818 if (mNavigationBarView == null) return;
819 mNavigationBarView.notifyScreenOn(screenOn);
820 }
821
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400822 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400823 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -0700824 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400825 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
826 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400827 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
828 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -0700829 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -0400830 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -0700831 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
John Spurlockad3e6cb2013-04-30 08:47:43 -0400832 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700833 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -0700834 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700835 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
836 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400837
838 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400839 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400840 return lp;
841 }
842
Chris Wren157026f2013-06-28 16:54:01 -0400843 private void addHeadsUpView() {
Joe Onorato808182d2010-07-09 18:52:06 -0400844 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Chris Wren0f2aa682013-08-02 12:03:02 -0400845 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
Chris Wren9afc50d2013-07-30 11:31:46 -0400846 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
Joe Onorato808182d2010-07-09 18:52:06 -0400847 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
848 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
849 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
850 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Jeff Brown46e75292010-11-10 16:53:45 -0800851 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
852 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Joe Onorato808182d2010-07-09 18:52:06 -0400853 PixelFormat.TRANSLUCENT);
Chris Wren51c75102013-07-16 20:49:17 -0400854 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Chris Wren0f2aa682013-08-02 12:03:02 -0400855 lp.gravity = Gravity.TOP;
856 lp.y = getStatusBarHeight();
Chris Wren157026f2013-06-28 16:54:01 -0400857 lp.setTitle("Heads Up");
Dianne Hackborn59aed382011-08-02 17:31:44 -0700858 lp.packageName = mContext.getPackageName();
Chris Wren157026f2013-06-28 16:54:01 -0400859 lp.windowAnimations = R.style.Animation_StatusBar_HeadsUp;
Joe Onorato808182d2010-07-09 18:52:06 -0400860
Chris Wren157026f2013-06-28 16:54:01 -0400861 mWindowManager.addView(mHeadsUpNotificationView, lp);
Joe Onorato808182d2010-07-09 18:52:06 -0400862 }
863
Chris Wrenf6e83f42013-09-11 14:02:59 -0400864 private void removeHeadsUpView() {
865 mWindowManager.removeView(mHeadsUpNotificationView);
866 }
867
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -0800868 public void refreshAllStatusBarIcons() {
Fabrice Di Meglioc0cea0f2013-01-11 16:18:00 -0800869 refreshAllIconsForLayout(mStatusIcons);
870 refreshAllIconsForLayout(mNotificationIcons);
871 }
872
873 private void refreshAllIconsForLayout(LinearLayout ll) {
874 final int count = ll.getChildCount();
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -0800875 for (int n = 0; n < count; n++) {
Fabrice Di Meglioc0cea0f2013-01-11 16:18:00 -0800876 View child = ll.getChildAt(n);
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -0800877 if (child instanceof StatusBarIconView) {
878 ((StatusBarIconView) child).updateDrawable();
879 }
880 }
881 }
882
Joe Onorato808182d2010-07-09 18:52:06 -0400883 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
John Spurlockcd686b52013-06-05 10:13:46 -0400884 if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
Joe Onorato808182d2010-07-09 18:52:06 -0400885 + " icon=" + icon);
John Spurlocke6f0a712013-09-03 16:23:49 -0400886 StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400887 view.set(icon);
888 mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
889 }
890
891 public void updateIcon(String slot, int index, int viewIndex,
892 StatusBarIcon old, StatusBarIcon icon) {
John Spurlockcd686b52013-06-05 10:13:46 -0400893 if (SPEW) Log.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
Joe Onorato808182d2010-07-09 18:52:06 -0400894 + " old=" + old + " icon=" + icon);
895 StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
896 view.set(icon);
897 }
898
899 public void removeIcon(String slot, int index, int viewIndex) {
John Spurlockcd686b52013-06-05 10:13:46 -0400900 if (SPEW) Log.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
Joe Onorato808182d2010-07-09 18:52:06 -0400901 mStatusIcons.removeViewAt(viewIndex);
902 }
903
904 public void addNotification(IBinder key, StatusBarNotification notification) {
John Spurlockcd686b52013-06-05 10:13:46 -0400905 if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore());
Chris Wrenf0048ce2013-08-07 16:43:43 -0400906 Entry shadeEntry = createNotificationViews(key, notification);
907 if (shadeEntry == null) {
908 return;
909 }
Chris Wren157026f2013-06-28 16:54:01 -0400910 if (mUseHeadsUp && shouldInterrupt(notification)) {
911 if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
Chris Wrend4db6cb2013-08-07 16:05:23 -0400912 Entry interruptionCandidate = new Entry(key, notification, null);
913 if (inflateViews(interruptionCandidate, mHeadsUpNotificationView.getHolder())) {
914 mInterruptingNotificationTime = System.currentTimeMillis();
915 mInterruptingNotificationEntry = interruptionCandidate;
Chris Wrenf0048ce2013-08-07 16:43:43 -0400916 shadeEntry.setInterruption();
Joe Onorato808182d2010-07-09 18:52:06 -0400917
Chris Wrend4db6cb2013-08-07 16:05:23 -0400918 // 1. Populate mHeadsUpNotificationView
Chris Wren51c75102013-07-16 20:49:17 -0400919 mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
Chris Wrend4db6cb2013-08-07 16:05:23 -0400920
Chris Wren157026f2013-06-28 16:54:01 -0400921 // 2. Animate mHeadsUpNotificationView in
922 mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
Joe Onorato808182d2010-07-09 18:52:06 -0400923
Chris Wren51c75102013-07-16 20:49:17 -0400924 // 3. Set alarm to age the notification off
925 resetHeadsUpDecayTimer();
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400926 }
Chris Wren157026f2013-06-28 16:54:01 -0400927 } else if (notification.getNotification().fullScreenIntent != null) {
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -0400928 // Stop screensaver if the notification has a full-screen intent.
929 // (like an incoming phone call)
930 awakenDreams();
931
Joe Onorato808182d2010-07-09 18:52:06 -0400932 // not immersive & a full-screen alert should be shown
John Spurlockcd686b52013-06-05 10:13:46 -0400933 if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
Joe Onorato808182d2010-07-09 18:52:06 -0400934 try {
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400935 notification.getNotification().fullScreenIntent.send();
Joe Onorato808182d2010-07-09 18:52:06 -0400936 } catch (PendingIntent.CanceledException e) {
937 }
938 } else {
939 // usual case: status bar visible & not immersive
940
Chris Wren157026f2013-06-28 16:54:01 -0400941 // show the ticker if there isn't already a heads up
Chris Wren51c75102013-07-16 20:49:17 -0400942 if (mInterruptingNotificationEntry == null) {
Chris Wren0c8275b2012-05-08 13:36:48 -0400943 tick(null, notification, true);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400944 }
Joe Onorato808182d2010-07-09 18:52:06 -0400945 }
Chris Wrenf0048ce2013-08-07 16:43:43 -0400946 addNotificationViews(shadeEntry);
Joe Onorato808182d2010-07-09 18:52:06 -0400947 // Recalculate the position of the sliding windows and the titles.
948 setAreThereNotifications();
949 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
950 }
951
Chris Wren51c75102013-07-16 20:49:17 -0400952 @Override
953 public void resetHeadsUpDecayTimer() {
Chris Wreneda110f2013-07-25 15:31:59 -0400954 if (mUseHeadsUp && mHeadsUpNotificationDecay > 0
Chris Wren6d15a362013-08-20 18:46:29 -0400955 && mHeadsUpNotificationView.isClearable()) {
956 mHandler.removeMessages(MSG_HIDE_HEADS_UP);
Chris Wren51c75102013-07-16 20:49:17 -0400957 mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay);
958 }
959 }
960
Joe Onorato808182d2010-07-09 18:52:06 -0400961 public void removeNotification(IBinder key) {
Joe Onorato808182d2010-07-09 18:52:06 -0400962 StatusBarNotification old = removeNotificationViews(key);
John Spurlockcd686b52013-06-05 10:13:46 -0400963 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -0400964
965 if (old != null) {
966 // Cancel the ticker if it's still running
967 mTicker.removeEntry(old);
968
969 // Recalculate the position of the sliding windows and the titles.
Joe Onorato808182d2010-07-09 18:52:06 -0400970 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Jim Millere898ac52012-04-06 17:10:57 -0700971
Chris Wren51c75102013-07-16 20:49:17 -0400972 if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
973 && old == mInterruptingNotificationEntry.notification) {
Chris Wren157026f2013-06-28 16:54:01 -0400974 mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400975 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400976
John Spurlock1caf7eb2013-08-07 18:06:18 -0400977 if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0
John Spurlocka4b70af2013-08-17 14:05:49 -0400978 && !mNotificationPanel.isTracking()) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400979 animateCollapsePanels();
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400980 }
Joe Onorato808182d2010-07-09 18:52:06 -0400981 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400982
983 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400984 }
985
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700986 @Override
987 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700988 if (mNavigationBarView != null) {
989 mNavigationBarView.setLayoutDirection(layoutDirection);
990 }
991
992 if (mClearButton != null && mClearButton instanceof ImageView) {
993 // Force asset reloading
994 ((ImageView)mClearButton).setImageDrawable(null);
995 ((ImageView)mClearButton).setImageResource(R.drawable.ic_notify_clear);
996 }
997
998 if (mSettingsButton != null) {
999 // Force asset reloading
1000 mSettingsButton.setImageDrawable(null);
1001 mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
1002 }
1003
1004 if (mNotificationButton != null) {
1005 // Force asset reloading
1006 mNotificationButton.setImageDrawable(null);
1007 mNotificationButton.setImageResource(R.drawable.ic_notifications);
1008 }
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -08001009
1010 refreshAllStatusBarIcons();
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001011 }
1012
John Spurlockd5ef5462012-06-13 11:19:51 -04001013 private void updateShowSearchHoldoff() {
1014 mShowSearchHoldoff = mContext.getResources().getInteger(
1015 R.integer.config_show_search_delay);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001016 }
1017
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001018 private void loadNotificationShade() {
Daniel Sandler26cda272012-05-22 15:44:08 -04001019 if (mPile == null) return;
1020
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001021 int N = mNotificationData.size();
1022
1023 ArrayList<View> toShow = new ArrayList<View>();
1024
Daniel Sandler26cda272012-05-22 15:44:08 -04001025 final boolean provisioned = isDeviceProvisioned();
1026 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001027 for (int i=0; i<N; i++) {
Daniel Sandler26cda272012-05-22 15:44:08 -04001028 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001029 if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
1030 if (!notificationIsForCurrentUser(ent.notification)) continue;
1031 toShow.add(ent.row);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001032 }
1033
1034 ArrayList<View> toRemove = new ArrayList<View>();
1035 for (int i=0; i<mPile.getChildCount(); i++) {
1036 View child = mPile.getChildAt(i);
1037 if (!toShow.contains(child)) {
1038 toRemove.add(child);
Joe Onorato808182d2010-07-09 18:52:06 -04001039 }
1040 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001041
1042 for (View remove : toRemove) {
1043 mPile.removeView(remove);
1044 }
1045
1046 for (int i=0; i<toShow.size(); i++) {
1047 View v = toShow.get(i);
1048 if (v.getParent() == null) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001049 mPile.addView(v, i);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001050 }
1051 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001052
Daniel Sandler6e5fe432012-09-16 15:34:36 -04001053 if (mSettingsButton != null) {
1054 mSettingsButton.setEnabled(isDeviceProvisioned());
1055 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001056 }
1057
Chris Wren0c8275b2012-05-08 13:36:48 -04001058 @Override
1059 protected void updateNotificationIcons() {
Daniel Sandler26cda272012-05-22 15:44:08 -04001060 if (mNotificationIcons == null) return;
1061
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001062 loadNotificationShade();
1063
1064 final LinearLayout.LayoutParams params
1065 = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
1066
1067 int N = mNotificationData.size();
1068
1069 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001070 Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001071 }
1072
1073 ArrayList<View> toShow = new ArrayList<View>();
1074
Daniel Sandler26cda272012-05-22 15:44:08 -04001075 final boolean provisioned = isDeviceProvisioned();
1076 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001077 for (int i=0; i<N; i++) {
Daniel Sandler58b173b2012-05-03 11:25:29 -04001078 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -04001079 if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001080 || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
1081 if (!notificationIsForCurrentUser(ent.notification)) continue;
1082 toShow.add(ent.icon);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001083 }
1084
1085 ArrayList<View> toRemove = new ArrayList<View>();
1086 for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
1087 View child = mNotificationIcons.getChildAt(i);
1088 if (!toShow.contains(child)) {
1089 toRemove.add(child);
1090 }
1091 }
1092
1093 for (View remove : toRemove) {
1094 mNotificationIcons.removeView(remove);
1095 }
1096
1097 for (int i=0; i<toShow.size(); i++) {
1098 View v = toShow.get(i);
1099 if (v.getParent() == null) {
1100 mNotificationIcons.addView(v, i, params);
1101 }
1102 }
1103 }
1104
Daniel Sandlere5011a32012-06-11 16:07:52 -04001105 protected void updateCarrierLabelVisibility(boolean force) {
Daniel Sandlerbf526d12012-09-04 22:56:44 -04001106 if (!mShowCarrierInPanel) return;
John Spurlock209bede2013-07-17 12:23:27 -04001107 // 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 -04001108 // i.e. when there aren't enough notifications to fill the panel.
Chris Wren6d15a362013-08-20 18:46:29 -04001109 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001110 Log.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
Daniel Sandler3d32a242012-06-05 13:44:14 -04001111 mPile.getHeight(), mScrollView.getHeight(), mCarrierLabelHeight));
1112 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -04001113
1114 final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
1115 final boolean makeVisible =
1116 !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
Daniel Sandler101784e2012-10-15 13:39:38 -04001117 && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight)
1118 && mScrollView.getVisibility() == View.VISIBLE;
John Spurlock209bede2013-07-17 12:23:27 -04001119
Daniel Sandlere5011a32012-06-11 16:07:52 -04001120 if (force || mCarrierLabelVisible != makeVisible) {
Daniel Sandler3d32a242012-06-05 13:44:14 -04001121 mCarrierLabelVisible = makeVisible;
1122 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001123 Log.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
Daniel Sandler3d32a242012-06-05 13:44:14 -04001124 }
1125 mCarrierLabel.animate().cancel();
1126 if (makeVisible) {
1127 mCarrierLabel.setVisibility(View.VISIBLE);
1128 }
1129 mCarrierLabel.animate()
1130 .alpha(makeVisible ? 1f : 0f)
1131 //.setStartDelay(makeVisible ? 500 : 0)
1132 //.setDuration(makeVisible ? 750 : 100)
1133 .setDuration(150)
1134 .setListener(makeVisible ? null : new AnimatorListenerAdapter() {
1135 @Override
1136 public void onAnimationEnd(Animator animation) {
1137 if (!mCarrierLabelVisible) { // race
1138 mCarrierLabel.setVisibility(View.INVISIBLE);
1139 mCarrierLabel.setAlpha(0f);
1140 }
1141 }
1142 })
1143 .start();
1144 }
1145 }
1146
Chris Wren0c8275b2012-05-08 13:36:48 -04001147 @Override
1148 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001149 final boolean any = mNotificationData.size() > 0;
Joe Onorato808182d2010-07-09 18:52:06 -04001150
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001151 final boolean clearable = any && mNotificationData.hasClearableItems();
1152
Chris Wren6d15a362013-08-20 18:46:29 -04001153 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001154 Log.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001155 + " any=" + any + " clearable=" + clearable);
1156 }
1157
John Spurlock209bede2013-07-17 12:23:27 -04001158 if (mHasFlipSettings
1159 && mFlipSettingsView != null
Daniel Sandlerf249efc2012-10-17 16:42:36 -04001160 && mFlipSettingsView.getVisibility() == View.VISIBLE
1161 && mScrollView.getVisibility() != View.VISIBLE) {
1162 // the flip settings panel is unequivocally showing; we should not be shown
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001163 mClearButton.setVisibility(View.INVISIBLE);
1164 } else if (mClearButton.isShown()) {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001165 if (clearable != (mClearButton.getAlpha() == 1.0f)) {
Romain Guy8900e632012-05-25 12:08:39 -07001166 ObjectAnimator clearAnimation = ObjectAnimator.ofFloat(
1167 mClearButton, "alpha", clearable ? 1.0f : 0.0f).setDuration(250);
1168 clearAnimation.addListener(new AnimatorListenerAdapter() {
1169 @Override
1170 public void onAnimationEnd(Animator animation) {
1171 if (mClearButton.getAlpha() <= 0.0f) {
1172 mClearButton.setVisibility(View.INVISIBLE);
1173 }
1174 }
1175
1176 @Override
1177 public void onAnimationStart(Animator animation) {
1178 if (mClearButton.getAlpha() <= 0.0f) {
1179 mClearButton.setVisibility(View.VISIBLE);
1180 }
1181 }
1182 });
1183 clearAnimation.start();
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001184 }
1185 } else {
1186 mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
Romain Guy8900e632012-05-25 12:08:39 -07001187 mClearButton.setVisibility(clearable ? View.VISIBLE : View.INVISIBLE);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001188 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001189 mClearButton.setEnabled(clearable);
Romain Guy8900e632012-05-25 12:08:39 -07001190
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001191 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
1192 final boolean showDot = (any&&!areLightsOn());
1193 if (showDot != (nlo.getAlpha() == 1.0f)) {
1194 if (showDot) {
1195 nlo.setAlpha(0f);
1196 nlo.setVisibility(View.VISIBLE);
1197 }
1198 nlo.animate()
1199 .alpha(showDot?1:0)
1200 .setDuration(showDot?750:250)
1201 .setInterpolator(new AccelerateInterpolator(2.0f))
1202 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1203 @Override
1204 public void onAnimationEnd(Animator _a) {
1205 nlo.setVisibility(View.GONE);
1206 }
1207 })
1208 .start();
1209 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001210
Daniel Sandlere5011a32012-06-11 16:07:52 -04001211 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001212 }
1213
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001214 public void showClock(boolean show) {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001215 if (mStatusBarView == null) return;
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001216 View clock = mStatusBarView.findViewById(R.id.clock);
1217 if (clock != null) {
1218 clock.setVisibility(show ? View.VISIBLE : View.GONE);
1219 }
1220 }
Joe Onorato808182d2010-07-09 18:52:06 -04001221
1222 /**
1223 * State is one or more of the DISABLE constants from StatusBarManager.
1224 */
1225 public void disable(int state) {
1226 final int old = mDisabled;
1227 final int diff = state ^ old;
1228 mDisabled = state;
1229
Daniel Sandlere21f2882011-08-18 10:14:59 -04001230 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001231 Log.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
Daniel Sandlere21f2882011-08-18 10:14:59 -04001232 old, state, diff));
1233 }
1234
Daniel Sandler6da2b762011-09-14 16:04:59 -04001235 StringBuilder flagdbg = new StringBuilder();
1236 flagdbg.append("disable: < ");
1237 flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
1238 flagdbg.append(((diff & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
1239 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
1240 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
1241 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
1242 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
1243 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "TICKER" : "ticker");
1244 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
1245 flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
1246 flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001247 flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
1248 flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
Daniel Sandlerdba93562011-10-06 16:39:58 -04001249 flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
1250 flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
1251 flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
1252 flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001253 flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
1254 flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001255 flagdbg.append(((state & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
1256 flagdbg.append(((diff & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001257 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04001258 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07001259
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001260 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001261 mSystemIconArea.animate().cancel();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001262 if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001263 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001264 .alpha(0f)
1265 .translationY(mNaturalBarHeight*0.5f)
Daniel Sandler67e7d902012-06-06 16:32:21 -04001266 .setDuration(175)
1267 .setInterpolator(new DecelerateInterpolator(1.5f))
1268 .setListener(mMakeIconsInvisible)
1269 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001270 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001271 mSystemIconArea.setVisibility(View.VISIBLE);
1272 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001273 .alpha(1f)
1274 .translationY(0)
1275 .setStartDelay(0)
1276 .setInterpolator(new DecelerateInterpolator(1.5f))
1277 .setDuration(175)
1278 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001279 }
1280 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04001281
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001282 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
1283 boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
1284 showClock(show);
1285 }
Joe Onorato808182d2010-07-09 18:52:06 -04001286 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1287 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001288 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04001289 }
1290 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001291
Jim Miller5e6af442011-12-02 18:24:26 -08001292 if ((diff & (StatusBarManager.DISABLE_HOME
1293 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001294 | StatusBarManager.DISABLE_BACK
1295 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04001296 // the nav bar will take care of these
Daniel Sandlerd9283b902011-09-14 21:42:00 -04001297 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001298
Daniel Sandlerdba93562011-10-06 16:39:58 -04001299 if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04001300 // close recents if it's visible
1301 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1302 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1303 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001304 }
1305
Joe Onorato808182d2010-07-09 18:52:06 -04001306 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1307 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Joe Onorato808182d2010-07-09 18:52:06 -04001308 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001309 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001310 }
Daniel Sandler173bae22012-09-25 14:37:42 -04001311
1312 mNotificationIcons.animate()
1313 .alpha(0f)
1314 .translationY(mNaturalBarHeight*0.5f)
1315 .setDuration(175)
1316 .setInterpolator(new DecelerateInterpolator(1.5f))
1317 .setListener(mMakeIconsInvisible)
1318 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001319 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001320 mNotificationIcons.setVisibility(View.VISIBLE);
1321 mNotificationIcons.animate()
1322 .alpha(1f)
1323 .translationY(0)
1324 .setStartDelay(0)
1325 .setInterpolator(new DecelerateInterpolator(1.5f))
1326 .setDuration(175)
1327 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001328 }
1329 } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1330 if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001331 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001332 }
1333 }
1334 }
1335
Michael Jurka7f2668c2012-03-27 07:49:52 -07001336 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07001337 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001338 return new PhoneStatusBar.H();
1339 }
1340
Joe Onorato808182d2010-07-09 18:52:06 -04001341 /**
1342 * All changes to the status bar and notifications funnel through here and are batched.
1343 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07001344 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04001345 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001346 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04001347 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001348 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04001349 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001350 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04001351 case MSG_OPEN_SETTINGS_PANEL:
1352 animateExpandSettingsPanel();
1353 break;
1354 case MSG_CLOSE_PANELS:
1355 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001356 break;
Chris Wren157026f2013-06-28 16:54:01 -04001357 case MSG_SHOW_HEADS_UP:
1358 setHeadsUpVisibility(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001359 break;
Chris Wren157026f2013-06-28 16:54:01 -04001360 case MSG_HIDE_HEADS_UP:
1361 setHeadsUpVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001362 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04001363 case MSG_ESCALATE_HEADS_UP:
1364 escalateHeadsUp();
1365 setHeadsUpVisibility(false);
Chris Wrene97f90b2013-08-07 17:39:35 -04001366 break;
1367 }
1368 }
1369 }
1370
1371 /** if the interrupting notification had a fullscreen intent, fire it now. */
1372 private void escalateHeadsUp() {
1373 if (mInterruptingNotificationEntry != null) {
1374 final StatusBarNotification sbn = mInterruptingNotificationEntry.notification;
1375 final Notification notification = sbn.getNotification();
1376 if (notification.fullScreenIntent != null) {
1377 if (DEBUG)
1378 Log.d(TAG, "converting a heads up to fullScreen");
1379 try {
1380 notification.fullScreenIntent.send();
1381 } catch (PendingIntent.CanceledException e) {
1382 }
Joe Onorato808182d2010-07-09 18:52:06 -04001383 }
1384 }
1385 }
1386
Daniel Sandler040c2e42012-10-17 00:56:33 -04001387 public Handler getHandler() {
1388 return mHandler;
1389 }
1390
Joe Onorato808182d2010-07-09 18:52:06 -04001391 View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
1392 public void onFocusChange(View v, boolean hasFocus) {
1393 // Because 'v' is a ViewGroup, all its children will be (un)selected
1394 // too, which allows marqueeing to work.
1395 v.setSelected(hasFocus);
1396 }
1397 };
1398
John Spurlock97642182013-07-29 17:58:39 -04001399 boolean panelsEnabled() {
John Spurlock79ec2a12013-09-11 09:28:49 -04001400 return (mDisabled & StatusBarManager.DISABLE_EXPAND) == 0;
John Spurlock97642182013-07-29 17:58:39 -04001401 }
1402
John Spurlocka5baf892013-07-25 13:15:42 -04001403 void makeExpandedVisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04001404 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04001405 if (mExpandedVisible || !panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04001406 return;
1407 }
Jim Millera073e572012-05-23 17:03:27 -07001408
Joe Onorato808182d2010-07-09 18:52:06 -04001409 mExpandedVisible = true;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001410 mPile.setLayoutTransitionsEnabled(true);
John Spurlockd5ef5462012-06-13 11:19:51 -04001411 if (mNavigationBarView != null)
1412 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001413
Daniel Sandlere5011a32012-06-11 16:07:52 -04001414 updateCarrierLabelVisibility(true);
Daniel Sandler3d32a242012-06-05 13:44:14 -04001415
Joe Onorato808182d2010-07-09 18:52:06 -04001416 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Daniel Sandlera310af82012-04-24 01:20:13 -04001417
1418 // Expand the window to encompass the full screen in anticipation of the drag.
1419 // This is only possible to do atomically because the status bar is at the top of the screen!
1420 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001421 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1422 lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Daniel Sandler21b274e2012-05-02 15:07:51 -04001423 lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
Jeff Brown98365d72012-08-19 20:30:52 -07001424 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Daniel Sandlera310af82012-04-24 01:20:13 -04001425
1426 visibilityChanged(true);
John Spurlock32beb2c2013-03-11 10:16:47 -04001427
John Spurlockcfc359a2013-09-05 10:42:03 -04001428 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
Joe Onorato808182d2010-07-09 18:52:06 -04001429 }
1430
John Spurlock37d608d2013-09-15 09:07:51 -04001431 private void releaseFocus() {
1432 WindowManager.LayoutParams lp =
1433 (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
1434 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1435 lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
1436 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
1437 }
1438
Daniel Sandler11cf1782012-09-27 14:03:08 -04001439 public void animateCollapsePanels() {
1440 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001441 }
1442
Daniel Sandler11cf1782012-09-27 14:03:08 -04001443 public void animateCollapsePanels(int flags) {
Joe Onorato808182d2010-07-09 18:52:06 -04001444 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001445 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04001446 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07001447 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04001448 }
1449
John Spurlock37d608d2013-09-15 09:07:51 -04001450 // release focus immediately to kick off focus change transition
1451 releaseFocus();
1452
Jim Miller9a720f52012-05-30 03:19:43 -07001453 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Michael Jurka3b1fc472011-06-13 10:54:40 -07001454 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1455 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1456 }
Jim Miller9a720f52012-05-30 03:19:43 -07001457
1458 if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
1459 mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
1460 mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
1461 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07001462
Daniel Sandlerac47ff72012-10-23 10:41:44 -04001463 mStatusBarWindow.cancelExpandHelper();
Daniel Sandler08d05e32012-08-08 16:39:54 -04001464 mStatusBarView.collapseAllPanels(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001465 }
1466
Daniel Sandler101784e2012-10-15 13:39:38 -04001467 public ViewPropertyAnimator setVisibilityWhenDone(
1468 final ViewPropertyAnimator a, final View v, final int vis) {
1469 a.setListener(new AnimatorListenerAdapter() {
1470 @Override
1471 public void onAnimationEnd(Animator animation) {
1472 v.setVisibility(vis);
1473 a.setListener(null); // oneshot
1474 }
1475 });
1476 return a;
1477 }
1478
1479 public Animator setVisibilityWhenDone(
1480 final Animator a, final View v, final int vis) {
1481 a.addListener(new AnimatorListenerAdapter() {
1482 @Override
1483 public void onAnimationEnd(Animator animation) {
1484 v.setVisibility(vis);
1485 }
1486 });
1487 return a;
1488 }
1489
1490 public Animator interpolator(TimeInterpolator ti, Animator a) {
1491 a.setInterpolator(ti);
1492 return a;
1493 }
1494
1495 public Animator startDelay(int d, Animator a) {
1496 a.setStartDelay(d);
1497 return a;
1498 }
John Spurlock209bede2013-07-17 12:23:27 -04001499
Daniel Sandler101784e2012-10-15 13:39:38 -04001500 public Animator start(Animator a) {
1501 a.start();
1502 return a;
1503 }
1504
1505 final TimeInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
1506 final TimeInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
1507 final int FLIP_DURATION_OUT = 125;
1508 final int FLIP_DURATION_IN = 225;
1509 final int FLIP_DURATION = (FLIP_DURATION_IN + FLIP_DURATION_OUT);
1510
1511 Animator mScrollViewAnim, mFlipSettingsViewAnim, mNotificationButtonAnim,
1512 mSettingsButtonAnim, mClearButtonAnim;
1513
Daniel Sandler08d05e32012-08-08 16:39:54 -04001514 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001515 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04001516 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04001517 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04001518 return ;
1519 }
Joe Onorato808182d2010-07-09 18:52:06 -04001520
Daniel Sandler08d05e32012-08-08 16:39:54 -04001521 mNotificationPanel.expand();
Daniel Sandler040c2e42012-10-17 00:56:33 -04001522 if (mHasFlipSettings && mScrollView.getVisibility() != View.VISIBLE) {
1523 flipToNotifications();
Daniel Sandler101784e2012-10-15 13:39:38 -04001524 }
Joe Onorato808182d2010-07-09 18:52:06 -04001525
1526 if (false) postStartTracing();
1527 }
1528
Daniel Sandler040c2e42012-10-17 00:56:33 -04001529 public void flipToNotifications() {
1530 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1531 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1532 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1533 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1534 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1535
1536 mScrollView.setVisibility(View.VISIBLE);
1537 mScrollViewAnim = start(
1538 startDelay(FLIP_DURATION_OUT,
1539 interpolator(mDecelerateInterpolator,
1540 ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f, 1f)
1541 .setDuration(FLIP_DURATION_IN)
1542 )));
1543 mFlipSettingsViewAnim = start(
1544 setVisibilityWhenDone(
1545 interpolator(mAccelerateInterpolator,
1546 ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f, 0f)
1547 )
1548 .setDuration(FLIP_DURATION_OUT),
1549 mFlipSettingsView, View.INVISIBLE));
1550 mNotificationButtonAnim = start(
1551 setVisibilityWhenDone(
1552 ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
1553 .setDuration(FLIP_DURATION),
1554 mNotificationButton, View.INVISIBLE));
1555 mSettingsButton.setVisibility(View.VISIBLE);
1556 mSettingsButtonAnim = start(
1557 ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
1558 .setDuration(FLIP_DURATION));
1559 mClearButton.setVisibility(View.VISIBLE);
1560 mClearButton.setAlpha(0f);
1561 setAreThereNotifications(); // this will show/hide the button as necessary
1562 mNotificationPanel.postDelayed(new Runnable() {
1563 public void run() {
1564 updateCarrierLabelVisibility(false);
1565 }
1566 }, FLIP_DURATION - 150);
1567 }
1568
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001569 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001570 public void animateExpandSettingsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04001571 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04001572 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001573 return;
1574 }
1575
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001576 // Settings are not available in setup
1577 if (!mUserSetup) return;
1578
Daniel Sandler101784e2012-10-15 13:39:38 -04001579 if (mHasFlipSettings) {
1580 mNotificationPanel.expand();
1581 if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
Daniel Sandler040c2e42012-10-17 00:56:33 -04001582 flipToSettings();
Daniel Sandler101784e2012-10-15 13:39:38 -04001583 }
1584 } else if (mSettingsPanel != null) {
1585 mSettingsPanel.expand();
1586 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001587
1588 if (false) postStartTracing();
1589 }
1590
Daniel Sandler040c2e42012-10-17 00:56:33 -04001591 public void switchToSettings() {
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001592 // Settings are not available in setup
1593 if (!mUserSetup) return;
1594
Daniel Sandler040c2e42012-10-17 00:56:33 -04001595 mFlipSettingsView.setScaleX(1f);
1596 mFlipSettingsView.setVisibility(View.VISIBLE);
1597 mSettingsButton.setVisibility(View.GONE);
1598 mScrollView.setVisibility(View.GONE);
Daniel Sandler720a34d2012-10-18 11:44:04 -04001599 mScrollView.setScaleX(0f);
Daniel Sandler040c2e42012-10-17 00:56:33 -04001600 mNotificationButton.setVisibility(View.VISIBLE);
1601 mNotificationButton.setAlpha(1f);
1602 mClearButton.setVisibility(View.GONE);
1603 }
1604
1605 public void flipToSettings() {
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001606 // Settings are not available in setup
1607 if (!mUserSetup) return;
1608
Daniel Sandler040c2e42012-10-17 00:56:33 -04001609 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1610 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1611 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1612 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1613 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1614
1615 mFlipSettingsView.setVisibility(View.VISIBLE);
1616 mFlipSettingsView.setScaleX(0f);
1617 mFlipSettingsViewAnim = start(
1618 startDelay(FLIP_DURATION_OUT,
1619 interpolator(mDecelerateInterpolator,
1620 ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f, 1f)
1621 .setDuration(FLIP_DURATION_IN)
1622 )));
1623 mScrollViewAnim = start(
1624 setVisibilityWhenDone(
1625 interpolator(mAccelerateInterpolator,
1626 ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f)
1627 )
John Spurlock209bede2013-07-17 12:23:27 -04001628 .setDuration(FLIP_DURATION_OUT),
Daniel Sandler040c2e42012-10-17 00:56:33 -04001629 mScrollView, View.INVISIBLE));
1630 mSettingsButtonAnim = start(
1631 setVisibilityWhenDone(
1632 ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
1633 .setDuration(FLIP_DURATION),
1634 mScrollView, View.INVISIBLE));
1635 mNotificationButton.setVisibility(View.VISIBLE);
1636 mNotificationButtonAnim = start(
1637 ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
1638 .setDuration(FLIP_DURATION));
1639 mClearButtonAnim = start(
1640 setVisibilityWhenDone(
1641 ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
1642 .setDuration(FLIP_DURATION),
1643 mClearButton, View.INVISIBLE));
1644 mNotificationPanel.postDelayed(new Runnable() {
1645 public void run() {
1646 updateCarrierLabelVisibility(false);
1647 }
1648 }, FLIP_DURATION - 150);
1649 }
1650
1651 public void flipPanels() {
1652 if (mHasFlipSettings) {
1653 if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
1654 flipToSettings();
1655 } else {
1656 flipToNotifications();
1657 }
1658 }
1659 }
1660
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001661 public void animateCollapseQuickSettings() {
1662 mStatusBarView.collapseAllPanels(true);
1663 }
1664
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001665 void makeExpandedInvisibleSoon() {
1666 mHandler.postDelayed(new Runnable() { public void run() { makeExpandedInvisible(); }}, 50);
1667 }
1668
Daniel Sandler08d05e32012-08-08 16:39:54 -04001669 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04001670 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04001671 + " mExpandedVisible=" + mExpandedVisible);
1672
1673 if (!mExpandedVisible) {
1674 return;
1675 }
Daniel Sandlered930e52012-07-03 14:31:22 -04001676
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04001677 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
1678 mStatusBarView.collapseAllPanels(/*animate=*/ false);
Daniel Sandlered930e52012-07-03 14:31:22 -04001679
Daniel Sandler040c2e42012-10-17 00:56:33 -04001680 if (mHasFlipSettings) {
1681 // reset things to their proper state
Daniel Sandler50bc4f52012-10-22 14:47:55 -04001682 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1683 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1684 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1685 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1686 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1687
Daniel Sandler040c2e42012-10-17 00:56:33 -04001688 mScrollView.setScaleX(1f);
1689 mScrollView.setVisibility(View.VISIBLE);
1690 mSettingsButton.setAlpha(1f);
1691 mSettingsButton.setVisibility(View.VISIBLE);
1692 mNotificationPanel.setVisibility(View.GONE);
1693 mFlipSettingsView.setVisibility(View.GONE);
1694 mNotificationButton.setVisibility(View.GONE);
1695 setAreThereNotifications(); // show the clear button
1696 }
1697
Joe Onorato808182d2010-07-09 18:52:06 -04001698 mExpandedVisible = false;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001699 mPile.setLayoutTransitionsEnabled(false);
John Spurlockd5ef5462012-06-13 11:19:51 -04001700 if (mNavigationBarView != null)
1701 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001702 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04001703
1704 // Shrink the window to the size of the status bar only
1705 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
1706 lp.height = getStatusBarHeight();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001707 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1708 lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jeff Brown98365d72012-08-19 20:30:52 -07001709 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04001710
1711 if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
1712 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1713 }
Joe Onorato808182d2010-07-09 18:52:06 -04001714
Daniel Sandler469e96e2012-05-04 15:56:19 -04001715 // Close any "App info" popups that might have snuck on-screen
1716 dismissPopups();
1717
Chet Haase2f2022a2011-10-11 06:41:59 -07001718 if (mPostCollapseCleanup != null) {
1719 mPostCollapseCleanup.run();
1720 mPostCollapseCleanup = null;
1721 }
John Spurlock32beb2c2013-03-11 10:16:47 -04001722
John Spurlockcfc359a2013-09-05 10:42:03 -04001723 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Joe Onorato808182d2010-07-09 18:52:06 -04001724 }
1725
Romain Guy54ab3472012-06-14 12:52:53 -07001726 /**
1727 * Enables or disables layers on the children of the notifications pile.
John Spurlock209bede2013-07-17 12:23:27 -04001728 *
Romain Guy54ab3472012-06-14 12:52:53 -07001729 * When layers are enabled, this method attempts to enable layers for the minimal
1730 * number of children. Only children visible when the notification area is fully
1731 * expanded will receive a layer. The technique used in this method might cause
1732 * more children than necessary to get a layer (at most one extra child with the
1733 * current UI.)
John Spurlock209bede2013-07-17 12:23:27 -04001734 *
Romain Guy54ab3472012-06-14 12:52:53 -07001735 * @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE}
1736 */
1737 private void setPileLayers(int layerType) {
1738 final int count = mPile.getChildCount();
1739
1740 switch (layerType) {
1741 case View.LAYER_TYPE_NONE:
1742 for (int i = 0; i < count; i++) {
1743 mPile.getChildAt(i).setLayerType(layerType, null);
1744 }
1745 break;
1746 case View.LAYER_TYPE_HARDWARE:
John Spurlock209bede2013-07-17 12:23:27 -04001747 final int[] location = new int[2];
Romain Guy54ab3472012-06-14 12:52:53 -07001748 mNotificationPanel.getLocationInWindow(location);
1749
1750 final int left = location[0];
1751 final int top = location[1];
1752 final int right = left + mNotificationPanel.getWidth();
1753 final int bottom = top + getExpandedViewMaxHeight();
1754
1755 final Rect childBounds = new Rect();
1756
1757 for (int i = 0; i < count; i++) {
1758 final View view = mPile.getChildAt(i);
1759 view.getLocationInWindow(location);
1760
1761 childBounds.set(location[0], location[1],
1762 location[0] + view.getWidth(), location[1] + view.getHeight());
1763
1764 if (childBounds.intersects(left, top, right, bottom)) {
1765 view.setLayerType(layerType, null);
1766 }
1767 }
1768
1769 break;
1770 }
1771 }
1772
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001773 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05001774 if (DEBUG_GESTURES) {
1775 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
1776 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
1777 event.getActionMasked(), (int) event.getX(), (int) event.getY(), mDisabled);
1778 }
1779
1780 }
1781
Joe Onorato808182d2010-07-09 18:52:06 -04001782 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001783 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
John Spurlock804df702012-06-01 15:34:27 -04001784 + mDisabled + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001785 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001786 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04001787 Log.d(TAG, String.format(
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001788 "panel: %s at (%f, %f) mDisabled=0x%08x",
1789 MotionEvent.actionToString(event.getAction()),
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001790 event.getRawX(), event.getRawY(), mDisabled));
1791 }
Joe Onorato808182d2010-07-09 18:52:06 -04001792 }
1793
Daniel Sandler151f00d2012-10-02 22:33:08 -04001794 if (DEBUG_GESTURES) {
1795 mGestureRec.add(event);
1796 }
Daniel Sandler33805342012-07-23 15:45:12 -04001797
John Spurlock686820a2013-09-03 14:44:16 -04001798 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04001799 final boolean upOrCancel =
1800 event.getAction() == MotionEvent.ACTION_UP ||
1801 event.getAction() == MotionEvent.ACTION_CANCEL;
1802 if (upOrCancel && !mExpandedVisible) {
1803 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
1804 } else {
1805 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
1806 }
John Spurlock686820a2013-09-03 14:44:16 -04001807 }
Joe Onorato808182d2010-07-09 18:52:06 -04001808 return false;
1809 }
1810
Daniel Sandler08d05e32012-08-08 16:39:54 -04001811 public GestureRecorder getGestureRecorder() {
1812 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07001813 }
1814
John Spurlock56d007b2013-10-28 18:40:56 -04001815 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04001816 if (hints == mNavigationIconHints) return;
1817
1818 mNavigationIconHints = hints;
1819
1820 if (mNavigationBarView != null) {
1821 mNavigationBarView.setNavigationIconHints(hints);
1822 }
John Spurlockd4e65752013-08-28 14:17:09 -04001823 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04001824 }
1825
1826 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04001827 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04001828 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04001829 if (mStatusBarWindow != null
1830 && window == StatusBarManager.WINDOW_STATUS_BAR
1831 && mStatusBarWindowState != state) {
1832 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04001833 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
John Spurlock5b9145b2013-08-20 15:13:47 -04001834 if (!showing) {
John Spurlock97642182013-07-29 17:58:39 -04001835 mStatusBarView.collapseAllPanels(false);
John Spurlock97642182013-07-29 17:58:39 -04001836 }
1837 }
1838 if (mNavigationBarView != null
1839 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
1840 && mNavigationBarWindowState != state) {
1841 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04001842 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04001843 }
1844 }
1845
John Spurlock97642182013-07-29 17:58:39 -04001846 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001847 public void setSystemUiVisibility(int vis, int mask) {
1848 final int oldVal = mSystemUiVisibility;
1849 final int newVal = (oldVal&~mask) | (vis&mask);
1850 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04001851 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04001852 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
1853 Integer.toHexString(vis), Integer.toHexString(mask),
1854 Integer.toHexString(oldVal), Integer.toHexString(newVal),
1855 Integer.toHexString(diff)));
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001856 if (diff != 0) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001857 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04001858
John Spurlocke1f366f2013-08-05 12:22:40 -04001859 // update low profile
1860 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
1861 final boolean lightsOut = (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001862 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001863 animateCollapsePanels();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001864 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001865 haltTicker();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001866 }
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001867 }
Jim Millera073e572012-05-23 17:03:27 -07001868
John Spurlock7edfbca2013-09-14 11:58:55 -04001869 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04001870 }
1871
John Spurlocke1f366f2013-08-05 12:22:40 -04001872 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04001873 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04001874 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04001875
1876 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04001877 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04001878 oldVal, newVal, mNavigationBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04001879 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT);
John Spurlockd4e65752013-08-28 14:17:09 -04001880 final boolean sbModeChanged = sbMode != -1;
1881 final boolean nbModeChanged = nbMode != -1;
1882 boolean checkBarModes = false;
1883 if (sbModeChanged && sbMode != mStatusBarMode) {
1884 mStatusBarMode = sbMode;
1885 checkBarModes = true;
1886 }
1887 if (nbModeChanged && nbMode != mNavigationBarMode) {
1888 mNavigationBarMode = nbMode;
1889 checkBarModes = true;
1890 }
1891 if (checkBarModes) {
1892 checkBarModes();
1893 }
1894 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04001895 // update transient bar autohide
John Spurlock89835dd2013-08-16 15:06:51 -04001896 if (sbMode == MODE_SEMI_TRANSPARENT || nbMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04001897 scheduleAutohide();
1898 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04001899 cancelAutohide();
1900 }
1901 }
John Spurlocke1f366f2013-08-05 12:22:40 -04001902
John Spurlock5b9145b2013-08-20 15:13:47 -04001903 // ready to unhide
1904 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
1905 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
1906 }
1907 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
1908 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
1909 }
1910
John Spurlocke1f366f2013-08-05 12:22:40 -04001911 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04001912 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04001913 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001914 }
1915
John Spurlockd4e65752013-08-28 14:17:09 -04001916 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
John Spurlockbd957402013-10-03 11:38:39 -04001917 int transientFlag, int translucentFlag) {
1918 final int oldMode = barMode(oldVis, transientFlag, translucentFlag);
1919 final int newMode = barMode(newVis, transientFlag, translucentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04001920 if (oldMode == newMode) {
1921 return -1; // no mode change
1922 }
John Spurlocke1f366f2013-08-05 12:22:40 -04001923 return newMode;
1924 }
1925
John Spurlockbd957402013-10-03 11:38:39 -04001926 private int barMode(int vis, int transientFlag, int translucentFlag) {
John Spurlock89835dd2013-08-16 15:06:51 -04001927 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04001928 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
John Spurlock7edfbca2013-09-14 11:58:55 -04001929 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04001930 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04001931 }
1932
John Spurlockd4e65752013-08-28 14:17:09 -04001933 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04001934 if (mDemoMode) return;
John Spurlock3d7e0952013-10-13 13:34:21 -04001935 int sbMode = mStatusBarMode;
1936 if (panelsEnabled() && (mInteractingWindows & StatusBarManager.WINDOW_STATUS_BAR) != 0) {
1937 // if panels are expandable, force the status bar opaque on any interaction
1938 sbMode = MODE_OPAQUE;
1939 }
1940 checkBarMode(sbMode, mStatusBarWindowState, mStatusBarView.getBarTransitions());
John Spurlockd4e65752013-08-28 14:17:09 -04001941 if (mNavigationBarView != null) {
1942 checkBarMode(mNavigationBarMode,
1943 mNavigationBarWindowState, mNavigationBarView.getBarTransitions());
1944 }
1945 }
1946
1947 private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
John Spurlock8c520422013-09-19 12:23:35 -04001948 final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN;
John Spurlockc68d5772013-10-08 11:47:58 -04001949 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04001950 }
1951
John Spurlock42197262013-10-21 09:32:25 -04001952 private void finishBarAnimations() {
1953 mStatusBarView.getBarTransitions().finishAnimations();
1954 if (mNavigationBarView != null) {
1955 mNavigationBarView.getBarTransitions().finishAnimations();
1956 }
1957 }
1958
John Spurlockd4e65752013-08-28 14:17:09 -04001959 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04001960 @Override
1961 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04001962 checkBarModes();
John Spurlock5b9145b2013-08-20 15:13:47 -04001963 }};
1964
John Spurlockad3e6cb2013-04-30 08:47:43 -04001965 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04001966 public void setInteracting(int barWindow, boolean interacting) {
1967 mInteractingWindows = interacting
1968 ? (mInteractingWindows | barWindow)
1969 : (mInteractingWindows & ~barWindow);
1970 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04001971 suspendAutohide();
1972 } else {
1973 resumeSuspendedAutohide();
1974 }
1975 checkBarModes();
1976 }
1977
1978 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04001979 if (mAutohideSuspended) {
1980 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04001981 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04001982 }
1983 }
1984
John Spurlockd4e65752013-08-28 14:17:09 -04001985 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04001986 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04001987 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04001988 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04001989 }
1990
1991 private void cancelAutohide() {
1992 mAutohideSuspended = false;
1993 mHandler.removeCallbacks(mAutohide);
1994 }
1995
1996 private void scheduleAutohide() {
1997 cancelAutohide();
1998 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
1999 }
2000
John Spurlock9deaa282013-07-25 13:03:47 -04002001 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002002 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04002003 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
2004 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
2005 ) {
2006 userAutohide();
2007 }
2008 }
2009
2010 private void userAutohide() {
2011 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04002012 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04002013 }
2014
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002015 private boolean areLightsOn() {
2016 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
2017 }
Jim Millera073e572012-05-23 17:03:27 -07002018
Daniel Sandler60ee2562011-07-22 12:34:33 -04002019 public void setLightsOn(boolean on) {
2020 Log.v(TAG, "setLightsOn(" + on + ")");
2021 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002022 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002023 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002024 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002025 }
2026 }
2027
John Spurlock32beb2c2013-03-11 10:16:47 -04002028 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002029 try {
John Spurlock32beb2c2013-03-11 10:16:47 -04002030 mWindowManagerService.statusBarVisibilityChanged(vis);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002031 } catch (RemoteException ex) {
2032 }
Joe Onorato93056472010-09-10 10:30:46 -04002033 }
2034
Daniel Sandler5c8da942011-06-28 00:29:04 -04002035 public void topAppWindowChanged(boolean showMenu) {
2036 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002037 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04002038 }
2039 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04002040 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04002041 }
2042
2043 // See above re: lights-out policy for legacy apps.
2044 if (showMenu) setLightsOn(true);
2045 }
2046
Daniel Sandler328310c2011-09-23 15:56:52 -04002047 @Override
2048 public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
2049 boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
2050 || ((vis & InputMethodService.IME_VISIBLE) != 0);
2051
John Spurlock56d007b2013-10-28 18:40:56 -04002052 setNavigationIconHints(
John Spurlockd4e65752013-08-28 14:17:09 -04002053 altBack ? (mNavigationIconHints | NAVIGATION_HINT_BACK_ALT)
2054 : (mNavigationIconHints & ~NAVIGATION_HINT_BACK_ALT));
Daniel Sandler101784e2012-10-15 13:39:38 -04002055 if (mQS != null) mQS.setImeWindowStatus(vis > 0);
Daniel Sandler328310c2011-09-23 15:56:52 -04002056 }
2057
Jeff Brown2992ea72011-01-28 22:04:14 -08002058 @Override
Winson Chung43229d72012-09-12 18:04:18 -07002059 public void setHardKeyboardStatus(boolean available, boolean enabled) {}
Daniel Sandlere02d8082010-10-08 15:13:22 -04002060
Chris Wren0c8275b2012-05-08 13:36:48 -04002061 @Override
2062 protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002063 // no ticking in lights-out mode
2064 if (!areLightsOn()) return;
Jim Millera073e572012-05-23 17:03:27 -07002065
Daniel Sandler26cda272012-05-22 15:44:08 -04002066 // no ticking in Setup
2067 if (!isDeviceProvisioned()) return;
2068
John Spurlock61e36832012-09-10 09:43:27 -04002069 // not for you
2070 if (!notificationIsForCurrentUser(n)) return;
2071
Joe Onorato808182d2010-07-09 18:52:06 -04002072 // Show the ticker if one is requested. Also don't do this
2073 // until status bar window is attached to the window manager,
2074 // because... well, what's the point otherwise? And trying to
2075 // run a ticker without being attached will crash!
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -04002076 if (n.getNotification().tickerText != null && mStatusBarWindow.getWindowToken() != null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002077 if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
2078 | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
2079 mTicker.addEntry(n);
2080 }
2081 }
2082 }
2083
Joe Onorato808182d2010-07-09 18:52:06 -04002084 private class MyTicker extends Ticker {
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002085 MyTicker(Context context, View sb) {
Joe Onorato808182d2010-07-09 18:52:06 -04002086 super(context, sb);
2087 }
2088
2089 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002090 public void tickerStarting() {
Joe Onorato808182d2010-07-09 18:52:06 -04002091 mTicking = true;
Daniel Sandler173bae22012-09-25 14:37:42 -04002092 mStatusBarContents.setVisibility(View.GONE);
Joe Onorato808182d2010-07-09 18:52:06 -04002093 mTickerView.setVisibility(View.VISIBLE);
2094 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
Daniel Sandler173bae22012-09-25 14:37:42 -04002095 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
Joe Onorato808182d2010-07-09 18:52:06 -04002096 }
2097
2098 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002099 public void tickerDone() {
Daniel Sandler173bae22012-09-25 14:37:42 -04002100 mStatusBarContents.setVisibility(View.VISIBLE);
Joe Onorato808182d2010-07-09 18:52:06 -04002101 mTickerView.setVisibility(View.GONE);
Daniel Sandler173bae22012-09-25 14:37:42 -04002102 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
Joe Onorato808182d2010-07-09 18:52:06 -04002103 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
2104 mTickingDoneListener));
Joe Onorato808182d2010-07-09 18:52:06 -04002105 }
2106
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002107 public void tickerHalting() {
John Spurlock26a08ac2013-11-08 16:56:54 -05002108 if (mStatusBarContents.getVisibility() != View.VISIBLE) {
2109 mStatusBarContents.setVisibility(View.VISIBLE);
2110 mStatusBarContents
2111 .startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
2112 }
Joe Onorato808182d2010-07-09 18:52:06 -04002113 mTickerView.setVisibility(View.GONE);
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04002114 // we do not animate the ticker away at this point, just get rid of it (b/6992707)
Joe Onorato808182d2010-07-09 18:52:06 -04002115 }
2116 }
2117
2118 Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
2119 public void onAnimationEnd(Animation animation) {
2120 mTicking = false;
2121 }
2122 public void onAnimationRepeat(Animation animation) {
2123 }
2124 public void onAnimationStart(Animation animation) {
2125 }
2126 };
2127
2128 private Animation loadAnim(int id, Animation.AnimationListener listener) {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002129 Animation anim = AnimationUtils.loadAnimation(mContext, id);
Joe Onorato808182d2010-07-09 18:52:06 -04002130 if (listener != null) {
2131 anim.setAnimationListener(listener);
2132 }
2133 return anim;
2134 }
2135
Daniel Sandler48852952011-12-01 14:34:23 -05002136 public static String viewInfo(View v) {
2137 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
2138 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04002139 }
2140
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002141 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04002142 synchronized (mQueueLock) {
2143 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002144 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04002145 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04002146 pw.println(" mTicking=" + mTicking);
2147 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04002148 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002149 pw.println(" mPile: " + viewInfo(mPile));
Joe Onorato808182d2010-07-09 18:52:06 -04002150 pw.println(" mTickerView: " + viewInfo(mTickerView));
2151 pw.println(" mScrollView: " + viewInfo(mScrollView)
2152 + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04002153 }
Joe Onorato808182d2010-07-09 18:52:06 -04002154
John Spurlockcfc359a2013-09-05 10:42:03 -04002155 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04002156 pw.print(" mStatusBarWindowState=");
2157 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002158 pw.print(" mStatusBarMode=");
2159 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002160 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
2161 if (mNavigationBarView != null) {
2162 pw.print(" mNavigationBarWindowState=");
2163 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002164 pw.print(" mNavigationBarMode=");
2165 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002166 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
2167 }
2168
Daniel Sandler48852952011-12-01 14:34:23 -05002169 pw.print(" mNavigationBarView=");
2170 if (mNavigationBarView == null) {
2171 pw.println("null");
2172 } else {
2173 mNavigationBarView.dump(fd, pw, args);
2174 }
2175
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002176 pw.println(" Panels: ");
2177 if (mNotificationPanel != null) {
2178 pw.println(" mNotificationPanel=" +
2179 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
2180 pw.print (" ");
2181 mNotificationPanel.dump(fd, pw, args);
2182 }
2183 if (mSettingsPanel != null) {
2184 pw.println(" mSettingsPanel=" +
2185 mSettingsPanel + " params=" + mSettingsPanel.getLayoutParams().debug(""));
2186 pw.print (" ");
2187 mSettingsPanel.dump(fd, pw, args);
2188 }
2189
Daniel Sandler7579bca2011-08-18 15:47:26 -04002190 if (DUMPTRUCK) {
2191 synchronized (mNotificationData) {
2192 int N = mNotificationData.size();
2193 pw.println(" notification icons: " + N);
2194 for (int i=0; i<N; i++) {
2195 NotificationData.Entry e = mNotificationData.get(i);
2196 pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
2197 StatusBarNotification n = e.notification;
Daniel Sandler4f91efd2013-04-25 16:38:41 -04002198 pw.println(" pkg=" + n.getPackageName() + " id=" + n.getId() + " score=" + n.getScore());
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -04002199 pw.println(" notification=" + n.getNotification());
2200 pw.println(" tickerText=\"" + n.getNotification().tickerText + "\"");
Daniel Sandler7579bca2011-08-18 15:47:26 -04002201 }
2202 }
2203
2204 int N = mStatusIcons.getChildCount();
2205 pw.println(" system icons: " + N);
2206 for (int i=0; i<N; i++) {
2207 StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
2208 pw.println(" [" + i + "] icon=" + ic);
2209 }
Jim Miller5e6af442011-12-02 18:24:26 -08002210
Daniel Sandler89d97132011-09-08 15:31:57 -04002211 if (false) {
2212 pw.println("see the logcat for a dump of the views we have created.");
2213 // must happen on ui thread
2214 mHandler.post(new Runnable() {
2215 public void run() {
2216 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04002217 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04002218 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002219 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002220 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002221 }
2222 });
2223 }
Joe Onorato808182d2010-07-09 18:52:06 -04002224 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002225
Daniel Sandler151f00d2012-10-02 22:33:08 -04002226 if (DEBUG_GESTURES) {
2227 pw.print(" status bar gestures: ");
2228 mGestureRec.dump(fd, pw, args);
2229 }
Daniel Sandler33805342012-07-23 15:45:12 -04002230
Daniel Sandler89d97132011-09-08 15:31:57 -04002231 mNetworkController.dump(fd, pw, args);
Joe Onorato808182d2010-07-09 18:52:06 -04002232 }
2233
John Spurlock0ec64c62013-08-26 15:37:58 -04002234 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
2235 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
2236 pw.println(BarTransitions.modeToString(transitions.getMode()));
2237 }
2238
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002239 @Override
2240 public void createAndAddWindows() {
2241 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04002242 }
Jim Millere898ac52012-04-06 17:10:57 -07002243
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002244 private void addStatusBarWindow() {
2245 // Put up the view
2246 final int height = getStatusBarHeight();
Joe Onorato808182d2010-07-09 18:52:06 -04002247
Daniel Sandlera310af82012-04-24 01:20:13 -04002248 // Now that the status bar window encompasses the sliding panel and its
2249 // translucent backdrop, the entire thing is made TRANSLUCENT and is
2250 // hardware-accelerated.
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002251 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
2252 ViewGroup.LayoutParams.MATCH_PARENT,
2253 height,
2254 WindowManager.LayoutParams.TYPE_STATUS_BAR,
2255 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
2256 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
John Spurlock9deaa282013-07-25 13:03:47 -04002257 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
2258 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
Daniel Sandlera310af82012-04-24 01:20:13 -04002259 PixelFormat.TRANSLUCENT);
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002260
Romain Guy0901fda2012-05-22 21:10:57 -07002261 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002262
2263 lp.gravity = getStatusBarGravity();
2264 lp.setTitle("StatusBar");
2265 lp.packageName = mContext.getPackageName();
Jim Millere898ac52012-04-06 17:10:57 -07002266
Daniel Sandlera310af82012-04-24 01:20:13 -04002267 makeStatusBarView();
Jeff Brown98365d72012-08-19 20:30:52 -07002268 mWindowManager.addView(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04002269 }
2270
Joe Onorato808182d2010-07-09 18:52:06 -04002271 void setNotificationIconVisibility(boolean visible, int anim) {
2272 int old = mNotificationIcons.getVisibility();
2273 int v = visible ? View.VISIBLE : View.INVISIBLE;
2274 if (old != v) {
2275 mNotificationIcons.setVisibility(v);
2276 mNotificationIcons.startAnimation(loadAnim(anim, null));
2277 }
2278 }
2279
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002280 void updateExpandedInvisiblePosition() {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002281 mTrackingPosition = -mDisplayMetrics.heightPixels;
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002282 }
2283
Daniel Sandler1fac1fd2012-04-30 12:07:30 -04002284 static final float saturate(float a) {
2285 return a < 0f ? 0f : (a > 1f ? 1f : a);
2286 }
2287
Chris Wren8fd12652012-05-09 21:25:57 -04002288 @Override
2289 protected int getExpandedViewMaxHeight() {
Daniel Sandler21b274e2012-05-02 15:07:51 -04002290 return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx;
2291 }
2292
Chris Wren0c8275b2012-05-08 13:36:48 -04002293 @Override
Daniel Sandler08d05e32012-08-08 16:39:54 -04002294 public void updateExpandedViewPos(int thingy) {
Chris Wren6d15a362013-08-20 18:46:29 -04002295 if (SPEW) Log.v(TAG, "updateExpandedViewPos");
Daniel Sandlere680f542012-09-28 12:22:27 -04002296
2297 // on larger devices, the notification panel is propped open a bit
2298 mNotificationPanel.setMinimumHeight(
2299 (int)(mNotificationPanelMinHeightFrac * mCurrentDisplaySize.y));
2300
Daniel Sandler21b274e2012-05-02 15:07:51 -04002301 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams();
Daniel Sandler21b274e2012-05-02 15:07:51 -04002302 lp.gravity = mNotificationPanelGravity;
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002303 lp.setMarginStart(mNotificationPanelMarginPx);
Daniel Sandler21b274e2012-05-02 15:07:51 -04002304 mNotificationPanel.setLayoutParams(lp);
Daniel Sandlere680f542012-09-28 12:22:27 -04002305
Daniel Sandlere111ad32012-10-13 15:17:45 -04002306 if (mSettingsPanel != null) {
2307 lp = (FrameLayout.LayoutParams) mSettingsPanel.getLayoutParams();
2308 lp.gravity = mSettingsPanelGravity;
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002309 lp.setMarginEnd(mNotificationPanelMarginPx);
Daniel Sandlere111ad32012-10-13 15:17:45 -04002310 mSettingsPanel.setLayoutParams(lp);
2311 }
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002312
Chris Wren0f2aa682013-08-02 12:03:02 -04002313 if (ENABLE_HEADS_UP && mHeadsUpNotificationView != null) {
2314 mHeadsUpNotificationView.setMargin(mNotificationPanelMarginPx);
Chris Wren9afc50d2013-07-30 11:31:46 -04002315 mPile.getLocationOnScreen(mPilePosition);
2316 mHeadsUpVerticalOffset = mPilePosition[1] - mNaturalBarHeight;
Chris Wren0f2aa682013-08-02 12:03:02 -04002317 }
2318
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002319 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002320 }
2321
Daniel Sandler747a9e92012-08-10 16:39:19 -04002322 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002323 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04002324 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002325 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04002326 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04002327 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04002328 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2329 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002330 }
2331
Joe Onorato808182d2010-07-09 18:52:06 -04002332 private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
2333 public void onClick(View v) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002334 synchronized (mNotificationData) {
Chet Haase2f2022a2011-10-11 06:41:59 -07002335 // animate-swipe all dismissable notifications, then animate the shade closed
2336 int numChildren = mPile.getChildCount();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002337
Chet Haase2f2022a2011-10-11 06:41:59 -07002338 int scrollTop = mScrollView.getScrollY();
2339 int scrollBottom = scrollTop + mScrollView.getHeight();
2340 final ArrayList<View> snapshot = new ArrayList<View>(numChildren);
2341 for (int i=0; i<numChildren; i++) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002342 final View child = mPile.getChildAt(i);
Chet Haase2f2022a2011-10-11 06:41:59 -07002343 if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop &&
2344 child.getTop() < scrollBottom) {
2345 snapshot.add(child);
2346 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002347 }
Craig Mautner93a035c2012-04-09 15:23:59 -07002348 if (snapshot.isEmpty()) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002349 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Craig Mautner93a035c2012-04-09 15:23:59 -07002350 return;
2351 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002352 new Thread(new Runnable() {
2353 @Override
2354 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07002355 // Decrease the delay for every row we animate to give the sense of
2356 // accelerating the swipes
2357 final int ROW_DELAY_DECREMENT = 10;
2358 int currentDelay = 140;
2359 int totalDelay = 0;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002360
Chet Haase2f2022a2011-10-11 06:41:59 -07002361 // Set the shade-animating state to avoid doing other work during
2362 // all of these animations. In particular, avoid layout and
2363 // redrawing when collapsing the shade.
2364 mPile.setViewRemoval(false);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002365
Chet Haase2f2022a2011-10-11 06:41:59 -07002366 mPostCollapseCleanup = new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07002367 @Override
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002368 public void run() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002369 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002370 Log.v(TAG, "running post-collapse cleanup");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002371 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002372 try {
Chet Haase2f2022a2011-10-11 06:41:59 -07002373 mPile.setViewRemoval(true);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002374 mBarService.onClearAllNotifications();
Chet Haase2f2022a2011-10-11 06:41:59 -07002375 } catch (Exception ex) { }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002376 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002377 };
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002378
Chet Haase2f2022a2011-10-11 06:41:59 -07002379 View sampleView = snapshot.get(0);
2380 int width = sampleView.getWidth();
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002381 final int dir = sampleView.isLayoutRtl() ? -1 : +1;
2382 final int velocity = dir * width * 8; // 1000/8 = 125 ms duration
Craig Mautner93a035c2012-04-09 15:23:59 -07002383 for (final View _v : snapshot) {
Chet Haase2f2022a2011-10-11 06:41:59 -07002384 mHandler.postDelayed(new Runnable() {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002385 @Override
2386 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07002387 mPile.dismissRowAnimated(_v, velocity);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002388 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002389 }, totalDelay);
2390 currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT);
2391 totalDelay += currentDelay;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002392 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002393 // Delay the collapse animation until after all swipe animations have
2394 // finished. Provide some buffer because there may be some extra delay
2395 // before actually starting each swipe animation. Ideally, we'd
2396 // synchronize the end of those animations with the start of the collaps
2397 // exactly.
2398 mHandler.postDelayed(new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07002399 @Override
Chet Haase2f2022a2011-10-11 06:41:59 -07002400 public void run() {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002401 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Chet Haase2f2022a2011-10-11 06:41:59 -07002402 }
2403 }, totalDelay + 225);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002404 }
2405 }).start();
Joe Onorato808182d2010-07-09 18:52:06 -04002406 }
Joe Onorato808182d2010-07-09 18:52:06 -04002407 }
2408 };
2409
Daniel Sandler3679bf52012-10-16 21:30:28 -04002410 public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
2411 if (onlyProvisioned && !isDeviceProvisioned()) return;
2412 try {
2413 // Dismiss the lock screen when Settings starts.
2414 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
2415 } catch (RemoteException e) {
2416 }
2417 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2418 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
2419 animateCollapsePanels();
2420 }
2421
Daniel Sandlerd3090562011-08-09 00:28:44 -04002422 private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
2423 public void onClick(View v) {
Daniel Sandlere111ad32012-10-13 15:17:45 -04002424 if (mHasSettingsPanel) {
2425 animateExpandSettingsPanel();
2426 } else {
Daniel Sandler3679bf52012-10-16 21:30:28 -04002427 startActivityDismissingKeyguard(
2428 new Intent(android.provider.Settings.ACTION_SETTINGS), true);
Daniel Sandlere111ad32012-10-13 15:17:45 -04002429 }
Daniel Sandlerd3090562011-08-09 00:28:44 -04002430 }
2431 };
2432
Daniel Sandler3679bf52012-10-16 21:30:28 -04002433 private View.OnClickListener mClockClickListener = new View.OnClickListener() {
2434 public void onClick(View v) {
2435 startActivityDismissingKeyguard(
2436 new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone
2437 }
2438 };
2439
Daniel Sandler101784e2012-10-15 13:39:38 -04002440 private View.OnClickListener mNotificationButtonListener = new View.OnClickListener() {
2441 public void onClick(View v) {
2442 animateExpandNotificationsPanel();
2443 }
2444 };
2445
Joe Onorato808182d2010-07-09 18:52:06 -04002446 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2447 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04002448 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04002449 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04002450 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Jim Miller9a720f52012-05-30 03:19:43 -07002451 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002452 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Daniel Sandleredbdd3a2011-06-21 12:57:08 -04002453 String reason = intent.getStringExtra("reason");
Jim Miller9a720f52012-05-30 03:19:43 -07002454 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
2455 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002456 }
2457 }
Daniel Sandler11cf1782012-09-27 14:03:08 -04002458 animateCollapsePanels(flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002459 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002460 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002461 mScreenOn = false;
Daniel Sandlered930e52012-07-03 14:31:22 -04002462 // no waiting!
Daniel Sandler08d05e32012-08-08 16:39:54 -04002463 makeExpandedInvisible();
John Spurlock1bbd49d2012-10-19 11:09:32 -04002464 notifyNavigationBarScreenOn(false);
Chris Wrene97f90b2013-08-07 17:39:35 -04002465 notifyHeadsUpScreenOn(false);
John Spurlock42197262013-10-21 09:32:25 -04002466 finishBarAnimations();
Daniel Sandlered930e52012-07-03 14:31:22 -04002467 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002468 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002469 mScreenOn = true;
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002470 // work around problem where mDisplay.getRotation() is not stable while screen is off (bug 7086018)
2471 repositionNavigationBar();
John Spurlock1bbd49d2012-10-19 11:09:32 -04002472 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002473 }
John Spurlock3c875662013-08-31 15:07:25 -04002474 else if (ACTION_DEMO.equals(action)) {
2475 Bundle bundle = intent.getExtras();
2476 if (bundle != null) {
2477 String command = bundle.getString("command", "").trim().toLowerCase();
2478 if (command.length() > 0) {
2479 try {
2480 dispatchDemoCommand(command, bundle);
2481 } catch (Throwable t) {
2482 Log.w(TAG, "Error running demo command, intent=" + intent, t);
2483 }
2484 }
2485 }
2486 }
Joe Onorato808182d2010-07-09 18:52:06 -04002487 }
2488 };
2489
Daniel Sandler777dcde2013-09-30 10:21:45 -04002490 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
2491 @Override
2492 protected void onConfigurationChanged(Configuration newConfig) {
2493 super.onConfigurationChanged(newConfig); // calls refreshLayout
2494
2495 if (DEBUG) {
2496 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
2497 }
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002498 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04002499
2500 updateResources();
2501 repositionNavigationBar();
2502 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
2503 updateShowSearchHoldoff();
2504 }
2505
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002506 @Override
2507 public void userSwitched(int newUserId) {
2508 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002509 animateCollapsePanels();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002510 updateNotificationIcons();
John Spurlock919adac2012-10-02 16:41:12 -04002511 resetUserSetupObserver();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002512 }
John Spurlock919adac2012-10-02 16:41:12 -04002513
2514 private void resetUserSetupObserver() {
2515 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
2516 mUserSetupObserver.onChange(false);
2517 mContext.getContentResolver().registerContentObserver(
2518 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
2519 mUserSetupObserver,
2520 mCurrentUserId);
2521 }
2522
Chris Wren157026f2013-06-28 16:54:01 -04002523 private void setHeadsUpVisibility(boolean vis) {
2524 if (!ENABLE_HEADS_UP) return;
2525 if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
2526 mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
Chris Wrene03f4e12013-08-08 16:48:48 -04002527 if (!vis) {
2528 if (DEBUG) Log.d(TAG, "setting heads up entry to null");
2529 mInterruptingNotificationEntry = null;
2530 }
Joe Onorato808182d2010-07-09 18:52:06 -04002531 }
2532
Chris Wren9afc50d2013-07-30 11:31:46 -04002533 public void animateHeadsUp(boolean animateInto, float frac) {
2534 if (!ENABLE_HEADS_UP || mHeadsUpNotificationView == null) return;
2535 frac = frac / 0.4f;
2536 frac = frac < 1.0f ? frac : 1.0f;
2537 float alpha = 1.0f - frac;
2538 float offset = mHeadsUpVerticalOffset * frac;
2539 offset = animateInto ? offset : 0f;
2540 mHeadsUpNotificationView.setAlpha(alpha);
2541 mHeadsUpNotificationView.setY(offset);
2542 }
2543
Chris Wren51c75102013-07-16 20:49:17 -04002544 public void onHeadsUpDismissed() {
2545 if (mInterruptingNotificationEntry == null) return;
Chris Wren6d15a362013-08-20 18:46:29 -04002546 mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
2547 if (mHeadsUpNotificationView.isClearable()) {
2548 try {
2549 mBarService.onNotificationClear(
2550 mInterruptingNotificationEntry.notification.getPackageName(),
2551 mInterruptingNotificationEntry.notification.getTag(),
2552 mInterruptingNotificationEntry.notification.getId());
2553 } catch (android.os.RemoteException ex) {
2554 // oh well
2555 }
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04002556 }
2557 }
Jim Millere898ac52012-04-06 17:10:57 -07002558
Joe Onorato808182d2010-07-09 18:52:06 -04002559 /**
2560 * Reload some of our resources when the configuration changes.
2561 *
2562 * We don't reload everything when the configuration changes -- we probably
2563 * should, but getting that smooth is tough. Someday we'll fix that. In the
2564 * meantime, just update the things that we know change.
2565 */
2566 void updateResources() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002567 final Context context = mContext;
2568 final Resources res = context.getResources();
Joe Onorato808182d2010-07-09 18:52:06 -04002569
Daniel Sandler1347c302011-08-01 16:47:53 -04002570 if (mClearButton instanceof TextView) {
2571 ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
2572 }
Winson Chungd63c59782012-09-05 17:34:41 -07002573
2574 // Update the QuickSettings container
Daniel Sandler101784e2012-10-15 13:39:38 -04002575 if (mQS != null) mQS.updateResources();
Winson Chungd63c59782012-09-05 17:34:41 -07002576
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002577 loadDimens();
2578 }
Jim Miller5e6af442011-12-02 18:24:26 -08002579
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002580 protected void loadDimens() {
2581 final Resources res = mContext.getResources();
2582
2583 mNaturalBarHeight = res.getDimensionPixelSize(
2584 com.android.internal.R.dimen.status_bar_height);
2585
2586 int newIconSize = res.getDimensionPixelSize(
2587 com.android.internal.R.dimen.status_bar_icon_size);
2588 int newIconHPadding = res.getDimensionPixelSize(
2589 R.dimen.status_bar_icon_padding);
2590
2591 if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
John Spurlockcd686b52013-06-05 10:13:46 -04002592// Log.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002593 mIconHPadding = newIconHPadding;
2594 mIconSize = newIconSize;
2595 //reloadAllNotificationIcons(); // reload the tray
2596 }
2597
Joe Onorato808182d2010-07-09 18:52:06 -04002598 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
2599
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002600 mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
2601 mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
2602 mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
2603 mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
2604
2605 mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
2606 mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
2607
2608 mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
2609 mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
2610
2611 mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
Jim Millera073e572012-05-23 17:03:27 -07002612
Daniel Sandlere5011a32012-06-11 16:07:52 -04002613 mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity);
2614
Daniel Sandler21b274e2012-05-02 15:07:51 -04002615 mNotificationPanelMarginBottomPx
2616 = (int) res.getDimension(R.dimen.notification_panel_margin_bottom);
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002617 mNotificationPanelMarginPx
Daniel Sandler21b274e2012-05-02 15:07:51 -04002618 = (int) res.getDimension(R.dimen.notification_panel_margin_left);
2619 mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
2620 if (mNotificationPanelGravity <= 0) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002621 mNotificationPanelGravity = Gravity.START | Gravity.TOP;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002622 }
2623 mSettingsPanelGravity = res.getInteger(R.integer.settings_panel_layout_gravity);
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002624 Log.d(TAG, "mSettingsPanelGravity = " + mSettingsPanelGravity);
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002625 if (mSettingsPanelGravity <= 0) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002626 mSettingsPanelGravity = Gravity.END | Gravity.TOP;
Daniel Sandler21b274e2012-05-02 15:07:51 -04002627 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04002628
2629 mCarrierLabelHeight = res.getDimensionPixelSize(R.dimen.carrier_label_height);
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002630 mNotificationHeaderHeight = res.getDimensionPixelSize(R.dimen.notification_panel_header_height);
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002631
Daniel Sandlere680f542012-09-28 12:22:27 -04002632 mNotificationPanelMinHeightFrac = res.getFraction(R.dimen.notification_panel_min_height_frac, 1, 1);
2633 if (mNotificationPanelMinHeightFrac < 0f || mNotificationPanelMinHeightFrac > 1f) {
2634 mNotificationPanelMinHeightFrac = 0f;
John Spurlock804df702012-06-01 15:34:27 -04002635 }
Daniel Sandlere680f542012-09-28 12:22:27 -04002636
Chris Wren51c75102013-07-16 20:49:17 -04002637 mHeadsUpNotificationDecay = res.getInteger(R.integer.heads_up_notification_decay);
2638 mRowHeight = res.getDimensionPixelSize(R.dimen.notification_row_min_height);
2639
John Spurlockcd686b52013-06-05 10:13:46 -04002640 if (false) Log.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04002641 }
2642
Joe Onorato808182d2010-07-09 18:52:06 -04002643 //
2644 // tracing
2645 //
2646
2647 void postStartTracing() {
2648 mHandler.postDelayed(mStartTracing, 3000);
2649 }
2650
2651 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002652 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
2653 Context.VIBRATOR_SERVICE);
Joe Onorato808182d2010-07-09 18:52:06 -04002654 vib.vibrate(250);
2655 }
2656
2657 Runnable mStartTracing = new Runnable() {
2658 public void run() {
2659 vibrate();
2660 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04002661 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002662 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2663 mHandler.postDelayed(mStopTracing, 10000);
2664 }
2665 };
2666
2667 Runnable mStopTracing = new Runnable() {
2668 public void run() {
2669 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04002670 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002671 vibrate();
2672 }
2673 };
Chris Wren0c8275b2012-05-08 13:36:48 -04002674
2675 @Override
2676 protected void haltTicker() {
2677 mTicker.halt();
2678 }
Jim Miller670d9dd2012-05-12 13:28:26 -07002679
2680 @Override
Jim Millerb4238e02012-05-14 15:26:20 -07002681 protected boolean shouldDisableNavbarGestures() {
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002682 return !isDeviceProvisioned()
2683 || mExpandedVisible
2684 || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07002685 }
Joe Onorato808182d2010-07-09 18:52:06 -04002686
Romain Guy648342f2012-05-25 10:44:45 -07002687 private static class FastColorDrawable extends Drawable {
2688 private final int mColor;
2689
2690 public FastColorDrawable(int color) {
2691 mColor = 0xff000000 | color;
2692 }
2693
2694 @Override
2695 public void draw(Canvas canvas) {
2696 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
2697 }
2698
2699 @Override
2700 public void setAlpha(int alpha) {
2701 }
2702
2703 @Override
2704 public void setColorFilter(ColorFilter cf) {
2705 }
2706
2707 @Override
2708 public int getOpacity() {
2709 return PixelFormat.OPAQUE;
2710 }
2711
2712 @Override
2713 public void setBounds(int left, int top, int right, int bottom) {
2714 }
2715
2716 @Override
2717 public void setBounds(Rect bounds) {
2718 }
2719 }
John Spurlock5c454122013-06-17 07:35:46 -04002720
2721 @Override
2722 public void destroy() {
2723 super.destroy();
2724 if (mStatusBarWindow != null) {
2725 mWindowManager.removeViewImmediate(mStatusBarWindow);
2726 }
2727 if (mNavigationBarView != null) {
2728 mWindowManager.removeViewImmediate(mNavigationBarView);
2729 }
2730 mContext.unregisterReceiver(mBroadcastReceiver);
2731 }
John Spurlock3c875662013-08-31 15:07:25 -04002732
2733 private boolean mDemoModeAllowed;
2734 private boolean mDemoMode;
2735 private DemoStatusIcons mDemoStatusIcons;
2736
2737 @Override
2738 public void dispatchDemoCommand(String command, Bundle args) {
2739 if (!mDemoModeAllowed) {
2740 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
2741 "sysui_demo_allowed", 0) != 0;
2742 }
2743 if (!mDemoModeAllowed) return;
2744 if (command.equals(COMMAND_ENTER)) {
2745 mDemoMode = true;
2746 } else if (command.equals(COMMAND_EXIT)) {
2747 mDemoMode = false;
2748 checkBarModes();
2749 } else if (!mDemoMode) {
2750 // automatically enter demo mode on first demo command
2751 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
2752 }
2753 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
2754 if (modeChange || command.equals(COMMAND_CLOCK)) {
2755 dispatchDemoCommandToView(command, args, R.id.clock);
2756 }
2757 if (modeChange || command.equals(COMMAND_BATTERY)) {
2758 dispatchDemoCommandToView(command, args, R.id.battery);
2759 }
2760 if (modeChange || command.equals(COMMAND_STATUS)) {
2761 if (mDemoStatusIcons == null) {
2762 mDemoStatusIcons = new DemoStatusIcons(mStatusIcons, mIconSize);
2763 }
2764 mDemoStatusIcons.dispatchDemoCommand(command, args);
2765 }
2766 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
2767 mNetworkController.dispatchDemoCommand(command, args);
2768 }
2769 if (command.equals(COMMAND_BARS)) {
2770 String mode = args.getString("mode");
2771 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04002772 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04002773 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
2774 -1;
2775 if (barMode != -1) {
2776 boolean animate = true;
2777 if (mStatusBarView != null) {
2778 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
2779 }
2780 if (mNavigationBarView != null) {
2781 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
2782 }
2783 }
2784 }
2785 }
2786
2787 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
2788 if (mStatusBarView == null) return;
2789 View v = mStatusBarView.findViewById(id);
2790 if (v instanceof DemoMode) {
2791 ((DemoMode)v).dispatchDemoCommand(command, args);
2792 }
2793 }
Romain Guy648342f2012-05-25 10:44:45 -07002794}