blob: 30af333f76693d892085556f7d23e9874389201f [file] [log] [blame]
Joe Onorato808182d2010-07-09 18:52:06 -04001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Joe Onoratofd52b182010-11-10 18:00:52 -080017package com.android.systemui.statusbar.phone;
Joe Onorato808182d2010-07-09 18:52:06 -040018
Daniel Sandlerd7e96862012-04-26 01:10:29 -040019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
21import android.animation.AnimatorSet;
Daniel Sandler0761e4c2011-08-11 00:19:49 -040022import android.animation.ObjectAnimator;
Daniel Sandler101784e2012-10-15 13:39:38 -040023import android.animation.TimeInterpolator;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070024import android.app.ActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040025import android.app.ActivityManagerNative;
Joe Onorato808182d2010-07-09 18:52:06 -040026import android.app.Notification;
27import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040028import android.app.StatusBarManager;
29import android.content.BroadcastReceiver;
30import android.content.Context;
31import android.content.Intent;
32import android.content.IntentFilter;
Daniel Sandlerb17a7262012-10-05 14:32:50 -040033import android.content.SharedPreferences;
Michael Jurka7f2668c2012-03-27 07:49:52 -070034import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040035import android.database.ContentObserver;
Romain Guy648342f2012-05-25 10:44:45 -070036import android.graphics.Canvas;
37import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040038import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040039import android.graphics.Point;
Romain Guy648342f2012-05-25 10:44:45 -070040import android.graphics.PorterDuff;
Joe Onorato808182d2010-07-09 18:52:06 -040041import android.graphics.Rect;
Romain Guy648342f2012-05-25 10:44:45 -070042import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070043import android.inputmethodservice.InputMethodService;
John Spurlock919adac2012-10-02 16:41:12 -040044import android.os.Handler;
Joe Onorato808182d2010-07-09 18:52:06 -040045import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040046import android.os.Message;
Michael Jurka7f2668c2012-03-27 07:49:52 -070047import android.os.RemoteException;
Daniel Sandler1d4d30a2011-04-28 12:35:29 -040048import android.os.ServiceManager;
Joe Onorato808182d2010-07-09 18:52:06 -040049import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070050import android.os.UserHandle;
Daniel Sandlerd3090562011-08-09 00:28:44 -040051import android.provider.Settings;
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -070052import android.service.dreams.DreamService;
Daniel Sandlera2fbe532012-08-10 01:19:03 -040053import android.service.dreams.IDreamManager;
Daniel Sandler36412a72011-08-04 09:35:13 -040054import android.util.DisplayMetrics;
Joe Onorato808182d2010-07-09 18:52:06 -040055import android.util.Log;
Michael Jurka7f2668c2012-03-27 07:49:52 -070056import android.util.Slog;
Joe Onorato808182d2010-07-09 18:52:06 -040057import android.view.Display;
58import android.view.Gravity;
Joe Onorato808182d2010-07-09 18:52:06 -040059import android.view.MotionEvent;
60import android.view.VelocityTracker;
61import android.view.View;
62import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -070063import android.view.ViewGroup.LayoutParams;
Daniel Sandler101784e2012-10-15 13:39:38 -040064import android.view.ViewPropertyAnimator;
Daniel Sandlerb17a7262012-10-05 14:32:50 -040065import android.view.ViewStub;
Joe Onorato808182d2010-07-09 18:52:06 -040066import android.view.WindowManager;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040067import android.view.animation.AccelerateInterpolator;
Joe Onorato808182d2010-07-09 18:52:06 -040068import android.view.animation.Animation;
69import android.view.animation.AnimationUtils;
Daniel Sandler67e7d902012-06-06 16:32:21 -040070import android.view.animation.DecelerateInterpolator;
Daniel Sandler21b274e2012-05-02 15:07:51 -040071import android.widget.FrameLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040072import android.widget.ImageView;
73import android.widget.LinearLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040074import android.widget.ScrollView;
75import android.widget.TextView;
Michael Jurkaa600fd92012-06-25 15:57:05 -070076
Joe Onorato808182d2010-07-09 18:52:06 -040077import com.android.internal.statusbar.StatusBarIcon;
Joe Onorato808182d2010-07-09 18:52:06 -040078import com.android.internal.statusbar.StatusBarNotification;
Joe Onorato808182d2010-07-09 18:52:06 -040079import com.android.systemui.R;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -050080import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -070081import com.android.systemui.statusbar.CommandQueue;
Daniel Sandler33805342012-07-23 15:45:12 -040082import com.android.systemui.statusbar.GestureRecorder;
Michael Jurka7f2668c2012-03-27 07:49:52 -070083import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -040084import com.android.systemui.statusbar.NotificationData.Entry;
Christian Robertson2e347422011-08-11 14:01:04 -070085import com.android.systemui.statusbar.SignalClusterView;
Michael Jurka7f2668c2012-03-27 07:49:52 -070086import com.android.systemui.statusbar.StatusBarIconView;
Daniel Sandler2b697352011-07-22 16:23:09 -040087import com.android.systemui.statusbar.policy.BatteryController;
Winson Chungd63c59782012-09-05 17:34:41 -070088import com.android.systemui.statusbar.policy.BluetoothController;
Michael Jurka7f2668c2012-03-27 07:49:52 -070089import com.android.systemui.statusbar.policy.DateView;
Daniel Sandler6a858c32012-03-12 14:38:58 -040090import com.android.systemui.statusbar.policy.IntruderAlertView;
Daniel Sandler2b697352011-07-22 16:23:09 -040091import com.android.systemui.statusbar.policy.LocationController;
92import com.android.systemui.statusbar.policy.NetworkController;
Daniel Sandler8ba33c92011-10-04 21:49:30 -040093import com.android.systemui.statusbar.policy.NotificationRowLayout;
Michael Jurkaa600fd92012-06-25 15:57:05 -070094import com.android.systemui.statusbar.policy.OnSizeChangedListener;
Daniel Sandlerb17a7262012-10-05 14:32:50 -040095import com.android.systemui.statusbar.policy.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -040096
Daniel Sandler6a858c32012-03-12 14:38:58 -040097import java.io.FileDescriptor;
98import java.io.PrintWriter;
99import java.util.ArrayList;
100
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500101public class PhoneStatusBar extends BaseStatusBar {
Joe Onoratofd52b182010-11-10 18:00:52 -0800102 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400103 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Daniel Sandlerc1ebee42012-03-26 19:39:46 -0400104 public static final boolean SPEW = DEBUG;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400105 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandler151f00d2012-10-02 22:33:08 -0400106 public static final boolean DEBUG_GESTURES = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400107
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400108 public static final boolean DEBUG_CLINGS = false;
109
Daniel Sandlerace0bd72012-10-11 09:56:45 -0700110 public static final boolean ENABLE_NOTIFICATION_PANEL_CLING = false;
111
Daniel Sandler040c2e42012-10-17 00:56:33 -0400112 public static final boolean SETTINGS_DRAG_SHORTCUT = true;
113
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400114 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400115 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400116
Joe Onorato808182d2010-07-09 18:52:06 -0400117 public static final String ACTION_STATUSBAR_START
118 = "com.android.internal.policy.statusbar.START";
119
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400120 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400121 private static final int MSG_CLOSE_PANELS = 1001;
122 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700123 // 1020-1030 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400124
125 // will likely move to a resource or other tunable param at some point
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400126 private static final int INTRUDER_ALERT_DECAY_MS = 0; // disabled, was 10000;
Joe Onorato808182d2010-07-09 18:52:06 -0400127
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400128 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
129
Daniel Sandler58b173b2012-05-03 11:25:29 -0400130 private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
131 private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
132
Daniel Sandlerdc940ea2011-08-25 14:35:53 -0700133 // fling gesture tuning parameters, scaled to display density
134 private float mSelfExpandVelocityPx; // classic value: 2000px/s
135 private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
136 private float mFlingExpandMinVelocityPx; // classic value: 200px/s
137 private float mFlingCollapseMinVelocityPx; // classic value: 200px/s
138 private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1)
139 private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
140 private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s
141
142 private float mExpandAccelPx; // classic value: 2000px/s/s
143 private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
144
Daniel Sandlere5011a32012-06-11 16:07:52 -0400145 private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little
146 // faster than mSelfCollapseVelocityPx)
147
Joe Onoratofd52b182010-11-10 18:00:52 -0800148 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400149
Daniel Sandler2b697352011-07-22 16:23:09 -0400150 // These are no longer handled by the policy, because we need custom strategies for them
Winson Chungd63c59782012-09-05 17:34:41 -0700151 BluetoothController mBluetoothController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400152 BatteryController mBatteryController;
153 LocationController mLocationController;
154 NetworkController mNetworkController;
Jim Miller5e6af442011-12-02 18:24:26 -0800155
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400156 int mNaturalBarHeight = -1;
157 int mIconSize = -1;
158 int mIconHPadding = -1;
Joe Onorato808182d2010-07-09 18:52:06 -0400159 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400160 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400161
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400162 IDreamManager mDreamManager;
Daniel Sandler1d4d30a2011-04-28 12:35:29 -0400163
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400164 StatusBarWindowView mStatusBarWindow;
Joe Onoratofd52b182010-11-10 18:00:52 -0800165 PhoneStatusBarView mStatusBarView;
Daniel Sandlera310af82012-04-24 01:20:13 -0400166
Joe Onorato808182d2010-07-09 18:52:06 -0400167 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400168 Object mQueueLock = new Object();
169
Daniel Sandler173bae22012-09-25 14:37:42 -0400170 // viewgroup containing the normal contents of the statusbar
171 LinearLayout mStatusBarContents;
172
173 // right-hand icons
174 LinearLayout mSystemIconArea;
175
176 // left-hand icons
Joe Onorato808182d2010-07-09 18:52:06 -0400177 LinearLayout mStatusIcons;
Daniel Sandler173bae22012-09-25 14:37:42 -0400178 // the icons themselves
179 IconMerger mNotificationIcons;
180 // [+>
181 View mMoreIcon;
Joe Onorato808182d2010-07-09 18:52:06 -0400182
183 // expanded notifications
Daniel Sandler040c2e42012-10-17 00:56:33 -0400184 NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400185 ScrollView mScrollView;
Joe Onorato808182d2010-07-09 18:52:06 -0400186 View mExpandedContents;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400187 int mNotificationPanelGravity;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400188 int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx;
Daniel Sandlere680f542012-09-28 12:22:27 -0400189 float mNotificationPanelMinHeightFrac;
Daniel Sandler66d92f82012-06-13 13:36:52 -0400190 boolean mNotificationPanelIsFullScreenWidth;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400191 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400192
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400193 // settings
Daniel Sandler101784e2012-10-15 13:39:38 -0400194 QuickSettings mQS;
195 boolean mHasSettingsPanel, mHasFlipSettings;
Daniel Sandler3ffdcc72012-09-23 14:31:48 -0400196 SettingsPanelView mSettingsPanel;
Daniel Sandler101784e2012-10-15 13:39:38 -0400197 View mFlipSettingsView;
198 QuickSettingsContainerView mSettingsContainer;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400199 int mSettingsPanelGravity;
200
Joe Onorato808182d2010-07-09 18:52:06 -0400201 // top bar
Daniel Sandler3679bf52012-10-16 21:30:28 -0400202 View mNotificationPanelHeader;
203 View mDateTimeView;
Daniel Sandler1347c302011-08-01 16:47:53 -0400204 View mClearButton;
Daniel Sandler101784e2012-10-15 13:39:38 -0400205 ImageView mSettingsButton, mNotificationButton;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400206
Daniel Sandler3d32a242012-06-05 13:44:14 -0400207 // carrier/wifi label
208 private TextView mCarrierLabel;
209 private boolean mCarrierLabelVisible = false;
210 private int mCarrierLabelHeight;
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400211 private TextView mEmergencyCallLabel;
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400212 private int mNotificationHeaderHeight;
213
214 private boolean mShowCarrierInPanel = false;
Daniel Sandler3d32a242012-06-05 13:44:14 -0400215
Joe Onorato808182d2010-07-09 18:52:06 -0400216 // position
217 int[] mPositionTmp = new int[2];
Joe Onorato808182d2010-07-09 18:52:06 -0400218 boolean mExpandedVisible;
219
220 // the date view
221 DateView mDateView;
222
223 // for immersive activities
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400224 private IntruderAlertView mIntruderAlertView;
Joe Onorato808182d2010-07-09 18:52:06 -0400225
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400226 // on-screen navigation buttons
Daniel Sandler0129b312011-05-11 11:54:11 -0400227 private NavigationBarView mNavigationBarView = null;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400228
Joe Onorato808182d2010-07-09 18:52:06 -0400229 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400230 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400231
232 // ticker
233 private Ticker mTicker;
234 private View mTickerView;
235 private boolean mTicking;
236
237 // Tracking finger for opening/closing.
238 int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
239 boolean mTracking;
240 VelocityTracker mVelocityTracker;
241
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400242 // help screen
243 private boolean mClingShown;
244 private ViewGroup mCling;
245 private boolean mSuppressStatusBarDrags; // while a cling is up, briefly deaden the bar to give things time to settle
246
Joe Onorato808182d2010-07-09 18:52:06 -0400247 boolean mAnimating;
Daniel Sandlerfbab8ae2012-05-09 02:06:29 -0400248 boolean mClosing; // only valid when mAnimating; indicates the initial acceleration
Joe Onorato808182d2010-07-09 18:52:06 -0400249 float mAnimY;
250 float mAnimVel;
251 float mAnimAccel;
Jeff Browned5f45a2012-05-03 15:53:47 -0700252 long mAnimLastTimeNanos;
Joe Onorato808182d2010-07-09 18:52:06 -0400253 boolean mAnimatingReveal = false;
254 int mViewDelta;
John Spurlock804df702012-06-01 15:34:27 -0400255 float mFlingVelocity;
256 int mFlingY;
Joe Onorato808182d2010-07-09 18:52:06 -0400257 int[] mAbsPos = new int[2];
Chet Haase2f2022a2011-10-11 06:41:59 -0700258 Runnable mPostCollapseCleanup = null;
259
Daniel Sandler173bae22012-09-25 14:37:42 -0400260 private Animator mLightsOutAnimation;
261 private Animator mLightsOnAnimation;
Joe Onorato808182d2010-07-09 18:52:06 -0400262
263 // for disabling the status bar
264 int mDisabled = 0;
265
Daniel Sandler60ee2562011-07-22 12:34:33 -0400266 // tracking calls to View.setSystemUiVisibility()
267 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
268
Daniel Sandler36412a72011-08-04 09:35:13 -0400269 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700270
Daniel Sandler33805342012-07-23 15:45:12 -0400271 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400272 private final GestureRecorder mGestureRec = DEBUG_GESTURES
273 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
274 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400275
Daniel Sandler328310c2011-09-23 15:56:52 -0400276 private int mNavigationIconHints = 0;
Romain Guyf7f16f72012-05-24 19:13:56 -0700277 private final Animator.AnimatorListener mMakeIconsInvisible = new AnimatorListenerAdapter() {
278 @Override
279 public void onAnimationEnd(Animator animation) {
Daniel Sandler67e7d902012-06-06 16:32:21 -0400280 // double-check to avoid races
Daniel Sandler173bae22012-09-25 14:37:42 -0400281 if (mStatusBarContents.getAlpha() == 0) {
Dianne Hackborn7ff30112012-11-08 11:12:09 -0800282 if (DEBUG) Slog.d(TAG, "makeIconsInvisible");
Daniel Sandler173bae22012-09-25 14:37:42 -0400283 mStatusBarContents.setVisibility(View.INVISIBLE);
Daniel Sandler67e7d902012-06-06 16:32:21 -0400284 }
Romain Guyf7f16f72012-05-24 19:13:56 -0700285 }
286 };
Daniel Sandler328310c2011-09-23 15:56:52 -0400287
John Spurlock919adac2012-10-02 16:41:12 -0400288 // ensure quick settings is disabled until the current user makes it through the setup wizard
289 private boolean mUserSetup = false;
290 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
291 @Override
292 public void onChange(boolean selfChange) {
293 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
294 mContext.getContentResolver(),
295 Settings.Secure.USER_SETUP_COMPLETE,
296 0 /*default */,
297 mCurrentUserId);
John Spurlocke4e8c562012-10-04 09:55:01 -0400298 if (MULTIUSER_DEBUG) Slog.d(TAG, String.format("User setup changed: " +
299 "selfChange=%s userSetup=%s mUserSetup=%s",
300 selfChange, userSetup, mUserSetup));
Daniel Sandlera8ef3b02012-11-29 15:52:39 -0500301 if (mSettingsButton != null && mHasFlipSettings) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400302 mSettingsButton.setVisibility(userSetup ? View.VISIBLE : View.INVISIBLE);
303 }
304 if (mSettingsPanel != null) {
John Spurlocke4e8c562012-10-04 09:55:01 -0400305 mSettingsPanel.setEnabled(userSetup);
Daniel Sandler101784e2012-10-15 13:39:38 -0400306 }
John Spurlock919adac2012-10-02 16:41:12 -0400307 if (userSetup != mUserSetup) {
308 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400309 if (!mUserSetup && mStatusBarView != null)
310 animateCollapseQuickSettings();
311 }
312 }
313 };
314
Joe Onorato808182d2010-07-09 18:52:06 -0400315 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400316 public void start() {
317 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
318 .getDefaultDisplay();
Joe Onorato808182d2010-07-09 18:52:06 -0400319
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400320 mDreamManager = IDreamManager.Stub.asInterface(
Dianne Hackbornbe87e2f2012-09-28 16:31:34 -0700321 ServiceManager.checkService(DreamService.DREAM_SERVICE));
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400322
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500323 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400324
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400325 addNavigationBar();
326
Daniel Sandlerfc6fda32012-02-24 22:00:46 -0500327 if (ENABLE_INTRUDERS) addIntruderView();
Joe Onorato808182d2010-07-09 18:52:06 -0400328
329 // Lastly, call to the icon policy to install/update all the icons.
Joe Onoratofd52b182010-11-10 18:00:52 -0800330 mIconPolicy = new PhoneStatusBarPolicy(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400331 }
332
333 // ================================================================================
334 // Constructing the view
335 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700336 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400337 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400338
339 Resources res = context.getResources();
340
Daniel Sandler6e8db882011-10-26 15:40:51 -0400341 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400342 loadDimens();
Joe Onorato808182d2010-07-09 18:52:06 -0400343
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700344 mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
345
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400346 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
Daniel Sandlera310af82012-04-24 01:20:13 -0400347 R.layout.super_status_bar, null);
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400348 mStatusBarWindow.mService = this;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400349 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
350 @Override
351 public boolean onTouch(View v, MotionEvent event) {
352 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandlere7237fc2012-08-14 16:08:27 -0400353 if (mExpandedVisible && !mAnimating) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400354 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400355 }
356 }
Chris Wren5de6e942012-05-16 14:22:21 -0400357 return mStatusBarWindow.onTouchEvent(event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400358 }});
359
Daniel Sandlera310af82012-04-24 01:20:13 -0400360 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400361 mStatusBarView.setBar(this);
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700362
Daniel Sandler08d05e32012-08-08 16:39:54 -0400363
364 PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
365 mStatusBarView.setPanelHolder(holder);
366
Daniel Sandler040c2e42012-10-17 00:56:33 -0400367 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(R.id.notification_panel);
368 mNotificationPanel.setStatusBar(this);
Daniel Sandler66d92f82012-06-13 13:36:52 -0400369 mNotificationPanelIsFullScreenWidth =
370 (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
Joe Onorato808182d2010-07-09 18:52:06 -0400371
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700372 // make the header non-responsive to clicks
373 mNotificationPanel.findViewById(R.id.header).setOnTouchListener(
374 new View.OnTouchListener() {
375 @Override
376 public boolean onTouch(View v, MotionEvent event) {
377 return true; // e eats everything
378 }
379 });
380
Jeff Brown98365d72012-08-19 20:30:52 -0700381 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700382 mStatusBarWindow.setBackground(null);
Romain Guy648342f2012-05-25 10:44:45 -0700383 mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
384 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700385 }
Daniel Sandler6b318802012-04-13 14:05:19 -0400386 if (ENABLE_INTRUDERS) {
387 mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
388 mIntruderAlertView.setVisibility(View.GONE);
389 mIntruderAlertView.setBar(this);
390 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400391 if (MULTIUSER_DEBUG) {
392 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info);
393 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
394 }
Joe Onorato808182d2010-07-09 18:52:06 -0400395
John Spurlockd5ef5462012-06-13 11:19:51 -0400396 updateShowSearchHoldoff();
397
Daniel Sandler0129b312011-05-11 11:54:11 -0400398 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700399 boolean showNav = mWindowManagerService.hasNavigationBar();
Daniel Sandler4a066c52012-04-20 14:49:13 -0400400 if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400401 if (showNav) {
Jim Miller5e6af442011-12-02 18:24:26 -0800402 mNavigationBarView =
Daniel Sandler0129b312011-05-11 11:54:11 -0400403 (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400404
Daniel Sandler6da2b762011-09-14 16:04:59 -0400405 mNavigationBarView.setDisabledFlags(mDisabled);
Jim Millere898ac52012-04-06 17:10:57 -0700406 mNavigationBarView.setBar(this);
Daniel Sandler0129b312011-05-11 11:54:11 -0400407 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400408 } catch (RemoteException ex) {
409 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400410 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400411
Joe Onorato808182d2010-07-09 18:52:06 -0400412 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400413 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400414
415 mSystemIconArea = (LinearLayout) mStatusBarView.findViewById(R.id.system_icon_area);
Daniel Sandlera310af82012-04-24 01:20:13 -0400416 mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons);
417 mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
Daniel Sandler05e24142011-11-10 11:56:49 -0500418 mNotificationIcons.setOverflowIndicator(mMoreIcon);
Daniel Sandler173bae22012-09-25 14:37:42 -0400419 mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
Daniel Sandlera310af82012-04-24 01:20:13 -0400420 mTickerView = mStatusBarView.findViewById(R.id.ticker);
Joe Onorato808182d2010-07-09 18:52:06 -0400421
Daniel Sandlera310af82012-04-24 01:20:13 -0400422 mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems);
Daniel Sandlere5011a32012-06-11 16:07:52 -0400423 mPile.setLayoutTransitionsEnabled(false);
Daniel Sandlerf7a19562012-04-04 14:04:21 -0400424 mPile.setLongPressListener(getNotificationLongClicker());
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400425 mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
Daniel Sandlerd7141482011-08-18 15:14:52 -0400426
Daniel Sandler3679bf52012-10-16 21:30:28 -0400427 mNotificationPanelHeader = mStatusBarWindow.findViewById(R.id.header);
428
Daniel Sandlera310af82012-04-24 01:20:13 -0400429 mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button);
Joe Onorato808182d2010-07-09 18:52:06 -0400430 mClearButton.setOnClickListener(mClearButtonListener);
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400431 mClearButton.setAlpha(0f);
Romain Guy8900e632012-05-25 12:08:39 -0700432 mClearButton.setVisibility(View.INVISIBLE);
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400433 mClearButton.setEnabled(false);
Daniel Sandlera310af82012-04-24 01:20:13 -0400434 mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400435
436 mHasSettingsPanel = res.getBoolean(R.bool.config_hasSettingsPanel);
Daniel Sandler101784e2012-10-15 13:39:38 -0400437 mHasFlipSettings = res.getBoolean(R.bool.config_hasFlipSettingsPanel);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400438
Daniel Sandler3679bf52012-10-16 21:30:28 -0400439 mDateTimeView = mNotificationPanelHeader.findViewById(R.id.datetime);
440 if (mHasFlipSettings) {
441 mDateTimeView.setOnClickListener(mClockClickListener);
442 mDateTimeView.setEnabled(true);
443 }
444
Daniel Sandlere111ad32012-10-13 15:17:45 -0400445 mSettingsButton = (ImageView) mStatusBarWindow.findViewById(R.id.settings_button);
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400446 if (mSettingsButton != null) {
Daniel Sandlere111ad32012-10-13 15:17:45 -0400447 mSettingsButton.setOnClickListener(mSettingsButtonListener);
448 if (mHasSettingsPanel) {
449 if (mStatusBarView.hasFullWidthNotifications()) {
450 // the settings panel is hiding behind this button
451 mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
452 mSettingsButton.setVisibility(View.VISIBLE);
453 } else {
454 // there is a settings panel, but it's on the other side of the (large) screen
Daniel Sandler7382a022012-10-22 14:36:50 -0400455 final View buttonHolder = mStatusBarWindow.findViewById(
456 R.id.settings_button_holder);
457 if (buttonHolder != null) {
458 buttonHolder.setVisibility(View.GONE);
459 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400460 }
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700461 } else {
Daniel Sandlere111ad32012-10-13 15:17:45 -0400462 // no settings panel, go straight to settings
463 mSettingsButton.setVisibility(View.VISIBLE);
464 mSettingsButton.setImageResource(R.drawable.ic_notify_settings);
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700465 }
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400466 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400467 if (mHasFlipSettings) {
468 mNotificationButton = (ImageView) mStatusBarWindow.findViewById(R.id.notification_button);
469 if (mNotificationButton != null) {
470 mNotificationButton.setOnClickListener(mNotificationButtonListener);
471 }
472 }
473
Daniel Sandlera310af82012-04-24 01:20:13 -0400474 mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll);
Daniel Sandler079b33d2012-03-02 16:29:41 -0500475 mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
Daniel Sandler3679bf52012-10-16 21:30:28 -0400476 if (!mNotificationPanelIsFullScreenWidth) {
477 mScrollView.setSystemUiVisibility(
478 View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER |
479 View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
480 View.STATUS_BAR_DISABLE_CLOCK);
481 }
Joe Onorato808182d2010-07-09 18:52:06 -0400482
Daniel Sandlera310af82012-04-24 01:20:13 -0400483 mTicker = new MyTicker(context, mStatusBarView);
Joe Onorato808182d2010-07-09 18:52:06 -0400484
Daniel Sandlera310af82012-04-24 01:20:13 -0400485 TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText);
Joe Onorato808182d2010-07-09 18:52:06 -0400486 tickerView.mTicker = mTicker;
487
Joe Onorato808182d2010-07-09 18:52:06 -0400488 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
489
Joe Onorato808182d2010-07-09 18:52:06 -0400490 // set the inital view visibility
491 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400492
Daniel Sandler2b697352011-07-22 16:23:09 -0400493 // Other icons
494 mLocationController = new LocationController(mContext); // will post a notification
495 mBatteryController = new BatteryController(mContext);
Daniel Sandlera310af82012-04-24 01:20:13 -0400496 mBatteryController.addIconView((ImageView)mStatusBarView.findViewById(R.id.battery));
Daniel Sandler2b697352011-07-22 16:23:09 -0400497 mNetworkController = new NetworkController(mContext);
Winson Chungd63c59782012-09-05 17:34:41 -0700498 mBluetoothController = new BluetoothController(mContext);
Jim Miller5e6af442011-12-02 18:24:26 -0800499 final SignalClusterView signalCluster =
Daniel Sandlera310af82012-04-24 01:20:13 -0400500 (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
Daniel Sandler3d32a242012-06-05 13:44:14 -0400501
Winson Chungd63c59782012-09-05 17:34:41 -0700502
Christian Robertson2e347422011-08-11 14:01:04 -0700503 mNetworkController.addSignalCluster(signalCluster);
Daniel Sandler28f89d42011-08-15 14:04:15 -0400504 signalCluster.setNetworkController(mNetworkController);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400505
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400506 mEmergencyCallLabel = (TextView)mStatusBarWindow.findViewById(R.id.emergency_calls_only);
507 if (mEmergencyCallLabel != null) {
508 mNetworkController.addEmergencyLabelView(mEmergencyCallLabel);
Daniel Sandler3679bf52012-10-16 21:30:28 -0400509 mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() {
510 public void onClick(View v) { }});
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400511 mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
512 @Override
513 public void onLayoutChange(View v, int left, int top, int right, int bottom,
514 int oldLeft, int oldTop, int oldRight, int oldBottom) {
515 updateCarrierLabelVisibility(false);
516 }});
517 }
518
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400519 mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
520 mShowCarrierInPanel = (mCarrierLabel != null);
Dianne Hackborn7ff30112012-11-08 11:12:09 -0800521 if (DEBUG) Slog.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400522 if (mShowCarrierInPanel) {
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400523 mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
524
Daniel Sandler67234c42012-06-15 13:17:39 -0400525 // for mobile devices, we always show mobile connection info here (SPN/PLMN)
526 // for other devices, we show whatever network is connected
Daniel Sandler18ac7822012-06-11 16:07:18 -0400527 if (mNetworkController.hasMobileDataFeature()) {
528 mNetworkController.addMobileLabelView(mCarrierLabel);
529 } else {
Daniel Sandler67234c42012-06-15 13:17:39 -0400530 mNetworkController.addCombinedLabelView(mCarrierLabel);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400531 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400532
533 // set up the dynamic hide/show of the label
534 mPile.setOnSizeChangedListener(new OnSizeChangedListener() {
535 @Override
536 public void onSizeChanged(View view, int w, int h, int oldw, int oldh) {
537 updateCarrierLabelVisibility(false);
538 }
539 });
Daniel Sandler3d32a242012-06-05 13:44:14 -0400540 }
541
Daniel Sandlere111ad32012-10-13 15:17:45 -0400542 // Quick Settings (where available, some restrictions apply)
543 if (mHasSettingsPanel) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400544 // first, figure out where quick settings should be inflated
545 final View settings_stub;
546 if (mHasFlipSettings) {
547 // a version of quick settings that flips around behind the notifications
548 settings_stub = mStatusBarWindow.findViewById(R.id.flip_settings_stub);
549 if (settings_stub != null) {
550 mFlipSettingsView = ((ViewStub)settings_stub).inflate();
551 mFlipSettingsView.setVisibility(View.GONE);
552 mFlipSettingsView.setVerticalScrollBarEnabled(false);
553 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400554 } else {
Daniel Sandler101784e2012-10-15 13:39:38 -0400555 // full quick settings panel
556 settings_stub = mStatusBarWindow.findViewById(R.id.quick_settings_stub);
557 if (settings_stub != null) {
558 mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate();
559 } else {
560 mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
561 }
562
563 if (mSettingsPanel != null) {
Daniel Sandler101784e2012-10-15 13:39:38 -0400564 if (!ActivityManager.isHighEndGfx()) {
565 mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
566 R.color.notification_panel_solid_background)));
567 }
568 }
Daniel Sandlere111ad32012-10-13 15:17:45 -0400569 }
570
Daniel Sandler101784e2012-10-15 13:39:38 -0400571 // wherever you find it, Quick Settings needs a container to survive
572 mSettingsContainer = (QuickSettingsContainerView)
573 mStatusBarWindow.findViewById(R.id.quick_settings_container);
574 if (mSettingsContainer != null) {
575 mQS = new QuickSettings(mContext, mSettingsContainer);
Daniel Sandler3679bf52012-10-16 21:30:28 -0400576 if (!mNotificationPanelIsFullScreenWidth) {
577 mSettingsContainer.setSystemUiVisibility(
578 View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
579 | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
580 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400581 if (mSettingsPanel != null) {
582 mSettingsPanel.setQuickSettings(mQS);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400583 }
Daniel Sandler101784e2012-10-15 13:39:38 -0400584 mQS.setService(this);
Daniel Sandlerfe3376b2012-10-16 19:54:02 -0400585 mQS.setBar(mStatusBarView);
Daniel Sandler101784e2012-10-15 13:39:38 -0400586 mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
587 mLocationController);
588 } else {
589 mQS = null; // fly away, be free
Daniel Sandlere111ad32012-10-13 15:17:45 -0400590 }
Siva Velusamy537421b2012-09-14 14:45:02 -0700591 }
592
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400593 mClingShown = ! (DEBUG_CLINGS
594 || !Prefs.read(mContext).getBoolean(Prefs.SHOWN_QUICK_SETTINGS_HELP, false));
595
Daniel Sandlerace0bd72012-10-11 09:56:45 -0700596 if (!ENABLE_NOTIFICATION_PANEL_CLING || ActivityManager.isRunningInTestHarness()) {
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400597 mClingShown = true;
598 }
599
Jim Miller5e6af442011-12-02 18:24:26 -0800600// final ImageView wimaxRSSI =
Daniel Sandler633eabe2011-11-09 16:49:44 -0500601// (ImageView)sb.findViewById(R.id.wimax_signal);
602// if (wimaxRSSI != null) {
603// mNetworkController.addWimaxIconView(wimaxRSSI);
604// }
Michael Jurka3b1fc472011-06-13 10:54:40 -0700605
Joe Onorato808182d2010-07-09 18:52:06 -0400606 // receive broadcasts
607 IntentFilter filter = new IntentFilter();
608 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
609 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
610 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400611 filter.addAction(Intent.ACTION_SCREEN_ON);
Joe Onorato808182d2010-07-09 18:52:06 -0400612 context.registerReceiver(mBroadcastReceiver, filter);
613
John Spurlock919adac2012-10-02 16:41:12 -0400614 // listen for USER_SETUP_COMPLETE setting (per-user)
615 resetUserSetupObserver();
616
Daniel Sandlera310af82012-04-24 01:20:13 -0400617 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400618 }
619
Michael Jurka7f2668c2012-03-27 07:49:52 -0700620 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -0700621 protected View getStatusBarView() {
622 return mStatusBarView;
623 }
624
625 @Override
Jim Millerf2a16b22011-07-06 17:32:48 -0700626 protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
Michael Jurka3cd0a592011-08-16 12:40:30 -0700627 boolean opaque = false;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700628 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Jim Millerf2a16b22011-07-06 17:32:48 -0700629 layoutParams.width,
630 layoutParams.height,
Michael Jurka3b1fc472011-06-13 10:54:40 -0700631 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
632 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
633 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700634 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Michael Jurka3cd0a592011-08-16 12:40:30 -0700635 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
Jeff Brown98365d72012-08-19 20:30:52 -0700636 if (ActivityManager.isHighEndGfx()) {
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700637 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Michael Jurkaf16fc512012-02-27 15:02:23 -0800638 } else {
639 lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
Michael Jurkaf3abbad2012-06-04 14:00:32 -0700640 lp.dimAmount = 0.75f;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -0700641 }
Michael Jurka3b1fc472011-06-13 10:54:40 -0700642 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
643 lp.setTitle("RecentsPanel");
Michael Jurka99a96552012-01-27 17:23:38 -0800644 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700645 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
646 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
647 return lp;
648 }
649
Jim Millere898ac52012-04-06 17:10:57 -0700650 @Override
651 protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
652 boolean opaque = false;
653 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
654 LayoutParams.MATCH_PARENT,
655 LayoutParams.MATCH_PARENT,
656 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
657 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
658 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
659 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
660 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
Jeff Brown98365d72012-08-19 20:30:52 -0700661 if (ActivityManager.isHighEndGfx()) {
Jim Millere898ac52012-04-06 17:10:57 -0700662 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Jim Millere898ac52012-04-06 17:10:57 -0700663 }
664 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
665 lp.setTitle("SearchPanel");
666 // TODO: Define custom animation for Search panel
667 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
668 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
669 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
670 return lp;
671 }
672
Jim Millere898ac52012-04-06 17:10:57 -0700673 @Override
674 protected void updateSearchPanel() {
675 super.updateSearchPanel();
Jim Miller354619c2012-04-27 17:33:44 -0700676 mSearchPanelView.setStatusBarView(mNavigationBarView);
Jim Millere898ac52012-04-06 17:10:57 -0700677 mNavigationBarView.setDelegateView(mSearchPanelView);
678 }
679
680 @Override
681 public void showSearchPanel() {
Jim Millerb490c3e2012-05-31 13:34:16 -0700682 super.showSearchPanel();
John Spurlock7a733442012-11-08 09:08:14 -0500683 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlerd5483c32012-10-19 16:44:15 -0400684
685 // we want to freeze the sysui state wherever it is
686 mSearchPanelView.setSystemUiVisibility(mSystemUiVisibility);
687
Jim Millere898ac52012-04-06 17:10:57 -0700688 WindowManager.LayoutParams lp =
689 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
690 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Jeff Brown98365d72012-08-19 20:30:52 -0700691 mWindowManager.updateViewLayout(mNavigationBarView, lp);
Jim Millere898ac52012-04-06 17:10:57 -0700692 }
693
694 @Override
695 public void hideSearchPanel() {
696 super.hideSearchPanel();
697 WindowManager.LayoutParams lp =
698 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
699 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Jeff Brown98365d72012-08-19 20:30:52 -0700700 mWindowManager.updateViewLayout(mNavigationBarView, lp);
Jim Millere898ac52012-04-06 17:10:57 -0700701 }
702
Joe Onorato808182d2010-07-09 18:52:06 -0400703 protected int getStatusBarGravity() {
704 return Gravity.TOP | Gravity.FILL_HORIZONTAL;
705 }
706
Joe Onoratodc100302011-01-11 17:07:41 -0800707 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -0400708 if (mNaturalBarHeight < 0) {
709 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -0700710 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -0400711 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
712 }
713 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -0800714 }
715
Daniel Sandler5c8da942011-06-28 00:29:04 -0400716 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
717 public void onClick(View v) {
718 toggleRecentApps();
719 }
720 };
Chris Wren0c8275b2012-05-08 13:36:48 -0400721
Jim Miller9a720f52012-05-30 03:19:43 -0700722 private int mShowSearchHoldoff = 0;
723 private Runnable mShowSearchPanel = new Runnable() {
724 public void run() {
725 showSearchPanel();
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400726 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700727 }
728 };
729
Jim Millere898ac52012-04-06 17:10:57 -0700730 View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
731 public boolean onTouch(View v, MotionEvent event) {
732 switch(event.getAction()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700733 case MotionEvent.ACTION_DOWN:
Daniel Sandlerd5483c32012-10-19 16:44:15 -0400734 if (!shouldDisableNavbarGestures()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700735 mHandler.removeCallbacks(mShowSearchPanel);
736 mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
737 }
738 break;
739
740 case MotionEvent.ACTION_UP:
741 case MotionEvent.ACTION_CANCEL:
742 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400743 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700744 break;
745 }
746 return false;
Jim Millere898ac52012-04-06 17:10:57 -0700747 }
748 };
Daniel Sandler5c8da942011-06-28 00:29:04 -0400749
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400750 private void awakenDreams() {
751 if (mDreamManager != null) {
752 try {
753 mDreamManager.awaken();
754 } catch (RemoteException e) {
755 // fine, stay asleep then
756 }
757 }
758 }
759
Michael Jurka412cba82011-10-17 09:05:00 -0700760 private void prepareNavigationBarView() {
761 mNavigationBarView.reorient();
762
763 mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
Michael Jurka80343f62012-10-18 13:13:46 +0200764 mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
Jim Miller998bb762012-05-21 13:37:27 -0700765 mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
Daniel Sandler207d5482012-11-06 16:23:43 -0500766 mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
Jim Millere898ac52012-04-06 17:10:57 -0700767 updateSearchPanel();
Michael Jurka412cba82011-10-17 09:05:00 -0700768 }
769
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400770 // For small-screen devices (read: phones) that lack hardware navigation buttons
771 private void addNavigationBar() {
Daniel Sandler4a066c52012-04-20 14:49:13 -0400772 if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -0400773 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700774
Michael Jurka412cba82011-10-17 09:05:00 -0700775 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400776
Jeff Brown98365d72012-08-19 20:30:52 -0700777 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400778 }
779
780 private void repositionNavigationBar() {
Daniel Sandler0129b312011-05-11 11:54:11 -0400781 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700782
Michael Jurka412cba82011-10-17 09:05:00 -0700783 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400784
Jeff Brown98365d72012-08-19 20:30:52 -0700785 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400786 }
787
John Spurlock1bbd49d2012-10-19 11:09:32 -0400788 private void notifyNavigationBarScreenOn(boolean screenOn) {
789 if (mNavigationBarView == null) return;
790 mNavigationBarView.notifyScreenOn(screenOn);
791 }
792
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400793 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400794 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -0700795 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400796 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
797 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400798 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
799 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -0700800 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -0400801 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -0700802 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Daniel Sandlera3884492011-08-16 15:55:44 -0400803 PixelFormat.OPAQUE);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700804 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -0700805 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700806 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
807 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400808
809 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400810 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400811 return lp;
812 }
813
Joe Onoratodc100302011-01-11 17:07:41 -0800814 private void addIntruderView() {
Joe Onorato808182d2010-07-09 18:52:06 -0400815 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
816 ViewGroup.LayoutParams.MATCH_PARENT,
817 ViewGroup.LayoutParams.WRAP_CONTENT,
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400818 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
Joe Onorato808182d2010-07-09 18:52:06 -0400819 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
820 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
821 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
822 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Jeff Brown46e75292010-11-10 16:53:45 -0800823 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
824 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Joe Onorato808182d2010-07-09 18:52:06 -0400825 PixelFormat.TRANSLUCENT);
826 lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400827 //lp.y += height * 1.5; // FIXME
Joe Onorato808182d2010-07-09 18:52:06 -0400828 lp.setTitle("IntruderAlert");
Dianne Hackborn59aed382011-08-02 17:31:44 -0700829 lp.packageName = mContext.getPackageName();
830 lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
Joe Onorato808182d2010-07-09 18:52:06 -0400831
Jeff Brown98365d72012-08-19 20:30:52 -0700832 mWindowManager.addView(mIntruderAlertView, lp);
Joe Onorato808182d2010-07-09 18:52:06 -0400833 }
834
835 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
836 if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
837 + " icon=" + icon);
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700838 StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400839 view.set(icon);
840 mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
841 }
842
843 public void updateIcon(String slot, int index, int viewIndex,
844 StatusBarIcon old, StatusBarIcon icon) {
845 if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
846 + " old=" + old + " icon=" + icon);
847 StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
848 view.set(icon);
849 }
850
851 public void removeIcon(String slot, int index, int viewIndex) {
852 if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
853 mStatusIcons.removeViewAt(viewIndex);
854 }
855
856 public void addNotification(IBinder key, StatusBarNotification notification) {
Dianne Hackborn7ff30112012-11-08 11:12:09 -0800857 if (DEBUG) Slog.d(TAG, "addNotification score=" + notification.score);
Joe Onorato808182d2010-07-09 18:52:06 -0400858 StatusBarIconView iconView = addNotificationViews(key, notification);
859 if (iconView == null) return;
860
861 boolean immersive = false;
862 try {
863 immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
Daniel Sandler8355e932011-08-11 00:27:45 -0400864 if (DEBUG) {
865 Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
866 }
Joe Onorato808182d2010-07-09 18:52:06 -0400867 } catch (RemoteException ex) {
868 }
Daniel Sandler6b318802012-04-13 14:05:19 -0400869
870 /*
871 * DISABLED due to missing API
Daniel Sandlerfc6fda32012-02-24 22:00:46 -0500872 if (ENABLE_INTRUDERS && (
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400873 // TODO(dsandler): Only if the screen is on
874 notification.notification.intruderView != null)) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500875 Slog.d(TAG, "Presenting high-priority notification");
876 // special new transient ticker mode
877 // 1. Populate mIntruderAlertView
Jim Millere898ac52012-04-06 17:10:57 -0700878
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400879 if (notification.notification.intruderView == null) {
880 Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
881 return;
882 }
Joe Onorato808182d2010-07-09 18:52:06 -0400883
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400884 // bind the click event to the content area
885 PendingIntent contentIntent = notification.notification.contentIntent;
886 final View.OnClickListener listener = (contentIntent != null)
887 ? new NotificationClicker(contentIntent,
888 notification.pkg, notification.tag, notification.id)
889 : null;
Joe Onorato808182d2010-07-09 18:52:06 -0400890
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400891 mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener);
Joe Onorato808182d2010-07-09 18:52:06 -0400892
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400893 mCurrentlyIntrudingNotification = notification;
Jim Millere898ac52012-04-06 17:10:57 -0700894
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500895 // 2. Animate mIntruderAlertView in
896 mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
Joe Onorato808182d2010-07-09 18:52:06 -0400897
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500898 // 3. Set alarm to age the notification off (TODO)
899 mHandler.removeMessages(MSG_HIDE_INTRUDER);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400900 if (INTRUDER_ALERT_DECAY_MS > 0) {
901 mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
902 }
Jim Millera073e572012-05-23 17:03:27 -0700903 } else
Daniel Sandler6b318802012-04-13 14:05:19 -0400904 */
Jim Millera073e572012-05-23 17:03:27 -0700905
Daniel Sandler6b318802012-04-13 14:05:19 -0400906 if (notification.notification.fullScreenIntent != null) {
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -0400907 // Stop screensaver if the notification has a full-screen intent.
908 // (like an incoming phone call)
909 awakenDreams();
910
Joe Onorato808182d2010-07-09 18:52:06 -0400911 // not immersive & a full-screen alert should be shown
Dianne Hackborn7ff30112012-11-08 11:12:09 -0800912 if (DEBUG) Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
Joe Onorato808182d2010-07-09 18:52:06 -0400913 try {
914 notification.notification.fullScreenIntent.send();
915 } catch (PendingIntent.CanceledException e) {
916 }
917 } else {
918 // usual case: status bar visible & not immersive
919
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400920 // show the ticker if there isn't an intruder too
921 if (mCurrentlyIntrudingNotification == null) {
Chris Wren0c8275b2012-05-08 13:36:48 -0400922 tick(null, notification, true);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400923 }
Joe Onorato808182d2010-07-09 18:52:06 -0400924 }
925
926 // Recalculate the position of the sliding windows and the titles.
927 setAreThereNotifications();
928 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
929 }
930
Joe Onorato808182d2010-07-09 18:52:06 -0400931 public void removeNotification(IBinder key) {
Joe Onorato808182d2010-07-09 18:52:06 -0400932 StatusBarNotification old = removeNotificationViews(key);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400933 if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -0400934
935 if (old != null) {
936 // Cancel the ticker if it's still running
937 mTicker.removeEntry(old);
938
939 // Recalculate the position of the sliding windows and the titles.
Joe Onorato808182d2010-07-09 18:52:06 -0400940 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Jim Millere898ac52012-04-06 17:10:57 -0700941
Daniel Sandler6b318802012-04-13 14:05:19 -0400942 if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) {
Daniel Sandlerfa7887b2012-03-26 09:43:31 -0400943 mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
944 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400945
946 if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 && !mAnimating) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400947 animateCollapsePanels();
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400948 }
Joe Onorato808182d2010-07-09 18:52:06 -0400949 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -0400950
951 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400952 }
953
John Spurlockd5ef5462012-06-13 11:19:51 -0400954 private void updateShowSearchHoldoff() {
955 mShowSearchHoldoff = mContext.getResources().getInteger(
956 R.integer.config_show_search_delay);
Michael Jurka3b1fc472011-06-13 10:54:40 -0700957 }
958
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400959 private void loadNotificationShade() {
Daniel Sandler26cda272012-05-22 15:44:08 -0400960 if (mPile == null) return;
961
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400962 int N = mNotificationData.size();
963
964 ArrayList<View> toShow = new ArrayList<View>();
965
Daniel Sandler26cda272012-05-22 15:44:08 -0400966 final boolean provisioned = isDeviceProvisioned();
967 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400968 for (int i=0; i<N; i++) {
Daniel Sandler26cda272012-05-22 15:44:08 -0400969 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400970 if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
971 if (!notificationIsForCurrentUser(ent.notification)) continue;
972 toShow.add(ent.row);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400973 }
974
975 ArrayList<View> toRemove = new ArrayList<View>();
976 for (int i=0; i<mPile.getChildCount(); i++) {
977 View child = mPile.getChildAt(i);
978 if (!toShow.contains(child)) {
979 toRemove.add(child);
Joe Onorato808182d2010-07-09 18:52:06 -0400980 }
981 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400982
983 for (View remove : toRemove) {
984 mPile.removeView(remove);
985 }
986
987 for (int i=0; i<toShow.size(); i++) {
988 View v = toShow.get(i);
989 if (v.getParent() == null) {
Daniel Sandler2561b0b2012-02-13 21:04:12 -0500990 mPile.addView(v, i);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400991 }
992 }
Daniel Sandler26cda272012-05-22 15:44:08 -0400993
Daniel Sandler6e5fe432012-09-16 15:34:36 -0400994 if (mSettingsButton != null) {
995 mSettingsButton.setEnabled(isDeviceProvisioned());
996 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400997 }
998
Chris Wren0c8275b2012-05-08 13:36:48 -0400999 @Override
1000 protected void updateNotificationIcons() {
Daniel Sandler26cda272012-05-22 15:44:08 -04001001 if (mNotificationIcons == null) return;
1002
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001003 loadNotificationShade();
1004
1005 final LinearLayout.LayoutParams params
1006 = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
1007
1008 int N = mNotificationData.size();
1009
1010 if (DEBUG) {
1011 Slog.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
1012 }
1013
1014 ArrayList<View> toShow = new ArrayList<View>();
1015
Daniel Sandler26cda272012-05-22 15:44:08 -04001016 final boolean provisioned = isDeviceProvisioned();
1017 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001018 for (int i=0; i<N; i++) {
Daniel Sandler58b173b2012-05-03 11:25:29 -04001019 Entry ent = mNotificationData.get(N-i-1);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001020 if (!((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE)
1021 || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
1022 if (!notificationIsForCurrentUser(ent.notification)) continue;
1023 toShow.add(ent.icon);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001024 }
1025
1026 ArrayList<View> toRemove = new ArrayList<View>();
1027 for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
1028 View child = mNotificationIcons.getChildAt(i);
1029 if (!toShow.contains(child)) {
1030 toRemove.add(child);
1031 }
1032 }
1033
1034 for (View remove : toRemove) {
1035 mNotificationIcons.removeView(remove);
1036 }
1037
1038 for (int i=0; i<toShow.size(); i++) {
1039 View v = toShow.get(i);
1040 if (v.getParent() == null) {
1041 mNotificationIcons.addView(v, i, params);
1042 }
1043 }
1044 }
1045
Daniel Sandlere5011a32012-06-11 16:07:52 -04001046 protected void updateCarrierLabelVisibility(boolean force) {
Daniel Sandlerbf526d12012-09-04 22:56:44 -04001047 if (!mShowCarrierInPanel) return;
Daniel Sandler3d32a242012-06-05 13:44:14 -04001048 // The idea here is to only show the carrier label when there is enough room to see it,
1049 // i.e. when there aren't enough notifications to fill the panel.
1050 if (DEBUG) {
1051 Slog.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
1052 mPile.getHeight(), mScrollView.getHeight(), mCarrierLabelHeight));
1053 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -04001054
1055 final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
1056 final boolean makeVisible =
1057 !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
Daniel Sandler101784e2012-10-15 13:39:38 -04001058 && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight)
1059 && mScrollView.getVisibility() == View.VISIBLE;
Daniel Sandler3d32a242012-06-05 13:44:14 -04001060
Daniel Sandlere5011a32012-06-11 16:07:52 -04001061 if (force || mCarrierLabelVisible != makeVisible) {
Daniel Sandler3d32a242012-06-05 13:44:14 -04001062 mCarrierLabelVisible = makeVisible;
1063 if (DEBUG) {
1064 Slog.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
1065 }
1066 mCarrierLabel.animate().cancel();
1067 if (makeVisible) {
1068 mCarrierLabel.setVisibility(View.VISIBLE);
1069 }
1070 mCarrierLabel.animate()
1071 .alpha(makeVisible ? 1f : 0f)
1072 //.setStartDelay(makeVisible ? 500 : 0)
1073 //.setDuration(makeVisible ? 750 : 100)
1074 .setDuration(150)
1075 .setListener(makeVisible ? null : new AnimatorListenerAdapter() {
1076 @Override
1077 public void onAnimationEnd(Animator animation) {
1078 if (!mCarrierLabelVisible) { // race
1079 mCarrierLabel.setVisibility(View.INVISIBLE);
1080 mCarrierLabel.setAlpha(0f);
1081 }
1082 }
1083 })
1084 .start();
1085 }
1086 }
1087
Chris Wren0c8275b2012-05-08 13:36:48 -04001088 @Override
1089 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001090 final boolean any = mNotificationData.size() > 0;
Joe Onorato808182d2010-07-09 18:52:06 -04001091
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001092 final boolean clearable = any && mNotificationData.hasClearableItems();
1093
1094 if (DEBUG) {
1095 Slog.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
1096 + " any=" + any + " clearable=" + clearable);
1097 }
1098
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001099 if (mHasFlipSettings
1100 && mFlipSettingsView != null
Daniel Sandlerf249efc2012-10-17 16:42:36 -04001101 && mFlipSettingsView.getVisibility() == View.VISIBLE
1102 && mScrollView.getVisibility() != View.VISIBLE) {
1103 // the flip settings panel is unequivocally showing; we should not be shown
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001104 mClearButton.setVisibility(View.INVISIBLE);
1105 } else if (mClearButton.isShown()) {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001106 if (clearable != (mClearButton.getAlpha() == 1.0f)) {
Romain Guy8900e632012-05-25 12:08:39 -07001107 ObjectAnimator clearAnimation = ObjectAnimator.ofFloat(
1108 mClearButton, "alpha", clearable ? 1.0f : 0.0f).setDuration(250);
1109 clearAnimation.addListener(new AnimatorListenerAdapter() {
1110 @Override
1111 public void onAnimationEnd(Animator animation) {
1112 if (mClearButton.getAlpha() <= 0.0f) {
1113 mClearButton.setVisibility(View.INVISIBLE);
1114 }
1115 }
1116
1117 @Override
1118 public void onAnimationStart(Animator animation) {
1119 if (mClearButton.getAlpha() <= 0.0f) {
1120 mClearButton.setVisibility(View.VISIBLE);
1121 }
1122 }
1123 });
1124 clearAnimation.start();
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001125 }
1126 } else {
1127 mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
Romain Guy8900e632012-05-25 12:08:39 -07001128 mClearButton.setVisibility(clearable ? View.VISIBLE : View.INVISIBLE);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001129 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001130 mClearButton.setEnabled(clearable);
Romain Guy8900e632012-05-25 12:08:39 -07001131
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001132 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
1133 final boolean showDot = (any&&!areLightsOn());
1134 if (showDot != (nlo.getAlpha() == 1.0f)) {
1135 if (showDot) {
1136 nlo.setAlpha(0f);
1137 nlo.setVisibility(View.VISIBLE);
1138 }
1139 nlo.animate()
1140 .alpha(showDot?1:0)
1141 .setDuration(showDot?750:250)
1142 .setInterpolator(new AccelerateInterpolator(2.0f))
1143 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1144 @Override
1145 public void onAnimationEnd(Animator _a) {
1146 nlo.setVisibility(View.GONE);
1147 }
1148 })
1149 .start();
1150 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001151
Daniel Sandlere5011a32012-06-11 16:07:52 -04001152 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001153 }
1154
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001155 public void showClock(boolean show) {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001156 if (mStatusBarView == null) return;
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001157 View clock = mStatusBarView.findViewById(R.id.clock);
1158 if (clock != null) {
1159 clock.setVisibility(show ? View.VISIBLE : View.GONE);
1160 }
1161 }
Joe Onorato808182d2010-07-09 18:52:06 -04001162
1163 /**
1164 * State is one or more of the DISABLE constants from StatusBarManager.
1165 */
1166 public void disable(int state) {
1167 final int old = mDisabled;
1168 final int diff = state ^ old;
1169 mDisabled = state;
1170
Daniel Sandlere21f2882011-08-18 10:14:59 -04001171 if (DEBUG) {
1172 Slog.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
1173 old, state, diff));
1174 }
1175
Daniel Sandler6da2b762011-09-14 16:04:59 -04001176 StringBuilder flagdbg = new StringBuilder();
1177 flagdbg.append("disable: < ");
1178 flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
1179 flagdbg.append(((diff & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
1180 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
1181 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
1182 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
1183 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
1184 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "TICKER" : "ticker");
1185 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
1186 flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
1187 flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001188 flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
1189 flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
Daniel Sandlerdba93562011-10-06 16:39:58 -04001190 flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
1191 flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
1192 flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
1193 flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001194 flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
1195 flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001196 flagdbg.append(((state & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
1197 flagdbg.append(((diff & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001198 flagdbg.append(">");
1199 Slog.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07001200
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001201 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001202 mSystemIconArea.animate().cancel();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001203 if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001204 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001205 .alpha(0f)
1206 .translationY(mNaturalBarHeight*0.5f)
Daniel Sandler67e7d902012-06-06 16:32:21 -04001207 .setDuration(175)
1208 .setInterpolator(new DecelerateInterpolator(1.5f))
1209 .setListener(mMakeIconsInvisible)
1210 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001211 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001212 mSystemIconArea.setVisibility(View.VISIBLE);
1213 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001214 .alpha(1f)
1215 .translationY(0)
1216 .setStartDelay(0)
1217 .setInterpolator(new DecelerateInterpolator(1.5f))
1218 .setDuration(175)
1219 .start();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001220 }
1221 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04001222
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001223 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
1224 boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
1225 showClock(show);
1226 }
Joe Onorato808182d2010-07-09 18:52:06 -04001227 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1228 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001229 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04001230 }
1231 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001232
Jim Miller5e6af442011-12-02 18:24:26 -08001233 if ((diff & (StatusBarManager.DISABLE_HOME
1234 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001235 | StatusBarManager.DISABLE_BACK
1236 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04001237 // the nav bar will take care of these
Daniel Sandlerd9283b902011-09-14 21:42:00 -04001238 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001239
Daniel Sandlerdba93562011-10-06 16:39:58 -04001240 if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04001241 // close recents if it's visible
1242 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1243 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1244 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001245 }
1246
Joe Onorato808182d2010-07-09 18:52:06 -04001247 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1248 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Joe Onorato808182d2010-07-09 18:52:06 -04001249 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001250 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001251 }
Daniel Sandler173bae22012-09-25 14:37:42 -04001252
1253 mNotificationIcons.animate()
1254 .alpha(0f)
1255 .translationY(mNaturalBarHeight*0.5f)
1256 .setDuration(175)
1257 .setInterpolator(new DecelerateInterpolator(1.5f))
1258 .setListener(mMakeIconsInvisible)
1259 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001260 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001261 mNotificationIcons.setVisibility(View.VISIBLE);
1262 mNotificationIcons.animate()
1263 .alpha(1f)
1264 .translationY(0)
1265 .setStartDelay(0)
1266 .setInterpolator(new DecelerateInterpolator(1.5f))
1267 .setDuration(175)
1268 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001269 }
1270 } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1271 if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001272 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001273 }
1274 }
1275 }
1276
Michael Jurka7f2668c2012-03-27 07:49:52 -07001277 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07001278 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001279 return new PhoneStatusBar.H();
1280 }
1281
Joe Onorato808182d2010-07-09 18:52:06 -04001282 /**
1283 * All changes to the status bar and notifications funnel through here and are batched.
1284 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07001285 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04001286 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001287 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04001288 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001289 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04001290 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001291 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04001292 case MSG_OPEN_SETTINGS_PANEL:
1293 animateExpandSettingsPanel();
1294 break;
1295 case MSG_CLOSE_PANELS:
1296 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001297 break;
Joe Onorato808182d2010-07-09 18:52:06 -04001298 case MSG_SHOW_INTRUDER:
1299 setIntruderAlertVisibility(true);
1300 break;
1301 case MSG_HIDE_INTRUDER:
1302 setIntruderAlertVisibility(false);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04001303 mCurrentlyIntrudingNotification = null;
Joe Onorato808182d2010-07-09 18:52:06 -04001304 break;
1305 }
1306 }
1307 }
1308
Daniel Sandler040c2e42012-10-17 00:56:33 -04001309 public Handler getHandler() {
1310 return mHandler;
1311 }
1312
Joe Onorato808182d2010-07-09 18:52:06 -04001313 View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
1314 public void onFocusChange(View v, boolean hasFocus) {
1315 // Because 'v' is a ViewGroup, all its children will be (un)selected
1316 // too, which allows marqueeing to work.
1317 v.setSelected(hasFocus);
1318 }
1319 };
1320
Daniel Sandler08d05e32012-08-08 16:39:54 -04001321 void makeExpandedVisible(boolean revealAfterDraw) {
Joe Onorato808182d2010-07-09 18:52:06 -04001322 if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
1323 if (mExpandedVisible) {
1324 return;
1325 }
Jim Millera073e572012-05-23 17:03:27 -07001326
Joe Onorato808182d2010-07-09 18:52:06 -04001327 mExpandedVisible = true;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001328 mPile.setLayoutTransitionsEnabled(true);
John Spurlockd5ef5462012-06-13 11:19:51 -04001329 if (mNavigationBarView != null)
1330 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001331
Daniel Sandlere5011a32012-06-11 16:07:52 -04001332 updateCarrierLabelVisibility(true);
Daniel Sandler3d32a242012-06-05 13:44:14 -04001333
Joe Onorato808182d2010-07-09 18:52:06 -04001334 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Daniel Sandlera310af82012-04-24 01:20:13 -04001335
1336 // Expand the window to encompass the full screen in anticipation of the drag.
1337 // This is only possible to do atomically because the status bar is at the top of the screen!
1338 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001339 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1340 lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Daniel Sandler21b274e2012-05-02 15:07:51 -04001341 lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
Jeff Brown98365d72012-08-19 20:30:52 -07001342 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Daniel Sandlera310af82012-04-24 01:20:13 -04001343
John Spurlock804df702012-06-01 15:34:27 -04001344 // Updating the window layout will force an expensive traversal/redraw.
1345 // Kick off the reveal animation after this is complete to avoid animation latency.
1346 if (revealAfterDraw) {
Daniel Sandler08d05e32012-08-08 16:39:54 -04001347// mHandler.post(mStartRevealAnimation);
John Spurlock804df702012-06-01 15:34:27 -04001348 }
1349
Daniel Sandlera310af82012-04-24 01:20:13 -04001350 visibilityChanged(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001351 }
1352
Daniel Sandler11cf1782012-09-27 14:03:08 -04001353 public void animateCollapsePanels() {
1354 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001355 }
1356
Daniel Sandler11cf1782012-09-27 14:03:08 -04001357 public void animateCollapsePanels(int flags) {
Joe Onorato808182d2010-07-09 18:52:06 -04001358 if (SPEW) {
Daniel Sandler198a0302012-08-17 16:04:31 -04001359 Slog.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04001360 + " mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04001361 + " mAnimating=" + mAnimating
Daniel Sandlered930e52012-07-03 14:31:22 -04001362 + " mAnimatingReveal=" + mAnimatingReveal
Joe Onorato808182d2010-07-09 18:52:06 -04001363 + " mAnimY=" + mAnimY
Jim Miller9a720f52012-05-30 03:19:43 -07001364 + " mAnimVel=" + mAnimVel
1365 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04001366 }
1367
Jim Miller9a720f52012-05-30 03:19:43 -07001368 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Michael Jurka3b1fc472011-06-13 10:54:40 -07001369 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1370 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1371 }
Jim Miller9a720f52012-05-30 03:19:43 -07001372
1373 if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
1374 mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
1375 mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
1376 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07001377
Daniel Sandlerac47ff72012-10-23 10:41:44 -04001378 mStatusBarWindow.cancelExpandHelper();
Daniel Sandler08d05e32012-08-08 16:39:54 -04001379 mStatusBarView.collapseAllPanels(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001380 }
1381
Daniel Sandler101784e2012-10-15 13:39:38 -04001382 public ViewPropertyAnimator setVisibilityWhenDone(
1383 final ViewPropertyAnimator a, final View v, final int vis) {
1384 a.setListener(new AnimatorListenerAdapter() {
1385 @Override
1386 public void onAnimationEnd(Animator animation) {
1387 v.setVisibility(vis);
1388 a.setListener(null); // oneshot
1389 }
1390 });
1391 return a;
1392 }
1393
1394 public Animator setVisibilityWhenDone(
1395 final Animator a, final View v, final int vis) {
1396 a.addListener(new AnimatorListenerAdapter() {
1397 @Override
1398 public void onAnimationEnd(Animator animation) {
1399 v.setVisibility(vis);
1400 }
1401 });
1402 return a;
1403 }
1404
1405 public Animator interpolator(TimeInterpolator ti, Animator a) {
1406 a.setInterpolator(ti);
1407 return a;
1408 }
1409
1410 public Animator startDelay(int d, Animator a) {
1411 a.setStartDelay(d);
1412 return a;
1413 }
1414
1415 public Animator start(Animator a) {
1416 a.start();
1417 return a;
1418 }
1419
1420 final TimeInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
1421 final TimeInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
1422 final int FLIP_DURATION_OUT = 125;
1423 final int FLIP_DURATION_IN = 225;
1424 final int FLIP_DURATION = (FLIP_DURATION_IN + FLIP_DURATION_OUT);
1425
1426 Animator mScrollViewAnim, mFlipSettingsViewAnim, mNotificationButtonAnim,
1427 mSettingsButtonAnim, mClearButtonAnim;
1428
Daniel Sandler08d05e32012-08-08 16:39:54 -04001429 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001430 public void animateExpandNotificationsPanel() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001431 if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
Joe Onorato808182d2010-07-09 18:52:06 -04001432 if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1433 return ;
1434 }
Joe Onorato808182d2010-07-09 18:52:06 -04001435
Daniel Sandler08d05e32012-08-08 16:39:54 -04001436 mNotificationPanel.expand();
Daniel Sandler040c2e42012-10-17 00:56:33 -04001437 if (mHasFlipSettings && mScrollView.getVisibility() != View.VISIBLE) {
1438 flipToNotifications();
Daniel Sandler101784e2012-10-15 13:39:38 -04001439 }
Joe Onorato808182d2010-07-09 18:52:06 -04001440
1441 if (false) postStartTracing();
1442 }
1443
Daniel Sandler040c2e42012-10-17 00:56:33 -04001444 public void flipToNotifications() {
1445 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1446 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1447 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1448 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1449 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1450
1451 mScrollView.setVisibility(View.VISIBLE);
1452 mScrollViewAnim = start(
1453 startDelay(FLIP_DURATION_OUT,
1454 interpolator(mDecelerateInterpolator,
1455 ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f, 1f)
1456 .setDuration(FLIP_DURATION_IN)
1457 )));
1458 mFlipSettingsViewAnim = start(
1459 setVisibilityWhenDone(
1460 interpolator(mAccelerateInterpolator,
1461 ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f, 0f)
1462 )
1463 .setDuration(FLIP_DURATION_OUT),
1464 mFlipSettingsView, View.INVISIBLE));
1465 mNotificationButtonAnim = start(
1466 setVisibilityWhenDone(
1467 ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
1468 .setDuration(FLIP_DURATION),
1469 mNotificationButton, View.INVISIBLE));
1470 mSettingsButton.setVisibility(View.VISIBLE);
1471 mSettingsButtonAnim = start(
1472 ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
1473 .setDuration(FLIP_DURATION));
1474 mClearButton.setVisibility(View.VISIBLE);
1475 mClearButton.setAlpha(0f);
1476 setAreThereNotifications(); // this will show/hide the button as necessary
1477 mNotificationPanel.postDelayed(new Runnable() {
1478 public void run() {
1479 updateCarrierLabelVisibility(false);
1480 }
1481 }, FLIP_DURATION - 150);
1482 }
1483
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001484 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001485 public void animateExpandSettingsPanel() {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001486 if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
1487 if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1488 return;
1489 }
1490
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001491 // Settings are not available in setup
1492 if (!mUserSetup) return;
1493
Daniel Sandler101784e2012-10-15 13:39:38 -04001494 if (mHasFlipSettings) {
1495 mNotificationPanel.expand();
1496 if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
Daniel Sandler040c2e42012-10-17 00:56:33 -04001497 flipToSettings();
Daniel Sandler101784e2012-10-15 13:39:38 -04001498 }
1499 } else if (mSettingsPanel != null) {
1500 mSettingsPanel.expand();
1501 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001502
1503 if (false) postStartTracing();
1504 }
1505
Daniel Sandler040c2e42012-10-17 00:56:33 -04001506 public void switchToSettings() {
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001507 // Settings are not available in setup
1508 if (!mUserSetup) return;
1509
Daniel Sandler040c2e42012-10-17 00:56:33 -04001510 mFlipSettingsView.setScaleX(1f);
1511 mFlipSettingsView.setVisibility(View.VISIBLE);
1512 mSettingsButton.setVisibility(View.GONE);
1513 mScrollView.setVisibility(View.GONE);
Daniel Sandler720a34d2012-10-18 11:44:04 -04001514 mScrollView.setScaleX(0f);
Daniel Sandler040c2e42012-10-17 00:56:33 -04001515 mNotificationButton.setVisibility(View.VISIBLE);
1516 mNotificationButton.setAlpha(1f);
1517 mClearButton.setVisibility(View.GONE);
1518 }
1519
1520 public void flipToSettings() {
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001521 // Settings are not available in setup
1522 if (!mUserSetup) return;
1523
Daniel Sandler040c2e42012-10-17 00:56:33 -04001524 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1525 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1526 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1527 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1528 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1529
1530 mFlipSettingsView.setVisibility(View.VISIBLE);
1531 mFlipSettingsView.setScaleX(0f);
1532 mFlipSettingsViewAnim = start(
1533 startDelay(FLIP_DURATION_OUT,
1534 interpolator(mDecelerateInterpolator,
1535 ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f, 1f)
1536 .setDuration(FLIP_DURATION_IN)
1537 )));
1538 mScrollViewAnim = start(
1539 setVisibilityWhenDone(
1540 interpolator(mAccelerateInterpolator,
1541 ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f)
1542 )
1543 .setDuration(FLIP_DURATION_OUT),
1544 mScrollView, View.INVISIBLE));
1545 mSettingsButtonAnim = start(
1546 setVisibilityWhenDone(
1547 ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
1548 .setDuration(FLIP_DURATION),
1549 mScrollView, View.INVISIBLE));
1550 mNotificationButton.setVisibility(View.VISIBLE);
1551 mNotificationButtonAnim = start(
1552 ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
1553 .setDuration(FLIP_DURATION));
1554 mClearButtonAnim = start(
1555 setVisibilityWhenDone(
1556 ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
1557 .setDuration(FLIP_DURATION),
1558 mClearButton, View.INVISIBLE));
1559 mNotificationPanel.postDelayed(new Runnable() {
1560 public void run() {
1561 updateCarrierLabelVisibility(false);
1562 }
1563 }, FLIP_DURATION - 150);
1564 }
1565
1566 public void flipPanels() {
1567 if (mHasFlipSettings) {
1568 if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
1569 flipToSettings();
1570 } else {
1571 flipToNotifications();
1572 }
1573 }
1574 }
1575
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001576 public void animateCollapseQuickSettings() {
1577 mStatusBarView.collapseAllPanels(true);
1578 }
1579
Daniel Sandler6e2810b2012-10-17 09:40:09 -04001580 void makeExpandedInvisibleSoon() {
1581 mHandler.postDelayed(new Runnable() { public void run() { makeExpandedInvisible(); }}, 50);
1582 }
1583
Daniel Sandler08d05e32012-08-08 16:39:54 -04001584 void makeExpandedInvisible() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001585 if (SPEW) Slog.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04001586 + " mExpandedVisible=" + mExpandedVisible);
1587
1588 if (!mExpandedVisible) {
1589 return;
1590 }
Daniel Sandlered930e52012-07-03 14:31:22 -04001591
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04001592 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
1593 mStatusBarView.collapseAllPanels(/*animate=*/ false);
Daniel Sandlered930e52012-07-03 14:31:22 -04001594
Daniel Sandler040c2e42012-10-17 00:56:33 -04001595 if (mHasFlipSettings) {
1596 // reset things to their proper state
Daniel Sandler50bc4f52012-10-22 14:47:55 -04001597 if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
1598 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1599 if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
1600 if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
1601 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
1602
Daniel Sandler040c2e42012-10-17 00:56:33 -04001603 mScrollView.setScaleX(1f);
1604 mScrollView.setVisibility(View.VISIBLE);
1605 mSettingsButton.setAlpha(1f);
1606 mSettingsButton.setVisibility(View.VISIBLE);
1607 mNotificationPanel.setVisibility(View.GONE);
1608 mFlipSettingsView.setVisibility(View.GONE);
1609 mNotificationButton.setVisibility(View.GONE);
1610 setAreThereNotifications(); // show the clear button
1611 }
1612
Joe Onorato808182d2010-07-09 18:52:06 -04001613 mExpandedVisible = false;
Daniel Sandlere5011a32012-06-11 16:07:52 -04001614 mPile.setLayoutTransitionsEnabled(false);
John Spurlockd5ef5462012-06-13 11:19:51 -04001615 if (mNavigationBarView != null)
1616 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001617 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04001618
1619 // Shrink the window to the size of the status bar only
1620 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
1621 lp.height = getStatusBarHeight();
Daniel Sandler4391b0b2012-05-10 13:15:26 -04001622 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1623 lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Jeff Brown98365d72012-08-19 20:30:52 -07001624 mWindowManager.updateViewLayout(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04001625
1626 if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
1627 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1628 }
Joe Onorato808182d2010-07-09 18:52:06 -04001629
Daniel Sandler469e96e2012-05-04 15:56:19 -04001630 // Close any "App info" popups that might have snuck on-screen
1631 dismissPopups();
1632
Chet Haase2f2022a2011-10-11 06:41:59 -07001633 if (mPostCollapseCleanup != null) {
1634 mPostCollapseCleanup.run();
1635 mPostCollapseCleanup = null;
1636 }
Joe Onorato808182d2010-07-09 18:52:06 -04001637 }
1638
Romain Guy54ab3472012-06-14 12:52:53 -07001639 /**
1640 * Enables or disables layers on the children of the notifications pile.
1641 *
1642 * When layers are enabled, this method attempts to enable layers for the minimal
1643 * number of children. Only children visible when the notification area is fully
1644 * expanded will receive a layer. The technique used in this method might cause
1645 * more children than necessary to get a layer (at most one extra child with the
1646 * current UI.)
1647 *
1648 * @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE}
1649 */
1650 private void setPileLayers(int layerType) {
1651 final int count = mPile.getChildCount();
1652
1653 switch (layerType) {
1654 case View.LAYER_TYPE_NONE:
1655 for (int i = 0; i < count; i++) {
1656 mPile.getChildAt(i).setLayerType(layerType, null);
1657 }
1658 break;
1659 case View.LAYER_TYPE_HARDWARE:
1660 final int[] location = new int[2];
1661 mNotificationPanel.getLocationInWindow(location);
1662
1663 final int left = location[0];
1664 final int top = location[1];
1665 final int right = left + mNotificationPanel.getWidth();
1666 final int bottom = top + getExpandedViewMaxHeight();
1667
1668 final Rect childBounds = new Rect();
1669
1670 for (int i = 0; i < count; i++) {
1671 final View view = mPile.getChildAt(i);
1672 view.getLocationInWindow(location);
1673
1674 childBounds.set(location[0], location[1],
1675 location[0] + view.getWidth(), location[1] + view.getHeight());
1676
1677 if (childBounds.intersects(left, top, right, bottom)) {
1678 view.setLayerType(layerType, null);
1679 }
1680 }
1681
1682 break;
1683 }
1684 }
1685
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001686 public boolean isClinging() {
1687 return mCling != null && mCling.getVisibility() == View.VISIBLE;
1688 }
1689
1690 public void hideCling() {
1691 if (isClinging()) {
1692 mCling.animate().alpha(0f).setDuration(250).start();
1693 mCling.setVisibility(View.GONE);
1694 mSuppressStatusBarDrags = false;
1695 }
1696 }
1697
1698 public void showCling() {
Daniel Sandler118f4842012-10-07 20:38:39 -04001699 // lazily inflate this to accommodate orientation change
1700 final ViewStub stub = (ViewStub) mStatusBarWindow.findViewById(R.id.status_bar_cling_stub);
1701 if (stub == null) {
1702 mClingShown = true;
1703 return; // no clings on this device
1704 }
1705
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001706 mSuppressStatusBarDrags = true;
1707
1708 mHandler.postDelayed(new Runnable() {
1709 @Override
1710 public void run() {
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001711 mCling = (ViewGroup) stub.inflate();
Daniel Sandler118f4842012-10-07 20:38:39 -04001712
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001713 mCling.setOnTouchListener(new View.OnTouchListener() {
1714 @Override
1715 public boolean onTouch(View v, MotionEvent event) {
1716 return true; // e eats everything
1717 }});
1718 mCling.findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {
1719 @Override
1720 public void onClick(View v) {
1721 hideCling();
1722 }});
1723
1724 mCling.setAlpha(0f);
1725 mCling.setVisibility(View.VISIBLE);
1726 mCling.animate().alpha(1f);
1727
1728 mClingShown = true;
1729 SharedPreferences.Editor editor = Prefs.edit(mContext);
1730 editor.putBoolean(Prefs.SHOWN_QUICK_SETTINGS_HELP, true);
1731 editor.apply();
1732
1733 makeExpandedVisible(true); // enforce visibility in case the shade is still animating closed
1734 animateExpandNotificationsPanel();
1735
1736 mSuppressStatusBarDrags = false;
1737 }
1738 }, 500);
1739
1740 animateExpandNotificationsPanel();
1741 }
1742
1743 public boolean interceptTouchEvent(MotionEvent event) {
Joe Onorato808182d2010-07-09 18:52:06 -04001744 if (SPEW) {
1745 Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
John Spurlock804df702012-06-01 15:34:27 -04001746 + mDisabled + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001747 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001748 if (event.getAction() != MotionEvent.ACTION_MOVE) {
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001749 Slog.d(TAG, String.format(
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001750 "panel: %s at (%f, %f) mDisabled=0x%08x",
1751 MotionEvent.actionToString(event.getAction()),
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001752 event.getRawX(), event.getRawY(), mDisabled));
1753 }
Joe Onorato808182d2010-07-09 18:52:06 -04001754 }
1755
Daniel Sandler151f00d2012-10-02 22:33:08 -04001756 if (DEBUG_GESTURES) {
1757 mGestureRec.add(event);
1758 }
Daniel Sandler33805342012-07-23 15:45:12 -04001759
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001760 // Cling (first-run help) handling.
1761 // The cling is supposed to show the first time you drag, or even tap, the status bar.
1762 // It should show the notification panel, then fade in after half a second, giving you
1763 // an explanation of what just happened, as well as teach you how to access quick
1764 // settings (another drag). The user can dismiss the cling by clicking OK or by
1765 // dragging quick settings into view.
1766 final int act = event.getActionMasked();
1767 if (mSuppressStatusBarDrags) {
1768 return true;
1769 } else if (act == MotionEvent.ACTION_UP && !mClingShown) {
1770 showCling();
1771 } else {
1772 hideCling();
1773 }
1774
Joe Onorato808182d2010-07-09 18:52:06 -04001775 return false;
1776 }
1777
Daniel Sandler08d05e32012-08-08 16:39:54 -04001778 public GestureRecorder getGestureRecorder() {
1779 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07001780 }
1781
Daniel Sandler60ee2562011-07-22 12:34:33 -04001782 @Override // CommandQueue
Daniel Sandler328310c2011-09-23 15:56:52 -04001783 public void setNavigationIconHints(int hints) {
1784 if (hints == mNavigationIconHints) return;
1785
1786 mNavigationIconHints = hints;
1787
1788 if (mNavigationBarView != null) {
1789 mNavigationBarView.setNavigationIconHints(hints);
1790 }
1791 }
1792
1793 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001794 public void setSystemUiVisibility(int vis, int mask) {
1795 final int oldVal = mSystemUiVisibility;
1796 final int newVal = (oldVal&~mask) | (vis&mask);
1797 final int diff = newVal ^ oldVal;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001798
1799 if (diff != 0) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001800 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04001801
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001802 if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
1803 final boolean lightsOut = (0 != (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE));
1804 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001805 animateCollapsePanels();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001806 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001807 haltTicker();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001808 }
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001809 }
Jim Millera073e572012-05-23 17:03:27 -07001810
Daniel Sandler69314e72011-08-20 00:31:08 -04001811 if (mNavigationBarView != null) {
1812 mNavigationBarView.setLowProfile(lightsOut);
1813 }
Jim Millera073e572012-05-23 17:03:27 -07001814
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001815 setStatusBarLowProfile(lightsOut);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001816 }
1817
1818 notifyUiVisibilityChanged();
Joe Onorato93056472010-09-10 10:30:46 -04001819 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001820 }
1821
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001822 private void setStatusBarLowProfile(boolean lightsOut) {
1823 if (mLightsOutAnimation == null) {
Daniel Sandler825b3302012-10-01 15:22:36 -04001824 final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area);
1825 final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons);
1826 final View signal = mStatusBarView.findViewById(R.id.signal_cluster);
1827 final View battery = mStatusBarView.findViewById(R.id.battery);
1828 final View clock = mStatusBarView.findViewById(R.id.clock);
Jim Millera073e572012-05-23 17:03:27 -07001829
Daniel Sandler825b3302012-10-01 15:22:36 -04001830 final AnimatorSet lightsOutAnim = new AnimatorSet();
1831 lightsOutAnim.playTogether(
1832 ObjectAnimator.ofFloat(notifications, View.ALPHA, 0),
1833 ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0),
1834 ObjectAnimator.ofFloat(signal, View.ALPHA, 0),
1835 ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f),
1836 ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
1837 );
1838 lightsOutAnim.setDuration(750);
1839
1840 final AnimatorSet lightsOnAnim = new AnimatorSet();
1841 lightsOnAnim.playTogether(
1842 ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
1843 ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1),
1844 ObjectAnimator.ofFloat(signal, View.ALPHA, 1),
1845 ObjectAnimator.ofFloat(battery, View.ALPHA, 1),
1846 ObjectAnimator.ofFloat(clock, View.ALPHA, 1)
1847 );
1848 lightsOnAnim.setDuration(250);
1849
1850 mLightsOutAnimation = lightsOutAnim;
1851 mLightsOnAnimation = lightsOnAnim;
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001852 }
Jim Millera073e572012-05-23 17:03:27 -07001853
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001854 mLightsOutAnimation.cancel();
1855 mLightsOnAnimation.cancel();
1856
1857 final Animator a = lightsOut ? mLightsOutAnimation : mLightsOnAnimation;
1858 a.start();
1859
1860 setAreThereNotifications();
1861 }
1862
1863 private boolean areLightsOn() {
1864 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
1865 }
Jim Millera073e572012-05-23 17:03:27 -07001866
Daniel Sandler60ee2562011-07-22 12:34:33 -04001867 public void setLightsOn(boolean on) {
1868 Log.v(TAG, "setLightsOn(" + on + ")");
1869 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001870 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001871 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001872 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001873 }
1874 }
1875
1876 private void notifyUiVisibilityChanged() {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001877 try {
Jeff Brown98365d72012-08-19 20:30:52 -07001878 mWindowManagerService.statusBarVisibilityChanged(mSystemUiVisibility);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001879 } catch (RemoteException ex) {
1880 }
Joe Onorato93056472010-09-10 10:30:46 -04001881 }
1882
Daniel Sandler5c8da942011-06-28 00:29:04 -04001883 public void topAppWindowChanged(boolean showMenu) {
1884 if (DEBUG) {
1885 Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
1886 }
1887 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04001888 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04001889 }
1890
1891 // See above re: lights-out policy for legacy apps.
1892 if (showMenu) setLightsOn(true);
1893 }
1894
Daniel Sandler328310c2011-09-23 15:56:52 -04001895 @Override
1896 public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
1897 boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
1898 || ((vis & InputMethodService.IME_VISIBLE) != 0);
1899
1900 mCommandQueue.setNavigationIconHints(
1901 altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
1902 : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
Daniel Sandler101784e2012-10-15 13:39:38 -04001903 if (mQS != null) mQS.setImeWindowStatus(vis > 0);
Daniel Sandler328310c2011-09-23 15:56:52 -04001904 }
1905
Jeff Brown2992ea72011-01-28 22:04:14 -08001906 @Override
Winson Chung43229d72012-09-12 18:04:18 -07001907 public void setHardKeyboardStatus(boolean available, boolean enabled) {}
Daniel Sandlere02d8082010-10-08 15:13:22 -04001908
Chris Wren0c8275b2012-05-08 13:36:48 -04001909 @Override
1910 protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001911 // no ticking in lights-out mode
1912 if (!areLightsOn()) return;
Jim Millera073e572012-05-23 17:03:27 -07001913
Daniel Sandler26cda272012-05-22 15:44:08 -04001914 // no ticking in Setup
1915 if (!isDeviceProvisioned()) return;
1916
John Spurlock61e36832012-09-10 09:43:27 -04001917 // not for you
1918 if (!notificationIsForCurrentUser(n)) return;
1919
Joe Onorato808182d2010-07-09 18:52:06 -04001920 // Show the ticker if one is requested. Also don't do this
1921 // until status bar window is attached to the window manager,
1922 // because... well, what's the point otherwise? And trying to
1923 // run a ticker without being attached will crash!
Daniel Sandlera310af82012-04-24 01:20:13 -04001924 if (n.notification.tickerText != null && mStatusBarWindow.getWindowToken() != null) {
Joe Onorato808182d2010-07-09 18:52:06 -04001925 if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
1926 | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
1927 mTicker.addEntry(n);
1928 }
1929 }
1930 }
1931
Joe Onorato808182d2010-07-09 18:52:06 -04001932 private class MyTicker extends Ticker {
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001933 MyTicker(Context context, View sb) {
Joe Onorato808182d2010-07-09 18:52:06 -04001934 super(context, sb);
1935 }
1936
1937 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001938 public void tickerStarting() {
Joe Onorato808182d2010-07-09 18:52:06 -04001939 mTicking = true;
Daniel Sandler173bae22012-09-25 14:37:42 -04001940 mStatusBarContents.setVisibility(View.GONE);
Joe Onorato808182d2010-07-09 18:52:06 -04001941 mTickerView.setVisibility(View.VISIBLE);
1942 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
Daniel Sandler173bae22012-09-25 14:37:42 -04001943 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
Joe Onorato808182d2010-07-09 18:52:06 -04001944 }
1945
1946 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001947 public void tickerDone() {
Daniel Sandler173bae22012-09-25 14:37:42 -04001948 mStatusBarContents.setVisibility(View.VISIBLE);
Joe Onorato808182d2010-07-09 18:52:06 -04001949 mTickerView.setVisibility(View.GONE);
Daniel Sandler173bae22012-09-25 14:37:42 -04001950 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
Joe Onorato808182d2010-07-09 18:52:06 -04001951 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
1952 mTickingDoneListener));
Joe Onorato808182d2010-07-09 18:52:06 -04001953 }
1954
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001955 public void tickerHalting() {
Daniel Sandler173bae22012-09-25 14:37:42 -04001956 mStatusBarContents.setVisibility(View.VISIBLE);
Joe Onorato808182d2010-07-09 18:52:06 -04001957 mTickerView.setVisibility(View.GONE);
Daniel Sandler173bae22012-09-25 14:37:42 -04001958 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001959 // we do not animate the ticker away at this point, just get rid of it (b/6992707)
Joe Onorato808182d2010-07-09 18:52:06 -04001960 }
1961 }
1962
1963 Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
1964 public void onAnimationEnd(Animation animation) {
1965 mTicking = false;
1966 }
1967 public void onAnimationRepeat(Animation animation) {
1968 }
1969 public void onAnimationStart(Animation animation) {
1970 }
1971 };
1972
1973 private Animation loadAnim(int id, Animation.AnimationListener listener) {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001974 Animation anim = AnimationUtils.loadAnimation(mContext, id);
Joe Onorato808182d2010-07-09 18:52:06 -04001975 if (listener != null) {
1976 anim.setAnimationListener(listener);
1977 }
1978 return anim;
1979 }
1980
Daniel Sandler48852952011-12-01 14:34:23 -05001981 public static String viewInfo(View v) {
1982 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
1983 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04001984 }
1985
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001986 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04001987 synchronized (mQueueLock) {
1988 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04001989 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04001990 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04001991 pw.println(" mTicking=" + mTicking);
1992 pw.println(" mTracking=" + mTracking);
Daniel Sandlerfdbac772012-07-03 14:30:10 -04001993 pw.println(" mNotificationPanel=" +
1994 ((mNotificationPanel == null)
1995 ? "null"
1996 : (mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""))));
Joe Onorato808182d2010-07-09 18:52:06 -04001997 pw.println(" mAnimating=" + mAnimating
1998 + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
1999 + ", mAnimAccel=" + mAnimAccel);
Jeff Browned5f45a2012-05-03 15:53:47 -07002000 pw.println(" mAnimLastTimeNanos=" + mAnimLastTimeNanos);
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002001 pw.println(" mAnimatingReveal=" + mAnimatingReveal
Joe Onorato808182d2010-07-09 18:52:06 -04002002 + " mViewDelta=" + mViewDelta);
Daniel Sandler36412a72011-08-04 09:35:13 -04002003 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002004 pw.println(" mPile: " + viewInfo(mPile));
Joe Onorato808182d2010-07-09 18:52:06 -04002005 pw.println(" mTickerView: " + viewInfo(mTickerView));
2006 pw.println(" mScrollView: " + viewInfo(mScrollView)
2007 + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04002008 }
Joe Onorato808182d2010-07-09 18:52:06 -04002009
Daniel Sandler48852952011-12-01 14:34:23 -05002010 pw.print(" mNavigationBarView=");
2011 if (mNavigationBarView == null) {
2012 pw.println("null");
2013 } else {
2014 mNavigationBarView.dump(fd, pw, args);
2015 }
2016
Daniel Sandler7579bca2011-08-18 15:47:26 -04002017 if (DUMPTRUCK) {
2018 synchronized (mNotificationData) {
2019 int N = mNotificationData.size();
2020 pw.println(" notification icons: " + N);
2021 for (int i=0; i<N; i++) {
2022 NotificationData.Entry e = mNotificationData.get(i);
2023 pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
2024 StatusBarNotification n = e.notification;
Daniel Sandler2561b0b2012-02-13 21:04:12 -05002025 pw.println(" pkg=" + n.pkg + " id=" + n.id + " score=" + n.score);
Daniel Sandler7579bca2011-08-18 15:47:26 -04002026 pw.println(" notification=" + n.notification);
2027 pw.println(" tickerText=\"" + n.notification.tickerText + "\"");
2028 }
2029 }
2030
2031 int N = mStatusIcons.getChildCount();
2032 pw.println(" system icons: " + N);
2033 for (int i=0; i<N; i++) {
2034 StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
2035 pw.println(" [" + i + "] icon=" + ic);
2036 }
Jim Miller5e6af442011-12-02 18:24:26 -08002037
Daniel Sandler89d97132011-09-08 15:31:57 -04002038 if (false) {
2039 pw.println("see the logcat for a dump of the views we have created.");
2040 // must happen on ui thread
2041 mHandler.post(new Runnable() {
2042 public void run() {
2043 mStatusBarView.getLocationOnScreen(mAbsPos);
2044 Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
2045 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002046 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002047 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002048 }
2049 });
2050 }
Joe Onorato808182d2010-07-09 18:52:06 -04002051 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002052
Daniel Sandler151f00d2012-10-02 22:33:08 -04002053 if (DEBUG_GESTURES) {
2054 pw.print(" status bar gestures: ");
2055 mGestureRec.dump(fd, pw, args);
2056 }
Daniel Sandler33805342012-07-23 15:45:12 -04002057
Daniel Sandler89d97132011-09-08 15:31:57 -04002058 mNetworkController.dump(fd, pw, args);
Joe Onorato808182d2010-07-09 18:52:06 -04002059 }
2060
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002061 @Override
2062 public void createAndAddWindows() {
2063 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04002064 }
Jim Millere898ac52012-04-06 17:10:57 -07002065
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002066 private void addStatusBarWindow() {
2067 // Put up the view
2068 final int height = getStatusBarHeight();
Joe Onorato808182d2010-07-09 18:52:06 -04002069
Daniel Sandlera310af82012-04-24 01:20:13 -04002070 // Now that the status bar window encompasses the sliding panel and its
2071 // translucent backdrop, the entire thing is made TRANSLUCENT and is
2072 // hardware-accelerated.
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002073 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
2074 ViewGroup.LayoutParams.MATCH_PARENT,
2075 height,
2076 WindowManager.LayoutParams.TYPE_STATUS_BAR,
2077 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
2078 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
2079 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Daniel Sandlera310af82012-04-24 01:20:13 -04002080 PixelFormat.TRANSLUCENT);
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002081
Romain Guy0901fda2012-05-22 21:10:57 -07002082 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002083
2084 lp.gravity = getStatusBarGravity();
2085 lp.setTitle("StatusBar");
2086 lp.packageName = mContext.getPackageName();
Jim Millere898ac52012-04-06 17:10:57 -07002087
Daniel Sandlera310af82012-04-24 01:20:13 -04002088 makeStatusBarView();
Jeff Brown98365d72012-08-19 20:30:52 -07002089 mWindowManager.addView(mStatusBarWindow, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04002090 }
2091
Joe Onorato808182d2010-07-09 18:52:06 -04002092 void setNotificationIconVisibility(boolean visible, int anim) {
2093 int old = mNotificationIcons.getVisibility();
2094 int v = visible ? View.VISIBLE : View.INVISIBLE;
2095 if (old != v) {
2096 mNotificationIcons.setVisibility(v);
2097 mNotificationIcons.startAnimation(loadAnim(anim, null));
2098 }
2099 }
2100
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002101 void updateExpandedInvisiblePosition() {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002102 mTrackingPosition = -mDisplayMetrics.heightPixels;
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002103 }
2104
Daniel Sandler1fac1fd2012-04-30 12:07:30 -04002105 static final float saturate(float a) {
2106 return a < 0f ? 0f : (a > 1f ? 1f : a);
2107 }
2108
Chris Wren8fd12652012-05-09 21:25:57 -04002109 @Override
2110 protected int getExpandedViewMaxHeight() {
Daniel Sandler21b274e2012-05-02 15:07:51 -04002111 return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx;
2112 }
2113
Chris Wren0c8275b2012-05-08 13:36:48 -04002114 @Override
Daniel Sandler08d05e32012-08-08 16:39:54 -04002115 public void updateExpandedViewPos(int thingy) {
Daniel Sandler08d05e32012-08-08 16:39:54 -04002116 if (DEBUG) Slog.v(TAG, "updateExpandedViewPos");
Daniel Sandlere680f542012-09-28 12:22:27 -04002117
2118 // on larger devices, the notification panel is propped open a bit
2119 mNotificationPanel.setMinimumHeight(
2120 (int)(mNotificationPanelMinHeightFrac * mCurrentDisplaySize.y));
2121
Daniel Sandler21b274e2012-05-02 15:07:51 -04002122 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams();
Daniel Sandler21b274e2012-05-02 15:07:51 -04002123 lp.gravity = mNotificationPanelGravity;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002124 lp.leftMargin = mNotificationPanelMarginPx;
Daniel Sandler21b274e2012-05-02 15:07:51 -04002125 mNotificationPanel.setLayoutParams(lp);
Daniel Sandlere680f542012-09-28 12:22:27 -04002126
Daniel Sandlere111ad32012-10-13 15:17:45 -04002127 if (mSettingsPanel != null) {
2128 lp = (FrameLayout.LayoutParams) mSettingsPanel.getLayoutParams();
2129 lp.gravity = mSettingsPanelGravity;
2130 lp.rightMargin = mNotificationPanelMarginPx;
2131 mSettingsPanel.setLayoutParams(lp);
2132 }
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002133
2134 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002135 }
2136
Daniel Sandler747a9e92012-08-10 16:39:19 -04002137 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002138 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04002139 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler151f00d2012-10-02 22:33:08 -04002140 if (DEBUG_GESTURES) {
2141 mGestureRec.tag("display",
2142 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2143 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002144 }
2145
Joe Onorato808182d2010-07-09 18:52:06 -04002146 private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
2147 public void onClick(View v) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002148 synchronized (mNotificationData) {
Chet Haase2f2022a2011-10-11 06:41:59 -07002149 // animate-swipe all dismissable notifications, then animate the shade closed
2150 int numChildren = mPile.getChildCount();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002151
Chet Haase2f2022a2011-10-11 06:41:59 -07002152 int scrollTop = mScrollView.getScrollY();
2153 int scrollBottom = scrollTop + mScrollView.getHeight();
2154 final ArrayList<View> snapshot = new ArrayList<View>(numChildren);
2155 for (int i=0; i<numChildren; i++) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002156 final View child = mPile.getChildAt(i);
Chet Haase2f2022a2011-10-11 06:41:59 -07002157 if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop &&
2158 child.getTop() < scrollBottom) {
2159 snapshot.add(child);
2160 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002161 }
Craig Mautner93a035c2012-04-09 15:23:59 -07002162 if (snapshot.isEmpty()) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002163 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Craig Mautner93a035c2012-04-09 15:23:59 -07002164 return;
2165 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002166 new Thread(new Runnable() {
2167 @Override
2168 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07002169 // Decrease the delay for every row we animate to give the sense of
2170 // accelerating the swipes
2171 final int ROW_DELAY_DECREMENT = 10;
2172 int currentDelay = 140;
2173 int totalDelay = 0;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002174
Chet Haase2f2022a2011-10-11 06:41:59 -07002175 // Set the shade-animating state to avoid doing other work during
2176 // all of these animations. In particular, avoid layout and
2177 // redrawing when collapsing the shade.
2178 mPile.setViewRemoval(false);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002179
Chet Haase2f2022a2011-10-11 06:41:59 -07002180 mPostCollapseCleanup = new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07002181 @Override
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002182 public void run() {
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002183 if (DEBUG) {
2184 Slog.v(TAG, "running post-collapse cleanup");
2185 }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002186 try {
Chet Haase2f2022a2011-10-11 06:41:59 -07002187 mPile.setViewRemoval(true);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002188 mBarService.onClearAllNotifications();
Chet Haase2f2022a2011-10-11 06:41:59 -07002189 } catch (Exception ex) { }
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002190 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002191 };
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002192
Chet Haase2f2022a2011-10-11 06:41:59 -07002193 View sampleView = snapshot.get(0);
2194 int width = sampleView.getWidth();
Craig Mautner93a035c2012-04-09 15:23:59 -07002195 final int velocity = width * 8; // 1000/8 = 125 ms duration
2196 for (final View _v : snapshot) {
Chet Haase2f2022a2011-10-11 06:41:59 -07002197 mHandler.postDelayed(new Runnable() {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002198 @Override
2199 public void run() {
Chet Haase2f2022a2011-10-11 06:41:59 -07002200 mPile.dismissRowAnimated(_v, velocity);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002201 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002202 }, totalDelay);
2203 currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT);
2204 totalDelay += currentDelay;
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002205 }
Chet Haase2f2022a2011-10-11 06:41:59 -07002206 // Delay the collapse animation until after all swipe animations have
2207 // finished. Provide some buffer because there may be some extra delay
2208 // before actually starting each swipe animation. Ideally, we'd
2209 // synchronize the end of those animations with the start of the collaps
2210 // exactly.
2211 mHandler.postDelayed(new Runnable() {
Craig Mautner93a035c2012-04-09 15:23:59 -07002212 @Override
Chet Haase2f2022a2011-10-11 06:41:59 -07002213 public void run() {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002214 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Chet Haase2f2022a2011-10-11 06:41:59 -07002215 }
2216 }, totalDelay + 225);
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002217 }
2218 }).start();
Joe Onorato808182d2010-07-09 18:52:06 -04002219 }
Joe Onorato808182d2010-07-09 18:52:06 -04002220 }
2221 };
2222
Daniel Sandler3679bf52012-10-16 21:30:28 -04002223 public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
2224 if (onlyProvisioned && !isDeviceProvisioned()) return;
2225 try {
2226 // Dismiss the lock screen when Settings starts.
2227 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
2228 } catch (RemoteException e) {
2229 }
2230 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2231 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
2232 animateCollapsePanels();
2233 }
2234
Daniel Sandlerd3090562011-08-09 00:28:44 -04002235 private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
2236 public void onClick(View v) {
Daniel Sandlere111ad32012-10-13 15:17:45 -04002237 if (mHasSettingsPanel) {
2238 animateExpandSettingsPanel();
2239 } else {
Daniel Sandler3679bf52012-10-16 21:30:28 -04002240 startActivityDismissingKeyguard(
2241 new Intent(android.provider.Settings.ACTION_SETTINGS), true);
Daniel Sandlere111ad32012-10-13 15:17:45 -04002242 }
Daniel Sandlerd3090562011-08-09 00:28:44 -04002243 }
2244 };
2245
Daniel Sandler3679bf52012-10-16 21:30:28 -04002246 private View.OnClickListener mClockClickListener = new View.OnClickListener() {
2247 public void onClick(View v) {
2248 startActivityDismissingKeyguard(
2249 new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone
2250 }
2251 };
2252
Daniel Sandler101784e2012-10-15 13:39:38 -04002253 private View.OnClickListener mNotificationButtonListener = new View.OnClickListener() {
2254 public void onClick(View v) {
2255 animateExpandNotificationsPanel();
2256 }
2257 };
2258
Joe Onorato808182d2010-07-09 18:52:06 -04002259 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2260 public void onReceive(Context context, Intent intent) {
Dianne Hackborn7ff30112012-11-08 11:12:09 -08002261 if (DEBUG) Slog.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04002262 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04002263 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Jim Miller9a720f52012-05-30 03:19:43 -07002264 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002265 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Daniel Sandleredbdd3a2011-06-21 12:57:08 -04002266 String reason = intent.getStringExtra("reason");
Jim Miller9a720f52012-05-30 03:19:43 -07002267 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
2268 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002269 }
2270 }
Daniel Sandler11cf1782012-09-27 14:03:08 -04002271 animateCollapsePanels(flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002272 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002273 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
2274 // no waiting!
Daniel Sandler08d05e32012-08-08 16:39:54 -04002275 makeExpandedInvisible();
John Spurlock1bbd49d2012-10-19 11:09:32 -04002276 notifyNavigationBarScreenOn(false);
Daniel Sandlered930e52012-07-03 14:31:22 -04002277 }
Joe Onorato808182d2010-07-09 18:52:06 -04002278 else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002279 if (DEBUG) {
2280 Slog.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
2281 }
Daniel Sandlere680f542012-09-28 12:22:27 -04002282 mDisplay.getSize(mCurrentDisplaySize);
2283
Joe Onorato808182d2010-07-09 18:52:06 -04002284 updateResources();
Daniel Sandler21b274e2012-05-02 15:07:51 -04002285 repositionNavigationBar();
2286 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002287 updateShowSearchHoldoff();
2288 }
2289 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
2290 // work around problem where mDisplay.getRotation() is not stable while screen is off (bug 7086018)
2291 repositionNavigationBar();
John Spurlock1bbd49d2012-10-19 11:09:32 -04002292 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002293 }
2294 }
2295 };
2296
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002297 @Override
2298 public void userSwitched(int newUserId) {
2299 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002300 animateCollapsePanels();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002301 updateNotificationIcons();
John Spurlock919adac2012-10-02 16:41:12 -04002302 resetUserSetupObserver();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002303 }
John Spurlock919adac2012-10-02 16:41:12 -04002304
2305 private void resetUserSetupObserver() {
2306 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
2307 mUserSetupObserver.onChange(false);
2308 mContext.getContentResolver().registerContentObserver(
2309 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
2310 mUserSetupObserver,
2311 mCurrentUserId);
2312 }
2313
Joe Onorato808182d2010-07-09 18:52:06 -04002314 private void setIntruderAlertVisibility(boolean vis) {
Daniel Sandler6b318802012-04-13 14:05:19 -04002315 if (!ENABLE_INTRUDERS) return;
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04002316 if (DEBUG) {
2317 Slog.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
2318 }
Joe Onorato808182d2010-07-09 18:52:06 -04002319 mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
2320 }
2321
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04002322 public void dismissIntruder() {
2323 if (mCurrentlyIntrudingNotification == null) return;
2324
2325 try {
2326 mBarService.onNotificationClear(
2327 mCurrentlyIntrudingNotification.pkg,
Jim Millera073e572012-05-23 17:03:27 -07002328 mCurrentlyIntrudingNotification.tag,
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04002329 mCurrentlyIntrudingNotification.id);
2330 } catch (android.os.RemoteException ex) {
2331 // oh well
2332 }
2333 }
Jim Millere898ac52012-04-06 17:10:57 -07002334
Joe Onorato808182d2010-07-09 18:52:06 -04002335 /**
2336 * Reload some of our resources when the configuration changes.
2337 *
2338 * We don't reload everything when the configuration changes -- we probably
2339 * should, but getting that smooth is tough. Someday we'll fix that. In the
2340 * meantime, just update the things that we know change.
2341 */
2342 void updateResources() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002343 final Context context = mContext;
2344 final Resources res = context.getResources();
Joe Onorato808182d2010-07-09 18:52:06 -04002345
Daniel Sandler1347c302011-08-01 16:47:53 -04002346 if (mClearButton instanceof TextView) {
2347 ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
2348 }
Winson Chungd63c59782012-09-05 17:34:41 -07002349
2350 // Update the QuickSettings container
Daniel Sandler101784e2012-10-15 13:39:38 -04002351 if (mQS != null) mQS.updateResources();
Winson Chungd63c59782012-09-05 17:34:41 -07002352
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002353 loadDimens();
2354 }
Jim Miller5e6af442011-12-02 18:24:26 -08002355
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002356 protected void loadDimens() {
2357 final Resources res = mContext.getResources();
2358
2359 mNaturalBarHeight = res.getDimensionPixelSize(
2360 com.android.internal.R.dimen.status_bar_height);
2361
2362 int newIconSize = res.getDimensionPixelSize(
2363 com.android.internal.R.dimen.status_bar_icon_size);
2364 int newIconHPadding = res.getDimensionPixelSize(
2365 R.dimen.status_bar_icon_padding);
2366
2367 if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
2368// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
2369 mIconHPadding = newIconHPadding;
2370 mIconSize = newIconSize;
2371 //reloadAllNotificationIcons(); // reload the tray
2372 }
2373
Joe Onorato808182d2010-07-09 18:52:06 -04002374 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
2375
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002376 mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
2377 mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
2378 mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
2379 mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
2380
2381 mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
2382 mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
2383
2384 mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
2385 mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
2386
2387 mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
Jim Millera073e572012-05-23 17:03:27 -07002388
Daniel Sandlere5011a32012-06-11 16:07:52 -04002389 mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity);
2390
Daniel Sandler21b274e2012-05-02 15:07:51 -04002391 mNotificationPanelMarginBottomPx
2392 = (int) res.getDimension(R.dimen.notification_panel_margin_bottom);
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002393 mNotificationPanelMarginPx
Daniel Sandler21b274e2012-05-02 15:07:51 -04002394 = (int) res.getDimension(R.dimen.notification_panel_margin_left);
2395 mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
2396 if (mNotificationPanelGravity <= 0) {
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002397 mNotificationPanelGravity = Gravity.LEFT | Gravity.TOP;
2398 }
2399 mSettingsPanelGravity = res.getInteger(R.integer.settings_panel_layout_gravity);
2400 if (mSettingsPanelGravity <= 0) {
2401 mSettingsPanelGravity = Gravity.RIGHT | Gravity.TOP;
Daniel Sandler21b274e2012-05-02 15:07:51 -04002402 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04002403
2404 mCarrierLabelHeight = res.getDimensionPixelSize(R.dimen.carrier_label_height);
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002405 mNotificationHeaderHeight = res.getDimensionPixelSize(R.dimen.notification_panel_header_height);
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002406
Daniel Sandlere680f542012-09-28 12:22:27 -04002407 mNotificationPanelMinHeightFrac = res.getFraction(R.dimen.notification_panel_min_height_frac, 1, 1);
2408 if (mNotificationPanelMinHeightFrac < 0f || mNotificationPanelMinHeightFrac > 1f) {
2409 mNotificationPanelMinHeightFrac = 0f;
John Spurlock804df702012-06-01 15:34:27 -04002410 }
Daniel Sandlere680f542012-09-28 12:22:27 -04002411
2412 if (false) Slog.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04002413 }
2414
Joe Onorato808182d2010-07-09 18:52:06 -04002415 //
2416 // tracing
2417 //
2418
2419 void postStartTracing() {
2420 mHandler.postDelayed(mStartTracing, 3000);
2421 }
2422
2423 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002424 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
2425 Context.VIBRATOR_SERVICE);
Joe Onorato808182d2010-07-09 18:52:06 -04002426 vib.vibrate(250);
2427 }
2428
2429 Runnable mStartTracing = new Runnable() {
2430 public void run() {
2431 vibrate();
2432 SystemClock.sleep(250);
2433 Slog.d(TAG, "startTracing");
2434 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2435 mHandler.postDelayed(mStopTracing, 10000);
2436 }
2437 };
2438
2439 Runnable mStopTracing = new Runnable() {
2440 public void run() {
2441 android.os.Debug.stopMethodTracing();
2442 Slog.d(TAG, "stopTracing");
2443 vibrate();
2444 }
2445 };
Chris Wren0c8275b2012-05-08 13:36:48 -04002446
2447 @Override
2448 protected void haltTicker() {
2449 mTicker.halt();
2450 }
Jim Miller670d9dd2012-05-12 13:28:26 -07002451
2452 @Override
Jim Millerb4238e02012-05-14 15:26:20 -07002453 protected boolean shouldDisableNavbarGestures() {
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002454 return !isDeviceProvisioned()
2455 || mExpandedVisible
2456 || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07002457 }
Joe Onorato808182d2010-07-09 18:52:06 -04002458
Romain Guy648342f2012-05-25 10:44:45 -07002459 private static class FastColorDrawable extends Drawable {
2460 private final int mColor;
2461
2462 public FastColorDrawable(int color) {
2463 mColor = 0xff000000 | color;
2464 }
2465
2466 @Override
2467 public void draw(Canvas canvas) {
2468 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
2469 }
2470
2471 @Override
2472 public void setAlpha(int alpha) {
2473 }
2474
2475 @Override
2476 public void setColorFilter(ColorFilter cf) {
2477 }
2478
2479 @Override
2480 public int getOpacity() {
2481 return PixelFormat.OPAQUE;
2482 }
2483
2484 @Override
2485 public void setBounds(int left, int top, int right, int bottom) {
2486 }
2487
2488 @Override
2489 public void setBounds(Rect bounds) {
2490 }
2491 }
2492}