blob: 1c4dff8458e203f59c7d01a914179defa3b595f4 [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
Daniel Sandlerd7e96862012-04-26 01:10:29 -040019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
21import android.animation.AnimatorSet;
Daniel Sandler0761e4c2011-08-11 00:19:49 -040022import android.animation.ObjectAnimator;
Daniel Sandler101784e2012-10-15 13:39:38 -040023import android.animation.TimeInterpolator;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070024import android.app.ActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040025import android.app.ActivityManagerNative;
Joe Onorato808182d2010-07-09 18:52:06 -040026import android.app.Notification;
27import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040028import android.app.StatusBarManager;
29import android.content.BroadcastReceiver;
30import android.content.Context;
31import android.content.Intent;
32import android.content.IntentFilter;
Daniel Sandlerb17a7262012-10-05 14:32:50 -040033import android.content.SharedPreferences;
Michael Jurka7f2668c2012-03-27 07:49:52 -070034import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040035import android.database.ContentObserver;
Romain Guy648342f2012-05-25 10:44:45 -070036import android.graphics.Canvas;
37import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040038import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040039import android.graphics.Point;
Romain Guy648342f2012-05-25 10:44:45 -070040import android.graphics.PorterDuff;
Joe Onorato808182d2010-07-09 18:52:06 -040041import android.graphics.Rect;
Romain Guy648342f2012-05-25 10:44:45 -070042import android.graphics.drawable.Drawable;
John Spurlock804df702012-06-01 15:34:27 -040043import android.graphics.drawable.NinePatchDrawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070044import android.inputmethodservice.InputMethodService;
John Spurlock919adac2012-10-02 16:41:12 -040045import android.os.Handler;
Joe Onorato808182d2010-07-09 18:52:06 -040046import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040047import android.os.Message;
Michael Jurka7f2668c2012-03-27 07:49:52 -070048import android.os.RemoteException;
Daniel Sandler1d4d30a2011-04-28 12:35:29 -040049import android.os.ServiceManager;
Joe Onorato808182d2010-07-09 18:52:06 -040050import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070051import android.os.UserHandle;
Daniel Sandlerd3090562011-08-09 00:28:44 -040052import android.provider.Settings;
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -070053import android.service.dreams.DreamService;
Daniel Sandlera2fbe532012-08-10 01:19:03 -040054import android.service.dreams.IDreamManager;
Daniel Sandler36412a72011-08-04 09:35:13 -040055import android.util.DisplayMetrics;
Joe Onorato808182d2010-07-09 18:52:06 -040056import android.util.Log;
Michael Jurka7f2668c2012-03-27 07:49:52 -070057import android.util.Slog;
Joe Onorato808182d2010-07-09 18:52:06 -040058import android.view.Display;
59import android.view.Gravity;
Joe Onorato808182d2010-07-09 18:52:06 -040060import android.view.MotionEvent;
61import android.view.VelocityTracker;
62import android.view.View;
63import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -070064import android.view.ViewGroup.LayoutParams;
Daniel Sandler101784e2012-10-15 13:39:38 -040065import android.view.ViewPropertyAnimator;
Daniel Sandlerb17a7262012-10-05 14:32:50 -040066import android.view.ViewStub;
Joe Onorato808182d2010-07-09 18:52:06 -040067import android.view.WindowManager;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040068import android.view.animation.AccelerateInterpolator;
Joe Onorato808182d2010-07-09 18:52:06 -040069import android.view.animation.Animation;
70import android.view.animation.AnimationUtils;
Daniel Sandler67e7d902012-06-06 16:32:21 -040071import android.view.animation.DecelerateInterpolator;
Daniel Sandler21b274e2012-05-02 15:07:51 -040072import android.widget.FrameLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040073import android.widget.ImageView;
74import android.widget.LinearLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040075import android.widget.ScrollView;
76import android.widget.TextView;
Michael Jurkaa600fd92012-06-25 15:57:05 -070077
Joe Onorato808182d2010-07-09 18:52:06 -040078import com.android.internal.statusbar.StatusBarIcon;
Joe Onorato808182d2010-07-09 18:52:06 -040079import com.android.internal.statusbar.StatusBarNotification;
Joe Onorato808182d2010-07-09 18:52:06 -040080import com.android.systemui.R;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -050081import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -070082import com.android.systemui.statusbar.CommandQueue;
Daniel Sandler33805342012-07-23 15:45:12 -040083import com.android.systemui.statusbar.GestureRecorder;
Michael Jurka7f2668c2012-03-27 07:49:52 -070084import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -040085import com.android.systemui.statusbar.NotificationData.Entry;
Christian Robertson2e347422011-08-11 14:01:04 -070086import com.android.systemui.statusbar.SignalClusterView;
Michael Jurka7f2668c2012-03-27 07:49:52 -070087import com.android.systemui.statusbar.StatusBarIconView;
Daniel Sandler2b697352011-07-22 16:23:09 -040088import com.android.systemui.statusbar.policy.BatteryController;
Winson Chungd63c59782012-09-05 17:34:41 -070089import com.android.systemui.statusbar.policy.BluetoothController;
Michael Jurka7f2668c2012-03-27 07:49:52 -070090import com.android.systemui.statusbar.policy.DateView;
Daniel Sandler6a858c32012-03-12 14:38:58 -040091import com.android.systemui.statusbar.policy.IntruderAlertView;
Daniel Sandler2b697352011-07-22 16:23:09 -040092import com.android.systemui.statusbar.policy.LocationController;
93import com.android.systemui.statusbar.policy.NetworkController;
Daniel Sandler8ba33c92011-10-04 21:49:30 -040094import com.android.systemui.statusbar.policy.NotificationRowLayout;
Michael Jurkaa600fd92012-06-25 15:57:05 -070095import com.android.systemui.statusbar.policy.OnSizeChangedListener;
Daniel Sandlerb17a7262012-10-05 14:32:50 -040096import com.android.systemui.statusbar.policy.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -040097
Daniel Sandler6a858c32012-03-12 14:38:58 -040098import java.io.FileDescriptor;
99import java.io.PrintWriter;
100import java.util.ArrayList;
101
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500102public class PhoneStatusBar extends BaseStatusBar {
Joe Onoratofd52b182010-11-10 18:00:52 -0800103 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400104 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Daniel Sandlerc1ebee42012-03-26 19:39:46 -0400105 public static final boolean SPEW = DEBUG;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400106 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandler151f00d2012-10-02 22:33:08 -0400107 public static final boolean DEBUG_GESTURES = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400108
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400109 public static final boolean DEBUG_CLINGS = false;
110
Daniel Sandlerace0bd72012-10-11 09:56:45 -0700111 public static final boolean ENABLE_NOTIFICATION_PANEL_CLING = false;
112
Daniel Sandler040c2e42012-10-17 00:56:33 -0400113 public static final boolean SETTINGS_DRAG_SHORTCUT = true;
114
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400115 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400116 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400117
Joe Onorato808182d2010-07-09 18:52:06 -0400118 public static final String ACTION_STATUSBAR_START
119 = "com.android.internal.policy.statusbar.START";
120
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400121 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400122 private static final int MSG_CLOSE_PANELS = 1001;
123 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700124 // 1020-1030 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400125
126 // will likely move to a resource or other tunable param at some point
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400127 private static final int INTRUDER_ALERT_DECAY_MS = 0; // disabled, was 10000;
Joe Onorato808182d2010-07-09 18:52:06 -0400128
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400129 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
130
Daniel Sandler58b173b2012-05-03 11:25:29 -0400131 private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
132 private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
133
Daniel Sandlerdc940ea2011-08-25 14:35:53 -0700134 // fling gesture tuning parameters, scaled to display density
135 private float mSelfExpandVelocityPx; // classic value: 2000px/s
136 private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
137 private float mFlingExpandMinVelocityPx; // classic value: 200px/s
138 private float mFlingCollapseMinVelocityPx; // classic value: 200px/s
139 private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1)
140 private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
141 private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s
142
143 private float mExpandAccelPx; // classic value: 2000px/s/s
144 private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
145
Daniel Sandlere5011a32012-06-11 16:07:52 -0400146 private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little
147 // faster than mSelfCollapseVelocityPx)
148
Joe Onoratofd52b182010-11-10 18:00:52 -0800149 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400150
Daniel Sandler2b697352011-07-22 16:23:09 -0400151 // These are no longer handled by the policy, because we need custom strategies for them
Winson Chungd63c59782012-09-05 17:34:41 -0700152 BluetoothController mBluetoothController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400153 BatteryController mBatteryController;
154 LocationController mLocationController;
155 NetworkController mNetworkController;
Jim Miller5e6af442011-12-02 18:24:26 -0800156
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400157 int mNaturalBarHeight = -1;
158 int mIconSize = -1;
159 int mIconHPadding = -1;
Joe Onorato808182d2010-07-09 18:52:06 -0400160 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400161 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400162
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400163 IDreamManager mDreamManager;
Daniel Sandler1d4d30a2011-04-28 12:35:29 -0400164
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400165 StatusBarWindowView mStatusBarWindow;
Joe Onoratofd52b182010-11-10 18:00:52 -0800166 PhoneStatusBarView mStatusBarView;
Daniel Sandlera310af82012-04-24 01:20:13 -0400167
Joe Onorato808182d2010-07-09 18:52:06 -0400168 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400169 Object mQueueLock = new Object();
170
Daniel Sandler173bae22012-09-25 14:37:42 -0400171 // viewgroup containing the normal contents of the statusbar
172 LinearLayout mStatusBarContents;
173
174 // right-hand icons
175 LinearLayout mSystemIconArea;
176
177 // left-hand icons
Joe Onorato808182d2010-07-09 18:52:06 -0400178 LinearLayout mStatusIcons;
Daniel Sandler173bae22012-09-25 14:37:42 -0400179 // the icons themselves
180 IconMerger mNotificationIcons;
181 // [+>
182 View mMoreIcon;
Joe Onorato808182d2010-07-09 18:52:06 -0400183
184 // expanded notifications
Daniel Sandler040c2e42012-10-17 00:56:33 -0400185 NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400186 ScrollView mScrollView;
Joe Onorato808182d2010-07-09 18:52:06 -0400187 View mExpandedContents;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400188 int mNotificationPanelGravity;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400189 int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx;
Daniel Sandlere680f542012-09-28 12:22:27 -0400190 float mNotificationPanelMinHeightFrac;
Daniel Sandler66d92f82012-06-13 13:36:52 -0400191 boolean mNotificationPanelIsFullScreenWidth;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400192 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400193
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400194 // settings
Daniel Sandler101784e2012-10-15 13:39:38 -0400195 QuickSettings mQS;
196 boolean mHasSettingsPanel, mHasFlipSettings;
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400197 SettingsPanelView mSettingsPanel;
Daniel Sandler101784e2012-10-15 13:39:38 -0400198 View mFlipSettingsView;
199 QuickSettingsContainerView mSettingsContainer;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400200 int mSettingsPanelGravity;
201
Joe Onorato808182d2010-07-09 18:52:06 -0400202 // top bar
Daniel Sandler3679bf52012-10-16 21:30:28 -0400203 View mNotificationPanelHeader;
204 View mDateTimeView;
Daniel Sandler1347c302011-08-01 16:47:53 -0400205 View mClearButton;
Daniel Sandler101784e2012-10-15 13:39:38 -0400206 ImageView mSettingsButton, mNotificationButton;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400207
Daniel Sandler3d32a242012-06-05 13:44:14 -0400208 // carrier/wifi label
209 private TextView mCarrierLabel;
210 private boolean mCarrierLabelVisible = false;
211 private int mCarrierLabelHeight;
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400212 private TextView mEmergencyCallLabel;
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400213 private int mNotificationHeaderHeight;
214
215 private boolean mShowCarrierInPanel = false;
Daniel Sandler3d32a242012-06-05 13:44:14 -0400216
Joe Onorato808182d2010-07-09 18:52:06 -0400217 // position
218 int[] mPositionTmp = new int[2];
Joe Onorato808182d2010-07-09 18:52:06 -0400219 boolean mExpandedVisible;
220
221 // the date view
222 DateView mDateView;
223
224 // for immersive activities
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400225 private IntruderAlertView mIntruderAlertView;
Joe Onorato808182d2010-07-09 18:52:06 -0400226
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400227 // on-screen navigation buttons
Daniel Sandler0129b312011-05-11 11:54:11 -0400228 private NavigationBarView mNavigationBarView = null;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400229
Joe Onorato808182d2010-07-09 18:52:06 -0400230 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400231 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400232
233 // ticker
234 private Ticker mTicker;
235 private View mTickerView;
236 private boolean mTicking;
237
238 // Tracking finger for opening/closing.
239 int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
240 boolean mTracking;
241 VelocityTracker mVelocityTracker;
242
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400243 // help screen
244 private boolean mClingShown;
245 private ViewGroup mCling;
246 private boolean mSuppressStatusBarDrags; // while a cling is up, briefly deaden the bar to give things time to settle
247
Joe Onorato808182d2010-07-09 18:52:06 -0400248 boolean mAnimating;
Daniel Sandlerfbab8ae2012-05-09 02:06:29 -0400249 boolean mClosing; // only valid when mAnimating; indicates the initial acceleration
Joe Onorato808182d2010-07-09 18:52:06 -0400250 float mAnimY;
251 float mAnimVel;
252 float mAnimAccel;
Jeff Browned5f45a2012-05-03 15:53:47 -0700253 long mAnimLastTimeNanos;
Joe Onorato808182d2010-07-09 18:52:06 -0400254 boolean mAnimatingReveal = false;
255 int mViewDelta;
John Spurlock804df702012-06-01 15:34:27 -0400256 float mFlingVelocity;
257 int mFlingY;
Joe Onorato808182d2010-07-09 18:52:06 -0400258 int[] mAbsPos = new int[2];
Chet Haase2f2022a2011-10-11 06:41:59 -0700259 Runnable mPostCollapseCleanup = null;
260
Daniel Sandler173bae22012-09-25 14:37:42 -0400261 private Animator mLightsOutAnimation;
262 private Animator mLightsOnAnimation;
Joe Onorato808182d2010-07-09 18:52:06 -0400263
264 // for disabling the status bar
265 int mDisabled = 0;
266
Daniel Sandler60ee2562011-07-22 12:34:33 -0400267 // tracking calls to View.setSystemUiVisibility()
268 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
269
Daniel Sandler36412a72011-08-04 09:35:13 -0400270 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700271
Daniel Sandler33805342012-07-23 15:45:12 -0400272 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400273 private final GestureRecorder mGestureRec = DEBUG_GESTURES
274 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
275 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400276
Daniel Sandler328310c2011-09-23 15:56:52 -0400277 private int mNavigationIconHints = 0;
Romain Guyf7f16f72012-05-24 19:13:56 -0700278 private final Animator.AnimatorListener mMakeIconsInvisible = new AnimatorListenerAdapter() {
279 @Override
280 public void onAnimationEnd(Animator animation) {
Daniel Sandler67e7d902012-06-06 16:32:21 -0400281 // double-check to avoid races
Daniel Sandler173bae22012-09-25 14:37:42 -0400282 if (mStatusBarContents.getAlpha() == 0) {
Daniel Sandler67e7d902012-06-06 16:32:21 -0400283 Slog.d(TAG, "makeIconsInvisible");
Daniel Sandler173bae22012-09-25 14:37:42 -0400284 mStatusBarContents.setVisibility(View.INVISIBLE);
Daniel Sandler67e7d902012-06-06 16:32:21 -0400285 }
Romain Guyf7f16f72012-05-24 19:13:56 -0700286 }
287 };
Daniel Sandler328310c2011-09-23 15:56:52 -0400288
John Spurlock919adac2012-10-02 16:41:12 -0400289 // ensure quick settings is disabled until the current user makes it through the setup wizard
290 private boolean mUserSetup = false;
291 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
292 @Override
293 public void onChange(boolean selfChange) {
294 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
295 mContext.getContentResolver(),
296 Settings.Secure.USER_SETUP_COMPLETE,
297 0 /*default */,
298 mCurrentUserId);
John Spurlocke4e8c562012-10-04 09:55:01 -0400299 if (MULTIUSER_DEBUG) Slog.d(TAG, String.format("User setup changed: " +
300 "selfChange=%s userSetup=%s mUserSetup=%s",
301 selfChange, userSetup, mUserSetup));
Daniel Sandler91ffedd2012-10-17 01:09:27 -0400302 if (mSettingsButton != null && !mHasSettingsPanel) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400303 mSettingsButton.setVisibility(userSetup ? View.VISIBLE : View.INVISIBLE);
304 }
305 if (mSettingsPanel != null) {
John Spurlocke4e8c562012-10-04 09:55:01 -0400306 mSettingsPanel.setEnabled(userSetup);
Daniel Sandler101784e2012-10-15 13:39:38 -0400307 }
John Spurlock919adac2012-10-02 16:41:12 -0400308 if (userSetup != mUserSetup) {
309 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400310 if (!mUserSetup && mStatusBarView != null)
311 animateCollapseQuickSettings();
312 }
313 }
314 };
315
Joe Onorato808182d2010-07-09 18:52:06 -0400316 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400317 public void start() {
318 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
319 .getDefaultDisplay();
Joe Onorato808182d2010-07-09 18:52:06 -0400320
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400321 mDreamManager = IDreamManager.Stub.asInterface(
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -0700322 ServiceManager.checkService(DreamService.DREAM_SERVICE));
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400323
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500324 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400325
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400326 addNavigationBar();
327
Daniel Sandlerfc6fda32012-02-24 22:00:46 -0500328 if (ENABLE_INTRUDERS) addIntruderView();
Joe Onorato808182d2010-07-09 18:52:06 -0400329
330 // Lastly, call to the icon policy to install/update all the icons.
Joe Onoratofd52b182010-11-10 18:00:52 -0800331 mIconPolicy = new PhoneStatusBarPolicy(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400332 }
333
334 // ================================================================================
335 // Constructing the view
336 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700337 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400338 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400339
340 Resources res = context.getResources();
341
Daniel Sandler6e8db882011-10-26 15:40:51 -0400342 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400343 loadDimens();
Joe Onorato808182d2010-07-09 18:52:06 -0400344
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700345 mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
346
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400347 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
Daniel Sandlera310af82012-04-24 01:20:13 -0400348 R.layout.super_status_bar, null);
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400349 mStatusBarWindow.mService = this;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400350 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
351 @Override
352 public boolean onTouch(View v, MotionEvent event) {
353 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandlere7237fc2012-08-14 16:08:27 -0400354 if (mExpandedVisible && !mAnimating) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400355 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400356 }
357 }
Chris Wren5de6e942012-05-16 14:22:21 -0400358 return mStatusBarWindow.onTouchEvent(event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400359 }});
360
Daniel Sandlera310af82012-04-24 01:20:13 -0400361 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400362 mStatusBarView.setBar(this);
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700363
Daniel Sandler08d05e32012-08-08 16:39:54 -0400364
365 PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
366 mStatusBarView.setPanelHolder(holder);
367
Daniel Sandler040c2e42012-10-17 00:56:33 -0400368 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(R.id.notification_panel);
369 mNotificationPanel.setStatusBar(this);
Daniel Sandler66d92f82012-06-13 13:36:52 -0400370 mNotificationPanelIsFullScreenWidth =
371 (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
Joe Onorato808182d2010-07-09 18:52:06 -0400372
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700373 // make the header non-responsive to clicks
374 mNotificationPanel.findViewById(R.id.header).setOnTouchListener(
375 new View.OnTouchListener() {
376 @Override
377 public boolean onTouch(View v, MotionEvent event) {
378 return true; // e eats everything
379 }
380 });
381
Jeff Brown98365d72012-08-19 20:30:52 -0700382 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700383 mStatusBarWindow.setBackground(null);
Romain Guy648342f2012-05-25 10:44:45 -0700384 mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
385 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700386 }
Daniel Sandler6b318802012-04-13 14:05:19 -0400387 if (ENABLE_INTRUDERS) {
388 mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
389 mIntruderAlertView.setVisibility(View.GONE);
390 mIntruderAlertView.setBar(this);
391 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400392 if (MULTIUSER_DEBUG) {
393 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info);
394 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
395 }
Joe Onorato808182d2010-07-09 18:52:06 -0400396
John Spurlockd5ef5462012-06-13 11:19:51 -0400397 updateShowSearchHoldoff();
398
Daniel Sandler0129b312011-05-11 11:54:11 -0400399 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700400 boolean showNav = mWindowManagerService.hasNavigationBar();
Daniel Sandler4a066c52012-04-20 14:49:13 -0400401 if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400402 if (showNav) {
Jim Miller5e6af442011-12-02 18:24:26 -0800403 mNavigationBarView =
Daniel Sandler0129b312011-05-11 11:54:11 -0400404 (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400405
Daniel Sandler6da2b762011-09-14 16:04:59 -0400406 mNavigationBarView.setDisabledFlags(mDisabled);
Jim Millere898ac52012-04-06 17:10:57 -0700407 mNavigationBarView.setBar(this);
Daniel Sandler0129b312011-05-11 11:54:11 -0400408 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400409 } catch (RemoteException ex) {
410 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400411 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400412
Joe Onorato808182d2010-07-09 18:52:06 -0400413 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400414 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400415
416 mSystemIconArea = (LinearLayout) mStatusBarView.findViewById(R.id.system_icon_area);
Daniel Sandlera310af82012-04-24 01:20:13 -0400417 mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons);
418 mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
Daniel Sandler05e24142011-11-10 11:56:49 -0500419 mNotificationIcons.setOverflowIndicator(mMoreIcon);
Daniel Sandler173bae22012-09-25 14:37:42 -0400420 mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
Daniel Sandlera310af82012-04-24 01:20:13 -0400421 mTickerView = mStatusBarView.findViewById(R.id.ticker);
Joe Onorato808182d2010-07-09 18:52:06 -0400422
Daniel Sandlera310af82012-04-24 01:20:13 -0400423 mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems);
Daniel Sandlere5011a32012-06-11 16:07:52 -0400424 mPile.setLayoutTransitionsEnabled(false);
Daniel Sandlerf7a19562012-04-04 14:04:21 -0400425 mPile.setLongPressListener(getNotificationLongClicker());
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400426 mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
Daniel Sandlerd7141482011-08-18 15:14:52 -0400427
Daniel Sandler3679bf52012-10-16 21:30:28 -0400428 mNotificationPanelHeader = mStatusBarWindow.findViewById(R.id.header);
429
Daniel Sandlera310af82012-04-24 01:20:13 -0400430 mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button);
Joe Onorato808182d2010-07-09 18:52:06 -0400431 mClearButton.setOnClickListener(mClearButtonListener);
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400432 mClearButton.setAlpha(0f);
Romain Guy8900e632012-05-25 12:08:39 -0700433 mClearButton.setVisibility(View.INVISIBLE);
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400434 mClearButton.setEnabled(false);
Daniel Sandlera310af82012-04-24 01:20:13 -0400435 mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400436
437 mHasSettingsPanel = res.getBoolean(R.bool.config_hasSettingsPanel);
Daniel Sandler101784e2012-10-15 13:39:38 -0400438 mHasFlipSettings = res.getBoolean(R.bool.config_hasFlipSettingsPanel);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400439
Daniel Sandler3679bf52012-10-16 21:30:28 -0400440 mDateTimeView = mNotificationPanelHeader.findViewById(R.id.datetime);
441 if (mHasFlipSettings) {
442 mDateTimeView.setOnClickListener(mClockClickListener);
443 mDateTimeView.setEnabled(true);
444 }
445
Daniel Sandlere111ad32012-10-13 15:17:45 -0400446 mSettingsButton = (ImageView) mStatusBarWindow.findViewById(R.id.settings_button);
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400447 if (mSettingsButton != null) {
Daniel Sandlere111ad32012-10-13 15:17:45 -0400448 mSettingsButton.setOnClickListener(mSettingsButtonListener);
449 if (mHasSettingsPanel) {
450 if (mStatusBarView.hasFullWidthNotifications()) {
451 // the settings panel is hiding behind this button
452 mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
453 mSettingsButton.setVisibility(View.VISIBLE);
454 } else {
455 // there is a settings panel, but it's on the other side of the (large) screen
456 mSettingsButton.setVisibility(View.GONE);
457 }
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700458 } else {
Daniel Sandlere111ad32012-10-13 15:17:45 -0400459 // no settings panel, go straight to settings
460 mSettingsButton.setVisibility(View.VISIBLE);
461 mSettingsButton.setImageResource(R.drawable.ic_notify_settings);
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700462 }
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400463 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400464 if (mHasFlipSettings) {
465 mNotificationButton = (ImageView) mStatusBarWindow.findViewById(R.id.notification_button);
466 if (mNotificationButton != null) {
467 mNotificationButton.setOnClickListener(mNotificationButtonListener);
468 }
469 }
470
Daniel Sandlera310af82012-04-24 01:20:13 -0400471 mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll);
Daniel Sandler079b33d2012-03-02 16:29:41 -0500472 mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
Daniel Sandler3679bf52012-10-16 21:30:28 -0400473 if (!mNotificationPanelIsFullScreenWidth) {
474 mScrollView.setSystemUiVisibility(
475 View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER |
476 View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
477 View.STATUS_BAR_DISABLE_CLOCK);
478 }
Joe Onorato808182d2010-07-09 18:52:06 -0400479
Daniel Sandlera310af82012-04-24 01:20:13 -0400480 mTicker = new MyTicker(context, mStatusBarView);
Joe Onorato808182d2010-07-09 18:52:06 -0400481
Daniel Sandlera310af82012-04-24 01:20:13 -0400482 TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText);
Joe Onorato808182d2010-07-09 18:52:06 -0400483 tickerView.mTicker = mTicker;
484
Joe Onorato808182d2010-07-09 18:52:06 -0400485 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
486
Joe Onorato808182d2010-07-09 18:52:06 -0400487 // set the inital view visibility
488 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400489
Daniel Sandler2b697352011-07-22 16:23:09 -0400490 // Other icons
491 mLocationController = new LocationController(mContext); // will post a notification
492 mBatteryController = new BatteryController(mContext);
Daniel Sandlera310af82012-04-24 01:20:13 -0400493 mBatteryController.addIconView((ImageView)mStatusBarView.findViewById(R.id.battery));
Daniel Sandler2b697352011-07-22 16:23:09 -0400494 mNetworkController = new NetworkController(mContext);
Winson Chungd63c59782012-09-05 17:34:41 -0700495 mBluetoothController = new BluetoothController(mContext);
Jim Miller5e6af442011-12-02 18:24:26 -0800496 final SignalClusterView signalCluster =
Daniel Sandlera310af82012-04-24 01:20:13 -0400497 (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
Daniel Sandler3d32a242012-06-05 13:44:14 -0400498
Winson Chungd63c59782012-09-05 17:34:41 -0700499
Christian Robertson2e347422011-08-11 14:01:04 -0700500 mNetworkController.addSignalCluster(signalCluster);
Daniel Sandler28f89d42011-08-15 14:04:15 -0400501 signalCluster.setNetworkController(mNetworkController);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400502
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400503 mEmergencyCallLabel = (TextView)mStatusBarWindow.findViewById(R.id.emergency_calls_only);
504 if (mEmergencyCallLabel != null) {
505 mNetworkController.addEmergencyLabelView(mEmergencyCallLabel);
Daniel Sandler3679bf52012-10-16 21:30:28 -0400506 mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() {
507 public void onClick(View v) { }});
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400508 mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
509 @Override
510 public void onLayoutChange(View v, int left, int top, int right, int bottom,
511 int oldLeft, int oldTop, int oldRight, int oldBottom) {
512 updateCarrierLabelVisibility(false);
513 }});
514 }
515
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400516 mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
517 mShowCarrierInPanel = (mCarrierLabel != null);
518 Slog.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
519 if (mShowCarrierInPanel) {
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400520 mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
521
Daniel Sandler67234c42012-06-15 13:17:39 -0400522 // for mobile devices, we always show mobile connection info here (SPN/PLMN)
523 // for other devices, we show whatever network is connected
Daniel Sandler18ac7822012-06-11 16:07:18 -0400524 if (mNetworkController.hasMobileDataFeature()) {
525 mNetworkController.addMobileLabelView(mCarrierLabel);
526 } else {
Daniel Sandler67234c42012-06-15 13:17:39 -0400527 mNetworkController.addCombinedLabelView(mCarrierLabel);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400528 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400529
530 // set up the dynamic hide/show of the label
531 mPile.setOnSizeChangedListener(new OnSizeChangedListener() {
532 @Override
533 public void onSizeChanged(View view, int w, int h, int oldw, int oldh) {
534 updateCarrierLabelVisibility(false);
535 }
536 });
Daniel Sandler3d32a242012-06-05 13:44:14 -0400537 }
538
Daniel Sandlere111ad32012-10-13 15:17:45 -0400539 // Quick Settings (where available, some restrictions apply)
540 if (mHasSettingsPanel) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400541 // first, figure out where quick settings should be inflated
542 final View settings_stub;
543 if (mHasFlipSettings) {
544 // a version of quick settings that flips around behind the notifications
545 settings_stub = mStatusBarWindow.findViewById(R.id.flip_settings_stub);
546 if (settings_stub != null) {
547 mFlipSettingsView = ((ViewStub)settings_stub).inflate();
548 mFlipSettingsView.setVisibility(View.GONE);
549 mFlipSettingsView.setVerticalScrollBarEnabled(false);
550 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400551 } else {
Daniel Sandler101784e2012-10-15 13:39:38 -0400552 // full quick settings panel
553 settings_stub = mStatusBarWindow.findViewById(R.id.quick_settings_stub);
554 if (settings_stub != null) {
555 mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate();
556 } else {
557 mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
558 }
559
560 if (mSettingsPanel != null) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400561 if (!ActivityManager.isHighEndGfx()) {
562 mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
563 R.color.notification_panel_solid_background)));
564 }
565 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400566 }
567
Daniel Sandler101784e2012-10-15 13:39:38 -0400568 // wherever you find it, Quick Settings needs a container to survive
569 mSettingsContainer = (QuickSettingsContainerView)
570 mStatusBarWindow.findViewById(R.id.quick_settings_container);
571 if (mSettingsContainer != null) {
572 mQS = new QuickSettings(mContext, mSettingsContainer);
Daniel Sandler3679bf52012-10-16 21:30:28 -0400573 if (!mNotificationPanelIsFullScreenWidth) {
574 mSettingsContainer.setSystemUiVisibility(
575 View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
576 | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
577 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400578 if (mSettingsPanel != null) {
579 mSettingsPanel.setQuickSettings(mQS);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400580 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400581 mQS.setService(this);
Daniel Sandlerfe3376b2012-10-16 19:54:02 -0400582 mQS.setBar(mStatusBarView);
Daniel Sandler101784e2012-10-15 13:39:38 -0400583 mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
584 mLocationController);
585 } else {
586 mQS = null; // fly away, be free
Daniel Sandlere111ad32012-10-13 15:17:45 -0400587 }
Siva Velusamy537421b2012-09-14 14:45:02 -0700588 }
589
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400590 mClingShown = ! (DEBUG_CLINGS
591 || !Prefs.read(mContext).getBoolean(Prefs.SHOWN_QUICK_SETTINGS_HELP, false));
592
Daniel Sandlerace0bd72012-10-11 09:56:45 -0700593 if (!ENABLE_NOTIFICATION_PANEL_CLING || ActivityManager.isRunningInTestHarness()) {
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400594 mClingShown = true;
595 }
596
Jim Miller5e6af442011-12-02 18:24:26 -0800597// final ImageView wimaxRSSI =
Daniel Sandler633eabe2011-11-09 16:49:44 -0500598// (ImageView)sb.findViewById(R.id.wimax_signal);
599// if (wimaxRSSI != null) {
600// mNetworkController.addWimaxIconView(wimaxRSSI);
601// }
Michael Jurka3b1fc472011-06-13 10:54:40 -0700602
Joe Onorato808182d2010-07-09 18:52:06 -0400603 // receive broadcasts
604 IntentFilter filter = new IntentFilter();
605 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
606 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
607 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400608 filter.addAction(Intent.ACTION_SCREEN_ON);
Joe Onorato808182d2010-07-09 18:52:06 -0400609 context.registerReceiver(mBroadcastReceiver, filter);
610
John Spurlock919adac2012-10-02 16:41:12 -0400611 // listen for USER_SETUP_COMPLETE setting (per-user)
612 resetUserSetupObserver();
613
Daniel Sandlera310af82012-04-24 01:20:13 -0400614 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400615 }
616
Michael Jurka7f2668c2012-03-27 07:49:52 -0700617 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -0700618 protected View getStatusBarView() {
619 return mStatusBarView;
620 }
621
622 @Override
Jim Millerf2a16b22011-07-06 17:32:48 -0700623 protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
Michael Jurka3cd0a592011-08-16 12:40:30 -0700624 boolean opaque = false;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700625 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Jim Millerf2a16b22011-07-06 17:32:48 -0700626 layoutParams.width,
627 layoutParams.height,
Michael Jurka3b1fc472011-06-13 10:54:40 -0700628 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
629 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
630 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700631 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Michael Jurka3cd0a592011-08-16 12:40:30 -0700632 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
Jeff Brown98365d72012-08-19 20:30:52 -0700633 if (ActivityManager.isHighEndGfx()) {
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700634 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Michael Jurkaf16fc512012-02-27 15:02:23 -0800635 } else {
636 lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
Michael Jurkaf3abbad2012-06-04 14:00:32 -0700637 lp.dimAmount = 0.75f;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700638 }
Michael Jurka3b1fc472011-06-13 10:54:40 -0700639 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
640 lp.setTitle("RecentsPanel");
Michael Jurka99a96552012-01-27 17:23:38 -0800641 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700642 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
643 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
644 return lp;
645 }
646
Jim Millere898ac52012-04-06 17:10:57 -0700647 @Override
648 protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
649 boolean opaque = false;
650 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
651 LayoutParams.MATCH_PARENT,
652 LayoutParams.MATCH_PARENT,
653 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
654 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
655 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
656 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
657 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
Jeff Brown98365d72012-08-19 20:30:52 -0700658 if (ActivityManager.isHighEndGfx()) {
Jim Millere898ac52012-04-06 17:10:57 -0700659 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Jim Millere898ac52012-04-06 17:10:57 -0700660 }
661 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
662 lp.setTitle("SearchPanel");
663 // TODO: Define custom animation for Search panel
664 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
665 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
666 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
667 return lp;
668 }
669
Jim Millere898ac52012-04-06 17:10:57 -0700670 @Override
671 protected void updateSearchPanel() {
672 super.updateSearchPanel();
Jim Miller354619c2012-04-27 17:33:44 -0700673 mSearchPanelView.setStatusBarView(mNavigationBarView);
Jim Millere898ac52012-04-06 17:10:57 -0700674 mNavigationBarView.setDelegateView(mSearchPanelView);
675 }
676
677 @Override
678 public void showSearchPanel() {
Jim Millerb490c3e2012-05-31 13:34:16 -0700679 super.showSearchPanel();
Jim Millere898ac52012-04-06 17:10:57 -0700680 WindowManager.LayoutParams lp =
681 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
682 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Jeff Brown98365d72012-08-19 20:30:52 -0700683 mWindowManager.updateViewLayout(mNavigationBarView, lp);
Jim Millere898ac52012-04-06 17:10:57 -0700684 }
685
686 @Override
687 public void hideSearchPanel() {
688 super.hideSearchPanel();
689 WindowManager.LayoutParams lp =
690 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
691 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Jeff Brown98365d72012-08-19 20:30:52 -0700692 mWindowManager.updateViewLayout(mNavigationBarView, lp);
Jim Millere898ac52012-04-06 17:10:57 -0700693 }
694
Joe Onorato808182d2010-07-09 18:52:06 -0400695 protected int getStatusBarGravity() {
696 return Gravity.TOP | Gravity.FILL_HORIZONTAL;
697 }
698
Joe Onoratodc100302011-01-11 17:07:41 -0800699 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -0400700 if (mNaturalBarHeight < 0) {
701 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -0700702 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -0400703 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
704 }
705 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -0800706 }
707
Daniel Sandler5c8da942011-06-28 00:29:04 -0400708 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
709 public void onClick(View v) {
710 toggleRecentApps();
711 }
712 };
Chris Wren0c8275b2012-05-08 13:36:48 -0400713
Jim Miller9a720f52012-05-30 03:19:43 -0700714 private int mShowSearchHoldoff = 0;
715 private Runnable mShowSearchPanel = new Runnable() {
716 public void run() {
717 showSearchPanel();
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400718 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700719 }
720 };
721
Jim Millere898ac52012-04-06 17:10:57 -0700722 View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
723 public boolean onTouch(View v, MotionEvent event) {
724 switch(event.getAction()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700725 case MotionEvent.ACTION_DOWN:
John Spurlock67ad3682012-06-26 17:42:00 -0400726 if (!shouldDisableNavbarGestures() && !inKeyguardRestrictedInputMode()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700727 mHandler.removeCallbacks(mShowSearchPanel);
728 mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
729 }
730 break;
731
732 case MotionEvent.ACTION_UP:
733 case MotionEvent.ACTION_CANCEL:
734 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400735 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700736 break;
737 }
738 return false;
Jim Millere898ac52012-04-06 17:10:57 -0700739 }
740 };
Daniel Sandler5c8da942011-06-28 00:29:04 -0400741
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400742 private void awakenDreams() {
743 if (mDreamManager != null) {
744 try {
745 mDreamManager.awaken();
746 } catch (RemoteException e) {
747 // fine, stay asleep then
748 }
749 }
750 }
751
Michael Jurka412cba82011-10-17 09:05:00 -0700752 private void prepareNavigationBarView() {
753 mNavigationBarView.reorient();
754
755 mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
Michael Jurkacb2522c2012-04-13 09:32:47 -0700756 mNavigationBarView.getRecentsButton().setOnTouchListener(getRecentTasksLoader());
Jim Miller998bb762012-05-21 13:37:27 -0700757 mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
Jim Millere898ac52012-04-06 17:10:57 -0700758 updateSearchPanel();
Michael Jurka412cba82011-10-17 09:05:00 -0700759 }
760
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400761 // For small-screen devices (read: phones) that lack hardware navigation buttons
762 private void addNavigationBar() {
Daniel Sandler4a066c52012-04-20 14:49:13 -0400763 if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -0400764 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700765
Michael Jurka412cba82011-10-17 09:05:00 -0700766 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400767
Jeff Brown98365d72012-08-19 20:30:52 -0700768 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400769 }
770
771 private void repositionNavigationBar() {
Daniel Sandler0129b312011-05-11 11:54:11 -0400772 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700773
Michael Jurka412cba82011-10-17 09:05:00 -0700774 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400775
Jeff Brown98365d72012-08-19 20:30:52 -0700776 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400777 }
778
779 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400780 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -0700781 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400782 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
783 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400784 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
785 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -0700786 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -0400787 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -0700788 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Daniel Sandlera3884492011-08-16 15:55:44 -0400789 PixelFormat.OPAQUE);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700790 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -0700791 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700792 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
793 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400794
795 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400796 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400797 return lp;
798 }
799
Joe Onoratodc100302011-01-11 17:07:41 -0800800 private void addIntruderView() {
Joe Onorato808182d2010-07-09 18:52:06 -0400801 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
802 ViewGroup.LayoutParams.MATCH_PARENT,
803 ViewGroup.LayoutParams.WRAP_CONTENT,
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400804 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
Joe Onorato808182d2010-07-09 18:52:06 -0400805 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
806 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
807 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
808 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Jeff Brown46e75292010-11-10 16:53:45 -0800809 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
810 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Joe Onorato808182d2010-07-09 18:52:06 -0400811 PixelFormat.TRANSLUCENT);
812 lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400813 //lp.y += height * 1.5; // FIXME
Joe Onorato808182d2010-07-09 18:52:06 -0400814 lp.setTitle("IntruderAlert");
Dianne Hackborn59aed382011-08-02 17:31:44 -0700815 lp.packageName = mContext.getPackageName();
816 lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
Joe Onorato808182d2010-07-09 18:52:06 -0400817
Jeff Brown98365d72012-08-19 20:30:52 -0700818 mWindowManager.addView(mIntruderAlertView, lp);
Joe Onorato808182d2010-07-09 18:52:06 -0400819 }
820
821 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
822 if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
823 + " icon=" + icon);
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700824 StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400825 view.set(icon);
826 mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
827 }
828
829 public void updateIcon(String slot, int index, int viewIndex,
830 StatusBarIcon old, StatusBarIcon icon) {
831 if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
832 + " old=" + old + " icon=" + icon);
833 StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
834 view.set(icon);
835 }
836
837 public void removeIcon(String slot, int index, int viewIndex) {
838 if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
839 mStatusIcons.removeViewAt(viewIndex);
840 }
841
842 public void addNotification(IBinder key, StatusBarNotification notification) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500843 /* if (DEBUG) */ Slog.d(TAG, "addNotification score=" + notification.score);
Joe Onorato808182d2010-07-09 18:52:06 -0400844 StatusBarIconView iconView = addNotificationViews(key, notification);
845 if (iconView == null) return;
846
847 boolean immersive = false;
848 try {
849 immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
Daniel Sandler8355e932011-08-11 00:27:45 -0400850 if (DEBUG) {
851 Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
852 }
Joe Onorato808182d2010-07-09 18:52:06 -0400853 } catch (RemoteException ex) {
854 }
Daniel Sandler6b318802012-04-13 14:05:19 -0400855
856 /*
857 * DISABLED due to missing API
Daniel Sandlerfc6fda32012-02-24 22:00:46 -0500858 if (ENABLE_INTRUDERS && (
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400859 // TODO(dsandler): Only if the screen is on
860 notification.notification.intruderView != null)) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500861 Slog.d(TAG, "Presenting high-priority notification");
862 // special new transient ticker mode
863 // 1. Populate mIntruderAlertView
Jim Millere898ac52012-04-06 17:10:57 -0700864
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400865 if (notification.notification.intruderView == null) {
866 Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
867 return;
868 }
Joe Onorato808182d2010-07-09 18:52:06 -0400869
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400870 // bind the click event to the content area
871 PendingIntent contentIntent = notification.notification.contentIntent;
872 final View.OnClickListener listener = (contentIntent != null)
873 ? new NotificationClicker(contentIntent,
874 notification.pkg, notification.tag, notification.id)
875 : null;
Joe Onorato808182d2010-07-09 18:52:06 -0400876
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400877 mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener);
Joe Onorato808182d2010-07-09 18:52:06 -0400878
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400879 mCurrentlyIntrudingNotification = notification;
Jim Millere898ac52012-04-06 17:10:57 -0700880
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500881 // 2. Animate mIntruderAlertView in
882 mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
Joe Onorato808182d2010-07-09 18:52:06 -0400883
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500884 // 3. Set alarm to age the notification off (TODO)
885 mHandler.removeMessages(MSG_HIDE_INTRUDER);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400886 if (INTRUDER_ALERT_DECAY_MS > 0) {
887 mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
888 }
Jim Millera073e572012-05-23 17:03:27 -0700889 } else
Daniel Sandler6b318802012-04-13 14:05:19 -0400890 */
Jim Millera073e572012-05-23 17:03:27 -0700891
Daniel Sandler6b318802012-04-13 14:05:19 -0400892 if (notification.notification.fullScreenIntent != null) {
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -0400893 // Stop screensaver if the notification has a full-screen intent.
894 // (like an incoming phone call)
895 awakenDreams();
896
Joe Onorato808182d2010-07-09 18:52:06 -0400897 // not immersive & a full-screen alert should be shown
Daniel Sandler8355e932011-08-11 00:27:45 -0400898 Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
Joe Onorato808182d2010-07-09 18:52:06 -0400899 try {
900 notification.notification.fullScreenIntent.send();
901 } catch (PendingIntent.CanceledException e) {
902 }
903 } else {
904 // usual case: status bar visible & not immersive
905
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400906 // show the ticker if there isn't an intruder too
907 if (mCurrentlyIntrudingNotification == null) {
Chris Wren0c8275b2012-05-08 13:36:48 -0400908 tick(null, notification, true);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400909 }
Joe Onorato808182d2010-07-09 18:52:06 -0400910 }
911
912 // Recalculate the position of the sliding windows and the titles.
913 setAreThereNotifications();
914 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
915 }
916
Joe Onorato808182d2010-07-09 18:52:06 -0400917 public void removeNotification(IBinder key) {
Joe Onorato808182d2010-07-09 18:52:06 -0400918 StatusBarNotification old = removeNotificationViews(key);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400919 if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -0400920
921 if (old != null) {
922 // Cancel the ticker if it's still running
923 mTicker.removeEntry(old);
924
925 // Recalculate the position of the sliding windows and the titles.
Joe Onorato808182d2010-07-09 18:52:06 -0400926 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Jim Millere898ac52012-04-06 17:10:57 -0700927
Daniel Sandler6b318802012-04-13 14:05:19 -0400928 if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) {
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400929 mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
930 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400931
932 if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 && !mAnimating) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400933 animateCollapsePanels();
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400934 }
Joe Onorato808182d2010-07-09 18:52:06 -0400935 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400936
937 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400938 }
939
John Spurlockd5ef5462012-06-13 11:19:51 -0400940 private void updateShowSearchHoldoff() {
941 mShowSearchHoldoff = mContext.getResources().getInteger(
942 R.integer.config_show_search_delay);
Michael Jurka3b1fc472011-06-13 10:54:40 -0700943 }
944
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400945 private void loadNotificationShade() {
Daniel Sandler26cda272012-05-22 15:44:08 -0400946 if (mPile == null) return;
947
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400948 int N = mNotificationData.size();
949
950 ArrayList<View> toShow = new ArrayList<View>();
951
Daniel Sandler26cda272012-05-22 15:44:08 -0400952 final boolean provisioned = isDeviceProvisioned();
953 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400954 for (int i=0; i<N; i++) {
Daniel Sandler26cda272012-05-22 15:44:08 -0400955 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400956 if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
957 if (!notificationIsForCurrentUser(ent.notification)) continue;
958 toShow.add(ent.row);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400959 }
960
961 ArrayList<View> toRemove = new ArrayList<View>();
962 for (int i=0; i<mPile.getChildCount(); i++) {
963 View child = mPile.getChildAt(i);
964 if (!toShow.contains(child)) {
965 toRemove.add(child);
Joe Onorato808182d2010-07-09 18:52:06 -0400966 }
967 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400968
969 for (View remove : toRemove) {
970 mPile.removeView(remove);
971 }
972
973 for (int i=0; i<toShow.size(); i++) {
974 View v = toShow.get(i);
975 if (v.getParent() == null) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500976 mPile.addView(v, i);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400977 }
978 }
Daniel Sandler26cda272012-05-22 15:44:08 -0400979
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400980 if (mSettingsButton != null) {
981 mSettingsButton.setEnabled(isDeviceProvisioned());
982 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400983 }
984
Chris Wren0c8275b2012-05-08 13:36:48 -0400985 @Override
986 protected void updateNotificationIcons() {
Daniel Sandler26cda272012-05-22 15:44:08 -0400987 if (mNotificationIcons == null) return;
988
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400989 loadNotificationShade();
990
991 final LinearLayout.LayoutParams params
992 = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
993
994 int N = mNotificationData.size();
995
996 if (DEBUG) {
997 Slog.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
998 }
999
1000 ArrayList<View> toShow = new ArrayList<View>();
1001
Daniel Sandler26cda272012-05-22 15:44:08 -04001002 final boolean provisioned = isDeviceProvisioned();
1003 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001004 for (int i=0; i<N; i++) {
Daniel Sandler58b173b2012-05-03 11:25:29 -04001005 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001006 if (!((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE)
1007 || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
1008 if (!notificationIsForCurrentUser(ent.notification)) continue;
1009 toShow.add(ent.icon);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001010 }
1011
1012 ArrayList<View> toRemove = new ArrayList<View>();
1013 for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
1014 View child = mNotificationIcons.getChildAt(i);
1015 if (!toShow.contains(child)) {
1016 toRemove.add(child);
1017 }
1018 }
1019
1020 for (View remove : toRemove) {
1021 mNotificationIcons.removeView(remove);
1022 }
1023
1024 for (int i=0; i<toShow.size(); i++) {
1025 View v = toShow.get(i);
1026 if (v.getParent() == null) {
1027 mNotificationIcons.addView(v, i, params);
1028 }
1029 }
1030 }
1031
Daniel Sandlere5011a32012-06-11 16:07:52 -04001032 protected void updateCarrierLabelVisibility(boolean force) {
Daniel Sandlerbf526d12012-09-04 22:56:44 -04001033 if (!mShowCarrierInPanel) return;
Daniel Sandler3d32a242012-06-05 13:44:14 -04001034 // The idea here is to only show the carrier label when there is enough room to see it,
1035 // i.e. when there aren't enough notifications to fill the panel.
1036 if (DEBUG) {
1037 Slog.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
1038 mPile.getHeight(), mScrollView.getHeight(), mCarrierLabelHeight));
1039 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -04001040
1041 final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
1042 final boolean makeVisible =
1043 !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
Daniel Sandler101784e2012-10-15 13:39:38 -04001044 && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight)
1045 && mScrollView.getVisibility() == View.VISIBLE;
Daniel Sandler3d32a242012-06-05 13:44:14 -04001046
Daniel Sandlere5011a32012-06-11 16:07:52 -04001047 if (force || mCarrierLabelVisible != makeVisible) {
Daniel Sandler3d32a242012-06-05 13:44:14 -04001048 mCarrierLabelVisible = makeVisible;
1049 if (DEBUG) {
1050 Slog.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
1051 }
1052 mCarrierLabel.animate().cancel();
1053 if (makeVisible) {
1054 mCarrierLabel.setVisibility(View.VISIBLE);
1055 }
1056 mCarrierLabel.animate()
1057 .alpha(makeVisible ? 1f : 0f)
1058 //.setStartDelay(makeVisible ? 500 : 0)
1059 //.setDuration(makeVisible ? 750 : 100)
1060 .setDuration(150)
1061 .setListener(makeVisible ? null : new AnimatorListenerAdapter() {
1062 @Override
1063 public void onAnimationEnd(Animator animation) {
1064 if (!mCarrierLabelVisible) { // race
1065 mCarrierLabel.setVisibility(View.INVISIBLE);
1066 mCarrierLabel.setAlpha(0f);
1067 }
1068 }
1069 })
1070 .start();
1071 }
1072 }
1073
Chris Wren0c8275b2012-05-08 13:36:48 -04001074 @Override
1075 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001076 final boolean any = mNotificationData.size() > 0;
Joe Onorato808182d2010-07-09 18:52:06 -04001077
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001078 final boolean clearable = any && mNotificationData.hasClearableItems();
1079
1080 if (DEBUG) {
1081 Slog.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
1082 + " any=" + any + " clearable=" + clearable);
1083 }
1084
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001085 if (mHasFlipSettings
1086 && mFlipSettingsView != null
Daniel Sandlerf249efc2012-10-17 16:42:36 -04001087 && mFlipSettingsView.getVisibility() == View.VISIBLE
1088 && mScrollView.getVisibility() != View.VISIBLE) {
1089 // the flip settings panel is unequivocally showing; we should not be shown
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001090 mClearButton.setVisibility(View.INVISIBLE);
1091 } else if (mClearButton.isShown()) {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001092 if (clearable != (mClearButton.getAlpha() == 1.0f)) {
Romain Guy8900e632012-05-25 12:08:39 -07001093 ObjectAnimator clearAnimation = ObjectAnimator.ofFloat(
1094 mClearButton, "alpha", clearable ? 1.0f : 0.0f).setDuration(250);
1095 clearAnimation.addListener(new AnimatorListenerAdapter() {
1096 @Override
1097 public void onAnimationEnd(Animator animation) {
1098 if (mClearButton.getAlpha() <= 0.0f) {
1099 mClearButton.setVisibility(View.INVISIBLE);
1100 }
1101 }
1102
1103 @Override
1104 public void onAnimationStart(Animator animation) {
1105 if (mClearButton.getAlpha() <= 0.0f) {
1106 mClearButton.setVisibility(View.VISIBLE);
1107 }
1108 }
1109 });
1110 clearAnimation.start();
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001111 }
1112 } else {
1113 mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
Romain Guy8900e632012-05-25 12:08:39 -07001114 mClearButton.setVisibility(clearable ? View.VISIBLE : View.INVISIBLE);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001115 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001116 mClearButton.setEnabled(clearable);
Romain Guy8900e632012-05-25 12:08:39 -07001117
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001118 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
1119 final boolean showDot = (any&&!areLightsOn());
1120 if (showDot != (nlo.getAlpha() == 1.0f)) {
1121 if (showDot) {
1122 nlo.setAlpha(0f);
1123 nlo.setVisibility(View.VISIBLE);
1124 }
1125 nlo.animate()
1126 .alpha(showDot?1:0)
1127 .setDuration(showDot?750:250)
1128 .setInterpolator(new AccelerateInterpolator(2.0f))
1129 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1130 @Override
1131 public void onAnimationEnd(Animator _a) {
1132 nlo.setVisibility(View.GONE);
1133 }
1134 })
1135 .start();
1136 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001137
Daniel Sandlere5011a32012-06-11 16:07:52 -04001138 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001139 }
1140
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001141 public void showClock(boolean show) {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001142 if (mStatusBarView == null) return;
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001143 View clock = mStatusBarView.findViewById(R.id.clock);
1144 if (clock != null) {
1145 clock.setVisibility(show ? View.VISIBLE : View.GONE);
1146 }
1147 }
Joe Onorato808182d2010-07-09 18:52:06 -04001148
1149 /**
1150 * State is one or more of the DISABLE constants from StatusBarManager.
1151 */
1152 public void disable(int state) {
1153 final int old = mDisabled;
1154 final int diff = state ^ old;
1155 mDisabled = state;
1156
Daniel Sandlere21f2882011-08-18 10:14:59 -04001157 if (DEBUG) {
1158 Slog.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
1159 old, state, diff));
1160 }
1161
Daniel Sandler6da2b762011-09-14 16:04:59 -04001162 StringBuilder flagdbg = new StringBuilder();
1163 flagdbg.append("disable: < ");
1164 flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
1165 flagdbg.append(((diff & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
1166 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
1167 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
1168 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
1169 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
1170 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "TICKER" : "ticker");
1171 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
1172 flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
1173 flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001174 flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
1175 flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
Daniel Sandlerdba93562011-10-06 16:39:58 -04001176 flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
1177 flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
1178 flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
1179 flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001180 flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
1181 flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
1182 flagdbg.append(">");
1183 Slog.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07001184
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001185 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001186 mSystemIconArea.animate().cancel();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001187 if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001188 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001189 .alpha(0f)
1190 .translationY(mNaturalBarHeight*0.5f)
Daniel Sandler67e7d902012-06-06 16:32:21 -04001191 .setDuration(175)
1192 .setInterpolator(new DecelerateInterpolator(1.5f))
1193 .setListener(mMakeIconsInvisible)
1194 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001195 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001196 mSystemIconArea.setVisibility(View.VISIBLE);
1197 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001198 .alpha(1f)
1199 .translationY(0)
1200 .setStartDelay(0)
1201 .setInterpolator(new DecelerateInterpolator(1.5f))
1202 .setDuration(175)
1203 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001204 }
1205 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04001206
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001207 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
1208 boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
1209 showClock(show);
1210 }
Joe Onorato808182d2010-07-09 18:52:06 -04001211 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1212 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001213 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04001214 }
1215 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001216
Jim Miller5e6af442011-12-02 18:24:26 -08001217 if ((diff & (StatusBarManager.DISABLE_HOME
1218 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerdba93562011-10-06 16:39:58 -04001219 | StatusBarManager.DISABLE_BACK)) != 0) {
1220 // the nav bar will take care of these
Daniel Sandlerd9283b902011-09-14 21:42:00 -04001221 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001222
Daniel Sandlerdba93562011-10-06 16:39:58 -04001223 if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04001224 // close recents if it's visible
1225 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1226 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1227 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001228 }
1229
Joe Onorato808182d2010-07-09 18:52:06 -04001230 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1231 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Joe Onorato808182d2010-07-09 18:52:06 -04001232 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001233 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001234 }
Daniel Sandler173bae22012-09-25 14:37:42 -04001235
1236 mNotificationIcons.animate()
1237 .alpha(0f)
1238 .translationY(mNaturalBarHeight*0.5f)
1239 .setDuration(175)
1240 .setInterpolator(new DecelerateInterpolator(1.5f))
1241 .setListener(mMakeIconsInvisible)
1242 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001243 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001244 mNotificationIcons.setVisibility(View.VISIBLE);
1245 mNotificationIcons.animate()
1246 .alpha(1f)
1247 .translationY(0)
1248 .setStartDelay(0)
1249 .setInterpolator(new DecelerateInterpolator(1.5f))
1250 .setDuration(175)
1251 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001252 }
1253 } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1254 if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001255 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001256 }
1257 }
1258 }
1259
Michael Jurka7f2668c2012-03-27 07:49:52 -07001260 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07001261 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001262 return new PhoneStatusBar.H();
1263 }
1264
Joe Onorato808182d2010-07-09 18:52:06 -04001265 /**
1266 * All changes to the status bar and notifications funnel through here and are batched.
1267 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07001268 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04001269 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001270 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04001271 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001272 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04001273 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001274 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04001275 case MSG_OPEN_SETTINGS_PANEL:
1276 animateExpandSettingsPanel();
1277 break;
1278 case MSG_CLOSE_PANELS:
1279 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001280 break;
Joe Onorato808182d2010-07-09 18:52:06 -04001281 case MSG_SHOW_INTRUDER:
1282 setIntruderAlertVisibility(true);
1283 break;
1284 case MSG_HIDE_INTRUDER:
1285 setIntruderAlertVisibility(false);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04001286 mCurrentlyIntrudingNotification = null;
Joe Onorato808182d2010-07-09 18:52:06 -04001287 break;
1288 }
1289 }
1290 }
1291
Daniel Sandler040c2e42012-10-17 00:56:33 -04001292 public Handler getHandler() {
1293 return mHandler;
1294 }
1295
Joe Onorato808182d2010-07-09 18:52:06 -04001296 View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
1297 public void onFocusChange(View v, boolean hasFocus) {
1298 // Because 'v' is a ViewGroup, all its children will be (un)selected
1299 // too, which allows marqueeing to work.
1300 v.setSelected(hasFocus);
1301 }
1302 };
1303
Daniel Sandler08d05e32012-08-08 16:39:54 -04001304 void makeExpandedVisible(boolean revealAfterDraw) {
Joe Onorato808182d2010-07-09 18:52:06 -04001305 if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
1306 if (mExpandedVisible) {
1307 return;
1308 }
Jim Millera073e572012-05-23 17:03:27 -07001309
Joe Onorato808182d2010-07-09 18:52:06 -04001310 mExpandedVisible = true;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001311 mPile.setLayoutTransitionsEnabled(true);
John Spurlockd5ef5462012-06-13 11:19:51 -04001312 if (mNavigationBarView != null)
1313 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001314
Daniel Sandlere5011a32012-06-11 16:07:52 -04001315 updateCarrierLabelVisibility(true);
Daniel Sandler3d32a242012-06-05 13:44:14 -04001316
Joe Onorato808182d2010-07-09 18:52:06 -04001317 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Daniel Sandlera310af82012-04-24 01:20:13 -04001318
1319 // Expand the window to encompass the full screen in anticipation of the drag.
1320 // This is only possible to do atomically because the status bar is at the top of the screen!
1321 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001322 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1323 lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Daniel Sandler21b274e2012-05-02 15:07:51 -04001324 lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
Jeff Brown98365d72012-08-19 20:30:52 -07001325 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Daniel Sandlera310af82012-04-24 01:20:13 -04001326
John Spurlock804df702012-06-01 15:34:27 -04001327 // Updating the window layout will force an expensive traversal/redraw.
1328 // Kick off the reveal animation after this is complete to avoid animation latency.
1329 if (revealAfterDraw) {
Daniel Sandler08d05e32012-08-08 16:39:54 -04001330// mHandler.post(mStartRevealAnimation);
John Spurlock804df702012-06-01 15:34:27 -04001331 }
1332
Daniel Sandlera310af82012-04-24 01:20:13 -04001333 visibilityChanged(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001334 }
1335
Daniel Sandler11cf1782012-09-27 14:03:08 -04001336 public void animateCollapsePanels() {
1337 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001338 }
1339
Daniel Sandler11cf1782012-09-27 14:03:08 -04001340 public void animateCollapsePanels(int flags) {
Joe Onorato808182d2010-07-09 18:52:06 -04001341 if (SPEW) {
Daniel Sandler198a0302012-08-17 16:04:31 -04001342 Slog.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04001343 + " mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04001344 + " mAnimating=" + mAnimating
Daniel Sandlered930e52012-07-03 14:31:22 -04001345 + " mAnimatingReveal=" + mAnimatingReveal
Joe Onorato808182d2010-07-09 18:52:06 -04001346 + " mAnimY=" + mAnimY
Jim Miller9a720f52012-05-30 03:19:43 -07001347 + " mAnimVel=" + mAnimVel
1348 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04001349 }
1350
Jim Miller9a720f52012-05-30 03:19:43 -07001351 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Michael Jurka3b1fc472011-06-13 10:54:40 -07001352 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1353 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1354 }
Jim Miller9a720f52012-05-30 03:19:43 -07001355
1356 if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
1357 mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
1358 mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
1359 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07001360
Daniel Sandler08d05e32012-08-08 16:39:54 -04001361 mStatusBarView.collapseAllPanels(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001362 }
1363
Daniel Sandler101784e2012-10-15 13:39:38 -04001364 public ViewPropertyAnimator setVisibilityWhenDone(
1365 final ViewPropertyAnimator a, final View v, final int vis) {
1366 a.setListener(new AnimatorListenerAdapter() {
1367 @Override
1368 public void onAnimationEnd(Animator animation) {
1369 v.setVisibility(vis);
1370 a.setListener(null); // oneshot
1371 }
1372 });
1373 return a;
1374 }
1375
1376 public Animator setVisibilityWhenDone(
1377 final Animator a, final View v, final int vis) {
1378 a.addListener(new AnimatorListenerAdapter() {
1379 @Override
1380 public void onAnimationEnd(Animator animation) {
1381 v.setVisibility(vis);
1382 }
1383 });
1384 return a;
1385 }
1386
1387 public Animator interpolator(TimeInterpolator ti, Animator a) {
1388 a.setInterpolator(ti);
1389 return a;
1390 }
1391
1392 public Animator startDelay(int d, Animator a) {
1393 a.setStartDelay(d);
1394 return a;
1395 }
1396
1397 public Animator start(Animator a) {
1398 a.start();
1399 return a;
1400 }
1401
1402 final TimeInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
1403 final TimeInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
1404 final int FLIP_DURATION_OUT = 125;
1405 final int FLIP_DURATION_IN = 225;
1406 final int FLIP_DURATION = (FLIP_DURATION_IN + FLIP_DURATION_OUT);
1407
1408 Animator mScrollViewAnim, mFlipSettingsViewAnim, mNotificationButtonAnim,
1409 mSettingsButtonAnim, mClearButtonAnim;
1410
Daniel Sandler08d05e32012-08-08 16:39:54 -04001411 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001412 public void animateExpandNotificationsPanel() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001413 if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
Joe Onorato808182d2010-07-09 18:52:06 -04001414 if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1415 return ;
1416 }
Joe Onorato808182d2010-07-09 18:52:06 -04001417
Daniel Sandler08d05e32012-08-08 16:39:54 -04001418 mNotificationPanel.expand();
Daniel Sandler040c2e42012-10-17 00:56:33 -04001419 if (mHasFlipSettings && mScrollView.getVisibility() != View.VISIBLE) {
1420 flipToNotifications();
Daniel Sandler101784e2012-10-15 13:39:38 -04001421 }
Joe Onorato808182d2010-07-09 18:52:06 -04001422
1423 if (false) postStartTracing();
1424 }
1425
Daniel Sandler040c2e42012-10-17 00:56:33 -04001426 public void flipToNotifications() {
1427 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1428 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1429 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1430 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1431 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1432
1433 mScrollView.setVisibility(View.VISIBLE);
1434 mScrollViewAnim = start(
1435 startDelay(FLIP_DURATION_OUT,
1436 interpolator(mDecelerateInterpolator,
1437 ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f, 1f)
1438 .setDuration(FLIP_DURATION_IN)
1439 )));
1440 mFlipSettingsViewAnim = start(
1441 setVisibilityWhenDone(
1442 interpolator(mAccelerateInterpolator,
1443 ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f, 0f)
1444 )
1445 .setDuration(FLIP_DURATION_OUT),
1446 mFlipSettingsView, View.INVISIBLE));
1447 mNotificationButtonAnim = start(
1448 setVisibilityWhenDone(
1449 ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
1450 .setDuration(FLIP_DURATION),
1451 mNotificationButton, View.INVISIBLE));
1452 mSettingsButton.setVisibility(View.VISIBLE);
1453 mSettingsButtonAnim = start(
1454 ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
1455 .setDuration(FLIP_DURATION));
1456 mClearButton.setVisibility(View.VISIBLE);
1457 mClearButton.setAlpha(0f);
1458 setAreThereNotifications(); // this will show/hide the button as necessary
1459 mNotificationPanel.postDelayed(new Runnable() {
1460 public void run() {
1461 updateCarrierLabelVisibility(false);
1462 }
1463 }, FLIP_DURATION - 150);
1464 }
1465
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001466 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001467 public void animateExpandSettingsPanel() {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001468 if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
1469 if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1470 return;
1471 }
1472
Daniel Sandler101784e2012-10-15 13:39:38 -04001473 if (mHasFlipSettings) {
1474 mNotificationPanel.expand();
1475 if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
Daniel Sandler040c2e42012-10-17 00:56:33 -04001476 flipToSettings();
Daniel Sandler101784e2012-10-15 13:39:38 -04001477 }
1478 } else if (mSettingsPanel != null) {
1479 mSettingsPanel.expand();
1480 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001481
1482 if (false) postStartTracing();
1483 }
1484
Daniel Sandler040c2e42012-10-17 00:56:33 -04001485 public void switchToSettings() {
1486 mFlipSettingsView.setScaleX(1f);
1487 mFlipSettingsView.setVisibility(View.VISIBLE);
1488 mSettingsButton.setVisibility(View.GONE);
1489 mScrollView.setVisibility(View.GONE);
Daniel Sandler720a34d2012-10-18 11:44:04 -04001490 mScrollView.setScaleX(0f);
Daniel Sandler040c2e42012-10-17 00:56:33 -04001491 mNotificationButton.setVisibility(View.VISIBLE);
1492 mNotificationButton.setAlpha(1f);
1493 mClearButton.setVisibility(View.GONE);
1494 }
1495
1496 public void flipToSettings() {
1497 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1498 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1499 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1500 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1501 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1502
1503 mFlipSettingsView.setVisibility(View.VISIBLE);
1504 mFlipSettingsView.setScaleX(0f);
1505 mFlipSettingsViewAnim = start(
1506 startDelay(FLIP_DURATION_OUT,
1507 interpolator(mDecelerateInterpolator,
1508 ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f, 1f)
1509 .setDuration(FLIP_DURATION_IN)
1510 )));
1511 mScrollViewAnim = start(
1512 setVisibilityWhenDone(
1513 interpolator(mAccelerateInterpolator,
1514 ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f)
1515 )
1516 .setDuration(FLIP_DURATION_OUT),
1517 mScrollView, View.INVISIBLE));
1518 mSettingsButtonAnim = start(
1519 setVisibilityWhenDone(
1520 ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
1521 .setDuration(FLIP_DURATION),
1522 mScrollView, View.INVISIBLE));
1523 mNotificationButton.setVisibility(View.VISIBLE);
1524 mNotificationButtonAnim = start(
1525 ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
1526 .setDuration(FLIP_DURATION));
1527 mClearButtonAnim = start(
1528 setVisibilityWhenDone(
1529 ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
1530 .setDuration(FLIP_DURATION),
1531 mClearButton, View.INVISIBLE));
1532 mNotificationPanel.postDelayed(new Runnable() {
1533 public void run() {
1534 updateCarrierLabelVisibility(false);
1535 }
1536 }, FLIP_DURATION - 150);
1537 }
1538
1539 public void flipPanels() {
1540 if (mHasFlipSettings) {
1541 if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
1542 flipToSettings();
1543 } else {
1544 flipToNotifications();
1545 }
1546 }
1547 }
1548
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001549 public void animateCollapseQuickSettings() {
1550 mStatusBarView.collapseAllPanels(true);
1551 }
1552
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001553 void makeExpandedInvisibleSoon() {
1554 mHandler.postDelayed(new Runnable() { public void run() { makeExpandedInvisible(); }}, 50);
1555 }
1556
Daniel Sandler08d05e32012-08-08 16:39:54 -04001557 void makeExpandedInvisible() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001558 if (SPEW) Slog.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04001559 + " mExpandedVisible=" + mExpandedVisible);
1560
1561 if (!mExpandedVisible) {
1562 return;
1563 }
Daniel Sandlered930e52012-07-03 14:31:22 -04001564
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04001565 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
1566 mStatusBarView.collapseAllPanels(/*animate=*/ false);
Daniel Sandlered930e52012-07-03 14:31:22 -04001567
Daniel Sandler040c2e42012-10-17 00:56:33 -04001568 if (mHasFlipSettings) {
1569 // reset things to their proper state
1570 mScrollView.setScaleX(1f);
1571 mScrollView.setVisibility(View.VISIBLE);
1572 mSettingsButton.setAlpha(1f);
1573 mSettingsButton.setVisibility(View.VISIBLE);
1574 mNotificationPanel.setVisibility(View.GONE);
1575 mFlipSettingsView.setVisibility(View.GONE);
1576 mNotificationButton.setVisibility(View.GONE);
1577 setAreThereNotifications(); // show the clear button
1578 }
1579
Joe Onorato808182d2010-07-09 18:52:06 -04001580 mExpandedVisible = false;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001581 mPile.setLayoutTransitionsEnabled(false);
John Spurlockd5ef5462012-06-13 11:19:51 -04001582 if (mNavigationBarView != null)
1583 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001584 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04001585
1586 // Shrink the window to the size of the status bar only
1587 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
1588 lp.height = getStatusBarHeight();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001589 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1590 lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jeff Brown98365d72012-08-19 20:30:52 -07001591 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04001592
1593 if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
1594 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1595 }
Joe Onorato808182d2010-07-09 18:52:06 -04001596
Daniel Sandler469e96e2012-05-04 15:56:19 -04001597 // Close any "App info" popups that might have snuck on-screen
1598 dismissPopups();
1599
Chet Haase2f2022a2011-10-11 06:41:59 -07001600 if (mPostCollapseCleanup != null) {
1601 mPostCollapseCleanup.run();
1602 mPostCollapseCleanup = null;
1603 }
Joe Onorato808182d2010-07-09 18:52:06 -04001604 }
1605
Romain Guy54ab3472012-06-14 12:52:53 -07001606 /**
1607 * Enables or disables layers on the children of the notifications pile.
1608 *
1609 * When layers are enabled, this method attempts to enable layers for the minimal
1610 * number of children. Only children visible when the notification area is fully
1611 * expanded will receive a layer. The technique used in this method might cause
1612 * more children than necessary to get a layer (at most one extra child with the
1613 * current UI.)
1614 *
1615 * @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE}
1616 */
1617 private void setPileLayers(int layerType) {
1618 final int count = mPile.getChildCount();
1619
1620 switch (layerType) {
1621 case View.LAYER_TYPE_NONE:
1622 for (int i = 0; i < count; i++) {
1623 mPile.getChildAt(i).setLayerType(layerType, null);
1624 }
1625 break;
1626 case View.LAYER_TYPE_HARDWARE:
1627 final int[] location = new int[2];
1628 mNotificationPanel.getLocationInWindow(location);
1629
1630 final int left = location[0];
1631 final int top = location[1];
1632 final int right = left + mNotificationPanel.getWidth();
1633 final int bottom = top + getExpandedViewMaxHeight();
1634
1635 final Rect childBounds = new Rect();
1636
1637 for (int i = 0; i < count; i++) {
1638 final View view = mPile.getChildAt(i);
1639 view.getLocationInWindow(location);
1640
1641 childBounds.set(location[0], location[1],
1642 location[0] + view.getWidth(), location[1] + view.getHeight());
1643
1644 if (childBounds.intersects(left, top, right, bottom)) {
1645 view.setLayerType(layerType, null);
1646 }
1647 }
1648
1649 break;
1650 }
1651 }
1652
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001653 public boolean isClinging() {
1654 return mCling != null && mCling.getVisibility() == View.VISIBLE;
1655 }
1656
1657 public void hideCling() {
1658 if (isClinging()) {
1659 mCling.animate().alpha(0f).setDuration(250).start();
1660 mCling.setVisibility(View.GONE);
1661 mSuppressStatusBarDrags = false;
1662 }
1663 }
1664
1665 public void showCling() {
Daniel Sandler118f4842012-10-07 20:38:39 -04001666 // lazily inflate this to accommodate orientation change
1667 final ViewStub stub = (ViewStub) mStatusBarWindow.findViewById(R.id.status_bar_cling_stub);
1668 if (stub == null) {
1669 mClingShown = true;
1670 return; // no clings on this device
1671 }
1672
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001673 mSuppressStatusBarDrags = true;
1674
1675 mHandler.postDelayed(new Runnable() {
1676 @Override
1677 public void run() {
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001678 mCling = (ViewGroup) stub.inflate();
Daniel Sandler118f4842012-10-07 20:38:39 -04001679
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001680 mCling.setOnTouchListener(new View.OnTouchListener() {
1681 @Override
1682 public boolean onTouch(View v, MotionEvent event) {
1683 return true; // e eats everything
1684 }});
1685 mCling.findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {
1686 @Override
1687 public void onClick(View v) {
1688 hideCling();
1689 }});
1690
1691 mCling.setAlpha(0f);
1692 mCling.setVisibility(View.VISIBLE);
1693 mCling.animate().alpha(1f);
1694
1695 mClingShown = true;
1696 SharedPreferences.Editor editor = Prefs.edit(mContext);
1697 editor.putBoolean(Prefs.SHOWN_QUICK_SETTINGS_HELP, true);
1698 editor.apply();
1699
1700 makeExpandedVisible(true); // enforce visibility in case the shade is still animating closed
1701 animateExpandNotificationsPanel();
1702
1703 mSuppressStatusBarDrags = false;
1704 }
1705 }, 500);
1706
1707 animateExpandNotificationsPanel();
1708 }
1709
1710 public boolean interceptTouchEvent(MotionEvent event) {
Joe Onorato808182d2010-07-09 18:52:06 -04001711 if (SPEW) {
1712 Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
John Spurlock804df702012-06-01 15:34:27 -04001713 + mDisabled + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001714 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001715 if (event.getAction() != MotionEvent.ACTION_MOVE) {
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001716 Slog.d(TAG, String.format(
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001717 "panel: %s at (%f, %f) mDisabled=0x%08x",
1718 MotionEvent.actionToString(event.getAction()),
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001719 event.getRawX(), event.getRawY(), mDisabled));
1720 }
Joe Onorato808182d2010-07-09 18:52:06 -04001721 }
1722
Daniel Sandler151f00d2012-10-02 22:33:08 -04001723 if (DEBUG_GESTURES) {
1724 mGestureRec.add(event);
1725 }
Daniel Sandler33805342012-07-23 15:45:12 -04001726
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001727 // Cling (first-run help) handling.
1728 // The cling is supposed to show the first time you drag, or even tap, the status bar.
1729 // It should show the notification panel, then fade in after half a second, giving you
1730 // an explanation of what just happened, as well as teach you how to access quick
1731 // settings (another drag). The user can dismiss the cling by clicking OK or by
1732 // dragging quick settings into view.
1733 final int act = event.getActionMasked();
1734 if (mSuppressStatusBarDrags) {
1735 return true;
1736 } else if (act == MotionEvent.ACTION_UP && !mClingShown) {
1737 showCling();
1738 } else {
1739 hideCling();
1740 }
1741
Joe Onorato808182d2010-07-09 18:52:06 -04001742 return false;
1743 }
1744
Daniel Sandler08d05e32012-08-08 16:39:54 -04001745 public GestureRecorder getGestureRecorder() {
1746 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07001747 }
1748
Daniel Sandler60ee2562011-07-22 12:34:33 -04001749 @Override // CommandQueue
Daniel Sandler328310c2011-09-23 15:56:52 -04001750 public void setNavigationIconHints(int hints) {
1751 if (hints == mNavigationIconHints) return;
1752
1753 mNavigationIconHints = hints;
1754
1755 if (mNavigationBarView != null) {
1756 mNavigationBarView.setNavigationIconHints(hints);
1757 }
1758 }
1759
1760 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001761 public void setSystemUiVisibility(int vis, int mask) {
1762 final int oldVal = mSystemUiVisibility;
1763 final int newVal = (oldVal&~mask) | (vis&mask);
1764 final int diff = newVal ^ oldVal;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001765
1766 if (diff != 0) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001767 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04001768
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001769 if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
1770 final boolean lightsOut = (0 != (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE));
1771 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001772 animateCollapsePanels();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001773 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001774 haltTicker();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001775 }
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001776 }
Jim Millera073e572012-05-23 17:03:27 -07001777
Daniel Sandler69314e72011-08-20 00:31:08 -04001778 if (mNavigationBarView != null) {
1779 mNavigationBarView.setLowProfile(lightsOut);
1780 }
Jim Millera073e572012-05-23 17:03:27 -07001781
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001782 setStatusBarLowProfile(lightsOut);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001783 }
1784
1785 notifyUiVisibilityChanged();
Joe Onorato93056472010-09-10 10:30:46 -04001786 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001787 }
1788
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001789 private void setStatusBarLowProfile(boolean lightsOut) {
1790 if (mLightsOutAnimation == null) {
Daniel Sandler825b3302012-10-01 15:22:36 -04001791 final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area);
1792 final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons);
1793 final View signal = mStatusBarView.findViewById(R.id.signal_cluster);
1794 final View battery = mStatusBarView.findViewById(R.id.battery);
1795 final View clock = mStatusBarView.findViewById(R.id.clock);
Jim Millera073e572012-05-23 17:03:27 -07001796
Daniel Sandler825b3302012-10-01 15:22:36 -04001797 final AnimatorSet lightsOutAnim = new AnimatorSet();
1798 lightsOutAnim.playTogether(
1799 ObjectAnimator.ofFloat(notifications, View.ALPHA, 0),
1800 ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0),
1801 ObjectAnimator.ofFloat(signal, View.ALPHA, 0),
1802 ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f),
1803 ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
1804 );
1805 lightsOutAnim.setDuration(750);
1806
1807 final AnimatorSet lightsOnAnim = new AnimatorSet();
1808 lightsOnAnim.playTogether(
1809 ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
1810 ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1),
1811 ObjectAnimator.ofFloat(signal, View.ALPHA, 1),
1812 ObjectAnimator.ofFloat(battery, View.ALPHA, 1),
1813 ObjectAnimator.ofFloat(clock, View.ALPHA, 1)
1814 );
1815 lightsOnAnim.setDuration(250);
1816
1817 mLightsOutAnimation = lightsOutAnim;
1818 mLightsOnAnimation = lightsOnAnim;
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001819 }
Jim Millera073e572012-05-23 17:03:27 -07001820
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001821 mLightsOutAnimation.cancel();
1822 mLightsOnAnimation.cancel();
1823
1824 final Animator a = lightsOut ? mLightsOutAnimation : mLightsOnAnimation;
1825 a.start();
1826
1827 setAreThereNotifications();
1828 }
1829
1830 private boolean areLightsOn() {
1831 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
1832 }
Jim Millera073e572012-05-23 17:03:27 -07001833
Daniel Sandler60ee2562011-07-22 12:34:33 -04001834 public void setLightsOn(boolean on) {
1835 Log.v(TAG, "setLightsOn(" + on + ")");
1836 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001837 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001838 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001839 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001840 }
1841 }
1842
1843 private void notifyUiVisibilityChanged() {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001844 try {
Jeff Brown98365d72012-08-19 20:30:52 -07001845 mWindowManagerService.statusBarVisibilityChanged(mSystemUiVisibility);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001846 } catch (RemoteException ex) {
1847 }
Joe Onorato93056472010-09-10 10:30:46 -04001848 }
1849
Daniel Sandler5c8da942011-06-28 00:29:04 -04001850 public void topAppWindowChanged(boolean showMenu) {
1851 if (DEBUG) {
1852 Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
1853 }
1854 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04001855 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04001856 }
1857
1858 // See above re: lights-out policy for legacy apps.
1859 if (showMenu) setLightsOn(true);
1860 }
1861
Daniel Sandler328310c2011-09-23 15:56:52 -04001862 @Override
1863 public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
1864 boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
1865 || ((vis & InputMethodService.IME_VISIBLE) != 0);
1866
1867 mCommandQueue.setNavigationIconHints(
1868 altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
1869 : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
Daniel Sandler101784e2012-10-15 13:39:38 -04001870 if (mQS != null) mQS.setImeWindowStatus(vis > 0);
Daniel Sandler328310c2011-09-23 15:56:52 -04001871 }
1872
Jeff Brown2992ea72011-01-28 22:04:14 -08001873 @Override
Winson Chung43229d72012-09-12 18:04:18 -07001874 public void setHardKeyboardStatus(boolean available, boolean enabled) {}
Daniel Sandlere02d8082010-10-08 15:13:22 -04001875
Chris Wren0c8275b2012-05-08 13:36:48 -04001876 @Override
1877 protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001878 // no ticking in lights-out mode
1879 if (!areLightsOn()) return;
Jim Millera073e572012-05-23 17:03:27 -07001880
Daniel Sandler26cda272012-05-22 15:44:08 -04001881 // no ticking in Setup
1882 if (!isDeviceProvisioned()) return;
1883
John Spurlock61e36832012-09-10 09:43:27 -04001884 // not for you
1885 if (!notificationIsForCurrentUser(n)) return;
1886
Joe Onorato808182d2010-07-09 18:52:06 -04001887 // Show the ticker if one is requested. Also don't do this
1888 // until status bar window is attached to the window manager,
1889 // because... well, what's the point otherwise? And trying to
1890 // run a ticker without being attached will crash!
Daniel Sandlera310af82012-04-24 01:20:13 -04001891 if (n.notification.tickerText != null && mStatusBarWindow.getWindowToken() != null) {
Joe Onorato808182d2010-07-09 18:52:06 -04001892 if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
1893 | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
1894 mTicker.addEntry(n);
1895 }
1896 }
1897 }
1898
Joe Onorato808182d2010-07-09 18:52:06 -04001899 private class MyTicker extends Ticker {
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001900 MyTicker(Context context, View sb) {
Joe Onorato808182d2010-07-09 18:52:06 -04001901 super(context, sb);
1902 }
1903
1904 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001905 public void tickerStarting() {
Joe Onorato808182d2010-07-09 18:52:06 -04001906 mTicking = true;
Daniel Sandler173bae22012-09-25 14:37:42 -04001907 mStatusBarContents.setVisibility(View.GONE);
Joe Onorato808182d2010-07-09 18:52:06 -04001908 mTickerView.setVisibility(View.VISIBLE);
1909 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
Daniel Sandler173bae22012-09-25 14:37:42 -04001910 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
Joe Onorato808182d2010-07-09 18:52:06 -04001911 }
1912
1913 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001914 public void tickerDone() {
Daniel Sandler173bae22012-09-25 14:37:42 -04001915 mStatusBarContents.setVisibility(View.VISIBLE);
Joe Onorato808182d2010-07-09 18:52:06 -04001916 mTickerView.setVisibility(View.GONE);
Daniel Sandler173bae22012-09-25 14:37:42 -04001917 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
Joe Onorato808182d2010-07-09 18:52:06 -04001918 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
1919 mTickingDoneListener));
Joe Onorato808182d2010-07-09 18:52:06 -04001920 }
1921
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001922 public void tickerHalting() {
Daniel Sandler173bae22012-09-25 14:37:42 -04001923 mStatusBarContents.setVisibility(View.VISIBLE);
Joe Onorato808182d2010-07-09 18:52:06 -04001924 mTickerView.setVisibility(View.GONE);
Daniel Sandler173bae22012-09-25 14:37:42 -04001925 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001926 // we do not animate the ticker away at this point, just get rid of it (b/6992707)
Joe Onorato808182d2010-07-09 18:52:06 -04001927 }
1928 }
1929
1930 Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
1931 public void onAnimationEnd(Animation animation) {
1932 mTicking = false;
1933 }
1934 public void onAnimationRepeat(Animation animation) {
1935 }
1936 public void onAnimationStart(Animation animation) {
1937 }
1938 };
1939
1940 private Animation loadAnim(int id, Animation.AnimationListener listener) {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001941 Animation anim = AnimationUtils.loadAnimation(mContext, id);
Joe Onorato808182d2010-07-09 18:52:06 -04001942 if (listener != null) {
1943 anim.setAnimationListener(listener);
1944 }
1945 return anim;
1946 }
1947
Daniel Sandler48852952011-12-01 14:34:23 -05001948 public static String viewInfo(View v) {
1949 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
1950 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04001951 }
1952
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001953 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04001954 synchronized (mQueueLock) {
1955 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001956 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04001957 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04001958 pw.println(" mTicking=" + mTicking);
1959 pw.println(" mTracking=" + mTracking);
Daniel Sandlerfdbac772012-07-03 14:30:10 -04001960 pw.println(" mNotificationPanel=" +
1961 ((mNotificationPanel == null)
1962 ? "null"
1963 : (mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""))));
Joe Onorato808182d2010-07-09 18:52:06 -04001964 pw.println(" mAnimating=" + mAnimating
1965 + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
1966 + ", mAnimAccel=" + mAnimAccel);
Jeff Browned5f45a2012-05-03 15:53:47 -07001967 pw.println(" mAnimLastTimeNanos=" + mAnimLastTimeNanos);
Dianne Hackborn1dacf272011-08-02 15:01:22 -07001968 pw.println(" mAnimatingReveal=" + mAnimatingReveal
Joe Onorato808182d2010-07-09 18:52:06 -04001969 + " mViewDelta=" + mViewDelta);
Daniel Sandler36412a72011-08-04 09:35:13 -04001970 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001971 pw.println(" mPile: " + viewInfo(mPile));
Joe Onorato808182d2010-07-09 18:52:06 -04001972 pw.println(" mTickerView: " + viewInfo(mTickerView));
1973 pw.println(" mScrollView: " + viewInfo(mScrollView)
1974 + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04001975 }
Joe Onorato808182d2010-07-09 18:52:06 -04001976
Daniel Sandler48852952011-12-01 14:34:23 -05001977 pw.print(" mNavigationBarView=");
1978 if (mNavigationBarView == null) {
1979 pw.println("null");
1980 } else {
1981 mNavigationBarView.dump(fd, pw, args);
1982 }
1983
Daniel Sandler7579bca2011-08-18 15:47:26 -04001984 if (DUMPTRUCK) {
1985 synchronized (mNotificationData) {
1986 int N = mNotificationData.size();
1987 pw.println(" notification icons: " + N);
1988 for (int i=0; i<N; i++) {
1989 NotificationData.Entry e = mNotificationData.get(i);
1990 pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
1991 StatusBarNotification n = e.notification;
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001992 pw.println(" pkg=" + n.pkg + " id=" + n.id + " score=" + n.score);
Daniel Sandler7579bca2011-08-18 15:47:26 -04001993 pw.println(" notification=" + n.notification);
1994 pw.println(" tickerText=\"" + n.notification.tickerText + "\"");
1995 }
1996 }
1997
1998 int N = mStatusIcons.getChildCount();
1999 pw.println(" system icons: " + N);
2000 for (int i=0; i<N; i++) {
2001 StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
2002 pw.println(" [" + i + "] icon=" + ic);
2003 }
Jim Miller5e6af442011-12-02 18:24:26 -08002004
Daniel Sandler89d97132011-09-08 15:31:57 -04002005 if (false) {
2006 pw.println("see the logcat for a dump of the views we have created.");
2007 // must happen on ui thread
2008 mHandler.post(new Runnable() {
2009 public void run() {
2010 mStatusBarView.getLocationOnScreen(mAbsPos);
2011 Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
2012 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002013 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002014 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002015 }
2016 });
2017 }
Joe Onorato808182d2010-07-09 18:52:06 -04002018 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002019
Daniel Sandler151f00d2012-10-02 22:33:08 -04002020 if (DEBUG_GESTURES) {
2021 pw.print(" status bar gestures: ");
2022 mGestureRec.dump(fd, pw, args);
2023 }
Daniel Sandler33805342012-07-23 15:45:12 -04002024
Daniel Sandler89d97132011-09-08 15:31:57 -04002025 mNetworkController.dump(fd, pw, args);
Joe Onorato808182d2010-07-09 18:52:06 -04002026 }
2027
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002028 @Override
2029 public void createAndAddWindows() {
2030 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04002031 }
Jim Millere898ac52012-04-06 17:10:57 -07002032
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002033 private void addStatusBarWindow() {
2034 // Put up the view
2035 final int height = getStatusBarHeight();
Joe Onorato808182d2010-07-09 18:52:06 -04002036
Daniel Sandlera310af82012-04-24 01:20:13 -04002037 // Now that the status bar window encompasses the sliding panel and its
2038 // translucent backdrop, the entire thing is made TRANSLUCENT and is
2039 // hardware-accelerated.
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002040 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
2041 ViewGroup.LayoutParams.MATCH_PARENT,
2042 height,
2043 WindowManager.LayoutParams.TYPE_STATUS_BAR,
2044 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
2045 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
2046 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Daniel Sandlera310af82012-04-24 01:20:13 -04002047 PixelFormat.TRANSLUCENT);
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002048
Romain Guy0901fda2012-05-22 21:10:57 -07002049 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002050
2051 lp.gravity = getStatusBarGravity();
2052 lp.setTitle("StatusBar");
2053 lp.packageName = mContext.getPackageName();
Jim Millere898ac52012-04-06 17:10:57 -07002054
Daniel Sandlera310af82012-04-24 01:20:13 -04002055 makeStatusBarView();
Jeff Brown98365d72012-08-19 20:30:52 -07002056 mWindowManager.addView(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04002057 }
2058
Joe Onorato808182d2010-07-09 18:52:06 -04002059 void setNotificationIconVisibility(boolean visible, int anim) {
2060 int old = mNotificationIcons.getVisibility();
2061 int v = visible ? View.VISIBLE : View.INVISIBLE;
2062 if (old != v) {
2063 mNotificationIcons.setVisibility(v);
2064 mNotificationIcons.startAnimation(loadAnim(anim, null));
2065 }
2066 }
2067
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002068 void updateExpandedInvisiblePosition() {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002069 mTrackingPosition = -mDisplayMetrics.heightPixels;
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002070 }
2071
Daniel Sandler1fac1fd2012-04-30 12:07:30 -04002072 static final float saturate(float a) {
2073 return a < 0f ? 0f : (a > 1f ? 1f : a);
2074 }
2075
Chris Wren8fd12652012-05-09 21:25:57 -04002076 @Override
2077 protected int getExpandedViewMaxHeight() {
Daniel Sandler21b274e2012-05-02 15:07:51 -04002078 return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx;
2079 }
2080
Chris Wren0c8275b2012-05-08 13:36:48 -04002081 @Override
Daniel Sandler08d05e32012-08-08 16:39:54 -04002082 public void updateExpandedViewPos(int thingy) {
Daniel Sandler08d05e32012-08-08 16:39:54 -04002083 if (DEBUG) Slog.v(TAG, "updateExpandedViewPos");
Daniel Sandlere680f542012-09-28 12:22:27 -04002084
2085 // on larger devices, the notification panel is propped open a bit
2086 mNotificationPanel.setMinimumHeight(
2087 (int)(mNotificationPanelMinHeightFrac * mCurrentDisplaySize.y));
2088
Daniel Sandler21b274e2012-05-02 15:07:51 -04002089 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams();
Daniel Sandler21b274e2012-05-02 15:07:51 -04002090 lp.gravity = mNotificationPanelGravity;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002091 lp.leftMargin = mNotificationPanelMarginPx;
Daniel Sandler21b274e2012-05-02 15:07:51 -04002092 mNotificationPanel.setLayoutParams(lp);
Daniel Sandlere680f542012-09-28 12:22:27 -04002093
Daniel Sandlere111ad32012-10-13 15:17:45 -04002094 if (mSettingsPanel != null) {
2095 lp = (FrameLayout.LayoutParams) mSettingsPanel.getLayoutParams();
2096 lp.gravity = mSettingsPanelGravity;
2097 lp.rightMargin = mNotificationPanelMarginPx;
2098 mSettingsPanel.setLayoutParams(lp);
2099 }
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002100
2101 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002102 }
2103
Daniel Sandler747a9e92012-08-10 16:39:19 -04002104 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002105 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04002106 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler151f00d2012-10-02 22:33:08 -04002107 if (DEBUG_GESTURES) {
2108 mGestureRec.tag("display",
2109 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2110 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002111 }
2112
Joe Onorato808182d2010-07-09 18:52:06 -04002113 private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
2114 public void onClick(View v) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002115 synchronized (mNotificationData) {
Chet Haase2f2022a2011-10-11 06:41:59 -07002116 // animate-swipe all dismissable notifications, then animate the shade closed
2117 int numChildren = mPile.getChildCount();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002118
Chet Haase2f2022a2011-10-11 06:41:59 -07002119 int scrollTop = mScrollView.getScrollY();
2120 int scrollBottom = scrollTop + mScrollView.getHeight();
2121 final ArrayList<View> snapshot = new ArrayList<View>(numChildren);
2122 for (int i=0; i<numChildren; i++) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002123 final View child = mPile.getChildAt(i);
Chet Haase2f2022a2011-10-11 06:41:59 -07002124 if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop &&
2125 child.getTop() < scrollBottom) {
2126 snapshot.add(child);
2127 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002128 }
Craig Mautner93a035c2012-04-09 15:23:59 -07002129 if (snapshot.isEmpty()) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002130 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Craig Mautner93a035c2012-04-09 15:23:59 -07002131 return;
2132 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002133 new Thread(new Runnable() {
2134 @Override
2135 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07002136 // Decrease the delay for every row we animate to give the sense of
2137 // accelerating the swipes
2138 final int ROW_DELAY_DECREMENT = 10;
2139 int currentDelay = 140;
2140 int totalDelay = 0;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002141
Chet Haase2f2022a2011-10-11 06:41:59 -07002142 // Set the shade-animating state to avoid doing other work during
2143 // all of these animations. In particular, avoid layout and
2144 // redrawing when collapsing the shade.
2145 mPile.setViewRemoval(false);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002146
Chet Haase2f2022a2011-10-11 06:41:59 -07002147 mPostCollapseCleanup = new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07002148 @Override
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002149 public void run() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002150 if (DEBUG) {
2151 Slog.v(TAG, "running post-collapse cleanup");
2152 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002153 try {
Chet Haase2f2022a2011-10-11 06:41:59 -07002154 mPile.setViewRemoval(true);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002155 mBarService.onClearAllNotifications();
Chet Haase2f2022a2011-10-11 06:41:59 -07002156 } catch (Exception ex) { }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002157 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002158 };
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002159
Chet Haase2f2022a2011-10-11 06:41:59 -07002160 View sampleView = snapshot.get(0);
2161 int width = sampleView.getWidth();
Craig Mautner93a035c2012-04-09 15:23:59 -07002162 final int velocity = width * 8; // 1000/8 = 125 ms duration
2163 for (final View _v : snapshot) {
Chet Haase2f2022a2011-10-11 06:41:59 -07002164 mHandler.postDelayed(new Runnable() {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002165 @Override
2166 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07002167 mPile.dismissRowAnimated(_v, velocity);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002168 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002169 }, totalDelay);
2170 currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT);
2171 totalDelay += currentDelay;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002172 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002173 // Delay the collapse animation until after all swipe animations have
2174 // finished. Provide some buffer because there may be some extra delay
2175 // before actually starting each swipe animation. Ideally, we'd
2176 // synchronize the end of those animations with the start of the collaps
2177 // exactly.
2178 mHandler.postDelayed(new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07002179 @Override
Chet Haase2f2022a2011-10-11 06:41:59 -07002180 public void run() {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002181 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Chet Haase2f2022a2011-10-11 06:41:59 -07002182 }
2183 }, totalDelay + 225);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002184 }
2185 }).start();
Joe Onorato808182d2010-07-09 18:52:06 -04002186 }
Joe Onorato808182d2010-07-09 18:52:06 -04002187 }
2188 };
2189
Daniel Sandler3679bf52012-10-16 21:30:28 -04002190 public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
2191 if (onlyProvisioned && !isDeviceProvisioned()) return;
2192 try {
2193 // Dismiss the lock screen when Settings starts.
2194 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
2195 } catch (RemoteException e) {
2196 }
2197 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2198 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
2199 animateCollapsePanels();
2200 }
2201
Daniel Sandlerd3090562011-08-09 00:28:44 -04002202 private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
2203 public void onClick(View v) {
Daniel Sandlere111ad32012-10-13 15:17:45 -04002204 if (mHasSettingsPanel) {
2205 animateExpandSettingsPanel();
2206 } else {
Daniel Sandler3679bf52012-10-16 21:30:28 -04002207 startActivityDismissingKeyguard(
2208 new Intent(android.provider.Settings.ACTION_SETTINGS), true);
Daniel Sandlere111ad32012-10-13 15:17:45 -04002209 }
Daniel Sandlerd3090562011-08-09 00:28:44 -04002210 }
2211 };
2212
Daniel Sandler3679bf52012-10-16 21:30:28 -04002213 private View.OnClickListener mClockClickListener = new View.OnClickListener() {
2214 public void onClick(View v) {
2215 startActivityDismissingKeyguard(
2216 new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone
2217 }
2218 };
2219
Daniel Sandler101784e2012-10-15 13:39:38 -04002220 private View.OnClickListener mNotificationButtonListener = new View.OnClickListener() {
2221 public void onClick(View v) {
2222 animateExpandNotificationsPanel();
2223 }
2224 };
2225
Joe Onorato808182d2010-07-09 18:52:06 -04002226 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2227 public void onReceive(Context context, Intent intent) {
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002228 Slog.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04002229 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04002230 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Jim Miller9a720f52012-05-30 03:19:43 -07002231 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002232 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Daniel Sandleredbdd3a2011-06-21 12:57:08 -04002233 String reason = intent.getStringExtra("reason");
Jim Miller9a720f52012-05-30 03:19:43 -07002234 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
2235 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002236 }
2237 }
Daniel Sandler11cf1782012-09-27 14:03:08 -04002238 animateCollapsePanels(flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002239 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002240 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
2241 // no waiting!
Daniel Sandler08d05e32012-08-08 16:39:54 -04002242 makeExpandedInvisible();
Daniel Sandlered930e52012-07-03 14:31:22 -04002243 }
Joe Onorato808182d2010-07-09 18:52:06 -04002244 else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002245 if (DEBUG) {
2246 Slog.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
2247 }
Daniel Sandlere680f542012-09-28 12:22:27 -04002248 mDisplay.getSize(mCurrentDisplaySize);
2249
Joe Onorato808182d2010-07-09 18:52:06 -04002250 updateResources();
Daniel Sandler21b274e2012-05-02 15:07:51 -04002251 repositionNavigationBar();
2252 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002253 updateShowSearchHoldoff();
2254 }
2255 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
2256 // work around problem where mDisplay.getRotation() is not stable while screen is off (bug 7086018)
2257 repositionNavigationBar();
Joe Onorato808182d2010-07-09 18:52:06 -04002258 }
2259 }
2260 };
2261
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002262 @Override
2263 public void userSwitched(int newUserId) {
2264 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002265 animateCollapsePanels();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002266 updateNotificationIcons();
John Spurlock919adac2012-10-02 16:41:12 -04002267 resetUserSetupObserver();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002268 }
John Spurlock919adac2012-10-02 16:41:12 -04002269
2270 private void resetUserSetupObserver() {
2271 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
2272 mUserSetupObserver.onChange(false);
2273 mContext.getContentResolver().registerContentObserver(
2274 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
2275 mUserSetupObserver,
2276 mCurrentUserId);
2277 }
2278
Joe Onorato808182d2010-07-09 18:52:06 -04002279 private void setIntruderAlertVisibility(boolean vis) {
Daniel Sandler6b318802012-04-13 14:05:19 -04002280 if (!ENABLE_INTRUDERS) return;
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04002281 if (DEBUG) {
2282 Slog.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
2283 }
Joe Onorato808182d2010-07-09 18:52:06 -04002284 mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
2285 }
2286
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04002287 public void dismissIntruder() {
2288 if (mCurrentlyIntrudingNotification == null) return;
2289
2290 try {
2291 mBarService.onNotificationClear(
2292 mCurrentlyIntrudingNotification.pkg,
Jim Millera073e572012-05-23 17:03:27 -07002293 mCurrentlyIntrudingNotification.tag,
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04002294 mCurrentlyIntrudingNotification.id);
2295 } catch (android.os.RemoteException ex) {
2296 // oh well
2297 }
2298 }
Jim Millere898ac52012-04-06 17:10:57 -07002299
Joe Onorato808182d2010-07-09 18:52:06 -04002300 /**
2301 * Reload some of our resources when the configuration changes.
2302 *
2303 * We don't reload everything when the configuration changes -- we probably
2304 * should, but getting that smooth is tough. Someday we'll fix that. In the
2305 * meantime, just update the things that we know change.
2306 */
2307 void updateResources() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002308 final Context context = mContext;
2309 final Resources res = context.getResources();
Joe Onorato808182d2010-07-09 18:52:06 -04002310
Daniel Sandler1347c302011-08-01 16:47:53 -04002311 if (mClearButton instanceof TextView) {
2312 ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
2313 }
Winson Chungd63c59782012-09-05 17:34:41 -07002314
2315 // Update the QuickSettings container
Daniel Sandler101784e2012-10-15 13:39:38 -04002316 if (mQS != null) mQS.updateResources();
Winson Chungd63c59782012-09-05 17:34:41 -07002317
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002318 loadDimens();
2319 }
Jim Miller5e6af442011-12-02 18:24:26 -08002320
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002321 protected void loadDimens() {
2322 final Resources res = mContext.getResources();
2323
2324 mNaturalBarHeight = res.getDimensionPixelSize(
2325 com.android.internal.R.dimen.status_bar_height);
2326
2327 int newIconSize = res.getDimensionPixelSize(
2328 com.android.internal.R.dimen.status_bar_icon_size);
2329 int newIconHPadding = res.getDimensionPixelSize(
2330 R.dimen.status_bar_icon_padding);
2331
2332 if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
2333// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
2334 mIconHPadding = newIconHPadding;
2335 mIconSize = newIconSize;
2336 //reloadAllNotificationIcons(); // reload the tray
2337 }
2338
Joe Onorato808182d2010-07-09 18:52:06 -04002339 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
2340
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002341 mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
2342 mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
2343 mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
2344 mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
2345
2346 mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
2347 mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
2348
2349 mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
2350 mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
2351
2352 mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
Jim Millera073e572012-05-23 17:03:27 -07002353
Daniel Sandlere5011a32012-06-11 16:07:52 -04002354 mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity);
2355
Daniel Sandler21b274e2012-05-02 15:07:51 -04002356 mNotificationPanelMarginBottomPx
2357 = (int) res.getDimension(R.dimen.notification_panel_margin_bottom);
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002358 mNotificationPanelMarginPx
Daniel Sandler21b274e2012-05-02 15:07:51 -04002359 = (int) res.getDimension(R.dimen.notification_panel_margin_left);
2360 mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
2361 if (mNotificationPanelGravity <= 0) {
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002362 mNotificationPanelGravity = Gravity.LEFT | Gravity.TOP;
2363 }
2364 mSettingsPanelGravity = res.getInteger(R.integer.settings_panel_layout_gravity);
2365 if (mSettingsPanelGravity <= 0) {
2366 mSettingsPanelGravity = Gravity.RIGHT | Gravity.TOP;
Daniel Sandler21b274e2012-05-02 15:07:51 -04002367 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04002368
2369 mCarrierLabelHeight = res.getDimensionPixelSize(R.dimen.carrier_label_height);
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002370 mNotificationHeaderHeight = res.getDimensionPixelSize(R.dimen.notification_panel_header_height);
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002371
Daniel Sandlere680f542012-09-28 12:22:27 -04002372 mNotificationPanelMinHeightFrac = res.getFraction(R.dimen.notification_panel_min_height_frac, 1, 1);
2373 if (mNotificationPanelMinHeightFrac < 0f || mNotificationPanelMinHeightFrac > 1f) {
2374 mNotificationPanelMinHeightFrac = 0f;
John Spurlock804df702012-06-01 15:34:27 -04002375 }
Daniel Sandlere680f542012-09-28 12:22:27 -04002376
2377 if (false) Slog.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04002378 }
2379
Joe Onorato808182d2010-07-09 18:52:06 -04002380 //
2381 // tracing
2382 //
2383
2384 void postStartTracing() {
2385 mHandler.postDelayed(mStartTracing, 3000);
2386 }
2387
2388 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002389 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
2390 Context.VIBRATOR_SERVICE);
Joe Onorato808182d2010-07-09 18:52:06 -04002391 vib.vibrate(250);
2392 }
2393
2394 Runnable mStartTracing = new Runnable() {
2395 public void run() {
2396 vibrate();
2397 SystemClock.sleep(250);
2398 Slog.d(TAG, "startTracing");
2399 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2400 mHandler.postDelayed(mStopTracing, 10000);
2401 }
2402 };
2403
2404 Runnable mStopTracing = new Runnable() {
2405 public void run() {
2406 android.os.Debug.stopMethodTracing();
2407 Slog.d(TAG, "stopTracing");
2408 vibrate();
2409 }
2410 };
Chris Wren0c8275b2012-05-08 13:36:48 -04002411
2412 @Override
2413 protected void haltTicker() {
2414 mTicker.halt();
2415 }
Jim Miller670d9dd2012-05-12 13:28:26 -07002416
2417 @Override
Jim Millerb4238e02012-05-14 15:26:20 -07002418 protected boolean shouldDisableNavbarGestures() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002419 return mExpandedVisible || (mDisabled & StatusBarManager.DISABLE_HOME) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07002420 }
Joe Onorato808182d2010-07-09 18:52:06 -04002421
Romain Guy648342f2012-05-25 10:44:45 -07002422 private static class FastColorDrawable extends Drawable {
2423 private final int mColor;
2424
2425 public FastColorDrawable(int color) {
2426 mColor = 0xff000000 | color;
2427 }
2428
2429 @Override
2430 public void draw(Canvas canvas) {
2431 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
2432 }
2433
2434 @Override
2435 public void setAlpha(int alpha) {
2436 }
2437
2438 @Override
2439 public void setColorFilter(ColorFilter cf) {
2440 }
2441
2442 @Override
2443 public int getOpacity() {
2444 return PixelFormat.OPAQUE;
2445 }
2446
2447 @Override
2448 public void setBounds(int left, int top, int right, int bottom) {
2449 }
2450
2451 @Override
2452 public void setBounds(Rect bounds) {
2453 }
2454 }
2455}