blob: 3aa81ea6b8d031010b2a553f99dc549a46fb7dab [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;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070023import android.app.ActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040024import android.app.ActivityManagerNative;
Joe Onorato808182d2010-07-09 18:52:06 -040025import android.app.Notification;
26import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040027import android.app.StatusBarManager;
28import android.content.BroadcastReceiver;
29import android.content.Context;
30import android.content.Intent;
31import android.content.IntentFilter;
Michael Jurka7f2668c2012-03-27 07:49:52 -070032import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040033import android.database.ContentObserver;
Romain Guy648342f2012-05-25 10:44:45 -070034import android.graphics.Canvas;
35import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040036import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040037import android.graphics.Point;
Romain Guy648342f2012-05-25 10:44:45 -070038import android.graphics.PorterDuff;
Joe Onorato808182d2010-07-09 18:52:06 -040039import android.graphics.Rect;
Romain Guy648342f2012-05-25 10:44:45 -070040import android.graphics.drawable.Drawable;
John Spurlock804df702012-06-01 15:34:27 -040041import android.graphics.drawable.NinePatchDrawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070042import android.inputmethodservice.InputMethodService;
John Spurlock919adac2012-10-02 16:41:12 -040043import android.os.Handler;
Joe Onorato808182d2010-07-09 18:52:06 -040044import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040045import android.os.Message;
Michael Jurka7f2668c2012-03-27 07:49:52 -070046import android.os.RemoteException;
Daniel Sandler1d4d30a2011-04-28 12:35:29 -040047import android.os.ServiceManager;
Joe Onorato808182d2010-07-09 18:52:06 -040048import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070049import android.os.UserHandle;
Daniel Sandlerd3090562011-08-09 00:28:44 -040050import android.provider.Settings;
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -070051import android.service.dreams.DreamService;
Daniel Sandlera2fbe532012-08-10 01:19:03 -040052import android.service.dreams.IDreamManager;
Daniel Sandler36412a72011-08-04 09:35:13 -040053import android.util.DisplayMetrics;
Joe Onorato808182d2010-07-09 18:52:06 -040054import android.util.Log;
Michael Jurka7f2668c2012-03-27 07:49:52 -070055import android.util.Slog;
Joe Onorato808182d2010-07-09 18:52:06 -040056import android.view.Display;
57import android.view.Gravity;
Joe Onorato808182d2010-07-09 18:52:06 -040058import android.view.MotionEvent;
59import android.view.VelocityTracker;
60import android.view.View;
61import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -070062import android.view.ViewGroup.LayoutParams;
Joe Onorato808182d2010-07-09 18:52:06 -040063import android.view.WindowManager;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040064import android.view.animation.AccelerateInterpolator;
Joe Onorato808182d2010-07-09 18:52:06 -040065import android.view.animation.Animation;
66import android.view.animation.AnimationUtils;
Daniel Sandler67e7d902012-06-06 16:32:21 -040067import android.view.animation.DecelerateInterpolator;
Daniel Sandler21b274e2012-05-02 15:07:51 -040068import android.widget.FrameLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040069import android.widget.ImageView;
70import android.widget.LinearLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040071import android.widget.ScrollView;
72import android.widget.TextView;
Michael Jurkaa600fd92012-06-25 15:57:05 -070073
Joe Onorato808182d2010-07-09 18:52:06 -040074import com.android.internal.statusbar.StatusBarIcon;
Joe Onorato808182d2010-07-09 18:52:06 -040075import com.android.internal.statusbar.StatusBarNotification;
Joe Onorato808182d2010-07-09 18:52:06 -040076import com.android.systemui.R;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -050077import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -070078import com.android.systemui.statusbar.CommandQueue;
Daniel Sandler33805342012-07-23 15:45:12 -040079import com.android.systemui.statusbar.GestureRecorder;
Michael Jurka7f2668c2012-03-27 07:49:52 -070080import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -040081import com.android.systemui.statusbar.NotificationData.Entry;
Christian Robertson2e347422011-08-11 14:01:04 -070082import com.android.systemui.statusbar.SignalClusterView;
Michael Jurka7f2668c2012-03-27 07:49:52 -070083import com.android.systemui.statusbar.StatusBarIconView;
Daniel Sandler2b697352011-07-22 16:23:09 -040084import com.android.systemui.statusbar.policy.BatteryController;
Winson Chungd63c59782012-09-05 17:34:41 -070085import com.android.systemui.statusbar.policy.BluetoothController;
Michael Jurka7f2668c2012-03-27 07:49:52 -070086import com.android.systemui.statusbar.policy.DateView;
Daniel Sandler6a858c32012-03-12 14:38:58 -040087import com.android.systemui.statusbar.policy.IntruderAlertView;
Daniel Sandler2b697352011-07-22 16:23:09 -040088import com.android.systemui.statusbar.policy.LocationController;
89import com.android.systemui.statusbar.policy.NetworkController;
Daniel Sandler8ba33c92011-10-04 21:49:30 -040090import com.android.systemui.statusbar.policy.NotificationRowLayout;
Michael Jurkaa600fd92012-06-25 15:57:05 -070091import com.android.systemui.statusbar.policy.OnSizeChangedListener;
Joe Onorato808182d2010-07-09 18:52:06 -040092
Daniel Sandler6a858c32012-03-12 14:38:58 -040093import java.io.FileDescriptor;
94import java.io.PrintWriter;
95import java.util.ArrayList;
96
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -050097public class PhoneStatusBar extends BaseStatusBar {
Joe Onoratofd52b182010-11-10 18:00:52 -080098 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -040099 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Daniel Sandlerc1ebee42012-03-26 19:39:46 -0400100 public static final boolean SPEW = DEBUG;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400101 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandler151f00d2012-10-02 22:33:08 -0400102 public static final boolean DEBUG_GESTURES = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400103
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400104 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400105 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400106
Joe Onorato808182d2010-07-09 18:52:06 -0400107 public static final String ACTION_STATUSBAR_START
108 = "com.android.internal.policy.statusbar.START";
109
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400110 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400111 private static final int MSG_CLOSE_PANELS = 1001;
112 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700113 // 1020-1030 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400114
115 // will likely move to a resource or other tunable param at some point
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400116 private static final int INTRUDER_ALERT_DECAY_MS = 0; // disabled, was 10000;
Joe Onorato808182d2010-07-09 18:52:06 -0400117
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400118 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
119
Daniel Sandler58b173b2012-05-03 11:25:29 -0400120 private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
121 private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
122
Daniel Sandlerdc940ea2011-08-25 14:35:53 -0700123 // fling gesture tuning parameters, scaled to display density
124 private float mSelfExpandVelocityPx; // classic value: 2000px/s
125 private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
126 private float mFlingExpandMinVelocityPx; // classic value: 200px/s
127 private float mFlingCollapseMinVelocityPx; // classic value: 200px/s
128 private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1)
129 private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
130 private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s
131
132 private float mExpandAccelPx; // classic value: 2000px/s/s
133 private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
134
Daniel Sandlere5011a32012-06-11 16:07:52 -0400135 private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little
136 // faster than mSelfCollapseVelocityPx)
137
Joe Onoratofd52b182010-11-10 18:00:52 -0800138 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400139
Daniel Sandler2b697352011-07-22 16:23:09 -0400140 // These are no longer handled by the policy, because we need custom strategies for them
Winson Chungd63c59782012-09-05 17:34:41 -0700141 BluetoothController mBluetoothController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400142 BatteryController mBatteryController;
143 LocationController mLocationController;
144 NetworkController mNetworkController;
Jim Miller5e6af442011-12-02 18:24:26 -0800145
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400146 int mNaturalBarHeight = -1;
147 int mIconSize = -1;
148 int mIconHPadding = -1;
Joe Onorato808182d2010-07-09 18:52:06 -0400149 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400150 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400151
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400152 IDreamManager mDreamManager;
Daniel Sandler1d4d30a2011-04-28 12:35:29 -0400153
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400154 StatusBarWindowView mStatusBarWindow;
Joe Onoratofd52b182010-11-10 18:00:52 -0800155 PhoneStatusBarView mStatusBarView;
Daniel Sandlera310af82012-04-24 01:20:13 -0400156
Joe Onorato808182d2010-07-09 18:52:06 -0400157 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400158 Object mQueueLock = new Object();
159
Daniel Sandler173bae22012-09-25 14:37:42 -0400160 // viewgroup containing the normal contents of the statusbar
161 LinearLayout mStatusBarContents;
162
163 // right-hand icons
164 LinearLayout mSystemIconArea;
165
166 // left-hand icons
Joe Onorato808182d2010-07-09 18:52:06 -0400167 LinearLayout mStatusIcons;
Daniel Sandler173bae22012-09-25 14:37:42 -0400168 // the icons themselves
169 IconMerger mNotificationIcons;
170 // [+>
171 View mMoreIcon;
Joe Onorato808182d2010-07-09 18:52:06 -0400172
173 // expanded notifications
Daniel Sandler08d05e32012-08-08 16:39:54 -0400174 PanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400175 ScrollView mScrollView;
Joe Onorato808182d2010-07-09 18:52:06 -0400176 View mExpandedContents;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400177 int mNotificationPanelGravity;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400178 int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx;
Daniel Sandlere680f542012-09-28 12:22:27 -0400179 float mNotificationPanelMinHeightFrac;
Daniel Sandler66d92f82012-06-13 13:36:52 -0400180 boolean mNotificationPanelIsFullScreenWidth;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400181 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400182
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400183 // settings
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400184 SettingsPanelView mSettingsPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400185 int mSettingsPanelGravity;
186
Joe Onorato808182d2010-07-09 18:52:06 -0400187 // top bar
Daniel Sandler1347c302011-08-01 16:47:53 -0400188 View mClearButton;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400189 View mSettingsButton;
190
Daniel Sandler3d32a242012-06-05 13:44:14 -0400191 // carrier/wifi label
192 private TextView mCarrierLabel;
193 private boolean mCarrierLabelVisible = false;
194 private int mCarrierLabelHeight;
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400195 private TextView mEmergencyCallLabel;
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400196 private int mNotificationHeaderHeight;
197
198 private boolean mShowCarrierInPanel = false;
Daniel Sandler3d32a242012-06-05 13:44:14 -0400199
Joe Onorato808182d2010-07-09 18:52:06 -0400200 // position
201 int[] mPositionTmp = new int[2];
Joe Onorato808182d2010-07-09 18:52:06 -0400202 boolean mExpandedVisible;
203
204 // the date view
205 DateView mDateView;
206
207 // for immersive activities
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400208 private IntruderAlertView mIntruderAlertView;
Joe Onorato808182d2010-07-09 18:52:06 -0400209
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400210 // on-screen navigation buttons
Daniel Sandler0129b312011-05-11 11:54:11 -0400211 private NavigationBarView mNavigationBarView = null;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400212
Joe Onorato808182d2010-07-09 18:52:06 -0400213 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400214 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400215
216 // ticker
217 private Ticker mTicker;
218 private View mTickerView;
219 private boolean mTicking;
220
221 // Tracking finger for opening/closing.
222 int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
223 boolean mTracking;
224 VelocityTracker mVelocityTracker;
225
Joe Onorato808182d2010-07-09 18:52:06 -0400226 boolean mAnimating;
Daniel Sandlerfbab8ae2012-05-09 02:06:29 -0400227 boolean mClosing; // only valid when mAnimating; indicates the initial acceleration
Joe Onorato808182d2010-07-09 18:52:06 -0400228 float mAnimY;
229 float mAnimVel;
230 float mAnimAccel;
Jeff Browned5f45a2012-05-03 15:53:47 -0700231 long mAnimLastTimeNanos;
Joe Onorato808182d2010-07-09 18:52:06 -0400232 boolean mAnimatingReveal = false;
233 int mViewDelta;
John Spurlock804df702012-06-01 15:34:27 -0400234 float mFlingVelocity;
235 int mFlingY;
Joe Onorato808182d2010-07-09 18:52:06 -0400236 int[] mAbsPos = new int[2];
Chet Haase2f2022a2011-10-11 06:41:59 -0700237 Runnable mPostCollapseCleanup = null;
238
Daniel Sandler173bae22012-09-25 14:37:42 -0400239 private Animator mLightsOutAnimation;
240 private Animator mLightsOnAnimation;
Joe Onorato808182d2010-07-09 18:52:06 -0400241
242 // for disabling the status bar
243 int mDisabled = 0;
244
Daniel Sandler60ee2562011-07-22 12:34:33 -0400245 // tracking calls to View.setSystemUiVisibility()
246 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
247
Daniel Sandler36412a72011-08-04 09:35:13 -0400248 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700249
Daniel Sandler33805342012-07-23 15:45:12 -0400250 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400251 private final GestureRecorder mGestureRec = DEBUG_GESTURES
252 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
253 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400254
Daniel Sandler328310c2011-09-23 15:56:52 -0400255 private int mNavigationIconHints = 0;
Romain Guyf7f16f72012-05-24 19:13:56 -0700256 private final Animator.AnimatorListener mMakeIconsInvisible = new AnimatorListenerAdapter() {
257 @Override
258 public void onAnimationEnd(Animator animation) {
Daniel Sandler67e7d902012-06-06 16:32:21 -0400259 // double-check to avoid races
Daniel Sandler173bae22012-09-25 14:37:42 -0400260 if (mStatusBarContents.getAlpha() == 0) {
Daniel Sandler67e7d902012-06-06 16:32:21 -0400261 Slog.d(TAG, "makeIconsInvisible");
Daniel Sandler173bae22012-09-25 14:37:42 -0400262 mStatusBarContents.setVisibility(View.INVISIBLE);
Daniel Sandler67e7d902012-06-06 16:32:21 -0400263 }
Romain Guyf7f16f72012-05-24 19:13:56 -0700264 }
265 };
Daniel Sandler328310c2011-09-23 15:56:52 -0400266
John Spurlock919adac2012-10-02 16:41:12 -0400267 // ensure quick settings is disabled until the current user makes it through the setup wizard
268 private boolean mUserSetup = false;
269 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
270 @Override
271 public void onChange(boolean selfChange) {
272 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
273 mContext.getContentResolver(),
274 Settings.Secure.USER_SETUP_COMPLETE,
275 0 /*default */,
276 mCurrentUserId);
John Spurlocke4e8c562012-10-04 09:55:01 -0400277 if (MULTIUSER_DEBUG) Slog.d(TAG, String.format("User setup changed: " +
278 "selfChange=%s userSetup=%s mUserSetup=%s",
279 selfChange, userSetup, mUserSetup));
280 if (mSettingsPanel != null)
281 mSettingsPanel.setEnabled(userSetup);
John Spurlock919adac2012-10-02 16:41:12 -0400282 if (userSetup != mUserSetup) {
283 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400284 if (!mUserSetup && mStatusBarView != null)
285 animateCollapseQuickSettings();
286 }
287 }
288 };
289
Joe Onorato808182d2010-07-09 18:52:06 -0400290 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400291 public void start() {
292 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
293 .getDefaultDisplay();
Joe Onorato808182d2010-07-09 18:52:06 -0400294
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400295 mDreamManager = IDreamManager.Stub.asInterface(
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -0700296 ServiceManager.checkService(DreamService.DREAM_SERVICE));
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400297
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500298 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400299
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400300 addNavigationBar();
301
Daniel Sandlerfc6fda32012-02-24 22:00:46 -0500302 if (ENABLE_INTRUDERS) addIntruderView();
Joe Onorato808182d2010-07-09 18:52:06 -0400303
304 // Lastly, call to the icon policy to install/update all the icons.
Joe Onoratofd52b182010-11-10 18:00:52 -0800305 mIconPolicy = new PhoneStatusBarPolicy(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400306 }
307
308 // ================================================================================
309 // Constructing the view
310 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700311 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400312 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400313
314 Resources res = context.getResources();
315
Daniel Sandler6e8db882011-10-26 15:40:51 -0400316 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400317 loadDimens();
Joe Onorato808182d2010-07-09 18:52:06 -0400318
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700319 mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
320
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400321 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
Daniel Sandlera310af82012-04-24 01:20:13 -0400322 R.layout.super_status_bar, null);
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400323 mStatusBarWindow.mService = this;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400324 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
325 @Override
326 public boolean onTouch(View v, MotionEvent event) {
327 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandlere7237fc2012-08-14 16:08:27 -0400328 if (mExpandedVisible && !mAnimating) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400329 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400330 }
331 }
Chris Wren5de6e942012-05-16 14:22:21 -0400332 return mStatusBarWindow.onTouchEvent(event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400333 }});
334
Daniel Sandlera310af82012-04-24 01:20:13 -0400335 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400336 mStatusBarView.setBar(this);
337
338 PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
339 mStatusBarView.setPanelHolder(holder);
340
341 mNotificationPanel = (PanelView) mStatusBarWindow.findViewById(R.id.notification_panel);
Daniel Sandler66d92f82012-06-13 13:36:52 -0400342 mNotificationPanelIsFullScreenWidth =
343 (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
Daniel Sandler8e18dc72012-05-17 00:44:59 -0400344 mNotificationPanel.setSystemUiVisibility(
Chris Wren85db8032012-10-03 17:03:15 -0400345 View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER |
346 View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
347 View.STATUS_BAR_DISABLE_CLOCK);
Joe Onorato808182d2010-07-09 18:52:06 -0400348
Jeff Brown98365d72012-08-19 20:30:52 -0700349 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700350 mStatusBarWindow.setBackground(null);
Romain Guy648342f2012-05-25 10:44:45 -0700351 mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
352 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700353 }
Daniel Sandler6b318802012-04-13 14:05:19 -0400354 if (ENABLE_INTRUDERS) {
355 mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
356 mIntruderAlertView.setVisibility(View.GONE);
357 mIntruderAlertView.setBar(this);
358 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400359 if (MULTIUSER_DEBUG) {
360 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info);
361 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
362 }
Joe Onorato808182d2010-07-09 18:52:06 -0400363
John Spurlockd5ef5462012-06-13 11:19:51 -0400364 updateShowSearchHoldoff();
365
Daniel Sandler0129b312011-05-11 11:54:11 -0400366 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700367 boolean showNav = mWindowManagerService.hasNavigationBar();
Daniel Sandler4a066c52012-04-20 14:49:13 -0400368 if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400369 if (showNav) {
Jim Miller5e6af442011-12-02 18:24:26 -0800370 mNavigationBarView =
Daniel Sandler0129b312011-05-11 11:54:11 -0400371 (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400372
Daniel Sandler6da2b762011-09-14 16:04:59 -0400373 mNavigationBarView.setDisabledFlags(mDisabled);
Jim Millere898ac52012-04-06 17:10:57 -0700374 mNavigationBarView.setBar(this);
Daniel Sandler0129b312011-05-11 11:54:11 -0400375 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400376 } catch (RemoteException ex) {
377 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400378 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400379
Joe Onorato808182d2010-07-09 18:52:06 -0400380 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400381 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400382
383 mSystemIconArea = (LinearLayout) mStatusBarView.findViewById(R.id.system_icon_area);
Daniel Sandlera310af82012-04-24 01:20:13 -0400384 mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons);
385 mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
Daniel Sandler05e24142011-11-10 11:56:49 -0500386 mNotificationIcons.setOverflowIndicator(mMoreIcon);
Daniel Sandler173bae22012-09-25 14:37:42 -0400387 mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
Daniel Sandlera310af82012-04-24 01:20:13 -0400388 mTickerView = mStatusBarView.findViewById(R.id.ticker);
Joe Onorato808182d2010-07-09 18:52:06 -0400389
Daniel Sandlera310af82012-04-24 01:20:13 -0400390 mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems);
Daniel Sandlere5011a32012-06-11 16:07:52 -0400391 mPile.setLayoutTransitionsEnabled(false);
Daniel Sandlerf7a19562012-04-04 14:04:21 -0400392 mPile.setLongPressListener(getNotificationLongClicker());
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400393 mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
Daniel Sandlerd7141482011-08-18 15:14:52 -0400394
Daniel Sandlera310af82012-04-24 01:20:13 -0400395 mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button);
Joe Onorato808182d2010-07-09 18:52:06 -0400396 mClearButton.setOnClickListener(mClearButtonListener);
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400397 mClearButton.setAlpha(0f);
Romain Guy8900e632012-05-25 12:08:39 -0700398 mClearButton.setVisibility(View.INVISIBLE);
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400399 mClearButton.setEnabled(false);
Daniel Sandlera310af82012-04-24 01:20:13 -0400400 mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
401 mSettingsButton = mStatusBarWindow.findViewById(R.id.settings_button);
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400402 if (mSettingsButton != null) {
403 mSettingsButton.setOnClickListener(mSettingsButtonListener);
404 }
Daniel Sandler3d32a242012-06-05 13:44:14 -0400405
Daniel Sandlera310af82012-04-24 01:20:13 -0400406 mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll);
Daniel Sandler079b33d2012-03-02 16:29:41 -0500407 mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
Joe Onorato808182d2010-07-09 18:52:06 -0400408
Daniel Sandlera310af82012-04-24 01:20:13 -0400409 mTicker = new MyTicker(context, mStatusBarView);
Joe Onorato808182d2010-07-09 18:52:06 -0400410
Daniel Sandlera310af82012-04-24 01:20:13 -0400411 TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText);
Joe Onorato808182d2010-07-09 18:52:06 -0400412 tickerView.mTicker = mTicker;
413
Joe Onorato808182d2010-07-09 18:52:06 -0400414 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
415
Joe Onorato808182d2010-07-09 18:52:06 -0400416 // set the inital view visibility
417 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400418
Daniel Sandler2b697352011-07-22 16:23:09 -0400419 // Other icons
420 mLocationController = new LocationController(mContext); // will post a notification
421 mBatteryController = new BatteryController(mContext);
Daniel Sandlera310af82012-04-24 01:20:13 -0400422 mBatteryController.addIconView((ImageView)mStatusBarView.findViewById(R.id.battery));
Daniel Sandler2b697352011-07-22 16:23:09 -0400423 mNetworkController = new NetworkController(mContext);
Winson Chungd63c59782012-09-05 17:34:41 -0700424 mBluetoothController = new BluetoothController(mContext);
Jim Miller5e6af442011-12-02 18:24:26 -0800425 final SignalClusterView signalCluster =
Daniel Sandlera310af82012-04-24 01:20:13 -0400426 (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
Daniel Sandler3d32a242012-06-05 13:44:14 -0400427
Winson Chungd63c59782012-09-05 17:34:41 -0700428
Christian Robertson2e347422011-08-11 14:01:04 -0700429 mNetworkController.addSignalCluster(signalCluster);
Daniel Sandler28f89d42011-08-15 14:04:15 -0400430 signalCluster.setNetworkController(mNetworkController);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400431
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400432 mEmergencyCallLabel = (TextView)mStatusBarWindow.findViewById(R.id.emergency_calls_only);
433 if (mEmergencyCallLabel != null) {
434 mNetworkController.addEmergencyLabelView(mEmergencyCallLabel);
435 mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
436 @Override
437 public void onLayoutChange(View v, int left, int top, int right, int bottom,
438 int oldLeft, int oldTop, int oldRight, int oldBottom) {
439 updateCarrierLabelVisibility(false);
440 }});
441 }
442
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400443 mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
444 mShowCarrierInPanel = (mCarrierLabel != null);
445 Slog.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
446 if (mShowCarrierInPanel) {
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400447 mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
448
Daniel Sandler67234c42012-06-15 13:17:39 -0400449 // for mobile devices, we always show mobile connection info here (SPN/PLMN)
450 // for other devices, we show whatever network is connected
Daniel Sandler18ac7822012-06-11 16:07:18 -0400451 if (mNetworkController.hasMobileDataFeature()) {
452 mNetworkController.addMobileLabelView(mCarrierLabel);
453 } else {
Daniel Sandler67234c42012-06-15 13:17:39 -0400454 mNetworkController.addCombinedLabelView(mCarrierLabel);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400455 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400456
457 // set up the dynamic hide/show of the label
458 mPile.setOnSizeChangedListener(new OnSizeChangedListener() {
459 @Override
460 public void onSizeChanged(View view, int w, int h, int oldw, int oldh) {
461 updateCarrierLabelVisibility(false);
462 }
463 });
Daniel Sandler3d32a242012-06-05 13:44:14 -0400464 }
465
Winson Chungd63c59782012-09-05 17:34:41 -0700466 // Quick Settings (WIP)
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400467 mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
Winson Chungd63c59782012-09-05 17:34:41 -0700468 mSettingsPanel.setBar(mStatusBarView);
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400469 mSettingsPanel.setService(this);
Winson Chungd63c59782012-09-05 17:34:41 -0700470 mSettingsPanel.setup(mNetworkController, mBluetoothController, mBatteryController,
471 mLocationController);
Daniel Sandler173bae22012-09-25 14:37:42 -0400472 mSettingsPanel.setSystemUiVisibility(
473 View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
Winson Chungd63c59782012-09-05 17:34:41 -0700474
Siva Velusamy537421b2012-09-14 14:45:02 -0700475 if (!ActivityManager.isHighEndGfx()) {
476 mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
477 R.color.notification_panel_solid_background)));
478 }
479
Jim Miller5e6af442011-12-02 18:24:26 -0800480// final ImageView wimaxRSSI =
Daniel Sandler633eabe2011-11-09 16:49:44 -0500481// (ImageView)sb.findViewById(R.id.wimax_signal);
482// if (wimaxRSSI != null) {
483// mNetworkController.addWimaxIconView(wimaxRSSI);
484// }
Michael Jurka3b1fc472011-06-13 10:54:40 -0700485
Joe Onorato808182d2010-07-09 18:52:06 -0400486 // receive broadcasts
487 IntentFilter filter = new IntentFilter();
488 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
489 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
490 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400491 filter.addAction(Intent.ACTION_SCREEN_ON);
Joe Onorato808182d2010-07-09 18:52:06 -0400492 context.registerReceiver(mBroadcastReceiver, filter);
493
John Spurlock919adac2012-10-02 16:41:12 -0400494 // listen for USER_SETUP_COMPLETE setting (per-user)
495 resetUserSetupObserver();
496
Daniel Sandlera310af82012-04-24 01:20:13 -0400497 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400498 }
499
Michael Jurka7f2668c2012-03-27 07:49:52 -0700500 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -0700501 protected View getStatusBarView() {
502 return mStatusBarView;
503 }
504
505 @Override
Jim Millerf2a16b22011-07-06 17:32:48 -0700506 protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
Michael Jurka3cd0a592011-08-16 12:40:30 -0700507 boolean opaque = false;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700508 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Jim Millerf2a16b22011-07-06 17:32:48 -0700509 layoutParams.width,
510 layoutParams.height,
Michael Jurka3b1fc472011-06-13 10:54:40 -0700511 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
512 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
513 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700514 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Michael Jurka3cd0a592011-08-16 12:40:30 -0700515 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
Jeff Brown98365d72012-08-19 20:30:52 -0700516 if (ActivityManager.isHighEndGfx()) {
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700517 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Michael Jurkaf16fc512012-02-27 15:02:23 -0800518 } else {
519 lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
Michael Jurkaf3abbad2012-06-04 14:00:32 -0700520 lp.dimAmount = 0.75f;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700521 }
Michael Jurka3b1fc472011-06-13 10:54:40 -0700522 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
523 lp.setTitle("RecentsPanel");
Michael Jurka99a96552012-01-27 17:23:38 -0800524 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700525 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
526 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
527 return lp;
528 }
529
Jim Millere898ac52012-04-06 17:10:57 -0700530 @Override
531 protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
532 boolean opaque = false;
533 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
534 LayoutParams.MATCH_PARENT,
535 LayoutParams.MATCH_PARENT,
536 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
537 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
538 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
539 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
540 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
Jeff Brown98365d72012-08-19 20:30:52 -0700541 if (ActivityManager.isHighEndGfx()) {
Jim Millere898ac52012-04-06 17:10:57 -0700542 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Jim Millere898ac52012-04-06 17:10:57 -0700543 }
544 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
545 lp.setTitle("SearchPanel");
546 // TODO: Define custom animation for Search panel
547 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
548 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
549 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
550 return lp;
551 }
552
Jim Millere898ac52012-04-06 17:10:57 -0700553 @Override
554 protected void updateSearchPanel() {
555 super.updateSearchPanel();
Jim Miller354619c2012-04-27 17:33:44 -0700556 mSearchPanelView.setStatusBarView(mNavigationBarView);
Jim Millere898ac52012-04-06 17:10:57 -0700557 mNavigationBarView.setDelegateView(mSearchPanelView);
558 }
559
560 @Override
561 public void showSearchPanel() {
Jim Millerb490c3e2012-05-31 13:34:16 -0700562 super.showSearchPanel();
Jim Millere898ac52012-04-06 17:10:57 -0700563 WindowManager.LayoutParams lp =
564 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
565 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Jeff Brown98365d72012-08-19 20:30:52 -0700566 mWindowManager.updateViewLayout(mNavigationBarView, lp);
Jim Millere898ac52012-04-06 17:10:57 -0700567 }
568
569 @Override
570 public void hideSearchPanel() {
571 super.hideSearchPanel();
572 WindowManager.LayoutParams lp =
573 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
574 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Jeff Brown98365d72012-08-19 20:30:52 -0700575 mWindowManager.updateViewLayout(mNavigationBarView, lp);
Jim Millere898ac52012-04-06 17:10:57 -0700576 }
577
Joe Onorato808182d2010-07-09 18:52:06 -0400578 protected int getStatusBarGravity() {
579 return Gravity.TOP | Gravity.FILL_HORIZONTAL;
580 }
581
Joe Onoratodc100302011-01-11 17:07:41 -0800582 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -0400583 if (mNaturalBarHeight < 0) {
584 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -0700585 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -0400586 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
587 }
588 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -0800589 }
590
Daniel Sandler5c8da942011-06-28 00:29:04 -0400591 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
592 public void onClick(View v) {
593 toggleRecentApps();
594 }
595 };
Chris Wren0c8275b2012-05-08 13:36:48 -0400596
Jim Miller9a720f52012-05-30 03:19:43 -0700597 private int mShowSearchHoldoff = 0;
598 private Runnable mShowSearchPanel = new Runnable() {
599 public void run() {
600 showSearchPanel();
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400601 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700602 }
603 };
604
Jim Millere898ac52012-04-06 17:10:57 -0700605 View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
606 public boolean onTouch(View v, MotionEvent event) {
607 switch(event.getAction()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700608 case MotionEvent.ACTION_DOWN:
John Spurlock67ad3682012-06-26 17:42:00 -0400609 if (!shouldDisableNavbarGestures() && !inKeyguardRestrictedInputMode()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700610 mHandler.removeCallbacks(mShowSearchPanel);
611 mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
612 }
613 break;
614
615 case MotionEvent.ACTION_UP:
616 case MotionEvent.ACTION_CANCEL:
617 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400618 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700619 break;
620 }
621 return false;
Jim Millere898ac52012-04-06 17:10:57 -0700622 }
623 };
Daniel Sandler5c8da942011-06-28 00:29:04 -0400624
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400625 private void awakenDreams() {
626 if (mDreamManager != null) {
627 try {
628 mDreamManager.awaken();
629 } catch (RemoteException e) {
630 // fine, stay asleep then
631 }
632 }
633 }
634
Michael Jurka412cba82011-10-17 09:05:00 -0700635 private void prepareNavigationBarView() {
636 mNavigationBarView.reorient();
637
638 mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
Michael Jurkacb2522c2012-04-13 09:32:47 -0700639 mNavigationBarView.getRecentsButton().setOnTouchListener(getRecentTasksLoader());
Jim Miller998bb762012-05-21 13:37:27 -0700640 mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
Jim Millere898ac52012-04-06 17:10:57 -0700641 updateSearchPanel();
Michael Jurka412cba82011-10-17 09:05:00 -0700642 }
643
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400644 // For small-screen devices (read: phones) that lack hardware navigation buttons
645 private void addNavigationBar() {
Daniel Sandler4a066c52012-04-20 14:49:13 -0400646 if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -0400647 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700648
Michael Jurka412cba82011-10-17 09:05:00 -0700649 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400650
Jeff Brown98365d72012-08-19 20:30:52 -0700651 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400652 }
653
654 private void repositionNavigationBar() {
Daniel Sandler0129b312011-05-11 11:54:11 -0400655 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700656
Michael Jurka412cba82011-10-17 09:05:00 -0700657 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400658
Jeff Brown98365d72012-08-19 20:30:52 -0700659 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400660 }
661
662 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400663 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -0700664 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400665 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
666 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400667 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
668 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -0700669 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -0400670 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -0700671 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Daniel Sandlera3884492011-08-16 15:55:44 -0400672 PixelFormat.OPAQUE);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700673 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -0700674 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700675 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
676 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400677
678 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400679 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400680 return lp;
681 }
682
Joe Onoratodc100302011-01-11 17:07:41 -0800683 private void addIntruderView() {
Joe Onorato808182d2010-07-09 18:52:06 -0400684 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
685 ViewGroup.LayoutParams.MATCH_PARENT,
686 ViewGroup.LayoutParams.WRAP_CONTENT,
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400687 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
Joe Onorato808182d2010-07-09 18:52:06 -0400688 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
689 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
690 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
691 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Jeff Brown46e75292010-11-10 16:53:45 -0800692 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
693 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Joe Onorato808182d2010-07-09 18:52:06 -0400694 PixelFormat.TRANSLUCENT);
695 lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400696 //lp.y += height * 1.5; // FIXME
Joe Onorato808182d2010-07-09 18:52:06 -0400697 lp.setTitle("IntruderAlert");
Dianne Hackborn59aed382011-08-02 17:31:44 -0700698 lp.packageName = mContext.getPackageName();
699 lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
Joe Onorato808182d2010-07-09 18:52:06 -0400700
Jeff Brown98365d72012-08-19 20:30:52 -0700701 mWindowManager.addView(mIntruderAlertView, lp);
Joe Onorato808182d2010-07-09 18:52:06 -0400702 }
703
704 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
705 if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
706 + " icon=" + icon);
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700707 StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400708 view.set(icon);
709 mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
710 }
711
712 public void updateIcon(String slot, int index, int viewIndex,
713 StatusBarIcon old, StatusBarIcon icon) {
714 if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
715 + " old=" + old + " icon=" + icon);
716 StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
717 view.set(icon);
718 }
719
720 public void removeIcon(String slot, int index, int viewIndex) {
721 if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
722 mStatusIcons.removeViewAt(viewIndex);
723 }
724
725 public void addNotification(IBinder key, StatusBarNotification notification) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500726 /* if (DEBUG) */ Slog.d(TAG, "addNotification score=" + notification.score);
Joe Onorato808182d2010-07-09 18:52:06 -0400727 StatusBarIconView iconView = addNotificationViews(key, notification);
728 if (iconView == null) return;
729
730 boolean immersive = false;
731 try {
732 immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
Daniel Sandler8355e932011-08-11 00:27:45 -0400733 if (DEBUG) {
734 Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
735 }
Joe Onorato808182d2010-07-09 18:52:06 -0400736 } catch (RemoteException ex) {
737 }
Daniel Sandler6b318802012-04-13 14:05:19 -0400738
739 /*
740 * DISABLED due to missing API
Daniel Sandlerfc6fda32012-02-24 22:00:46 -0500741 if (ENABLE_INTRUDERS && (
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400742 // TODO(dsandler): Only if the screen is on
743 notification.notification.intruderView != null)) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500744 Slog.d(TAG, "Presenting high-priority notification");
745 // special new transient ticker mode
746 // 1. Populate mIntruderAlertView
Jim Millere898ac52012-04-06 17:10:57 -0700747
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400748 if (notification.notification.intruderView == null) {
749 Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
750 return;
751 }
Joe Onorato808182d2010-07-09 18:52:06 -0400752
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400753 // bind the click event to the content area
754 PendingIntent contentIntent = notification.notification.contentIntent;
755 final View.OnClickListener listener = (contentIntent != null)
756 ? new NotificationClicker(contentIntent,
757 notification.pkg, notification.tag, notification.id)
758 : null;
Joe Onorato808182d2010-07-09 18:52:06 -0400759
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400760 mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener);
Joe Onorato808182d2010-07-09 18:52:06 -0400761
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400762 mCurrentlyIntrudingNotification = notification;
Jim Millere898ac52012-04-06 17:10:57 -0700763
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500764 // 2. Animate mIntruderAlertView in
765 mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
Joe Onorato808182d2010-07-09 18:52:06 -0400766
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500767 // 3. Set alarm to age the notification off (TODO)
768 mHandler.removeMessages(MSG_HIDE_INTRUDER);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400769 if (INTRUDER_ALERT_DECAY_MS > 0) {
770 mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
771 }
Jim Millera073e572012-05-23 17:03:27 -0700772 } else
Daniel Sandler6b318802012-04-13 14:05:19 -0400773 */
Jim Millera073e572012-05-23 17:03:27 -0700774
Daniel Sandler6b318802012-04-13 14:05:19 -0400775 if (notification.notification.fullScreenIntent != null) {
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -0400776 // Stop screensaver if the notification has a full-screen intent.
777 // (like an incoming phone call)
778 awakenDreams();
779
Joe Onorato808182d2010-07-09 18:52:06 -0400780 // not immersive & a full-screen alert should be shown
Daniel Sandler8355e932011-08-11 00:27:45 -0400781 Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
Joe Onorato808182d2010-07-09 18:52:06 -0400782 try {
783 notification.notification.fullScreenIntent.send();
784 } catch (PendingIntent.CanceledException e) {
785 }
786 } else {
787 // usual case: status bar visible & not immersive
788
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400789 // show the ticker if there isn't an intruder too
790 if (mCurrentlyIntrudingNotification == null) {
Chris Wren0c8275b2012-05-08 13:36:48 -0400791 tick(null, notification, true);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400792 }
Joe Onorato808182d2010-07-09 18:52:06 -0400793 }
794
795 // Recalculate the position of the sliding windows and the titles.
796 setAreThereNotifications();
797 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
798 }
799
Joe Onorato808182d2010-07-09 18:52:06 -0400800 public void removeNotification(IBinder key) {
Joe Onorato808182d2010-07-09 18:52:06 -0400801 StatusBarNotification old = removeNotificationViews(key);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400802 if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -0400803
804 if (old != null) {
805 // Cancel the ticker if it's still running
806 mTicker.removeEntry(old);
807
808 // Recalculate the position of the sliding windows and the titles.
Joe Onorato808182d2010-07-09 18:52:06 -0400809 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Jim Millere898ac52012-04-06 17:10:57 -0700810
Daniel Sandler6b318802012-04-13 14:05:19 -0400811 if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) {
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400812 mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
813 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400814
815 if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 && !mAnimating) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400816 animateCollapsePanels();
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400817 }
Joe Onorato808182d2010-07-09 18:52:06 -0400818 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400819
820 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400821 }
822
John Spurlockd5ef5462012-06-13 11:19:51 -0400823 private void updateShowSearchHoldoff() {
824 mShowSearchHoldoff = mContext.getResources().getInteger(
825 R.integer.config_show_search_delay);
Michael Jurka3b1fc472011-06-13 10:54:40 -0700826 }
827
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400828 private void loadNotificationShade() {
Daniel Sandler26cda272012-05-22 15:44:08 -0400829 if (mPile == null) return;
830
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400831 int N = mNotificationData.size();
832
833 ArrayList<View> toShow = new ArrayList<View>();
834
Daniel Sandler26cda272012-05-22 15:44:08 -0400835 final boolean provisioned = isDeviceProvisioned();
836 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400837 for (int i=0; i<N; i++) {
Daniel Sandler26cda272012-05-22 15:44:08 -0400838 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400839 if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
840 if (!notificationIsForCurrentUser(ent.notification)) continue;
841 toShow.add(ent.row);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400842 }
843
844 ArrayList<View> toRemove = new ArrayList<View>();
845 for (int i=0; i<mPile.getChildCount(); i++) {
846 View child = mPile.getChildAt(i);
847 if (!toShow.contains(child)) {
848 toRemove.add(child);
Joe Onorato808182d2010-07-09 18:52:06 -0400849 }
850 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400851
852 for (View remove : toRemove) {
853 mPile.removeView(remove);
854 }
855
856 for (int i=0; i<toShow.size(); i++) {
857 View v = toShow.get(i);
858 if (v.getParent() == null) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500859 mPile.addView(v, i);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400860 }
861 }
Daniel Sandler26cda272012-05-22 15:44:08 -0400862
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400863 if (mSettingsButton != null) {
864 mSettingsButton.setEnabled(isDeviceProvisioned());
865 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400866 }
867
Chris Wren0c8275b2012-05-08 13:36:48 -0400868 @Override
869 protected void updateNotificationIcons() {
Daniel Sandler26cda272012-05-22 15:44:08 -0400870 if (mNotificationIcons == null) return;
871
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400872 loadNotificationShade();
873
874 final LinearLayout.LayoutParams params
875 = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
876
877 int N = mNotificationData.size();
878
879 if (DEBUG) {
880 Slog.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
881 }
882
883 ArrayList<View> toShow = new ArrayList<View>();
884
Daniel Sandler26cda272012-05-22 15:44:08 -0400885 final boolean provisioned = isDeviceProvisioned();
886 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400887 for (int i=0; i<N; i++) {
Daniel Sandler58b173b2012-05-03 11:25:29 -0400888 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400889 if (!((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE)
890 || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
891 if (!notificationIsForCurrentUser(ent.notification)) continue;
892 toShow.add(ent.icon);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400893 }
894
895 ArrayList<View> toRemove = new ArrayList<View>();
896 for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
897 View child = mNotificationIcons.getChildAt(i);
898 if (!toShow.contains(child)) {
899 toRemove.add(child);
900 }
901 }
902
903 for (View remove : toRemove) {
904 mNotificationIcons.removeView(remove);
905 }
906
907 for (int i=0; i<toShow.size(); i++) {
908 View v = toShow.get(i);
909 if (v.getParent() == null) {
910 mNotificationIcons.addView(v, i, params);
911 }
912 }
913 }
914
Daniel Sandlere5011a32012-06-11 16:07:52 -0400915 protected void updateCarrierLabelVisibility(boolean force) {
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400916 if (!mShowCarrierInPanel) return;
Daniel Sandler3d32a242012-06-05 13:44:14 -0400917 // The idea here is to only show the carrier label when there is enough room to see it,
918 // i.e. when there aren't enough notifications to fill the panel.
919 if (DEBUG) {
920 Slog.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
921 mPile.getHeight(), mScrollView.getHeight(), mCarrierLabelHeight));
922 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400923
924 final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
925 final boolean makeVisible =
926 !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400927 && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight);
Daniel Sandler3d32a242012-06-05 13:44:14 -0400928
Daniel Sandlere5011a32012-06-11 16:07:52 -0400929 if (force || mCarrierLabelVisible != makeVisible) {
Daniel Sandler3d32a242012-06-05 13:44:14 -0400930 mCarrierLabelVisible = makeVisible;
931 if (DEBUG) {
932 Slog.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
933 }
934 mCarrierLabel.animate().cancel();
935 if (makeVisible) {
936 mCarrierLabel.setVisibility(View.VISIBLE);
937 }
938 mCarrierLabel.animate()
939 .alpha(makeVisible ? 1f : 0f)
940 //.setStartDelay(makeVisible ? 500 : 0)
941 //.setDuration(makeVisible ? 750 : 100)
942 .setDuration(150)
943 .setListener(makeVisible ? null : new AnimatorListenerAdapter() {
944 @Override
945 public void onAnimationEnd(Animator animation) {
946 if (!mCarrierLabelVisible) { // race
947 mCarrierLabel.setVisibility(View.INVISIBLE);
948 mCarrierLabel.setAlpha(0f);
949 }
950 }
951 })
952 .start();
953 }
954 }
955
Chris Wren0c8275b2012-05-08 13:36:48 -0400956 @Override
957 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400958 final boolean any = mNotificationData.size() > 0;
Joe Onorato808182d2010-07-09 18:52:06 -0400959
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400960 final boolean clearable = any && mNotificationData.hasClearableItems();
961
962 if (DEBUG) {
963 Slog.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
964 + " any=" + any + " clearable=" + clearable);
965 }
966
967 if (mClearButton.isShown()) {
968 if (clearable != (mClearButton.getAlpha() == 1.0f)) {
Romain Guy8900e632012-05-25 12:08:39 -0700969 ObjectAnimator clearAnimation = ObjectAnimator.ofFloat(
970 mClearButton, "alpha", clearable ? 1.0f : 0.0f).setDuration(250);
971 clearAnimation.addListener(new AnimatorListenerAdapter() {
972 @Override
973 public void onAnimationEnd(Animator animation) {
974 if (mClearButton.getAlpha() <= 0.0f) {
975 mClearButton.setVisibility(View.INVISIBLE);
976 }
977 }
978
979 @Override
980 public void onAnimationStart(Animator animation) {
981 if (mClearButton.getAlpha() <= 0.0f) {
982 mClearButton.setVisibility(View.VISIBLE);
983 }
984 }
985 });
986 clearAnimation.start();
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400987 }
988 } else {
989 mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
Romain Guy8900e632012-05-25 12:08:39 -0700990 mClearButton.setVisibility(clearable ? View.VISIBLE : View.INVISIBLE);
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400991 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400992 mClearButton.setEnabled(clearable);
Romain Guy8900e632012-05-25 12:08:39 -0700993
Daniel Sandlerd7e96862012-04-26 01:10:29 -0400994 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
995 final boolean showDot = (any&&!areLightsOn());
996 if (showDot != (nlo.getAlpha() == 1.0f)) {
997 if (showDot) {
998 nlo.setAlpha(0f);
999 nlo.setVisibility(View.VISIBLE);
1000 }
1001 nlo.animate()
1002 .alpha(showDot?1:0)
1003 .setDuration(showDot?750:250)
1004 .setInterpolator(new AccelerateInterpolator(2.0f))
1005 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1006 @Override
1007 public void onAnimationEnd(Animator _a) {
1008 nlo.setVisibility(View.GONE);
1009 }
1010 })
1011 .start();
1012 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001013
Daniel Sandlere5011a32012-06-11 16:07:52 -04001014 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001015 }
1016
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001017 public void showClock(boolean show) {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001018 if (mStatusBarView == null) return;
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001019 View clock = mStatusBarView.findViewById(R.id.clock);
1020 if (clock != null) {
1021 clock.setVisibility(show ? View.VISIBLE : View.GONE);
1022 }
1023 }
Joe Onorato808182d2010-07-09 18:52:06 -04001024
1025 /**
1026 * State is one or more of the DISABLE constants from StatusBarManager.
1027 */
1028 public void disable(int state) {
1029 final int old = mDisabled;
1030 final int diff = state ^ old;
1031 mDisabled = state;
1032
Daniel Sandlere21f2882011-08-18 10:14:59 -04001033 if (DEBUG) {
1034 Slog.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
1035 old, state, diff));
1036 }
1037
Daniel Sandler6da2b762011-09-14 16:04:59 -04001038 StringBuilder flagdbg = new StringBuilder();
1039 flagdbg.append("disable: < ");
1040 flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
1041 flagdbg.append(((diff & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
1042 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
1043 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
1044 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
1045 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
1046 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "TICKER" : "ticker");
1047 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
1048 flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
1049 flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001050 flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
1051 flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
Daniel Sandlerdba93562011-10-06 16:39:58 -04001052 flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
1053 flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
1054 flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
1055 flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001056 flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
1057 flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
1058 flagdbg.append(">");
1059 Slog.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07001060
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001061 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001062 mSystemIconArea.animate().cancel();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001063 if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001064 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001065 .alpha(0f)
1066 .translationY(mNaturalBarHeight*0.5f)
Daniel Sandler67e7d902012-06-06 16:32:21 -04001067 .setDuration(175)
1068 .setInterpolator(new DecelerateInterpolator(1.5f))
1069 .setListener(mMakeIconsInvisible)
1070 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001071 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001072 mSystemIconArea.setVisibility(View.VISIBLE);
1073 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001074 .alpha(1f)
1075 .translationY(0)
1076 .setStartDelay(0)
1077 .setInterpolator(new DecelerateInterpolator(1.5f))
1078 .setDuration(175)
1079 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001080 }
1081 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04001082
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001083 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
1084 boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
1085 showClock(show);
1086 }
Joe Onorato808182d2010-07-09 18:52:06 -04001087 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1088 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001089 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04001090 }
1091 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001092
Jim Miller5e6af442011-12-02 18:24:26 -08001093 if ((diff & (StatusBarManager.DISABLE_HOME
1094 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerdba93562011-10-06 16:39:58 -04001095 | StatusBarManager.DISABLE_BACK)) != 0) {
1096 // the nav bar will take care of these
Daniel Sandlerd9283b902011-09-14 21:42:00 -04001097 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001098
Daniel Sandlerdba93562011-10-06 16:39:58 -04001099 if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04001100 // close recents if it's visible
1101 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1102 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1103 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001104 }
1105
Joe Onorato808182d2010-07-09 18:52:06 -04001106 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1107 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Joe Onorato808182d2010-07-09 18:52:06 -04001108 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001109 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001110 }
Daniel Sandler173bae22012-09-25 14:37:42 -04001111
1112 mNotificationIcons.animate()
1113 .alpha(0f)
1114 .translationY(mNaturalBarHeight*0.5f)
1115 .setDuration(175)
1116 .setInterpolator(new DecelerateInterpolator(1.5f))
1117 .setListener(mMakeIconsInvisible)
1118 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001119 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001120 mNotificationIcons.setVisibility(View.VISIBLE);
1121 mNotificationIcons.animate()
1122 .alpha(1f)
1123 .translationY(0)
1124 .setStartDelay(0)
1125 .setInterpolator(new DecelerateInterpolator(1.5f))
1126 .setDuration(175)
1127 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001128 }
1129 } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1130 if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001131 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001132 }
1133 }
1134 }
1135
Michael Jurka7f2668c2012-03-27 07:49:52 -07001136 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07001137 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001138 return new PhoneStatusBar.H();
1139 }
1140
Joe Onorato808182d2010-07-09 18:52:06 -04001141 /**
1142 * All changes to the status bar and notifications funnel through here and are batched.
1143 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07001144 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04001145 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001146 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04001147 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001148 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04001149 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001150 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04001151 case MSG_OPEN_SETTINGS_PANEL:
1152 animateExpandSettingsPanel();
1153 break;
1154 case MSG_CLOSE_PANELS:
1155 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001156 break;
Joe Onorato808182d2010-07-09 18:52:06 -04001157 case MSG_SHOW_INTRUDER:
1158 setIntruderAlertVisibility(true);
1159 break;
1160 case MSG_HIDE_INTRUDER:
1161 setIntruderAlertVisibility(false);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04001162 mCurrentlyIntrudingNotification = null;
Joe Onorato808182d2010-07-09 18:52:06 -04001163 break;
1164 }
1165 }
1166 }
1167
1168 View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
1169 public void onFocusChange(View v, boolean hasFocus) {
1170 // Because 'v' is a ViewGroup, all its children will be (un)selected
1171 // too, which allows marqueeing to work.
1172 v.setSelected(hasFocus);
1173 }
1174 };
1175
Daniel Sandler08d05e32012-08-08 16:39:54 -04001176 void makeExpandedVisible(boolean revealAfterDraw) {
Joe Onorato808182d2010-07-09 18:52:06 -04001177 if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
1178 if (mExpandedVisible) {
1179 return;
1180 }
Jim Millera073e572012-05-23 17:03:27 -07001181
Joe Onorato808182d2010-07-09 18:52:06 -04001182 mExpandedVisible = true;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001183 mPile.setLayoutTransitionsEnabled(true);
John Spurlockd5ef5462012-06-13 11:19:51 -04001184 if (mNavigationBarView != null)
1185 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001186
Daniel Sandlere5011a32012-06-11 16:07:52 -04001187 updateCarrierLabelVisibility(true);
Daniel Sandler3d32a242012-06-05 13:44:14 -04001188
Joe Onorato808182d2010-07-09 18:52:06 -04001189 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Daniel Sandlera310af82012-04-24 01:20:13 -04001190
1191 // Expand the window to encompass the full screen in anticipation of the drag.
1192 // This is only possible to do atomically because the status bar is at the top of the screen!
1193 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001194 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1195 lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Daniel Sandler21b274e2012-05-02 15:07:51 -04001196 lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
Jeff Brown98365d72012-08-19 20:30:52 -07001197 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Daniel Sandlera310af82012-04-24 01:20:13 -04001198
John Spurlock804df702012-06-01 15:34:27 -04001199 // Updating the window layout will force an expensive traversal/redraw.
1200 // Kick off the reveal animation after this is complete to avoid animation latency.
1201 if (revealAfterDraw) {
Daniel Sandler08d05e32012-08-08 16:39:54 -04001202// mHandler.post(mStartRevealAnimation);
John Spurlock804df702012-06-01 15:34:27 -04001203 }
1204
Daniel Sandlera310af82012-04-24 01:20:13 -04001205 visibilityChanged(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001206 }
1207
Daniel Sandler11cf1782012-09-27 14:03:08 -04001208 public void animateCollapsePanels() {
1209 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001210 }
1211
Daniel Sandler11cf1782012-09-27 14:03:08 -04001212 public void animateCollapsePanels(int flags) {
Joe Onorato808182d2010-07-09 18:52:06 -04001213 if (SPEW) {
Daniel Sandler198a0302012-08-17 16:04:31 -04001214 Slog.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04001215 + " mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04001216 + " mAnimating=" + mAnimating
Daniel Sandlered930e52012-07-03 14:31:22 -04001217 + " mAnimatingReveal=" + mAnimatingReveal
Joe Onorato808182d2010-07-09 18:52:06 -04001218 + " mAnimY=" + mAnimY
Jim Miller9a720f52012-05-30 03:19:43 -07001219 + " mAnimVel=" + mAnimVel
1220 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04001221 }
1222
Jim Miller9a720f52012-05-30 03:19:43 -07001223 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Michael Jurka3b1fc472011-06-13 10:54:40 -07001224 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1225 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1226 }
Jim Miller9a720f52012-05-30 03:19:43 -07001227
1228 if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
1229 mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
1230 mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
1231 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07001232
Daniel Sandler08d05e32012-08-08 16:39:54 -04001233 mStatusBarView.collapseAllPanels(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001234 }
1235
Daniel Sandler08d05e32012-08-08 16:39:54 -04001236 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001237 public void animateExpandNotificationsPanel() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001238 if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
Joe Onorato808182d2010-07-09 18:52:06 -04001239 if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1240 return ;
1241 }
Joe Onorato808182d2010-07-09 18:52:06 -04001242
Daniel Sandler08d05e32012-08-08 16:39:54 -04001243 mNotificationPanel.expand();
Joe Onorato808182d2010-07-09 18:52:06 -04001244
1245 if (false) postStartTracing();
1246 }
1247
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001248 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001249 public void animateExpandSettingsPanel() {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001250 if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
1251 if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1252 return;
1253 }
1254
1255 mSettingsPanel.expand();
1256
1257 if (false) postStartTracing();
1258 }
1259
1260 public void animateCollapseQuickSettings() {
1261 mStatusBarView.collapseAllPanels(true);
1262 }
1263
Daniel Sandler08d05e32012-08-08 16:39:54 -04001264 void makeExpandedInvisible() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001265 if (SPEW) Slog.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04001266 + " mExpandedVisible=" + mExpandedVisible);
1267
1268 if (!mExpandedVisible) {
1269 return;
1270 }
Daniel Sandlered930e52012-07-03 14:31:22 -04001271
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04001272 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
1273 mStatusBarView.collapseAllPanels(/*animate=*/ false);
Daniel Sandlered930e52012-07-03 14:31:22 -04001274
Joe Onorato808182d2010-07-09 18:52:06 -04001275 mExpandedVisible = false;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001276 mPile.setLayoutTransitionsEnabled(false);
John Spurlockd5ef5462012-06-13 11:19:51 -04001277 if (mNavigationBarView != null)
1278 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001279 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04001280
1281 // Shrink the window to the size of the status bar only
1282 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
1283 lp.height = getStatusBarHeight();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001284 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1285 lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jeff Brown98365d72012-08-19 20:30:52 -07001286 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04001287
1288 if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
1289 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1290 }
Joe Onorato808182d2010-07-09 18:52:06 -04001291
Daniel Sandler469e96e2012-05-04 15:56:19 -04001292 // Close any "App info" popups that might have snuck on-screen
1293 dismissPopups();
1294
Chet Haase2f2022a2011-10-11 06:41:59 -07001295 if (mPostCollapseCleanup != null) {
1296 mPostCollapseCleanup.run();
1297 mPostCollapseCleanup = null;
1298 }
Joe Onorato808182d2010-07-09 18:52:06 -04001299 }
1300
Romain Guy54ab3472012-06-14 12:52:53 -07001301 /**
1302 * Enables or disables layers on the children of the notifications pile.
1303 *
1304 * When layers are enabled, this method attempts to enable layers for the minimal
1305 * number of children. Only children visible when the notification area is fully
1306 * expanded will receive a layer. The technique used in this method might cause
1307 * more children than necessary to get a layer (at most one extra child with the
1308 * current UI.)
1309 *
1310 * @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE}
1311 */
1312 private void setPileLayers(int layerType) {
1313 final int count = mPile.getChildCount();
1314
1315 switch (layerType) {
1316 case View.LAYER_TYPE_NONE:
1317 for (int i = 0; i < count; i++) {
1318 mPile.getChildAt(i).setLayerType(layerType, null);
1319 }
1320 break;
1321 case View.LAYER_TYPE_HARDWARE:
1322 final int[] location = new int[2];
1323 mNotificationPanel.getLocationInWindow(location);
1324
1325 final int left = location[0];
1326 final int top = location[1];
1327 final int right = left + mNotificationPanel.getWidth();
1328 final int bottom = top + getExpandedViewMaxHeight();
1329
1330 final Rect childBounds = new Rect();
1331
1332 for (int i = 0; i < count; i++) {
1333 final View view = mPile.getChildAt(i);
1334 view.getLocationInWindow(location);
1335
1336 childBounds.set(location[0], location[1],
1337 location[0] + view.getWidth(), location[1] + view.getHeight());
1338
1339 if (childBounds.intersects(left, top, right, bottom)) {
1340 view.setLayerType(layerType, null);
1341 }
1342 }
1343
1344 break;
1345 }
1346 }
1347
Joe Onorato808182d2010-07-09 18:52:06 -04001348 boolean interceptTouchEvent(MotionEvent event) {
1349 if (SPEW) {
1350 Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
John Spurlock804df702012-06-01 15:34:27 -04001351 + mDisabled + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001352 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001353 if (event.getAction() != MotionEvent.ACTION_MOVE) {
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001354 Slog.d(TAG, String.format(
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001355 "panel: %s at (%f, %f) mDisabled=0x%08x",
1356 MotionEvent.actionToString(event.getAction()),
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001357 event.getRawX(), event.getRawY(), mDisabled));
1358 }
Joe Onorato808182d2010-07-09 18:52:06 -04001359 }
1360
Daniel Sandler151f00d2012-10-02 22:33:08 -04001361 if (DEBUG_GESTURES) {
1362 mGestureRec.add(event);
1363 }
Daniel Sandler33805342012-07-23 15:45:12 -04001364
Joe Onorato808182d2010-07-09 18:52:06 -04001365 return false;
1366 }
1367
Daniel Sandler08d05e32012-08-08 16:39:54 -04001368 public GestureRecorder getGestureRecorder() {
1369 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07001370 }
1371
Daniel Sandler60ee2562011-07-22 12:34:33 -04001372 @Override // CommandQueue
Daniel Sandler328310c2011-09-23 15:56:52 -04001373 public void setNavigationIconHints(int hints) {
1374 if (hints == mNavigationIconHints) return;
1375
1376 mNavigationIconHints = hints;
1377
1378 if (mNavigationBarView != null) {
1379 mNavigationBarView.setNavigationIconHints(hints);
1380 }
1381 }
1382
1383 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001384 public void setSystemUiVisibility(int vis, int mask) {
1385 final int oldVal = mSystemUiVisibility;
1386 final int newVal = (oldVal&~mask) | (vis&mask);
1387 final int diff = newVal ^ oldVal;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001388
1389 if (diff != 0) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001390 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04001391
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001392 if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
1393 final boolean lightsOut = (0 != (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE));
1394 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001395 animateCollapsePanels();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001396 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001397 haltTicker();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001398 }
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001399 }
Jim Millera073e572012-05-23 17:03:27 -07001400
Daniel Sandler69314e72011-08-20 00:31:08 -04001401 if (mNavigationBarView != null) {
1402 mNavigationBarView.setLowProfile(lightsOut);
1403 }
Jim Millera073e572012-05-23 17:03:27 -07001404
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001405 setStatusBarLowProfile(lightsOut);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001406 }
1407
1408 notifyUiVisibilityChanged();
Joe Onorato93056472010-09-10 10:30:46 -04001409 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001410 }
1411
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001412 private void setStatusBarLowProfile(boolean lightsOut) {
1413 if (mLightsOutAnimation == null) {
Daniel Sandler825b3302012-10-01 15:22:36 -04001414 final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area);
1415 final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons);
1416 final View signal = mStatusBarView.findViewById(R.id.signal_cluster);
1417 final View battery = mStatusBarView.findViewById(R.id.battery);
1418 final View clock = mStatusBarView.findViewById(R.id.clock);
Jim Millera073e572012-05-23 17:03:27 -07001419
Daniel Sandler825b3302012-10-01 15:22:36 -04001420 final AnimatorSet lightsOutAnim = new AnimatorSet();
1421 lightsOutAnim.playTogether(
1422 ObjectAnimator.ofFloat(notifications, View.ALPHA, 0),
1423 ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0),
1424 ObjectAnimator.ofFloat(signal, View.ALPHA, 0),
1425 ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f),
1426 ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
1427 );
1428 lightsOutAnim.setDuration(750);
1429
1430 final AnimatorSet lightsOnAnim = new AnimatorSet();
1431 lightsOnAnim.playTogether(
1432 ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
1433 ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1),
1434 ObjectAnimator.ofFloat(signal, View.ALPHA, 1),
1435 ObjectAnimator.ofFloat(battery, View.ALPHA, 1),
1436 ObjectAnimator.ofFloat(clock, View.ALPHA, 1)
1437 );
1438 lightsOnAnim.setDuration(250);
1439
1440 mLightsOutAnimation = lightsOutAnim;
1441 mLightsOnAnimation = lightsOnAnim;
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001442 }
Jim Millera073e572012-05-23 17:03:27 -07001443
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001444 mLightsOutAnimation.cancel();
1445 mLightsOnAnimation.cancel();
1446
1447 final Animator a = lightsOut ? mLightsOutAnimation : mLightsOnAnimation;
1448 a.start();
1449
1450 setAreThereNotifications();
1451 }
1452
1453 private boolean areLightsOn() {
1454 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
1455 }
Jim Millera073e572012-05-23 17:03:27 -07001456
Daniel Sandler60ee2562011-07-22 12:34:33 -04001457 public void setLightsOn(boolean on) {
1458 Log.v(TAG, "setLightsOn(" + on + ")");
1459 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001460 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001461 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001462 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001463 }
1464 }
1465
1466 private void notifyUiVisibilityChanged() {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001467 try {
Jeff Brown98365d72012-08-19 20:30:52 -07001468 mWindowManagerService.statusBarVisibilityChanged(mSystemUiVisibility);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001469 } catch (RemoteException ex) {
1470 }
Joe Onorato93056472010-09-10 10:30:46 -04001471 }
1472
Daniel Sandler5c8da942011-06-28 00:29:04 -04001473 public void topAppWindowChanged(boolean showMenu) {
1474 if (DEBUG) {
1475 Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
1476 }
1477 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04001478 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04001479 }
1480
1481 // See above re: lights-out policy for legacy apps.
1482 if (showMenu) setLightsOn(true);
1483 }
1484
Daniel Sandler328310c2011-09-23 15:56:52 -04001485 @Override
1486 public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
1487 boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
1488 || ((vis & InputMethodService.IME_VISIBLE) != 0);
1489
1490 mCommandQueue.setNavigationIconHints(
1491 altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
1492 : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
Winson Chung43229d72012-09-12 18:04:18 -07001493 mSettingsPanel.setImeWindowStatus(vis > 0);
Daniel Sandler328310c2011-09-23 15:56:52 -04001494 }
1495
Jeff Brown2992ea72011-01-28 22:04:14 -08001496 @Override
Winson Chung43229d72012-09-12 18:04:18 -07001497 public void setHardKeyboardStatus(boolean available, boolean enabled) {}
Daniel Sandlere02d8082010-10-08 15:13:22 -04001498
Chris Wren0c8275b2012-05-08 13:36:48 -04001499 @Override
1500 protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001501 // no ticking in lights-out mode
1502 if (!areLightsOn()) return;
Jim Millera073e572012-05-23 17:03:27 -07001503
Daniel Sandler26cda272012-05-22 15:44:08 -04001504 // no ticking in Setup
1505 if (!isDeviceProvisioned()) return;
1506
John Spurlock61e36832012-09-10 09:43:27 -04001507 // not for you
1508 if (!notificationIsForCurrentUser(n)) return;
1509
Joe Onorato808182d2010-07-09 18:52:06 -04001510 // Show the ticker if one is requested. Also don't do this
1511 // until status bar window is attached to the window manager,
1512 // because... well, what's the point otherwise? And trying to
1513 // run a ticker without being attached will crash!
Daniel Sandlera310af82012-04-24 01:20:13 -04001514 if (n.notification.tickerText != null && mStatusBarWindow.getWindowToken() != null) {
Joe Onorato808182d2010-07-09 18:52:06 -04001515 if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
1516 | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
1517 mTicker.addEntry(n);
1518 }
1519 }
1520 }
1521
Joe Onorato808182d2010-07-09 18:52:06 -04001522 private class MyTicker extends Ticker {
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001523 MyTicker(Context context, View sb) {
Joe Onorato808182d2010-07-09 18:52:06 -04001524 super(context, sb);
1525 }
1526
1527 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001528 public void tickerStarting() {
Joe Onorato808182d2010-07-09 18:52:06 -04001529 mTicking = true;
Daniel Sandler173bae22012-09-25 14:37:42 -04001530 mStatusBarContents.setVisibility(View.GONE);
Joe Onorato808182d2010-07-09 18:52:06 -04001531 mTickerView.setVisibility(View.VISIBLE);
1532 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
Daniel Sandler173bae22012-09-25 14:37:42 -04001533 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
Joe Onorato808182d2010-07-09 18:52:06 -04001534 }
1535
1536 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001537 public void tickerDone() {
Daniel Sandler173bae22012-09-25 14:37:42 -04001538 mStatusBarContents.setVisibility(View.VISIBLE);
Joe Onorato808182d2010-07-09 18:52:06 -04001539 mTickerView.setVisibility(View.GONE);
Daniel Sandler173bae22012-09-25 14:37:42 -04001540 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
Joe Onorato808182d2010-07-09 18:52:06 -04001541 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
1542 mTickingDoneListener));
Joe Onorato808182d2010-07-09 18:52:06 -04001543 }
1544
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001545 public void tickerHalting() {
Daniel Sandler173bae22012-09-25 14:37:42 -04001546 mStatusBarContents.setVisibility(View.VISIBLE);
Joe Onorato808182d2010-07-09 18:52:06 -04001547 mTickerView.setVisibility(View.GONE);
Daniel Sandler173bae22012-09-25 14:37:42 -04001548 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001549 // we do not animate the ticker away at this point, just get rid of it (b/6992707)
Joe Onorato808182d2010-07-09 18:52:06 -04001550 }
1551 }
1552
1553 Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
1554 public void onAnimationEnd(Animation animation) {
1555 mTicking = false;
1556 }
1557 public void onAnimationRepeat(Animation animation) {
1558 }
1559 public void onAnimationStart(Animation animation) {
1560 }
1561 };
1562
1563 private Animation loadAnim(int id, Animation.AnimationListener listener) {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001564 Animation anim = AnimationUtils.loadAnimation(mContext, id);
Joe Onorato808182d2010-07-09 18:52:06 -04001565 if (listener != null) {
1566 anim.setAnimationListener(listener);
1567 }
1568 return anim;
1569 }
1570
Daniel Sandler48852952011-12-01 14:34:23 -05001571 public static String viewInfo(View v) {
1572 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
1573 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04001574 }
1575
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001576 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04001577 synchronized (mQueueLock) {
1578 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001579 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04001580 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04001581 pw.println(" mTicking=" + mTicking);
1582 pw.println(" mTracking=" + mTracking);
Daniel Sandlerfdbac772012-07-03 14:30:10 -04001583 pw.println(" mNotificationPanel=" +
1584 ((mNotificationPanel == null)
1585 ? "null"
1586 : (mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""))));
Joe Onorato808182d2010-07-09 18:52:06 -04001587 pw.println(" mAnimating=" + mAnimating
1588 + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
1589 + ", mAnimAccel=" + mAnimAccel);
Jeff Browned5f45a2012-05-03 15:53:47 -07001590 pw.println(" mAnimLastTimeNanos=" + mAnimLastTimeNanos);
Dianne Hackborn1dacf272011-08-02 15:01:22 -07001591 pw.println(" mAnimatingReveal=" + mAnimatingReveal
Joe Onorato808182d2010-07-09 18:52:06 -04001592 + " mViewDelta=" + mViewDelta);
Daniel Sandler36412a72011-08-04 09:35:13 -04001593 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001594 pw.println(" mPile: " + viewInfo(mPile));
Joe Onorato808182d2010-07-09 18:52:06 -04001595 pw.println(" mTickerView: " + viewInfo(mTickerView));
1596 pw.println(" mScrollView: " + viewInfo(mScrollView)
1597 + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04001598 }
Joe Onorato808182d2010-07-09 18:52:06 -04001599
Daniel Sandler48852952011-12-01 14:34:23 -05001600 pw.print(" mNavigationBarView=");
1601 if (mNavigationBarView == null) {
1602 pw.println("null");
1603 } else {
1604 mNavigationBarView.dump(fd, pw, args);
1605 }
1606
Daniel Sandler7579bca2011-08-18 15:47:26 -04001607 if (DUMPTRUCK) {
1608 synchronized (mNotificationData) {
1609 int N = mNotificationData.size();
1610 pw.println(" notification icons: " + N);
1611 for (int i=0; i<N; i++) {
1612 NotificationData.Entry e = mNotificationData.get(i);
1613 pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
1614 StatusBarNotification n = e.notification;
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001615 pw.println(" pkg=" + n.pkg + " id=" + n.id + " score=" + n.score);
Daniel Sandler7579bca2011-08-18 15:47:26 -04001616 pw.println(" notification=" + n.notification);
1617 pw.println(" tickerText=\"" + n.notification.tickerText + "\"");
1618 }
1619 }
1620
1621 int N = mStatusIcons.getChildCount();
1622 pw.println(" system icons: " + N);
1623 for (int i=0; i<N; i++) {
1624 StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
1625 pw.println(" [" + i + "] icon=" + ic);
1626 }
Jim Miller5e6af442011-12-02 18:24:26 -08001627
Daniel Sandler89d97132011-09-08 15:31:57 -04001628 if (false) {
1629 pw.println("see the logcat for a dump of the views we have created.");
1630 // must happen on ui thread
1631 mHandler.post(new Runnable() {
1632 public void run() {
1633 mStatusBarView.getLocationOnScreen(mAbsPos);
1634 Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
1635 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04001636 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04001637 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04001638 }
1639 });
1640 }
Joe Onorato808182d2010-07-09 18:52:06 -04001641 }
Daniel Sandler89d97132011-09-08 15:31:57 -04001642
Daniel Sandler151f00d2012-10-02 22:33:08 -04001643 if (DEBUG_GESTURES) {
1644 pw.print(" status bar gestures: ");
1645 mGestureRec.dump(fd, pw, args);
1646 }
Daniel Sandler33805342012-07-23 15:45:12 -04001647
Daniel Sandler89d97132011-09-08 15:31:57 -04001648 mNetworkController.dump(fd, pw, args);
Joe Onorato808182d2010-07-09 18:52:06 -04001649 }
1650
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001651 @Override
1652 public void createAndAddWindows() {
1653 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04001654 }
Jim Millere898ac52012-04-06 17:10:57 -07001655
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001656 private void addStatusBarWindow() {
1657 // Put up the view
1658 final int height = getStatusBarHeight();
Joe Onorato808182d2010-07-09 18:52:06 -04001659
Daniel Sandlera310af82012-04-24 01:20:13 -04001660 // Now that the status bar window encompasses the sliding panel and its
1661 // translucent backdrop, the entire thing is made TRANSLUCENT and is
1662 // hardware-accelerated.
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001663 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
1664 ViewGroup.LayoutParams.MATCH_PARENT,
1665 height,
1666 WindowManager.LayoutParams.TYPE_STATUS_BAR,
1667 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
1668 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1669 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Daniel Sandlera310af82012-04-24 01:20:13 -04001670 PixelFormat.TRANSLUCENT);
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001671
Romain Guy0901fda2012-05-22 21:10:57 -07001672 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001673
1674 lp.gravity = getStatusBarGravity();
1675 lp.setTitle("StatusBar");
1676 lp.packageName = mContext.getPackageName();
Jim Millere898ac52012-04-06 17:10:57 -07001677
Daniel Sandlera310af82012-04-24 01:20:13 -04001678 makeStatusBarView();
Jeff Brown98365d72012-08-19 20:30:52 -07001679 mWindowManager.addView(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04001680 }
1681
Joe Onorato808182d2010-07-09 18:52:06 -04001682 void setNotificationIconVisibility(boolean visible, int anim) {
1683 int old = mNotificationIcons.getVisibility();
1684 int v = visible ? View.VISIBLE : View.INVISIBLE;
1685 if (old != v) {
1686 mNotificationIcons.setVisibility(v);
1687 mNotificationIcons.startAnimation(loadAnim(anim, null));
1688 }
1689 }
1690
Dianne Hackborn1dacf272011-08-02 15:01:22 -07001691 void updateExpandedInvisiblePosition() {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001692 mTrackingPosition = -mDisplayMetrics.heightPixels;
Dianne Hackborn1dacf272011-08-02 15:01:22 -07001693 }
1694
Daniel Sandler1fac1fd2012-04-30 12:07:30 -04001695 static final float saturate(float a) {
1696 return a < 0f ? 0f : (a > 1f ? 1f : a);
1697 }
1698
Chris Wren8fd12652012-05-09 21:25:57 -04001699 @Override
1700 protected int getExpandedViewMaxHeight() {
Daniel Sandler21b274e2012-05-02 15:07:51 -04001701 return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx;
1702 }
1703
Chris Wren0c8275b2012-05-08 13:36:48 -04001704 @Override
Daniel Sandler08d05e32012-08-08 16:39:54 -04001705 public void updateExpandedViewPos(int thingy) {
Daniel Sandler08d05e32012-08-08 16:39:54 -04001706 if (DEBUG) Slog.v(TAG, "updateExpandedViewPos");
Daniel Sandlere680f542012-09-28 12:22:27 -04001707
1708 // on larger devices, the notification panel is propped open a bit
1709 mNotificationPanel.setMinimumHeight(
1710 (int)(mNotificationPanelMinHeightFrac * mCurrentDisplaySize.y));
1711
Daniel Sandler21b274e2012-05-02 15:07:51 -04001712 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams();
Daniel Sandler21b274e2012-05-02 15:07:51 -04001713 lp.gravity = mNotificationPanelGravity;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04001714 lp.leftMargin = mNotificationPanelMarginPx;
Daniel Sandler21b274e2012-05-02 15:07:51 -04001715 mNotificationPanel.setLayoutParams(lp);
Daniel Sandlere680f542012-09-28 12:22:27 -04001716
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04001717 lp = (FrameLayout.LayoutParams) mSettingsPanel.getLayoutParams();
1718 lp.gravity = mSettingsPanelGravity;
1719 lp.rightMargin = mNotificationPanelMarginPx;
1720 mSettingsPanel.setLayoutParams(lp);
Daniel Sandlerbf526d12012-09-04 22:56:44 -04001721
1722 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001723 }
1724
Daniel Sandler747a9e92012-08-10 16:39:19 -04001725 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07001726 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04001727 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler151f00d2012-10-02 22:33:08 -04001728 if (DEBUG_GESTURES) {
1729 mGestureRec.tag("display",
1730 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
1731 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07001732 }
1733
Joe Onorato808182d2010-07-09 18:52:06 -04001734 private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
1735 public void onClick(View v) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001736 synchronized (mNotificationData) {
Chet Haase2f2022a2011-10-11 06:41:59 -07001737 // animate-swipe all dismissable notifications, then animate the shade closed
1738 int numChildren = mPile.getChildCount();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001739
Chet Haase2f2022a2011-10-11 06:41:59 -07001740 int scrollTop = mScrollView.getScrollY();
1741 int scrollBottom = scrollTop + mScrollView.getHeight();
1742 final ArrayList<View> snapshot = new ArrayList<View>(numChildren);
1743 for (int i=0; i<numChildren; i++) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001744 final View child = mPile.getChildAt(i);
Chet Haase2f2022a2011-10-11 06:41:59 -07001745 if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop &&
1746 child.getTop() < scrollBottom) {
1747 snapshot.add(child);
1748 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001749 }
Craig Mautner93a035c2012-04-09 15:23:59 -07001750 if (snapshot.isEmpty()) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001751 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Craig Mautner93a035c2012-04-09 15:23:59 -07001752 return;
1753 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001754 new Thread(new Runnable() {
1755 @Override
1756 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07001757 // Decrease the delay for every row we animate to give the sense of
1758 // accelerating the swipes
1759 final int ROW_DELAY_DECREMENT = 10;
1760 int currentDelay = 140;
1761 int totalDelay = 0;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001762
Chet Haase2f2022a2011-10-11 06:41:59 -07001763 // Set the shade-animating state to avoid doing other work during
1764 // all of these animations. In particular, avoid layout and
1765 // redrawing when collapsing the shade.
1766 mPile.setViewRemoval(false);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001767
Chet Haase2f2022a2011-10-11 06:41:59 -07001768 mPostCollapseCleanup = new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07001769 @Override
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001770 public void run() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001771 if (DEBUG) {
1772 Slog.v(TAG, "running post-collapse cleanup");
1773 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001774 try {
Chet Haase2f2022a2011-10-11 06:41:59 -07001775 mPile.setViewRemoval(true);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001776 mBarService.onClearAllNotifications();
Chet Haase2f2022a2011-10-11 06:41:59 -07001777 } catch (Exception ex) { }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001778 }
Chet Haase2f2022a2011-10-11 06:41:59 -07001779 };
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001780
Chet Haase2f2022a2011-10-11 06:41:59 -07001781 View sampleView = snapshot.get(0);
1782 int width = sampleView.getWidth();
Craig Mautner93a035c2012-04-09 15:23:59 -07001783 final int velocity = width * 8; // 1000/8 = 125 ms duration
1784 for (final View _v : snapshot) {
Chet Haase2f2022a2011-10-11 06:41:59 -07001785 mHandler.postDelayed(new Runnable() {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001786 @Override
1787 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07001788 mPile.dismissRowAnimated(_v, velocity);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001789 }
Chet Haase2f2022a2011-10-11 06:41:59 -07001790 }, totalDelay);
1791 currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT);
1792 totalDelay += currentDelay;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001793 }
Chet Haase2f2022a2011-10-11 06:41:59 -07001794 // Delay the collapse animation until after all swipe animations have
1795 // finished. Provide some buffer because there may be some extra delay
1796 // before actually starting each swipe animation. Ideally, we'd
1797 // synchronize the end of those animations with the start of the collaps
1798 // exactly.
1799 mHandler.postDelayed(new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07001800 @Override
Chet Haase2f2022a2011-10-11 06:41:59 -07001801 public void run() {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001802 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Chet Haase2f2022a2011-10-11 06:41:59 -07001803 }
1804 }, totalDelay + 225);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001805 }
1806 }).start();
Joe Onorato808182d2010-07-09 18:52:06 -04001807 }
Joe Onorato808182d2010-07-09 18:52:06 -04001808 }
1809 };
1810
Daniel Sandlerd3090562011-08-09 00:28:44 -04001811 private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
1812 public void onClick(View v) {
Daniel Sandler26cda272012-05-22 15:44:08 -04001813 // We take this as a good indicator that Setup is running and we shouldn't
1814 // allow you to go somewhere else
1815 if (!isDeviceProvisioned()) return;
Jim Miller5e6af442011-12-02 18:24:26 -08001816 try {
1817 // Dismiss the lock screen when Settings starts.
1818 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
1819 } catch (RemoteException e) {
1820 }
Amith Yamasani82644082012-08-03 13:09:11 -07001821 v.getContext().startActivityAsUser(new Intent(Settings.ACTION_SETTINGS)
Dianne Hackborn79af1dd2012-08-16 16:42:52 -07001822 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
1823 new UserHandle(UserHandle.USER_CURRENT));
Daniel Sandler11cf1782012-09-27 14:03:08 -04001824 animateCollapsePanels();
Daniel Sandlerd3090562011-08-09 00:28:44 -04001825 }
1826 };
1827
Joe Onorato808182d2010-07-09 18:52:06 -04001828 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
1829 public void onReceive(Context context, Intent intent) {
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001830 Slog.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04001831 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04001832 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Jim Miller9a720f52012-05-30 03:19:43 -07001833 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
Michael Jurka3b1fc472011-06-13 10:54:40 -07001834 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Daniel Sandleredbdd3a2011-06-21 12:57:08 -04001835 String reason = intent.getStringExtra("reason");
Jim Miller9a720f52012-05-30 03:19:43 -07001836 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
1837 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
Michael Jurka3b1fc472011-06-13 10:54:40 -07001838 }
1839 }
Daniel Sandler11cf1782012-09-27 14:03:08 -04001840 animateCollapsePanels(flags);
Joe Onorato808182d2010-07-09 18:52:06 -04001841 }
Daniel Sandlered930e52012-07-03 14:31:22 -04001842 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
1843 // no waiting!
Daniel Sandler08d05e32012-08-08 16:39:54 -04001844 makeExpandedInvisible();
Daniel Sandlered930e52012-07-03 14:31:22 -04001845 }
Joe Onorato808182d2010-07-09 18:52:06 -04001846 else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
Daniel Sandler7f3cf952012-08-31 14:57:09 -04001847 if (DEBUG) {
1848 Slog.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
1849 }
Daniel Sandlere680f542012-09-28 12:22:27 -04001850 mDisplay.getSize(mCurrentDisplaySize);
1851
Joe Onorato808182d2010-07-09 18:52:06 -04001852 updateResources();
Daniel Sandler21b274e2012-05-02 15:07:51 -04001853 repositionNavigationBar();
1854 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Daniel Sandler7f3cf952012-08-31 14:57:09 -04001855 updateShowSearchHoldoff();
1856 }
1857 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
1858 // work around problem where mDisplay.getRotation() is not stable while screen is off (bug 7086018)
1859 repositionNavigationBar();
Joe Onorato808182d2010-07-09 18:52:06 -04001860 }
1861 }
1862 };
1863
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001864 @Override
1865 public void userSwitched(int newUserId) {
1866 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04001867 animateCollapsePanels();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001868 updateNotificationIcons();
John Spurlock919adac2012-10-02 16:41:12 -04001869 resetUserSetupObserver();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001870 }
John Spurlock919adac2012-10-02 16:41:12 -04001871
1872 private void resetUserSetupObserver() {
1873 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
1874 mUserSetupObserver.onChange(false);
1875 mContext.getContentResolver().registerContentObserver(
1876 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
1877 mUserSetupObserver,
1878 mCurrentUserId);
1879 }
1880
Joe Onorato808182d2010-07-09 18:52:06 -04001881 private void setIntruderAlertVisibility(boolean vis) {
Daniel Sandler6b318802012-04-13 14:05:19 -04001882 if (!ENABLE_INTRUDERS) return;
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04001883 if (DEBUG) {
1884 Slog.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
1885 }
Joe Onorato808182d2010-07-09 18:52:06 -04001886 mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
1887 }
1888
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04001889 public void dismissIntruder() {
1890 if (mCurrentlyIntrudingNotification == null) return;
1891
1892 try {
1893 mBarService.onNotificationClear(
1894 mCurrentlyIntrudingNotification.pkg,
Jim Millera073e572012-05-23 17:03:27 -07001895 mCurrentlyIntrudingNotification.tag,
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04001896 mCurrentlyIntrudingNotification.id);
1897 } catch (android.os.RemoteException ex) {
1898 // oh well
1899 }
1900 }
Jim Millere898ac52012-04-06 17:10:57 -07001901
Joe Onorato808182d2010-07-09 18:52:06 -04001902 /**
1903 * Reload some of our resources when the configuration changes.
1904 *
1905 * We don't reload everything when the configuration changes -- we probably
1906 * should, but getting that smooth is tough. Someday we'll fix that. In the
1907 * meantime, just update the things that we know change.
1908 */
1909 void updateResources() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001910 final Context context = mContext;
1911 final Resources res = context.getResources();
Joe Onorato808182d2010-07-09 18:52:06 -04001912
Daniel Sandler1347c302011-08-01 16:47:53 -04001913 if (mClearButton instanceof TextView) {
1914 ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
1915 }
Winson Chungd63c59782012-09-05 17:34:41 -07001916
1917 // Update the QuickSettings container
Daniel Sandler3ffdcc72012-09-23 14:31:48 -04001918 mSettingsPanel.updateResources();
Winson Chungd63c59782012-09-05 17:34:41 -07001919
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001920 loadDimens();
1921 }
Jim Miller5e6af442011-12-02 18:24:26 -08001922
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001923 protected void loadDimens() {
1924 final Resources res = mContext.getResources();
1925
1926 mNaturalBarHeight = res.getDimensionPixelSize(
1927 com.android.internal.R.dimen.status_bar_height);
1928
1929 int newIconSize = res.getDimensionPixelSize(
1930 com.android.internal.R.dimen.status_bar_icon_size);
1931 int newIconHPadding = res.getDimensionPixelSize(
1932 R.dimen.status_bar_icon_padding);
1933
1934 if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
1935// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
1936 mIconHPadding = newIconHPadding;
1937 mIconSize = newIconSize;
1938 //reloadAllNotificationIcons(); // reload the tray
1939 }
1940
Joe Onorato808182d2010-07-09 18:52:06 -04001941 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
1942
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07001943 mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
1944 mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
1945 mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
1946 mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
1947
1948 mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
1949 mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
1950
1951 mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
1952 mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
1953
1954 mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
Jim Millera073e572012-05-23 17:03:27 -07001955
Daniel Sandlere5011a32012-06-11 16:07:52 -04001956 mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity);
1957
Daniel Sandler21b274e2012-05-02 15:07:51 -04001958 mNotificationPanelMarginBottomPx
1959 = (int) res.getDimension(R.dimen.notification_panel_margin_bottom);
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04001960 mNotificationPanelMarginPx
Daniel Sandler21b274e2012-05-02 15:07:51 -04001961 = (int) res.getDimension(R.dimen.notification_panel_margin_left);
1962 mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
1963 if (mNotificationPanelGravity <= 0) {
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04001964 mNotificationPanelGravity = Gravity.LEFT | Gravity.TOP;
1965 }
1966 mSettingsPanelGravity = res.getInteger(R.integer.settings_panel_layout_gravity);
1967 if (mSettingsPanelGravity <= 0) {
1968 mSettingsPanelGravity = Gravity.RIGHT | Gravity.TOP;
Daniel Sandler21b274e2012-05-02 15:07:51 -04001969 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001970
1971 mCarrierLabelHeight = res.getDimensionPixelSize(R.dimen.carrier_label_height);
Daniel Sandlerbf526d12012-09-04 22:56:44 -04001972 mNotificationHeaderHeight = res.getDimensionPixelSize(R.dimen.notification_panel_header_height);
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07001973
Daniel Sandlere680f542012-09-28 12:22:27 -04001974 mNotificationPanelMinHeightFrac = res.getFraction(R.dimen.notification_panel_min_height_frac, 1, 1);
1975 if (mNotificationPanelMinHeightFrac < 0f || mNotificationPanelMinHeightFrac > 1f) {
1976 mNotificationPanelMinHeightFrac = 0f;
John Spurlock804df702012-06-01 15:34:27 -04001977 }
Daniel Sandlere680f542012-09-28 12:22:27 -04001978
1979 if (false) Slog.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04001980 }
1981
Joe Onorato808182d2010-07-09 18:52:06 -04001982 //
1983 // tracing
1984 //
1985
1986 void postStartTracing() {
1987 mHandler.postDelayed(mStartTracing, 3000);
1988 }
1989
1990 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001991 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
1992 Context.VIBRATOR_SERVICE);
Joe Onorato808182d2010-07-09 18:52:06 -04001993 vib.vibrate(250);
1994 }
1995
1996 Runnable mStartTracing = new Runnable() {
1997 public void run() {
1998 vibrate();
1999 SystemClock.sleep(250);
2000 Slog.d(TAG, "startTracing");
2001 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2002 mHandler.postDelayed(mStopTracing, 10000);
2003 }
2004 };
2005
2006 Runnable mStopTracing = new Runnable() {
2007 public void run() {
2008 android.os.Debug.stopMethodTracing();
2009 Slog.d(TAG, "stopTracing");
2010 vibrate();
2011 }
2012 };
Chris Wren0c8275b2012-05-08 13:36:48 -04002013
2014 @Override
2015 protected void haltTicker() {
2016 mTicker.halt();
2017 }
Jim Miller670d9dd2012-05-12 13:28:26 -07002018
2019 @Override
Jim Millerb4238e02012-05-14 15:26:20 -07002020 protected boolean shouldDisableNavbarGestures() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002021 return mExpandedVisible || (mDisabled & StatusBarManager.DISABLE_HOME) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07002022 }
Joe Onorato808182d2010-07-09 18:52:06 -04002023
Romain Guy648342f2012-05-25 10:44:45 -07002024 private static class FastColorDrawable extends Drawable {
2025 private final int mColor;
2026
2027 public FastColorDrawable(int color) {
2028 mColor = 0xff000000 | color;
2029 }
2030
2031 @Override
2032 public void draw(Canvas canvas) {
2033 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
2034 }
2035
2036 @Override
2037 public void setAlpha(int alpha) {
2038 }
2039
2040 @Override
2041 public void setColorFilter(ColorFilter cf) {
2042 }
2043
2044 @Override
2045 public int getOpacity() {
2046 return PixelFormat.OPAQUE;
2047 }
2048
2049 @Override
2050 public void setBounds(int left, int top, int right, int bottom) {
2051 }
2052
2053 @Override
2054 public void setBounds(Rect bounds) {
2055 }
2056 }
2057}