blob: b6dbfceb8e2d656f16fd35d3d2aaf640dafdfe20 [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
Daniel Sandlerd7e96862012-04-26 01:10:29 -040020import android.animation.Animator;
21import android.animation.AnimatorListenerAdapter;
Jeff Brown4d69e222014-09-18 15:27:50 -070022import android.annotation.NonNull;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070023import android.app.ActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040024import android.app.ActivityManagerNative;
Jason Monk62515be2014-05-21 16:06:19 -040025import android.app.IActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040026import android.app.Notification;
27import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040028import android.app.StatusBarManager;
29import android.content.BroadcastReceiver;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020030import android.content.ComponentCallbacks2;
Joe Onorato808182d2010-07-09 18:52:06 -040031import android.content.Context;
32import android.content.Intent;
33import android.content.IntentFilter;
Daniel Sandler777dcde2013-09-30 10:21:45 -040034import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070035import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040036import android.database.ContentObserver;
Dan Sandler16128f42014-05-21 12:48:22 -040037import android.graphics.Bitmap;
Romain Guy648342f2012-05-25 10:44:45 -070038import android.graphics.Canvas;
39import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040040import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040041import android.graphics.Point;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +010042import android.graphics.PointF;
Romain Guy648342f2012-05-25 10:44:45 -070043import android.graphics.PorterDuff;
Selim Cineka0fad3b2014-09-19 17:20:05 +020044import android.graphics.PorterDuffXfermode;
Joe Onorato808182d2010-07-09 18:52:06 -040045import android.graphics.Rect;
Dan Sandler16128f42014-05-21 12:48:22 -040046import android.graphics.drawable.ColorDrawable;
Romain Guy648342f2012-05-25 10:44:45 -070047import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070048import android.inputmethodservice.InputMethodService;
John Spurlock7b414672014-07-18 13:02:39 -040049import android.media.AudioAttributes;
Dan Sandler16128f42014-05-21 12:48:22 -040050import android.media.MediaMetadata;
51import android.media.session.MediaController;
52import android.media.session.MediaSession;
53import android.media.session.MediaSessionManager;
54import android.media.session.PlaybackState;
Selim Cinekbaa23272014-07-08 18:01:07 +020055import android.os.AsyncTask;
John Spurlock3c875662013-08-31 15:07:25 -040056import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040057import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050058import android.os.HandlerThread;
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;
Jason Monk4ae97d32014-12-17 10:14:33 -050062import android.os.Process;
Michael Jurka7f2668c2012-03-27 07:49:52 -070063import android.os.RemoteException;
Joe Onorato808182d2010-07-09 18:52:06 -040064import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070065import android.os.UserHandle;
Adrian Roos2b154a92014-11-17 15:18:39 +010066import android.os.UserManager;
Daniel Sandlerd3090562011-08-09 00:28:44 -040067import android.provider.Settings;
Chris Wren3ad4e3a2014-09-02 17:23:51 -040068import android.service.notification.NotificationListenerService;
Christoph Studerd0694b62014-06-04 16:36:01 +020069import android.service.notification.NotificationListenerService.RankingMap;
John Spurlockde84f0e2013-06-12 12:41:00 -040070import android.service.notification.StatusBarNotification;
Christoph Studer92b389d2014-04-01 18:44:40 +020071import android.util.ArraySet;
Daniel Sandler36412a72011-08-04 09:35:13 -040072import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -050073import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -040074import android.util.Log;
75import android.view.Display;
Jorim Jaggidf993512014-05-13 23:06:35 +020076import android.view.KeyEvent;
Jorim Jaggid4a57442014-04-10 02:45:55 +020077import android.view.LayoutInflater;
Joe Onorato808182d2010-07-09 18:52:06 -040078import android.view.MotionEvent;
79import android.view.VelocityTracker;
80import android.view.View;
Jim Millerf2a16b22011-07-06 17:32:48 -070081import android.view.ViewGroup.LayoutParams;
Dan Sandler44c0dfd2014-06-09 11:26:16 -040082import android.view.ViewStub;
Joe Onorato808182d2010-07-09 18:52:06 -040083import android.view.WindowManager;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020084import android.view.WindowManagerGlobal;
Jason Monk815e0572014-08-12 17:26:36 -040085import android.view.accessibility.AccessibilityEvent;
Jorim Jaggi4e0880e2014-07-25 14:51:50 +020086import android.view.animation.AccelerateDecelerateInterpolator;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040087import android.view.animation.AccelerateInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020088import android.view.animation.Interpolator;
Jorim Jaggi4e0880e2014-07-25 14:51:50 +020089import android.view.animation.LinearInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020090import android.view.animation.PathInterpolator;
Dan Sandler16128f42014-05-21 12:48:22 -040091import android.widget.ImageView;
Joe Onorato808182d2010-07-09 18:52:06 -040092import android.widget.TextView;
John Spurlock34e13d92013-08-10 06:52:28 -040093
Joe Onorato808182d2010-07-09 18:52:06 -040094import com.android.internal.statusbar.StatusBarIcon;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +010095import com.android.keyguard.KeyguardHostView.OnDismissAction;
Jorim Jaggi03c701e2014-04-02 12:39:51 +020096import com.android.keyguard.ViewMediatorCallback;
Jorim Jaggi708f7722014-08-20 17:30:38 +020097import com.android.systemui.BatteryMeterView;
John Spurlock3c875662013-08-31 15:07:25 -040098import com.android.systemui.DemoMode;
Christoph Studerb0183992014-12-22 21:02:26 +010099import com.android.systemui.EventLogConstants;
Chris Wren64161cc2012-12-17 16:49:30 -0500100import com.android.systemui.EventLogTags;
Andrew Flynn82862572015-04-01 14:22:37 -0400101import com.android.systemui.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -0400102import com.android.systemui.R;
Selim Cinekaac93252015-04-14 20:04:12 -0700103import com.android.systemui.assist.AssistGestureManager;
Jeff Brown4d69e222014-09-18 15:27:50 -0700104import com.android.systemui.doze.DozeHost;
John Spurlock813552c2014-09-19 08:30:21 -0400105import com.android.systemui.doze.DozeLog;
Jorim Jaggicff0acb2014-03-31 16:35:15 +0200106import com.android.systemui.keyguard.KeyguardViewMediator;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400107import com.android.systemui.qs.QSPanel;
Jorim Jaggid61f2272014-12-19 20:35:35 +0100108import com.android.systemui.recents.ScreenPinningRequest;
Selim Cineka32ab602014-06-11 15:06:01 +0200109import com.android.systemui.statusbar.ActivatableNotificationView;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200110import com.android.systemui.statusbar.BackDropView;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500111import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700112import com.android.systemui.statusbar.CommandQueue;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400113import com.android.systemui.statusbar.DismissView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200114import com.android.systemui.statusbar.DragDownHelper;
Jorim Jaggia2052ea2014-08-05 16:22:30 +0200115import com.android.systemui.statusbar.EmptyShadeView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200116import com.android.systemui.statusbar.ExpandableNotificationRow;
Daniel Sandler33805342012-07-23 15:45:12 -0400117import com.android.systemui.statusbar.GestureRecorder;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200118import com.android.systemui.statusbar.KeyguardIndicationController;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700119import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -0400120import com.android.systemui.statusbar.NotificationData.Entry;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200121import com.android.systemui.statusbar.NotificationOverflowContainer;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200122import com.android.systemui.statusbar.ScrimView;
Christian Robertson2e347422011-08-11 14:01:04 -0700123import com.android.systemui.statusbar.SignalClusterView;
Selim Cinekc27437b2014-05-14 10:23:33 +0200124import com.android.systemui.statusbar.SpeedBumpView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200125import com.android.systemui.statusbar.StatusBarState;
Christoph Studer2231c6e2014-12-19 12:40:13 +0100126import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200127import com.android.systemui.statusbar.policy.AccessibilityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400128import com.android.systemui.statusbar.policy.BatteryController;
John Spurlock0ff62e02014-07-22 16:15:08 -0400129import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400130import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200131import com.android.systemui.statusbar.policy.BrightnessMirrorController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400132import com.android.systemui.statusbar.policy.CastControllerImpl;
Adrian Roosb83777b2014-06-30 15:11:53 +0200133import com.android.systemui.statusbar.policy.FlashlightController;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700134import com.android.systemui.statusbar.policy.HeadsUpManager;
Jason Monk3d5f5512014-07-25 11:17:28 -0400135import com.android.systemui.statusbar.policy.HotspotControllerImpl;
Jason Monk815e0572014-08-12 17:26:36 -0400136import com.android.systemui.statusbar.policy.KeyButtonView;
John Spurlock657c62c2014-07-22 12:18:09 -0400137import com.android.systemui.statusbar.policy.KeyguardMonitor;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700138import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400139import com.android.systemui.statusbar.policy.LocationControllerImpl;
140import com.android.systemui.statusbar.policy.NetworkControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400141import com.android.systemui.statusbar.policy.NextAlarmController;
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200142import com.android.systemui.statusbar.policy.PreviewInflater;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400143import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400144import com.android.systemui.statusbar.policy.SecurityControllerImpl;
145import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200146import com.android.systemui.statusbar.policy.UserSwitcherController;
John Spurlock86005342014-05-23 11:58:00 -0400147import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek67b22602014-03-10 15:40:16 +0100148import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Christoph Studer92b389d2014-04-01 18:44:40 +0200149import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
Selim Cinekb036ca42015-02-20 15:56:28 +0100150import com.android.systemui.statusbar.stack.StackViewState;
John Spurlock86005342014-05-23 11:58:00 -0400151import com.android.systemui.volume.VolumeComponent;
Selim Cinek67b22602014-03-10 15:40:16 +0100152
Daniel Sandler6a858c32012-03-12 14:38:58 -0400153import java.io.FileDescriptor;
154import java.io.PrintWriter;
155import java.util.ArrayList;
Christoph Studer92b389d2014-04-01 18:44:40 +0200156import java.util.Collection;
157import java.util.Collections;
Selim Cinekb5605e52015-02-20 18:21:41 +0100158import java.util.HashMap;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700159import java.util.HashSet;
Dan Sandler16128f42014-05-21 12:48:22 -0400160import java.util.List;
John Spurlock7bbb9f62014-10-21 12:15:28 -0400161import java.util.Map;
Selim Cineka59ecc32015-04-07 10:51:49 -0700162import java.util.TreeSet;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700163
164import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
165import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
166import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
167import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
168import static android.app.StatusBarManager.windowStateToString;
169import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
170import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
171import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
172import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
173import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
174import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
175import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
Daniel Sandler6a858c32012-03-12 14:38:58 -0400176
Jorim Jaggiecbab362014-04-23 16:13:15 +0200177public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Selim Cinek8d490d42015-04-10 00:05:50 -0700178 DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
179 HeadsUpManager.OnHeadsUpChangedListener {
Joe Onoratofd52b182010-11-10 18:00:52 -0800180 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400181 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400182 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400183 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400184 public static final boolean DEBUG_GESTURES = false;
Dan Sandler16128f42014-05-21 12:48:22 -0400185 public static final boolean DEBUG_MEDIA = false;
186 public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400187
John Spurlock342cad72013-10-08 09:36:50 -0400188 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400189
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400190 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400191 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400192
Dan Sandler16128f42014-05-21 12:48:22 -0400193 public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
194
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400195 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400196 private static final int MSG_CLOSE_PANELS = 1001;
197 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Jorim Jaggi826730a2014-12-08 21:05:13 +0100198 private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
Winson Chungb1f74992014-08-08 12:53:09 -0700199 // 1020-1040 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400200
Jorim Jaggi826730a2014-12-08 21:05:13 +0100201 // Time after we abort the launch transition.
202 private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
203
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400204 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
205
John Spurlocke1f366f2013-08-05 12:22:40 -0400206 private static final int STATUS_OR_NAV_TRANSIENT =
207 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400208 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400209
Christoph Studer92b389d2014-04-01 18:44:40 +0200210 /** The minimum delay in ms between reports of notification visibility. */
211 private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
212
Jorim Jaggi93a2bb22014-06-02 19:57:28 +0200213 /**
214 * The delay to reset the hint text when the hint animation is finished running.
215 */
216 private static final int HINT_RESET_DELAY_MS = 1200;
217
John Spurlock7b414672014-07-18 13:02:39 -0400218 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
219 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
220 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
221 .build();
222
Selim Cinekbaa23272014-07-08 18:01:07 +0200223 public static final int FADE_KEYGUARD_START_DELAY = 100;
224 public static final int FADE_KEYGUARD_DURATION = 300;
225
Jason Monk815e0572014-08-12 17:26:36 -0400226 /** Allow some time inbetween the long press for back and recents. */
227 private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
228
Joe Onoratofd52b182010-11-10 18:00:52 -0800229 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400230
Daniel Sandler2b697352011-07-22 16:23:09 -0400231 // These are no longer handled by the policy, because we need custom strategies for them
John Spurlockaf8d6c42014-05-07 17:49:08 -0400232 BluetoothControllerImpl mBluetoothController;
Jason Monk3d5f5512014-07-25 11:17:28 -0400233 SecurityControllerImpl mSecurityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400234 BatteryController mBatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400235 LocationControllerImpl mLocationController;
236 NetworkControllerImpl mNetworkController;
Jason Monk51e4dc02014-07-22 12:00:47 -0400237 HotspotControllerImpl mHotspotController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400238 RotationLockControllerImpl mRotationLockController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200239 UserInfoController mUserInfoController;
John Spurlock86005342014-05-23 11:58:00 -0400240 ZenModeController mZenModeController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400241 CastControllerImpl mCastController;
John Spurlock86005342014-05-23 11:58:00 -0400242 VolumeComponent mVolumeComponent;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700243 KeyguardUserSwitcher mKeyguardUserSwitcher;
Adrian Roosb83777b2014-06-30 15:11:53 +0200244 FlashlightController mFlashlightController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200245 UserSwitcherController mUserSwitcherController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200246 NextAlarmController mNextAlarmController;
John Spurlock657c62c2014-07-22 12:18:09 -0400247 KeyguardMonitor mKeyguardMonitor;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200248 BrightnessMirrorController mBrightnessMirrorController;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200249 AccessibilityController mAccessibilityController;
Jim Miller5e6af442011-12-02 18:24:26 -0800250
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400251 int mNaturalBarHeight = -1;
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100252
Joe Onorato808182d2010-07-09 18:52:06 -0400253 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400254 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400255
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400256 StatusBarWindowView mStatusBarWindow;
Joe Onoratofd52b182010-11-10 18:00:52 -0800257 PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400258 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100259 private StatusBarWindowManager mStatusBarWindowManager;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200260 private UnlockMethodCache mUnlockMethodCache;
John Spurlockbf370992014-06-17 13:58:31 -0400261 private DozeServiceHost mDozeServiceHost;
Selim Cinek29ed3c92014-09-23 20:44:35 +0200262 private boolean mScreenOnComingFromTouch;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +0100263 private PointF mScreenOnTouchLocation;
Daniel Sandlera310af82012-04-24 01:20:13 -0400264
Joe Onorato808182d2010-07-09 18:52:06 -0400265 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400266 Object mQueueLock = new Object();
267
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100268 StatusBarIconController mIconController;
Joe Onorato808182d2010-07-09 18:52:06 -0400269
270 // expanded notifications
Daniel Sandler040c2e42012-10-17 00:56:33 -0400271 NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400272 View mExpandedContents;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400273 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400274
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400275 // settings
John Spurlockaf8d6c42014-05-07 17:49:08 -0400276 private QSPanel mQSPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400277
Joe Onorato808182d2010-07-09 18:52:06 -0400278 // top bar
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200279 StatusBarHeaderView mHeader;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200280 KeyguardStatusBarView mKeyguardStatusBar;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200281 View mKeyguardStatusView;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200282 KeyguardBottomAreaView mKeyguardBottomArea;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200283 boolean mLeaveOpenOnKeyguardHide;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200284 KeyguardIndicationController mKeyguardIndicationController;
Jorim Jaggie70d31f2014-04-24 22:08:30 +0200285
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700286 private boolean mKeyguardFadingAway;
287 private long mKeyguardFadingAwayDelay;
288 private long mKeyguardFadingAwayDuration;
289
Jorim Jaggid4a57442014-04-10 02:45:55 +0200290 int mKeyguardMaxNotificationCount;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400291
Joe Onorato808182d2010-07-09 18:52:06 -0400292 boolean mExpandedVisible;
293
John Spurlockd4e65752013-08-28 14:17:09 -0400294 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400295
Joe Onorato808182d2010-07-09 18:52:06 -0400296 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400297 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400298
Joe Onorato808182d2010-07-09 18:52:06 -0400299 // Tracking finger for opening/closing.
300 int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
301 boolean mTracking;
302 VelocityTracker mVelocityTracker;
303
Joe Onorato808182d2010-07-09 18:52:06 -0400304 int[] mAbsPos = new int[2];
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200305 ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
Chet Haase2f2022a2011-10-11 06:41:59 -0700306
Joe Onorato808182d2010-07-09 18:52:06 -0400307 // for disabling the status bar
308 int mDisabled = 0;
309
Daniel Sandler60ee2562011-07-22 12:34:33 -0400310 // tracking calls to View.setSystemUiVisibility()
311 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
312
Daniel Sandler36412a72011-08-04 09:35:13 -0400313 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700314
Daniel Sandler33805342012-07-23 15:45:12 -0400315 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400316 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400317 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400318 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400319
Jason Monk18f99d92014-09-11 13:36:42 -0400320 private ScreenPinningRequest mScreenPinningRequest;
321
Daniel Sandler328310c2011-09-23 15:56:52 -0400322 private int mNavigationIconHints = 0;
Jason Monk4ae97d32014-12-17 10:14:33 -0500323 private HandlerThread mHandlerThread;
Daniel Sandler328310c2011-09-23 15:56:52 -0400324
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700325 private AssistGestureManager mAssistGestureManager;
326
John Spurlock919adac2012-10-02 16:41:12 -0400327 // ensure quick settings is disabled until the current user makes it through the setup wizard
328 private boolean mUserSetup = false;
329 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
330 @Override
331 public void onChange(boolean selfChange) {
332 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
333 mContext.getContentResolver(),
334 Settings.Secure.USER_SETUP_COMPLETE,
335 0 /*default */,
336 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400337 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400338 "selfChange=%s userSetup=%s mUserSetup=%s",
339 selfChange, userSetup, mUserSetup));
John Spurlock73203eb2014-04-15 16:14:46 -0400340
John Spurlock919adac2012-10-02 16:41:12 -0400341 if (userSetup != mUserSetup) {
342 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400343 if (!mUserSetup && mStatusBarView != null)
344 animateCollapseQuickSettings();
345 }
346 }
347 };
348
Chris Wrenf6e83f42013-09-11 14:02:59 -0400349 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
350 @Override
351 public void onChange(boolean selfChange) {
352 boolean wasUsing = mUseHeadsUp;
Jason Monkf7019542014-07-31 12:42:25 -0400353 mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
354 && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
Chris Wren10d82df2014-03-01 10:34:51 -0500355 mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Chris Wren7bd241232014-02-28 16:25:05 -0500356 Settings.Global.HEADS_UP_OFF);
Chris Wren22ae46e2014-02-26 18:08:09 -0500357 mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
358 mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400359 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
360 if (wasUsing != mUseHeadsUp) {
361 if (!mUseHeadsUp) {
362 Log.d(TAG, "dismissing any existing heads up notification on disable event");
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700363 mHeadsUpManager.releaseAllImmediately();
Chris Wrenf6e83f42013-09-11 14:02:59 -0400364 }
365 }
366 }
367 };
368
John Spurlockcfc359a2013-09-05 10:42:03 -0400369 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400370 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400371 private int mStatusBarMode;
372 private int mNavigationBarMode;
Jorim Jaggid41083a2014-09-12 02:54:40 +0200373
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200374 private ViewMediatorCallback mKeyguardViewMediatorCallback;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200375 private ScrimController mScrimController;
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100376 private DozeScrimController mDozeScrimController;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200377
John Spurlock32beb2c2013-03-11 10:16:47 -0400378 private final Runnable mAutohide = new Runnable() {
379 @Override
380 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400381 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400382 if (mSystemUiVisibility != requested) {
383 notifyUiVisibilityChanged(requested);
384 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400385 }};
386
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700387 private boolean mWaitingForKeyguardExit;
John Spurlockbf370992014-06-17 13:58:31 -0400388 private boolean mDozing;
Jorim Jaggi0e664392014-09-27 01:30:22 +0200389 private boolean mScrimSrcModeEnabled;
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100390
Jorim Jaggi4e0880e2014-07-25 14:51:50 +0200391 private Interpolator mLinearInterpolator = new LinearInterpolator();
392 private Interpolator mBackdropInterpolator = new AccelerateDecelerateInterpolator();
Jorim Jaggi61d37f62014-07-30 17:26:55 +0200393 public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
394 public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200395
Selim Cineka0fad3b2014-09-19 17:20:05 +0200396 private BackDropView mBackdrop;
Dan Sandler16128f42014-05-21 12:48:22 -0400397 private ImageView mBackdropFront, mBackdropBack;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200398 private PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
399 private PorterDuffXfermode mSrcOverXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
Dan Sandler16128f42014-05-21 12:48:22 -0400400
401 private MediaSessionManager mMediaSessionManager;
402 private MediaController mMediaController;
403 private String mMediaNotificationKey;
404 private MediaMetadata mMediaMetadata;
405 private MediaController.Callback mMediaListener
406 = new MediaController.Callback() {
407 @Override
408 public void onPlaybackStateChanged(PlaybackState state) {
409 super.onPlaybackStateChanged(state);
410 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state);
411 }
412
413 @Override
414 public void onMetadataChanged(MediaMetadata metadata) {
415 super.onMetadataChanged(metadata);
416 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
417 mMediaMetadata = metadata;
418 updateMediaMetaData(true);
419 }
420 };
421
422 private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
423 new OnChildLocationsChangedListener() {
424 @Override
425 public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
426 userActivity();
427 }
428 };
429
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200430 private int mDisabledUnmodified;
431
Christoph Studer92b389d2014-04-01 18:44:40 +0200432 /** Keys of notifications currently visible to the user. */
433 private final ArraySet<String> mCurrentlyVisibleNotifications = new ArraySet<String>();
434 private long mLastVisibilityReportUptimeMs;
435
John Spurlockbf370992014-06-17 13:58:31 -0400436 private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
437
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200438 private int mDrawCount;
Selim Cinekbaa23272014-07-08 18:01:07 +0200439 private Runnable mLaunchTransitionEndRunnable;
440 private boolean mLaunchTransitionFadingAway;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +0200441 private ExpandableNotificationRow mDraggedDownRow;
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200442
Christoph Studer2231c6e2014-12-19 12:40:13 +0100443 // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
444 private int mLastLoggedStateFingerprint;
445
Selim Cinekb036ca42015-02-20 15:56:28 +0100446 private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_CARD
447 | StackViewState.LOCATION_TOP_STACK_PEEKING
448 | StackViewState.LOCATION_MAIN_AREA
449 | StackViewState.LOCATION_BOTTOM_STACK_PEEKING;
Christoph Studer92b389d2014-04-01 18:44:40 +0200450
451 private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
452 new OnChildLocationsChangedListener() {
453 @Override
454 public void onChildLocationsChanged(
455 NotificationStackScrollLayout stackScrollLayout) {
456 if (mHandler.hasCallbacks(mVisibilityReporter)) {
457 // Visibilities will be reported when the existing
458 // callback is executed.
459 return;
460 }
461 // Calculate when we're allowed to run the visibility
462 // reporter. Note that this timestamp might already have
463 // passed. That's OK, the callback will just be executed
464 // ASAP.
465 long nextReportUptimeMs =
466 mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
467 mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
468 }
469 };
470
471 // Tracks notifications currently visible in mNotificationStackScroller and
472 // emits visibility events via NoMan on changes.
473 private final Runnable mVisibilityReporter = new Runnable() {
474 private final ArrayList<String> mTmpNewlyVisibleNotifications = new ArrayList<String>();
475 private final ArrayList<String> mTmpCurrentlyVisibleNotifications = new ArrayList<String>();
476
477 @Override
478 public void run() {
479 mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
480
481 // 1. Loop over mNotificationData entries:
482 // A. Keep list of visible notifications.
483 // B. Keep list of previously hidden, now visible notifications.
484 // 2. Compute no-longer visible notifications by removing currently
485 // visible notifications from the set of previously visible
486 // notifications.
487 // 3. Report newly visible and no-longer visible notifications.
488 // 4. Keep currently visible notifications for next report.
Christoph Studerc8db24b2014-07-25 17:50:30 +0200489 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
490 int N = activeNotifications.size();
Christoph Studer92b389d2014-04-01 18:44:40 +0200491 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +0200492 Entry entry = activeNotifications.get(i);
Christoph Studer92b389d2014-04-01 18:44:40 +0200493 String key = entry.notification.getKey();
494 boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(key);
495 boolean currentlyVisible =
496 (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
497 if (currentlyVisible) {
498 // Build new set of visible notifications.
499 mTmpCurrentlyVisibleNotifications.add(key);
500 }
501 if (!previouslyVisible && currentlyVisible) {
502 mTmpNewlyVisibleNotifications.add(key);
503 }
504 }
505 ArraySet<String> noLongerVisibleNotifications = mCurrentlyVisibleNotifications;
506 noLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
507
508 logNotificationVisibilityChanges(
509 mTmpNewlyVisibleNotifications, noLongerVisibleNotifications);
510
511 mCurrentlyVisibleNotifications.clear();
512 mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
513
514 mTmpNewlyVisibleNotifications.clear();
515 mTmpCurrentlyVisibleNotifications.clear();
516 }
517 };
518
Jorim Jaggiecbab362014-04-23 16:13:15 +0200519 private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
520 @Override
521 public void onClick(View v) {
522 goToLockedShade(null);
523 }
524 };
Selim Cinekb5605e52015-02-20 18:21:41 +0100525 private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
526 = new HashMap<>();
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700527 private HashSet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new HashSet<>();
528 private RankingMap mLatestRankingMap;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200529
Joe Onorato808182d2010-07-09 18:52:06 -0400530 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400531 public void start() {
532 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
533 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400534 updateDisplaySize();
Jorim Jaggi0e664392014-09-27 01:30:22 +0200535 mScrimSrcModeEnabled = mContext.getResources().getBoolean(
536 R.bool.config_status_bar_scrim_behind_use_src);
Adrian Roos75fa3852015-01-27 20:21:44 +0100537
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500538 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400539
Dan Sandler16128f42014-05-21 12:48:22 -0400540 mMediaSessionManager
541 = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
542 // TODO: use MediaSessionManager.SessionListener to hook us up to future updates
543 // in session state
544
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400545 addNavigationBar();
546
Joe Onorato808182d2010-07-09 18:52:06 -0400547 // Lastly, call to the icon policy to install/update all the icons.
Jason Monk952d5d82014-10-27 15:28:22 -0400548 mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController);
John Spurlocke677d712014-02-13 12:52:19 -0500549 mSettingsObserver.onChange(false); // set up
Chris Wrenf6e83f42013-09-11 14:02:59 -0400550
551 mHeadsUpObserver.onChange(true); // set up
552 if (ENABLE_HEADS_UP) {
553 mContext.getContentResolver().registerContentObserver(
Chris Wren10d82df2014-03-01 10:34:51 -0500554 Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
Chris Wrenf6e83f42013-09-11 14:02:59 -0400555 mHeadsUpObserver);
Chris Wren22ae46e2014-02-26 18:08:09 -0500556 mContext.getContentResolver().registerContentObserver(
557 Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
558 mHeadsUpObserver);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400559 }
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200560 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Christoph Studer2231c6e2014-12-19 12:40:13 +0100561 mUnlockMethodCache.addListener(this);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100562 startKeyguard();
John Spurlockbf370992014-06-17 13:58:31 -0400563
564 mDozeServiceHost = new DozeServiceHost();
Jeff Brown4d69e222014-09-18 15:27:50 -0700565 putComponent(DozeHost.class, mDozeServiceHost);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200566 putComponent(PhoneStatusBar.class, this);
John Spurlock89f060a2014-07-16 21:03:15 -0400567
568 setControllerUsers();
Chris Wrencd8f4f72014-08-27 18:48:13 -0400569
570 notifyUserAboutHiddenNotifications();
Jason Monk18f99d92014-09-11 13:36:42 -0400571
572 mScreenPinningRequest = new ScreenPinningRequest(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400573 }
574
575 // ================================================================================
576 // Constructing the view
577 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700578 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400579 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400580
581 Resources res = context.getResources();
582
Daniel Sandler6e8db882011-10-26 15:40:51 -0400583 updateDisplaySize(); // populates mDisplayMetrics
Jorim Jaggi2e115c52014-07-01 21:27:58 +0200584 updateResources();
Joe Onorato808182d2010-07-09 18:52:06 -0400585
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400586 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
Daniel Sandlera310af82012-04-24 01:20:13 -0400587 R.layout.super_status_bar, null);
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400588 mStatusBarWindow.mService = this;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400589 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
590 @Override
591 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400592 checkUserAutohide(v, event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400593 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500594 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400595 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400596 }
597 }
Chris Wren5de6e942012-05-16 14:22:21 -0400598 return mStatusBarWindow.onTouchEvent(event);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700599 }
600 });
Daniel Sandler21b274e2012-05-02 15:07:51 -0400601
Daniel Sandlera310af82012-04-24 01:20:13 -0400602 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400603 mStatusBarView.setBar(this);
John Spurlock209bede2013-07-17 12:23:27 -0400604
Daniel Sandler08d05e32012-08-08 16:39:54 -0400605 PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
606 mStatusBarView.setPanelHolder(holder);
607
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100608 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
609 R.id.notification_panel);
Daniel Sandler040c2e42012-10-17 00:56:33 -0400610 mNotificationPanel.setStatusBar(this);
Joe Onorato808182d2010-07-09 18:52:06 -0400611
Jeff Brown98365d72012-08-19 20:30:52 -0700612 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700613 mStatusBarWindow.setBackground(null);
Alan Viverette4a357cd2015-03-18 18:37:18 -0700614 mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
Romain Guy648342f2012-05-25 10:44:45 -0700615 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700616 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700617
Selim Cineka59ecc32015-04-07 10:51:49 -0700618 mHeadsUpManager = new HeadsUpManager(context, mNotificationPanel.getViewTreeObserver());
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700619 mHeadsUpManager.setBar(this);
620 mHeadsUpManager.addListener(this);
621 mHeadsUpManager.addListener(mNotificationPanel);
622 mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
Selim Cinekfbe9a442015-04-13 16:09:49 -0700623 mNotificationData.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700624
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400625 if (MULTIUSER_DEBUG) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100626 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
627 R.id.header_debug_info);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400628 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
629 }
Joe Onorato808182d2010-07-09 18:52:06 -0400630
John Spurlockd5ef5462012-06-13 11:19:51 -0400631 updateShowSearchHoldoff();
632
Daniel Sandler0129b312011-05-11 11:54:11 -0400633 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700634 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400635 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400636 if (showNav) {
Jim Miller5e6af442011-12-02 18:24:26 -0800637 mNavigationBarView =
Daniel Sandler0129b312011-05-11 11:54:11 -0400638 (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400639
Daniel Sandler6da2b762011-09-14 16:04:59 -0400640 mNavigationBarView.setDisabledFlags(mDisabled);
Jim Millere898ac52012-04-06 17:10:57 -0700641 mNavigationBarView.setBar(this);
Jorim Jaggif4797922014-08-04 22:49:41 +0200642 mNavigationBarView.setOnVerticalChangedListener(
643 new NavigationBarView.OnVerticalChangedListener() {
644 @Override
645 public void onVerticalChanged(boolean isVertical) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700646 if (mAssistGestureManager != null) {
647 mAssistGestureManager.onConfigurationChanged();
Jorim Jaggif4797922014-08-04 22:49:41 +0200648 }
Jorim Jaggidd5b8862014-08-05 21:04:39 +0200649 mNotificationPanel.setQsScrimEnabled(!isVertical);
Jorim Jaggif4797922014-08-04 22:49:41 +0200650 }
651 });
John Spurlock9deaa282013-07-25 13:03:47 -0400652 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
653 @Override
654 public boolean onTouch(View v, MotionEvent event) {
655 checkUserAutohide(v, event);
656 return false;
657 }});
Daniel Sandler0129b312011-05-11 11:54:11 -0400658 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400659 } catch (RemoteException ex) {
660 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400661 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400662
Joe Onorato808182d2010-07-09 18:52:06 -0400663 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400664 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400665
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100666 mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
667 R.id.notification_stack_scroller);
668 mStackScroller.setLongPressListener(getNotificationLongClicker());
Selim Cinek19c8c702014-08-25 22:09:19 +0200669 mStackScroller.setPhoneStatusBar(this);
Selim Cinekb5605e52015-02-20 18:21:41 +0100670 mStackScroller.setGroupManager(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700671 mStackScroller.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb5605e52015-02-20 18:21:41 +0100672 mGroupManager.setOnGroupChangeListener(mStackScroller);
Selim Cinek80a14e52014-03-27 16:58:04 +0100673
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200674 mKeyguardIconOverflowContainer =
675 (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
676 R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
677 mKeyguardIconOverflowContainer.setOnActivatedListener(this);
Jorim Jaggie96fcd12014-05-07 21:10:35 +0200678 mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
Jorim Jaggid4a57442014-04-10 02:45:55 +0200679 mStackScroller.addView(mKeyguardIconOverflowContainer);
680
Selim Cinekc27437b2014-05-14 10:23:33 +0200681 SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate(
682 R.layout.status_bar_notification_speed_bump, mStackScroller, false);
683 mStackScroller.setSpeedBumpView(speedBump);
Selim Cinekbecf5e32014-08-12 14:29:18 +0200684 mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
685 R.layout.status_bar_no_notifications, mStackScroller, false);
686 mStackScroller.setEmptyShadeView(mEmptyShadeView);
Dan Sandlereceda3d2014-07-21 15:35:01 -0400687 mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
688 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
689 mDismissView.setOnButtonClickListener(new View.OnClickListener() {
690 @Override
691 public void onClick(View v) {
692 clearAllNotifications();
693 }
694 });
695 mStackScroller.setDismissView(mDismissView);
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100696 mExpandedContents = mStackScroller;
Selim Cinek67b22602014-03-10 15:40:16 +0100697
Selim Cineka0fad3b2014-09-19 17:20:05 +0200698 mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
699 mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
700 mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
701
702 ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
703 ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
Selim Cinekaac93252015-04-14 20:04:12 -0700704 View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
705 mScrimController = new ScrimController(scrimBehind, scrimInFront, headsUpScrim,
706 mScrimSrcModeEnabled);
707 mHeadsUpManager.addListener(mScrimController);
708 mStackScroller.setScrimController(mScrimController);
Selim Cineka0fad3b2014-09-19 17:20:05 +0200709 mScrimController.setBackDropView(mBackdrop);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200710 mStatusBarView.setScrimController(mScrimController);
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100711 mDozeScrimController = new DozeScrimController(mScrimController, context);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200712
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200713 mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200714 mHeader.setActivityStarter(this);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200715 mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200716 mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200717 mKeyguardBottomArea =
718 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
719 mKeyguardBottomArea.setActivityStarter(this);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200720 mKeyguardIndicationController = new KeyguardIndicationController(mContext,
721 (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
722 R.id.keyguard_indication_text));
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200723 mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400724
Joe Onorato808182d2010-07-09 18:52:06 -0400725 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
726
Joe Onorato808182d2010-07-09 18:52:06 -0400727 // set the inital view visibility
728 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400729
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100730 mIconController = new StatusBarIconController(
731 mContext, mStatusBarView, mKeyguardStatusBar, this);
732
Jason Monk4ae97d32014-12-17 10:14:33 -0500733 // Background thread for any controllers that need it.
734 mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
735 mHandlerThread.start();
736
Daniel Sandler2b697352011-07-22 16:23:09 -0400737 // Other icons
John Spurlockaf8d6c42014-05-07 17:49:08 -0400738 mLocationController = new LocationControllerImpl(mContext); // will post a notification
Daniel Sandler2b697352011-07-22 16:23:09 -0400739 mBatteryController = new BatteryController(mContext);
John Spurlock0ff62e02014-07-22 16:15:08 -0400740 mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
741 @Override
742 public void onPowerSaveChanged() {
743 mHandler.post(mCheckBarModes);
John Spurlockd96179e2014-08-21 16:43:45 -0400744 if (mDozeServiceHost != null) {
745 mDozeServiceHost.firePowerSaveChanged(mBatteryController.isPowerSave());
746 }
John Spurlock0ff62e02014-07-22 16:15:08 -0400747 }
748 @Override
749 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
750 // noop
751 }
752 });
John Spurlockaf8d6c42014-05-07 17:49:08 -0400753 mNetworkController = new NetworkControllerImpl(mContext);
Jason Monk51e4dc02014-07-22 12:00:47 -0400754 mHotspotController = new HotspotControllerImpl(mContext);
Jason Monk4ae97d32014-12-17 10:14:33 -0500755 mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk3d5f5512014-07-25 11:17:28 -0400756 mSecurityController = new SecurityControllerImpl(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400757 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
758 mRotationLockController = new RotationLockControllerImpl(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500759 }
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200760 mUserInfoController = new UserInfoController(mContext);
John Spurlock86005342014-05-23 11:58:00 -0400761 mVolumeComponent = getComponent(VolumeComponent.class);
John Spurlockf2565a82014-10-23 20:16:22 -0400762 if (mVolumeComponent != null) {
763 mZenModeController = mVolumeComponent.getZenController();
764 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400765 mCastController = new CastControllerImpl(mContext);
Jim Miller5e6af442011-12-02 18:24:26 -0800766 final SignalClusterView signalCluster =
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200767 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
768 final SignalClusterView signalClusterKeyguard =
769 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200770 final SignalClusterView signalClusterQs =
771 (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
Christian Robertson2e347422011-08-11 14:01:04 -0700772 mNetworkController.addSignalCluster(signalCluster);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200773 mNetworkController.addSignalCluster(signalClusterKeyguard);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200774 mNetworkController.addSignalCluster(signalClusterQs);
Jason Monk3128f122014-09-03 13:18:57 -0400775 signalCluster.setSecurityController(mSecurityController);
Daniel Sandler28f89d42011-08-15 14:04:15 -0400776 signalCluster.setNetworkController(mNetworkController);
Jason Monk3128f122014-09-03 13:18:57 -0400777 signalClusterKeyguard.setSecurityController(mSecurityController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200778 signalClusterKeyguard.setNetworkController(mNetworkController);
Jason Monk3128f122014-09-03 13:18:57 -0400779 signalClusterQs.setSecurityController(mSecurityController);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200780 signalClusterQs.setNetworkController(mNetworkController);
Daniel Sandler8b268d42013-05-28 16:17:13 -0400781 final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
782 if (isAPhone) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500783 mNetworkController.addEmergencyListener(new NetworkControllerImpl.EmergencyListener() {
784 @Override
785 public void setEmergencyCallsOnly(boolean emergencyOnly) {
786 mHeader.setShowEmergencyCallsOnly(emergencyOnly);
787 }
788 });
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400789 }
790
Adrian Roosb83777b2014-06-30 15:11:53 +0200791 mFlashlightController = new FlashlightController(mContext);
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200792 mKeyguardBottomArea.setFlashlightController(mFlashlightController);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200793 mKeyguardBottomArea.setPhoneStatusBar(this);
794 mAccessibilityController = new AccessibilityController(mContext);
795 mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200796 mNextAlarmController = new NextAlarmController(mContext);
John Spurlock657c62c2014-07-22 12:18:09 -0400797 mKeyguardMonitor = new KeyguardMonitor();
Adrian Roos2b154a92014-11-17 15:18:39 +0100798 if (UserSwitcherController.isUserSwitcherAvailable(UserManager.get(mContext))) {
799 mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor);
800 }
Adrian Roos723632e2014-07-23 21:13:21 +0200801 mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200802 (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
Jorim Jaggibf1899e2014-08-07 02:04:18 +0200803 mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
Adrian Roos723632e2014-07-23 21:13:21 +0200804
805
John Spurlockaf8d6c42014-05-07 17:49:08 -0400806 // Set up the quick settings tile panel
807 mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel);
808 if (mQSPanel != null) {
809 final QSTileHost qsh = new QSTileHost(mContext, this,
810 mBluetoothController, mLocationController, mRotationLockController,
Jason Monk51e4dc02014-07-22 12:00:47 -0400811 mNetworkController, mZenModeController, mHotspotController,
John Spurlock657c62c2014-07-22 12:18:09 -0400812 mCastController, mFlashlightController,
Jason Monk3d5f5512014-07-25 11:17:28 -0400813 mUserSwitcherController, mKeyguardMonitor,
814 mSecurityController);
Adrian Roos1ef80fe2014-07-14 22:53:54 +0200815 mQSPanel.setHost(qsh);
John Spurlockbceed062014-08-10 18:04:16 -0400816 mQSPanel.setTiles(qsh.getTiles());
Adrian Roos5fd872e2014-08-12 17:28:58 +0200817 mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
818 mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400819 mHeader.setQSPanel(mQSPanel);
John Spurlockbceed062014-08-10 18:04:16 -0400820 qsh.setCallback(new QSTileHost.Callback() {
821 @Override
822 public void onTilesChanged() {
823 mQSPanel.setTiles(qsh.getTiles());
824 }
825 });
Siva Velusamy537421b2012-09-14 14:45:02 -0700826 }
827
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200828 // User info. Trigger first load.
829 mHeader.setUserInfoController(mUserInfoController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200830 mKeyguardStatusBar.setUserInfoController(mUserInfoController);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200831 mUserInfoController.reloadUserInfo();
832
Jorim Jaggi853b0702014-07-05 04:31:14 +0200833 mHeader.setBatteryController(mBatteryController);
Jorim Jaggi708f7722014-08-20 17:30:38 +0200834 ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
835 mBatteryController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200836 mKeyguardStatusBar.setBatteryController(mBatteryController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200837 mHeader.setNextAlarmController(mNextAlarmController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200838
John Spurlock56d007b2013-10-28 18:40:56 -0400839 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
840 mBroadcastReceiver.onReceive(mContext,
841 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
842
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700843 mAssistGestureManager = new AssistGestureManager(this, context);
844
Joe Onorato808182d2010-07-09 18:52:06 -0400845 // receive broadcasts
846 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400847 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
848 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400849 filter.addAction(Intent.ACTION_SCREEN_ON);
Dan Sandler16128f42014-05-21 12:48:22 -0400850 if (DEBUG_MEDIA_FAKE_ARTWORK) {
851 filter.addAction("fake_artwork");
852 }
John Spurlock3c875662013-08-31 15:07:25 -0400853 filter.addAction(ACTION_DEMO);
Kenny Guy44fc65f2014-11-28 22:18:14 +0000854 context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400855
John Spurlock919adac2012-10-02 16:41:12 -0400856 // listen for USER_SETUP_COMPLETE setting (per-user)
857 resetUserSetupObserver();
858
Daniel Sandlera310af82012-04-24 01:20:13 -0400859 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400860 }
861
Dan Sandlereceda3d2014-07-21 15:35:01 -0400862 private void clearAllNotifications() {
863
864 // animate-swipe all dismissable notifications, then animate the shade closed
865 int numChildren = mStackScroller.getChildCount();
866
867 final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
868 for (int i = 0; i < numChildren; i++) {
869 final View child = mStackScroller.getChildAt(i);
Selim Cinekb5605e52015-02-20 18:21:41 +0100870 if (child instanceof ExpandableNotificationRow) {
871 if (mStackScroller.canChildBeDismissed(child)) {
872 if (child.getVisibility() == View.VISIBLE) {
873 viewsToHide.add(child);
874 }
875 }
876 ExpandableNotificationRow row = (ExpandableNotificationRow) child;
877 List<ExpandableNotificationRow> children = row.getNotificationChildren();
878 if (row.areChildrenExpanded() && children != null) {
879 for (ExpandableNotificationRow childRow : children) {
880 if (childRow.getVisibility() == View.VISIBLE) {
881 viewsToHide.add(childRow);
882 }
883 }
Dan Sandlereceda3d2014-07-21 15:35:01 -0400884 }
885 }
886 }
887 if (viewsToHide.isEmpty()) {
888 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
889 return;
890 }
891
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200892 addPostCollapseAction(new Runnable() {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400893 @Override
894 public void run() {
895 try {
896 mBarService.onClearAllNotifications(mCurrentUserId);
897 } catch (Exception ex) { }
898 }
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200899 });
Dan Sandlereceda3d2014-07-21 15:35:01 -0400900
901 performDismissAllAnimations(viewsToHide);
902
903 }
904
905 private void performDismissAllAnimations(ArrayList<View> hideAnimatedList) {
906 Runnable animationFinishAction = new Runnable() {
907 @Override
908 public void run() {
909 mStackScroller.post(new Runnable() {
910 @Override
911 public void run() {
912 mStackScroller.setDismissAllInProgress(false);
913 }
914 });
915 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
916 }
917 };
918
919 // let's disable our normal animations
920 mStackScroller.setDismissAllInProgress(true);
921
922 // Decrease the delay for every row we animate to give the sense of
923 // accelerating the swipes
924 int rowDelayDecrement = 10;
925 int currentDelay = 140;
Selim Cinek7d5f3742014-11-07 18:07:49 +0100926 int totalDelay = 180;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400927 int numItems = hideAnimatedList.size();
Selim Cinek7d5f3742014-11-07 18:07:49 +0100928 for (int i = numItems - 1; i >= 0; i--) {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400929 View view = hideAnimatedList.get(i);
930 Runnable endRunnable = null;
Selim Cinek7d5f3742014-11-07 18:07:49 +0100931 if (i == 0) {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400932 endRunnable = animationFinishAction;
933 }
934 mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
935 currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
936 totalDelay += currentDelay;
937 }
938 }
939
John Spurlockae641c92014-06-30 18:11:40 -0400940 @Override
941 protected void setZenMode(int mode) {
942 super.setZenMode(mode);
943 if (mIconPolicy != null) {
944 mIconPolicy.setZenMode(mode);
945 }
946 }
947
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100948 private void startKeyguard() {
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200949 KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
950 mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200951 mStatusBarWindow, mStatusBarWindowManager, mScrimController);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200952 mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100953 }
954
Michael Jurka7f2668c2012-03-27 07:49:52 -0700955 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -0700956 protected View getStatusBarView() {
957 return mStatusBarView;
958 }
959
Jorim Jaggi0a27be82014-06-11 03:22:39 +0200960 public StatusBarWindowView getStatusBarWindow() {
961 return mStatusBarWindow;
962 }
963
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700964 public void invokeAssistGesture(boolean vibrate) {
965 mHandler.removeCallbacks(mInvokeAssist);
966 mAssistGestureManager.onGestureInvoked(vibrate);
Jim Millere898ac52012-04-06 17:10:57 -0700967 }
968
Joe Onoratodc100302011-01-11 17:07:41 -0800969 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -0400970 if (mNaturalBarHeight < 0) {
971 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -0700972 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -0400973 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
974 }
975 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -0800976 }
977
Daniel Sandler5c8da942011-06-28 00:29:04 -0400978 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
979 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -0400980 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -0400981 toggleRecentApps();
982 }
983 };
Chris Wren0c8275b2012-05-08 13:36:48 -0400984
Jason Monk815e0572014-08-12 17:26:36 -0400985 private long mLastLockToAppLongPress;
Jason Monk815e0572014-08-12 17:26:36 -0400986 private View.OnLongClickListener mLongPressBackRecentsListener =
987 new View.OnLongClickListener() {
Jason Monk62515be2014-05-21 16:06:19 -0400988 @Override
989 public boolean onLongClick(View v) {
Jason Monk815e0572014-08-12 17:26:36 -0400990 handleLongPressBackRecents(v);
Jason Monk62515be2014-05-21 16:06:19 -0400991 return true;
992 }
993 };
994
Jim Miller9a720f52012-05-30 03:19:43 -0700995 private int mShowSearchHoldoff = 0;
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700996 private Runnable mInvokeAssist = new Runnable() {
Jim Miller9a720f52012-05-30 03:19:43 -0700997 public void run() {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700998 invokeAssistGesture(true /* vibrate */);
Daniel Sandlera2fbe532012-08-10 01:19:03 -0400999 awakenDreams();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001000 if (mNavigationBarView != null) {
1001 mNavigationBarView.getHomeButton().abortCurrentGesture();
1002 }
Jim Miller9a720f52012-05-30 03:19:43 -07001003 }
1004 };
1005
Jorim Jaggi7b0de292014-05-27 21:41:55 +02001006 View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
Jim Millere898ac52012-04-06 17:10:57 -07001007 public boolean onTouch(View v, MotionEvent event) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001008 switch (event.getAction()) {
Jorim Jaggif4797922014-08-04 22:49:41 +02001009 case MotionEvent.ACTION_DOWN:
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001010 if (!shouldDisableNavbarGestures()) {
1011 mHandler.removeCallbacks(mInvokeAssist);
1012 mHandler.postDelayed(mInvokeAssist, mShowSearchHoldoff);
1013 }
1014 break;
Jim Miller9a720f52012-05-30 03:19:43 -07001015
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001016 case MotionEvent.ACTION_UP:
1017 case MotionEvent.ACTION_CANCEL:
1018 mHandler.removeCallbacks(mInvokeAssist);
1019 awakenDreams();
1020 break;
1021 }
1022 return false;
Jim Millere898ac52012-04-06 17:10:57 -07001023 }
1024 };
Daniel Sandler5c8da942011-06-28 00:29:04 -04001025
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001026 private void awakenDreams() {
1027 if (mDreamManager != null) {
1028 try {
1029 mDreamManager.awaken();
1030 } catch (RemoteException e) {
1031 // fine, stay asleep then
1032 }
1033 }
1034 }
1035
Michael Jurka412cba82011-10-17 09:05:00 -07001036 private void prepareNavigationBarView() {
1037 mNavigationBarView.reorient();
1038
1039 mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
Michael Jurka80343f62012-10-18 13:13:46 +02001040 mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
Jason Monk62515be2014-05-21 16:06:19 -04001041 mNavigationBarView.getRecentsButton().setLongClickable(true);
Jason Monk815e0572014-08-12 17:26:36 -04001042 mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener);
1043 mNavigationBarView.getBackButton().setLongClickable(true);
1044 mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);
Jorim Jaggi7b0de292014-05-27 21:41:55 +02001045 mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001046 mAssistGestureManager.onConfigurationChanged();
Michael Jurka412cba82011-10-17 09:05:00 -07001047 }
1048
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001049 // For small-screen devices (read: phones) that lack hardware navigation buttons
1050 private void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -04001051 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -04001052 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001053
Michael Jurka412cba82011-10-17 09:05:00 -07001054 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001055
Jeff Brown98365d72012-08-19 20:30:52 -07001056 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001057 }
1058
1059 private void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -04001060 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001061
Michael Jurka412cba82011-10-17 09:05:00 -07001062 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001063
Jeff Brown98365d72012-08-19 20:30:52 -07001064 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001065 }
1066
John Spurlock1bbd49d2012-10-19 11:09:32 -04001067 private void notifyNavigationBarScreenOn(boolean screenOn) {
1068 if (mNavigationBarView == null) return;
1069 mNavigationBarView.notifyScreenOn(screenOn);
1070 }
1071
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001072 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001073 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001074 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001075 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
1076 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001077 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1078 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -07001079 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -04001080 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -07001081 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
John Spurlockad3e6cb2013-04-30 08:47:43 -04001082 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001083 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -07001084 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001085 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
1086 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001087
1088 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001089 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001090 return lp;
1091 }
1092
Joe Onorato808182d2010-07-09 18:52:06 -04001093 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001094 mIconController.addSystemIcon(slot, index, viewIndex, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001095 }
1096
1097 public void updateIcon(String slot, int index, int viewIndex,
1098 StatusBarIcon old, StatusBarIcon icon) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001099 mIconController.updateSystemIcon(slot, index, viewIndex, old, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001100 }
1101
1102 public void removeIcon(String slot, int index, int viewIndex) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001103 mIconController.removeSystemIcon(slot, index, viewIndex);
Joe Onorato808182d2010-07-09 18:52:06 -04001104 }
1105
John Spurlockbf20eab2014-04-09 16:40:39 -04001106 public UserHandle getCurrentUserHandle() {
1107 return new UserHandle(mCurrentUserId);
1108 }
1109
Christoph Studer71f18fd2014-05-20 17:02:04 +02001110 @Override
Selim Cinek379ff8f2015-02-20 17:03:16 +01001111 public void addNotification(StatusBarNotification notification, RankingMap ranking,
1112 Entry oldEntry) {
Chris Wrenaaa58d12014-06-03 14:29:12 -04001113 if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
Chris Wrend4db6cb2013-08-07 16:05:23 -04001114
Selim Cinek8d490d42015-04-10 00:05:50 -07001115 Entry shadeEntry = createNotificationViews(notification);
Chris Wrena4ef6202014-06-09 18:07:30 -04001116 if (shadeEntry == null) {
1117 return;
1118 }
Selim Cinek31d9ef72015-04-15 19:29:49 -07001119 boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(notification);
1120 if (isHeadsUped) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001121 mHeadsUpManager.showNotification(shadeEntry);
1122 }
Chris Wrena4ef6202014-06-09 18:07:30 -04001123
Selim Cinek31d9ef72015-04-15 19:29:49 -07001124 if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
John Spurlockbf20eab2014-04-09 16:40:39 -04001125 // Stop screensaver if the notification has a full-screen intent.
1126 // (like an incoming phone call)
1127 awakenDreams();
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -04001128
John Spurlockbf20eab2014-04-09 16:40:39 -04001129 // not immersive & a full-screen alert should be shown
1130 if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
1131 try {
Chris Wren223c66b62014-11-10 16:00:09 -05001132 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
1133 notification.getKey());
John Spurlockbf20eab2014-04-09 16:40:39 -04001134 notification.getNotification().fullScreenIntent.send();
1135 } catch (PendingIntent.CanceledException e) {
1136 }
Joe Onorato808182d2010-07-09 18:52:06 -04001137 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001138 addNotificationViews(shadeEntry, ranking);
Joe Onorato808182d2010-07-09 18:52:06 -04001139 // Recalculate the position of the sliding windows and the titles.
1140 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001141 }
1142
Chris Wren51c75102013-07-16 20:49:17 -04001143 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001144 protected void updateNotificationRanking(RankingMap ranking) {
Chris Wren333a61c2014-05-28 16:40:57 -04001145 mNotificationData.updateRanking(ranking);
Chris Wren333a61c2014-05-28 16:40:57 -04001146 updateNotifications();
1147 }
1148
1149 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001150 public void removeNotification(String key, RankingMap ranking) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001151 boolean defferRemoval = false;
1152 if (mHeadsUpManager.isHeadsUp(key)) {
1153 defferRemoval = !mHeadsUpManager.removeNotification(key);
Chris Wrena4ef6202014-06-09 18:07:30 -04001154 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001155 if (defferRemoval) {
1156 mLatestRankingMap = ranking;
1157 mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
1158 return;
1159 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001160 StatusBarNotification old = removeNotificationViews(key, ranking);
John Spurlockcd686b52013-06-05 10:13:46 -04001161 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -04001162
1163 if (old != null) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001164 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
Jorim Jaggiba94f882014-08-20 19:23:55 +02001165 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001166 if (mState == StatusBarState.SHADE) {
1167 animateCollapsePanels();
1168 } else if (mState == StatusBarState.SHADE_LOCKED) {
1169 goToKeyguard();
1170 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001171 }
Joe Onorato808182d2010-07-09 18:52:06 -04001172 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001173 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001174 }
1175
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001176 @Override
1177 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001178 if (mNavigationBarView != null) {
1179 mNavigationBarView.setLayoutDirection(layoutDirection);
1180 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001181 }
1182
John Spurlockd5ef5462012-06-13 11:19:51 -04001183 private void updateShowSearchHoldoff() {
1184 mShowSearchHoldoff = mContext.getResources().getInteger(
1185 R.integer.config_show_search_delay);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001186 }
1187
Christoph Studer37fe6932014-05-26 13:10:30 +02001188 private void updateNotificationShade() {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001189 if (mStackScroller == null) return;
Daniel Sandler26cda272012-05-22 15:44:08 -04001190
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001191 // Do not modify the notifications during collapse.
1192 if (isCollapsing()) {
1193 addPostCollapseAction(new Runnable() {
1194 @Override
1195 public void run() {
1196 updateNotificationShade();
1197 }
1198 });
1199 return;
1200 }
1201
Christoph Studerc8db24b2014-07-25 17:50:30 +02001202 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
Jorim Jaggif6411742014-08-05 17:10:43 +00001203 ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
Christoph Studerc8db24b2014-07-25 17:50:30 +02001204 final int N = activeNotifications.size();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001205 for (int i=0; i<N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001206 Entry ent = activeNotifications.get(i);
1207 int vis = ent.notification.getNotification().visibility;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001208
Christoph Studerc8db24b2014-07-25 17:50:30 +02001209 // Display public version of the notification if we need to redact.
Jorim Jaggiae441282014-08-01 02:45:18 +02001210 final boolean hideSensitive =
1211 !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId());
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001212 boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE;
1213 boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey());
1214 boolean sensitive = (sensitiveNote && hideSensitive) || sensitivePackage;
1215 boolean showingPublic = sensitive && isLockscreenPublicMode();
1216 ent.row.setSensitive(sensitive);
Dan Sandler1b718782014-07-18 12:43:45 -04001217 if (ent.autoRedacted && ent.legacy) {
Jorim Jaggiae441282014-08-01 02:45:18 +02001218 // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
1219 // for legacy auto redacted notifications.
Dan Sandler1b718782014-07-18 12:43:45 -04001220 if (showingPublic) {
1221 ent.row.setShowingLegacyBackground(false);
1222 } else {
1223 ent.row.setShowingLegacyBackground(true);
1224 }
1225 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001226 if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
1227 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
1228 ent.row.getStatusBarNotification());
1229 List<ExpandableNotificationRow> orderedChildren =
1230 mTmpChildOrderMap.get(summary);
1231 if (orderedChildren == null) {
1232 orderedChildren = new ArrayList<>();
1233 mTmpChildOrderMap.put(summary, orderedChildren);
1234 }
1235 orderedChildren.add(ent.row);
1236 } else {
1237 toShow.add(ent.row);
1238 }
1239
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001240 }
1241
Selim Cinekb5605e52015-02-20 18:21:41 +01001242 ArrayList<View> toRemove = new ArrayList<>();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001243 for (int i=0; i< mStackScroller.getChildCount(); i++) {
1244 View child = mStackScroller.getChildAt(i);
Jorim Jaggif6411742014-08-05 17:10:43 +00001245 if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001246 toRemove.add(child);
Joe Onorato808182d2010-07-09 18:52:06 -04001247 }
1248 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001249
1250 for (View remove : toRemove) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001251 mStackScroller.removeView(remove);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001252 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001253 for (int i=0; i<toShow.size(); i++) {
1254 View v = toShow.get(i);
1255 if (v.getParent() == null) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001256 mStackScroller.addView(v);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001257 }
1258 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001259
Christoph Studer37fe6932014-05-26 13:10:30 +02001260 // So after all this work notifications still aren't sorted correctly.
1261 // Let's do that now by advancing through toShow and mStackScroller in
1262 // lock-step, making sure mStackScroller matches what we see in toShow.
1263 int j = 0;
1264 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1265 View child = mStackScroller.getChildAt(i);
1266 if (!(child instanceof ExpandableNotificationRow)) {
1267 // We don't care about non-notification views.
1268 continue;
1269 }
1270
Selim Cinekb5605e52015-02-20 18:21:41 +01001271 ExpandableNotificationRow targetChild = toShow.get(j);
1272 if (child != targetChild) {
1273 // Oops, wrong notification at this position. Put the right one
1274 // here and advance both lists.
1275 mStackScroller.changeViewPosition(targetChild, i);
Christoph Studer37fe6932014-05-26 13:10:30 +02001276 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001277 j++;
Selim Cinekb5605e52015-02-20 18:21:41 +01001278
Christoph Studer37fe6932014-05-26 13:10:30 +02001279 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001280
1281 // lets handle the child notifications now
1282 updateNotificationShadeForChildren();
1283
1284 // clear the map again for the next usage
1285 mTmpChildOrderMap.clear();
1286
Christoph Studer37fe6932014-05-26 13:10:30 +02001287 updateRowStates();
Jorim Jaggif6411742014-08-05 17:10:43 +00001288 updateSpeedbump();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001289 updateClearAll();
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001290 updateEmptyShadeView();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001291
Jason Monk3ad242d2014-09-15 11:13:35 -04001292 // Disable QS if device not provisioned.
1293 // If the user switcher is simple then disable QS during setup because
1294 // the user intends to use the lock screen user switcher, QS in not needed.
1295 mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
Adrian Roos2b154a92014-11-17 15:18:39 +01001296 && (mUserSetup || mUserSwitcherController == null
1297 || !mUserSwitcherController.isSimpleUserSwitcher()));
John Spurlockbf370992014-06-17 13:58:31 -04001298 mShadeUpdates.check();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001299 }
1300
Selim Cinekb5605e52015-02-20 18:21:41 +01001301 private void updateNotificationShadeForChildren() {
1302 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
1303 boolean orderChanged = false;
1304 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1305 View view = mStackScroller.getChildAt(i);
1306 if (!(view instanceof ExpandableNotificationRow)) {
1307 // We don't care about non-notification views.
1308 continue;
1309 }
1310
1311 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1312 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1313 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1314
1315 // lets first remove all undesired children
1316 if (children != null) {
1317 toRemove.clear();
1318 for (ExpandableNotificationRow childRow : children) {
1319 if (orderedChildren == null || !orderedChildren.contains(childRow)) {
1320 toRemove.add(childRow);
1321 }
1322 }
1323 for (ExpandableNotificationRow remove : toRemove) {
1324 parent.removeChildNotification(remove);
1325 mStackScroller.notifyGroupChildRemoved(remove);
1326 }
1327 }
1328
1329 // We now add all the children which are not in there already
1330 for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
1331 childIndex++) {
1332 ExpandableNotificationRow childView = orderedChildren.get(childIndex);
1333 if (children == null || !children.contains(childView)) {
1334 parent.addChildNotification(childView, childIndex);
1335 mStackScroller.notifyGroupChildAdded(childView);
1336 }
1337 }
1338
1339 // Finally after removing and adding has been beformed we can apply the order.
1340 orderChanged |= parent.applyChildOrder(orderedChildren);
1341 }
1342 if (orderChanged) {
1343 mStackScroller.generateChildOrderChangedEvent();
1344 }
1345 }
1346
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001347 private boolean packageHasVisibilityOverride(String key) {
1348 return mNotificationData.getVisibilityOverride(key)
1349 != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
1350 }
1351
Dan Sandlereceda3d2014-07-21 15:35:01 -04001352 private void updateClearAll() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001353 boolean showDismissView =
1354 mState != StatusBarState.KEYGUARD &&
1355 mNotificationData.hasActiveClearableNotifications();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001356 mStackScroller.updateDismissView(showDismissView);
1357 }
1358
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001359 private void updateEmptyShadeView() {
1360 boolean showEmptyShade =
1361 mState != StatusBarState.KEYGUARD &&
1362 mNotificationData.getActiveNotifications().size() == 0;
1363 mNotificationPanel.setShadeEmpty(showEmptyShade);
1364 }
1365
Jorim Jaggif6411742014-08-05 17:10:43 +00001366 private void updateSpeedbump() {
1367 int speedbumpIndex = -1;
1368 int currentIndex = 0;
1369 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1370 final int N = activeNotifications.size();
1371 for (int i = 0; i < N; i++) {
1372 Entry entry = activeNotifications.get(i);
Selim Cinekb5605e52015-02-20 18:21:41 +01001373 boolean isChild = !isTopLevelChild(entry);
1374 if (isChild) {
1375 continue;
1376 }
Jorim Jaggif6411742014-08-05 17:10:43 +00001377 if (entry.row.getVisibility() != View.GONE &&
1378 mNotificationData.isAmbient(entry.key)) {
1379 speedbumpIndex = currentIndex;
1380 break;
1381 }
1382 currentIndex++;
1383 }
1384 mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
1385 }
1386
Selim Cinekb5605e52015-02-20 18:21:41 +01001387 public static boolean isTopLevelChild(Entry entry) {
1388 return entry.row.getParent() instanceof NotificationStackScrollLayout;
1389 }
1390
Chris Wren0c8275b2012-05-08 13:36:48 -04001391 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001392 protected void updateNotifications() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001393 mNotificationData.filterAndSort();
1394
Christoph Studer37fe6932014-05-26 13:10:30 +02001395 updateNotificationShade();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001396 mIconController.updateNotificationIcons(mNotificationData);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001397 }
1398
Jorim Jaggi54045422014-07-03 18:30:40 +02001399 @Override
1400 protected void updateRowStates() {
1401 super.updateRowStates();
1402 mNotificationPanel.notifyVisibleChildrenChanged();
1403 }
1404
Chris Wren0c8275b2012-05-08 13:36:48 -04001405 @Override
1406 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001407
Chris Wren6d15a362013-08-20 18:46:29 -04001408 if (SPEW) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001409 final boolean clearable = hasActiveNotifications() &&
1410 mNotificationData.hasActiveClearableNotifications();
1411 Log.d(TAG, "setAreThereNotifications: N=" +
1412 mNotificationData.getActiveNotifications().size() + " any=" +
1413 hasActiveNotifications() + " clearable=" + clearable);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001414 }
1415
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001416 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
Christoph Studerc8db24b2014-07-25 17:50:30 +02001417 final boolean showDot = hasActiveNotifications() && !areLightsOn();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001418 if (showDot != (nlo.getAlpha() == 1.0f)) {
1419 if (showDot) {
1420 nlo.setAlpha(0f);
1421 nlo.setVisibility(View.VISIBLE);
1422 }
1423 nlo.animate()
1424 .alpha(showDot?1:0)
1425 .setDuration(showDot?750:250)
1426 .setInterpolator(new AccelerateInterpolator(2.0f))
1427 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1428 @Override
1429 public void onAnimationEnd(Animator _a) {
1430 nlo.setVisibility(View.GONE);
1431 }
1432 })
1433 .start();
1434 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001435
Dan Sandler16128f42014-05-21 12:48:22 -04001436 findAndUpdateMediaNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001437 }
1438
Dan Sandler16128f42014-05-21 12:48:22 -04001439 public void findAndUpdateMediaNotifications() {
1440 boolean metaDataChanged = false;
1441
1442 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001443 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1444 final int N = activeNotifications.size();
Dan Sandler16128f42014-05-21 12:48:22 -04001445 Entry mediaNotification = null;
1446 MediaController controller = null;
Christoph Studerc8db24b2014-07-25 17:50:30 +02001447 for (int i = 0; i < N; i++) {
1448 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04001449 if (isMediaNotification(entry)) {
1450 final MediaSession.Token token = entry.notification.getNotification().extras
1451 .getParcelable(Notification.EXTRA_MEDIA_SESSION);
1452 if (token != null) {
RoboErik031149c2014-07-25 16:00:52 -07001453 controller = new MediaController(mContext, token);
Dan Sandler16128f42014-05-21 12:48:22 -04001454 if (controller != null) {
1455 // we've got a live one, here
1456 mediaNotification = entry;
1457 }
1458 }
1459 }
1460 }
1461
1462 if (mediaNotification == null) {
1463 // Still nothing? OK, let's just look for live media sessions and see if they match
1464 // one of our notifications. This will catch apps that aren't (yet!) using media
1465 // notifications.
1466
1467 if (mMediaSessionManager != null) {
1468 final List<MediaController> sessions
1469 = mMediaSessionManager.getActiveSessionsForUser(
1470 null,
1471 UserHandle.USER_ALL);
1472
1473 for (MediaController aController : sessions) {
1474 if (aController == null) continue;
1475 final PlaybackState state = aController.getPlaybackState();
1476 if (state == null) continue;
1477 switch (state.getState()) {
1478 case PlaybackState.STATE_STOPPED:
1479 case PlaybackState.STATE_ERROR:
1480 continue;
1481 default:
1482 // now to see if we have one like this
RoboErikaa4e23b2014-07-24 18:35:11 -07001483 final String pkg = aController.getPackageName();
Dan Sandler16128f42014-05-21 12:48:22 -04001484
1485 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001486 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04001487 if (entry.notification.getPackageName().equals(pkg)) {
1488 if (DEBUG_MEDIA) {
1489 Log.v(TAG, "DEBUG_MEDIA: found controller matching "
1490 + entry.notification.getKey());
1491 }
1492 controller = aController;
1493 mediaNotification = entry;
1494 break;
1495 }
1496 }
1497 }
1498 }
1499 }
1500 }
1501
Christoph Studerb5245d82014-09-19 16:54:36 +02001502 if (!sameSessions(mMediaController, controller)) {
Dan Sandler16128f42014-05-21 12:48:22 -04001503 // We have a new media session
1504
1505 if (mMediaController != null) {
1506 // something old was playing
1507 Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
1508 + mMediaController);
RoboErik14f717a2014-09-04 16:08:00 -07001509 mMediaController.unregisterCallback(mMediaListener);
Dan Sandler16128f42014-05-21 12:48:22 -04001510 }
1511 mMediaController = controller;
1512
1513 if (mMediaController != null) {
RoboErik14f717a2014-09-04 16:08:00 -07001514 mMediaController.registerCallback(mMediaListener);
Dan Sandler16128f42014-05-21 12:48:22 -04001515 mMediaMetadata = mMediaController.getMetadata();
1516 if (DEBUG_MEDIA) {
1517 Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: "
1518 + mMediaMetadata);
1519 }
1520
1521 final String notificationKey = mediaNotification == null
1522 ? null
1523 : mediaNotification.notification.getKey();
1524
1525 if (notificationKey == null || !notificationKey.equals(mMediaNotificationKey)) {
1526 // we have a new notification!
1527 if (DEBUG_MEDIA) {
1528 Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
1529 + notificationKey + " controller=" + controller);
1530 }
1531 mMediaNotificationKey = notificationKey;
1532 }
1533 } else {
1534 mMediaMetadata = null;
1535 mMediaNotificationKey = null;
1536 }
1537
1538 metaDataChanged = true;
1539 } else {
1540 // Media session unchanged
1541
1542 if (DEBUG_MEDIA) {
1543 Log.v(TAG, "DEBUG_MEDIA: Continuing media notification: key=" + mMediaNotificationKey);
1544 }
1545 }
1546 }
1547
1548 updateMediaMetaData(metaDataChanged);
1549 }
1550
Christoph Studerb5245d82014-09-19 16:54:36 +02001551 private boolean sameSessions(MediaController a, MediaController b) {
1552 if (a == b) return true;
1553 if (a == null) return false;
1554 return a.controlsSameSession(b);
1555 }
1556
Dan Sandler16128f42014-05-21 12:48:22 -04001557 /**
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001558 * Hide the album artwork that is fading out and release its bitmap.
Dan Sandler16128f42014-05-21 12:48:22 -04001559 */
1560 private Runnable mHideBackdropFront = new Runnable() {
1561 @Override
1562 public void run() {
1563 if (DEBUG_MEDIA) {
1564 Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
1565 }
1566 mBackdropFront.setVisibility(View.INVISIBLE);
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001567 mBackdropFront.animate().cancel();
1568 mBackdropFront.setImageDrawable(null);
Dan Sandler16128f42014-05-21 12:48:22 -04001569 }
1570 };
1571
1572 /**
1573 * Refresh or remove lockscreen artwork from media metadata.
1574 */
1575 public void updateMediaMetaData(boolean metaDataChanged) {
1576 if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) return;
1577
1578 if (mBackdrop == null) return; // called too early
1579
1580 if (DEBUG_MEDIA) {
1581 Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey
1582 + " metadata=" + mMediaMetadata
1583 + " metaDataChanged=" + metaDataChanged
1584 + " state=" + mState);
1585 }
1586
1587 Bitmap artworkBitmap = null;
1588 if (mMediaMetadata != null) {
1589 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
1590 if (artworkBitmap == null) {
1591 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
1592 // might still be null
1593 }
1594 }
1595
1596 final boolean hasArtwork = artworkBitmap != null;
1597
1598 if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
1599 && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
1600 // time to show some art!
1601 if (mBackdrop.getVisibility() != View.VISIBLE) {
1602 mBackdrop.setVisibility(View.VISIBLE);
1603 mBackdrop.animate().alpha(1f);
1604 metaDataChanged = true;
1605 if (DEBUG_MEDIA) {
1606 Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
1607 }
1608 }
1609 if (metaDataChanged) {
1610 if (mBackdropBack.getDrawable() != null) {
Selim Cineka0fad3b2014-09-19 17:20:05 +02001611 Drawable drawable = mBackdropBack.getDrawable();
1612 mBackdropFront.setImageDrawable(drawable);
Jorim Jaggi0e664392014-09-27 01:30:22 +02001613 if (mScrimSrcModeEnabled) {
1614 mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
1615 }
Dan Sandler16128f42014-05-21 12:48:22 -04001616 mBackdropFront.setAlpha(1f);
1617 mBackdropFront.setVisibility(View.VISIBLE);
1618 } else {
1619 mBackdropFront.setVisibility(View.INVISIBLE);
1620 }
1621
1622 if (DEBUG_MEDIA_FAKE_ARTWORK) {
1623 final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
1624 Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
1625 mBackdropBack.setBackgroundColor(0xFFFFFFFF);
1626 mBackdropBack.setImageDrawable(new ColorDrawable(c));
1627 } else {
1628 mBackdropBack.setImageBitmap(artworkBitmap);
1629 }
Jorim Jaggi0e664392014-09-27 01:30:22 +02001630 if (mScrimSrcModeEnabled) {
1631 mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
1632 }
Dan Sandler16128f42014-05-21 12:48:22 -04001633
1634 if (mBackdropFront.getVisibility() == View.VISIBLE) {
1635 if (DEBUG_MEDIA) {
1636 Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
1637 + mBackdropFront.getDrawable()
1638 + " to "
1639 + mBackdropBack.getDrawable());
1640 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001641 mBackdropFront.animate()
Dan Sandler16128f42014-05-21 12:48:22 -04001642 .setDuration(250)
1643 .alpha(0f).withEndAction(mHideBackdropFront);
1644 }
1645 }
1646 } else {
1647 // need to hide the album art, either because we are unlocked or because
1648 // the metadata isn't there to support it
1649 if (mBackdrop.getVisibility() != View.GONE) {
1650 if (DEBUG_MEDIA) {
1651 Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
1652 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001653 mBackdrop.animate()
1654 .alpha(0f)
1655 .setInterpolator(mBackdropInterpolator)
1656 .setDuration(300)
1657 .setStartDelay(0)
1658 .withEndAction(new Runnable() {
1659 @Override
1660 public void run() {
1661 mBackdrop.setVisibility(View.GONE);
1662 mBackdropFront.animate().cancel();
1663 mBackdropBack.animate().cancel();
1664 mHandler.post(mHideBackdropFront);
1665 }
1666 });
1667 if (mKeyguardFadingAway) {
1668 mBackdrop.animate()
1669
1670 // Make it disappear faster, as the focus should be on the activity behind.
1671 .setDuration(mKeyguardFadingAwayDuration / 2)
1672 .setStartDelay(mKeyguardFadingAwayDelay)
1673 .setInterpolator(mLinearInterpolator)
1674 .start();
1675 }
Dan Sandler16128f42014-05-21 12:48:22 -04001676 }
1677 }
1678 }
1679
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001680 private int adjustDisableFlags(int state) {
Selim Cinekbaa23272014-07-08 18:01:07 +02001681 if (!mLaunchTransitionFadingAway
1682 && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001683 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
1684 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
1685 }
1686 return state;
1687 }
1688
Joe Onorato808182d2010-07-09 18:52:06 -04001689 /**
1690 * State is one or more of the DISABLE constants from StatusBarManager.
1691 */
Jorim Jaggi2580a9762014-06-25 03:08:25 +02001692 public void disable(int state, boolean animate) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001693 mDisabledUnmodified = state;
1694 state = adjustDisableFlags(state);
Joe Onorato808182d2010-07-09 18:52:06 -04001695 final int old = mDisabled;
1696 final int diff = state ^ old;
1697 mDisabled = state;
1698
Daniel Sandlere21f2882011-08-18 10:14:59 -04001699 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04001700 Log.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
Daniel Sandlere21f2882011-08-18 10:14:59 -04001701 old, state, diff));
1702 }
1703
Daniel Sandler6da2b762011-09-14 16:04:59 -04001704 StringBuilder flagdbg = new StringBuilder();
1705 flagdbg.append("disable: < ");
1706 flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
1707 flagdbg.append(((diff & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
1708 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
1709 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
1710 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
1711 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001712 flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
1713 flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001714 flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
1715 flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
Daniel Sandlerdba93562011-10-06 16:39:58 -04001716 flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
1717 flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
1718 flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
1719 flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001720 flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
1721 flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001722 flagdbg.append(((state & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
1723 flagdbg.append(((diff & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001724 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04001725 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07001726
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001727 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001728 if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001729 mIconController.hideSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001730 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001731 mIconController.showSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001732 }
1733 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04001734
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001735 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001736 boolean visible = (state & StatusBarManager.DISABLE_CLOCK) == 0;
1737 mIconController.setClockVisibility(visible);
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001738 }
Joe Onorato808182d2010-07-09 18:52:06 -04001739 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1740 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001741 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04001742 }
1743 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001744
Jim Miller5e6af442011-12-02 18:24:26 -08001745 if ((diff & (StatusBarManager.DISABLE_HOME
1746 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001747 | StatusBarManager.DISABLE_BACK
1748 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04001749 // the nav bar will take care of these
Daniel Sandlerd9283b902011-09-14 21:42:00 -04001750 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001751
Daniel Sandlerdba93562011-10-06 16:39:58 -04001752 if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04001753 // close recents if it's visible
Winson Chung1e8d71b2014-05-16 17:05:22 -07001754 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
1755 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001756 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001757 }
1758
Joe Onorato808182d2010-07-09 18:52:06 -04001759 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1760 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001761 mIconController.hideNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04001762 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001763 mIconController.showNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04001764 }
Joe Onorato808182d2010-07-09 18:52:06 -04001765 }
Jason Monkf7019542014-07-31 12:42:25 -04001766
1767 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
1768 mDisableNotificationAlerts =
1769 (state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
1770 mHeadsUpObserver.onChange(true);
1771 }
Joe Onorato808182d2010-07-09 18:52:06 -04001772 }
1773
Michael Jurka7f2668c2012-03-27 07:49:52 -07001774 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07001775 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001776 return new PhoneStatusBar.H();
1777 }
1778
Jorim Jaggi97b63c42014-05-02 23:03:34 +02001779 @Override
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02001780 public void startActivity(Intent intent, boolean dismissShade) {
1781 startActivityDismissingKeyguard(intent, false, dismissShade);
Jorim Jaggi97b63c42014-05-02 23:03:34 +02001782 }
1783
Jorim Jaggib690f0d2014-07-03 23:25:44 +02001784 public void setQsExpanded(boolean expanded) {
1785 mStatusBarWindowManager.setQsExpanded(expanded);
1786 }
1787
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02001788 public boolean isGoingToNotificationShade() {
1789 return mLeaveOpenOnKeyguardHide;
1790 }
1791
Jorim Jaggid692dd02014-08-14 20:57:42 +02001792 public boolean isQsExpanded() {
1793 return mNotificationPanel.isQsExpanded();
1794 }
1795
Selim Cinek29ed3c92014-09-23 20:44:35 +02001796 public boolean isScreenOnComingFromTouch() {
1797 return mScreenOnComingFromTouch;
1798 }
1799
Selim Cinek19c8c702014-08-25 22:09:19 +02001800 public boolean isFalsingThresholdNeeded() {
1801 boolean onKeyguard = getBarState() == StatusBarState.KEYGUARD;
Christoph Studer2231c6e2014-12-19 12:40:13 +01001802 boolean isCurrentlyInsecure = mUnlockMethodCache.isCurrentlyInsecure();
1803 return onKeyguard && (isCurrentlyInsecure || mDozing || mScreenOnComingFromTouch);
Selim Cinek19c8c702014-08-25 22:09:19 +02001804 }
1805
John Spurlock0b99ea92014-10-01 15:32:22 -04001806 public boolean isDozing() {
1807 return mDozing;
1808 }
1809
Christoph Studer2e731b52014-08-22 16:01:51 +02001810 @Override // NotificationData.Environment
1811 public String getCurrentMediaNotificationKey() {
1812 return mMediaNotificationKey;
1813 }
1814
Jorim Jaggi0e664392014-09-27 01:30:22 +02001815 public boolean isScrimSrcModeEnabled() {
1816 return mScrimSrcModeEnabled;
1817 }
1818
Joe Onorato808182d2010-07-09 18:52:06 -04001819 /**
Christoph Studer2231c6e2014-12-19 12:40:13 +01001820 * To be called when there's a state change in StatusBarKeyguardViewManager.
1821 */
1822 public void onKeyguardViewManagerStatesUpdated() {
1823 logStateToEventlog();
1824 }
1825
1826 @Override // UnlockMethodCache.OnUnlockMethodChangedListener
1827 public void onUnlockMethodStateChanged() {
1828 logStateToEventlog();
1829 }
1830
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001831 @Override
1832 public void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly) {
1833 if (exist) {
1834 mStatusBarWindowManager.setHeadsUpShowing(true);
1835 } else {
1836 Runnable endRunnable = new Runnable() {
1837 @Override
1838 public void run() {
1839 if (!mHeadsUpManager.hasPinnedHeadsUp()) {
1840 mStatusBarWindowManager.setHeadsUpShowing(false);
1841 }
1842 }
1843 };
1844 if (changeImmediatly) {
1845 endRunnable.run();
1846 } else {
1847 mStackScroller.performOnAnimationFinished(endRunnable);
1848 }
1849 }
1850 }
1851
1852 @Override
Selim Cinekaac93252015-04-14 20:04:12 -07001853 public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
Selim Cinek1f3f5442015-04-10 17:54:46 -07001854 }
1855
1856 @Override
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001857 public void OnHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
1858 if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
1859 removeNotification(entry.key, mLatestRankingMap);
1860 mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
1861 if (mHeadsUpEntriesToRemoveOnSwitch.isEmpty()) {
1862 mLatestRankingMap = null;
1863 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07001864 } else {
1865 updateNotificationRanking(null);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001866 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07001867
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001868 }
1869
Selim Cinek29fa89b2015-04-17 10:39:11 -07001870 protected void updateHeadsUp(String key, Entry entry, boolean shouldInterrupt,
1871 boolean alertAgain) {
1872 final boolean wasHeadsUp = isHeadsUp(key);
1873 if (wasHeadsUp) {
1874 mHeadsUpManager.updateNotification(entry, alertAgain);
1875 if (!shouldInterrupt) {
1876 // We don't want this to be interrupting anymore, lets remove it
1877 mHeadsUpManager.removeNotification(key);
1878 }
1879 } else if (shouldInterrupt && alertAgain) {
1880 // This notification was updated to be a heads-up, show it!
1881 mHeadsUpManager.showNotification(entry);
1882 }
1883 }
1884
1885 protected void setHeadsUpUser(int newUserId) {
1886 if (mHeadsUpManager != null) {
1887 mHeadsUpManager.setUser(newUserId);
1888 }
1889 }
1890
1891 public boolean isHeadsUp(String key) {
1892 return mHeadsUpManager.isHeadsUp(key);
1893 }
1894
1895 protected boolean isSnoozedPackage(StatusBarNotification sbn) {
1896 return mHeadsUpManager.isSnoozed(sbn.getPackageName());
1897 }
1898
Christoph Studer2231c6e2014-12-19 12:40:13 +01001899 /**
Joe Onorato808182d2010-07-09 18:52:06 -04001900 * All changes to the status bar and notifications funnel through here and are batched.
1901 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07001902 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04001903 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001904 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04001905 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001906 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04001907 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001908 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04001909 case MSG_OPEN_SETTINGS_PANEL:
1910 animateExpandSettingsPanel();
1911 break;
1912 case MSG_CLOSE_PANELS:
1913 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04001914 break;
Jorim Jaggi826730a2014-12-08 21:05:13 +01001915 case MSG_LAUNCH_TRANSITION_TIMEOUT:
1916 onLaunchTransitionTimeout();
1917 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04001918 }
1919 }
1920 }
1921
Chris Wren930ecca2014-11-12 17:43:41 -05001922 @Override
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001923 public void escalateHeadsUp() {
Selim Cineka59ecc32015-04-07 10:51:49 -07001924 TreeSet<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getSortedEntries();
1925 for (HeadsUpManager.HeadsUpEntry entry : entries) {
1926 final StatusBarNotification sbn = entry.entry.notification;
Chris Wrene97f90b2013-08-07 17:39:35 -04001927 final Notification notification = sbn.getNotification();
1928 if (notification.fullScreenIntent != null) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001929 if (DEBUG) {
Chris Wrene97f90b2013-08-07 17:39:35 -04001930 Log.d(TAG, "converting a heads up to fullScreen");
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001931 }
Chris Wrene97f90b2013-08-07 17:39:35 -04001932 try {
Chris Wren223c66b62014-11-10 16:00:09 -05001933 EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
1934 sbn.getKey());
Chris Wrene97f90b2013-08-07 17:39:35 -04001935 notification.fullScreenIntent.send();
1936 } catch (PendingIntent.CanceledException e) {
1937 }
Joe Onorato808182d2010-07-09 18:52:06 -04001938 }
1939 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001940 mHeadsUpManager.releaseAllImmediately();
Joe Onorato808182d2010-07-09 18:52:06 -04001941 }
1942
John Spurlock97642182013-07-29 17:58:39 -04001943 boolean panelsEnabled() {
John Spurlock79ec2a12013-09-11 09:28:49 -04001944 return (mDisabled & StatusBarManager.DISABLE_EXPAND) == 0;
John Spurlock97642182013-07-29 17:58:39 -04001945 }
1946
Jorim Jaggifa505a72014-04-28 20:04:11 +02001947 void makeExpandedVisible(boolean force) {
John Spurlockcd686b52013-06-05 10:13:46 -04001948 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
Jorim Jaggifa505a72014-04-28 20:04:11 +02001949 if (!force && (mExpandedVisible || !panelsEnabled())) {
Joe Onorato808182d2010-07-09 18:52:06 -04001950 return;
1951 }
Jim Millera073e572012-05-23 17:03:27 -07001952
Joe Onorato808182d2010-07-09 18:52:06 -04001953 mExpandedVisible = true;
John Spurlockd5ef5462012-06-13 11:19:51 -04001954 if (mNavigationBarView != null)
1955 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04001956
Daniel Sandlera310af82012-04-24 01:20:13 -04001957 // Expand the window to encompass the full screen in anticipation of the drag.
1958 // 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 +01001959 mStatusBarWindowManager.setStatusBarExpanded(true);
Selim Cineke32010a2014-08-20 23:50:41 +02001960 mStatusBarView.setFocusable(false);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01001961
1962 visibilityChanged(true);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07001963 mWaitingForKeyguardExit = false;
Jorim Jaggi2580a9762014-06-25 03:08:25 +02001964 disable(mDisabledUnmodified, !force /* animate */);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01001965 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
1966 }
1967
Daniel Sandler11cf1782012-09-27 14:03:08 -04001968 public void animateCollapsePanels() {
1969 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001970 }
1971
John Spurlockaf8d6c42014-05-07 17:49:08 -04001972 private final Runnable mAnimateCollapsePanels = new Runnable() {
1973 @Override
1974 public void run() {
1975 animateCollapsePanels();
1976 }
1977 };
1978
1979 public void postAnimateCollapsePanels() {
1980 mHandler.post(mAnimateCollapsePanels);
1981 }
1982
Daniel Sandler11cf1782012-09-27 14:03:08 -04001983 public void animateCollapsePanels(int flags) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07001984 animateCollapsePanels(flags, false /* force */, false /* delayed */,
1985 1.0f /* speedUpFactor */);
Jorim Jaggi34250762014-07-03 23:51:19 +02001986 }
1987
1988 public void animateCollapsePanels(int flags, boolean force) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07001989 animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi27c9b742015-04-09 10:34:49 -07001990 }
1991
1992 public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07001993 animateCollapsePanels(flags, force, delayed, 1.0f /* speedUpFactor */);
1994 }
1995
1996 public void animateCollapsePanels(int flags, boolean force, boolean delayed,
1997 float speedUpFactor) {
Jorim Jaggi34250762014-07-03 23:51:19 +02001998 if (!force &&
1999 (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002000 runPostCollapseRunnables();
Jorim Jaggic1cf1ae2014-05-02 21:19:17 +02002001 return;
2002 }
Joe Onorato808182d2010-07-09 18:52:06 -04002003 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04002004 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04002005 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07002006 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002007 }
2008
Jim Miller9a720f52012-05-30 03:19:43 -07002009 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Winson Chungcdcd4872014-08-05 18:00:13 -07002010 if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
2011 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2012 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
2013 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07002014 }
Jim Miller9a720f52012-05-30 03:19:43 -07002015
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002016 if (mStatusBarWindow != null) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002017 // release focus immediately to kick off focus change transition
2018 mStatusBarWindowManager.setStatusBarFocusable(false);
2019
John Spurlockab847cf2014-01-15 14:13:59 -05002020 mStatusBarWindow.cancelExpandHelper();
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002021 mStatusBarView.collapseAllPanels(true /* animate */, delayed, speedUpFactor);
John Spurlockab847cf2014-01-15 14:13:59 -05002022 }
Joe Onorato808182d2010-07-09 18:52:06 -04002023 }
2024
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002025 private void runPostCollapseRunnables() {
2026 int size = mPostCollapseRunnables.size();
2027 for (int i = 0; i < size; i++) {
2028 mPostCollapseRunnables.get(i).run();
2029 }
2030 mPostCollapseRunnables.clear();
2031 }
2032
John Spurlockaf8d6c42014-05-07 17:49:08 -04002033 Animator mScrollViewAnim, mClearButtonAnim;
Daniel Sandler101784e2012-10-15 13:39:38 -04002034
Daniel Sandler08d05e32012-08-08 16:39:54 -04002035 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002036 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002037 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002038 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04002039 return ;
2040 }
Joe Onorato808182d2010-07-09 18:52:06 -04002041
Daniel Sandler08d05e32012-08-08 16:39:54 -04002042 mNotificationPanel.expand();
Joe Onorato808182d2010-07-09 18:52:06 -04002043
2044 if (false) postStartTracing();
2045 }
2046
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002047 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002048 public void animateExpandSettingsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002049 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002050 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002051 return;
2052 }
2053
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05002054 // Settings are not available in setup
2055 if (!mUserSetup) return;
2056
Jason Monk3c68ca22015-01-30 11:30:29 -05002057 mNotificationPanel.expandWithQs();
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002058
2059 if (false) postStartTracing();
2060 }
2061
2062 public void animateCollapseQuickSettings() {
Jorim Jaggi449981b2014-10-03 14:24:55 -07002063 if (mState == StatusBarState.SHADE) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002064 mStatusBarView.collapseAllPanels(true, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi449981b2014-10-03 14:24:55 -07002065 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002066 }
2067
Daniel Sandler08d05e32012-08-08 16:39:54 -04002068 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04002069 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04002070 + " mExpandedVisible=" + mExpandedVisible);
2071
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002072 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002073 return;
2074 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002075
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04002076 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002077 mStatusBarView.collapseAllPanels(/*animate=*/ false, false /* delayed*/,
2078 1.0f /* speedUpFactor */);
Daniel Sandlered930e52012-07-03 14:31:22 -04002079
Jorim Jaggid7daab72014-05-06 22:22:20 +02002080 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04002081
Joe Onorato808182d2010-07-09 18:52:06 -04002082 mExpandedVisible = false;
John Spurlockd5ef5462012-06-13 11:19:51 -04002083 if (mNavigationBarView != null)
2084 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002085 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04002086
2087 // Shrink the window to the size of the status bar only
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002088 mStatusBarWindowManager.setStatusBarExpanded(false);
Selim Cineke32010a2014-08-20 23:50:41 +02002089 mStatusBarView.setFocusable(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002090
Daniel Sandler469e96e2012-05-04 15:56:19 -04002091 // Close any "App info" popups that might have snuck on-screen
2092 dismissPopups();
2093
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002094 runPostCollapseRunnables();
John Spurlockcfc359a2013-09-05 10:42:03 -04002095 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002096 showBouncer();
Jorim Jaggi2580a9762014-06-25 03:08:25 +02002097 disable(mDisabledUnmodified, true /* animate */);
Jorim Jaggi786afcb2014-09-25 02:41:29 +02002098
2099 // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
2100 // the bouncer appear animation.
2101 if (!mStatusBarKeyguardViewManager.isShowing()) {
2102 WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
2103 }
Joe Onorato808182d2010-07-09 18:52:06 -04002104 }
2105
Daniel Sandlerb17a7262012-10-05 14:32:50 -04002106 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05002107 if (DEBUG_GESTURES) {
2108 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
2109 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
2110 event.getActionMasked(), (int) event.getX(), (int) event.getY(), mDisabled);
2111 }
2112
2113 }
2114
Joe Onorato808182d2010-07-09 18:52:06 -04002115 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04002116 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
John Spurlock804df702012-06-01 15:34:27 -04002117 + mDisabled + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002118 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002119 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04002120 Log.d(TAG, String.format(
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002121 "panel: %s at (%f, %f) mDisabled=0x%08x",
2122 MotionEvent.actionToString(event.getAction()),
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002123 event.getRawX(), event.getRawY(), mDisabled));
2124 }
Joe Onorato808182d2010-07-09 18:52:06 -04002125 }
2126
Daniel Sandler151f00d2012-10-02 22:33:08 -04002127 if (DEBUG_GESTURES) {
2128 mGestureRec.add(event);
2129 }
Daniel Sandler33805342012-07-23 15:45:12 -04002130
John Spurlock686820a2013-09-03 14:44:16 -04002131 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04002132 final boolean upOrCancel =
2133 event.getAction() == MotionEvent.ACTION_UP ||
2134 event.getAction() == MotionEvent.ACTION_CANCEL;
2135 if (upOrCancel && !mExpandedVisible) {
2136 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
2137 } else {
2138 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2139 }
John Spurlock686820a2013-09-03 14:44:16 -04002140 }
Joe Onorato808182d2010-07-09 18:52:06 -04002141 return false;
2142 }
2143
Daniel Sandler08d05e32012-08-08 16:39:54 -04002144 public GestureRecorder getGestureRecorder() {
2145 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07002146 }
2147
John Spurlock56d007b2013-10-28 18:40:56 -04002148 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04002149 if (hints == mNavigationIconHints) return;
2150
2151 mNavigationIconHints = hints;
2152
2153 if (mNavigationBarView != null) {
2154 mNavigationBarView.setNavigationIconHints(hints);
2155 }
John Spurlockd4e65752013-08-28 14:17:09 -04002156 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04002157 }
2158
2159 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04002160 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04002161 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04002162 if (mStatusBarWindow != null
2163 && window == StatusBarManager.WINDOW_STATUS_BAR
2164 && mStatusBarWindowState != state) {
2165 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002166 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
Jorim Jaggi449981b2014-10-03 14:24:55 -07002167 if (!showing && mState == StatusBarState.SHADE) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002168 mStatusBarView.collapseAllPanels(false /* animate */, false /* delayed */,
2169 1.0f /* speedUpFactor */);
John Spurlock97642182013-07-29 17:58:39 -04002170 }
2171 }
2172 if (mNavigationBarView != null
2173 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
2174 && mNavigationBarWindowState != state) {
2175 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002176 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04002177 }
2178 }
2179
John Spurlock97642182013-07-29 17:58:39 -04002180 @Override // CommandQueue
John Spurlockcad57682014-07-26 17:09:56 -04002181 public void buzzBeepBlinked() {
2182 if (mDozeServiceHost != null) {
2183 mDozeServiceHost.fireBuzzBeepBlinked();
2184 }
2185 }
2186
John Spurlockcb566aa2014-08-03 22:58:28 -04002187 @Override
2188 public void notificationLightOff() {
2189 if (mDozeServiceHost != null) {
2190 mDozeServiceHost.fireNotificationLight(false);
2191 }
2192 }
2193
2194 @Override
2195 public void notificationLightPulse(int argb, int onMillis, int offMillis) {
2196 if (mDozeServiceHost != null) {
2197 mDozeServiceHost.fireNotificationLight(true);
2198 }
2199 }
2200
John Spurlockcad57682014-07-26 17:09:56 -04002201 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002202 public void setSystemUiVisibility(int vis, int mask) {
2203 final int oldVal = mSystemUiVisibility;
2204 final int newVal = (oldVal&~mask) | (vis&mask);
2205 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04002206 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04002207 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
2208 Integer.toHexString(vis), Integer.toHexString(mask),
2209 Integer.toHexString(oldVal), Integer.toHexString(newVal),
2210 Integer.toHexString(diff)));
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002211 if (diff != 0) {
Winson Chung9214eff2014-06-12 13:59:25 -07002212 // we never set the recents bit via this method, so save the prior state to prevent
2213 // clobbering the bit below
2214 final boolean wasRecentsVisible = (mSystemUiVisibility & View.RECENT_APPS_VISIBLE) > 0;
2215
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002216 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04002217
John Spurlocke1f366f2013-08-05 12:22:40 -04002218 // update low profile
2219 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
2220 final boolean lightsOut = (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002221 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002222 animateCollapsePanels();
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002223 }
Jim Millera073e572012-05-23 17:03:27 -07002224
John Spurlock7edfbca2013-09-14 11:58:55 -04002225 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04002226 }
2227
John Spurlocke1f366f2013-08-05 12:22:40 -04002228 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002229 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04002230 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04002231
2232 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002233 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04002234 oldVal, newVal, mNavigationBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04002235 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT);
John Spurlockd4e65752013-08-28 14:17:09 -04002236 final boolean sbModeChanged = sbMode != -1;
2237 final boolean nbModeChanged = nbMode != -1;
2238 boolean checkBarModes = false;
2239 if (sbModeChanged && sbMode != mStatusBarMode) {
2240 mStatusBarMode = sbMode;
2241 checkBarModes = true;
2242 }
2243 if (nbModeChanged && nbMode != mNavigationBarMode) {
2244 mNavigationBarMode = nbMode;
2245 checkBarModes = true;
2246 }
2247 if (checkBarModes) {
2248 checkBarModes();
2249 }
2250 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002251 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05002252 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04002253 scheduleAutohide();
2254 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04002255 cancelAutohide();
2256 }
2257 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002258
John Spurlock5b9145b2013-08-20 15:13:47 -04002259 // ready to unhide
2260 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
2261 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
2262 }
2263 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
2264 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
2265 }
2266
Adrian Roos75fa3852015-01-27 20:21:44 +01002267 if ((diff & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0 || sbModeChanged) {
Adrian Roos761c1562015-02-04 14:35:23 +01002268 boolean isTransparentBar = (mStatusBarMode == MODE_TRANSPARENT
2269 || mStatusBarMode == MODE_LIGHTS_OUT_TRANSPARENT);
2270 boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave();
Adrian Roos75fa3852015-01-27 20:21:44 +01002271 boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
2272
Jorim Jaggi5443cc52015-03-20 14:39:24 -07002273 mIconController.setIconsDark(allowLight && light);
Adrian Roos75fa3852015-01-27 20:21:44 +01002274 }
Winson Chung9214eff2014-06-12 13:59:25 -07002275 // restore the recents bit
2276 if (wasRecentsVisible) {
2277 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
2278 }
2279
John Spurlocke1f366f2013-08-05 12:22:40 -04002280 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04002281 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04002282 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002283 }
2284
John Spurlockd4e65752013-08-28 14:17:09 -04002285 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
John Spurlockbd957402013-10-03 11:38:39 -04002286 int transientFlag, int translucentFlag) {
2287 final int oldMode = barMode(oldVis, transientFlag, translucentFlag);
2288 final int newMode = barMode(newVis, transientFlag, translucentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04002289 if (oldMode == newMode) {
2290 return -1; // no mode change
2291 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002292 return newMode;
2293 }
2294
John Spurlockbd957402013-10-03 11:38:39 -04002295 private int barMode(int vis, int transientFlag, int translucentFlag) {
Adrian Roosc0f0a742014-10-28 16:39:56 +01002296 int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_TRANSPARENT;
John Spurlock89835dd2013-08-16 15:06:51 -04002297 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04002298 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
Adrian Roosc0f0a742014-10-28 16:39:56 +01002299 : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
Adrian Roosea562512014-05-05 13:33:03 +02002300 : (vis & View.SYSTEM_UI_TRANSPARENT) != 0 ? MODE_TRANSPARENT
John Spurlock7edfbca2013-09-14 11:58:55 -04002301 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04002302 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04002303 }
2304
John Spurlockd4e65752013-08-28 14:17:09 -04002305 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04002306 if (mDemoMode) return;
Jorim Jaggi28d22d02014-05-10 03:37:04 +02002307 checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions());
John Spurlockd4e65752013-08-28 14:17:09 -04002308 if (mNavigationBarView != null) {
2309 checkBarMode(mNavigationBarMode,
2310 mNavigationBarWindowState, mNavigationBarView.getBarTransitions());
2311 }
2312 }
2313
2314 private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002315 final boolean powerSave = mBatteryController.isPowerSave();
2316 final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN
2317 && !powerSave;
John Spurlock1bb480a2014-08-02 17:12:43 -04002318 if (powerSave && getBarState() == StatusBarState.SHADE) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002319 mode = MODE_WARNING;
2320 }
John Spurlockc68d5772013-10-08 11:47:58 -04002321 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04002322 }
2323
John Spurlock42197262013-10-21 09:32:25 -04002324 private void finishBarAnimations() {
2325 mStatusBarView.getBarTransitions().finishAnimations();
2326 if (mNavigationBarView != null) {
2327 mNavigationBarView.getBarTransitions().finishAnimations();
2328 }
2329 }
2330
John Spurlockd4e65752013-08-28 14:17:09 -04002331 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04002332 @Override
2333 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04002334 checkBarModes();
John Spurlock0ff62e02014-07-22 16:15:08 -04002335 }
2336 };
John Spurlock5b9145b2013-08-20 15:13:47 -04002337
John Spurlockad3e6cb2013-04-30 08:47:43 -04002338 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04002339 public void setInteracting(int barWindow, boolean interacting) {
John Spurlock7fbf5732014-11-18 11:40:22 -05002340 final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
John Spurlockcfc359a2013-09-05 10:42:03 -04002341 mInteractingWindows = interacting
2342 ? (mInteractingWindows | barWindow)
2343 : (mInteractingWindows & ~barWindow);
2344 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04002345 suspendAutohide();
2346 } else {
2347 resumeSuspendedAutohide();
2348 }
John Spurlock7fbf5732014-11-18 11:40:22 -05002349 // manually dismiss the volume panel when interacting with the nav bar
2350 if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
2351 if (mVolumeComponent != null) {
2352 mVolumeComponent.dismissNow();
2353 }
2354 }
John Spurlockd4e65752013-08-28 14:17:09 -04002355 checkBarModes();
2356 }
2357
2358 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04002359 if (mAutohideSuspended) {
2360 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04002361 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04002362 }
2363 }
2364
John Spurlockd4e65752013-08-28 14:17:09 -04002365 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04002366 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04002367 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04002368 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04002369 }
2370
2371 private void cancelAutohide() {
2372 mAutohideSuspended = false;
2373 mHandler.removeCallbacks(mAutohide);
2374 }
2375
2376 private void scheduleAutohide() {
2377 cancelAutohide();
2378 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
2379 }
2380
John Spurlock9deaa282013-07-25 13:03:47 -04002381 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002382 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04002383 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
2384 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
2385 ) {
2386 userAutohide();
2387 }
2388 }
2389
2390 private void userAutohide() {
2391 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04002392 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04002393 }
2394
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002395 private boolean areLightsOn() {
2396 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
2397 }
Jim Millera073e572012-05-23 17:03:27 -07002398
Daniel Sandler60ee2562011-07-22 12:34:33 -04002399 public void setLightsOn(boolean on) {
2400 Log.v(TAG, "setLightsOn(" + on + ")");
2401 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002402 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002403 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002404 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002405 }
2406 }
2407
John Spurlock32beb2c2013-03-11 10:16:47 -04002408 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002409 try {
John Spurlock32beb2c2013-03-11 10:16:47 -04002410 mWindowManagerService.statusBarVisibilityChanged(vis);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002411 } catch (RemoteException ex) {
2412 }
Joe Onorato93056472010-09-10 10:30:46 -04002413 }
2414
Daniel Sandler5c8da942011-06-28 00:29:04 -04002415 public void topAppWindowChanged(boolean showMenu) {
2416 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002417 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04002418 }
2419 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04002420 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04002421 }
2422
2423 // See above re: lights-out policy for legacy apps.
2424 if (showMenu) setLightsOn(true);
2425 }
2426
Daniel Sandler328310c2011-09-23 15:56:52 -04002427 @Override
Jason Monkb605fec2014-05-02 17:04:10 -04002428 public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
2429 boolean showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002430 boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
2431 int flags = mNavigationIconHints;
2432 if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
2433 flags |= NAVIGATION_HINT_BACK_ALT;
2434 } else {
2435 flags &= ~NAVIGATION_HINT_BACK_ALT;
2436 }
Jason Monkb605fec2014-05-02 17:04:10 -04002437 if (showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002438 flags |= NAVIGATION_HINT_IME_SHOWN;
2439 } else {
2440 flags &= ~NAVIGATION_HINT_IME_SHOWN;
2441 }
Daniel Sandler328310c2011-09-23 15:56:52 -04002442
Jason Monkf1ff2092014-04-29 16:50:53 -04002443 setNavigationIconHints(flags);
Daniel Sandler328310c2011-09-23 15:56:52 -04002444 }
2445
Daniel Sandler48852952011-12-01 14:34:23 -05002446 public static String viewInfo(View v) {
2447 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
2448 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04002449 }
2450
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002451 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04002452 synchronized (mQueueLock) {
2453 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002454 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04002455 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04002456 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04002457 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002458 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002459 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
2460 + " scroll " + mStackScroller.getScrollX()
2461 + "," + mStackScroller.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04002462 }
Joe Onorato808182d2010-07-09 18:52:06 -04002463
John Spurlockcfc359a2013-09-05 10:42:03 -04002464 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04002465 pw.print(" mStatusBarWindowState=");
2466 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002467 pw.print(" mStatusBarMode=");
2468 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlockbf370992014-06-17 13:58:31 -04002469 pw.print(" mDozing="); pw.println(mDozing);
John Spurlocke677d712014-02-13 12:52:19 -05002470 pw.print(" mZenMode=");
2471 pw.println(Settings.Global.zenModeToString(mZenMode));
Chris Wren3b6745b2014-03-07 14:34:35 -05002472 pw.print(" mUseHeadsUp=");
2473 pw.println(mUseHeadsUp);
John Spurlock0ec64c62013-08-26 15:37:58 -04002474 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
2475 if (mNavigationBarView != null) {
2476 pw.print(" mNavigationBarWindowState=");
2477 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002478 pw.print(" mNavigationBarMode=");
2479 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002480 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
2481 }
2482
Daniel Sandler48852952011-12-01 14:34:23 -05002483 pw.print(" mNavigationBarView=");
2484 if (mNavigationBarView == null) {
2485 pw.println("null");
2486 } else {
2487 mNavigationBarView.dump(fd, pw, args);
2488 }
2489
Dan Sandler16128f42014-05-21 12:48:22 -04002490 pw.print(" mMediaSessionManager=");
2491 pw.println(mMediaSessionManager);
2492 pw.print(" mMediaNotificationKey=");
2493 pw.println(mMediaNotificationKey);
2494 pw.print(" mMediaController=");
2495 pw.print(mMediaController);
2496 if (mMediaController != null) {
2497 pw.print(" state=" + mMediaController.getPlaybackState());
2498 }
2499 pw.println();
2500 pw.print(" mMediaMetadata=");
2501 pw.print(mMediaMetadata);
2502 if (mMediaMetadata != null) {
RoboErik75847b92014-07-29 13:10:17 -07002503 pw.print(" title=" + mMediaMetadata.getText(MediaMetadata.METADATA_KEY_TITLE));
Dan Sandler16128f42014-05-21 12:48:22 -04002504 }
2505 pw.println();
2506
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002507 pw.println(" Panels: ");
2508 if (mNotificationPanel != null) {
2509 pw.println(" mNotificationPanel=" +
2510 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
2511 pw.print (" ");
2512 mNotificationPanel.dump(fd, pw, args);
2513 }
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002514
John Spurlock813552c2014-09-19 08:30:21 -04002515 DozeLog.dump(pw);
2516
Daniel Sandler7579bca2011-08-18 15:47:26 -04002517 if (DUMPTRUCK) {
2518 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002519 mNotificationData.dump(pw, " ");
Daniel Sandler7579bca2011-08-18 15:47:26 -04002520 }
2521
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002522 mIconController.dump(pw);
Jim Miller5e6af442011-12-02 18:24:26 -08002523
Daniel Sandler89d97132011-09-08 15:31:57 -04002524 if (false) {
2525 pw.println("see the logcat for a dump of the views we have created.");
2526 // must happen on ui thread
2527 mHandler.post(new Runnable() {
2528 public void run() {
2529 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04002530 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04002531 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002532 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002533 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002534 }
2535 });
2536 }
Joe Onorato808182d2010-07-09 18:52:06 -04002537 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002538
Daniel Sandler151f00d2012-10-02 22:33:08 -04002539 if (DEBUG_GESTURES) {
2540 pw.print(" status bar gestures: ");
2541 mGestureRec.dump(fd, pw, args);
2542 }
Daniel Sandler33805342012-07-23 15:45:12 -04002543
John Spurlock486b78e2014-07-07 08:37:56 -04002544 if (mNetworkController != null) {
2545 mNetworkController.dump(fd, pw, args);
2546 }
2547 if (mBluetoothController != null) {
2548 mBluetoothController.dump(fd, pw, args);
2549 }
John Spurlock1e6eb172014-07-13 11:59:50 -04002550 if (mCastController != null) {
2551 mCastController.dump(fd, pw, args);
2552 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +02002553 if (mUserSwitcherController != null) {
2554 mUserSwitcherController.dump(fd, pw, args);
2555 }
John Spurlock0ff62e02014-07-22 16:15:08 -04002556 if (mBatteryController != null) {
2557 mBatteryController.dump(fd, pw, args);
2558 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02002559 if (mNextAlarmController != null) {
2560 mNextAlarmController.dump(fd, pw, args);
2561 }
Jason Monk3d5f5512014-07-25 11:17:28 -04002562 if (mSecurityController != null) {
2563 mSecurityController.dump(fd, pw, args);
2564 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002565 if (mHeadsUpManager != null) {
2566 mHeadsUpManager.dump(fd, pw, args);
Chris Wren428c6b62014-12-05 16:07:06 -05002567 } else {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002568 pw.println(" mHeadsUpManager: null");
Chris Wren428c6b62014-12-05 16:07:06 -05002569 }
2570
John Spurlock7bbb9f62014-10-21 12:15:28 -04002571 pw.println("SharedPreferences:");
Andrew Flynn82862572015-04-01 14:22:37 -04002572 for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
John Spurlock7bbb9f62014-10-21 12:15:28 -04002573 pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
2574 }
Joe Onorato808182d2010-07-09 18:52:06 -04002575 }
2576
Chris Wren3b6745b2014-03-07 14:34:35 -05002577 private String hunStateToString(Entry entry) {
2578 if (entry == null) return "null";
2579 if (entry.notification == null) return "corrupt";
2580 return entry.notification.getPackageName();
2581 }
2582
John Spurlock0ec64c62013-08-26 15:37:58 -04002583 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
2584 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
2585 pw.println(BarTransitions.modeToString(transitions.getMode()));
2586 }
2587
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002588 @Override
2589 public void createAndAddWindows() {
2590 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04002591 }
Jim Millere898ac52012-04-06 17:10:57 -07002592
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002593 private void addStatusBarWindow() {
Daniel Sandlera310af82012-04-24 01:20:13 -04002594 makeStatusBarView();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002595 mStatusBarWindowManager = new StatusBarWindowManager(mContext);
2596 mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
Joe Onorato808182d2010-07-09 18:52:06 -04002597 }
2598
Daniel Sandler747a9e92012-08-10 16:39:19 -04002599 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002600 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04002601 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002602 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04002603 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04002604 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04002605 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2606 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002607 }
2608
Christoph Studerb0183992014-12-22 21:02:26 +01002609 float getDisplayDensity() {
2610 return mDisplayMetrics.density;
2611 }
2612
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002613 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002614 final boolean dismissShade) {
Daniel Sandler3679bf52012-10-16 21:30:28 -04002615 if (onlyProvisioned && !isDeviceProvisioned()) return;
Adrian Roos4314f6d2014-05-28 14:10:27 +02002616
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002617 final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
2618 mContext, intent, mCurrentUserId);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02002619 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Adrian Roos4314f6d2014-05-28 14:10:27 +02002620 dismissKeyguardThenExecute(new OnDismissAction() {
2621 @Override
2622 public boolean onDismiss() {
Selim Cinekbaa23272014-07-08 18:01:07 +02002623 AsyncTask.execute(new Runnable() {
2624 public void run() {
2625 try {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002626 if (keyguardShowing && !afterKeyguardGone) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002627 ActivityManagerNative.getDefault()
2628 .keyguardWaitingForActivityDrawn();
2629 }
Selim Cinekbaa23272014-07-08 18:01:07 +02002630 intent.setFlags(
2631 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2632 mContext.startActivityAsUser(
2633 intent, new UserHandle(UserHandle.USER_CURRENT));
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002634 overrideActivityPendingAppTransition(
2635 keyguardShowing && !afterKeyguardGone);
Selim Cinekbaa23272014-07-08 18:01:07 +02002636 } catch (RemoteException e) {
2637 }
2638 }
2639 });
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002640 if (dismissShade) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002641 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
2642 true /* delayed*/);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002643 }
2644 return true;
Adrian Roos4314f6d2014-05-28 14:10:27 +02002645 }
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002646 }, afterKeyguardGone);
Daniel Sandler3679bf52012-10-16 21:30:28 -04002647 }
2648
Joe Onorato808182d2010-07-09 18:52:06 -04002649 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2650 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04002651 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04002652 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04002653 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Kenny Guy44fc65f2014-11-28 22:18:14 +00002654 if (isCurrentProfile(getSendingUserId())) {
2655 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
2656 String reason = intent.getStringExtra("reason");
2657 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
2658 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
2659 }
2660 animateCollapsePanels(flags);
Michael Jurka3b1fc472011-06-13 10:54:40 -07002661 }
Joe Onorato808182d2010-07-09 18:52:06 -04002662 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002663 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002664 mScreenOn = false;
John Spurlock1bbd49d2012-10-19 11:09:32 -04002665 notifyNavigationBarScreenOn(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002666 notifyHeadsUpScreenOff();
John Spurlock42197262013-10-21 09:32:25 -04002667 finishBarAnimations();
Selim Cinekccd14fb2014-08-12 18:53:24 +02002668 resetUserExpandedStates();
Daniel Sandlered930e52012-07-03 14:31:22 -04002669 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002670 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlocke631b412013-09-18 16:33:57 -04002671 mScreenOn = true;
John Spurlock1bbd49d2012-10-19 11:09:32 -04002672 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002673 }
John Spurlock3c875662013-08-31 15:07:25 -04002674 else if (ACTION_DEMO.equals(action)) {
2675 Bundle bundle = intent.getExtras();
2676 if (bundle != null) {
2677 String command = bundle.getString("command", "").trim().toLowerCase();
2678 if (command.length() > 0) {
2679 try {
2680 dispatchDemoCommand(command, bundle);
2681 } catch (Throwable t) {
2682 Log.w(TAG, "Error running demo command, intent=" + intent, t);
2683 }
2684 }
2685 }
Dan Sandler16128f42014-05-21 12:48:22 -04002686 } else if ("fake_artwork".equals(action)) {
2687 if (DEBUG_MEDIA_FAKE_ARTWORK) {
2688 updateMediaMetaData(true);
2689 }
John Spurlock3c875662013-08-31 15:07:25 -04002690 }
Joe Onorato808182d2010-07-09 18:52:06 -04002691 }
2692 };
2693
Selim Cinekccd14fb2014-08-12 18:53:24 +02002694 private void resetUserExpandedStates() {
2695 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
2696 final int notificationCount = activeNotifications.size();
2697 for (int i = 0; i < notificationCount; i++) {
2698 NotificationData.Entry entry = activeNotifications.get(i);
2699 if (entry.row != null) {
2700 entry.row.resetUserExpansion();
2701 }
2702 }
2703 }
2704
Adrian Roos7d7090d2014-05-21 13:10:23 +02002705 @Override
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002706 protected void dismissKeyguardThenExecute(final OnDismissAction action,
2707 boolean afterKeyguardGone) {
Adrian Roos7d7090d2014-05-21 13:10:23 +02002708 if (mStatusBarKeyguardViewManager.isShowing()) {
Jorim Jaggid6f440e02014-11-10 19:27:54 +01002709 mStatusBarKeyguardViewManager.dismissWithAction(action, afterKeyguardGone);
Adrian Roos7d7090d2014-05-21 13:10:23 +02002710 } else {
2711 action.onDismiss();
2712 }
2713 }
2714
Daniel Sandler777dcde2013-09-30 10:21:45 -04002715 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
2716 @Override
2717 protected void onConfigurationChanged(Configuration newConfig) {
2718 super.onConfigurationChanged(newConfig); // calls refreshLayout
2719
2720 if (DEBUG) {
2721 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
2722 }
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002723 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04002724
2725 updateResources();
2726 repositionNavigationBar();
Daniel Sandler777dcde2013-09-30 10:21:45 -04002727 updateShowSearchHoldoff();
Jorim Jaggif6411742014-08-05 17:10:43 +00002728 updateRowStates();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002729 mIconController.updateResources();
Jason Monk18f99d92014-09-11 13:36:42 -04002730 mScreenPinningRequest.onConfigurationChanged();
Daniel Sandler777dcde2013-09-30 10:21:45 -04002731 }
2732
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002733 @Override
2734 public void userSwitched(int newUserId) {
Chris Wrena6d4fb62014-11-20 14:46:23 -05002735 super.userSwitched(newUserId);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002736 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002737 animateCollapsePanels();
Adrian Roos31b844b2014-11-21 13:55:09 +01002738 updatePublicMode();
Christoph Studer37fe6932014-05-26 13:10:30 +02002739 updateNotifications();
John Spurlock919adac2012-10-02 16:41:12 -04002740 resetUserSetupObserver();
John Spurlock89f060a2014-07-16 21:03:15 -04002741 setControllerUsers();
2742 }
2743
2744 private void setControllerUsers() {
2745 if (mZenModeController != null) {
2746 mZenModeController.setUserId(mCurrentUserId);
2747 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002748 }
John Spurlock919adac2012-10-02 16:41:12 -04002749
2750 private void resetUserSetupObserver() {
2751 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
2752 mUserSetupObserver.onChange(false);
2753 mContext.getContentResolver().registerContentObserver(
2754 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002755 mUserSetupObserver, mCurrentUserId);
John Spurlock919adac2012-10-02 16:41:12 -04002756 }
2757
Joe Onorato808182d2010-07-09 18:52:06 -04002758 /**
2759 * Reload some of our resources when the configuration changes.
2760 *
2761 * We don't reload everything when the configuration changes -- we probably
2762 * should, but getting that smooth is tough. Someday we'll fix that. In the
2763 * meantime, just update the things that we know change.
2764 */
2765 void updateResources() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04002766 // Update the quick setting tiles
John Spurlock7e6809a2014-08-06 16:03:14 -04002767 if (mQSPanel != null) {
2768 mQSPanel.updateResources();
2769 }
Winson Chungd63c59782012-09-05 17:34:41 -07002770
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002771 loadDimens();
John Spurlock7e6809a2014-08-06 16:03:14 -04002772
2773 if (mNotificationPanel != null) {
2774 mNotificationPanel.updateResources();
2775 }
Adrian Roos5fd872e2014-08-12 17:28:58 +02002776 if (mBrightnessMirrorController != null) {
2777 mBrightnessMirrorController.updateResources();
2778 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002779 }
Jim Miller5e6af442011-12-02 18:24:26 -08002780
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04002781 protected void loadDimens() {
2782 final Resources res = mContext.getResources();
2783
2784 mNaturalBarHeight = res.getDimensionPixelSize(
2785 com.android.internal.R.dimen.status_bar_height);
2786
Joe Onorato808182d2010-07-09 18:52:06 -04002787 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
2788
Jorim Jaggife40f7d2014-04-28 15:20:04 +02002789 mRowMinHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
2790 mRowMaxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
Chris Wren51c75102013-07-16 20:49:17 -04002791
Jorim Jaggid4a57442014-04-10 02:45:55 +02002792 mKeyguardMaxNotificationCount = res.getInteger(R.integer.keyguard_max_notification_count);
2793
John Spurlock7e6809a2014-08-06 16:03:14 -04002794 if (DEBUG) Log.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04002795 }
2796
Christoph Studer92b389d2014-04-01 18:44:40 +02002797 // Visibility reporting
2798
2799 @Override
Christoph Studere8e28652014-10-29 17:27:53 +01002800 protected void handleVisibleToUserChanged(boolean visibleToUser) {
2801 if (visibleToUser) {
2802 super.handleVisibleToUserChanged(visibleToUser);
2803 startNotificationLogging();
Christoph Studer92b389d2014-04-01 18:44:40 +02002804 } else {
Christoph Studer037e34c2014-04-30 20:06:04 +02002805 stopNotificationLogging();
Christoph Studere8e28652014-10-29 17:27:53 +01002806 super.handleVisibleToUserChanged(visibleToUser);
Christoph Studer92b389d2014-04-01 18:44:40 +02002807 }
Christoph Studer92b389d2014-04-01 18:44:40 +02002808 }
2809
Christoph Studer037e34c2014-04-30 20:06:04 +02002810 private void stopNotificationLogging() {
2811 // Report all notifications as invisible and turn down the
2812 // reporter.
2813 if (!mCurrentlyVisibleNotifications.isEmpty()) {
2814 logNotificationVisibilityChanges(
2815 Collections.<String>emptyList(), mCurrentlyVisibleNotifications);
2816 mCurrentlyVisibleNotifications.clear();
2817 }
2818 mHandler.removeCallbacks(mVisibilityReporter);
2819 mStackScroller.setChildLocationsChangedListener(null);
2820 }
2821
Christoph Studere8e28652014-10-29 17:27:53 +01002822 private void startNotificationLogging() {
2823 mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
2824 // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
2825 // cause the scroller to emit child location events. Hence generate
2826 // one ourselves to guarantee that we're reporting visible
2827 // notifications.
2828 // (Note that in cases where the scroller does emit events, this
2829 // additional event doesn't break anything.)
2830 mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
Christoph Studer037e34c2014-04-30 20:06:04 +02002831 }
2832
Christoph Studer92b389d2014-04-01 18:44:40 +02002833 private void logNotificationVisibilityChanges(
2834 Collection<String> newlyVisible, Collection<String> noLongerVisible) {
2835 if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
2836 return;
2837 }
Christoph Studer92b389d2014-04-01 18:44:40 +02002838 String[] newlyVisibleAr = newlyVisible.toArray(new String[newlyVisible.size()]);
2839 String[] noLongerVisibleAr = noLongerVisible.toArray(new String[noLongerVisible.size()]);
2840 try {
2841 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
2842 } catch (RemoteException e) {
2843 // Ignore.
2844 }
2845 }
2846
Christoph Studer2231c6e2014-12-19 12:40:13 +01002847 // State logging
2848
2849 private void logStateToEventlog() {
2850 boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
2851 boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
2852 boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
2853 boolean isSecure = mUnlockMethodCache.isMethodSecure();
2854 boolean isCurrentlyInsecure = mUnlockMethodCache.isCurrentlyInsecure();
2855 int stateFingerprint = getLoggingFingerprint(mState,
2856 isShowing,
2857 isOccluded,
2858 isBouncerShowing,
2859 isSecure,
2860 isCurrentlyInsecure);
2861 if (stateFingerprint != mLastLoggedStateFingerprint) {
2862 EventLogTags.writeSysuiStatusBarState(mState,
2863 isShowing ? 1 : 0,
2864 isOccluded ? 1 : 0,
2865 isBouncerShowing ? 1 : 0,
2866 isSecure ? 1 : 0,
2867 isCurrentlyInsecure ? 1 : 0);
2868 mLastLoggedStateFingerprint = stateFingerprint;
2869 }
2870 }
2871
2872 /**
2873 * Returns a fingerprint of fields logged to eventlog
2874 */
2875 private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
2876 boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
2877 boolean currentlyInsecure) {
2878 // Reserve 8 bits for statusBarState. We'll never go higher than
2879 // that, right? Riiiight.
2880 return (statusBarState & 0xFF)
2881 | ((keyguardShowing ? 1 : 0) << 8)
2882 | ((keyguardOccluded ? 1 : 0) << 9)
2883 | ((bouncerShowing ? 1 : 0) << 10)
2884 | ((secure ? 1 : 0) << 11)
2885 | ((currentlyInsecure ? 1 : 0) << 12);
2886 }
2887
Joe Onorato808182d2010-07-09 18:52:06 -04002888 //
2889 // tracing
2890 //
2891
2892 void postStartTracing() {
2893 mHandler.postDelayed(mStartTracing, 3000);
2894 }
2895
2896 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002897 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
2898 Context.VIBRATOR_SERVICE);
John Spurlock7b414672014-07-18 13:02:39 -04002899 vib.vibrate(250, VIBRATION_ATTRIBUTES);
Joe Onorato808182d2010-07-09 18:52:06 -04002900 }
2901
2902 Runnable mStartTracing = new Runnable() {
2903 public void run() {
2904 vibrate();
2905 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04002906 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002907 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2908 mHandler.postDelayed(mStopTracing, 10000);
2909 }
2910 };
2911
2912 Runnable mStopTracing = new Runnable() {
2913 public void run() {
2914 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04002915 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04002916 vibrate();
2917 }
2918 };
Chris Wren0c8275b2012-05-08 13:36:48 -04002919
2920 @Override
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07002921 public boolean shouldDisableNavbarGestures() {
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002922 return !isDeviceProvisioned()
2923 || mExpandedVisible
2924 || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07002925 }
Joe Onorato808182d2010-07-09 18:52:06 -04002926
John Spurlockd47a3f32014-05-18 19:14:14 -04002927 public void postStartSettingsActivity(final Intent intent, int delay) {
2928 mHandler.postDelayed(new Runnable() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04002929 @Override
2930 public void run() {
2931 handleStartSettingsActivity(intent, true /*onlyProvisioned*/);
2932 }
John Spurlockd47a3f32014-05-18 19:14:14 -04002933 }, delay);
John Spurlockaf8d6c42014-05-07 17:49:08 -04002934 }
2935
2936 private void handleStartSettingsActivity(Intent intent, boolean onlyProvisioned) {
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002937 startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
John Spurlockde547002014-02-28 17:50:39 -05002938 }
2939
Romain Guy648342f2012-05-25 10:44:45 -07002940 private static class FastColorDrawable extends Drawable {
2941 private final int mColor;
2942
2943 public FastColorDrawable(int color) {
2944 mColor = 0xff000000 | color;
2945 }
2946
2947 @Override
2948 public void draw(Canvas canvas) {
2949 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
2950 }
2951
2952 @Override
2953 public void setAlpha(int alpha) {
2954 }
2955
2956 @Override
Chris Craikbd3bfc52015-03-02 10:43:29 -08002957 public void setColorFilter(ColorFilter colorFilter) {
Romain Guy648342f2012-05-25 10:44:45 -07002958 }
2959
2960 @Override
2961 public int getOpacity() {
2962 return PixelFormat.OPAQUE;
2963 }
2964
2965 @Override
2966 public void setBounds(int left, int top, int right, int bottom) {
2967 }
2968
2969 @Override
2970 public void setBounds(Rect bounds) {
2971 }
2972 }
John Spurlock5c454122013-06-17 07:35:46 -04002973
2974 @Override
2975 public void destroy() {
2976 super.destroy();
2977 if (mStatusBarWindow != null) {
2978 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05002979 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04002980 }
2981 if (mNavigationBarView != null) {
2982 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05002983 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04002984 }
Jason Monk4ae97d32014-12-17 10:14:33 -05002985 if (mHandlerThread != null) {
2986 mHandlerThread.quitSafely();
2987 mHandlerThread = null;
2988 }
John Spurlock5c454122013-06-17 07:35:46 -04002989 mContext.unregisterReceiver(mBroadcastReceiver);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07002990 mAssistGestureManager.destroy();
John Spurlock5c454122013-06-17 07:35:46 -04002991 }
John Spurlock3c875662013-08-31 15:07:25 -04002992
2993 private boolean mDemoModeAllowed;
2994 private boolean mDemoMode;
John Spurlock3c875662013-08-31 15:07:25 -04002995
2996 @Override
2997 public void dispatchDemoCommand(String command, Bundle args) {
2998 if (!mDemoModeAllowed) {
2999 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
3000 "sysui_demo_allowed", 0) != 0;
3001 }
3002 if (!mDemoModeAllowed) return;
3003 if (command.equals(COMMAND_ENTER)) {
3004 mDemoMode = true;
3005 } else if (command.equals(COMMAND_EXIT)) {
3006 mDemoMode = false;
3007 checkBarModes();
3008 } else if (!mDemoMode) {
3009 // automatically enter demo mode on first demo command
3010 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
3011 }
3012 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
John Spurlockbb4a7022014-11-08 12:40:19 -05003013 if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
3014 mVolumeComponent.dispatchDemoCommand(command, args);
3015 }
John Spurlock3c875662013-08-31 15:07:25 -04003016 if (modeChange || command.equals(COMMAND_CLOCK)) {
3017 dispatchDemoCommandToView(command, args, R.id.clock);
3018 }
3019 if (modeChange || command.equals(COMMAND_BATTERY)) {
3020 dispatchDemoCommandToView(command, args, R.id.battery);
3021 }
3022 if (modeChange || command.equals(COMMAND_STATUS)) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003023 mIconController.dispatchDemoCommand(command, args);
3024
John Spurlock3c875662013-08-31 15:07:25 -04003025 }
3026 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
3027 mNetworkController.dispatchDemoCommand(command, args);
3028 }
John Spurlock7f42fc52014-01-14 16:20:39 -05003029 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
3030 View notifications = mStatusBarView == null ? null
3031 : mStatusBarView.findViewById(R.id.notification_icon_area);
3032 if (notifications != null) {
3033 String visible = args.getString("visible");
3034 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
3035 notifications.setVisibility(vis);
3036 }
3037 }
John Spurlock3c875662013-08-31 15:07:25 -04003038 if (command.equals(COMMAND_BARS)) {
3039 String mode = args.getString("mode");
3040 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04003041 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04003042 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
John Spurlock0ff62e02014-07-22 16:15:08 -04003043 "transparent".equals(mode) ? MODE_TRANSPARENT :
3044 "warning".equals(mode) ? MODE_WARNING :
John Spurlock3c875662013-08-31 15:07:25 -04003045 -1;
3046 if (barMode != -1) {
3047 boolean animate = true;
3048 if (mStatusBarView != null) {
3049 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
3050 }
3051 if (mNavigationBarView != null) {
3052 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
3053 }
3054 }
3055 }
3056 }
3057
3058 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
3059 if (mStatusBarView == null) return;
3060 View v = mStatusBarView.findViewById(id);
3061 if (v instanceof DemoMode) {
3062 ((DemoMode)v).dispatchDemoCommand(command, args);
3063 }
3064 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003065
Jorim Jaggiecbab362014-04-23 16:13:15 +02003066 /**
3067 * @return The {@link StatusBarState} the status bar is in.
3068 */
3069 public int getBarState() {
3070 return mState;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003071 }
3072
3073 public void showKeyguard() {
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003074 if (mLaunchTransitionFadingAway) {
3075 mNotificationPanel.animate().cancel();
3076 mNotificationPanel.setAlpha(1f);
Jorim Jaggi826730a2014-12-08 21:05:13 +01003077 runLaunchTransitionEndRunnable();
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003078 mLaunchTransitionFadingAway = false;
3079 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003080 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003081 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003082 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggid41083a2014-09-12 02:54:40 +02003083 if (!mScreenOnFromKeyguard) {
3084
3085 // If the screen is off already, we need to disable touch events because these might
3086 // collapse the panel after we expanded it, and thus we would end up with a blank
3087 // Keyguard.
3088 mNotificationPanel.setTouchDisabled(true);
3089 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003090 instantExpandNotificationsPanel();
Jorim Jaggiecbab362014-04-23 16:13:15 +02003091 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003092 if (mDraggedDownRow != null) {
3093 mDraggedDownRow.setUserLocked(false);
Selim Cinekb5605e52015-02-20 18:21:41 +01003094 mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003095 mDraggedDownRow = null;
3096 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003097 }
3098
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003099 public boolean isCollapsing() {
3100 return mNotificationPanel.isCollapsing();
3101 }
3102
3103 public void addPostCollapseAction(Runnable r) {
3104 mPostCollapseRunnables.add(r);
3105 }
3106
Selim Cinekbaa23272014-07-08 18:01:07 +02003107 public boolean isInLaunchTransition() {
3108 return mNotificationPanel.isLaunchTransitionRunning()
3109 || mNotificationPanel.isLaunchTransitionFinished();
3110 }
3111
3112 /**
3113 * Fades the content of the keyguard away after the launch transition is done.
3114 *
3115 * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
3116 * starts
3117 * @param endRunnable the runnable to be run when the transition is done
3118 */
3119 public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003120 Runnable endRunnable) {
Jorim Jaggi826730a2014-12-08 21:05:13 +01003121 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003122 mLaunchTransitionEndRunnable = endRunnable;
Selim Cinekbaa23272014-07-08 18:01:07 +02003123 Runnable hideRunnable = new Runnable() {
3124 @Override
3125 public void run() {
3126 mLaunchTransitionFadingAway = true;
3127 if (beforeFading != null) {
3128 beforeFading.run();
3129 }
3130 mNotificationPanel.setAlpha(1);
3131 mNotificationPanel.animate()
3132 .alpha(0)
3133 .setStartDelay(FADE_KEYGUARD_START_DELAY)
3134 .setDuration(FADE_KEYGUARD_DURATION)
3135 .withLayer()
3136 .withEndAction(new Runnable() {
3137 @Override
3138 public void run() {
3139 mNotificationPanel.setAlpha(1);
Jorim Jaggi826730a2014-12-08 21:05:13 +01003140 runLaunchTransitionEndRunnable();
Selim Cinekbaa23272014-07-08 18:01:07 +02003141 mLaunchTransitionFadingAway = false;
3142 }
3143 });
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003144 mIconController.appTransitionStarting(SystemClock.uptimeMillis(),
3145 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Selim Cinekbaa23272014-07-08 18:01:07 +02003146 }
3147 };
3148 if (mNotificationPanel.isLaunchTransitionRunning()) {
3149 mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
3150 } else {
3151 hideRunnable.run();
3152 }
3153 }
3154
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003155 /**
Jorim Jaggi826730a2014-12-08 21:05:13 +01003156 * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
3157 * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
3158 * because the launched app crashed or something else went wrong.
3159 */
3160 public void startLaunchTransitionTimeout() {
3161 mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
3162 LAUNCH_TRANSITION_TIMEOUT_MS);
3163 }
3164
3165 private void onLaunchTransitionTimeout() {
3166 Log.w(TAG, "Launch transition: Timeout!");
3167 mNotificationPanel.resetViews();
3168 }
3169
3170 private void runLaunchTransitionEndRunnable() {
3171 if (mLaunchTransitionEndRunnable != null) {
3172 Runnable r = mLaunchTransitionEndRunnable;
3173
3174 // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
3175 // which would lead to infinite recursion. Protect against it.
3176 mLaunchTransitionEndRunnable = null;
3177 r.run();
3178 }
3179 }
3180
3181 /**
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003182 * @return true if we would like to stay in the shade, false if it should go away entirely
3183 */
3184 public boolean hideKeyguard() {
3185 boolean staying = mLeaveOpenOnKeyguardHide;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003186 setBarState(StatusBarState.SHADE);
3187 if (mLeaveOpenOnKeyguardHide) {
3188 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003189 mNotificationPanel.animateToFullShade(calculateGoingToFullShadeDelay());
3190 if (mDraggedDownRow != null) {
3191 mDraggedDownRow.setUserLocked(false);
3192 mDraggedDownRow = null;
3193 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003194 } else {
3195 instantCollapseNotificationPanel();
3196 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02003197 updateKeyguardState(staying, false /* fromShadeLocked */);
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01003198
3199 // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
3200 // visibilities so next time we open the panel we know the correct height already.
3201 if (mQSPanel != null) {
3202 mQSPanel.refreshAllTiles();
3203 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003204 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003205 return staying;
3206 }
3207
3208 public long calculateGoingToFullShadeDelay() {
3209 return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
Jorim Jaggi15682502014-04-23 12:01:36 +02003210 }
3211
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003212 /**
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003213 * Notifies the status bar that Keyguard is going away very soon.
3214 */
3215 public void keyguardGoingAway() {
3216
3217 // Treat Keyguard exit animation as an app transition to achieve nice transition for status
3218 // bar.
3219 mIconController.appTransitionPending();
3220 }
3221
3222 /**
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003223 * Notifies the status bar the Keyguard is fading away with the specified timings.
3224 *
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003225 * @param startTime the start time of the animations in uptime millis
3226 * @param delay the precalculated animation delay in miliseconds
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003227 * @param fadeoutDuration the duration of the exit animation, in milliseconds
3228 */
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003229 public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003230 mKeyguardFadingAway = true;
3231 mKeyguardFadingAwayDelay = delay;
3232 mKeyguardFadingAwayDuration = fadeoutDuration;
3233 mWaitingForKeyguardExit = false;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003234 mIconController.appTransitionStarting(
3235 startTime + fadeoutDuration
3236 - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
3237 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Jorim Jaggi2580a9762014-06-25 03:08:25 +02003238 disable(mDisabledUnmodified, true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003239 }
3240
Jorim Jaggi416493b2014-09-13 03:57:32 +02003241 public boolean isKeyguardFadingAway() {
3242 return mKeyguardFadingAway;
3243 }
3244
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003245 /**
3246 * Notifies that the Keyguard fading away animation is done.
3247 */
3248 public void finishKeyguardFadingAway() {
3249 mKeyguardFadingAway = false;
3250 }
3251
Jorim Jaggi15682502014-04-23 12:01:36 +02003252 private void updatePublicMode() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003253 setLockscreenPublicMode(
3254 mStatusBarKeyguardViewManager.isShowing() && mStatusBarKeyguardViewManager
3255 .isSecure(mCurrentUserId));
Jorim Jaggi15682502014-04-23 12:01:36 +02003256 }
3257
Jorim Jaggi98f85302014-08-07 17:45:04 +02003258 private void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003259 if (mState == StatusBarState.KEYGUARD) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003260 mKeyguardIndicationController.setVisible(true);
Selim Cinek4c6969a2014-05-26 19:22:17 +02003261 mNotificationPanel.resetViews();
Jorim Jaggi98f85302014-08-07 17:45:04 +02003262 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
Jorim Jaggi15682502014-04-23 12:01:36 +02003263 } else {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003264 mKeyguardIndicationController.setVisible(false);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003265 mKeyguardUserSwitcher.setKeyguard(false,
3266 goingToFullShade || mState == StatusBarState.SHADE_LOCKED || fromShadeLocked);
Jorim Jaggi15682502014-04-23 12:01:36 +02003267 }
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003268 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003269 mScrimController.setKeyguardShowing(true);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003270 mIconPolicy.setKeyguardShowing(true);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003271 } else {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003272 mScrimController.setKeyguardShowing(false);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003273 mIconPolicy.setKeyguardShowing(false);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003274 }
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003275 mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
John Spurlockbf370992014-06-17 13:58:31 -04003276 updateDozingState();
Jorim Jaggi15682502014-04-23 12:01:36 +02003277 updatePublicMode();
Jorim Jaggiae441282014-08-01 02:45:18 +02003278 updateStackScrollerState(goingToFullShade);
Christoph Studer37fe6932014-05-26 13:10:30 +02003279 updateNotifications();
Jorim Jaggia6310292014-04-16 14:11:52 +02003280 checkBarModes();
Dan Sandler16128f42014-05-21 12:48:22 -04003281 updateMediaMetaData(false);
John Spurlock657c62c2014-07-22 12:18:09 -04003282 mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
3283 mStatusBarKeyguardViewManager.isSecure());
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003284 }
3285
John Spurlockbf370992014-06-17 13:58:31 -04003286 private void updateDozingState() {
John Spurlockcf5d3c92014-09-21 17:55:01 -04003287 if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) {
Jorim Jaggi61d37f62014-07-30 17:26:55 +02003288 return;
3289 }
Jorim Jaggi4e857f42014-11-17 19:14:04 +01003290 boolean animate = !mDozing && mDozeScrimController.isPulsing();
3291 mNotificationPanel.setDozing(mDozing, animate);
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003292 mStackScroller.setDark(mDozing, animate, mScreenOnTouchLocation);
Jorim Jaggi048af1f2014-11-11 22:51:10 +01003293 mScrimController.setDozing(mDozing);
Jorim Jaggi4e857f42014-11-17 19:14:04 +01003294 mDozeScrimController.setDozing(mDozing, animate);
John Spurlockbf370992014-06-17 13:58:31 -04003295 }
3296
Jorim Jaggiae441282014-08-01 02:45:18 +02003297 public void updateStackScrollerState(boolean goingToFullShade) {
John Spurlock4b3bda22014-05-22 14:32:20 -04003298 if (mStackScroller == null) return;
Selim Cinek1408eb52014-06-02 14:45:38 +02003299 boolean onKeyguard = mState == StatusBarState.KEYGUARD;
Jorim Jaggiae441282014-08-01 02:45:18 +02003300 mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
Selim Cinek1408eb52014-06-02 14:45:38 +02003301 mStackScroller.setDimmed(onKeyguard, false /* animate */);
Selim Cinek1408eb52014-06-02 14:45:38 +02003302 mStackScroller.setExpandingEnabled(!onKeyguard);
Selim Cineka32ab602014-06-11 15:06:01 +02003303 ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
3304 mStackScroller.setActivatedChild(null);
3305 if (activatedChild != null) {
3306 activatedChild.makeInactive(false /* animate */);
3307 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003308 }
3309
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003310 public void userActivity() {
Jorim Jaggib690f0d2014-07-03 23:25:44 +02003311 if (mState == StatusBarState.KEYGUARD) {
3312 mKeyguardViewMediatorCallback.userActivity();
3313 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003314 }
3315
Jorim Jaggidf993512014-05-13 23:06:35 +02003316 public boolean interceptMediaKey(KeyEvent event) {
3317 return mState == StatusBarState.KEYGUARD
3318 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
3319 }
3320
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003321 public boolean onMenuPressed() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003322 return mState == StatusBarState.KEYGUARD && mStatusBarKeyguardViewManager.onMenuPressed();
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003323 }
3324
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003325 public boolean onBackPressed() {
Adrian Roos0002a452014-07-03 13:46:07 +02003326 if (mStatusBarKeyguardViewManager.onBackPressed()) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003327 return true;
3328 }
Adrian Roos0002a452014-07-03 13:46:07 +02003329 if (mNotificationPanel.isQsExpanded()) {
John Spurlockf7ae4422014-08-01 12:45:18 -04003330 if (mNotificationPanel.isQsDetailShowing()) {
3331 mNotificationPanel.closeQsDetail();
3332 } else {
3333 mNotificationPanel.animateCloseQs();
3334 }
Adrian Roos0002a452014-07-03 13:46:07 +02003335 return true;
3336 }
3337 if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
3338 animateCollapsePanels();
3339 return true;
3340 }
3341 return false;
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003342 }
3343
Jorim Jaggi34250762014-07-03 23:51:19 +02003344 public boolean onSpacePressed() {
Jorim Jaggi2c33d5d2014-08-29 16:28:20 +02003345 if (mScreenOn != null && mScreenOn
3346 && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
Jorim Jaggi4eedc1d2014-10-27 13:45:56 +01003347 animateCollapsePanels(
3348 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
Jorim Jaggi34250762014-07-03 23:51:19 +02003349 return true;
3350 }
3351 return false;
3352 }
3353
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003354 private void showBouncer() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003355 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekbaa23272014-07-08 18:01:07 +02003356 mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003357 mStatusBarKeyguardViewManager.dismiss();
3358 }
3359 }
3360
3361 private void instantExpandNotificationsPanel() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02003362
Jorim Jaggi0a27be82014-06-11 03:22:39 +02003363 // Make our window larger and the panel expanded.
Jorim Jaggifa505a72014-04-28 20:04:11 +02003364 makeExpandedVisible(true);
Jorim Jaggi0a27be82014-06-11 03:22:39 +02003365 mNotificationPanel.instantExpand();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003366 }
Adrian Roos5a46cd32014-04-03 16:51:58 +02003367
Jorim Jaggia005f1b2014-04-16 19:06:10 +02003368 private void instantCollapseNotificationPanel() {
Selim Cinek6bb4a9b2014-10-09 17:48:05 -07003369 mNotificationPanel.instantCollapse();
Jorim Jaggia005f1b2014-04-16 19:06:10 +02003370 }
3371
Jorim Jaggid4a57442014-04-10 02:45:55 +02003372 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02003373 public void onActivated(ActivatableNotificationView view) {
Christoph Studerb0183992014-12-22 21:02:26 +01003374 EventLogTags.writeSysuiLockscreenGesture(
3375 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
3376 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
Adrian Roos12c1ef52014-06-04 13:54:08 +02003377 mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
Selim Cineka32ab602014-06-11 15:06:01 +02003378 ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
3379 if (previousView != null) {
3380 previousView.makeInactive(true /* animate */);
3381 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003382 mStackScroller.setActivatedChild(view);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02003383 }
3384
Jorim Jaggiecbab362014-04-23 16:13:15 +02003385 /**
3386 * @param state The {@link StatusBarState} to set.
3387 */
3388 public void setBarState(int state) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01003389 // If we're visible and switched to SHADE_LOCKED (the user dragged
3390 // down on the lockscreen), clear notification LED, vibration,
3391 // ringing.
3392 // Other transitions are covered in handleVisibleToUserChanged().
3393 if (state != mState && mVisible && state == StatusBarState.SHADE_LOCKED) {
3394 try {
3395 mBarService.clearNotificationEffects();
3396 } catch (RemoteException e) {
3397 // Ignore.
Christoph Studer1f32c652014-11-26 15:32:20 +01003398 }
3399 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003400 mState = state;
Selim Cinek25fd4e2b2015-02-20 17:46:07 +01003401 mGroupManager.setStatusBarState(state);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003402 mStatusBarWindowManager.setStatusBarState(state);
3403 }
3404
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02003405 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02003406 public void onActivationReset(ActivatableNotificationView view) {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003407 if (view == mStackScroller.getActivatedChild()) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003408 mKeyguardIndicationController.hideTransientIndication();
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003409 mStackScroller.setActivatedChild(null);
3410 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003411 }
3412
3413 public void onTrackingStarted() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003414 runPostCollapseRunnables();
Jorim Jaggi90129582014-06-02 14:44:49 +02003415 }
3416
Selim Cinekdbbcfbe2014-10-24 17:52:35 +02003417 public void onClosingFinished() {
3418 runPostCollapseRunnables();
3419 }
3420
Jorim Jaggi90129582014-06-02 14:44:49 +02003421 public void onUnlockHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003422 mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
Jorim Jaggi90129582014-06-02 14:44:49 +02003423 }
3424
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003425 public void onHintFinished() {
Jorim Jaggi93a2bb22014-06-02 19:57:28 +02003426 // Delay the reset a bit so the user can read the text.
Adrian Roos12c1ef52014-06-04 13:54:08 +02003427 mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003428 }
3429
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003430 public void onCameraHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003431 mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003432 }
3433
3434 public void onPhoneHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003435 mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003436 }
3437
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003438 public void onTrackingStopped(boolean expand) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003439 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01003440 if (!expand && !mUnlockMethodCache.isCurrentlyInsecure()) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003441 showBouncer();
3442 }
3443 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003444 }
3445
3446 @Override
Jorim Jaggid4a57442014-04-10 02:45:55 +02003447 protected int getMaxKeyguardNotifications() {
3448 return mKeyguardMaxNotificationCount;
3449 }
3450
Jorim Jaggia6310292014-04-16 14:11:52 +02003451 public NavigationBarView getNavigationBarView() {
3452 return mNavigationBarView;
3453 }
3454
Jorim Jaggiecbab362014-04-23 16:13:15 +02003455 // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
3456
3457 @Override
Christoph Studerb0183992014-12-22 21:02:26 +01003458 public boolean onDraggedDown(View startingChild, int dragLengthY) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02003459 if (hasActiveNotifications()) {
Christoph Studerb0183992014-12-22 21:02:26 +01003460 EventLogTags.writeSysuiLockscreenGesture(
3461 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
3462 (int) (dragLengthY / mDisplayMetrics.density),
3463 0 /* velocityDp - N/A */);
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003464
3465 // We have notifications, go to locked shade.
3466 goToLockedShade(startingChild);
3467 return true;
3468 } else {
3469
3470 // No notifications - abort gesture.
3471 return false;
3472 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003473 }
3474
3475 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003476 public void onDragDownReset() {
3477 mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003478 }
3479
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003480 @Override
Jorim Jaggiecbab362014-04-23 16:13:15 +02003481 public void onThresholdReached() {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003482 mStackScroller.setDimmed(false /* dimmed */, true /* animate */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003483 }
3484
Selim Cinek1408eb52014-06-02 14:45:38 +02003485 @Override
3486 public void onTouchSlopExceeded() {
3487 mStackScroller.removeLongPressCallback();
3488 }
3489
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003490 @Override
3491 public void setEmptyDragAmount(float amount) {
3492 mNotificationPanel.setEmptyDragAmount(amount);
3493 }
3494
Jorim Jaggiecbab362014-04-23 16:13:15 +02003495 /**
3496 * If secure with redaction: Show bouncer, go to unlocked shade.
3497 *
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003498 * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
Jorim Jaggiecbab362014-04-23 16:13:15 +02003499 *
3500 * @param expandView The view to expand after going to the shade.
3501 */
3502 public void goToLockedShade(View expandView) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003503 ExpandableNotificationRow row = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003504 if (expandView instanceof ExpandableNotificationRow) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003505 row = (ExpandableNotificationRow) expandView;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003506 row.setUserExpanded(true);
3507 }
Adrian Roosaee70462014-09-03 16:27:39 +02003508 boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
3509 || !mShowLockscreenNotifications;
3510 if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003511 mLeaveOpenOnKeyguardHide = true;
3512 showBouncer();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003513 mDraggedDownRow = row;
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003514 } else {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003515 mNotificationPanel.animateToFullShade(0 /* delay */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003516 setBarState(StatusBarState.SHADE_LOCKED);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003517 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003518 if (row != null) {
3519 row.setUserLocked(false);
3520 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003521 }
3522 }
3523
Adrian Roos5a46cd32014-04-03 16:51:58 +02003524 /**
Jorim Jaggi6539a832014-06-03 23:33:09 +02003525 * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
3526 */
3527 public void goToKeyguard() {
3528 if (mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekd9acca52014-09-01 22:33:25 +02003529 mStackScroller.onGoToKeyguard();
Jorim Jaggi6539a832014-06-03 23:33:09 +02003530 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003531 updateKeyguardState(false /* goingToFullShade */, true /* fromShadeLocked*/);
Jorim Jaggi6539a832014-06-03 23:33:09 +02003532 }
3533 }
3534
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003535 public long getKeyguardFadingAwayDelay() {
3536 return mKeyguardFadingAwayDelay;
3537 }
3538
3539 public long getKeyguardFadingAwayDuration() {
3540 return mKeyguardFadingAwayDuration;
3541 }
3542
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003543 @Override
3544 public void setBouncerShowing(boolean bouncerShowing) {
3545 super.setBouncerShowing(bouncerShowing);
Jorim Jaggi2580a9762014-06-25 03:08:25 +02003546 disable(mDisabledUnmodified, true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003547 }
3548
Jorim Jaggi75c95042014-05-16 19:09:59 +02003549 public void onScreenTurnedOff() {
Jorim Jaggid41083a2014-09-12 02:54:40 +02003550 mScreenOnFromKeyguard = false;
Selim Cinek29ed3c92014-09-23 20:44:35 +02003551 mScreenOnComingFromTouch = false;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003552 mScreenOnTouchLocation = null;
Jorim Jaggi75c95042014-05-16 19:09:59 +02003553 mStackScroller.setAnimationsEnabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01003554 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02003555 }
3556
3557 public void onScreenTurnedOn() {
Jorim Jaggid41083a2014-09-12 02:54:40 +02003558 mScreenOnFromKeyguard = true;
Jorim Jaggi75c95042014-05-16 19:09:59 +02003559 mStackScroller.setAnimationsEnabled(true);
Jorim Jaggid09def7512014-09-02 18:36:45 +02003560 mNotificationPanel.onScreenTurnedOn();
Jorim Jaggid41083a2014-09-12 02:54:40 +02003561 mNotificationPanel.setTouchDisabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01003562 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02003563 }
John Spurlockd08f91f2014-05-23 11:00:34 -04003564
Jason Monk815e0572014-08-12 17:26:36 -04003565 /**
3566 * This handles long-press of both back and recents. They are
3567 * handled together to capture them both being long-pressed
3568 * at the same time to exit screen pinning (lock task).
3569 *
3570 * When accessibility mode is on, only a long-press from recents
3571 * is required to exit.
3572 *
3573 * In all other circumstances we try to pass through long-press events
3574 * for Back, so that apps can still use it. Which can be from two things.
3575 * 1) Not currently in screen pinning (lock task).
3576 * 2) Back is long-pressed without recents.
3577 */
3578 private void handleLongPressBackRecents(View v) {
Jason Monk62515be2014-05-21 16:06:19 -04003579 try {
Jason Monk815e0572014-08-12 17:26:36 -04003580 boolean sendBackLongPress = false;
Jason Monk62515be2014-05-21 16:06:19 -04003581 IActivityManager activityManager = ActivityManagerNative.getDefault();
Jason Monk815e0572014-08-12 17:26:36 -04003582 boolean isAccessiblityEnabled = mAccessibilityManager.isEnabled();
3583 if (activityManager.isInLockTaskMode() && !isAccessiblityEnabled) {
3584 long time = System.currentTimeMillis();
3585 // If we recently long-pressed the other button then they were
3586 // long-pressed 'together'
3587 if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) {
3588 activityManager.stopLockTaskModeOnCurrent();
Jason Monk17488b92014-11-06 11:26:14 -05003589 // When exiting refresh disabled flags.
3590 mNavigationBarView.setDisabledFlags(mDisabled, true);
Jason Monk815e0572014-08-12 17:26:36 -04003591 } else if ((v.getId() == R.id.back)
3592 && !mNavigationBarView.getRecentsButton().isPressed()) {
3593 // If we aren't pressing recents right now then they presses
3594 // won't be together, so send the standard long-press action.
3595 sendBackLongPress = true;
3596 }
3597 mLastLockToAppLongPress = time;
3598 } else {
3599 // If this is back still need to handle sending the long-press event.
3600 if (v.getId() == R.id.back) {
3601 sendBackLongPress = true;
3602 } else if (isAccessiblityEnabled && activityManager.isInLockTaskMode()) {
3603 // When in accessibility mode a long press that is recents (not back)
3604 // should stop lock task.
3605 activityManager.stopLockTaskModeOnCurrent();
Jason Monk17488b92014-11-06 11:26:14 -05003606 // When exiting refresh disabled flags.
3607 mNavigationBarView.setDisabledFlags(mDisabled, true);
Jason Monk815e0572014-08-12 17:26:36 -04003608 }
3609 }
3610 if (sendBackLongPress) {
3611 KeyButtonView keyButtonView = (KeyButtonView) v;
3612 keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
3613 keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
Jason Monk62515be2014-05-21 16:06:19 -04003614 }
3615 } catch (RemoteException e) {
Jason Monk815e0572014-08-12 17:26:36 -04003616 Log.d(TAG, "Unable to reach activity manager", e);
Jason Monk62515be2014-05-21 16:06:19 -04003617 }
3618 }
3619
Winson Chungd42a6cf2014-06-03 16:24:04 -07003620 // Recents
3621
3622 @Override
3623 protected void showRecents(boolean triggeredFromAltTab) {
3624 // Set the recents visibility flag
3625 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
3626 notifyUiVisibilityChanged(mSystemUiVisibility);
3627 super.showRecents(triggeredFromAltTab);
3628 }
3629
3630 @Override
Winson Chungcdcd4872014-08-05 18:00:13 -07003631 protected void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
Winson Chungd42a6cf2014-06-03 16:24:04 -07003632 // Unset the recents visibility flag
3633 mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
3634 notifyUiVisibilityChanged(mSystemUiVisibility);
Winson Chungcdcd4872014-08-05 18:00:13 -07003635 super.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
Winson Chungd42a6cf2014-06-03 16:24:04 -07003636 }
3637
3638 @Override
3639 protected void toggleRecents() {
3640 // Toggle the recents visibility flag
3641 mSystemUiVisibility ^= View.RECENT_APPS_VISIBLE;
3642 notifyUiVisibilityChanged(mSystemUiVisibility);
3643 super.toggleRecents();
3644 }
Winson Chung9214eff2014-06-12 13:59:25 -07003645
3646 @Override
3647 public void onVisibilityChanged(boolean visible) {
3648 // Update the recents visibility flag
3649 if (visible) {
3650 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
3651 } else {
3652 mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
3653 }
3654 notifyUiVisibilityChanged(mSystemUiVisibility);
3655 }
John Spurlockbf370992014-06-17 13:58:31 -04003656
Jason Monk5565cb42014-09-12 10:59:21 -04003657 @Override
3658 public void showScreenPinningRequest() {
Jason Monk18f99d92014-09-11 13:36:42 -04003659 if (mKeyguardMonitor.isShowing()) {
3660 // Don't allow apps to trigger this from keyguard.
3661 return;
3662 }
3663 // Show screen pinning request, since this comes from an app, show 'no thanks', button.
3664 showScreenPinningRequest(true);
3665 }
3666
3667 public void showScreenPinningRequest(boolean allowCancel) {
3668 mScreenPinningRequest.showPrompt(allowCancel);
Jason Monk5565cb42014-09-12 10:59:21 -04003669 }
3670
Christoph Studerc8db24b2014-07-25 17:50:30 +02003671 public boolean hasActiveNotifications() {
3672 return !mNotificationData.getActiveNotifications().isEmpty();
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003673 }
3674
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003675 public void wakeUpIfDozing(long time, MotionEvent event) {
Jorim Jaggi048af1f2014-11-11 22:51:10 +01003676 if (mDozing && mDozeScrimController.isPulsing()) {
John Spurlock8b12f222014-09-09 11:54:11 -04003677 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
3678 pm.wakeUp(time);
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003679 mScreenOnComingFromTouch = true;
3680 mScreenOnTouchLocation = new PointF(event.getX(), event.getY());
3681 mNotificationPanel.setTouchDisabled(false);
John Spurlock8b12f222014-09-09 11:54:11 -04003682 }
3683 }
3684
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01003685 @Override
3686 public void appTransitionPending() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003687
3688 // Use own timings when Keyguard is going away, see keyguardGoingAway and
3689 // setKeyguardFadingAway
3690 if (!mKeyguardFadingAway) {
3691 mIconController.appTransitionPending();
3692 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01003693 }
3694
3695 @Override
3696 public void appTransitionCancelled() {
3697 mIconController.appTransitionCancelled();
3698 }
3699
3700 @Override
3701 public void appTransitionStarting(long startTime, long duration) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003702
3703 // Use own timings when Keyguard is going away, see keyguardGoingAway and
3704 // setKeyguardFadingAway
3705 if (!mKeyguardFadingAway) {
3706 mIconController.appTransitionStarting(startTime, duration);
3707 }
Kenny Guy3094d4a2015-04-01 19:14:10 +01003708 if (mIconPolicy != null) {
3709 mIconPolicy.appTransitionStarting(startTime, duration);
3710 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01003711 }
3712
John Spurlockbf370992014-06-17 13:58:31 -04003713 private final class ShadeUpdates {
3714 private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
3715 private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
3716
3717 public void check() {
3718 mNewVisibleNotifications.clear();
Christoph Studerc8db24b2014-07-25 17:50:30 +02003719 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
3720 for (int i = 0; i < activeNotifications.size(); i++) {
3721 final Entry entry = activeNotifications.get(i);
John Spurlockbf370992014-06-17 13:58:31 -04003722 final boolean visible = entry.row != null
3723 && entry.row.getVisibility() == View.VISIBLE;
3724 if (visible) {
3725 mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
3726 }
3727 }
3728 final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
3729 mVisibleNotifications.clear();
Dianne Hackborn497175b2014-07-01 12:56:08 -07003730 mVisibleNotifications.addAll(mNewVisibleNotifications);
John Spurlockbf370992014-06-17 13:58:31 -04003731
3732 // We have new notifications
3733 if (updates && mDozeServiceHost != null) {
3734 mDozeServiceHost.fireNewNotifications();
3735 }
3736 }
3737 }
3738
Jeff Brown4d69e222014-09-18 15:27:50 -07003739 private final class DozeServiceHost implements DozeHost {
John Spurlockbf370992014-06-17 13:58:31 -04003740 // Amount of time to allow to update the time shown on the screen before releasing
3741 // the wakelock. This timeout is design to compensate for the fact that we don't
3742 // currently have a way to know when time display contents have actually been
3743 // refreshed once we've finished rendering a new frame.
3744 private static final long PROCESSING_TIME = 500;
3745
3746 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
3747 private final H mHandler = new H();
3748
Christoph Studer1f32c652014-11-26 15:32:20 +01003749 // Keeps the last reported state by fireNotificationLight.
3750 private boolean mNotificationLightOn;
3751
John Spurlockc6eed842014-08-25 12:19:41 -04003752 @Override
3753 public String toString() {
Jeff Brown4d69e222014-09-18 15:27:50 -07003754 return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
John Spurlock8b12f222014-09-09 11:54:11 -04003755 }
3756
John Spurlockd96179e2014-08-21 16:43:45 -04003757 public void firePowerSaveChanged(boolean active) {
3758 for (Callback callback : mCallbacks) {
3759 callback.onPowerSaveChanged(active);
3760 }
3761 }
3762
John Spurlockcad57682014-07-26 17:09:56 -04003763 public void fireBuzzBeepBlinked() {
3764 for (Callback callback : mCallbacks) {
3765 callback.onBuzzBeepBlinked();
3766 }
3767 }
3768
John Spurlockcb566aa2014-08-03 22:58:28 -04003769 public void fireNotificationLight(boolean on) {
Christoph Studer1f32c652014-11-26 15:32:20 +01003770 mNotificationLightOn = on;
John Spurlockcb566aa2014-08-03 22:58:28 -04003771 for (Callback callback : mCallbacks) {
3772 callback.onNotificationLight(on);
3773 }
3774 }
3775
John Spurlockbf370992014-06-17 13:58:31 -04003776 public void fireNewNotifications() {
3777 for (Callback callback : mCallbacks) {
3778 callback.onNewNotifications();
3779 }
3780 }
3781
3782 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07003783 public void addCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04003784 mCallbacks.add(callback);
3785 }
3786
3787 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07003788 public void removeCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04003789 mCallbacks.remove(callback);
3790 }
3791
3792 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07003793 public void startDozing(@NonNull Runnable ready) {
3794 mHandler.obtainMessage(H.MSG_START_DOZING, ready).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04003795 }
3796
3797 @Override
John Spurlockeab28e62014-11-29 11:33:49 -05003798 public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
3799 mHandler.obtainMessage(H.MSG_PULSE_WHILE_DOZING, reason, 0, callback).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04003800 }
3801
3802 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07003803 public void stopDozing() {
3804 mHandler.obtainMessage(H.MSG_STOP_DOZING).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04003805 }
3806
John Spurlockd96179e2014-08-21 16:43:45 -04003807 @Override
3808 public boolean isPowerSaveActive() {
3809 return mBatteryController != null && mBatteryController.isPowerSave();
3810 }
3811
Christoph Studer1f32c652014-11-26 15:32:20 +01003812 @Override
3813 public boolean isNotificationLightOn() {
3814 return mNotificationLightOn;
3815 }
3816
Jeff Brown4d69e222014-09-18 15:27:50 -07003817 private void handleStartDozing(@NonNull Runnable ready) {
John Spurlockbf370992014-06-17 13:58:31 -04003818 if (!mDozing) {
3819 mDozing = true;
John Spurlock813552c2014-09-19 08:30:21 -04003820 DozeLog.traceDozing(mContext, mDozing);
John Spurlockbf370992014-06-17 13:58:31 -04003821 updateDozingState();
3822 }
Jeff Brown4d69e222014-09-18 15:27:50 -07003823 ready.run();
John Spurlockbf370992014-06-17 13:58:31 -04003824 }
3825
John Spurlockeab28e62014-11-29 11:33:49 -05003826 private void handlePulseWhileDozing(@NonNull PulseCallback callback, int reason) {
3827 mDozeScrimController.pulse(callback, reason);
John Spurlockbf370992014-06-17 13:58:31 -04003828 }
3829
Jeff Brown4d69e222014-09-18 15:27:50 -07003830 private void handleStopDozing() {
John Spurlockbf370992014-06-17 13:58:31 -04003831 if (mDozing) {
3832 mDozing = false;
John Spurlock813552c2014-09-19 08:30:21 -04003833 DozeLog.traceDozing(mContext, mDozing);
John Spurlockbf370992014-06-17 13:58:31 -04003834 updateDozingState();
3835 }
3836 }
3837
3838 private final class H extends Handler {
Jeff Brown4d69e222014-09-18 15:27:50 -07003839 private static final int MSG_START_DOZING = 1;
3840 private static final int MSG_PULSE_WHILE_DOZING = 2;
3841 private static final int MSG_STOP_DOZING = 3;
John Spurlockbf370992014-06-17 13:58:31 -04003842
3843 @Override
3844 public void handleMessage(Message msg) {
Jeff Brown4d69e222014-09-18 15:27:50 -07003845 switch (msg.what) {
3846 case MSG_START_DOZING:
3847 handleStartDozing((Runnable) msg.obj);
3848 break;
3849 case MSG_PULSE_WHILE_DOZING:
John Spurlockeab28e62014-11-29 11:33:49 -05003850 handlePulseWhileDozing((PulseCallback) msg.obj, msg.arg1);
Jeff Brown4d69e222014-09-18 15:27:50 -07003851 break;
3852 case MSG_STOP_DOZING:
3853 handleStopDozing();
3854 break;
John Spurlockbf370992014-06-17 13:58:31 -04003855 }
3856 }
3857 }
3858 }
Romain Guy648342f2012-05-25 10:44:45 -07003859}