blob: ac9866cadfaadfae29e2a040cd5a976a14f3fe53 [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
Jorim Jaggicff0acb2014-03-31 16:35:15 +020019
John Spurlockd4e65752013-08-28 14:17:09 -040020import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
Jason Monkf1ff2092014-04-29 16:50:53 -040021import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
John Spurlock7edfbca2013-09-14 11:58:55 -040022import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
John Spurlockd4e65752013-08-28 14:17:09 -040023import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
John Spurlock0ec64c62013-08-26 15:37:58 -040024import static android.app.StatusBarManager.windowStateToString;
Adrian Roos7d7090d2014-05-21 13:10:23 +020025import static com.android.keyguard.KeyguardHostView.OnDismissAction;
Jorim Jaggicff0acb2014-03-31 16:35:15 +020026import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
John Spurlock3b139a92013-08-17 17:18:08 -040027import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
John Spurlock89835dd2013-08-16 15:06:51 -040028import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
John Spurlockbd957402013-10-03 11:38:39 -040029import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
Adrian Roosea562512014-05-05 13:33:03 +020030import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
John Spurlocke932e302013-08-12 10:16:29 -040031
Daniel Sandlerd7e96862012-04-26 01:10:29 -040032import android.animation.Animator;
33import android.animation.AnimatorListenerAdapter;
Daniel Sandler101784e2012-10-15 13:39:38 -040034import android.animation.TimeInterpolator;
John Spurlock4bf31982014-05-21 13:04:22 -040035import android.animation.ValueAnimator;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070036import android.app.ActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040037import android.app.ActivityManagerNative;
Joe Onorato808182d2010-07-09 18:52:06 -040038import android.app.Notification;
39import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040040import android.app.StatusBarManager;
41import android.content.BroadcastReceiver;
42import android.content.Context;
43import android.content.Intent;
44import android.content.IntentFilter;
Daniel Sandler777dcde2013-09-30 10:21:45 -040045import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070046import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040047import android.database.ContentObserver;
Romain Guy648342f2012-05-25 10:44:45 -070048import android.graphics.Canvas;
49import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040050import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040051import android.graphics.Point;
Romain Guy648342f2012-05-25 10:44:45 -070052import android.graphics.PorterDuff;
Joe Onorato808182d2010-07-09 18:52:06 -040053import android.graphics.Rect;
Romain Guy648342f2012-05-25 10:44:45 -070054import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070055import android.inputmethodservice.InputMethodService;
John Spurlockf9e1a0b2014-03-19 22:09:06 -040056import android.media.AudioManager;
John Spurlock3c875662013-08-31 15:07:25 -040057import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040058import android.os.Handler;
Joe Onorato808182d2010-07-09 18:52:06 -040059import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040060import android.os.Message;
John Spurlock56d007b2013-10-28 18:40:56 -040061import android.os.PowerManager;
Michael Jurka7f2668c2012-03-27 07:49:52 -070062import android.os.RemoteException;
Joe Onorato808182d2010-07-09 18:52:06 -040063import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070064import android.os.UserHandle;
Daniel Sandlerd3090562011-08-09 00:28:44 -040065import android.provider.Settings;
John Spurlockbf20eab2014-04-09 16:40:39 -040066import android.provider.Settings.Global;
Christoph Studer37fe6932014-05-26 13:10:30 +020067import android.service.notification.NotificationListenerService.Ranking;
John Spurlockde84f0e2013-06-12 12:41:00 -040068import android.service.notification.StatusBarNotification;
Christoph Studer92b389d2014-04-01 18:44:40 +020069import android.util.ArraySet;
Daniel Sandler36412a72011-08-04 09:35:13 -040070import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -050071import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -040072import android.util.Log;
73import android.view.Display;
74import android.view.Gravity;
Jorim Jaggidf993512014-05-13 23:06:35 +020075import android.view.KeyEvent;
Jorim Jaggid4a57442014-04-10 02:45:55 +020076import android.view.LayoutInflater;
Joe Onorato808182d2010-07-09 18:52:06 -040077import android.view.MotionEvent;
78import android.view.VelocityTracker;
79import android.view.View;
ztenghui62f30e02014-06-05 09:55:04 -070080import android.view.ViewAnimationUtils;
Joe Onorato808182d2010-07-09 18:52:06 -040081import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -070082import android.view.ViewGroup.LayoutParams;
Daniel Sandler101784e2012-10-15 13:39:38 -040083import android.view.ViewPropertyAnimator;
Jorim Jaggia6310292014-04-16 14:11:52 +020084import android.view.ViewTreeObserver;
Joe Onorato808182d2010-07-09 18:52:06 -040085import android.view.WindowManager;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040086import android.view.animation.AccelerateInterpolator;
Joe Onorato808182d2010-07-09 18:52:06 -040087import android.view.animation.Animation;
88import android.view.animation.AnimationUtils;
Daniel Sandler67e7d902012-06-06 16:32:21 -040089import android.view.animation.DecelerateInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020090import android.view.animation.Interpolator;
91import android.view.animation.PathInterpolator;
Daniel Sandler21b274e2012-05-02 15:07:51 -040092import android.widget.FrameLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040093import android.widget.LinearLayout;
Joe Onorato808182d2010-07-09 18:52:06 -040094import android.widget.TextView;
John Spurlock34e13d92013-08-10 06:52:28 -040095
Joe Onorato808182d2010-07-09 18:52:06 -040096import com.android.internal.statusbar.StatusBarIcon;
Jorim Jaggi03c701e2014-04-02 12:39:51 +020097import com.android.keyguard.ViewMediatorCallback;
John Spurlock3c875662013-08-31 15:07:25 -040098import com.android.systemui.DemoMode;
Chris Wren64161cc2012-12-17 16:49:30 -050099import com.android.systemui.EventLogTags;
Joe Onorato808182d2010-07-09 18:52:06 -0400100import com.android.systemui.R;
Jorim Jaggicff0acb2014-03-31 16:35:15 +0200101import com.android.systemui.keyguard.KeyguardViewMediator;
John Spurlock4bf31982014-05-21 13:04:22 -0400102import com.android.systemui.qs.CircularClipper;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400103import com.android.systemui.qs.QSPanel;
104import com.android.systemui.qs.QSTile;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500105import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700106import com.android.systemui.statusbar.CommandQueue;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200107import com.android.systemui.statusbar.DragDownHelper;
108import com.android.systemui.statusbar.ExpandableNotificationRow;
Daniel Sandler33805342012-07-23 15:45:12 -0400109import com.android.systemui.statusbar.GestureRecorder;
John Spurlockbf20eab2014-04-09 16:40:39 -0400110import com.android.systemui.statusbar.InterceptedNotifications;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200111import com.android.systemui.statusbar.KeyguardIndicationController;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700112import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -0400113import com.android.systemui.statusbar.NotificationData.Entry;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200114import com.android.systemui.statusbar.NotificationOverflowContainer;
Christian Robertson2e347422011-08-11 14:01:04 -0700115import com.android.systemui.statusbar.SignalClusterView;
Selim Cinekc27437b2014-05-14 10:23:33 +0200116import com.android.systemui.statusbar.SpeedBumpView;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700117import com.android.systemui.statusbar.StatusBarIconView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200118import com.android.systemui.statusbar.StatusBarState;
Daniel Sandler2b697352011-07-22 16:23:09 -0400119import com.android.systemui.statusbar.policy.BatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400120import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
121import com.android.systemui.statusbar.policy.CastControllerImpl;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700122import com.android.systemui.statusbar.policy.DateView;
Chris Wren157026f2013-06-28 16:54:01 -0400123import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200124import com.android.systemui.statusbar.policy.UserInfoController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400125import com.android.systemui.statusbar.policy.LocationControllerImpl;
126import com.android.systemui.statusbar.policy.NetworkControllerImpl;
127import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
John Spurlock86005342014-05-23 11:58:00 -0400128import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek67b22602014-03-10 15:40:16 +0100129import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Christoph Studer92b389d2014-04-01 18:44:40 +0200130import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
131import com.android.systemui.statusbar.stack.StackScrollState.ViewState;
John Spurlock86005342014-05-23 11:58:00 -0400132import com.android.systemui.volume.VolumeComponent;
Selim Cinek67b22602014-03-10 15:40:16 +0100133
Daniel Sandler6a858c32012-03-12 14:38:58 -0400134import java.io.FileDescriptor;
135import java.io.PrintWriter;
136import java.util.ArrayList;
Christoph Studer92b389d2014-04-01 18:44:40 +0200137import java.util.Collection;
138import java.util.Collections;
Daniel Sandler6a858c32012-03-12 14:38:58 -0400139
Jorim Jaggiecbab362014-04-23 16:13:15 +0200140public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200141 DragDownHelper.OnDragDownListener, ActivityStarter {
Joe Onoratofd52b182010-11-10 18:00:52 -0800142 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400143 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400144 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400145 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400146 public static final boolean DEBUG_GESTURES = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400147
John Spurlock342cad72013-10-08 09:36:50 -0400148 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400149
Daniel Sandler040c2e42012-10-17 00:56:33 -0400150 public static final boolean SETTINGS_DRAG_SHORTCUT = true;
151
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400152 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400153 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400154
Joe Onorato808182d2010-07-09 18:52:06 -0400155 public static final String ACTION_STATUSBAR_START
156 = "com.android.internal.policy.statusbar.START";
157
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400158 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400159 private static final int MSG_CLOSE_PANELS = 1001;
160 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700161 // 1020-1030 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400162
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400163 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
164
Daniel Sandler58b173b2012-05-03 11:25:29 -0400165 private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
166 private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
167
Jorim Jaggi15682502014-04-23 12:01:36 +0200168 /**
169 * Default value of {@link android.provider.Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}.
170 */
171 private static final boolean ALLOW_NOTIFICATIONS_DEFAULT = false;
172
John Spurlocke1f366f2013-08-05 12:22:40 -0400173 private static final int STATUS_OR_NAV_TRANSIENT =
174 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400175 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400176
Christoph Studer92b389d2014-04-01 18:44:40 +0200177 /** The minimum delay in ms between reports of notification visibility. */
178 private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
179
Jorim Jaggi93a2bb22014-06-02 19:57:28 +0200180 /**
181 * The delay to reset the hint text when the hint animation is finished running.
182 */
183 private static final int HINT_RESET_DELAY_MS = 1200;
184
Daniel Sandlerdc940ea2011-08-25 14:35:53 -0700185 // fling gesture tuning parameters, scaled to display density
186 private float mSelfExpandVelocityPx; // classic value: 2000px/s
187 private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
188 private float mFlingExpandMinVelocityPx; // classic value: 200px/s
189 private float mFlingCollapseMinVelocityPx; // classic value: 200px/s
190 private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1)
191 private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
192 private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s
193
194 private float mExpandAccelPx; // classic value: 2000px/s/s
195 private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
196
John Spurlock209bede2013-07-17 12:23:27 -0400197 private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little
Daniel Sandlere5011a32012-06-11 16:07:52 -0400198 // faster than mSelfCollapseVelocityPx)
199
Joe Onoratofd52b182010-11-10 18:00:52 -0800200 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400201
Daniel Sandler2b697352011-07-22 16:23:09 -0400202 // These are no longer handled by the policy, because we need custom strategies for them
John Spurlockaf8d6c42014-05-07 17:49:08 -0400203 BluetoothControllerImpl mBluetoothController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400204 BatteryController mBatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400205 LocationControllerImpl mLocationController;
206 NetworkControllerImpl mNetworkController;
207 RotationLockControllerImpl mRotationLockController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200208 UserInfoController mUserInfoController;
John Spurlock86005342014-05-23 11:58:00 -0400209 ZenModeController mZenModeController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400210 CastControllerImpl mCastController;
John Spurlock86005342014-05-23 11:58:00 -0400211 VolumeComponent mVolumeComponent;
Jim Miller5e6af442011-12-02 18:24:26 -0800212
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400213 int mNaturalBarHeight = -1;
214 int mIconSize = -1;
215 int mIconHPadding = -1;
Joe Onorato808182d2010-07-09 18:52:06 -0400216 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400217 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400218
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400219 StatusBarWindowView mStatusBarWindow;
Joe Onoratofd52b182010-11-10 18:00:52 -0800220 PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400221 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100222 private StatusBarWindowManager mStatusBarWindowManager;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200223 private UnlockMethodCache mUnlockMethodCache;
Daniel Sandlera310af82012-04-24 01:20:13 -0400224
Joe Onorato808182d2010-07-09 18:52:06 -0400225 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400226 Object mQueueLock = new Object();
227
Daniel Sandler173bae22012-09-25 14:37:42 -0400228 // viewgroup containing the normal contents of the statusbar
229 LinearLayout mStatusBarContents;
John Spurlock209bede2013-07-17 12:23:27 -0400230
Daniel Sandler173bae22012-09-25 14:37:42 -0400231 // right-hand icons
232 LinearLayout mSystemIconArea;
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200233 LinearLayout mSystemIcons;
John Spurlock209bede2013-07-17 12:23:27 -0400234
235 // left-hand icons
Joe Onorato808182d2010-07-09 18:52:06 -0400236 LinearLayout mStatusIcons;
Daniel Sandler173bae22012-09-25 14:37:42 -0400237 // the icons themselves
238 IconMerger mNotificationIcons;
239 // [+>
240 View mMoreIcon;
Joe Onorato808182d2010-07-09 18:52:06 -0400241
242 // expanded notifications
Daniel Sandler040c2e42012-10-17 00:56:33 -0400243 NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400244 View mExpandedContents;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400245 int mNotificationPanelGravity;
Jorim Jaggid7daab72014-05-06 22:22:20 +0200246 int mNotificationPanelMarginBottomPx;
Daniel Sandlere680f542012-09-28 12:22:27 -0400247 float mNotificationPanelMinHeightFrac;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400248 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400249
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400250 // settings
Daniel Sandler101784e2012-10-15 13:39:38 -0400251 View mFlipSettingsView;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400252 private QSPanel mQSPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400253
Joe Onorato808182d2010-07-09 18:52:06 -0400254 // top bar
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200255 StatusBarHeaderView mHeader;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200256 View mKeyguardStatusView;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200257 KeyguardBottomAreaView mKeyguardBottomArea;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200258 boolean mLeaveOpenOnKeyguardHide;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200259 KeyguardIndicationController mKeyguardIndicationController;
Jorim Jaggie70d31f2014-04-24 22:08:30 +0200260
Jorim Jaggid4a57442014-04-10 02:45:55 +0200261 int mKeyguardMaxNotificationCount;
John Spurlock209bede2013-07-17 12:23:27 -0400262 View mDateTimeView;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400263
Daniel Sandler3d32a242012-06-05 13:44:14 -0400264 // carrier/wifi label
265 private TextView mCarrierLabel;
266 private boolean mCarrierLabelVisible = false;
267 private int mCarrierLabelHeight;
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400268 private TextView mEmergencyCallLabel;
Jorim Jaggid7daab72014-05-06 22:22:20 +0200269 private int mStatusBarHeaderHeight;
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400270
271 private boolean mShowCarrierInPanel = false;
Daniel Sandler3d32a242012-06-05 13:44:14 -0400272
Joe Onorato808182d2010-07-09 18:52:06 -0400273 // position
274 int[] mPositionTmp = new int[2];
Joe Onorato808182d2010-07-09 18:52:06 -0400275 boolean mExpandedVisible;
276
277 // the date view
278 DateView mDateView;
279
Chris Wren157026f2013-06-28 16:54:01 -0400280 // for heads up notifications
281 private HeadsUpNotificationView mHeadsUpNotificationView;
Chris Wren51c75102013-07-16 20:49:17 -0400282 private int mHeadsUpNotificationDecay;
Joe Onorato808182d2010-07-09 18:52:06 -0400283
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400284 // on-screen navigation buttons
Daniel Sandler0129b312011-05-11 11:54:11 -0400285 private NavigationBarView mNavigationBarView = null;
John Spurlockd4e65752013-08-28 14:17:09 -0400286 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400287
Joe Onorato808182d2010-07-09 18:52:06 -0400288 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400289 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400290
291 // ticker
292 private Ticker mTicker;
293 private View mTickerView;
294 private boolean mTicking;
295
296 // Tracking finger for opening/closing.
297 int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
298 boolean mTracking;
299 VelocityTracker mVelocityTracker;
300
Joe Onorato808182d2010-07-09 18:52:06 -0400301 int[] mAbsPos = new int[2];
Chet Haase2f2022a2011-10-11 06:41:59 -0700302 Runnable mPostCollapseCleanup = null;
303
Joe Onorato808182d2010-07-09 18:52:06 -0400304 // for disabling the status bar
305 int mDisabled = 0;
306
Daniel Sandler60ee2562011-07-22 12:34:33 -0400307 // tracking calls to View.setSystemUiVisibility()
308 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
309
Daniel Sandler36412a72011-08-04 09:35:13 -0400310 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700311
Daniel Sandler33805342012-07-23 15:45:12 -0400312 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400313 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400314 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400315 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400316
Daniel Sandler328310c2011-09-23 15:56:52 -0400317 private int mNavigationIconHints = 0;
Romain Guyf7f16f72012-05-24 19:13:56 -0700318 private final Animator.AnimatorListener mMakeIconsInvisible = new AnimatorListenerAdapter() {
319 @Override
320 public void onAnimationEnd(Animator animation) {
Daniel Sandler67e7d902012-06-06 16:32:21 -0400321 // double-check to avoid races
Daniel Sandler173bae22012-09-25 14:37:42 -0400322 if (mStatusBarContents.getAlpha() == 0) {
John Spurlockcd686b52013-06-05 10:13:46 -0400323 if (DEBUG) Log.d(TAG, "makeIconsInvisible");
Daniel Sandler173bae22012-09-25 14:37:42 -0400324 mStatusBarContents.setVisibility(View.INVISIBLE);
Daniel Sandler67e7d902012-06-06 16:32:21 -0400325 }
Romain Guyf7f16f72012-05-24 19:13:56 -0700326 }
327 };
Daniel Sandler328310c2011-09-23 15:56:52 -0400328
John Spurlock919adac2012-10-02 16:41:12 -0400329 // ensure quick settings is disabled until the current user makes it through the setup wizard
330 private boolean mUserSetup = false;
331 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
332 @Override
333 public void onChange(boolean selfChange) {
334 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
335 mContext.getContentResolver(),
336 Settings.Secure.USER_SETUP_COMPLETE,
337 0 /*default */,
338 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400339 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400340 "selfChange=%s userSetup=%s mUserSetup=%s",
341 selfChange, userSetup, mUserSetup));
John Spurlock73203eb2014-04-15 16:14:46 -0400342
John Spurlock919adac2012-10-02 16:41:12 -0400343 if (userSetup != mUserSetup) {
344 mUserSetup = userSetup;
Jorim Jaggid7daab72014-05-06 22:22:20 +0200345 if (mNotificationPanel != null) {
346 mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned() && userSetup);
347 }
John Spurlock919adac2012-10-02 16:41:12 -0400348 if (!mUserSetup && mStatusBarView != null)
349 animateCollapseQuickSettings();
350 }
351 }
352 };
353
Chris Wrenf6e83f42013-09-11 14:02:59 -0400354 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
355 @Override
356 public void onChange(boolean selfChange) {
357 boolean wasUsing = mUseHeadsUp;
Chris Wren7bd241232014-02-28 16:25:05 -0500358 mUseHeadsUp = ENABLE_HEADS_UP && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
Chris Wren10d82df2014-03-01 10:34:51 -0500359 mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Chris Wren7bd241232014-02-28 16:25:05 -0500360 Settings.Global.HEADS_UP_OFF);
Chris Wren22ae46e2014-02-26 18:08:09 -0500361 mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
362 mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400363 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
364 if (wasUsing != mUseHeadsUp) {
365 if (!mUseHeadsUp) {
366 Log.d(TAG, "dismissing any existing heads up notification on disable event");
Chris Wren7bd241232014-02-28 16:25:05 -0500367 setHeadsUpVisibility(false);
368 mHeadsUpNotificationView.setNotification(null);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400369 removeHeadsUpView();
370 } else {
371 addHeadsUpView();
372 }
373 }
374 }
375 };
376
John Spurlockcfc359a2013-09-05 10:42:03 -0400377 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400378 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400379 private int mStatusBarMode;
380 private int mNavigationBarMode;
John Spurlock8c520422013-09-19 12:23:35 -0400381 private Boolean mScreenOn;
John Spurlock32beb2c2013-03-11 10:16:47 -0400382
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200383 private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200384 private ViewMediatorCallback mKeyguardViewMediatorCallback;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200385 private ScrimController mScrimController;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200386
John Spurlock32beb2c2013-03-11 10:16:47 -0400387 private final Runnable mAutohide = new Runnable() {
388 @Override
389 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400390 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400391 if (mSystemUiVisibility != requested) {
392 notifyUiVisibilityChanged(requested);
393 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400394 }};
395
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100396 private Runnable mOnFlipRunnable;
John Spurlockbf20eab2014-04-09 16:40:39 -0400397 private InterceptedNotifications mIntercepted;
John Spurlock73203eb2014-04-15 16:14:46 -0400398 private VelocityTracker mSettingsTracker;
399 private float mSettingsDownY;
John Spurlock4e9d7c12014-04-25 10:16:27 -0400400 private boolean mSettingsStarted;
John Spurlock73203eb2014-04-15 16:14:46 -0400401 private boolean mSettingsCancelled;
402 private boolean mSettingsClosing;
Christoph Studer037e34c2014-04-30 20:06:04 +0200403 private boolean mVisible;
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100404
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200405 private Interpolator mAlphaOut = new PathInterpolator(0f, 0.4f, 1f, 1f);
406 private Interpolator mAlphaIn = new PathInterpolator(0f, 0f, 0.8f, 1f);
407
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200408 private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
409 new OnChildLocationsChangedListener() {
410 @Override
411 public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
412 userActivity();
413 }
414 };
415
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200416 private int mDisabledUnmodified;
417
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100418 public void setOnFlipRunnable(Runnable onFlipRunnable) {
419 mOnFlipRunnable = onFlipRunnable;
420 }
421
Christoph Studer92b389d2014-04-01 18:44:40 +0200422 /** Keys of notifications currently visible to the user. */
423 private final ArraySet<String> mCurrentlyVisibleNotifications = new ArraySet<String>();
424 private long mLastVisibilityReportUptimeMs;
425
426 private static final int VISIBLE_LOCATIONS = ViewState.LOCATION_FIRST_CARD
427 | ViewState.LOCATION_TOP_STACK_PEEKING
428 | ViewState.LOCATION_MAIN_AREA
429 | ViewState.LOCATION_BOTTOM_STACK_PEEKING;
430
431 private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
432 new OnChildLocationsChangedListener() {
433 @Override
434 public void onChildLocationsChanged(
435 NotificationStackScrollLayout stackScrollLayout) {
436 if (mHandler.hasCallbacks(mVisibilityReporter)) {
437 // Visibilities will be reported when the existing
438 // callback is executed.
439 return;
440 }
441 // Calculate when we're allowed to run the visibility
442 // reporter. Note that this timestamp might already have
443 // passed. That's OK, the callback will just be executed
444 // ASAP.
445 long nextReportUptimeMs =
446 mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
447 mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
448 }
449 };
450
451 // Tracks notifications currently visible in mNotificationStackScroller and
452 // emits visibility events via NoMan on changes.
453 private final Runnable mVisibilityReporter = new Runnable() {
454 private final ArrayList<String> mTmpNewlyVisibleNotifications = new ArrayList<String>();
455 private final ArrayList<String> mTmpCurrentlyVisibleNotifications = new ArrayList<String>();
456
457 @Override
458 public void run() {
459 mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
460
461 // 1. Loop over mNotificationData entries:
462 // A. Keep list of visible notifications.
463 // B. Keep list of previously hidden, now visible notifications.
464 // 2. Compute no-longer visible notifications by removing currently
465 // visible notifications from the set of previously visible
466 // notifications.
467 // 3. Report newly visible and no-longer visible notifications.
468 // 4. Keep currently visible notifications for next report.
469 int N = mNotificationData.size();
470 for (int i = 0; i < N; i++) {
471 Entry entry = mNotificationData.get(i);
472 String key = entry.notification.getKey();
473 boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(key);
474 boolean currentlyVisible =
475 (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
476 if (currentlyVisible) {
477 // Build new set of visible notifications.
478 mTmpCurrentlyVisibleNotifications.add(key);
479 }
480 if (!previouslyVisible && currentlyVisible) {
481 mTmpNewlyVisibleNotifications.add(key);
482 }
483 }
484 ArraySet<String> noLongerVisibleNotifications = mCurrentlyVisibleNotifications;
485 noLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
486
487 logNotificationVisibilityChanges(
488 mTmpNewlyVisibleNotifications, noLongerVisibleNotifications);
489
490 mCurrentlyVisibleNotifications.clear();
491 mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
492
493 mTmpNewlyVisibleNotifications.clear();
494 mTmpCurrentlyVisibleNotifications.clear();
495 }
496 };
497
Jorim Jaggiecbab362014-04-23 16:13:15 +0200498 private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
499 @Override
500 public void onClick(View v) {
501 goToLockedShade(null);
502 }
503 };
504
Joe Onorato808182d2010-07-09 18:52:06 -0400505 @Override
John Spurlocke677d712014-02-13 12:52:19 -0500506 public void setZenMode(int mode) {
507 super.setZenMode(mode);
John Spurlock110e5b12014-02-27 13:09:35 -0500508 if (!isDeviceProvisioned()) return;
John Spurlockbf20eab2014-04-09 16:40:39 -0400509 final boolean zen = mode != Settings.Global.ZEN_MODE_OFF;
John Spurlockbf20eab2014-04-09 16:40:39 -0400510 if (!zen) {
511 mIntercepted.releaseIntercepted();
512 }
John Spurlockba2c6a02014-05-19 09:44:06 -0400513 if (mIconPolicy != null) {
514 mIconPolicy.setZenMode(zen);
515 }
John Spurlocke677d712014-02-13 12:52:19 -0500516 }
517
518 @Override
John Spurlock4b3bda22014-05-22 14:32:20 -0400519 protected void setShowLockscreenNotifications(boolean show) {
520 super.setShowLockscreenNotifications(show);
521 updateStackScrollerState();
522 }
523
524 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400525 public void start() {
526 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
527 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400528 updateDisplaySize();
John Spurlockbf20eab2014-04-09 16:40:39 -0400529 mIntercepted = new InterceptedNotifications(mContext, this);
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500530 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400531
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400532 addNavigationBar();
533
Joe Onorato808182d2010-07-09 18:52:06 -0400534 // Lastly, call to the icon policy to install/update all the icons.
Joe Onoratofd52b182010-11-10 18:00:52 -0800535 mIconPolicy = new PhoneStatusBarPolicy(mContext);
John Spurlocke677d712014-02-13 12:52:19 -0500536 mSettingsObserver.onChange(false); // set up
Chris Wrenf6e83f42013-09-11 14:02:59 -0400537
538 mHeadsUpObserver.onChange(true); // set up
539 if (ENABLE_HEADS_UP) {
540 mContext.getContentResolver().registerContentObserver(
Chris Wren10d82df2014-03-01 10:34:51 -0500541 Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
Chris Wrenf6e83f42013-09-11 14:02:59 -0400542 mHeadsUpObserver);
Chris Wren22ae46e2014-02-26 18:08:09 -0500543 mContext.getContentResolver().registerContentObserver(
544 Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
545 mHeadsUpObserver);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400546 }
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200547 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100548 startKeyguard();
Joe Onorato808182d2010-07-09 18:52:06 -0400549 }
550
551 // ================================================================================
552 // Constructing the view
553 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700554 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400555 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400556
557 Resources res = context.getResources();
558
Daniel Sandler6e8db882011-10-26 15:40:51 -0400559 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400560 loadDimens();
Joe Onorato808182d2010-07-09 18:52:06 -0400561
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700562 mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
563
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400564 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
Daniel Sandlera310af82012-04-24 01:20:13 -0400565 R.layout.super_status_bar, null);
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400566 mStatusBarWindow.mService = this;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400567 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
568 @Override
569 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400570 checkUserAutohide(v, event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400571 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500572 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400573 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400574 }
575 }
Chris Wren5de6e942012-05-16 14:22:21 -0400576 return mStatusBarWindow.onTouchEvent(event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400577 }});
578
Daniel Sandlera310af82012-04-24 01:20:13 -0400579 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400580 mStatusBarView.setBar(this);
John Spurlock209bede2013-07-17 12:23:27 -0400581
Daniel Sandler08d05e32012-08-08 16:39:54 -0400582 PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
583 mStatusBarView.setPanelHolder(holder);
584
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100585 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
586 R.id.notification_panel);
Daniel Sandler040c2e42012-10-17 00:56:33 -0400587 mNotificationPanel.setStatusBar(this);
Joe Onorato808182d2010-07-09 18:52:06 -0400588
Daniel Sandlerefb0faf2012-10-10 14:15:34 -0700589 // make the header non-responsive to clicks
590 mNotificationPanel.findViewById(R.id.header).setOnTouchListener(
591 new View.OnTouchListener() {
592 @Override
593 public boolean onTouch(View v, MotionEvent event) {
594 return true; // e eats everything
595 }
596 });
597
Jeff Brown98365d72012-08-19 20:30:52 -0700598 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700599 mStatusBarWindow.setBackground(null);
Romain Guy648342f2012-05-25 10:44:45 -0700600 mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
601 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700602 }
Chris Wren157026f2013-06-28 16:54:01 -0400603 if (ENABLE_HEADS_UP) {
604 mHeadsUpNotificationView =
605 (HeadsUpNotificationView) View.inflate(context, R.layout.heads_up, null);
606 mHeadsUpNotificationView.setVisibility(View.GONE);
607 mHeadsUpNotificationView.setBar(this);
Daniel Sandler6b318802012-04-13 14:05:19 -0400608 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400609 if (MULTIUSER_DEBUG) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100610 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
611 R.id.header_debug_info);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400612 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
613 }
Joe Onorato808182d2010-07-09 18:52:06 -0400614
John Spurlockd5ef5462012-06-13 11:19:51 -0400615 updateShowSearchHoldoff();
616
Daniel Sandler0129b312011-05-11 11:54:11 -0400617 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700618 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400619 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400620 if (showNav) {
Jim Miller5e6af442011-12-02 18:24:26 -0800621 mNavigationBarView =
Daniel Sandler0129b312011-05-11 11:54:11 -0400622 (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400623
Daniel Sandler6da2b762011-09-14 16:04:59 -0400624 mNavigationBarView.setDisabledFlags(mDisabled);
Jim Millere898ac52012-04-06 17:10:57 -0700625 mNavigationBarView.setBar(this);
John Spurlock9deaa282013-07-25 13:03:47 -0400626 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
627 @Override
628 public boolean onTouch(View v, MotionEvent event) {
629 checkUserAutohide(v, event);
630 return false;
631 }});
Daniel Sandler0129b312011-05-11 11:54:11 -0400632 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400633 } catch (RemoteException ex) {
634 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400635 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400636
Joe Onorato808182d2010-07-09 18:52:06 -0400637 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400638 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400639
640 mSystemIconArea = (LinearLayout) mStatusBarView.findViewById(R.id.system_icon_area);
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200641 mSystemIcons = (LinearLayout) mStatusBarView.findViewById(R.id.system_icons);
Daniel Sandlera310af82012-04-24 01:20:13 -0400642 mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons);
643 mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
Mats H Carlssoncd231432012-10-10 13:37:38 +0200644 mMoreIcon = mStatusBarView.findViewById(R.id.moreIcon);
Daniel Sandler05e24142011-11-10 11:56:49 -0500645 mNotificationIcons.setOverflowIndicator(mMoreIcon);
Daniel Sandler173bae22012-09-25 14:37:42 -0400646 mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
Daniel Sandlera310af82012-04-24 01:20:13 -0400647 mTickerView = mStatusBarView.findViewById(R.id.ticker);
Joe Onorato808182d2010-07-09 18:52:06 -0400648
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100649 mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
650 R.id.notification_stack_scroller);
651 mStackScroller.setLongPressListener(getNotificationLongClicker());
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200652 mStackScroller.setChildLocationsChangedListener(mOnChildLocationsChangedListener);
Selim Cinek80a14e52014-03-27 16:58:04 +0100653
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200654 mKeyguardIconOverflowContainer =
655 (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
656 R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
657 mKeyguardIconOverflowContainer.setOnActivatedListener(this);
Jorim Jaggie96fcd12014-05-07 21:10:35 +0200658 mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
Jorim Jaggid4a57442014-04-10 02:45:55 +0200659 mStackScroller.addView(mKeyguardIconOverflowContainer);
660
Selim Cinekc27437b2014-05-14 10:23:33 +0200661 SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate(
662 R.layout.status_bar_notification_speed_bump, mStackScroller, false);
663 mStackScroller.setSpeedBumpView(speedBump);
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100664 mExpandedContents = mStackScroller;
Selim Cinek67b22602014-03-10 15:40:16 +0100665
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200666 mScrimController = new ScrimController(mStatusBarWindow.findViewById(R.id.scrim_behind),
667 mStatusBarWindow.findViewById(R.id.scrim_in_front));
668 mStatusBarView.setScrimController(mScrimController);
669
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200670 mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200671 mHeader.setActivityStarter(this);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200672 mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200673 mKeyguardBottomArea =
674 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
675 mKeyguardBottomArea.setActivityStarter(this);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200676 mKeyguardIndicationController = new KeyguardIndicationController(mContext,
677 (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
678 R.id.keyguard_indication_text));
Daniel Sandlera310af82012-04-24 01:20:13 -0400679 mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400680
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200681 mDateTimeView = mHeader.findViewById(R.id.datetime);
Daniel Sandler458d5e12013-02-21 15:12:49 -0500682 if (mDateTimeView != null) {
Daniel Sandler3679bf52012-10-16 21:30:28 -0400683 mDateTimeView.setOnClickListener(mClockClickListener);
684 mDateTimeView.setEnabled(true);
685 }
686
Daniel Sandlera310af82012-04-24 01:20:13 -0400687 mTicker = new MyTicker(context, mStatusBarView);
Joe Onorato808182d2010-07-09 18:52:06 -0400688
Daniel Sandlera310af82012-04-24 01:20:13 -0400689 TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText);
Joe Onorato808182d2010-07-09 18:52:06 -0400690 tickerView.mTicker = mTicker;
691
Joe Onorato808182d2010-07-09 18:52:06 -0400692 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
693
Joe Onorato808182d2010-07-09 18:52:06 -0400694 // set the inital view visibility
695 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400696
Daniel Sandler2b697352011-07-22 16:23:09 -0400697 // Other icons
John Spurlockaf8d6c42014-05-07 17:49:08 -0400698 mLocationController = new LocationControllerImpl(mContext); // will post a notification
Daniel Sandler2b697352011-07-22 16:23:09 -0400699 mBatteryController = new BatteryController(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400700 mNetworkController = new NetworkControllerImpl(mContext);
701 mBluetoothController = new BluetoothControllerImpl(mContext);
702 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
703 mRotationLockController = new RotationLockControllerImpl(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500704 }
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200705 mUserInfoController = new UserInfoController(mContext);
John Spurlock86005342014-05-23 11:58:00 -0400706 mVolumeComponent = getComponent(VolumeComponent.class);
707 mZenModeController = mVolumeComponent.getZenController();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400708 mCastController = new CastControllerImpl(mContext);
Jim Miller5e6af442011-12-02 18:24:26 -0800709 final SignalClusterView signalCluster =
Daniel Sandlera310af82012-04-24 01:20:13 -0400710 (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
Daniel Sandler3d32a242012-06-05 13:44:14 -0400711
Winson Chungd63c59782012-09-05 17:34:41 -0700712
Christian Robertson2e347422011-08-11 14:01:04 -0700713 mNetworkController.addSignalCluster(signalCluster);
Daniel Sandler28f89d42011-08-15 14:04:15 -0400714 signalCluster.setNetworkController(mNetworkController);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400715
Daniel Sandler8b268d42013-05-28 16:17:13 -0400716 final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
717 if (isAPhone) {
718 mEmergencyCallLabel =
719 (TextView) mStatusBarWindow.findViewById(R.id.emergency_calls_only);
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100720 // TODO: Uncomment when correctly positioned
721// if (mEmergencyCallLabel != null) {
722// mNetworkController.addEmergencyLabelView(mEmergencyCallLabel);
723// mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() {
724// public void onClick(View v) { }});
725// mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
726// @Override
727// public void onLayoutChange(View v, int left, int top, int right, int bottom,
728// int oldLeft, int oldTop, int oldRight, int oldBottom) {
729// updateCarrierLabelVisibility(false);
730// }});
731// }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400732 }
733
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400734 mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
735 mShowCarrierInPanel = (mCarrierLabel != null);
John Spurlockcd686b52013-06-05 10:13:46 -0400736 if (DEBUG) Log.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
Daniel Sandlerbf526d12012-09-04 22:56:44 -0400737 if (mShowCarrierInPanel) {
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400738 mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
739
Daniel Sandler67234c42012-06-15 13:17:39 -0400740 // for mobile devices, we always show mobile connection info here (SPN/PLMN)
741 // for other devices, we show whatever network is connected
Daniel Sandler18ac7822012-06-11 16:07:18 -0400742 if (mNetworkController.hasMobileDataFeature()) {
743 mNetworkController.addMobileLabelView(mCarrierLabel);
744 } else {
Daniel Sandler67234c42012-06-15 13:17:39 -0400745 mNetworkController.addCombinedLabelView(mCarrierLabel);
Daniel Sandler18ac7822012-06-11 16:07:18 -0400746 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400747
748 // set up the dynamic hide/show of the label
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100749 // TODO: uncomment, handle this for the Stack scroller aswell
750// ((NotificationRowLayout) mStackScroller)
751// .setOnSizeChangedListener(new OnSizeChangedListener() {
752// @Override
753// public void onSizeChanged(View view, int w, int h, int oldw, int oldh) {
754// updateCarrierLabelVisibility(false);
Daniel Sandler3d32a242012-06-05 13:44:14 -0400755 }
756
John Spurlockaf8d6c42014-05-07 17:49:08 -0400757 // Set up the quick settings tile panel
758 mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel);
759 if (mQSPanel != null) {
John Spurlock4bf31982014-05-21 13:04:22 -0400760 mQSPanel.setUtils(new CircularClipper.Utils() {
761 @Override
762 public ValueAnimator createRevealAnimator(View v, int centerX, int centerY,
763 float startRadius, float endRadius) {
ztenghui62f30e02014-06-05 09:55:04 -0700764 return ViewAnimationUtils.createCircularReveal(v, centerX, centerY,
765 startRadius, endRadius);
John Spurlock4bf31982014-05-21 13:04:22 -0400766 }
767 });
John Spurlockaf8d6c42014-05-07 17:49:08 -0400768 final QSTileHost qsh = new QSTileHost(mContext, this,
769 mBluetoothController, mLocationController, mRotationLockController,
770 mNetworkController, mZenModeController, null /*tethering*/,
John Spurlock86005342014-05-23 11:58:00 -0400771 mCastController, mVolumeComponent);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400772 for (QSTile<?> tile : qsh.getTiles()) {
773 mQSPanel.addTile(tile);
774 }
775 mHeader.setQSPanel(mQSPanel);
Siva Velusamy537421b2012-09-14 14:45:02 -0700776 }
777
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200778 // User info. Trigger first load.
779 mHeader.setUserInfoController(mUserInfoController);
780 mUserInfoController.reloadUserInfo();
781
John Spurlock56d007b2013-10-28 18:40:56 -0400782 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
783 mBroadcastReceiver.onReceive(mContext,
784 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
785
Joe Onorato808182d2010-07-09 18:52:06 -0400786 // receive broadcasts
787 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400788 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
789 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400790 filter.addAction(Intent.ACTION_SCREEN_ON);
John Spurlock3c875662013-08-31 15:07:25 -0400791 filter.addAction(ACTION_DEMO);
Joe Onorato808182d2010-07-09 18:52:06 -0400792 context.registerReceiver(mBroadcastReceiver, filter);
793
John Spurlock919adac2012-10-02 16:41:12 -0400794 // listen for USER_SETUP_COMPLETE setting (per-user)
795 resetUserSetupObserver();
796
Daniel Sandlera310af82012-04-24 01:20:13 -0400797 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400798 }
799
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100800 private void startKeyguard() {
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200801 KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
802 mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200803 mStatusBarWindow, mStatusBarWindowManager, mScrimController);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200804 mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100805 }
806
Michael Jurka7f2668c2012-03-27 07:49:52 -0700807 @Override
Jim Millerad178a42013-10-08 20:03:38 -0700808 protected void onShowSearchPanel() {
809 if (mNavigationBarView != null) {
John Spurlock56d007b2013-10-28 18:40:56 -0400810 mNavigationBarView.getBarTransitions().setContentVisible(false);
Jim Millerad178a42013-10-08 20:03:38 -0700811 }
812 }
813
814 @Override
815 protected void onHideSearchPanel() {
816 if (mNavigationBarView != null) {
John Spurlock56d007b2013-10-28 18:40:56 -0400817 mNavigationBarView.getBarTransitions().setContentVisible(true);
Jim Millerad178a42013-10-08 20:03:38 -0700818 }
819 }
820
821 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -0700822 protected View getStatusBarView() {
823 return mStatusBarView;
824 }
825
826 @Override
Jim Millere898ac52012-04-06 17:10:57 -0700827 protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
828 boolean opaque = false;
829 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
830 LayoutParams.MATCH_PARENT,
831 LayoutParams.MATCH_PARENT,
832 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
833 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
834 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
835 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
836 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
Jeff Brown98365d72012-08-19 20:30:52 -0700837 if (ActivityManager.isHighEndGfx()) {
Jim Millere898ac52012-04-06 17:10:57 -0700838 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Jim Millere898ac52012-04-06 17:10:57 -0700839 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700840 lp.gravity = Gravity.BOTTOM | Gravity.START;
Jim Millere898ac52012-04-06 17:10:57 -0700841 lp.setTitle("SearchPanel");
842 // TODO: Define custom animation for Search panel
843 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
844 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
845 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
846 return lp;
847 }
848
Jim Millere898ac52012-04-06 17:10:57 -0700849 @Override
850 protected void updateSearchPanel() {
851 super.updateSearchPanel();
John Spurlockf6b63972013-08-27 16:08:28 -0400852 if (mNavigationBarView != null) {
853 mNavigationBarView.setDelegateView(mSearchPanelView);
854 }
Jim Millere898ac52012-04-06 17:10:57 -0700855 }
856
857 @Override
858 public void showSearchPanel() {
Jim Millerb490c3e2012-05-31 13:34:16 -0700859 super.showSearchPanel();
John Spurlock7a733442012-11-08 09:08:14 -0500860 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlerd5483c32012-10-19 16:44:15 -0400861
862 // we want to freeze the sysui state wherever it is
863 mSearchPanelView.setSystemUiVisibility(mSystemUiVisibility);
864
John Spurlockf6b63972013-08-27 16:08:28 -0400865 if (mNavigationBarView != null) {
866 WindowManager.LayoutParams lp =
867 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
868 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
869 mWindowManager.updateViewLayout(mNavigationBarView, lp);
870 }
Jim Millere898ac52012-04-06 17:10:57 -0700871 }
872
873 @Override
874 public void hideSearchPanel() {
875 super.hideSearchPanel();
John Spurlockf6b63972013-08-27 16:08:28 -0400876 if (mNavigationBarView != null) {
877 WindowManager.LayoutParams lp =
878 (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
879 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
880 mWindowManager.updateViewLayout(mNavigationBarView, lp);
881 }
Jim Millere898ac52012-04-06 17:10:57 -0700882 }
883
Joe Onoratodc100302011-01-11 17:07:41 -0800884 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -0400885 if (mNaturalBarHeight < 0) {
886 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -0700887 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -0400888 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
889 }
890 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -0800891 }
892
Daniel Sandler5c8da942011-06-28 00:29:04 -0400893 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
894 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -0400895 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400896 toggleRecentApps();
897 }
898 };
Chris Wren0c8275b2012-05-08 13:36:48 -0400899
Jim Miller9a720f52012-05-30 03:19:43 -0700900 private int mShowSearchHoldoff = 0;
901 private Runnable mShowSearchPanel = new Runnable() {
902 public void run() {
903 showSearchPanel();
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400904 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700905 }
906 };
907
Jorim Jaggi7b0de292014-05-27 21:41:55 +0200908 View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
Jim Millere898ac52012-04-06 17:10:57 -0700909 public boolean onTouch(View v, MotionEvent event) {
910 switch(event.getAction()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700911 case MotionEvent.ACTION_DOWN:
Daniel Sandlerd5483c32012-10-19 16:44:15 -0400912 if (!shouldDisableNavbarGestures()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700913 mHandler.removeCallbacks(mShowSearchPanel);
914 mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
915 }
916 break;
917
918 case MotionEvent.ACTION_UP:
919 case MotionEvent.ACTION_CANCEL:
920 mHandler.removeCallbacks(mShowSearchPanel);
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400921 awakenDreams();
Jim Miller9a720f52012-05-30 03:19:43 -0700922 break;
923 }
924 return false;
Jim Millere898ac52012-04-06 17:10:57 -0700925 }
926 };
Daniel Sandler5c8da942011-06-28 00:29:04 -0400927
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400928 private void awakenDreams() {
929 if (mDreamManager != null) {
930 try {
931 mDreamManager.awaken();
932 } catch (RemoteException e) {
933 // fine, stay asleep then
934 }
935 }
936 }
937
Michael Jurka412cba82011-10-17 09:05:00 -0700938 private void prepareNavigationBarView() {
939 mNavigationBarView.reorient();
940
941 mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
Michael Jurka80343f62012-10-18 13:13:46 +0200942 mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
Jorim Jaggi7b0de292014-05-27 21:41:55 +0200943 mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
Jim Millere898ac52012-04-06 17:10:57 -0700944 updateSearchPanel();
Michael Jurka412cba82011-10-17 09:05:00 -0700945 }
946
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400947 // For small-screen devices (read: phones) that lack hardware navigation buttons
948 private void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -0400949 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -0400950 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700951
Michael Jurka412cba82011-10-17 09:05:00 -0700952 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400953
Jeff Brown98365d72012-08-19 20:30:52 -0700954 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400955 }
956
957 private void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -0400958 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -0700959
Michael Jurka412cba82011-10-17 09:05:00 -0700960 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400961
Jeff Brown98365d72012-08-19 20:30:52 -0700962 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400963 }
964
John Spurlock1bbd49d2012-10-19 11:09:32 -0400965 private void notifyNavigationBarScreenOn(boolean screenOn) {
966 if (mNavigationBarView == null) return;
967 mNavigationBarView.notifyScreenOn(screenOn);
968 }
969
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400970 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400971 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -0700972 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400973 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
974 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400975 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
976 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -0700977 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -0400978 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -0700979 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
John Spurlockad3e6cb2013-04-30 08:47:43 -0400980 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700981 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -0700982 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -0700983 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
984 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400985
986 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400987 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400988 return lp;
989 }
990
Chris Wren157026f2013-06-28 16:54:01 -0400991 private void addHeadsUpView() {
Adrian Roos5d9cc662014-05-28 17:08:13 +0200992 int headsUpHeight = mContext.getResources()
993 .getDimensionPixelSize(R.dimen.heads_up_window_height);
Joe Onorato808182d2010-07-09 18:52:06 -0400994 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Adrian Roos5d9cc662014-05-28 17:08:13 +0200995 LayoutParams.MATCH_PARENT, headsUpHeight,
Chris Wren9afc50d2013-07-30 11:31:46 -0400996 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
Joe Onorato808182d2010-07-09 18:52:06 -0400997 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
998 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
999 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
1000 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Jeff Brown46e75292010-11-10 16:53:45 -08001001 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
1002 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Joe Onorato808182d2010-07-09 18:52:06 -04001003 PixelFormat.TRANSLUCENT);
Chris Wren51c75102013-07-16 20:49:17 -04001004 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Chris Wren0f2aa682013-08-02 12:03:02 -04001005 lp.gravity = Gravity.TOP;
Chris Wren157026f2013-06-28 16:54:01 -04001006 lp.setTitle("Heads Up");
Dianne Hackborn59aed382011-08-02 17:31:44 -07001007 lp.packageName = mContext.getPackageName();
Chris Wren157026f2013-06-28 16:54:01 -04001008 lp.windowAnimations = R.style.Animation_StatusBar_HeadsUp;
Joe Onorato808182d2010-07-09 18:52:06 -04001009
Chris Wren157026f2013-06-28 16:54:01 -04001010 mWindowManager.addView(mHeadsUpNotificationView, lp);
Joe Onorato808182d2010-07-09 18:52:06 -04001011 }
1012
Chris Wrenf6e83f42013-09-11 14:02:59 -04001013 private void removeHeadsUpView() {
1014 mWindowManager.removeView(mHeadsUpNotificationView);
1015 }
1016
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -08001017 public void refreshAllStatusBarIcons() {
Fabrice Di Meglioc0cea0f2013-01-11 16:18:00 -08001018 refreshAllIconsForLayout(mStatusIcons);
1019 refreshAllIconsForLayout(mNotificationIcons);
1020 }
1021
1022 private void refreshAllIconsForLayout(LinearLayout ll) {
1023 final int count = ll.getChildCount();
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -08001024 for (int n = 0; n < count; n++) {
Fabrice Di Meglioc0cea0f2013-01-11 16:18:00 -08001025 View child = ll.getChildAt(n);
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -08001026 if (child instanceof StatusBarIconView) {
1027 ((StatusBarIconView) child).updateDrawable();
1028 }
1029 }
1030 }
1031
Joe Onorato808182d2010-07-09 18:52:06 -04001032 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
John Spurlockcd686b52013-06-05 10:13:46 -04001033 if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
Joe Onorato808182d2010-07-09 18:52:06 -04001034 + " icon=" + icon);
John Spurlocke6f0a712013-09-03 16:23:49 -04001035 StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
Joe Onorato808182d2010-07-09 18:52:06 -04001036 view.set(icon);
1037 mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
1038 }
1039
1040 public void updateIcon(String slot, int index, int viewIndex,
1041 StatusBarIcon old, StatusBarIcon icon) {
John Spurlockcd686b52013-06-05 10:13:46 -04001042 if (SPEW) Log.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
Joe Onorato808182d2010-07-09 18:52:06 -04001043 + " old=" + old + " icon=" + icon);
1044 StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
1045 view.set(icon);
1046 }
1047
1048 public void removeIcon(String slot, int index, int viewIndex) {
John Spurlockcd686b52013-06-05 10:13:46 -04001049 if (SPEW) Log.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
Joe Onorato808182d2010-07-09 18:52:06 -04001050 mStatusIcons.removeViewAt(viewIndex);
1051 }
1052
John Spurlockbf20eab2014-04-09 16:40:39 -04001053 public UserHandle getCurrentUserHandle() {
1054 return new UserHandle(mCurrentUserId);
1055 }
1056
Christoph Studer71f18fd2014-05-20 17:02:04 +02001057 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001058 public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
Chris Wrenaaa58d12014-06-03 14:29:12 -04001059 if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
Chris Wren333a61c2014-05-28 16:40:57 -04001060 if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification, ranking)) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001061 // Forward the ranking so we can sort the new notification.
1062 mNotificationData.updateRanking(ranking);
John Spurlockbf20eab2014-04-09 16:40:39 -04001063 return;
1064 }
Chris Wrenaaa58d12014-06-03 14:29:12 -04001065 mIntercepted.remove(notification.getKey());
1066 displayNotification(notification, ranking);
1067 }
1068
1069 public void displayNotification(StatusBarNotification notification,
1070 Ranking ranking) {
1071 Entry shadeEntry = createNotificationViews(notification);
1072 if (shadeEntry == null) {
1073 return;
1074 }
John Spurlockbf20eab2014-04-09 16:40:39 -04001075 if (mUseHeadsUp && shouldInterrupt(notification)) {
1076 if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
Christoph Studer71f18fd2014-05-20 17:02:04 +02001077 Entry interruptionCandidate = new Entry(notification, null);
John Spurlockbf20eab2014-04-09 16:40:39 -04001078 ViewGroup holder = mHeadsUpNotificationView.getHolder();
1079 if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
1080 mInterruptingNotificationTime = System.currentTimeMillis();
1081 mInterruptingNotificationEntry = interruptionCandidate;
1082 shadeEntry.setInterruption();
Joe Onorato808182d2010-07-09 18:52:06 -04001083
John Spurlockbf20eab2014-04-09 16:40:39 -04001084 // 1. Populate mHeadsUpNotificationView
1085 mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
Chris Wrend4db6cb2013-08-07 16:05:23 -04001086
John Spurlockbf20eab2014-04-09 16:40:39 -04001087 // 2. Animate mHeadsUpNotificationView in
1088 mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
Joe Onorato808182d2010-07-09 18:52:06 -04001089
John Spurlockbf20eab2014-04-09 16:40:39 -04001090 // 3. Set alarm to age the notification off
1091 resetHeadsUpDecayTimer();
1092 }
1093 } else if (notification.getNotification().fullScreenIntent != null) {
1094 // Stop screensaver if the notification has a full-screen intent.
1095 // (like an incoming phone call)
1096 awakenDreams();
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -04001097
John Spurlockbf20eab2014-04-09 16:40:39 -04001098 // not immersive & a full-screen alert should be shown
1099 if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
1100 try {
1101 notification.getNotification().fullScreenIntent.send();
1102 } catch (PendingIntent.CanceledException e) {
1103 }
1104 } else {
1105 // usual case: status bar visible & not immersive
Joe Onorato808182d2010-07-09 18:52:06 -04001106
John Spurlockbf20eab2014-04-09 16:40:39 -04001107 // show the ticker if there isn't already a heads up
1108 if (mInterruptingNotificationEntry == null) {
Christoph Studer71f18fd2014-05-20 17:02:04 +02001109 tick(notification, true);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04001110 }
Joe Onorato808182d2010-07-09 18:52:06 -04001111 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001112 addNotificationViews(shadeEntry, ranking);
Joe Onorato808182d2010-07-09 18:52:06 -04001113 // Recalculate the position of the sliding windows and the titles.
1114 setAreThereNotifications();
1115 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
1116 }
1117
Chris Wren51c75102013-07-16 20:49:17 -04001118 @Override
1119 public void resetHeadsUpDecayTimer() {
Chris Wren7fd2a3b2014-03-26 12:39:41 -04001120 mHandler.removeMessages(MSG_HIDE_HEADS_UP);
Chris Wreneda110f2013-07-25 15:31:59 -04001121 if (mUseHeadsUp && mHeadsUpNotificationDecay > 0
Chris Wren6d15a362013-08-20 18:46:29 -04001122 && mHeadsUpNotificationView.isClearable()) {
Chris Wren51c75102013-07-16 20:49:17 -04001123 mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay);
1124 }
1125 }
1126
John Spurlockbf20eab2014-04-09 16:40:39 -04001127 @Override
Christoph Studere3589682014-05-26 23:21:16 +02001128 public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
1129 super.updateNotificationInternal(notification, ranking);
Chris Wrenaaa58d12014-06-03 14:29:12 -04001130 // if we're here, then the notification is already in the shade
1131 mIntercepted.remove(notification.getKey());
John Spurlockbf20eab2014-04-09 16:40:39 -04001132 }
1133
Christoph Studer71f18fd2014-05-20 17:02:04 +02001134 @Override
Chris Wren333a61c2014-05-28 16:40:57 -04001135 protected void updateRankingInternal(Ranking ranking) {
1136 mNotificationData.updateRanking(ranking);
1137 mIntercepted.retryIntercepts(ranking);
1138 updateNotifications();
1139 }
1140
1141 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001142 public void removeNotificationInternal(String key, Ranking ranking) {
1143 StatusBarNotification old = removeNotificationViews(key, ranking);
John Spurlockcd686b52013-06-05 10:13:46 -04001144 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -04001145
1146 if (old != null) {
1147 // Cancel the ticker if it's still running
1148 mTicker.removeEntry(old);
1149
1150 // Recalculate the position of the sliding windows and the titles.
Joe Onorato808182d2010-07-09 18:52:06 -04001151 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Jim Millere898ac52012-04-06 17:10:57 -07001152
Chris Wren51c75102013-07-16 20:49:17 -04001153 if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
1154 && old == mInterruptingNotificationEntry.notification) {
Chris Wren157026f2013-06-28 16:54:01 -04001155 mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04001156 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001157
John Spurlock1caf7eb2013-08-07 18:06:18 -04001158 if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0
Jorim Jaggiecbab362014-04-23 16:13:15 +02001159 && !mNotificationPanel.isTracking() && mState != StatusBarState.KEYGUARD) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001160 animateCollapsePanels();
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001161 }
Joe Onorato808182d2010-07-09 18:52:06 -04001162 }
John Spurlockbf20eab2014-04-09 16:40:39 -04001163 mIntercepted.remove(key);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001164 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001165 }
1166
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001167 @Override
1168 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001169 if (mNavigationBarView != null) {
1170 mNavigationBarView.setLayoutDirection(layoutDirection);
1171 }
Fabrice Di Meglio82fca5d2013-01-09 15:42:31 -08001172 refreshAllStatusBarIcons();
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001173 }
1174
John Spurlockd5ef5462012-06-13 11:19:51 -04001175 private void updateShowSearchHoldoff() {
1176 mShowSearchHoldoff = mContext.getResources().getInteger(
1177 R.integer.config_show_search_delay);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001178 }
1179
Christoph Studer37fe6932014-05-26 13:10:30 +02001180 private void updateNotificationShade() {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001181 if (mStackScroller == null) return;
Daniel Sandler26cda272012-05-22 15:44:08 -04001182
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001183 int N = mNotificationData.size();
1184
1185 ArrayList<View> toShow = new ArrayList<View>();
1186
Daniel Sandler26cda272012-05-22 15:44:08 -04001187 final boolean provisioned = isDeviceProvisioned();
1188 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001189 for (int i=0; i<N; i++) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001190 Entry ent = mNotificationData.get(i);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001191 if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001192
Kenny Guy2a764942014-04-02 13:29:20 +01001193 if (!notificationIsForCurrentProfiles(ent.notification)) continue;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001194
Dan Sandlera5e0f412014-01-23 15:11:54 -05001195 final int vis = ent.notification.getNotification().visibility;
1196 if (vis != Notification.VISIBILITY_SECRET) {
Dan Sandlerfd16d562014-02-13 18:43:31 -08001197 // when isLockscreenPublicMode() we show the public form of VISIBILITY_PRIVATE notifications
1198 ent.row.setShowingPublic(isLockscreenPublicMode()
1199 && vis == Notification.VISIBILITY_PRIVATE
1200 && !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId()));
Dan Sandlera5e0f412014-01-23 15:11:54 -05001201 toShow.add(ent.row);
1202 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001203 }
1204
1205 ArrayList<View> toRemove = new ArrayList<View>();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001206 for (int i=0; i< mStackScroller.getChildCount(); i++) {
1207 View child = mStackScroller.getChildAt(i);
Selim Cinekc27437b2014-05-14 10:23:33 +02001208 if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001209 toRemove.add(child);
Joe Onorato808182d2010-07-09 18:52:06 -04001210 }
1211 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001212
1213 for (View remove : toRemove) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001214 mStackScroller.removeView(remove);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001215 }
1216
1217 for (int i=0; i<toShow.size(); i++) {
1218 View v = toShow.get(i);
1219 if (v.getParent() == null) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001220 mStackScroller.addView(v);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001221 }
1222 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001223
Christoph Studer37fe6932014-05-26 13:10:30 +02001224 // So after all this work notifications still aren't sorted correctly.
1225 // Let's do that now by advancing through toShow and mStackScroller in
1226 // lock-step, making sure mStackScroller matches what we see in toShow.
1227 int j = 0;
1228 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1229 View child = mStackScroller.getChildAt(i);
1230 if (!(child instanceof ExpandableNotificationRow)) {
1231 // We don't care about non-notification views.
1232 continue;
1233 }
1234
1235 if (child == toShow.get(j)) {
1236 // Everything is well, advance both lists.
1237 j++;
1238 continue;
1239 }
1240
1241 // Oops, wrong notification at this position. Put the right one
1242 // here and advance both lists.
1243 mStackScroller.changeViewPosition(toShow.get(j), i);
1244 j++;
1245 }
1246 updateRowStates();
1247 updateSpeedbump();
Jorim Jaggid7daab72014-05-06 22:22:20 +02001248 mNotificationPanel.setQsExpansionEnabled(provisioned && mUserSetup);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001249 }
1250
Christoph Studer37fe6932014-05-26 13:10:30 +02001251 private void updateSpeedbump() {
1252 int speedbumpIndex = -1;
1253 int currentIndex = 0;
1254 for (int i = 0; i < mNotificationData.size(); i++) {
1255 Entry entry = mNotificationData.get(i);
1256 if (entry.row.getParent() == null) {
1257 // This view isn't even added, so the stack scroller doesn't
1258 // know about it. Ignore completely.
1259 continue;
1260 }
1261 if (entry.row.getVisibility() != View.GONE &&
1262 mNotificationData.isAmbient(entry.key)) {
1263 speedbumpIndex = currentIndex;
1264 break;
1265 }
1266 currentIndex++;
1267 }
1268 mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
1269 }
1270
Chris Wren0c8275b2012-05-08 13:36:48 -04001271 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001272 protected void updateNotifications() {
1273 // TODO: Move this into updateNotificationIcons()?
Daniel Sandler26cda272012-05-22 15:44:08 -04001274 if (mNotificationIcons == null) return;
1275
Christoph Studer37fe6932014-05-26 13:10:30 +02001276 updateNotificationShade();
1277 updateNotificationIcons();
1278 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001279
Christoph Studer37fe6932014-05-26 13:10:30 +02001280 private void updateNotificationIcons() {
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001281 final LinearLayout.LayoutParams params
1282 = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
1283
1284 int N = mNotificationData.size();
1285
1286 if (DEBUG) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001287 Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" +
1288 mNotificationIcons);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001289 }
1290
1291 ArrayList<View> toShow = new ArrayList<View>();
1292
Daniel Sandler26cda272012-05-22 15:44:08 -04001293 final boolean provisioned = isDeviceProvisioned();
1294 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001295 for (int i=0; i<N; i++) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001296 Entry ent = mNotificationData.get(i);
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -04001297 if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001298 || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
Kenny Guy2a764942014-04-02 13:29:20 +01001299 if (!notificationIsForCurrentProfiles(ent.notification)) continue;
Dan Sandlerfd16d562014-02-13 18:43:31 -08001300 if (isLockscreenPublicMode()
Dan Sandlera5e0f412014-01-23 15:11:54 -05001301 && ent.notification.getNotification().visibility
Dan Sandlerfd16d562014-02-13 18:43:31 -08001302 == Notification.VISIBILITY_SECRET
1303 && !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId())) {
Dan Sandlera5e0f412014-01-23 15:11:54 -05001304 // in "public" mode (atop a secure keyguard), secret notifs are totally hidden
1305 continue;
1306 }
John Spurlockbf20eab2014-04-09 16:40:39 -04001307 if (mIntercepted.isSyntheticEntry(ent)) {
John Spurlocke677d712014-02-13 12:52:19 -05001308 continue;
1309 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04001310 toShow.add(ent.icon);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001311 }
1312
1313 ArrayList<View> toRemove = new ArrayList<View>();
1314 for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
1315 View child = mNotificationIcons.getChildAt(i);
1316 if (!toShow.contains(child)) {
1317 toRemove.add(child);
1318 }
1319 }
1320
1321 for (View remove : toRemove) {
1322 mNotificationIcons.removeView(remove);
1323 }
1324
1325 for (int i=0; i<toShow.size(); i++) {
1326 View v = toShow.get(i);
1327 if (v.getParent() == null) {
1328 mNotificationIcons.addView(v, i, params);
1329 }
1330 }
1331 }
1332
Daniel Sandlere5011a32012-06-11 16:07:52 -04001333 protected void updateCarrierLabelVisibility(boolean force) {
Selim Cinek80a14e52014-03-27 16:58:04 +01001334 // TODO: Handle this for the notification stack scroller as well
Daniel Sandlerbf526d12012-09-04 22:56:44 -04001335 if (!mShowCarrierInPanel) return;
John Spurlock209bede2013-07-17 12:23:27 -04001336 // The idea here is to only show the carrier label when there is enough room to see it,
Daniel Sandler3d32a242012-06-05 13:44:14 -04001337 // i.e. when there aren't enough notifications to fill the panel.
Chris Wren6d15a362013-08-20 18:46:29 -04001338 if (SPEW) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001339 Log.d(TAG, String.format("stackScrollerh=%d scrollh=%d carrierh=%d",
1340 mStackScroller.getHeight(), mStackScroller.getHeight(),
1341 mCarrierLabelHeight));
Daniel Sandler3d32a242012-06-05 13:44:14 -04001342 }
Daniel Sandlerdd4ef492012-07-27 11:19:52 -04001343
1344 final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
1345 final boolean makeVisible =
1346 !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001347 && mStackScroller.getHeight() < (mNotificationPanel.getHeight()
Jorim Jaggid7daab72014-05-06 22:22:20 +02001348 - mCarrierLabelHeight - mStatusBarHeaderHeight)
Jorim Jaggi25807932014-04-24 23:29:46 +02001349 && mStackScroller.getVisibility() == View.VISIBLE
Jorim Jaggiecbab362014-04-23 16:13:15 +02001350 && mState != StatusBarState.KEYGUARD;
John Spurlock209bede2013-07-17 12:23:27 -04001351
Daniel Sandlere5011a32012-06-11 16:07:52 -04001352 if (force || mCarrierLabelVisible != makeVisible) {
Daniel Sandler3d32a242012-06-05 13:44:14 -04001353 mCarrierLabelVisible = makeVisible;
1354 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001355 Log.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
Daniel Sandler3d32a242012-06-05 13:44:14 -04001356 }
1357 mCarrierLabel.animate().cancel();
1358 if (makeVisible) {
1359 mCarrierLabel.setVisibility(View.VISIBLE);
1360 }
1361 mCarrierLabel.animate()
1362 .alpha(makeVisible ? 1f : 0f)
1363 //.setStartDelay(makeVisible ? 500 : 0)
1364 //.setDuration(makeVisible ? 750 : 100)
1365 .setDuration(150)
1366 .setListener(makeVisible ? null : new AnimatorListenerAdapter() {
1367 @Override
1368 public void onAnimationEnd(Animator animation) {
1369 if (!mCarrierLabelVisible) { // race
1370 mCarrierLabel.setVisibility(View.INVISIBLE);
1371 mCarrierLabel.setAlpha(0f);
1372 }
1373 }
1374 })
1375 .start();
1376 }
1377 }
1378
Chris Wren0c8275b2012-05-08 13:36:48 -04001379 @Override
1380 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001381 final boolean any = mNotificationData.size() > 0;
Joe Onorato808182d2010-07-09 18:52:06 -04001382
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001383 final boolean clearable = any && mNotificationData.hasClearableItems();
1384
Chris Wren6d15a362013-08-20 18:46:29 -04001385 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001386 Log.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001387 + " any=" + any + " clearable=" + clearable);
1388 }
1389
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001390 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
1391 final boolean showDot = (any&&!areLightsOn());
1392 if (showDot != (nlo.getAlpha() == 1.0f)) {
1393 if (showDot) {
1394 nlo.setAlpha(0f);
1395 nlo.setVisibility(View.VISIBLE);
1396 }
1397 nlo.animate()
1398 .alpha(showDot?1:0)
1399 .setDuration(showDot?750:250)
1400 .setInterpolator(new AccelerateInterpolator(2.0f))
1401 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1402 @Override
1403 public void onAnimationEnd(Animator _a) {
1404 nlo.setVisibility(View.GONE);
1405 }
1406 })
1407 .start();
1408 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001409
Daniel Sandlere5011a32012-06-11 16:07:52 -04001410 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001411 }
1412
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001413 public void showClock(boolean show) {
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001414 if (mStatusBarView == null) return;
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001415 View clock = mStatusBarView.findViewById(R.id.clock);
1416 if (clock != null) {
1417 clock.setVisibility(show ? View.VISIBLE : View.GONE);
1418 }
1419 }
Joe Onorato808182d2010-07-09 18:52:06 -04001420
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001421 private int adjustDisableFlags(int state) {
1422 if (mExpandedVisible) {
1423 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
1424 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
1425 }
1426 return state;
1427 }
1428
Joe Onorato808182d2010-07-09 18:52:06 -04001429 /**
1430 * State is one or more of the DISABLE constants from StatusBarManager.
1431 */
1432 public void disable(int state) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001433 mDisabledUnmodified = state;
1434 state = adjustDisableFlags(state);
Joe Onorato808182d2010-07-09 18:52:06 -04001435 final int old = mDisabled;
1436 final int diff = state ^ old;
1437 mDisabled = state;
1438
Daniel Sandlere21f2882011-08-18 10:14:59 -04001439 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001440 Log.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
Daniel Sandlere21f2882011-08-18 10:14:59 -04001441 old, state, diff));
1442 }
1443
Daniel Sandler6da2b762011-09-14 16:04:59 -04001444 StringBuilder flagdbg = new StringBuilder();
1445 flagdbg.append("disable: < ");
1446 flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
1447 flagdbg.append(((diff & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
1448 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
1449 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
1450 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
1451 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001452 flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
1453 flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001454 flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
1455 flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
Daniel Sandlerdba93562011-10-06 16:39:58 -04001456 flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
1457 flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
1458 flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
1459 flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001460 flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
1461 flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001462 flagdbg.append(((state & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
1463 flagdbg.append(((diff & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001464 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04001465 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07001466
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001467 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001468 mSystemIconArea.animate().cancel();
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001469 if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler173bae22012-09-25 14:37:42 -04001470 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001471 .alpha(0f)
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001472 .withLayer()
1473 .setDuration(160)
1474 .setInterpolator(mAlphaIn)
1475 .setListener(mMakeIconsInvisible);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001476 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001477 mSystemIconArea.setVisibility(View.VISIBLE);
1478 mSystemIconArea.animate()
Daniel Sandler67e7d902012-06-06 16:32:21 -04001479 .alpha(1f)
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001480 .withLayer()
1481 .setInterpolator(mAlphaOut)
1482 .setDuration(320);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001483 }
1484 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04001485
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001486 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
1487 boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
1488 showClock(show);
1489 }
Joe Onorato808182d2010-07-09 18:52:06 -04001490 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1491 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001492 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04001493 }
1494 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001495
Jim Miller5e6af442011-12-02 18:24:26 -08001496 if ((diff & (StatusBarManager.DISABLE_HOME
1497 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001498 | StatusBarManager.DISABLE_BACK
1499 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04001500 // the nav bar will take care of these
Daniel Sandlerd9283b902011-09-14 21:42:00 -04001501 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001502
Daniel Sandlerdba93562011-10-06 16:39:58 -04001503 if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04001504 // close recents if it's visible
Winson Chung1e8d71b2014-05-16 17:05:22 -07001505 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
1506 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001507 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001508 }
1509
Joe Onorato808182d2010-07-09 18:52:06 -04001510 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1511 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Joe Onorato808182d2010-07-09 18:52:06 -04001512 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001513 haltTicker();
Joe Onorato808182d2010-07-09 18:52:06 -04001514 }
Daniel Sandler173bae22012-09-25 14:37:42 -04001515
1516 mNotificationIcons.animate()
1517 .alpha(0f)
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001518 .withLayer()
1519 .setDuration(160)
1520 .setInterpolator(mAlphaIn)
Daniel Sandler173bae22012-09-25 14:37:42 -04001521 .setListener(mMakeIconsInvisible)
1522 .start();
Joe Onorato808182d2010-07-09 18:52:06 -04001523 } else {
Daniel Sandler173bae22012-09-25 14:37:42 -04001524 mNotificationIcons.setVisibility(View.VISIBLE);
1525 mNotificationIcons.animate()
1526 .alpha(1f)
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001527 .withLayer()
1528 .setInterpolator(mAlphaOut)
1529 .setDuration(320);
Joe Onorato808182d2010-07-09 18:52:06 -04001530 }
Joe Onorato808182d2010-07-09 18:52:06 -04001531 }
1532 }
1533
Michael Jurka7f2668c2012-03-27 07:49:52 -07001534 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07001535 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001536 return new PhoneStatusBar.H();
1537 }
1538
Jorim Jaggi97b63c42014-05-02 23:03:34 +02001539 @Override
1540 public void startActivity(Intent intent) {
1541 startActivityDismissingKeyguard(intent, false);
1542 }
1543
Jorim Jaggiecc798e2014-05-26 18:14:37 +02001544 public ScrimController getScrimController() {
1545 return mScrimController;
1546 }
1547
Joe Onorato808182d2010-07-09 18:52:06 -04001548 /**
1549 * All changes to the status bar and notifications funnel through here and are batched.
1550 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07001551 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04001552 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001553 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04001554 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001555 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04001556 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001557 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04001558 case MSG_OPEN_SETTINGS_PANEL:
1559 animateExpandSettingsPanel();
1560 break;
1561 case MSG_CLOSE_PANELS:
1562 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001563 break;
Chris Wren157026f2013-06-28 16:54:01 -04001564 case MSG_SHOW_HEADS_UP:
1565 setHeadsUpVisibility(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001566 break;
Chris Wren157026f2013-06-28 16:54:01 -04001567 case MSG_HIDE_HEADS_UP:
1568 setHeadsUpVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001569 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04001570 case MSG_ESCALATE_HEADS_UP:
1571 escalateHeadsUp();
1572 setHeadsUpVisibility(false);
Chris Wrene97f90b2013-08-07 17:39:35 -04001573 break;
1574 }
1575 }
1576 }
1577
1578 /** if the interrupting notification had a fullscreen intent, fire it now. */
1579 private void escalateHeadsUp() {
1580 if (mInterruptingNotificationEntry != null) {
1581 final StatusBarNotification sbn = mInterruptingNotificationEntry.notification;
1582 final Notification notification = sbn.getNotification();
1583 if (notification.fullScreenIntent != null) {
1584 if (DEBUG)
1585 Log.d(TAG, "converting a heads up to fullScreen");
1586 try {
1587 notification.fullScreenIntent.send();
1588 } catch (PendingIntent.CanceledException e) {
1589 }
Joe Onorato808182d2010-07-09 18:52:06 -04001590 }
1591 }
1592 }
1593
John Spurlockaf8d6c42014-05-07 17:49:08 -04001594 private Handler getHandler() {
Daniel Sandler040c2e42012-10-17 00:56:33 -04001595 return mHandler;
1596 }
1597
Joe Onorato808182d2010-07-09 18:52:06 -04001598 View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
1599 public void onFocusChange(View v, boolean hasFocus) {
1600 // Because 'v' is a ViewGroup, all its children will be (un)selected
1601 // too, which allows marqueeing to work.
1602 v.setSelected(hasFocus);
1603 }
1604 };
1605
John Spurlock97642182013-07-29 17:58:39 -04001606 boolean panelsEnabled() {
John Spurlock79ec2a12013-09-11 09:28:49 -04001607 return (mDisabled & StatusBarManager.DISABLE_EXPAND) == 0;
John Spurlock97642182013-07-29 17:58:39 -04001608 }
1609
Jorim Jaggifa505a72014-04-28 20:04:11 +02001610 void makeExpandedVisible(boolean force) {
John Spurlockcd686b52013-06-05 10:13:46 -04001611 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
Jorim Jaggifa505a72014-04-28 20:04:11 +02001612 if (!force && (mExpandedVisible || !panelsEnabled())) {
Joe Onorato808182d2010-07-09 18:52:06 -04001613 return;
1614 }
Jim Millera073e572012-05-23 17:03:27 -07001615
Joe Onorato808182d2010-07-09 18:52:06 -04001616 mExpandedVisible = true;
John Spurlockd5ef5462012-06-13 11:19:51 -04001617 if (mNavigationBarView != null)
1618 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001619
Daniel Sandlere5011a32012-06-11 16:07:52 -04001620 updateCarrierLabelVisibility(true);
Daniel Sandler3d32a242012-06-05 13:44:14 -04001621
Joe Onorato808182d2010-07-09 18:52:06 -04001622 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
Daniel Sandlera310af82012-04-24 01:20:13 -04001623
1624 // Expand the window to encompass the full screen in anticipation of the drag.
1625 // This is only possible to do atomically because the status bar is at the top of the screen!
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001626 mStatusBarWindowManager.setStatusBarExpanded(true);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01001627
1628 visibilityChanged(true);
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001629 disable(mDisabledUnmodified);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01001630 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
1631 }
1632
Daniel Sandler11cf1782012-09-27 14:03:08 -04001633 public void animateCollapsePanels() {
1634 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001635 }
1636
John Spurlockaf8d6c42014-05-07 17:49:08 -04001637 private final Runnable mAnimateCollapsePanels = new Runnable() {
1638 @Override
1639 public void run() {
1640 animateCollapsePanels();
1641 }
1642 };
1643
1644 public void postAnimateCollapsePanels() {
1645 mHandler.post(mAnimateCollapsePanels);
1646 }
1647
Daniel Sandler11cf1782012-09-27 14:03:08 -04001648 public void animateCollapsePanels(int flags) {
Jorim Jaggic1cf1ae2014-05-02 21:19:17 +02001649 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
1650 return;
1651 }
Joe Onorato808182d2010-07-09 18:52:06 -04001652 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001653 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04001654 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07001655 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04001656 }
1657
Jim Miller9a720f52012-05-30 03:19:43 -07001658 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Winson Chung1e8d71b2014-05-16 17:05:22 -07001659 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
1660 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001661 }
Jim Miller9a720f52012-05-30 03:19:43 -07001662
1663 if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
1664 mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
1665 mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
1666 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07001667
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001668 if (mStatusBarWindow != null) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001669
1670 // release focus immediately to kick off focus change transition
1671 mStatusBarWindowManager.setStatusBarFocusable(false);
1672
John Spurlockab847cf2014-01-15 14:13:59 -05001673 mStatusBarWindow.cancelExpandHelper();
1674 mStatusBarView.collapseAllPanels(true);
John Spurlock73203eb2014-04-15 16:14:46 -04001675 if (isFlippedToSettings()) {
John Spurlock17880ef2014-04-23 16:12:54 -04001676 flipToNotifications(true /*animate*/);
John Spurlock73203eb2014-04-15 16:14:46 -04001677 }
John Spurlockab847cf2014-01-15 14:13:59 -05001678 }
Joe Onorato808182d2010-07-09 18:52:06 -04001679 }
1680
Daniel Sandler101784e2012-10-15 13:39:38 -04001681 public ViewPropertyAnimator setVisibilityWhenDone(
1682 final ViewPropertyAnimator a, final View v, final int vis) {
1683 a.setListener(new AnimatorListenerAdapter() {
1684 @Override
1685 public void onAnimationEnd(Animator animation) {
1686 v.setVisibility(vis);
1687 a.setListener(null); // oneshot
1688 }
1689 });
1690 return a;
1691 }
1692
1693 public Animator setVisibilityWhenDone(
1694 final Animator a, final View v, final int vis) {
1695 a.addListener(new AnimatorListenerAdapter() {
1696 @Override
1697 public void onAnimationEnd(Animator animation) {
1698 v.setVisibility(vis);
1699 }
1700 });
1701 return a;
1702 }
1703
1704 public Animator interpolator(TimeInterpolator ti, Animator a) {
1705 a.setInterpolator(ti);
1706 return a;
1707 }
1708
1709 public Animator startDelay(int d, Animator a) {
1710 a.setStartDelay(d);
1711 return a;
1712 }
John Spurlock209bede2013-07-17 12:23:27 -04001713
Daniel Sandler101784e2012-10-15 13:39:38 -04001714 public Animator start(Animator a) {
1715 a.start();
1716 return a;
1717 }
1718
1719 final TimeInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
1720 final TimeInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
1721 final int FLIP_DURATION_OUT = 125;
1722 final int FLIP_DURATION_IN = 225;
1723 final int FLIP_DURATION = (FLIP_DURATION_IN + FLIP_DURATION_OUT);
1724
John Spurlockaf8d6c42014-05-07 17:49:08 -04001725 Animator mScrollViewAnim, mClearButtonAnim;
Daniel Sandler101784e2012-10-15 13:39:38 -04001726
Daniel Sandler08d05e32012-08-08 16:39:54 -04001727 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001728 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04001729 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04001730 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04001731 return ;
1732 }
Joe Onorato808182d2010-07-09 18:52:06 -04001733
Daniel Sandler08d05e32012-08-08 16:39:54 -04001734 mNotificationPanel.expand();
John Spurlock50728832014-04-17 19:05:28 -04001735 if (mStackScroller.getVisibility() != View.VISIBLE) {
John Spurlock17880ef2014-04-23 16:12:54 -04001736 flipToNotifications(true /*animate*/);
Daniel Sandler101784e2012-10-15 13:39:38 -04001737 }
Joe Onorato808182d2010-07-09 18:52:06 -04001738
1739 if (false) postStartTracing();
1740 }
1741
John Spurlock17880ef2014-04-23 16:12:54 -04001742 private static void cancelAnim(Animator anim) {
1743 if (anim != null) {
1744 anim.cancel();
1745 }
1746 }
1747
1748 public void flipToNotifications(boolean animate) {
Jorim Jaggid7daab72014-05-06 22:22:20 +02001749 // TODO: Animation
1750 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04001751 }
1752
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001753 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04001754 public void animateExpandSettingsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04001755 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04001756 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001757 return;
1758 }
1759
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05001760 // Settings are not available in setup
1761 if (!mUserSetup) return;
1762
John Spurlock50728832014-04-17 19:05:28 -04001763 mNotificationPanel.expand();
Jorim Jaggid7daab72014-05-06 22:22:20 +02001764 mNotificationPanel.openQs();
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001765
1766 if (false) postStartTracing();
1767 }
1768
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001769 public boolean isFlippedToSettings() {
Jorim Jaggid7daab72014-05-06 22:22:20 +02001770 if (mNotificationPanel != null) {
1771 return mNotificationPanel.isQsExpanded();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001772 }
1773 return false;
Daniel Sandler040c2e42012-10-17 00:56:33 -04001774 }
1775
Svetoslav Ganove20a1772012-09-25 16:07:46 -07001776 public void animateCollapseQuickSettings() {
1777 mStatusBarView.collapseAllPanels(true);
1778 }
1779
Daniel Sandler08d05e32012-08-08 16:39:54 -04001780 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04001781 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04001782 + " mExpandedVisible=" + mExpandedVisible);
1783
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001784 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04001785 return;
1786 }
Daniel Sandlered930e52012-07-03 14:31:22 -04001787
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04001788 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
1789 mStatusBarView.collapseAllPanels(/*animate=*/ false);
Daniel Sandlered930e52012-07-03 14:31:22 -04001790
John Spurlock50728832014-04-17 19:05:28 -04001791 // reset things to their proper state
John Spurlock50728832014-04-17 19:05:28 -04001792 if (mScrollViewAnim != null) mScrollViewAnim.cancel();
1793 if (mClearButtonAnim != null) mClearButtonAnim.cancel();
Daniel Sandler50bc4f52012-10-22 14:47:55 -04001794
John Spurlock50728832014-04-17 19:05:28 -04001795 mStackScroller.setVisibility(View.VISIBLE);
1796 mNotificationPanel.setVisibility(View.GONE);
John Spurlock73203eb2014-04-15 16:14:46 -04001797
John Spurlock50728832014-04-17 19:05:28 -04001798 setAreThereNotifications(); // show the clear button
John Spurlock73203eb2014-04-15 16:14:46 -04001799
Jorim Jaggid7daab72014-05-06 22:22:20 +02001800 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04001801
Joe Onorato808182d2010-07-09 18:52:06 -04001802 mExpandedVisible = false;
John Spurlockd5ef5462012-06-13 11:19:51 -04001803 if (mNavigationBarView != null)
1804 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001805 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04001806
1807 // Shrink the window to the size of the status bar only
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001808 mStatusBarWindowManager.setStatusBarExpanded(false);
Joe Onorato808182d2010-07-09 18:52:06 -04001809
1810 if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
1811 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1812 }
Joe Onorato808182d2010-07-09 18:52:06 -04001813
Daniel Sandler469e96e2012-05-04 15:56:19 -04001814 // Close any "App info" popups that might have snuck on-screen
1815 dismissPopups();
1816
Chet Haase2f2022a2011-10-11 06:41:59 -07001817 if (mPostCollapseCleanup != null) {
1818 mPostCollapseCleanup.run();
1819 mPostCollapseCleanup = null;
1820 }
John Spurlock32beb2c2013-03-11 10:16:47 -04001821
John Spurlockcfc359a2013-09-05 10:42:03 -04001822 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001823 disable(mDisabledUnmodified);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001824 showBouncer();
Joe Onorato808182d2010-07-09 18:52:06 -04001825 }
1826
Daniel Sandlerb17a7262012-10-05 14:32:50 -04001827 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05001828 if (DEBUG_GESTURES) {
1829 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
1830 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
1831 event.getActionMasked(), (int) event.getX(), (int) event.getY(), mDisabled);
1832 }
1833
1834 }
1835
Joe Onorato808182d2010-07-09 18:52:06 -04001836 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04001837 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
John Spurlock804df702012-06-01 15:34:27 -04001838 + mDisabled + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001839 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001840 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04001841 Log.d(TAG, String.format(
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04001842 "panel: %s at (%f, %f) mDisabled=0x%08x",
1843 MotionEvent.actionToString(event.getAction()),
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04001844 event.getRawX(), event.getRawY(), mDisabled));
1845 }
Joe Onorato808182d2010-07-09 18:52:06 -04001846 }
1847
Daniel Sandler151f00d2012-10-02 22:33:08 -04001848 if (DEBUG_GESTURES) {
1849 mGestureRec.add(event);
1850 }
Daniel Sandler33805342012-07-23 15:45:12 -04001851
John Spurlock686820a2013-09-03 14:44:16 -04001852 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04001853 final boolean upOrCancel =
1854 event.getAction() == MotionEvent.ACTION_UP ||
1855 event.getAction() == MotionEvent.ACTION_CANCEL;
1856 if (upOrCancel && !mExpandedVisible) {
1857 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
1858 } else {
1859 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
1860 }
John Spurlock686820a2013-09-03 14:44:16 -04001861 }
Joe Onorato808182d2010-07-09 18:52:06 -04001862 return false;
1863 }
1864
Daniel Sandler08d05e32012-08-08 16:39:54 -04001865 public GestureRecorder getGestureRecorder() {
1866 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07001867 }
1868
John Spurlock56d007b2013-10-28 18:40:56 -04001869 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04001870 if (hints == mNavigationIconHints) return;
1871
1872 mNavigationIconHints = hints;
1873
1874 if (mNavigationBarView != null) {
1875 mNavigationBarView.setNavigationIconHints(hints);
1876 }
John Spurlockd4e65752013-08-28 14:17:09 -04001877 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04001878 }
1879
1880 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04001881 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04001882 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04001883 if (mStatusBarWindow != null
1884 && window == StatusBarManager.WINDOW_STATUS_BAR
1885 && mStatusBarWindowState != state) {
1886 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04001887 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001888 if (!showing) {
John Spurlock97642182013-07-29 17:58:39 -04001889 mStatusBarView.collapseAllPanels(false);
John Spurlock97642182013-07-29 17:58:39 -04001890 }
1891 }
1892 if (mNavigationBarView != null
1893 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
1894 && mNavigationBarWindowState != state) {
1895 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04001896 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04001897 }
1898 }
1899
John Spurlock97642182013-07-29 17:58:39 -04001900 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001901 public void setSystemUiVisibility(int vis, int mask) {
1902 final int oldVal = mSystemUiVisibility;
1903 final int newVal = (oldVal&~mask) | (vis&mask);
1904 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04001905 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04001906 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
1907 Integer.toHexString(vis), Integer.toHexString(mask),
1908 Integer.toHexString(oldVal), Integer.toHexString(newVal),
1909 Integer.toHexString(diff)));
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001910 if (diff != 0) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001911 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04001912
John Spurlocke1f366f2013-08-05 12:22:40 -04001913 // update low profile
1914 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
1915 final boolean lightsOut = (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001916 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001917 animateCollapsePanels();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001918 if (mTicking) {
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04001919 haltTicker();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001920 }
Daniel Sandlere137a1e2011-08-17 16:47:19 -04001921 }
Jim Millera073e572012-05-23 17:03:27 -07001922
John Spurlock7edfbca2013-09-14 11:58:55 -04001923 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04001924 }
1925
John Spurlocke1f366f2013-08-05 12:22:40 -04001926 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04001927 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04001928 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04001929
1930 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04001931 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04001932 oldVal, newVal, mNavigationBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04001933 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT);
John Spurlockd4e65752013-08-28 14:17:09 -04001934 final boolean sbModeChanged = sbMode != -1;
1935 final boolean nbModeChanged = nbMode != -1;
1936 boolean checkBarModes = false;
1937 if (sbModeChanged && sbMode != mStatusBarMode) {
1938 mStatusBarMode = sbMode;
1939 checkBarModes = true;
1940 }
1941 if (nbModeChanged && nbMode != mNavigationBarMode) {
1942 mNavigationBarMode = nbMode;
1943 checkBarModes = true;
1944 }
1945 if (checkBarModes) {
1946 checkBarModes();
1947 }
1948 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04001949 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05001950 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04001951 scheduleAutohide();
1952 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04001953 cancelAutohide();
1954 }
1955 }
John Spurlocke1f366f2013-08-05 12:22:40 -04001956
John Spurlock5b9145b2013-08-20 15:13:47 -04001957 // ready to unhide
1958 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
1959 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
1960 }
1961 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
1962 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
1963 }
1964
John Spurlocke1f366f2013-08-05 12:22:40 -04001965 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04001966 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04001967 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04001968 }
1969
John Spurlockd4e65752013-08-28 14:17:09 -04001970 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
John Spurlockbd957402013-10-03 11:38:39 -04001971 int transientFlag, int translucentFlag) {
1972 final int oldMode = barMode(oldVis, transientFlag, translucentFlag);
1973 final int newMode = barMode(newVis, transientFlag, translucentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04001974 if (oldMode == newMode) {
1975 return -1; // no mode change
1976 }
John Spurlocke1f366f2013-08-05 12:22:40 -04001977 return newMode;
1978 }
1979
John Spurlockbd957402013-10-03 11:38:39 -04001980 private int barMode(int vis, int transientFlag, int translucentFlag) {
John Spurlock89835dd2013-08-16 15:06:51 -04001981 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04001982 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
Adrian Roosea562512014-05-05 13:33:03 +02001983 : (vis & View.SYSTEM_UI_TRANSPARENT) != 0 ? MODE_TRANSPARENT
John Spurlock7edfbca2013-09-14 11:58:55 -04001984 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04001985 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04001986 }
1987
John Spurlockd4e65752013-08-28 14:17:09 -04001988 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04001989 if (mDemoMode) return;
Jorim Jaggi28d22d02014-05-10 03:37:04 +02001990 checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions());
John Spurlockd4e65752013-08-28 14:17:09 -04001991 if (mNavigationBarView != null) {
1992 checkBarMode(mNavigationBarMode,
1993 mNavigationBarWindowState, mNavigationBarView.getBarTransitions());
1994 }
1995 }
1996
1997 private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
John Spurlock8c520422013-09-19 12:23:35 -04001998 final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN;
John Spurlockc68d5772013-10-08 11:47:58 -04001999 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04002000 }
2001
John Spurlock42197262013-10-21 09:32:25 -04002002 private void finishBarAnimations() {
2003 mStatusBarView.getBarTransitions().finishAnimations();
2004 if (mNavigationBarView != null) {
2005 mNavigationBarView.getBarTransitions().finishAnimations();
2006 }
2007 }
2008
John Spurlockd4e65752013-08-28 14:17:09 -04002009 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04002010 @Override
2011 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04002012 checkBarModes();
John Spurlock5b9145b2013-08-20 15:13:47 -04002013 }};
2014
John Spurlockad3e6cb2013-04-30 08:47:43 -04002015 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04002016 public void setInteracting(int barWindow, boolean interacting) {
2017 mInteractingWindows = interacting
2018 ? (mInteractingWindows | barWindow)
2019 : (mInteractingWindows & ~barWindow);
2020 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04002021 suspendAutohide();
2022 } else {
2023 resumeSuspendedAutohide();
2024 }
2025 checkBarModes();
2026 }
2027
2028 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04002029 if (mAutohideSuspended) {
2030 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04002031 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04002032 }
2033 }
2034
John Spurlockd4e65752013-08-28 14:17:09 -04002035 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04002036 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04002037 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04002038 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04002039 }
2040
2041 private void cancelAutohide() {
2042 mAutohideSuspended = false;
2043 mHandler.removeCallbacks(mAutohide);
2044 }
2045
2046 private void scheduleAutohide() {
2047 cancelAutohide();
2048 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
2049 }
2050
John Spurlock9deaa282013-07-25 13:03:47 -04002051 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002052 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04002053 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
2054 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
2055 ) {
2056 userAutohide();
2057 }
2058 }
2059
2060 private void userAutohide() {
2061 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04002062 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04002063 }
2064
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002065 private boolean areLightsOn() {
2066 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
2067 }
Jim Millera073e572012-05-23 17:03:27 -07002068
Daniel Sandler60ee2562011-07-22 12:34:33 -04002069 public void setLightsOn(boolean on) {
2070 Log.v(TAG, "setLightsOn(" + on + ")");
2071 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002072 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002073 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002074 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002075 }
2076 }
2077
John Spurlock32beb2c2013-03-11 10:16:47 -04002078 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002079 try {
John Spurlock32beb2c2013-03-11 10:16:47 -04002080 mWindowManagerService.statusBarVisibilityChanged(vis);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002081 } catch (RemoteException ex) {
2082 }
Joe Onorato93056472010-09-10 10:30:46 -04002083 }
2084
Daniel Sandler5c8da942011-06-28 00:29:04 -04002085 public void topAppWindowChanged(boolean showMenu) {
2086 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002087 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04002088 }
2089 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04002090 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04002091 }
2092
2093 // See above re: lights-out policy for legacy apps.
2094 if (showMenu) setLightsOn(true);
2095 }
2096
Daniel Sandler328310c2011-09-23 15:56:52 -04002097 @Override
Jason Monkb605fec2014-05-02 17:04:10 -04002098 public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
2099 boolean showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002100 boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
2101 int flags = mNavigationIconHints;
2102 if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
2103 flags |= NAVIGATION_HINT_BACK_ALT;
2104 } else {
2105 flags &= ~NAVIGATION_HINT_BACK_ALT;
2106 }
Jason Monkb605fec2014-05-02 17:04:10 -04002107 if (showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002108 flags |= NAVIGATION_HINT_IME_SHOWN;
2109 } else {
2110 flags &= ~NAVIGATION_HINT_IME_SHOWN;
2111 }
Daniel Sandler328310c2011-09-23 15:56:52 -04002112
Jason Monkf1ff2092014-04-29 16:50:53 -04002113 setNavigationIconHints(flags);
Daniel Sandler328310c2011-09-23 15:56:52 -04002114 }
2115
Jeff Brown2992ea72011-01-28 22:04:14 -08002116 @Override
Winson Chung43229d72012-09-12 18:04:18 -07002117 public void setHardKeyboardStatus(boolean available, boolean enabled) {}
Daniel Sandlere02d8082010-10-08 15:13:22 -04002118
Chris Wren0c8275b2012-05-08 13:36:48 -04002119 @Override
Christoph Studer71f18fd2014-05-20 17:02:04 +02002120 protected void tick(StatusBarNotification n, boolean firstTime) {
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002121 // no ticking in lights-out mode
2122 if (!areLightsOn()) return;
Jim Millera073e572012-05-23 17:03:27 -07002123
Daniel Sandler26cda272012-05-22 15:44:08 -04002124 // no ticking in Setup
2125 if (!isDeviceProvisioned()) return;
2126
John Spurlock61e36832012-09-10 09:43:27 -04002127 // not for you
Kenny Guy2a764942014-04-02 13:29:20 +01002128 if (!notificationIsForCurrentProfiles(n)) return;
John Spurlock61e36832012-09-10 09:43:27 -04002129
Joe Onorato808182d2010-07-09 18:52:06 -04002130 // Show the ticker if one is requested. Also don't do this
2131 // until status bar window is attached to the window manager,
2132 // because... well, what's the point otherwise? And trying to
2133 // run a ticker without being attached will crash!
John Spurlockab847cf2014-01-15 14:13:59 -05002134 if (n.getNotification().tickerText != null && mStatusBarWindow != null
2135 && mStatusBarWindow.getWindowToken() != null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002136 if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
2137 | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
2138 mTicker.addEntry(n);
2139 }
2140 }
2141 }
2142
Joe Onorato808182d2010-07-09 18:52:06 -04002143 private class MyTicker extends Ticker {
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002144 MyTicker(Context context, View sb) {
Joe Onorato808182d2010-07-09 18:52:06 -04002145 super(context, sb);
2146 }
2147
2148 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002149 public void tickerStarting() {
Joe Onorato808182d2010-07-09 18:52:06 -04002150 mTicking = true;
Daniel Sandler173bae22012-09-25 14:37:42 -04002151 mStatusBarContents.setVisibility(View.GONE);
Joe Onorato808182d2010-07-09 18:52:06 -04002152 mTickerView.setVisibility(View.VISIBLE);
2153 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
Daniel Sandler173bae22012-09-25 14:37:42 -04002154 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
Joe Onorato808182d2010-07-09 18:52:06 -04002155 }
2156
2157 @Override
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002158 public void tickerDone() {
Daniel Sandler173bae22012-09-25 14:37:42 -04002159 mStatusBarContents.setVisibility(View.VISIBLE);
Joe Onorato808182d2010-07-09 18:52:06 -04002160 mTickerView.setVisibility(View.GONE);
Daniel Sandler173bae22012-09-25 14:37:42 -04002161 mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
Joe Onorato808182d2010-07-09 18:52:06 -04002162 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
2163 mTickingDoneListener));
Joe Onorato808182d2010-07-09 18:52:06 -04002164 }
2165
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04002166 public void tickerHalting() {
John Spurlock26a08ac2013-11-08 16:56:54 -05002167 if (mStatusBarContents.getVisibility() != View.VISIBLE) {
2168 mStatusBarContents.setVisibility(View.VISIBLE);
2169 mStatusBarContents
2170 .startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
2171 }
Joe Onorato808182d2010-07-09 18:52:06 -04002172 mTickerView.setVisibility(View.GONE);
Daniel Sandlerf59a90c2012-09-28 15:33:14 -04002173 // we do not animate the ticker away at this point, just get rid of it (b/6992707)
Joe Onorato808182d2010-07-09 18:52:06 -04002174 }
2175 }
2176
2177 Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
2178 public void onAnimationEnd(Animation animation) {
2179 mTicking = false;
2180 }
2181 public void onAnimationRepeat(Animation animation) {
2182 }
2183 public void onAnimationStart(Animation animation) {
2184 }
2185 };
2186
2187 private Animation loadAnim(int id, Animation.AnimationListener listener) {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002188 Animation anim = AnimationUtils.loadAnimation(mContext, id);
Joe Onorato808182d2010-07-09 18:52:06 -04002189 if (listener != null) {
2190 anim.setAnimationListener(listener);
2191 }
2192 return anim;
2193 }
2194
Daniel Sandler48852952011-12-01 14:34:23 -05002195 public static String viewInfo(View v) {
2196 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
2197 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04002198 }
2199
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002200 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04002201 synchronized (mQueueLock) {
2202 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002203 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04002204 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04002205 pw.println(" mTicking=" + mTicking);
2206 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04002207 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002208 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
Joe Onorato808182d2010-07-09 18:52:06 -04002209 pw.println(" mTickerView: " + viewInfo(mTickerView));
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002210 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
2211 + " scroll " + mStackScroller.getScrollX()
2212 + "," + mStackScroller.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04002213 }
Joe Onorato808182d2010-07-09 18:52:06 -04002214
John Spurlockcfc359a2013-09-05 10:42:03 -04002215 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04002216 pw.print(" mStatusBarWindowState=");
2217 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002218 pw.print(" mStatusBarMode=");
2219 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlocke677d712014-02-13 12:52:19 -05002220 pw.print(" mZenMode=");
2221 pw.println(Settings.Global.zenModeToString(mZenMode));
Chris Wren3b6745b2014-03-07 14:34:35 -05002222 pw.print(" mUseHeadsUp=");
2223 pw.println(mUseHeadsUp);
2224 pw.print(" interrupting package: ");
2225 pw.println(hunStateToString(mInterruptingNotificationEntry));
John Spurlock0ec64c62013-08-26 15:37:58 -04002226 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
2227 if (mNavigationBarView != null) {
2228 pw.print(" mNavigationBarWindowState=");
2229 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002230 pw.print(" mNavigationBarMode=");
2231 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002232 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
2233 }
2234
Daniel Sandler48852952011-12-01 14:34:23 -05002235 pw.print(" mNavigationBarView=");
2236 if (mNavigationBarView == null) {
2237 pw.println("null");
2238 } else {
2239 mNavigationBarView.dump(fd, pw, args);
2240 }
2241
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002242 pw.println(" Panels: ");
2243 if (mNotificationPanel != null) {
2244 pw.println(" mNotificationPanel=" +
2245 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
2246 pw.print (" ");
2247 mNotificationPanel.dump(fd, pw, args);
2248 }
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002249
Daniel Sandler7579bca2011-08-18 15:47:26 -04002250 if (DUMPTRUCK) {
2251 synchronized (mNotificationData) {
2252 int N = mNotificationData.size();
2253 pw.println(" notification icons: " + N);
2254 for (int i=0; i<N; i++) {
2255 NotificationData.Entry e = mNotificationData.get(i);
2256 pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
2257 StatusBarNotification n = e.notification;
Daniel Sandler4f91efd2013-04-25 16:38:41 -04002258 pw.println(" pkg=" + n.getPackageName() + " id=" + n.getId() + " score=" + n.getScore());
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -04002259 pw.println(" notification=" + n.getNotification());
2260 pw.println(" tickerText=\"" + n.getNotification().tickerText + "\"");
Daniel Sandler7579bca2011-08-18 15:47:26 -04002261 }
2262 }
2263
2264 int N = mStatusIcons.getChildCount();
2265 pw.println(" system icons: " + N);
2266 for (int i=0; i<N; i++) {
2267 StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
2268 pw.println(" [" + i + "] icon=" + ic);
2269 }
Jim Miller5e6af442011-12-02 18:24:26 -08002270
Daniel Sandler89d97132011-09-08 15:31:57 -04002271 if (false) {
2272 pw.println("see the logcat for a dump of the views we have created.");
2273 // must happen on ui thread
2274 mHandler.post(new Runnable() {
2275 public void run() {
2276 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04002277 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04002278 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002279 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002280 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002281 }
2282 });
2283 }
Joe Onorato808182d2010-07-09 18:52:06 -04002284 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002285
Daniel Sandler151f00d2012-10-02 22:33:08 -04002286 if (DEBUG_GESTURES) {
2287 pw.print(" status bar gestures: ");
2288 mGestureRec.dump(fd, pw, args);
2289 }
Daniel Sandler33805342012-07-23 15:45:12 -04002290
Daniel Sandler89d97132011-09-08 15:31:57 -04002291 mNetworkController.dump(fd, pw, args);
Joe Onorato808182d2010-07-09 18:52:06 -04002292 }
2293
Chris Wren3b6745b2014-03-07 14:34:35 -05002294 private String hunStateToString(Entry entry) {
2295 if (entry == null) return "null";
2296 if (entry.notification == null) return "corrupt";
2297 return entry.notification.getPackageName();
2298 }
2299
John Spurlock0ec64c62013-08-26 15:37:58 -04002300 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
2301 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
2302 pw.println(BarTransitions.modeToString(transitions.getMode()));
2303 }
2304
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002305 @Override
2306 public void createAndAddWindows() {
2307 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04002308 }
Jim Millere898ac52012-04-06 17:10:57 -07002309
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002310 private void addStatusBarWindow() {
Daniel Sandlera310af82012-04-24 01:20:13 -04002311 makeStatusBarView();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002312 mStatusBarWindowManager = new StatusBarWindowManager(mContext);
2313 mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
Joe Onorato808182d2010-07-09 18:52:06 -04002314 }
2315
Joe Onorato808182d2010-07-09 18:52:06 -04002316 void setNotificationIconVisibility(boolean visible, int anim) {
2317 int old = mNotificationIcons.getVisibility();
2318 int v = visible ? View.VISIBLE : View.INVISIBLE;
2319 if (old != v) {
2320 mNotificationIcons.setVisibility(v);
2321 mNotificationIcons.startAnimation(loadAnim(anim, null));
2322 }
2323 }
2324
Daniel Sandler1fac1fd2012-04-30 12:07:30 -04002325 static final float saturate(float a) {
2326 return a < 0f ? 0f : (a > 1f ? 1f : a);
2327 }
2328
Chris Wren8fd12652012-05-09 21:25:57 -04002329 @Override
Daniel Sandler08d05e32012-08-08 16:39:54 -04002330 public void updateExpandedViewPos(int thingy) {
Chris Wren6d15a362013-08-20 18:46:29 -04002331 if (SPEW) Log.v(TAG, "updateExpandedViewPos");
Daniel Sandlere680f542012-09-28 12:22:27 -04002332
2333 // on larger devices, the notification panel is propped open a bit
2334 mNotificationPanel.setMinimumHeight(
2335 (int)(mNotificationPanelMinHeightFrac * mCurrentDisplaySize.y));
2336
Daniel Sandler21b274e2012-05-02 15:07:51 -04002337 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams();
Daniel Sandler21b274e2012-05-02 15:07:51 -04002338 lp.gravity = mNotificationPanelGravity;
Daniel Sandler21b274e2012-05-02 15:07:51 -04002339 mNotificationPanel.setLayoutParams(lp);
Daniel Sandlere680f542012-09-28 12:22:27 -04002340
Daniel Sandlerbf526d12012-09-04 22:56:44 -04002341 updateCarrierLabelVisibility(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002342 }
2343
Daniel Sandler747a9e92012-08-10 16:39:19 -04002344 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002345 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04002346 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002347 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04002348 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04002349 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04002350 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2351 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002352 }
2353
Joe Onorato808182d2010-07-09 18:52:06 -04002354 private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
2355 public void onClick(View v) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002356 synchronized (mNotificationData) {
Selim Cinek80a14e52014-03-27 16:58:04 +01002357 mPostCollapseCleanup = new Runnable() {
2358 @Override
2359 public void run() {
2360 if (DEBUG) {
2361 Log.v(TAG, "running post-collapse cleanup");
2362 }
2363 try {
Selim Cinek80a14e52014-03-27 16:58:04 +01002364 mBarService.onClearAllNotifications(mCurrentUserId);
2365 } catch (Exception ex) { }
2366 }
2367 };
2368
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002369 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
2370 return;
2371 // TODO: Handle this better with notification stack scroller
Joe Onorato808182d2010-07-09 18:52:06 -04002372 }
Joe Onorato808182d2010-07-09 18:52:06 -04002373 }
2374 };
2375
Adrian Roos4314f6d2014-05-28 14:10:27 +02002376 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned) {
Daniel Sandler3679bf52012-10-16 21:30:28 -04002377 if (onlyProvisioned && !isDeviceProvisioned()) return;
Adrian Roos4314f6d2014-05-28 14:10:27 +02002378
2379 dismissKeyguardThenExecute(new OnDismissAction() {
2380 @Override
2381 public boolean onDismiss() {
2382 try {
2383 // Dismiss the lock screen when Settings starts.
2384 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
2385 } catch (RemoteException e) {
2386 }
2387 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2388 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
2389 animateCollapsePanels();
2390
2391 return DELAY_DISMISS_TO_ACTIVITY_LAUNCH;
2392 }
2393 });
Daniel Sandler3679bf52012-10-16 21:30:28 -04002394 }
2395
Daniel Sandler3679bf52012-10-16 21:30:28 -04002396 private View.OnClickListener mClockClickListener = new View.OnClickListener() {
2397 public void onClick(View v) {
2398 startActivityDismissingKeyguard(
2399 new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone
2400 }
2401 };
2402
Daniel Sandler101784e2012-10-15 13:39:38 -04002403 private View.OnClickListener mNotificationButtonListener = new View.OnClickListener() {
2404 public void onClick(View v) {
2405 animateExpandNotificationsPanel();
2406 }
2407 };
2408
Joe Onorato808182d2010-07-09 18:52:06 -04002409 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2410 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04002411 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04002412 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04002413 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Jim Miller9a720f52012-05-30 03:19:43 -07002414 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002415 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Daniel Sandleredbdd3a2011-06-21 12:57:08 -04002416 String reason = intent.getStringExtra("reason");
Jim Miller9a720f52012-05-30 03:19:43 -07002417 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
2418 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
Michael Jurka3b1fc472011-06-13 10:54:40 -07002419 }
2420 }
Daniel Sandler11cf1782012-09-27 14:03:08 -04002421 animateCollapsePanels(flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002422 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002423 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002424 mScreenOn = false;
John Spurlock1bbd49d2012-10-19 11:09:32 -04002425 notifyNavigationBarScreenOn(false);
Chris Wrene97f90b2013-08-07 17:39:35 -04002426 notifyHeadsUpScreenOn(false);
John Spurlock42197262013-10-21 09:32:25 -04002427 finishBarAnimations();
Christoph Studer037e34c2014-04-30 20:06:04 +02002428 stopNotificationLogging();
Daniel Sandlered930e52012-07-03 14:31:22 -04002429 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002430 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002431 mScreenOn = true;
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002432 // work around problem where mDisplay.getRotation() is not stable while screen is off (bug 7086018)
2433 repositionNavigationBar();
John Spurlock1bbd49d2012-10-19 11:09:32 -04002434 notifyNavigationBarScreenOn(true);
Christoph Studer037e34c2014-04-30 20:06:04 +02002435 startNotificationLoggingIfScreenOnAndVisible();
Joe Onorato808182d2010-07-09 18:52:06 -04002436 }
John Spurlock3c875662013-08-31 15:07:25 -04002437 else if (ACTION_DEMO.equals(action)) {
2438 Bundle bundle = intent.getExtras();
2439 if (bundle != null) {
2440 String command = bundle.getString("command", "").trim().toLowerCase();
2441 if (command.length() > 0) {
2442 try {
2443 dispatchDemoCommand(command, bundle);
2444 } catch (Throwable t) {
2445 Log.w(TAG, "Error running demo command, intent=" + intent, t);
2446 }
2447 }
2448 }
2449 }
Joe Onorato808182d2010-07-09 18:52:06 -04002450 }
2451 };
2452
Adrian Roos7d7090d2014-05-21 13:10:23 +02002453 @Override
Adrian Roos4314f6d2014-05-28 14:10:27 +02002454 protected void dismissKeyguardThenExecute(OnDismissAction action) {
Adrian Roos7d7090d2014-05-21 13:10:23 +02002455 if (mStatusBarKeyguardViewManager.isShowing()) {
2456 mStatusBarKeyguardViewManager.dismissWithAction(action);
2457 } else {
2458 action.onDismiss();
2459 }
2460 }
2461
Daniel Sandler777dcde2013-09-30 10:21:45 -04002462 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
2463 @Override
2464 protected void onConfigurationChanged(Configuration newConfig) {
2465 super.onConfigurationChanged(newConfig); // calls refreshLayout
2466
2467 if (DEBUG) {
2468 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
2469 }
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002470 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04002471
2472 updateResources();
2473 repositionNavigationBar();
2474 updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
2475 updateShowSearchHoldoff();
2476 }
2477
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002478 @Override
2479 public void userSwitched(int newUserId) {
2480 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002481 animateCollapsePanels();
Christoph Studer37fe6932014-05-26 13:10:30 +02002482 updateNotifications();
John Spurlock919adac2012-10-02 16:41:12 -04002483 resetUserSetupObserver();
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002484 }
John Spurlock919adac2012-10-02 16:41:12 -04002485
2486 private void resetUserSetupObserver() {
2487 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
2488 mUserSetupObserver.onChange(false);
2489 mContext.getContentResolver().registerContentObserver(
2490 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
2491 mUserSetupObserver,
2492 mCurrentUserId);
2493 }
2494
Chris Wren157026f2013-06-28 16:54:01 -04002495 private void setHeadsUpVisibility(boolean vis) {
2496 if (!ENABLE_HEADS_UP) return;
2497 if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
2498 mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
Chris Wrene03f4e12013-08-08 16:48:48 -04002499 if (!vis) {
2500 if (DEBUG) Log.d(TAG, "setting heads up entry to null");
2501 mInterruptingNotificationEntry = null;
2502 }
Joe Onorato808182d2010-07-09 18:52:06 -04002503 }
2504
Chris Wren51c75102013-07-16 20:49:17 -04002505 public void onHeadsUpDismissed() {
2506 if (mInterruptingNotificationEntry == null) return;
Chris Wren6d15a362013-08-20 18:46:29 -04002507 mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
2508 if (mHeadsUpNotificationView.isClearable()) {
2509 try {
2510 mBarService.onNotificationClear(
2511 mInterruptingNotificationEntry.notification.getPackageName(),
2512 mInterruptingNotificationEntry.notification.getTag(),
Kenny Guy3a7c4a52014-03-03 18:24:03 +00002513 mInterruptingNotificationEntry.notification.getId(),
2514 mInterruptingNotificationEntry.notification.getUserId());
Chris Wren6d15a362013-08-20 18:46:29 -04002515 } catch (android.os.RemoteException ex) {
2516 // oh well
2517 }
Daniel Sandlerfa7887b2012-03-26 09:43:31 -04002518 }
2519 }
Jim Millere898ac52012-04-06 17:10:57 -07002520
Joe Onorato808182d2010-07-09 18:52:06 -04002521 /**
2522 * Reload some of our resources when the configuration changes.
2523 *
2524 * We don't reload everything when the configuration changes -- we probably
2525 * should, but getting that smooth is tough. Someday we'll fix that. In the
2526 * meantime, just update the things that we know change.
2527 */
2528 void updateResources() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04002529 // Update the quick setting tiles
2530 if (mQSPanel != null) mQSPanel.updateResources();
Winson Chungd63c59782012-09-05 17:34:41 -07002531
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002532 loadDimens();
2533 }
Jim Miller5e6af442011-12-02 18:24:26 -08002534
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002535 protected void loadDimens() {
2536 final Resources res = mContext.getResources();
2537
2538 mNaturalBarHeight = res.getDimensionPixelSize(
2539 com.android.internal.R.dimen.status_bar_height);
2540
2541 int newIconSize = res.getDimensionPixelSize(
2542 com.android.internal.R.dimen.status_bar_icon_size);
2543 int newIconHPadding = res.getDimensionPixelSize(
2544 R.dimen.status_bar_icon_padding);
2545
2546 if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
John Spurlockcd686b52013-06-05 10:13:46 -04002547// Log.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002548 mIconHPadding = newIconHPadding;
2549 mIconSize = newIconSize;
2550 //reloadAllNotificationIcons(); // reload the tray
2551 }
2552
Joe Onorato808182d2010-07-09 18:52:06 -04002553 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
2554
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002555 mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
2556 mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
2557 mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
2558 mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
2559
2560 mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
2561 mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
2562
2563 mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
2564 mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
2565
2566 mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
Jim Millera073e572012-05-23 17:03:27 -07002567
Daniel Sandlere5011a32012-06-11 16:07:52 -04002568 mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity);
2569
Daniel Sandler21b274e2012-05-02 15:07:51 -04002570 mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
2571 if (mNotificationPanelGravity <= 0) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07002572 mNotificationPanelGravity = Gravity.START | Gravity.TOP;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -04002573 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04002574
2575 mCarrierLabelHeight = res.getDimensionPixelSize(R.dimen.carrier_label_height);
Jorim Jaggid7daab72014-05-06 22:22:20 +02002576 mStatusBarHeaderHeight = res.getDimensionPixelSize(R.dimen.status_bar_header_height);
Daniel Sandlerdc940ea2011-08-25 14:35:53 -07002577
Daniel Sandlere680f542012-09-28 12:22:27 -04002578 mNotificationPanelMinHeightFrac = res.getFraction(R.dimen.notification_panel_min_height_frac, 1, 1);
2579 if (mNotificationPanelMinHeightFrac < 0f || mNotificationPanelMinHeightFrac > 1f) {
2580 mNotificationPanelMinHeightFrac = 0f;
John Spurlock804df702012-06-01 15:34:27 -04002581 }
Daniel Sandlere680f542012-09-28 12:22:27 -04002582
Chris Wren51c75102013-07-16 20:49:17 -04002583 mHeadsUpNotificationDecay = res.getInteger(R.integer.heads_up_notification_decay);
Jorim Jaggife40f7d2014-04-28 15:20:04 +02002584 mRowMinHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
2585 mRowMaxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
Chris Wren51c75102013-07-16 20:49:17 -04002586
Jorim Jaggid4a57442014-04-10 02:45:55 +02002587 mKeyguardMaxNotificationCount = res.getInteger(R.integer.keyguard_max_notification_count);
2588
John Spurlockcd686b52013-06-05 10:13:46 -04002589 if (false) Log.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04002590 }
2591
Christoph Studer92b389d2014-04-01 18:44:40 +02002592 // Visibility reporting
2593
2594 @Override
2595 protected void visibilityChanged(boolean visible) {
Christoph Studer037e34c2014-04-30 20:06:04 +02002596 mVisible = visible;
Christoph Studer92b389d2014-04-01 18:44:40 +02002597 if (visible) {
Christoph Studer037e34c2014-04-30 20:06:04 +02002598 startNotificationLoggingIfScreenOnAndVisible();
Christoph Studer92b389d2014-04-01 18:44:40 +02002599 } else {
Christoph Studer037e34c2014-04-30 20:06:04 +02002600 stopNotificationLogging();
Christoph Studer92b389d2014-04-01 18:44:40 +02002601 }
2602 super.visibilityChanged(visible);
2603 }
2604
Christoph Studer037e34c2014-04-30 20:06:04 +02002605 private void stopNotificationLogging() {
2606 // Report all notifications as invisible and turn down the
2607 // reporter.
2608 if (!mCurrentlyVisibleNotifications.isEmpty()) {
2609 logNotificationVisibilityChanges(
2610 Collections.<String>emptyList(), mCurrentlyVisibleNotifications);
2611 mCurrentlyVisibleNotifications.clear();
2612 }
2613 mHandler.removeCallbacks(mVisibilityReporter);
2614 mStackScroller.setChildLocationsChangedListener(null);
2615 }
2616
2617 private void startNotificationLoggingIfScreenOnAndVisible() {
2618 if (mVisible && mScreenOn) {
2619 mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
2620 // Some transitions like mScreenOn=false -> mScreenOn=true don't
2621 // cause the scroller to emit child location events. Hence generate
2622 // one ourselves to guarantee that we're reporting visible
2623 // notifications.
2624 // (Note that in cases where the scroller does emit events, this
2625 // additional event doesn't break anything.)
2626 mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
2627 }
2628 }
2629
Christoph Studer92b389d2014-04-01 18:44:40 +02002630 private void logNotificationVisibilityChanges(
2631 Collection<String> newlyVisible, Collection<String> noLongerVisible) {
2632 if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
2633 return;
2634 }
2635
2636 String[] newlyVisibleAr = newlyVisible.toArray(new String[newlyVisible.size()]);
2637 String[] noLongerVisibleAr = noLongerVisible.toArray(new String[noLongerVisible.size()]);
2638 try {
2639 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
2640 } catch (RemoteException e) {
2641 // Ignore.
2642 }
2643 }
2644
Joe Onorato808182d2010-07-09 18:52:06 -04002645 //
2646 // tracing
2647 //
2648
2649 void postStartTracing() {
2650 mHandler.postDelayed(mStartTracing, 3000);
2651 }
2652
2653 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002654 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
2655 Context.VIBRATOR_SERVICE);
John Spurlockf9e1a0b2014-03-19 22:09:06 -04002656 vib.vibrate(250, AudioManager.STREAM_SYSTEM);
Joe Onorato808182d2010-07-09 18:52:06 -04002657 }
2658
2659 Runnable mStartTracing = new Runnable() {
2660 public void run() {
2661 vibrate();
2662 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04002663 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002664 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2665 mHandler.postDelayed(mStopTracing, 10000);
2666 }
2667 };
2668
2669 Runnable mStopTracing = new Runnable() {
2670 public void run() {
2671 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04002672 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002673 vibrate();
2674 }
2675 };
Chris Wren0c8275b2012-05-08 13:36:48 -04002676
2677 @Override
2678 protected void haltTicker() {
2679 mTicker.halt();
2680 }
Jim Miller670d9dd2012-05-12 13:28:26 -07002681
2682 @Override
Jim Millerb4238e02012-05-14 15:26:20 -07002683 protected boolean shouldDisableNavbarGestures() {
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002684 return !isDeviceProvisioned()
2685 || mExpandedVisible
2686 || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07002687 }
Joe Onorato808182d2010-07-09 18:52:06 -04002688
John Spurlockd47a3f32014-05-18 19:14:14 -04002689 public void postStartSettingsActivity(final Intent intent, int delay) {
2690 mHandler.postDelayed(new Runnable() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04002691 @Override
2692 public void run() {
2693 handleStartSettingsActivity(intent, true /*onlyProvisioned*/);
2694 }
John Spurlockd47a3f32014-05-18 19:14:14 -04002695 }, delay);
John Spurlockaf8d6c42014-05-07 17:49:08 -04002696 }
2697
2698 private void handleStartSettingsActivity(Intent intent, boolean onlyProvisioned) {
2699 if (onlyProvisioned && !isDeviceProvisioned()) return;
2700 try {
2701 // Dismiss the lock screen when Settings starts.
2702 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
2703 } catch (RemoteException e) {
John Spurlockde547002014-02-28 17:50:39 -05002704 }
John Spurlockaf8d6c42014-05-07 17:49:08 -04002705 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2706 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
2707 animateCollapsePanels();
2708 }
2709
2710 public void startSettingsActivity(String action) {
John Spurlockd47a3f32014-05-18 19:14:14 -04002711 postStartSettingsActivity(new Intent(action), 0);
John Spurlockde547002014-02-28 17:50:39 -05002712 }
2713
Romain Guy648342f2012-05-25 10:44:45 -07002714 private static class FastColorDrawable extends Drawable {
2715 private final int mColor;
2716
2717 public FastColorDrawable(int color) {
2718 mColor = 0xff000000 | color;
2719 }
2720
2721 @Override
2722 public void draw(Canvas canvas) {
2723 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
2724 }
2725
2726 @Override
2727 public void setAlpha(int alpha) {
2728 }
2729
2730 @Override
2731 public void setColorFilter(ColorFilter cf) {
2732 }
2733
2734 @Override
2735 public int getOpacity() {
2736 return PixelFormat.OPAQUE;
2737 }
2738
2739 @Override
2740 public void setBounds(int left, int top, int right, int bottom) {
2741 }
2742
2743 @Override
2744 public void setBounds(Rect bounds) {
2745 }
2746 }
John Spurlock5c454122013-06-17 07:35:46 -04002747
2748 @Override
2749 public void destroy() {
2750 super.destroy();
2751 if (mStatusBarWindow != null) {
2752 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05002753 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04002754 }
2755 if (mNavigationBarView != null) {
2756 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05002757 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04002758 }
2759 mContext.unregisterReceiver(mBroadcastReceiver);
2760 }
John Spurlock3c875662013-08-31 15:07:25 -04002761
2762 private boolean mDemoModeAllowed;
2763 private boolean mDemoMode;
2764 private DemoStatusIcons mDemoStatusIcons;
2765
2766 @Override
2767 public void dispatchDemoCommand(String command, Bundle args) {
2768 if (!mDemoModeAllowed) {
2769 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
2770 "sysui_demo_allowed", 0) != 0;
2771 }
2772 if (!mDemoModeAllowed) return;
2773 if (command.equals(COMMAND_ENTER)) {
2774 mDemoMode = true;
2775 } else if (command.equals(COMMAND_EXIT)) {
2776 mDemoMode = false;
2777 checkBarModes();
2778 } else if (!mDemoMode) {
2779 // automatically enter demo mode on first demo command
2780 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
2781 }
2782 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
2783 if (modeChange || command.equals(COMMAND_CLOCK)) {
2784 dispatchDemoCommandToView(command, args, R.id.clock);
2785 }
2786 if (modeChange || command.equals(COMMAND_BATTERY)) {
2787 dispatchDemoCommandToView(command, args, R.id.battery);
2788 }
2789 if (modeChange || command.equals(COMMAND_STATUS)) {
2790 if (mDemoStatusIcons == null) {
2791 mDemoStatusIcons = new DemoStatusIcons(mStatusIcons, mIconSize);
2792 }
2793 mDemoStatusIcons.dispatchDemoCommand(command, args);
2794 }
2795 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
2796 mNetworkController.dispatchDemoCommand(command, args);
2797 }
John Spurlock7f42fc52014-01-14 16:20:39 -05002798 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
2799 View notifications = mStatusBarView == null ? null
2800 : mStatusBarView.findViewById(R.id.notification_icon_area);
2801 if (notifications != null) {
2802 String visible = args.getString("visible");
2803 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
2804 notifications.setVisibility(vis);
2805 }
2806 }
John Spurlock3c875662013-08-31 15:07:25 -04002807 if (command.equals(COMMAND_BARS)) {
2808 String mode = args.getString("mode");
2809 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04002810 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04002811 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
2812 -1;
2813 if (barMode != -1) {
2814 boolean animate = true;
2815 if (mStatusBarView != null) {
2816 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
2817 }
2818 if (mNavigationBarView != null) {
2819 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
2820 }
2821 }
2822 }
2823 }
2824
2825 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
2826 if (mStatusBarView == null) return;
2827 View v = mStatusBarView.findViewById(id);
2828 if (v instanceof DemoMode) {
2829 ((DemoMode)v).dispatchDemoCommand(command, args);
2830 }
2831 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002832
Jorim Jaggiecbab362014-04-23 16:13:15 +02002833 /**
2834 * @return The {@link StatusBarState} the status bar is in.
2835 */
2836 public int getBarState() {
2837 return mState;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002838 }
2839
2840 public void showKeyguard() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02002841 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi15682502014-04-23 12:01:36 +02002842 updateKeyguardState();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002843 instantExpandNotificationsPanel();
Jorim Jaggiecbab362014-04-23 16:13:15 +02002844 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002845 }
2846
2847 public void hideKeyguard() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02002848 setBarState(StatusBarState.SHADE);
2849 if (mLeaveOpenOnKeyguardHide) {
2850 mLeaveOpenOnKeyguardHide = false;
Selim Cinekc27437b2014-05-14 10:23:33 +02002851 mNotificationPanel.animateToFullShade();
Jorim Jaggiecbab362014-04-23 16:13:15 +02002852 } else {
2853 instantCollapseNotificationPanel();
2854 }
Jorim Jaggi15682502014-04-23 12:01:36 +02002855 updateKeyguardState();
Jorim Jaggi15682502014-04-23 12:01:36 +02002856 }
2857
2858 private void updatePublicMode() {
Dan Sandler4b22bdf2014-06-05 00:58:02 -04002859 setLockscreenPublicMode(
2860 (mStatusBarKeyguardViewManager.isShowing() ||
2861 mStatusBarKeyguardViewManager.isOccluded())
Jorim Jaggiecbab362014-04-23 16:13:15 +02002862 && mStatusBarKeyguardViewManager.isSecure());
Jorim Jaggi15682502014-04-23 12:01:36 +02002863 }
2864
2865 private void updateKeyguardState() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02002866 if (mState == StatusBarState.KEYGUARD) {
Jorim Jaggi15682502014-04-23 12:01:36 +02002867 mKeyguardStatusView.setVisibility(View.VISIBLE);
Adrian Roos12c1ef52014-06-04 13:54:08 +02002868 mKeyguardIndicationController.setVisible(true);
Selim Cinek4c6969a2014-05-26 19:22:17 +02002869 mNotificationPanel.resetViews();
Jorim Jaggi15682502014-04-23 12:01:36 +02002870 } else {
2871 mKeyguardStatusView.setVisibility(View.GONE);
Adrian Roos12c1ef52014-06-04 13:54:08 +02002872 mKeyguardIndicationController.setVisible(false);
Jorim Jaggi15682502014-04-23 12:01:36 +02002873 }
Jorim Jaggi2042ef22014-05-13 21:55:18 +02002874 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
2875 mKeyguardBottomArea.setVisibility(View.VISIBLE);
2876 mHeader.setKeyguardShowing(true);
Jorim Jaggif62f2bb2014-05-25 22:28:41 +02002877 mNotificationPanel.setKeyguardShowing(true);
Jorim Jaggiecc798e2014-05-26 18:14:37 +02002878 mScrimController.setKeyguardShowing(true);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02002879 } else {
2880 mKeyguardBottomArea.setVisibility(View.GONE);
2881 mHeader.setKeyguardShowing(false);
Jorim Jaggif62f2bb2014-05-25 22:28:41 +02002882 mNotificationPanel.setKeyguardShowing(false);
Jorim Jaggiecc798e2014-05-26 18:14:37 +02002883 mScrimController.setKeyguardShowing(false);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02002884 }
Jorim Jaggi15682502014-04-23 12:01:36 +02002885
Jorim Jaggid552d9d2014-05-07 19:41:13 +02002886 updateStackScrollerState();
Jorim Jaggi15682502014-04-23 12:01:36 +02002887 updatePublicMode();
Christoph Studer37fe6932014-05-26 13:10:30 +02002888 updateNotifications();
Jorim Jaggia6310292014-04-16 14:11:52 +02002889 checkBarModes();
Jorim Jaggi25807932014-04-24 23:29:46 +02002890 updateCarrierLabelVisibility(false);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002891 }
2892
Jorim Jaggid552d9d2014-05-07 19:41:13 +02002893 public void updateStackScrollerState() {
John Spurlock4b3bda22014-05-22 14:32:20 -04002894 if (mStackScroller == null) return;
Selim Cinek1408eb52014-06-02 14:45:38 +02002895 boolean onKeyguard = mState == StatusBarState.KEYGUARD;
2896 mStackScroller.setDimmed(onKeyguard, false /* animate */);
2897 mStackScroller.setVisibility(!mShowLockscreenNotifications && onKeyguard
John Spurlock4b3bda22014-05-22 14:32:20 -04002898 ? View.INVISIBLE : View.VISIBLE);
Selim Cinek1408eb52014-06-02 14:45:38 +02002899 mStackScroller.setScrollingEnabled(!onKeyguard);
2900 mStackScroller.setExpandingEnabled(!onKeyguard);
Jorim Jaggid552d9d2014-05-07 19:41:13 +02002901 }
2902
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002903 public void userActivity() {
John Spurlockd08f91f2014-05-23 11:00:34 -04002904 mHandler.removeCallbacks(mUserActivity);
2905 mHandler.post(mUserActivity);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002906 }
2907
Jorim Jaggidf993512014-05-13 23:06:35 +02002908 public boolean interceptMediaKey(KeyEvent event) {
2909 return mState == StatusBarState.KEYGUARD
2910 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
2911 }
2912
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02002913 public boolean onMenuPressed() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02002914 return mState == StatusBarState.KEYGUARD && mStatusBarKeyguardViewManager.onMenuPressed();
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02002915 }
2916
Jorim Jaggie5c7a892014-04-10 20:37:32 +02002917 public boolean onBackPressed() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02002918 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +02002919 return mStatusBarKeyguardViewManager.onBackPressed();
2920 } else {
2921 animateCollapsePanels();
2922 return true;
2923 }
2924 }
2925
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002926 private void showBouncer() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02002927 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002928 mStatusBarKeyguardViewManager.dismiss();
2929 }
2930 }
2931
2932 private void instantExpandNotificationsPanel() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02002933
Jorim Jaggifa505a72014-04-28 20:04:11 +02002934 // Make our window larger and the panel visible.
2935 makeExpandedVisible(true);
2936 mNotificationPanel.setVisibility(View.VISIBLE);
Jorim Jaggic357ca22014-04-25 14:56:15 +02002937
2938 // Wait for window manager to pickup the change, so we know the maximum height of the panel
2939 // then.
Jorim Jaggia6310292014-04-16 14:11:52 +02002940 mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener(
2941 new ViewTreeObserver.OnGlobalLayoutListener() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02002942 @Override
2943 public void onGlobalLayout() {
2944 if (mStatusBarWindow.getHeight() != getStatusBarHeight()) {
2945 mNotificationPanel.getViewTreeObserver().removeOnGlobalLayoutListener(this);
2946 mNotificationPanel.setExpandedFraction(1);
2947 }
2948 }
2949 });
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002950 }
Adrian Roos5a46cd32014-04-03 16:51:58 +02002951
Jorim Jaggia005f1b2014-04-16 19:06:10 +02002952 private void instantCollapseNotificationPanel() {
2953 mNotificationPanel.setExpandedFraction(0);
2954 }
2955
Jorim Jaggid4a57442014-04-10 02:45:55 +02002956 @Override
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02002957 public void onActivated(View view) {
2958 userActivity();
Adrian Roos12c1ef52014-06-04 13:54:08 +02002959 mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
Jorim Jaggid552d9d2014-05-07 19:41:13 +02002960 mStackScroller.setActivatedChild(view);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02002961 }
2962
Jorim Jaggiecbab362014-04-23 16:13:15 +02002963 /**
2964 * @param state The {@link StatusBarState} to set.
2965 */
2966 public void setBarState(int state) {
2967 mState = state;
2968 mStatusBarWindowManager.setStatusBarState(state);
2969 }
2970
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02002971 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02002972 public void onActivationReset(View view) {
2973 if (view == mStackScroller.getActivatedChild()) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02002974 mKeyguardIndicationController.hideTransientIndication();
Jorim Jaggid552d9d2014-05-07 19:41:13 +02002975 mStackScroller.setActivatedChild(null);
2976 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02002977 }
2978
2979 public void onTrackingStarted() {
Jorim Jaggi90129582014-06-02 14:44:49 +02002980 }
2981
2982 public void onUnlockHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02002983 mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
Jorim Jaggi90129582014-06-02 14:44:49 +02002984 }
2985
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02002986 public void onHintFinished() {
Jorim Jaggi93a2bb22014-06-02 19:57:28 +02002987 // Delay the reset a bit so the user can read the text.
Adrian Roos12c1ef52014-06-04 13:54:08 +02002988 mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
Jorim Jaggie70d31f2014-04-24 22:08:30 +02002989 }
2990
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02002991 public void onCameraHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02002992 mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02002993 }
2994
2995 public void onPhoneHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02002996 mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02002997 }
2998
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02002999 public void onTrackingStopped(boolean expand) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003000 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
3001 if (!expand && !mUnlockMethodCache.isMethodInsecure()) {
3002 showBouncer();
3003 }
3004 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003005 }
3006
3007 @Override
Jorim Jaggid4a57442014-04-10 02:45:55 +02003008 protected int getMaxKeyguardNotifications() {
3009 return mKeyguardMaxNotificationCount;
3010 }
3011
Jorim Jaggia6310292014-04-16 14:11:52 +02003012 public NavigationBarView getNavigationBarView() {
3013 return mNavigationBarView;
3014 }
3015
Jorim Jaggiecbab362014-04-23 16:13:15 +02003016 // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
3017
3018 @Override
3019 public void onDraggedDown(View startingChild) {
3020 goToLockedShade(startingChild);
3021 }
3022
3023 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003024 public void onDragDownReset() {
3025 mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003026 }
3027
3028 public void onThresholdReached() {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003029 mStackScroller.setDimmed(false /* dimmed */, true /* animate */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003030 }
3031
Selim Cinek1408eb52014-06-02 14:45:38 +02003032 @Override
3033 public void onTouchSlopExceeded() {
3034 mStackScroller.removeLongPressCallback();
3035 }
3036
Jorim Jaggiecbab362014-04-23 16:13:15 +02003037 /**
3038 * If secure with redaction: Show bouncer, go to unlocked shade.
3039 *
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003040 * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
Jorim Jaggiecbab362014-04-23 16:13:15 +02003041 *
3042 * @param expandView The view to expand after going to the shade.
3043 */
3044 public void goToLockedShade(View expandView) {
3045 if (expandView instanceof ExpandableNotificationRow) {
3046 ExpandableNotificationRow row = (ExpandableNotificationRow) expandView;
3047 row.setUserExpanded(true);
3048 }
3049 if (isLockscreenPublicMode() && !userAllowsPrivateNotificationsInPublic(mCurrentUserId)) {
3050 mLeaveOpenOnKeyguardHide = true;
3051 showBouncer();
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003052 } else {
Selim Cinekc27437b2014-05-14 10:23:33 +02003053 mNotificationPanel.animateToFullShade();
Jorim Jaggiecbab362014-04-23 16:13:15 +02003054 setBarState(StatusBarState.SHADE_LOCKED);
3055 updateKeyguardState();
Jorim Jaggiecbab362014-04-23 16:13:15 +02003056 }
3057 }
3058
Adrian Roos5a46cd32014-04-03 16:51:58 +02003059 /**
Jorim Jaggi6539a832014-06-03 23:33:09 +02003060 * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
3061 */
3062 public void goToKeyguard() {
3063 if (mState == StatusBarState.SHADE_LOCKED) {
3064 setBarState(StatusBarState.KEYGUARD);
3065 updateKeyguardState();
3066 }
3067 }
3068
3069 /**
Adrian Roos5a46cd32014-04-03 16:51:58 +02003070 * @return a ViewGroup that spans the entire panel which contains the quick settings
3071 */
3072 public ViewGroup getQuickSettingsOverlayParent() {
Jorim Jaggid7daab72014-05-06 22:22:20 +02003073 return mNotificationPanel;
Adrian Roos9a0a4c92014-04-08 15:52:18 +02003074 }
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +02003075
3076 public LinearLayout getSystemIcons() {
3077 return mSystemIcons;
3078 }
3079
3080 /**
3081 * Reattaches the system icons to its normal parent in collapsed status bar.
3082 */
3083 public void reattachSystemIcons() {
3084 mSystemIconArea.addView(mSystemIcons, 0);
3085 }
Jorim Jaggi75c95042014-05-16 19:09:59 +02003086
3087 public void onScreenTurnedOff() {
3088 mStackScroller.setAnimationsEnabled(false);
3089 }
3090
3091 public void onScreenTurnedOn() {
3092 mStackScroller.setAnimationsEnabled(true);
3093 }
John Spurlockd08f91f2014-05-23 11:00:34 -04003094
3095 private final Runnable mUserActivity = new Runnable() {
3096 @Override
3097 public void run() {
3098 if (mState == StatusBarState.KEYGUARD) {
3099 mKeyguardViewMediatorCallback.userActivity();
3100 }
3101 }
3102 };
Romain Guy648342f2012-05-25 10:44:45 -07003103}