blob: 1062db9b57486b77d245439dd0714a54cfa652f6 [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;
Adrian Roos21d2a252015-06-01 13:59:59 -070034import android.content.pm.IPackageManager;
Daniel Sandler777dcde2013-09-30 10:21:45 -040035import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070036import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040037import android.database.ContentObserver;
Dan Sandler16128f42014-05-21 12:48:22 -040038import android.graphics.Bitmap;
Romain Guy648342f2012-05-25 10:44:45 -070039import android.graphics.Canvas;
40import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040041import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040042import android.graphics.Point;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +010043import android.graphics.PointF;
Romain Guy648342f2012-05-25 10:44:45 -070044import android.graphics.PorterDuff;
Selim Cineka0fad3b2014-09-19 17:20:05 +020045import android.graphics.PorterDuffXfermode;
Joe Onorato808182d2010-07-09 18:52:06 -040046import android.graphics.Rect;
Dan Sandler16128f42014-05-21 12:48:22 -040047import android.graphics.drawable.ColorDrawable;
Romain Guy648342f2012-05-25 10:44:45 -070048import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070049import android.inputmethodservice.InputMethodService;
John Spurlock7b414672014-07-18 13:02:39 -040050import android.media.AudioAttributes;
Dan Sandler16128f42014-05-21 12:48:22 -040051import android.media.MediaMetadata;
52import android.media.session.MediaController;
53import android.media.session.MediaSession;
54import android.media.session.MediaSessionManager;
55import android.media.session.PlaybackState;
Selim Cinekbaa23272014-07-08 18:01:07 +020056import android.os.AsyncTask;
John Spurlock3c875662013-08-31 15:07:25 -040057import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040058import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050059import android.os.HandlerThread;
Joe Onorato808182d2010-07-09 18:52:06 -040060import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040061import android.os.Message;
John Spurlock56d007b2013-10-28 18:40:56 -040062import android.os.PowerManager;
Jason Monk4ae97d32014-12-17 10:14:33 -050063import android.os.Process;
Michael Jurka7f2668c2012-03-27 07:49:52 -070064import android.os.RemoteException;
Adrian Roos21d2a252015-06-01 13:59:59 -070065import android.os.ServiceManager;
Joe Onorato808182d2010-07-09 18:52:06 -040066import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070067import android.os.UserHandle;
Adrian Roos2b154a92014-11-17 15:18:39 +010068import android.os.UserManager;
Daniel Sandlerd3090562011-08-09 00:28:44 -040069import android.provider.Settings;
Chris Wren3ad4e3a2014-09-02 17:23:51 -040070import android.service.notification.NotificationListenerService;
Christoph Studerd0694b62014-06-04 16:36:01 +020071import android.service.notification.NotificationListenerService.RankingMap;
John Spurlockde84f0e2013-06-12 12:41:00 -040072import android.service.notification.StatusBarNotification;
Christoph Studer92b389d2014-04-01 18:44:40 +020073import android.util.ArraySet;
Daniel Sandler36412a72011-08-04 09:35:13 -040074import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -050075import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -040076import android.util.Log;
77import android.view.Display;
Jorim Jaggidf993512014-05-13 23:06:35 +020078import android.view.KeyEvent;
Jorim Jaggid4a57442014-04-10 02:45:55 +020079import android.view.LayoutInflater;
Joe Onorato808182d2010-07-09 18:52:06 -040080import android.view.MotionEvent;
Chris Craik2507c342015-05-04 14:36:49 -070081import android.view.ThreadedRenderer;
Joe Onorato808182d2010-07-09 18:52:06 -040082import android.view.VelocityTracker;
83import android.view.View;
Jim Millerf2a16b22011-07-06 17:32:48 -070084import android.view.ViewGroup.LayoutParams;
Dan Sandler44c0dfd2014-06-09 11:26:16 -040085import android.view.ViewStub;
Joe Onorato808182d2010-07-09 18:52:06 -040086import android.view.WindowManager;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020087import android.view.WindowManagerGlobal;
Jason Monk815e0572014-08-12 17:26:36 -040088import android.view.accessibility.AccessibilityEvent;
Jorim Jaggi4e0880e2014-07-25 14:51:50 +020089import android.view.animation.AccelerateDecelerateInterpolator;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040090import android.view.animation.AccelerateInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020091import android.view.animation.Interpolator;
Jorim Jaggi4e0880e2014-07-25 14:51:50 +020092import android.view.animation.LinearInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020093import android.view.animation.PathInterpolator;
Dan Sandler16128f42014-05-21 12:48:22 -040094import android.widget.ImageView;
Joe Onorato808182d2010-07-09 18:52:06 -040095import android.widget.TextView;
John Spurlock34e13d92013-08-10 06:52:28 -040096
Chris Wren9763d422015-04-30 15:24:05 -040097import com.android.internal.logging.MetricsLogger;
Chris Wrend1dbc922015-06-19 17:51:16 -040098import com.android.internal.statusbar.NotificationVisibility;
Joe Onorato808182d2010-07-09 18:52:06 -040099import com.android.internal.statusbar.StatusBarIcon;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100100import com.android.keyguard.KeyguardHostView.OnDismissAction;
Jason Monkab525272015-07-13 17:02:49 -0400101import com.android.keyguard.KeyguardUpdateMonitor;
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700102import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200103import com.android.keyguard.ViewMediatorCallback;
Jorim Jaggi708f7722014-08-20 17:30:38 +0200104import com.android.systemui.BatteryMeterView;
John Spurlock3c875662013-08-31 15:07:25 -0400105import com.android.systemui.DemoMode;
Christoph Studerb0183992014-12-22 21:02:26 +0100106import com.android.systemui.EventLogConstants;
Chris Wren64161cc2012-12-17 16:49:30 -0500107import com.android.systemui.EventLogTags;
Andrew Flynn82862572015-04-01 14:22:37 -0400108import com.android.systemui.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -0400109import com.android.systemui.R;
Selim Cineke70d6532015-04-24 16:46:13 -0700110import com.android.systemui.assist.AssistManager;
Jeff Brown4d69e222014-09-18 15:27:50 -0700111import com.android.systemui.doze.DozeHost;
John Spurlock813552c2014-09-19 08:30:21 -0400112import com.android.systemui.doze.DozeLog;
Jorim Jaggicff0acb2014-03-31 16:35:15 +0200113import com.android.systemui.keyguard.KeyguardViewMediator;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400114import com.android.systemui.qs.QSPanel;
Jorim Jaggid61f2272014-12-19 20:35:35 +0100115import com.android.systemui.recents.ScreenPinningRequest;
Selim Cineka32ab602014-06-11 15:06:01 +0200116import com.android.systemui.statusbar.ActivatableNotificationView;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200117import com.android.systemui.statusbar.BackDropView;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500118import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700119import com.android.systemui.statusbar.CommandQueue;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400120import com.android.systemui.statusbar.DismissView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200121import com.android.systemui.statusbar.DragDownHelper;
Jorim Jaggia2052ea2014-08-05 16:22:30 +0200122import com.android.systemui.statusbar.EmptyShadeView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200123import com.android.systemui.statusbar.ExpandableNotificationRow;
Daniel Sandler33805342012-07-23 15:45:12 -0400124import com.android.systemui.statusbar.GestureRecorder;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200125import com.android.systemui.statusbar.KeyguardIndicationController;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700126import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -0400127import com.android.systemui.statusbar.NotificationData.Entry;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200128import com.android.systemui.statusbar.NotificationOverflowContainer;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200129import com.android.systemui.statusbar.ScrimView;
Christian Robertson2e347422011-08-11 14:01:04 -0700130import com.android.systemui.statusbar.SignalClusterView;
Selim Cinekc27437b2014-05-14 10:23:33 +0200131import com.android.systemui.statusbar.SpeedBumpView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200132import com.android.systemui.statusbar.StatusBarState;
Christoph Studer2231c6e2014-12-19 12:40:13 +0100133import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200134import com.android.systemui.statusbar.policy.AccessibilityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400135import com.android.systemui.statusbar.policy.BatteryController;
John Spurlock0ff62e02014-07-22 16:15:08 -0400136import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400137import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200138import com.android.systemui.statusbar.policy.BrightnessMirrorController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400139import com.android.systemui.statusbar.policy.CastControllerImpl;
Adrian Roosb83777b2014-06-30 15:11:53 +0200140import com.android.systemui.statusbar.policy.FlashlightController;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700141import com.android.systemui.statusbar.policy.HeadsUpManager;
Jason Monk3d5f5512014-07-25 11:17:28 -0400142import com.android.systemui.statusbar.policy.HotspotControllerImpl;
Jason Monk815e0572014-08-12 17:26:36 -0400143import com.android.systemui.statusbar.policy.KeyButtonView;
John Spurlock657c62c2014-07-22 12:18:09 -0400144import com.android.systemui.statusbar.policy.KeyguardMonitor;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700145import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400146import com.android.systemui.statusbar.policy.LocationControllerImpl;
147import com.android.systemui.statusbar.policy.NetworkControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400148import com.android.systemui.statusbar.policy.NextAlarmController;
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200149import com.android.systemui.statusbar.policy.PreviewInflater;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400150import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400151import com.android.systemui.statusbar.policy.SecurityControllerImpl;
152import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200153import com.android.systemui.statusbar.policy.UserSwitcherController;
John Spurlock86005342014-05-23 11:58:00 -0400154import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek67b22602014-03-10 15:40:16 +0100155import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Christoph Studer92b389d2014-04-01 18:44:40 +0200156import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
Selim Cinekb036ca42015-02-20 15:56:28 +0100157import com.android.systemui.statusbar.stack.StackViewState;
John Spurlock86005342014-05-23 11:58:00 -0400158import com.android.systemui.volume.VolumeComponent;
Selim Cinek67b22602014-03-10 15:40:16 +0100159
Daniel Sandler6a858c32012-03-12 14:38:58 -0400160import java.io.FileDescriptor;
161import java.io.PrintWriter;
162import java.util.ArrayList;
Christoph Studer92b389d2014-04-01 18:44:40 +0200163import java.util.Collection;
164import java.util.Collections;
Selim Cinekb5605e52015-02-20 18:21:41 +0100165import java.util.HashMap;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700166import java.util.HashSet;
Dan Sandler16128f42014-05-21 12:48:22 -0400167import java.util.List;
John Spurlock7bbb9f62014-10-21 12:15:28 -0400168import java.util.Map;
Selim Cineka59ecc32015-04-07 10:51:49 -0700169import java.util.TreeSet;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700170
171import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
172import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
173import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
174import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
175import static android.app.StatusBarManager.windowStateToString;
176import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
177import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
178import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
179import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
180import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
181import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
182import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
Daniel Sandler6a858c32012-03-12 14:38:58 -0400183
Jorim Jaggiecbab362014-04-23 16:13:15 +0200184public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Selim Cinek8d490d42015-04-10 00:05:50 -0700185 DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
186 HeadsUpManager.OnHeadsUpChangedListener {
Joe Onoratofd52b182010-11-10 18:00:52 -0800187 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400188 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400189 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400190 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400191 public static final boolean DEBUG_GESTURES = false;
Dan Sandler16128f42014-05-21 12:48:22 -0400192 public static final boolean DEBUG_MEDIA = false;
193 public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400194
John Spurlock342cad72013-10-08 09:36:50 -0400195 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400196
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400197 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400198 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400199
Dan Sandler16128f42014-05-21 12:48:22 -0400200 public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
201
Adrian Roos8e3e8362015-07-16 19:42:22 -0700202 public static final String ACTION_FAKE_ARTWORK = "fake_artwork";
203
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400204 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400205 private static final int MSG_CLOSE_PANELS = 1001;
206 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Jorim Jaggi826730a2014-12-08 21:05:13 +0100207 private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
Winson Chungb1f74992014-08-08 12:53:09 -0700208 // 1020-1040 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400209
Jorim Jaggi826730a2014-12-08 21:05:13 +0100210 // Time after we abort the launch transition.
211 private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
212
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400213 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
214
John Spurlocke1f366f2013-08-05 12:22:40 -0400215 private static final int STATUS_OR_NAV_TRANSIENT =
216 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400217 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400218
Christoph Studer92b389d2014-04-01 18:44:40 +0200219 /** The minimum delay in ms between reports of notification visibility. */
220 private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
221
Jorim Jaggi93a2bb22014-06-02 19:57:28 +0200222 /**
223 * The delay to reset the hint text when the hint animation is finished running.
224 */
225 private static final int HINT_RESET_DELAY_MS = 1200;
226
John Spurlock7b414672014-07-18 13:02:39 -0400227 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
228 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
229 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
230 .build();
231
Selim Cinekbaa23272014-07-08 18:01:07 +0200232 public static final int FADE_KEYGUARD_START_DELAY = 100;
233 public static final int FADE_KEYGUARD_DURATION = 300;
234
Jason Monk815e0572014-08-12 17:26:36 -0400235 /** Allow some time inbetween the long press for back and recents. */
236 private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
237
Adrian Roos2f2bd9a2015-06-04 18:11:14 -0700238 /** If true, the system is in the half-boot-to-decryption-screen state.
239 * Prudently disable QS and notifications. */
Adrian Roos21d2a252015-06-01 13:59:59 -0700240 private static final boolean ONLY_CORE_APPS;
241
242 static {
243 boolean onlyCoreApps;
244 try {
245 onlyCoreApps = IPackageManager.Stub.asInterface(ServiceManager.getService("package"))
246 .isOnlyCoreApps();
247 } catch (RemoteException e) {
248 onlyCoreApps = false;
249 }
250 ONLY_CORE_APPS = onlyCoreApps;
251 }
252
Joe Onoratofd52b182010-11-10 18:00:52 -0800253 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400254
Daniel Sandler2b697352011-07-22 16:23:09 -0400255 // These are no longer handled by the policy, because we need custom strategies for them
John Spurlockaf8d6c42014-05-07 17:49:08 -0400256 BluetoothControllerImpl mBluetoothController;
Jason Monk3d5f5512014-07-25 11:17:28 -0400257 SecurityControllerImpl mSecurityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400258 BatteryController mBatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400259 LocationControllerImpl mLocationController;
260 NetworkControllerImpl mNetworkController;
Jason Monk51e4dc02014-07-22 12:00:47 -0400261 HotspotControllerImpl mHotspotController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400262 RotationLockControllerImpl mRotationLockController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200263 UserInfoController mUserInfoController;
John Spurlock86005342014-05-23 11:58:00 -0400264 ZenModeController mZenModeController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400265 CastControllerImpl mCastController;
John Spurlock86005342014-05-23 11:58:00 -0400266 VolumeComponent mVolumeComponent;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700267 KeyguardUserSwitcher mKeyguardUserSwitcher;
Adrian Roosb83777b2014-06-30 15:11:53 +0200268 FlashlightController mFlashlightController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200269 UserSwitcherController mUserSwitcherController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200270 NextAlarmController mNextAlarmController;
John Spurlock657c62c2014-07-22 12:18:09 -0400271 KeyguardMonitor mKeyguardMonitor;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200272 BrightnessMirrorController mBrightnessMirrorController;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200273 AccessibilityController mAccessibilityController;
Jim Miller5e6af442011-12-02 18:24:26 -0800274
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400275 int mNaturalBarHeight = -1;
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100276
Joe Onorato808182d2010-07-09 18:52:06 -0400277 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400278 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400279
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400280 StatusBarWindowView mStatusBarWindow;
Joe Onoratofd52b182010-11-10 18:00:52 -0800281 PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400282 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100283 private StatusBarWindowManager mStatusBarWindowManager;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200284 private UnlockMethodCache mUnlockMethodCache;
John Spurlockbf370992014-06-17 13:58:31 -0400285 private DozeServiceHost mDozeServiceHost;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -0700286 private boolean mWakeUpComingFromTouch;
287 private PointF mWakeUpTouchLocation;
Daniel Sandlera310af82012-04-24 01:20:13 -0400288
Joe Onorato808182d2010-07-09 18:52:06 -0400289 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400290 Object mQueueLock = new Object();
291
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100292 StatusBarIconController mIconController;
Joe Onorato808182d2010-07-09 18:52:06 -0400293
294 // expanded notifications
Daniel Sandler040c2e42012-10-17 00:56:33 -0400295 NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400296 View mExpandedContents;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400297 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400298
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400299 // settings
John Spurlockaf8d6c42014-05-07 17:49:08 -0400300 private QSPanel mQSPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400301
Joe Onorato808182d2010-07-09 18:52:06 -0400302 // top bar
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200303 StatusBarHeaderView mHeader;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200304 KeyguardStatusBarView mKeyguardStatusBar;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200305 View mKeyguardStatusView;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200306 KeyguardBottomAreaView mKeyguardBottomArea;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200307 boolean mLeaveOpenOnKeyguardHide;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200308 KeyguardIndicationController mKeyguardIndicationController;
Jorim Jaggie70d31f2014-04-24 22:08:30 +0200309
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700310 private boolean mKeyguardFadingAway;
311 private long mKeyguardFadingAwayDelay;
312 private long mKeyguardFadingAwayDuration;
313
Jorim Jaggid4a57442014-04-10 02:45:55 +0200314 int mKeyguardMaxNotificationCount;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400315
Joe Onorato808182d2010-07-09 18:52:06 -0400316 boolean mExpandedVisible;
317
John Spurlockd4e65752013-08-28 14:17:09 -0400318 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400319
Joe Onorato808182d2010-07-09 18:52:06 -0400320 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400321 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400322
Joe Onorato808182d2010-07-09 18:52:06 -0400323 // Tracking finger for opening/closing.
Joe Onorato808182d2010-07-09 18:52:06 -0400324 boolean mTracking;
325 VelocityTracker mVelocityTracker;
326
Joe Onorato808182d2010-07-09 18:52:06 -0400327 int[] mAbsPos = new int[2];
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200328 ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
Chet Haase2f2022a2011-10-11 06:41:59 -0700329
Joe Onorato808182d2010-07-09 18:52:06 -0400330 // for disabling the status bar
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100331 int mDisabled1 = 0;
332 int mDisabled2 = 0;
Joe Onorato808182d2010-07-09 18:52:06 -0400333
Daniel Sandler60ee2562011-07-22 12:34:33 -0400334 // tracking calls to View.setSystemUiVisibility()
335 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
336
Adrian Roos389beec2015-05-12 13:33:25 -0700337 // last value sent to window manager
338 private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
339
Daniel Sandler36412a72011-08-04 09:35:13 -0400340 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700341
Daniel Sandler33805342012-07-23 15:45:12 -0400342 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400343 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400344 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400345 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400346
Jason Monk18f99d92014-09-11 13:36:42 -0400347 private ScreenPinningRequest mScreenPinningRequest;
348
Daniel Sandler328310c2011-09-23 15:56:52 -0400349 private int mNavigationIconHints = 0;
Jason Monk4ae97d32014-12-17 10:14:33 -0500350 private HandlerThread mHandlerThread;
Daniel Sandler328310c2011-09-23 15:56:52 -0400351
John Spurlock919adac2012-10-02 16:41:12 -0400352 // ensure quick settings is disabled until the current user makes it through the setup wizard
353 private boolean mUserSetup = false;
354 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
355 @Override
356 public void onChange(boolean selfChange) {
357 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
358 mContext.getContentResolver(),
359 Settings.Secure.USER_SETUP_COMPLETE,
360 0 /*default */,
361 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400362 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400363 "selfChange=%s userSetup=%s mUserSetup=%s",
364 selfChange, userSetup, mUserSetup));
John Spurlock73203eb2014-04-15 16:14:46 -0400365
John Spurlock919adac2012-10-02 16:41:12 -0400366 if (userSetup != mUserSetup) {
367 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400368 if (!mUserSetup && mStatusBarView != null)
369 animateCollapseQuickSettings();
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700370 if (mKeyguardBottomArea != null) {
371 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
372 }
John Spurlock919adac2012-10-02 16:41:12 -0400373 }
John Spurlock604a5ee2015-06-01 12:27:22 -0400374 if (mIconPolicy != null) {
375 mIconPolicy.setCurrentUserSetup(mUserSetup);
376 }
John Spurlock919adac2012-10-02 16:41:12 -0400377 }
378 };
379
Chris Wrenf6e83f42013-09-11 14:02:59 -0400380 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
381 @Override
382 public void onChange(boolean selfChange) {
383 boolean wasUsing = mUseHeadsUp;
Jason Monkf7019542014-07-31 12:42:25 -0400384 mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
385 && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
Chris Wren10d82df2014-03-01 10:34:51 -0500386 mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Chris Wren7bd241232014-02-28 16:25:05 -0500387 Settings.Global.HEADS_UP_OFF);
Chris Wren22ae46e2014-02-26 18:08:09 -0500388 mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
389 mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400390 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
391 if (wasUsing != mUseHeadsUp) {
392 if (!mUseHeadsUp) {
393 Log.d(TAG, "dismissing any existing heads up notification on disable event");
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700394 mHeadsUpManager.releaseAllImmediately();
Chris Wrenf6e83f42013-09-11 14:02:59 -0400395 }
396 }
397 }
398 };
399
John Spurlockcfc359a2013-09-05 10:42:03 -0400400 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400401 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400402 private int mStatusBarMode;
403 private int mNavigationBarMode;
Jorim Jaggid41083a2014-09-12 02:54:40 +0200404
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200405 private ViewMediatorCallback mKeyguardViewMediatorCallback;
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200406 private ScrimController mScrimController;
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100407 private DozeScrimController mDozeScrimController;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200408
John Spurlock32beb2c2013-03-11 10:16:47 -0400409 private final Runnable mAutohide = new Runnable() {
410 @Override
411 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400412 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400413 if (mSystemUiVisibility != requested) {
414 notifyUiVisibilityChanged(requested);
415 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400416 }};
417
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700418 private boolean mWaitingForKeyguardExit;
John Spurlockbf370992014-06-17 13:58:31 -0400419 private boolean mDozing;
Jorim Jaggi83969702015-06-05 14:59:24 -0700420 private boolean mDozingRequested;
Jorim Jaggi0e664392014-09-27 01:30:22 +0200421 private boolean mScrimSrcModeEnabled;
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100422
Jorim Jaggi4e0880e2014-07-25 14:51:50 +0200423 private Interpolator mLinearInterpolator = new LinearInterpolator();
424 private Interpolator mBackdropInterpolator = new AccelerateDecelerateInterpolator();
Jorim Jaggi61d37f62014-07-30 17:26:55 +0200425 public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
426 public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200427
Selim Cineka0fad3b2014-09-19 17:20:05 +0200428 private BackDropView mBackdrop;
Dan Sandler16128f42014-05-21 12:48:22 -0400429 private ImageView mBackdropFront, mBackdropBack;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200430 private PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
431 private PorterDuffXfermode mSrcOverXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
Dan Sandler16128f42014-05-21 12:48:22 -0400432
433 private MediaSessionManager mMediaSessionManager;
434 private MediaController mMediaController;
435 private String mMediaNotificationKey;
436 private MediaMetadata mMediaMetadata;
437 private MediaController.Callback mMediaListener
438 = new MediaController.Callback() {
439 @Override
440 public void onPlaybackStateChanged(PlaybackState state) {
441 super.onPlaybackStateChanged(state);
442 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400443 if (state != null) {
444 if (!isPlaybackActive(state.getState())) {
445 clearCurrentMediaNotification();
446 updateMediaMetaData(true);
447 }
448 }
Dan Sandler16128f42014-05-21 12:48:22 -0400449 }
450
451 @Override
452 public void onMetadataChanged(MediaMetadata metadata) {
453 super.onMetadataChanged(metadata);
454 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
455 mMediaMetadata = metadata;
456 updateMediaMetaData(true);
457 }
458 };
459
460 private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
461 new OnChildLocationsChangedListener() {
462 @Override
463 public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
464 userActivity();
465 }
466 };
467
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100468 private int mDisabledUnmodified1;
469 private int mDisabledUnmodified2;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200470
Christoph Studer92b389d2014-04-01 18:44:40 +0200471 /** Keys of notifications currently visible to the user. */
Chris Wrend1dbc922015-06-19 17:51:16 -0400472 private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications =
473 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200474 private long mLastVisibilityReportUptimeMs;
475
John Spurlockbf370992014-06-17 13:58:31 -0400476 private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
477
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200478 private int mDrawCount;
Selim Cinekbaa23272014-07-08 18:01:07 +0200479 private Runnable mLaunchTransitionEndRunnable;
480 private boolean mLaunchTransitionFadingAway;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +0200481 private ExpandableNotificationRow mDraggedDownRow;
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200482
Christoph Studer2231c6e2014-12-19 12:40:13 +0100483 // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
484 private int mLastLoggedStateFingerprint;
485
Selim Cinekb036ca42015-02-20 15:56:28 +0100486 private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_CARD
Chris Wren35a7c922015-06-22 16:31:01 -0400487 | StackViewState.LOCATION_MAIN_AREA;
Christoph Studer92b389d2014-04-01 18:44:40 +0200488
489 private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
490 new OnChildLocationsChangedListener() {
491 @Override
492 public void onChildLocationsChanged(
493 NotificationStackScrollLayout stackScrollLayout) {
494 if (mHandler.hasCallbacks(mVisibilityReporter)) {
495 // Visibilities will be reported when the existing
496 // callback is executed.
497 return;
498 }
499 // Calculate when we're allowed to run the visibility
500 // reporter. Note that this timestamp might already have
501 // passed. That's OK, the callback will just be executed
502 // ASAP.
503 long nextReportUptimeMs =
504 mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
505 mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
506 }
507 };
508
509 // Tracks notifications currently visible in mNotificationStackScroller and
510 // emits visibility events via NoMan on changes.
511 private final Runnable mVisibilityReporter = new Runnable() {
Chris Wrend1dbc922015-06-19 17:51:16 -0400512 private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
513 new ArraySet<>();
514 private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
515 new ArraySet<>();
516 private final ArraySet<NotificationVisibility> mTmpNoLongerVisibleNotifications =
517 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200518
519 @Override
520 public void run() {
521 mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
Chris Wrend1dbc922015-06-19 17:51:16 -0400522 final String mediaKey = getCurrentMediaNotificationKey();
Christoph Studer92b389d2014-04-01 18:44:40 +0200523
524 // 1. Loop over mNotificationData entries:
525 // A. Keep list of visible notifications.
526 // B. Keep list of previously hidden, now visible notifications.
527 // 2. Compute no-longer visible notifications by removing currently
528 // visible notifications from the set of previously visible
529 // notifications.
530 // 3. Report newly visible and no-longer visible notifications.
531 // 4. Keep currently visible notifications for next report.
Christoph Studerc8db24b2014-07-25 17:50:30 +0200532 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
533 int N = activeNotifications.size();
Christoph Studer92b389d2014-04-01 18:44:40 +0200534 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +0200535 Entry entry = activeNotifications.get(i);
Christoph Studer92b389d2014-04-01 18:44:40 +0200536 String key = entry.notification.getKey();
Chris Wrend1dbc922015-06-19 17:51:16 -0400537 boolean isVisible =
Christoph Studer92b389d2014-04-01 18:44:40 +0200538 (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
Chris Wrend1dbc922015-06-19 17:51:16 -0400539 NotificationVisibility visObj = NotificationVisibility.obtain(key, i, isVisible);
540 boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(visObj);
541 if (isVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +0200542 // Build new set of visible notifications.
Chris Wrend1dbc922015-06-19 17:51:16 -0400543 mTmpCurrentlyVisibleNotifications.add(visObj);
544 if (!previouslyVisible) {
545 mTmpNewlyVisibleNotifications.add(visObj);
546 }
547 } else {
548 // release object
549 visObj.recycle();
Christoph Studer92b389d2014-04-01 18:44:40 +0200550 }
551 }
Chris Wrend1dbc922015-06-19 17:51:16 -0400552 mTmpNoLongerVisibleNotifications.addAll(mCurrentlyVisibleNotifications);
553 mTmpNoLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200554
555 logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -0400556 mTmpNewlyVisibleNotifications, mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200557
Chris Wrend1dbc922015-06-19 17:51:16 -0400558 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200559 mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
560
Chris Wrend1dbc922015-06-19 17:51:16 -0400561 recycleAllVisibilityObjects(mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200562 mTmpCurrentlyVisibleNotifications.clear();
Chris Wrend1dbc922015-06-19 17:51:16 -0400563 mTmpNewlyVisibleNotifications.clear();
564 mTmpNoLongerVisibleNotifications.clear();
Christoph Studer92b389d2014-04-01 18:44:40 +0200565 }
566 };
567
Chris Wrend1dbc922015-06-19 17:51:16 -0400568 private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
569 final int N = array.size();
570 for (int i = 0 ; i < N; i++) {
571 array.valueAt(i).recycle();
572 }
573 array.clear();
574 }
575
Jorim Jaggiecbab362014-04-23 16:13:15 +0200576 private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
577 @Override
578 public void onClick(View v) {
579 goToLockedShade(null);
580 }
581 };
Selim Cinekb5605e52015-02-20 18:21:41 +0100582 private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
583 = new HashMap<>();
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700584 private HashSet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new HashSet<>();
585 private RankingMap mLatestRankingMap;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700586 private boolean mNoAnimationOnNextBarModeChange;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200587
Joe Onorato808182d2010-07-09 18:52:06 -0400588 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400589 public void start() {
590 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
591 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400592 updateDisplaySize();
Jorim Jaggi0e664392014-09-27 01:30:22 +0200593 mScrimSrcModeEnabled = mContext.getResources().getBoolean(
594 R.bool.config_status_bar_scrim_behind_use_src);
Adrian Roos75fa3852015-01-27 20:21:44 +0100595
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500596 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400597
Dan Sandler16128f42014-05-21 12:48:22 -0400598 mMediaSessionManager
599 = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
600 // TODO: use MediaSessionManager.SessionListener to hook us up to future updates
601 // in session state
602
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400603 addNavigationBar();
604
Joe Onorato808182d2010-07-09 18:52:06 -0400605 // Lastly, call to the icon policy to install/update all the icons.
Adrian Roos88b11932015-07-22 14:59:48 -0700606 mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController,
Jason Monk70364362015-08-06 16:32:18 -0400607 mUserInfoController, mBluetoothController);
John Spurlock604a5ee2015-06-01 12:27:22 -0400608 mIconPolicy.setCurrentUserSetup(mUserSetup);
John Spurlocke677d712014-02-13 12:52:19 -0500609 mSettingsObserver.onChange(false); // set up
Chris Wrenf6e83f42013-09-11 14:02:59 -0400610
611 mHeadsUpObserver.onChange(true); // set up
612 if (ENABLE_HEADS_UP) {
613 mContext.getContentResolver().registerContentObserver(
Chris Wren10d82df2014-03-01 10:34:51 -0500614 Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
Chris Wrenf6e83f42013-09-11 14:02:59 -0400615 mHeadsUpObserver);
Chris Wren22ae46e2014-02-26 18:08:09 -0500616 mContext.getContentResolver().registerContentObserver(
617 Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
618 mHeadsUpObserver);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400619 }
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200620 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Christoph Studer2231c6e2014-12-19 12:40:13 +0100621 mUnlockMethodCache.addListener(this);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100622 startKeyguard();
John Spurlockbf370992014-06-17 13:58:31 -0400623
624 mDozeServiceHost = new DozeServiceHost();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700625 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mDozeServiceHost);
Jeff Brown4d69e222014-09-18 15:27:50 -0700626 putComponent(DozeHost.class, mDozeServiceHost);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200627 putComponent(PhoneStatusBar.class, this);
John Spurlock89f060a2014-07-16 21:03:15 -0400628
629 setControllerUsers();
Chris Wrencd8f4f72014-08-27 18:48:13 -0400630
631 notifyUserAboutHiddenNotifications();
Jason Monk18f99d92014-09-11 13:36:42 -0400632
633 mScreenPinningRequest = new ScreenPinningRequest(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400634 }
635
636 // ================================================================================
637 // Constructing the view
638 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700639 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400640 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400641
642 Resources res = context.getResources();
643
Daniel Sandler6e8db882011-10-26 15:40:51 -0400644 updateDisplaySize(); // populates mDisplayMetrics
Jorim Jaggi2e115c52014-07-01 21:27:58 +0200645 updateResources();
Joe Onorato808182d2010-07-09 18:52:06 -0400646
Daniel Sandlerc4f2a562012-05-04 11:55:46 -0400647 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
Daniel Sandlera310af82012-04-24 01:20:13 -0400648 R.layout.super_status_bar, null);
Selim Cinek4e6b2d32015-06-25 20:15:33 -0400649 mStatusBarWindow.setService(this);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400650 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
651 @Override
652 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400653 checkUserAutohide(v, event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400654 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500655 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400656 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400657 }
658 }
Chris Wren5de6e942012-05-16 14:22:21 -0400659 return mStatusBarWindow.onTouchEvent(event);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700660 }
661 });
Daniel Sandler21b274e2012-05-02 15:07:51 -0400662
Daniel Sandlera310af82012-04-24 01:20:13 -0400663 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
Daniel Sandler08d05e32012-08-08 16:39:54 -0400664 mStatusBarView.setBar(this);
John Spurlock209bede2013-07-17 12:23:27 -0400665
Daniel Sandler08d05e32012-08-08 16:39:54 -0400666 PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
667 mStatusBarView.setPanelHolder(holder);
668
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100669 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
670 R.id.notification_panel);
Daniel Sandler040c2e42012-10-17 00:56:33 -0400671 mNotificationPanel.setStatusBar(this);
Joe Onorato808182d2010-07-09 18:52:06 -0400672
Jeff Brown98365d72012-08-19 20:30:52 -0700673 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700674 mStatusBarWindow.setBackground(null);
Alan Viverette4a357cd2015-03-18 18:37:18 -0700675 mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
Romain Guy648342f2012-05-25 10:44:45 -0700676 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700677 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700678
Selim Cinek737bff32015-05-08 16:08:35 -0700679 mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700680 mHeadsUpManager.setBar(this);
681 mHeadsUpManager.addListener(this);
682 mHeadsUpManager.addListener(mNotificationPanel);
683 mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
Selim Cinekfbe9a442015-04-13 16:09:49 -0700684 mNotificationData.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700685
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400686 if (MULTIUSER_DEBUG) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100687 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
688 R.id.header_debug_info);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400689 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
690 }
Joe Onorato808182d2010-07-09 18:52:06 -0400691
Daniel Sandler0129b312011-05-11 11:54:11 -0400692 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700693 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400694 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400695 if (showNav) {
Jim Miller5e6af442011-12-02 18:24:26 -0800696 mNavigationBarView =
Daniel Sandler0129b312011-05-11 11:54:11 -0400697 (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400698
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100699 mNavigationBarView.setDisabledFlags(mDisabled1);
Jim Millere898ac52012-04-06 17:10:57 -0700700 mNavigationBarView.setBar(this);
Jorim Jaggif4797922014-08-04 22:49:41 +0200701 mNavigationBarView.setOnVerticalChangedListener(
702 new NavigationBarView.OnVerticalChangedListener() {
703 @Override
704 public void onVerticalChanged(boolean isVertical) {
Selim Cineke70d6532015-04-24 16:46:13 -0700705 if (mAssistManager != null) {
706 mAssistManager.onConfigurationChanged();
Jorim Jaggif4797922014-08-04 22:49:41 +0200707 }
Jorim Jaggidd5b8862014-08-05 21:04:39 +0200708 mNotificationPanel.setQsScrimEnabled(!isVertical);
Jorim Jaggif4797922014-08-04 22:49:41 +0200709 }
710 });
John Spurlock9deaa282013-07-25 13:03:47 -0400711 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
712 @Override
713 public boolean onTouch(View v, MotionEvent event) {
714 checkUserAutohide(v, event);
715 return false;
716 }});
Daniel Sandler0129b312011-05-11 11:54:11 -0400717 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400718 } catch (RemoteException ex) {
719 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400720 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400721
Selim Cineke70d6532015-04-24 16:46:13 -0700722 mAssistManager = new AssistManager(this, context);
723
Joe Onorato808182d2010-07-09 18:52:06 -0400724 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400725 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400726
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100727 mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
728 R.id.notification_stack_scroller);
729 mStackScroller.setLongPressListener(getNotificationLongClicker());
Selim Cinek19c8c702014-08-25 22:09:19 +0200730 mStackScroller.setPhoneStatusBar(this);
Selim Cinekb5605e52015-02-20 18:21:41 +0100731 mStackScroller.setGroupManager(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700732 mStackScroller.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb5605e52015-02-20 18:21:41 +0100733 mGroupManager.setOnGroupChangeListener(mStackScroller);
Selim Cinek80a14e52014-03-27 16:58:04 +0100734
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200735 mKeyguardIconOverflowContainer =
736 (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
737 R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
738 mKeyguardIconOverflowContainer.setOnActivatedListener(this);
Jorim Jaggie96fcd12014-05-07 21:10:35 +0200739 mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
Selim Cinek2cd45df2015-06-09 18:00:07 -0700740 mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
Jorim Jaggid4a57442014-04-10 02:45:55 +0200741
Selim Cinekc27437b2014-05-14 10:23:33 +0200742 SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate(
743 R.layout.status_bar_notification_speed_bump, mStackScroller, false);
744 mStackScroller.setSpeedBumpView(speedBump);
Selim Cinekbecf5e32014-08-12 14:29:18 +0200745 mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
746 R.layout.status_bar_no_notifications, mStackScroller, false);
747 mStackScroller.setEmptyShadeView(mEmptyShadeView);
Dan Sandlereceda3d2014-07-21 15:35:01 -0400748 mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
749 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
750 mDismissView.setOnButtonClickListener(new View.OnClickListener() {
751 @Override
752 public void onClick(View v) {
Chris Wren9763d422015-04-30 15:24:05 -0400753 MetricsLogger.action(mContext, MetricsLogger.ACTION_DISMISS_ALL_NOTES);
Dan Sandlereceda3d2014-07-21 15:35:01 -0400754 clearAllNotifications();
755 }
756 });
757 mStackScroller.setDismissView(mDismissView);
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100758 mExpandedContents = mStackScroller;
Selim Cinek67b22602014-03-10 15:40:16 +0100759
Selim Cineka0fad3b2014-09-19 17:20:05 +0200760 mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
761 mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
762 mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
763
764 ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
765 ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
Selim Cinekaac93252015-04-14 20:04:12 -0700766 View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
767 mScrimController = new ScrimController(scrimBehind, scrimInFront, headsUpScrim,
768 mScrimSrcModeEnabled);
769 mHeadsUpManager.addListener(mScrimController);
770 mStackScroller.setScrimController(mScrimController);
Selim Cineka0fad3b2014-09-19 17:20:05 +0200771 mScrimController.setBackDropView(mBackdrop);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200772 mStatusBarView.setScrimController(mScrimController);
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100773 mDozeScrimController = new DozeScrimController(mScrimController, context);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200774
Jorim Jaggi0d74eeb2014-05-09 22:05:24 +0200775 mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
Jorim Jaggi13c1b1f2014-05-11 21:55:00 +0200776 mHeader.setActivityStarter(this);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200777 mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200778 mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200779 mKeyguardBottomArea =
780 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
781 mKeyguardBottomArea.setActivityStarter(this);
Selim Cineke70d6532015-04-24 16:46:13 -0700782 mKeyguardBottomArea.setAssistManager(mAssistManager);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200783 mKeyguardIndicationController = new KeyguardIndicationController(mContext,
784 (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700785 R.id.keyguard_indication_text),
786 mKeyguardBottomArea.getLockIcon());
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200787 mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400788
Joe Onorato808182d2010-07-09 18:52:06 -0400789 // set the inital view visibility
790 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400791
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100792 mIconController = new StatusBarIconController(
793 mContext, mStatusBarView, mKeyguardStatusBar, this);
794
Jason Monk4ae97d32014-12-17 10:14:33 -0500795 // Background thread for any controllers that need it.
796 mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
797 mHandlerThread.start();
798
Daniel Sandler2b697352011-07-22 16:23:09 -0400799 // Other icons
Jason Monk05b86bc2015-05-19 14:21:28 -0400800 mLocationController = new LocationControllerImpl(mContext,
801 mHandlerThread.getLooper()); // will post a notification
Daniel Sandler2b697352011-07-22 16:23:09 -0400802 mBatteryController = new BatteryController(mContext);
John Spurlock0ff62e02014-07-22 16:15:08 -0400803 mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
804 @Override
805 public void onPowerSaveChanged() {
806 mHandler.post(mCheckBarModes);
John Spurlockd96179e2014-08-21 16:43:45 -0400807 if (mDozeServiceHost != null) {
808 mDozeServiceHost.firePowerSaveChanged(mBatteryController.isPowerSave());
809 }
John Spurlock0ff62e02014-07-22 16:15:08 -0400810 }
811 @Override
812 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
813 // noop
814 }
815 });
Jason Monk30d80042015-05-08 16:54:18 -0400816 mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk51e4dc02014-07-22 12:00:47 -0400817 mHotspotController = new HotspotControllerImpl(mContext);
Jason Monk4ae97d32014-12-17 10:14:33 -0500818 mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk3d5f5512014-07-25 11:17:28 -0400819 mSecurityController = new SecurityControllerImpl(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400820 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
821 mRotationLockController = new RotationLockControllerImpl(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500822 }
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200823 mUserInfoController = new UserInfoController(mContext);
John Spurlock86005342014-05-23 11:58:00 -0400824 mVolumeComponent = getComponent(VolumeComponent.class);
John Spurlockf2565a82014-10-23 20:16:22 -0400825 if (mVolumeComponent != null) {
826 mZenModeController = mVolumeComponent.getZenController();
827 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400828 mCastController = new CastControllerImpl(mContext);
Jim Miller5e6af442011-12-02 18:24:26 -0800829 final SignalClusterView signalCluster =
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200830 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
831 final SignalClusterView signalClusterKeyguard =
832 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200833 final SignalClusterView signalClusterQs =
834 (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
Jason Monk07b75fe2015-05-14 16:47:03 -0400835 mNetworkController.addSignalCallback(signalCluster);
836 mNetworkController.addSignalCallback(signalClusterKeyguard);
837 mNetworkController.addSignalCallback(signalClusterQs);
Jason Monk3128f122014-09-03 13:18:57 -0400838 signalCluster.setSecurityController(mSecurityController);
Daniel Sandler28f89d42011-08-15 14:04:15 -0400839 signalCluster.setNetworkController(mNetworkController);
Jason Monk3128f122014-09-03 13:18:57 -0400840 signalClusterKeyguard.setSecurityController(mSecurityController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200841 signalClusterKeyguard.setNetworkController(mNetworkController);
Jason Monk3128f122014-09-03 13:18:57 -0400842 signalClusterQs.setSecurityController(mSecurityController);
Jorim Jaggi06d551a2014-09-02 15:55:57 +0200843 signalClusterQs.setNetworkController(mNetworkController);
Daniel Sandler8b268d42013-05-28 16:17:13 -0400844 final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
845 if (isAPhone) {
Jason Monkc6cc6262015-06-11 11:10:15 -0400846 mNetworkController.addEmergencyListener(mHeader);
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400847 }
848
Adrian Roosb83777b2014-06-30 15:11:53 +0200849 mFlashlightController = new FlashlightController(mContext);
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200850 mKeyguardBottomArea.setFlashlightController(mFlashlightController);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200851 mKeyguardBottomArea.setPhoneStatusBar(this);
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700852 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200853 mAccessibilityController = new AccessibilityController(mContext);
854 mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200855 mNextAlarmController = new NextAlarmController(mContext);
Jason Monk8a3a9642015-06-05 11:01:30 -0400856 mKeyguardMonitor = new KeyguardMonitor(mContext);
Adrian Roos2b154a92014-11-17 15:18:39 +0100857 if (UserSwitcherController.isUserSwitcherAvailable(UserManager.get(mContext))) {
Adrian Roos88b11932015-07-22 14:59:48 -0700858 mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
859 mHandler);
Adrian Roos2b154a92014-11-17 15:18:39 +0100860 }
Adrian Roos723632e2014-07-23 21:13:21 +0200861 mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200862 (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
Jorim Jaggibf1899e2014-08-07 02:04:18 +0200863 mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
Adrian Roos723632e2014-07-23 21:13:21 +0200864
865
John Spurlockaf8d6c42014-05-07 17:49:08 -0400866 // Set up the quick settings tile panel
867 mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel);
868 if (mQSPanel != null) {
869 final QSTileHost qsh = new QSTileHost(mContext, this,
870 mBluetoothController, mLocationController, mRotationLockController,
Jason Monk51e4dc02014-07-22 12:00:47 -0400871 mNetworkController, mZenModeController, mHotspotController,
John Spurlock657c62c2014-07-22 12:18:09 -0400872 mCastController, mFlashlightController,
Jason Monk3d5f5512014-07-25 11:17:28 -0400873 mUserSwitcherController, mKeyguardMonitor,
874 mSecurityController);
Adrian Roos1ef80fe2014-07-14 22:53:54 +0200875 mQSPanel.setHost(qsh);
John Spurlockbceed062014-08-10 18:04:16 -0400876 mQSPanel.setTiles(qsh.getTiles());
Adrian Roos5fd872e2014-08-12 17:28:58 +0200877 mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
878 mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400879 mHeader.setQSPanel(mQSPanel);
John Spurlockbceed062014-08-10 18:04:16 -0400880 qsh.setCallback(new QSTileHost.Callback() {
881 @Override
882 public void onTilesChanged() {
883 mQSPanel.setTiles(qsh.getTiles());
884 }
885 });
Siva Velusamy537421b2012-09-14 14:45:02 -0700886 }
887
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200888 // User info. Trigger first load.
889 mHeader.setUserInfoController(mUserInfoController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200890 mKeyguardStatusBar.setUserInfoController(mUserInfoController);
Adrian Roosffc90972015-06-09 18:09:49 -0700891 mKeyguardStatusBar.setUserSwitcherController(mUserSwitcherController);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200892 mUserInfoController.reloadUserInfo();
893
Jorim Jaggi853b0702014-07-05 04:31:14 +0200894 mHeader.setBatteryController(mBatteryController);
Jorim Jaggi708f7722014-08-20 17:30:38 +0200895 ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
896 mBatteryController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200897 mKeyguardStatusBar.setBatteryController(mBatteryController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200898 mHeader.setNextAlarmController(mNextAlarmController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200899
John Spurlock56d007b2013-10-28 18:40:56 -0400900 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
901 mBroadcastReceiver.onReceive(mContext,
902 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
903
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700904
Joe Onorato808182d2010-07-09 18:52:06 -0400905 // receive broadcasts
906 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400907 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
908 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400909 filter.addAction(Intent.ACTION_SCREEN_ON);
Kenny Guy44fc65f2014-11-28 22:18:14 +0000910 context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400911
Adrian Roos8e3e8362015-07-16 19:42:22 -0700912 IntentFilter demoFilter = new IntentFilter();
913 if (DEBUG_MEDIA_FAKE_ARTWORK) {
914 demoFilter.addAction(ACTION_FAKE_ARTWORK);
915 }
916 demoFilter.addAction(ACTION_DEMO);
917 context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
918 android.Manifest.permission.DUMP, null);
919
John Spurlock919adac2012-10-02 16:41:12 -0400920 // listen for USER_SETUP_COMPLETE setting (per-user)
921 resetUserSetupObserver();
922
Chris Craik2507c342015-05-04 14:36:49 -0700923 // disable profiling bars, since they overlap and clutter the output on app windows
924 ThreadedRenderer.overrideProperty("disableProfileBars", "true");
925
926 // Private API call to make the shadows look better for Recents
927 ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
928
Daniel Sandlera310af82012-04-24 01:20:13 -0400929 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400930 }
931
Dan Sandlereceda3d2014-07-21 15:35:01 -0400932 private void clearAllNotifications() {
933
934 // animate-swipe all dismissable notifications, then animate the shade closed
935 int numChildren = mStackScroller.getChildCount();
936
937 final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
938 for (int i = 0; i < numChildren; i++) {
939 final View child = mStackScroller.getChildAt(i);
Selim Cinekb5605e52015-02-20 18:21:41 +0100940 if (child instanceof ExpandableNotificationRow) {
941 if (mStackScroller.canChildBeDismissed(child)) {
942 if (child.getVisibility() == View.VISIBLE) {
943 viewsToHide.add(child);
944 }
945 }
946 ExpandableNotificationRow row = (ExpandableNotificationRow) child;
947 List<ExpandableNotificationRow> children = row.getNotificationChildren();
948 if (row.areChildrenExpanded() && children != null) {
949 for (ExpandableNotificationRow childRow : children) {
950 if (childRow.getVisibility() == View.VISIBLE) {
951 viewsToHide.add(childRow);
952 }
953 }
Dan Sandlereceda3d2014-07-21 15:35:01 -0400954 }
955 }
956 }
957 if (viewsToHide.isEmpty()) {
958 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
959 return;
960 }
961
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200962 addPostCollapseAction(new Runnable() {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400963 @Override
964 public void run() {
Selim Cinek9c17b772015-07-07 20:37:09 -0700965 mStackScroller.setDismissAllInProgress(false);
Dan Sandlereceda3d2014-07-21 15:35:01 -0400966 try {
967 mBarService.onClearAllNotifications(mCurrentUserId);
968 } catch (Exception ex) { }
969 }
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200970 });
Dan Sandlereceda3d2014-07-21 15:35:01 -0400971
972 performDismissAllAnimations(viewsToHide);
973
974 }
975
976 private void performDismissAllAnimations(ArrayList<View> hideAnimatedList) {
977 Runnable animationFinishAction = new Runnable() {
978 @Override
979 public void run() {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400980 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
981 }
982 };
983
984 // let's disable our normal animations
985 mStackScroller.setDismissAllInProgress(true);
986
987 // Decrease the delay for every row we animate to give the sense of
988 // accelerating the swipes
989 int rowDelayDecrement = 10;
990 int currentDelay = 140;
Selim Cinek7d5f3742014-11-07 18:07:49 +0100991 int totalDelay = 180;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400992 int numItems = hideAnimatedList.size();
Selim Cinek7d5f3742014-11-07 18:07:49 +0100993 for (int i = numItems - 1; i >= 0; i--) {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400994 View view = hideAnimatedList.get(i);
995 Runnable endRunnable = null;
Selim Cinek7d5f3742014-11-07 18:07:49 +0100996 if (i == 0) {
Dan Sandlereceda3d2014-07-21 15:35:01 -0400997 endRunnable = animationFinishAction;
998 }
999 mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
1000 currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
1001 totalDelay += currentDelay;
1002 }
1003 }
1004
John Spurlockae641c92014-06-30 18:11:40 -04001005 @Override
1006 protected void setZenMode(int mode) {
1007 super.setZenMode(mode);
1008 if (mIconPolicy != null) {
1009 mIconPolicy.setZenMode(mode);
1010 }
1011 }
1012
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001013 private void startKeyguard() {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001014 KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
1015 mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
Jorim Jaggiecc798e2014-05-26 18:14:37 +02001016 mStatusBarWindow, mStatusBarWindowManager, mScrimController);
Selim Cinekcfafe4e2015-08-11 14:58:44 -07001017 mKeyguardIndicationController.setStatusBarKeyguardViewManager(
1018 mStatusBarKeyguardViewManager);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001019 mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001020 }
1021
Michael Jurka7f2668c2012-03-27 07:49:52 -07001022 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -07001023 protected View getStatusBarView() {
1024 return mStatusBarView;
1025 }
1026
Jorim Jaggi0a27be82014-06-11 03:22:39 +02001027 public StatusBarWindowView getStatusBarWindow() {
1028 return mStatusBarWindow;
1029 }
1030
Joe Onoratodc100302011-01-11 17:07:41 -08001031 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -04001032 if (mNaturalBarHeight < 0) {
1033 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -07001034 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -04001035 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
1036 }
1037 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -08001038 }
1039
Daniel Sandler5c8da942011-06-28 00:29:04 -04001040 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
1041 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -04001042 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001043 toggleRecentApps();
1044 }
1045 };
Chris Wren0c8275b2012-05-08 13:36:48 -04001046
Jason Monk815e0572014-08-12 17:26:36 -04001047 private long mLastLockToAppLongPress;
Jason Monk815e0572014-08-12 17:26:36 -04001048 private View.OnLongClickListener mLongPressBackRecentsListener =
1049 new View.OnLongClickListener() {
Jason Monk62515be2014-05-21 16:06:19 -04001050 @Override
1051 public boolean onLongClick(View v) {
Jason Monk815e0572014-08-12 17:26:36 -04001052 handleLongPressBackRecents(v);
Jason Monk62515be2014-05-21 16:06:19 -04001053 return true;
1054 }
1055 };
1056
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001057 private final View.OnLongClickListener mLongPressHomeListener
1058 = new View.OnLongClickListener() {
1059 @Override
1060 public boolean onLongClick(View v) {
1061 if (shouldDisableNavbarGestures()) {
1062 return false;
1063 }
Chris Wrena35c96e2015-08-06 14:53:32 -04001064 MetricsLogger.action(mContext, MetricsLogger.ACTION_ASSIST_LONG_PRESS);
Jorim Jaggi165ce062015-07-06 16:18:11 -07001065 mAssistManager.startAssist(new Bundle() /* args */);
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001066 awakenDreams();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001067 if (mNavigationBarView != null) {
Xiyuan Xiaee7dd052015-05-15 09:46:27 -07001068 mNavigationBarView.abortCurrentGesture();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001069 }
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001070 return true;
Jim Miller9a720f52012-05-30 03:19:43 -07001071 }
1072 };
1073
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001074 private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
Jim Millere898ac52012-04-06 17:10:57 -07001075 public boolean onTouch(View v, MotionEvent event) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001076 switch (event.getAction()) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001077 case MotionEvent.ACTION_UP:
1078 case MotionEvent.ACTION_CANCEL:
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001079 awakenDreams();
1080 break;
1081 }
1082 return false;
Jim Millere898ac52012-04-06 17:10:57 -07001083 }
1084 };
Daniel Sandler5c8da942011-06-28 00:29:04 -04001085
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001086 private void awakenDreams() {
1087 if (mDreamManager != null) {
1088 try {
1089 mDreamManager.awaken();
1090 } catch (RemoteException e) {
1091 // fine, stay asleep then
1092 }
1093 }
1094 }
1095
Michael Jurka412cba82011-10-17 09:05:00 -07001096 private void prepareNavigationBarView() {
1097 mNavigationBarView.reorient();
1098
1099 mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
Michael Jurka80343f62012-10-18 13:13:46 +02001100 mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
Jason Monk62515be2014-05-21 16:06:19 -04001101 mNavigationBarView.getRecentsButton().setLongClickable(true);
Jason Monk815e0572014-08-12 17:26:36 -04001102 mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener);
1103 mNavigationBarView.getBackButton().setLongClickable(true);
1104 mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);
Jorim Jaggi7b0de292014-05-27 21:41:55 +02001105 mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001106 mNavigationBarView.getHomeButton().setOnLongClickListener(mLongPressHomeListener);
Selim Cineke70d6532015-04-24 16:46:13 -07001107 mAssistManager.onConfigurationChanged();
Michael Jurka412cba82011-10-17 09:05:00 -07001108 }
1109
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001110 // For small-screen devices (read: phones) that lack hardware navigation buttons
1111 private void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -04001112 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -04001113 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001114
Michael Jurka412cba82011-10-17 09:05:00 -07001115 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001116
Jeff Brown98365d72012-08-19 20:30:52 -07001117 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001118 }
1119
1120 private void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -04001121 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001122
Michael Jurka412cba82011-10-17 09:05:00 -07001123 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001124
Jeff Brown98365d72012-08-19 20:30:52 -07001125 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001126 }
1127
John Spurlock1bbd49d2012-10-19 11:09:32 -04001128 private void notifyNavigationBarScreenOn(boolean screenOn) {
1129 if (mNavigationBarView == null) return;
1130 mNavigationBarView.notifyScreenOn(screenOn);
1131 }
1132
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001133 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001134 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001135 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001136 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
1137 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001138 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1139 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -07001140 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -04001141 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -07001142 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
John Spurlockad3e6cb2013-04-30 08:47:43 -04001143 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001144 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -07001145 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001146 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
1147 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001148
1149 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001150 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001151 return lp;
1152 }
1153
Joe Onorato808182d2010-07-09 18:52:06 -04001154 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001155 mIconController.addSystemIcon(slot, index, viewIndex, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001156 }
1157
1158 public void updateIcon(String slot, int index, int viewIndex,
1159 StatusBarIcon old, StatusBarIcon icon) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001160 mIconController.updateSystemIcon(slot, index, viewIndex, old, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001161 }
1162
1163 public void removeIcon(String slot, int index, int viewIndex) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001164 mIconController.removeSystemIcon(slot, index, viewIndex);
Joe Onorato808182d2010-07-09 18:52:06 -04001165 }
1166
John Spurlockbf20eab2014-04-09 16:40:39 -04001167 public UserHandle getCurrentUserHandle() {
1168 return new UserHandle(mCurrentUserId);
1169 }
1170
Christoph Studer71f18fd2014-05-20 17:02:04 +02001171 @Override
Selim Cinek379ff8f2015-02-20 17:03:16 +01001172 public void addNotification(StatusBarNotification notification, RankingMap ranking,
1173 Entry oldEntry) {
Chris Wrenaaa58d12014-06-03 14:29:12 -04001174 if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
Chris Wrend4db6cb2013-08-07 16:05:23 -04001175
Selim Cinek8d490d42015-04-10 00:05:50 -07001176 Entry shadeEntry = createNotificationViews(notification);
Chris Wrena4ef6202014-06-09 18:07:30 -04001177 if (shadeEntry == null) {
1178 return;
1179 }
Selim Cinekb18a20f2015-06-04 17:08:35 +02001180 boolean isHeadsUped = mUseHeadsUp && shouldInterrupt(shadeEntry);
Selim Cinek31d9ef72015-04-15 19:29:49 -07001181 if (isHeadsUped) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001182 mHeadsUpManager.showNotification(shadeEntry);
Amith Yamasanif47e51e2015-04-17 10:02:15 -07001183 // Mark as seen immediately
1184 setNotificationShown(notification);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001185 }
Chris Wrena4ef6202014-06-09 18:07:30 -04001186
Selim Cinek31d9ef72015-04-15 19:29:49 -07001187 if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
John Spurlockbf20eab2014-04-09 16:40:39 -04001188 // Stop screensaver if the notification has a full-screen intent.
1189 // (like an incoming phone call)
1190 awakenDreams();
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -04001191
John Spurlockbf20eab2014-04-09 16:40:39 -04001192 // not immersive & a full-screen alert should be shown
1193 if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
1194 try {
Chris Wren223c66b62014-11-10 16:00:09 -05001195 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
1196 notification.getKey());
John Spurlockbf20eab2014-04-09 16:40:39 -04001197 notification.getNotification().fullScreenIntent.send();
Selim Cinekb18a20f2015-06-04 17:08:35 +02001198 shadeEntry.notifyFullScreenIntentLaunched();
Chris Wrenb659c4f2015-06-25 17:12:27 -04001199 MetricsLogger.count(mContext, "note_fullscreen", 1);
John Spurlockbf20eab2014-04-09 16:40:39 -04001200 } catch (PendingIntent.CanceledException e) {
1201 }
Joe Onorato808182d2010-07-09 18:52:06 -04001202 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001203 addNotificationViews(shadeEntry, ranking);
Joe Onorato808182d2010-07-09 18:52:06 -04001204 // Recalculate the position of the sliding windows and the titles.
1205 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001206 }
1207
Chris Wren51c75102013-07-16 20:49:17 -04001208 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001209 protected void updateNotificationRanking(RankingMap ranking) {
Chris Wren333a61c2014-05-28 16:40:57 -04001210 mNotificationData.updateRanking(ranking);
Chris Wren333a61c2014-05-28 16:40:57 -04001211 updateNotifications();
1212 }
1213
1214 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001215 public void removeNotification(String key, RankingMap ranking) {
Selim Cinek684a4422015-04-15 16:18:39 -07001216 boolean deferRemoval = false;
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001217 if (mHeadsUpManager.isHeadsUp(key)) {
Selim Cinek684a4422015-04-15 16:18:39 -07001218 deferRemoval = !mHeadsUpManager.removeNotification(key);
Chris Wrena4ef6202014-06-09 18:07:30 -04001219 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001220 if (key.equals(mMediaNotificationKey)) {
1221 clearCurrentMediaNotification();
1222 updateMediaMetaData(true);
1223 }
Selim Cinek684a4422015-04-15 16:18:39 -07001224 if (deferRemoval) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001225 mLatestRankingMap = ranking;
1226 mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
1227 return;
1228 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001229 StatusBarNotification old = removeNotificationViews(key, ranking);
John Spurlockcd686b52013-06-05 10:13:46 -04001230 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -04001231
1232 if (old != null) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001233 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
Jorim Jaggiba94f882014-08-20 19:23:55 +02001234 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001235 if (mState == StatusBarState.SHADE) {
1236 animateCollapsePanels();
1237 } else if (mState == StatusBarState.SHADE_LOCKED) {
1238 goToKeyguard();
1239 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001240 }
Joe Onorato808182d2010-07-09 18:52:06 -04001241 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001242 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001243 }
1244
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001245 @Override
1246 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001247 if (mNavigationBarView != null) {
1248 mNavigationBarView.setLayoutDirection(layoutDirection);
1249 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001250 }
1251
Christoph Studer37fe6932014-05-26 13:10:30 +02001252 private void updateNotificationShade() {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001253 if (mStackScroller == null) return;
Daniel Sandler26cda272012-05-22 15:44:08 -04001254
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001255 // Do not modify the notifications during collapse.
1256 if (isCollapsing()) {
1257 addPostCollapseAction(new Runnable() {
1258 @Override
1259 public void run() {
1260 updateNotificationShade();
1261 }
1262 });
1263 return;
1264 }
1265
Christoph Studerc8db24b2014-07-25 17:50:30 +02001266 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
Jorim Jaggif6411742014-08-05 17:10:43 +00001267 ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
Christoph Studerc8db24b2014-07-25 17:50:30 +02001268 final int N = activeNotifications.size();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001269 for (int i=0; i<N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001270 Entry ent = activeNotifications.get(i);
1271 int vis = ent.notification.getNotification().visibility;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001272
Christoph Studerc8db24b2014-07-25 17:50:30 +02001273 // Display public version of the notification if we need to redact.
Jorim Jaggiae441282014-08-01 02:45:18 +02001274 final boolean hideSensitive =
1275 !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId());
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001276 boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE;
1277 boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey());
1278 boolean sensitive = (sensitiveNote && hideSensitive) || sensitivePackage;
1279 boolean showingPublic = sensitive && isLockscreenPublicMode();
1280 ent.row.setSensitive(sensitive);
Dan Sandler1b718782014-07-18 12:43:45 -04001281 if (ent.autoRedacted && ent.legacy) {
Jorim Jaggiae441282014-08-01 02:45:18 +02001282 // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
1283 // for legacy auto redacted notifications.
Dan Sandler1b718782014-07-18 12:43:45 -04001284 if (showingPublic) {
1285 ent.row.setShowingLegacyBackground(false);
1286 } else {
1287 ent.row.setShowingLegacyBackground(true);
1288 }
1289 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001290 if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
1291 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
1292 ent.row.getStatusBarNotification());
1293 List<ExpandableNotificationRow> orderedChildren =
1294 mTmpChildOrderMap.get(summary);
1295 if (orderedChildren == null) {
1296 orderedChildren = new ArrayList<>();
1297 mTmpChildOrderMap.put(summary, orderedChildren);
1298 }
1299 orderedChildren.add(ent.row);
1300 } else {
1301 toShow.add(ent.row);
1302 }
1303
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001304 }
1305
Selim Cinekb5605e52015-02-20 18:21:41 +01001306 ArrayList<View> toRemove = new ArrayList<>();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001307 for (int i=0; i< mStackScroller.getChildCount(); i++) {
1308 View child = mStackScroller.getChildAt(i);
Jorim Jaggif6411742014-08-05 17:10:43 +00001309 if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001310 toRemove.add(child);
Joe Onorato808182d2010-07-09 18:52:06 -04001311 }
1312 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001313
1314 for (View remove : toRemove) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001315 mStackScroller.removeView(remove);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001316 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001317 for (int i=0; i<toShow.size(); i++) {
1318 View v = toShow.get(i);
1319 if (v.getParent() == null) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001320 mStackScroller.addView(v);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001321 }
1322 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001323
Christoph Studer37fe6932014-05-26 13:10:30 +02001324 // So after all this work notifications still aren't sorted correctly.
1325 // Let's do that now by advancing through toShow and mStackScroller in
1326 // lock-step, making sure mStackScroller matches what we see in toShow.
1327 int j = 0;
1328 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1329 View child = mStackScroller.getChildAt(i);
1330 if (!(child instanceof ExpandableNotificationRow)) {
1331 // We don't care about non-notification views.
1332 continue;
1333 }
1334
Selim Cinekb5605e52015-02-20 18:21:41 +01001335 ExpandableNotificationRow targetChild = toShow.get(j);
1336 if (child != targetChild) {
1337 // Oops, wrong notification at this position. Put the right one
1338 // here and advance both lists.
1339 mStackScroller.changeViewPosition(targetChild, i);
Christoph Studer37fe6932014-05-26 13:10:30 +02001340 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001341 j++;
Selim Cinekb5605e52015-02-20 18:21:41 +01001342
Christoph Studer37fe6932014-05-26 13:10:30 +02001343 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001344
1345 // lets handle the child notifications now
1346 updateNotificationShadeForChildren();
1347
1348 // clear the map again for the next usage
1349 mTmpChildOrderMap.clear();
1350
Christoph Studer37fe6932014-05-26 13:10:30 +02001351 updateRowStates();
Jorim Jaggif6411742014-08-05 17:10:43 +00001352 updateSpeedbump();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001353 updateClearAll();
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001354 updateEmptyShadeView();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001355
Benjamin Franz27cf1462015-04-23 19:36:42 +01001356 updateQsExpansionEnabled();
1357 mShadeUpdates.check();
1358 }
1359
1360 /**
1361 * Disable QS if device not provisioned.
1362 * If the user switcher is simple then disable QS during setup because
1363 * the user intends to use the lock screen user switcher, QS in not needed.
1364 */
1365 private void updateQsExpansionEnabled() {
Jason Monk3ad242d2014-09-15 11:13:35 -04001366 mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
Adrian Roos2b154a92014-11-17 15:18:39 +01001367 && (mUserSetup || mUserSwitcherController == null
Benjamin Franz27cf1462015-04-23 19:36:42 +01001368 || !mUserSwitcherController.isSimpleUserSwitcher())
Adrian Roos21d2a252015-06-01 13:59:59 -07001369 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
1370 && !ONLY_CORE_APPS);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001371 }
1372
Selim Cinekb5605e52015-02-20 18:21:41 +01001373 private void updateNotificationShadeForChildren() {
1374 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
1375 boolean orderChanged = false;
1376 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1377 View view = mStackScroller.getChildAt(i);
1378 if (!(view instanceof ExpandableNotificationRow)) {
1379 // We don't care about non-notification views.
1380 continue;
1381 }
1382
1383 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1384 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1385 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1386
1387 // lets first remove all undesired children
1388 if (children != null) {
1389 toRemove.clear();
1390 for (ExpandableNotificationRow childRow : children) {
1391 if (orderedChildren == null || !orderedChildren.contains(childRow)) {
1392 toRemove.add(childRow);
1393 }
1394 }
1395 for (ExpandableNotificationRow remove : toRemove) {
1396 parent.removeChildNotification(remove);
1397 mStackScroller.notifyGroupChildRemoved(remove);
1398 }
1399 }
1400
1401 // We now add all the children which are not in there already
1402 for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
1403 childIndex++) {
1404 ExpandableNotificationRow childView = orderedChildren.get(childIndex);
1405 if (children == null || !children.contains(childView)) {
1406 parent.addChildNotification(childView, childIndex);
1407 mStackScroller.notifyGroupChildAdded(childView);
1408 }
1409 }
1410
1411 // Finally after removing and adding has been beformed we can apply the order.
1412 orderChanged |= parent.applyChildOrder(orderedChildren);
1413 }
1414 if (orderChanged) {
1415 mStackScroller.generateChildOrderChangedEvent();
1416 }
1417 }
1418
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001419 private boolean packageHasVisibilityOverride(String key) {
1420 return mNotificationData.getVisibilityOverride(key)
1421 != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
1422 }
1423
Dan Sandlereceda3d2014-07-21 15:35:01 -04001424 private void updateClearAll() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001425 boolean showDismissView =
1426 mState != StatusBarState.KEYGUARD &&
1427 mNotificationData.hasActiveClearableNotifications();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001428 mStackScroller.updateDismissView(showDismissView);
1429 }
1430
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001431 private void updateEmptyShadeView() {
1432 boolean showEmptyShade =
1433 mState != StatusBarState.KEYGUARD &&
1434 mNotificationData.getActiveNotifications().size() == 0;
1435 mNotificationPanel.setShadeEmpty(showEmptyShade);
1436 }
1437
Jorim Jaggif6411742014-08-05 17:10:43 +00001438 private void updateSpeedbump() {
1439 int speedbumpIndex = -1;
1440 int currentIndex = 0;
1441 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1442 final int N = activeNotifications.size();
1443 for (int i = 0; i < N; i++) {
1444 Entry entry = activeNotifications.get(i);
Selim Cinekb5605e52015-02-20 18:21:41 +01001445 boolean isChild = !isTopLevelChild(entry);
1446 if (isChild) {
1447 continue;
1448 }
Jorim Jaggif6411742014-08-05 17:10:43 +00001449 if (entry.row.getVisibility() != View.GONE &&
1450 mNotificationData.isAmbient(entry.key)) {
1451 speedbumpIndex = currentIndex;
1452 break;
1453 }
1454 currentIndex++;
1455 }
1456 mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
1457 }
1458
Selim Cinekb5605e52015-02-20 18:21:41 +01001459 public static boolean isTopLevelChild(Entry entry) {
1460 return entry.row.getParent() instanceof NotificationStackScrollLayout;
1461 }
1462
Chris Wren0c8275b2012-05-08 13:36:48 -04001463 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001464 protected void updateNotifications() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001465 mNotificationData.filterAndSort();
1466
Christoph Studer37fe6932014-05-26 13:10:30 +02001467 updateNotificationShade();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001468 mIconController.updateNotificationIcons(mNotificationData);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001469 }
1470
Jorim Jaggi54045422014-07-03 18:30:40 +02001471 @Override
1472 protected void updateRowStates() {
1473 super.updateRowStates();
1474 mNotificationPanel.notifyVisibleChildrenChanged();
1475 }
1476
Chris Wren0c8275b2012-05-08 13:36:48 -04001477 @Override
1478 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001479
Chris Wren6d15a362013-08-20 18:46:29 -04001480 if (SPEW) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001481 final boolean clearable = hasActiveNotifications() &&
1482 mNotificationData.hasActiveClearableNotifications();
1483 Log.d(TAG, "setAreThereNotifications: N=" +
1484 mNotificationData.getActiveNotifications().size() + " any=" +
1485 hasActiveNotifications() + " clearable=" + clearable);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001486 }
1487
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001488 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
Christoph Studerc8db24b2014-07-25 17:50:30 +02001489 final boolean showDot = hasActiveNotifications() && !areLightsOn();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001490 if (showDot != (nlo.getAlpha() == 1.0f)) {
1491 if (showDot) {
1492 nlo.setAlpha(0f);
1493 nlo.setVisibility(View.VISIBLE);
1494 }
1495 nlo.animate()
1496 .alpha(showDot?1:0)
1497 .setDuration(showDot?750:250)
1498 .setInterpolator(new AccelerateInterpolator(2.0f))
1499 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1500 @Override
1501 public void onAnimationEnd(Animator _a) {
1502 nlo.setVisibility(View.GONE);
1503 }
1504 })
1505 .start();
1506 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001507
Dan Sandler16128f42014-05-21 12:48:22 -04001508 findAndUpdateMediaNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001509 }
1510
Dan Sandler16128f42014-05-21 12:48:22 -04001511 public void findAndUpdateMediaNotifications() {
1512 boolean metaDataChanged = false;
1513
1514 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001515 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1516 final int N = activeNotifications.size();
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001517
1518 // Promote the media notification with a controller in 'playing' state, if any.
Dan Sandler16128f42014-05-21 12:48:22 -04001519 Entry mediaNotification = null;
1520 MediaController controller = null;
Christoph Studerc8db24b2014-07-25 17:50:30 +02001521 for (int i = 0; i < N; i++) {
1522 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04001523 if (isMediaNotification(entry)) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001524 final MediaSession.Token token =
1525 entry.notification.getNotification().extras
Dan Sandler16128f42014-05-21 12:48:22 -04001526 .getParcelable(Notification.EXTRA_MEDIA_SESSION);
1527 if (token != null) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001528 MediaController aController = new MediaController(mContext, token);
1529 if (PlaybackState.STATE_PLAYING ==
1530 getMediaControllerPlaybackState(aController)) {
1531 if (DEBUG_MEDIA) {
1532 Log.v(TAG, "DEBUG_MEDIA: found mediastyle controller matching "
1533 + entry.notification.getKey());
1534 }
Dan Sandler16128f42014-05-21 12:48:22 -04001535 mediaNotification = entry;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001536 controller = aController;
1537 break;
Dan Sandler16128f42014-05-21 12:48:22 -04001538 }
1539 }
1540 }
1541 }
Dan Sandler16128f42014-05-21 12:48:22 -04001542 if (mediaNotification == null) {
1543 // Still nothing? OK, let's just look for live media sessions and see if they match
1544 // one of our notifications. This will catch apps that aren't (yet!) using media
1545 // notifications.
1546
1547 if (mMediaSessionManager != null) {
1548 final List<MediaController> sessions
1549 = mMediaSessionManager.getActiveSessionsForUser(
1550 null,
1551 UserHandle.USER_ALL);
1552
1553 for (MediaController aController : sessions) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001554 if (PlaybackState.STATE_PLAYING ==
1555 getMediaControllerPlaybackState(aController)) {
1556 // now to see if we have one like this
1557 final String pkg = aController.getPackageName();
Dan Sandler16128f42014-05-21 12:48:22 -04001558
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001559 for (int i = 0; i < N; i++) {
1560 final Entry entry = activeNotifications.get(i);
1561 if (entry.notification.getPackageName().equals(pkg)) {
1562 if (DEBUG_MEDIA) {
1563 Log.v(TAG, "DEBUG_MEDIA: found controller matching "
1564 + entry.notification.getKey());
Dan Sandler16128f42014-05-21 12:48:22 -04001565 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001566 controller = aController;
1567 mediaNotification = entry;
1568 break;
Dan Sandler16128f42014-05-21 12:48:22 -04001569 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001570 }
Dan Sandler16128f42014-05-21 12:48:22 -04001571 }
1572 }
1573 }
1574 }
1575
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001576 if (controller != null && !sameSessions(mMediaController, controller)) {
Dan Sandler16128f42014-05-21 12:48:22 -04001577 // We have a new media session
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001578 clearCurrentMediaNotification();
Dan Sandler16128f42014-05-21 12:48:22 -04001579 mMediaController = controller;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001580 mMediaController.registerCallback(mMediaListener);
1581 mMediaMetadata = mMediaController.getMetadata();
Dan Sandler16128f42014-05-21 12:48:22 -04001582 if (DEBUG_MEDIA) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001583 Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: "
1584 + mMediaMetadata);
Dan Sandler16128f42014-05-21 12:48:22 -04001585 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001586
1587 if (mediaNotification != null) {
1588 mMediaNotificationKey = mediaNotification.notification.getKey();
1589 if (DEBUG_MEDIA) {
1590 Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
1591 + mMediaNotificationKey + " controller=" + mMediaController);
1592 }
1593 }
1594 metaDataChanged = true;
Dan Sandler16128f42014-05-21 12:48:22 -04001595 }
1596 }
1597
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001598 if (metaDataChanged) {
1599 updateNotifications();
1600 }
Dan Sandler16128f42014-05-21 12:48:22 -04001601 updateMediaMetaData(metaDataChanged);
1602 }
1603
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001604 private int getMediaControllerPlaybackState(MediaController controller) {
1605 if (controller != null) {
1606 final PlaybackState playbackState = controller.getPlaybackState();
1607 if (playbackState != null) {
1608 return playbackState.getState();
1609 }
1610 }
1611 return PlaybackState.STATE_NONE;
1612 }
1613
1614 private boolean isPlaybackActive(int state) {
1615 if (state != PlaybackState.STATE_STOPPED
1616 && state != PlaybackState.STATE_ERROR
1617 && state != PlaybackState.STATE_NONE) {
1618 return true;
1619 }
1620 return false;
1621 }
1622
1623 private void clearCurrentMediaNotification() {
1624 mMediaNotificationKey = null;
1625 mMediaMetadata = null;
1626 if (mMediaController != null) {
1627 if (DEBUG_MEDIA) {
1628 Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
1629 + mMediaController.getPackageName());
1630 }
1631 mMediaController.unregisterCallback(mMediaListener);
1632 }
1633 mMediaController = null;
1634 }
1635
Christoph Studerb5245d82014-09-19 16:54:36 +02001636 private boolean sameSessions(MediaController a, MediaController b) {
1637 if (a == b) return true;
1638 if (a == null) return false;
1639 return a.controlsSameSession(b);
1640 }
1641
Dan Sandler16128f42014-05-21 12:48:22 -04001642 /**
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001643 * Hide the album artwork that is fading out and release its bitmap.
Dan Sandler16128f42014-05-21 12:48:22 -04001644 */
1645 private Runnable mHideBackdropFront = new Runnable() {
1646 @Override
1647 public void run() {
1648 if (DEBUG_MEDIA) {
1649 Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
1650 }
1651 mBackdropFront.setVisibility(View.INVISIBLE);
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001652 mBackdropFront.animate().cancel();
1653 mBackdropFront.setImageDrawable(null);
Dan Sandler16128f42014-05-21 12:48:22 -04001654 }
1655 };
1656
1657 /**
1658 * Refresh or remove lockscreen artwork from media metadata.
1659 */
1660 public void updateMediaMetaData(boolean metaDataChanged) {
1661 if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) return;
1662
1663 if (mBackdrop == null) return; // called too early
1664
Selim Cinek37c110f2015-05-22 12:38:44 -07001665 if (mLaunchTransitionFadingAway) {
1666 mBackdrop.setVisibility(View.INVISIBLE);
1667 return;
1668 }
1669
Dan Sandler16128f42014-05-21 12:48:22 -04001670 if (DEBUG_MEDIA) {
1671 Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey
Selim Cinek131c1e22015-05-11 19:04:49 -07001672 + " metadata=" + mMediaMetadata
1673 + " metaDataChanged=" + metaDataChanged
1674 + " state=" + mState);
Dan Sandler16128f42014-05-21 12:48:22 -04001675 }
1676
1677 Bitmap artworkBitmap = null;
1678 if (mMediaMetadata != null) {
1679 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
1680 if (artworkBitmap == null) {
1681 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
1682 // might still be null
1683 }
1684 }
1685
1686 final boolean hasArtwork = artworkBitmap != null;
1687
1688 if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
1689 && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
1690 // time to show some art!
1691 if (mBackdrop.getVisibility() != View.VISIBLE) {
1692 mBackdrop.setVisibility(View.VISIBLE);
1693 mBackdrop.animate().alpha(1f);
1694 metaDataChanged = true;
1695 if (DEBUG_MEDIA) {
1696 Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
1697 }
1698 }
1699 if (metaDataChanged) {
1700 if (mBackdropBack.getDrawable() != null) {
Julia Reynolds4b9658a2015-07-22 17:07:42 -04001701 Drawable drawable =
1702 mBackdropBack.getDrawable().getConstantState().newDrawable().mutate();
Selim Cineka0fad3b2014-09-19 17:20:05 +02001703 mBackdropFront.setImageDrawable(drawable);
Jorim Jaggi0e664392014-09-27 01:30:22 +02001704 if (mScrimSrcModeEnabled) {
1705 mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
1706 }
Dan Sandler16128f42014-05-21 12:48:22 -04001707 mBackdropFront.setAlpha(1f);
1708 mBackdropFront.setVisibility(View.VISIBLE);
1709 } else {
1710 mBackdropFront.setVisibility(View.INVISIBLE);
1711 }
1712
1713 if (DEBUG_MEDIA_FAKE_ARTWORK) {
1714 final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
1715 Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
1716 mBackdropBack.setBackgroundColor(0xFFFFFFFF);
1717 mBackdropBack.setImageDrawable(new ColorDrawable(c));
1718 } else {
1719 mBackdropBack.setImageBitmap(artworkBitmap);
1720 }
Jorim Jaggi0e664392014-09-27 01:30:22 +02001721 if (mScrimSrcModeEnabled) {
1722 mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
1723 }
Dan Sandler16128f42014-05-21 12:48:22 -04001724
1725 if (mBackdropFront.getVisibility() == View.VISIBLE) {
1726 if (DEBUG_MEDIA) {
1727 Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
1728 + mBackdropFront.getDrawable()
1729 + " to "
1730 + mBackdropBack.getDrawable());
1731 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001732 mBackdropFront.animate()
Dan Sandler16128f42014-05-21 12:48:22 -04001733 .setDuration(250)
1734 .alpha(0f).withEndAction(mHideBackdropFront);
1735 }
1736 }
1737 } else {
1738 // need to hide the album art, either because we are unlocked or because
1739 // the metadata isn't there to support it
1740 if (mBackdrop.getVisibility() != View.GONE) {
1741 if (DEBUG_MEDIA) {
1742 Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
1743 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001744 mBackdrop.animate()
Adrian Roos18a0b9e2015-07-10 15:49:03 -07001745 // Never let the alpha become zero - otherwise the RenderNode
1746 // won't draw anything and uninitialized memory will show through
1747 // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in libhwui.
1748 .alpha(0.002f)
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001749 .setInterpolator(mBackdropInterpolator)
1750 .setDuration(300)
1751 .setStartDelay(0)
1752 .withEndAction(new Runnable() {
1753 @Override
1754 public void run() {
1755 mBackdrop.setVisibility(View.GONE);
1756 mBackdropFront.animate().cancel();
1757 mBackdropBack.animate().cancel();
1758 mHandler.post(mHideBackdropFront);
1759 }
1760 });
1761 if (mKeyguardFadingAway) {
1762 mBackdrop.animate()
1763
1764 // Make it disappear faster, as the focus should be on the activity behind.
1765 .setDuration(mKeyguardFadingAwayDuration / 2)
1766 .setStartDelay(mKeyguardFadingAwayDelay)
1767 .setInterpolator(mLinearInterpolator)
1768 .start();
1769 }
Dan Sandler16128f42014-05-21 12:48:22 -04001770 }
1771 }
1772 }
1773
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001774 private int adjustDisableFlags(int state) {
Jorim Jaggi740452e2015-07-09 12:13:59 -07001775 if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway
Selim Cinekbaa23272014-07-08 18:01:07 +02001776 && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001777 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
1778 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
1779 }
1780 return state;
1781 }
1782
Joe Onorato808182d2010-07-09 18:52:06 -04001783 /**
1784 * State is one or more of the DISABLE constants from StatusBarManager.
1785 */
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001786 public void disable(int state1, int state2, boolean animate) {
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07001787 animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001788 mDisabledUnmodified1 = state1;
1789 mDisabledUnmodified2 = state2;
1790 state1 = adjustDisableFlags(state1);
1791 final int old1 = mDisabled1;
1792 final int diff1 = state1 ^ old1;
1793 mDisabled1 = state1;
1794
1795 final int old2 = mDisabled2;
1796 final int diff2 = state2 ^ old2;
1797 mDisabled2 = state2;
Joe Onorato808182d2010-07-09 18:52:06 -04001798
Daniel Sandlere21f2882011-08-18 10:14:59 -04001799 if (DEBUG) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001800 Log.d(TAG, String.format("disable1: 0x%08x -> 0x%08x (diff1: 0x%08x)",
1801 old1, state1, diff1));
1802 Log.d(TAG, String.format("disable2: 0x%08x -> 0x%08x (diff2: 0x%08x)",
1803 old2, state2, diff2));
Daniel Sandlere21f2882011-08-18 10:14:59 -04001804 }
1805
Daniel Sandler6da2b762011-09-14 16:04:59 -04001806 StringBuilder flagdbg = new StringBuilder();
1807 flagdbg.append("disable: < ");
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001808 flagdbg.append(((state1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
1809 flagdbg.append(((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
1810 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
1811 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
1812 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
1813 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
1814 flagdbg.append(((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
1815 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
1816 flagdbg.append(((state1 & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
1817 flagdbg.append(((diff1 & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
1818 flagdbg.append(((state1 & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
1819 flagdbg.append(((diff1 & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
1820 flagdbg.append(((state1 & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
1821 flagdbg.append(((diff1 & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
1822 flagdbg.append(((state1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
1823 flagdbg.append(((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
1824 flagdbg.append(((state1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
1825 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Benjamin Franz27cf1462015-04-23 19:36:42 +01001826 flagdbg.append(((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "QUICK_SETTINGS"
1827 : "quick_settings");
1828 flagdbg.append(((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04001829 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04001830 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07001831
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001832 if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
1833 if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001834 mIconController.hideSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001835 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001836 mIconController.showSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04001837 }
1838 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04001839
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001840 if ((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) {
1841 boolean visible = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001842 mIconController.setClockVisibility(visible);
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07001843 }
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001844 if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
1845 if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04001846 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04001847 }
1848 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001849
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001850 if ((diff1 & (StatusBarManager.DISABLE_HOME
Jim Miller5e6af442011-12-02 18:24:26 -08001851 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04001852 | StatusBarManager.DISABLE_BACK
1853 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04001854 // the nav bar will take care of these
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001855 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001856
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001857 if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04001858 // close recents if it's visible
Winson Chung1e8d71b2014-05-16 17:05:22 -07001859 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
1860 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Daniel Sandler6da2b762011-09-14 16:04:59 -04001861 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04001862 }
1863
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001864 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1865 if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001866 mIconController.hideNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04001867 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001868 mIconController.showNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04001869 }
Joe Onorato808182d2010-07-09 18:52:06 -04001870 }
Jason Monkf7019542014-07-31 12:42:25 -04001871
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001872 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
Jason Monkf7019542014-07-31 12:42:25 -04001873 mDisableNotificationAlerts =
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001874 (state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
Jason Monkf7019542014-07-31 12:42:25 -04001875 mHeadsUpObserver.onChange(true);
1876 }
Benjamin Franz27cf1462015-04-23 19:36:42 +01001877
1878 if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
1879 updateQsExpansionEnabled();
1880 }
Joe Onorato808182d2010-07-09 18:52:06 -04001881 }
1882
Michael Jurka7f2668c2012-03-27 07:49:52 -07001883 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07001884 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001885 return new PhoneStatusBar.H();
1886 }
1887
Jorim Jaggi97b63c42014-05-02 23:03:34 +02001888 @Override
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02001889 public void startActivity(Intent intent, boolean dismissShade) {
1890 startActivityDismissingKeyguard(intent, false, dismissShade);
Jorim Jaggi97b63c42014-05-02 23:03:34 +02001891 }
1892
Selim Cineke70d6532015-04-24 16:46:13 -07001893 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07001894 public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
1895 startActivityDismissingKeyguard(intent, false, dismissShade, callback);
1896 }
1897
1898 @Override
Selim Cineke70d6532015-04-24 16:46:13 -07001899 public void preventNextAnimation() {
1900 overrideActivityPendingAppTransition(true /* keyguardShowing */);
1901 }
1902
Jorim Jaggib690f0d2014-07-03 23:25:44 +02001903 public void setQsExpanded(boolean expanded) {
1904 mStatusBarWindowManager.setQsExpanded(expanded);
Adrian Roos4c7d9602015-06-10 13:44:48 -07001905 mKeyguardStatusView.setImportantForAccessibility(expanded
1906 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
1907 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
Jorim Jaggib690f0d2014-07-03 23:25:44 +02001908 }
1909
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02001910 public boolean isGoingToNotificationShade() {
1911 return mLeaveOpenOnKeyguardHide;
1912 }
1913
Jorim Jaggid692dd02014-08-14 20:57:42 +02001914 public boolean isQsExpanded() {
1915 return mNotificationPanel.isQsExpanded();
1916 }
1917
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07001918 public boolean isWakeUpComingFromTouch() {
1919 return mWakeUpComingFromTouch;
Selim Cinek29ed3c92014-09-23 20:44:35 +02001920 }
1921
Selim Cinek19c8c702014-08-25 22:09:19 +02001922 public boolean isFalsingThresholdNeeded() {
Selim Cinek9db71052015-04-24 18:54:30 -07001923 return getBarState() == StatusBarState.KEYGUARD;
Selim Cinek19c8c702014-08-25 22:09:19 +02001924 }
1925
John Spurlock0b99ea92014-10-01 15:32:22 -04001926 public boolean isDozing() {
1927 return mDozing;
1928 }
1929
Christoph Studer2e731b52014-08-22 16:01:51 +02001930 @Override // NotificationData.Environment
1931 public String getCurrentMediaNotificationKey() {
1932 return mMediaNotificationKey;
1933 }
1934
Jorim Jaggi0e664392014-09-27 01:30:22 +02001935 public boolean isScrimSrcModeEnabled() {
1936 return mScrimSrcModeEnabled;
1937 }
1938
Joe Onorato808182d2010-07-09 18:52:06 -04001939 /**
Christoph Studer2231c6e2014-12-19 12:40:13 +01001940 * To be called when there's a state change in StatusBarKeyguardViewManager.
1941 */
1942 public void onKeyguardViewManagerStatesUpdated() {
1943 logStateToEventlog();
1944 }
1945
1946 @Override // UnlockMethodCache.OnUnlockMethodChangedListener
1947 public void onUnlockMethodStateChanged() {
1948 logStateToEventlog();
1949 }
1950
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001951 @Override
John Spurlockb349af572015-04-29 12:24:19 -04001952 public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
Selim Cinek684a4422015-04-15 16:18:39 -07001953 if (inPinnedMode) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001954 mStatusBarWindowManager.setHeadsUpShowing(true);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07001955 mStatusBarWindowManager.setForceStatusBarVisible(true);
Selim Cinek131c1e22015-05-11 19:04:49 -07001956 if (mNotificationPanel.isFullyCollapsed()) {
1957 // We need to ensure that the touchable region is updated before the window will be
1958 // resized, in order to not catch any touches. A layout will ensure that
1959 // onComputeInternalInsets will be called and after that we can resize the layout. Let's
1960 // make sure that the window stays small for one frame until the touchableRegion is set.
1961 mNotificationPanel.requestLayout();
1962 mStatusBarWindowManager.setForceWindowCollapsed(true);
1963 mNotificationPanel.post(new Runnable() {
1964 @Override
1965 public void run() {
1966 mStatusBarWindowManager.setForceWindowCollapsed(false);
1967 }
1968 });
1969 }
Selim Cinek737bff32015-05-08 16:08:35 -07001970 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07001971 if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) {
1972 // We are currently tracking or is open and the shade doesn't need to be kept
1973 // open artificially.
Selim Cinek737bff32015-05-08 16:08:35 -07001974 mStatusBarWindowManager.setHeadsUpShowing(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001975 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07001976 // we need to keep the panel open artificially, let's wait until the animation
1977 // is finished.
Selim Cinek737bff32015-05-08 16:08:35 -07001978 mHeadsUpManager.setHeadsUpGoingAway(true);
1979 mStackScroller.runAfterAnimationFinished(new Runnable() {
1980 @Override
1981 public void run() {
1982 if (!mHeadsUpManager.hasPinnedHeadsUp()) {
1983 mStatusBarWindowManager.setHeadsUpShowing(false);
1984 mHeadsUpManager.setHeadsUpGoingAway(false);
1985 }
1986 }
1987 });
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001988 }
1989 }
1990 }
1991
1992 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07001993 public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
John Spurlockb349af572015-04-29 12:24:19 -04001994 dismissVolumeDialog();
Selim Cinek1f3f5442015-04-10 17:54:46 -07001995 }
1996
1997 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07001998 public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
1999 }
2000
2001 @Override
2002 public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002003 if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
2004 removeNotification(entry.key, mLatestRankingMap);
2005 mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
2006 if (mHeadsUpEntriesToRemoveOnSwitch.isEmpty()) {
2007 mLatestRankingMap = null;
2008 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002009 } else {
2010 updateNotificationRanking(null);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002011 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002012
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002013 }
2014
Selim Cinek29fa89b2015-04-17 10:39:11 -07002015 protected void updateHeadsUp(String key, Entry entry, boolean shouldInterrupt,
2016 boolean alertAgain) {
2017 final boolean wasHeadsUp = isHeadsUp(key);
2018 if (wasHeadsUp) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002019 if (!shouldInterrupt) {
2020 // We don't want this to be interrupting anymore, lets remove it
2021 mHeadsUpManager.removeNotification(key);
Selim Cinek684a4422015-04-15 16:18:39 -07002022 } else {
2023 mHeadsUpManager.updateNotification(entry, alertAgain);
Selim Cinek29fa89b2015-04-17 10:39:11 -07002024 }
2025 } else if (shouldInterrupt && alertAgain) {
2026 // This notification was updated to be a heads-up, show it!
2027 mHeadsUpManager.showNotification(entry);
2028 }
2029 }
2030
2031 protected void setHeadsUpUser(int newUserId) {
2032 if (mHeadsUpManager != null) {
2033 mHeadsUpManager.setUser(newUserId);
2034 }
2035 }
2036
2037 public boolean isHeadsUp(String key) {
2038 return mHeadsUpManager.isHeadsUp(key);
2039 }
2040
2041 protected boolean isSnoozedPackage(StatusBarNotification sbn) {
2042 return mHeadsUpManager.isSnoozed(sbn.getPackageName());
2043 }
2044
Selim Cineke70d6532015-04-24 16:46:13 -07002045 public boolean isKeyguardCurrentlySecure() {
Selim Cineke8bae622015-07-15 13:24:06 -07002046 return !mUnlockMethodCache.canSkipBouncer();
Selim Cineke70d6532015-04-24 16:46:13 -07002047 }
2048
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002049 public void setPanelExpanded(boolean isExpanded) {
2050 mStatusBarWindowManager.setPanelExpanded(isExpanded);
2051 }
2052
Christoph Studer2231c6e2014-12-19 12:40:13 +01002053 /**
Joe Onorato808182d2010-07-09 18:52:06 -04002054 * All changes to the status bar and notifications funnel through here and are batched.
2055 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07002056 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04002057 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002058 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04002059 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002060 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04002061 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002062 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04002063 case MSG_OPEN_SETTINGS_PANEL:
2064 animateExpandSettingsPanel();
2065 break;
2066 case MSG_CLOSE_PANELS:
2067 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002068 break;
Jorim Jaggi826730a2014-12-08 21:05:13 +01002069 case MSG_LAUNCH_TRANSITION_TIMEOUT:
2070 onLaunchTransitionTimeout();
2071 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04002072 }
2073 }
2074 }
2075
Chris Wren930ecca2014-11-12 17:43:41 -05002076 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002077 public void maybeEscalateHeadsUp() {
Selim Cineka59ecc32015-04-07 10:51:49 -07002078 TreeSet<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getSortedEntries();
2079 for (HeadsUpManager.HeadsUpEntry entry : entries) {
2080 final StatusBarNotification sbn = entry.entry.notification;
Chris Wrene97f90b2013-08-07 17:39:35 -04002081 final Notification notification = sbn.getNotification();
2082 if (notification.fullScreenIntent != null) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002083 if (DEBUG) {
Chris Wrene97f90b2013-08-07 17:39:35 -04002084 Log.d(TAG, "converting a heads up to fullScreen");
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002085 }
Chris Wrene97f90b2013-08-07 17:39:35 -04002086 try {
Chris Wren223c66b62014-11-10 16:00:09 -05002087 EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
2088 sbn.getKey());
Chris Wrene97f90b2013-08-07 17:39:35 -04002089 notification.fullScreenIntent.send();
Selim Cinekb18a20f2015-06-04 17:08:35 +02002090 entry.entry.notifyFullScreenIntentLaunched();
Chris Wrene97f90b2013-08-07 17:39:35 -04002091 } catch (PendingIntent.CanceledException e) {
2092 }
Joe Onorato808182d2010-07-09 18:52:06 -04002093 }
2094 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002095 mHeadsUpManager.releaseAllImmediately();
Joe Onorato808182d2010-07-09 18:52:06 -04002096 }
2097
John Spurlock97642182013-07-29 17:58:39 -04002098 boolean panelsEnabled() {
Adrian Roos21d2a252015-06-01 13:59:59 -07002099 return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && !ONLY_CORE_APPS;
John Spurlock97642182013-07-29 17:58:39 -04002100 }
2101
Jorim Jaggifa505a72014-04-28 20:04:11 +02002102 void makeExpandedVisible(boolean force) {
John Spurlockcd686b52013-06-05 10:13:46 -04002103 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
Jorim Jaggifa505a72014-04-28 20:04:11 +02002104 if (!force && (mExpandedVisible || !panelsEnabled())) {
Joe Onorato808182d2010-07-09 18:52:06 -04002105 return;
2106 }
Jim Millera073e572012-05-23 17:03:27 -07002107
Joe Onorato808182d2010-07-09 18:52:06 -04002108 mExpandedVisible = true;
John Spurlockd5ef5462012-06-13 11:19:51 -04002109 if (mNavigationBarView != null)
2110 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002111
Daniel Sandlera310af82012-04-24 01:20:13 -04002112 // Expand the window to encompass the full screen in anticipation of the drag.
2113 // This is only possible to do atomically because the status bar is at the top of the screen!
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002114 mStatusBarWindowManager.setPanelVisible(true);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002115
2116 visibilityChanged(true);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07002117 mWaitingForKeyguardExit = false;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002118 disable(mDisabledUnmodified1, mDisabledUnmodified2, !force /* animate */);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002119 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2120 }
2121
Daniel Sandler11cf1782012-09-27 14:03:08 -04002122 public void animateCollapsePanels() {
2123 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07002124 }
2125
John Spurlockaf8d6c42014-05-07 17:49:08 -04002126 private final Runnable mAnimateCollapsePanels = new Runnable() {
2127 @Override
2128 public void run() {
2129 animateCollapsePanels();
2130 }
2131 };
2132
2133 public void postAnimateCollapsePanels() {
2134 mHandler.post(mAnimateCollapsePanels);
2135 }
2136
Daniel Sandler11cf1782012-09-27 14:03:08 -04002137 public void animateCollapsePanels(int flags) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002138 animateCollapsePanels(flags, false /* force */, false /* delayed */,
2139 1.0f /* speedUpFactor */);
Jorim Jaggi34250762014-07-03 23:51:19 +02002140 }
2141
2142 public void animateCollapsePanels(int flags, boolean force) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002143 animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002144 }
2145
2146 public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002147 animateCollapsePanels(flags, force, delayed, 1.0f /* speedUpFactor */);
2148 }
2149
2150 public void animateCollapsePanels(int flags, boolean force, boolean delayed,
2151 float speedUpFactor) {
Jorim Jaggi34250762014-07-03 23:51:19 +02002152 if (!force &&
2153 (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002154 runPostCollapseRunnables();
Jorim Jaggic1cf1ae2014-05-02 21:19:17 +02002155 return;
2156 }
Joe Onorato808182d2010-07-09 18:52:06 -04002157 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04002158 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04002159 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07002160 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002161 }
2162
Jim Miller9a720f52012-05-30 03:19:43 -07002163 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Winson Chungcdcd4872014-08-05 18:00:13 -07002164 if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
2165 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2166 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
2167 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07002168 }
Jim Miller9a720f52012-05-30 03:19:43 -07002169
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002170 if (mStatusBarWindow != null) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002171 // release focus immediately to kick off focus change transition
2172 mStatusBarWindowManager.setStatusBarFocusable(false);
2173
John Spurlockab847cf2014-01-15 14:13:59 -05002174 mStatusBarWindow.cancelExpandHelper();
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002175 mStatusBarView.collapseAllPanels(true /* animate */, delayed, speedUpFactor);
John Spurlockab847cf2014-01-15 14:13:59 -05002176 }
Joe Onorato808182d2010-07-09 18:52:06 -04002177 }
2178
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002179 private void runPostCollapseRunnables() {
Selim Cinekae77f8e2015-07-07 18:43:59 -07002180 ArrayList<Runnable> clonedList = new ArrayList<>(mPostCollapseRunnables);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002181 mPostCollapseRunnables.clear();
Selim Cinekae77f8e2015-07-07 18:43:59 -07002182 int size = clonedList.size();
2183 for (int i = 0; i < size; i++) {
2184 clonedList.get(i).run();
2185 }
2186
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002187 }
2188
John Spurlockaf8d6c42014-05-07 17:49:08 -04002189 Animator mScrollViewAnim, mClearButtonAnim;
Daniel Sandler101784e2012-10-15 13:39:38 -04002190
Daniel Sandler08d05e32012-08-08 16:39:54 -04002191 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002192 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002193 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002194 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04002195 return ;
2196 }
Joe Onorato808182d2010-07-09 18:52:06 -04002197
Daniel Sandler08d05e32012-08-08 16:39:54 -04002198 mNotificationPanel.expand();
Joe Onorato808182d2010-07-09 18:52:06 -04002199
2200 if (false) postStartTracing();
2201 }
2202
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002203 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002204 public void animateExpandSettingsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002205 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002206 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002207 return;
2208 }
2209
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05002210 // Settings are not available in setup
2211 if (!mUserSetup) return;
2212
Jason Monk3c68ca22015-01-30 11:30:29 -05002213 mNotificationPanel.expandWithQs();
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002214
2215 if (false) postStartTracing();
2216 }
2217
2218 public void animateCollapseQuickSettings() {
Jorim Jaggi449981b2014-10-03 14:24:55 -07002219 if (mState == StatusBarState.SHADE) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002220 mStatusBarView.collapseAllPanels(true, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi449981b2014-10-03 14:24:55 -07002221 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002222 }
2223
Daniel Sandler08d05e32012-08-08 16:39:54 -04002224 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04002225 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04002226 + " mExpandedVisible=" + mExpandedVisible);
2227
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002228 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002229 return;
2230 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002231
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04002232 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002233 mStatusBarView.collapseAllPanels(/*animate=*/ false, false /* delayed*/,
2234 1.0f /* speedUpFactor */);
Daniel Sandlered930e52012-07-03 14:31:22 -04002235
Jorim Jaggid7daab72014-05-06 22:22:20 +02002236 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04002237
Joe Onorato808182d2010-07-09 18:52:06 -04002238 mExpandedVisible = false;
John Spurlockd5ef5462012-06-13 11:19:51 -04002239 if (mNavigationBarView != null)
2240 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002241 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04002242
2243 // Shrink the window to the size of the status bar only
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002244 mStatusBarWindowManager.setPanelVisible(false);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002245 mStatusBarWindowManager.setForceStatusBarVisible(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002246
Daniel Sandler469e96e2012-05-04 15:56:19 -04002247 // Close any "App info" popups that might have snuck on-screen
2248 dismissPopups();
2249
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002250 runPostCollapseRunnables();
John Spurlockcfc359a2013-09-05 10:42:03 -04002251 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002252 showBouncer();
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002253 disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
Jorim Jaggi786afcb2014-09-25 02:41:29 +02002254
2255 // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
2256 // the bouncer appear animation.
2257 if (!mStatusBarKeyguardViewManager.isShowing()) {
2258 WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
2259 }
Joe Onorato808182d2010-07-09 18:52:06 -04002260 }
2261
Daniel Sandlerb17a7262012-10-05 14:32:50 -04002262 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05002263 if (DEBUG_GESTURES) {
2264 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
2265 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002266 event.getActionMasked(), (int) event.getX(), (int) event.getY(),
2267 mDisabled1, mDisabled2);
Chris Wren64161cc2012-12-17 16:49:30 -05002268 }
2269
2270 }
2271
Joe Onorato808182d2010-07-09 18:52:06 -04002272 if (SPEW) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002273 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
2274 + mDisabled1 + " mDisabled2=" + mDisabled2 + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002275 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002276 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04002277 Log.d(TAG, String.format(
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002278 "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002279 MotionEvent.actionToString(event.getAction()),
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002280 event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002281 }
Joe Onorato808182d2010-07-09 18:52:06 -04002282 }
2283
Daniel Sandler151f00d2012-10-02 22:33:08 -04002284 if (DEBUG_GESTURES) {
2285 mGestureRec.add(event);
2286 }
Daniel Sandler33805342012-07-23 15:45:12 -04002287
John Spurlock686820a2013-09-03 14:44:16 -04002288 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04002289 final boolean upOrCancel =
2290 event.getAction() == MotionEvent.ACTION_UP ||
2291 event.getAction() == MotionEvent.ACTION_CANCEL;
2292 if (upOrCancel && !mExpandedVisible) {
2293 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
2294 } else {
2295 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2296 }
John Spurlock686820a2013-09-03 14:44:16 -04002297 }
Joe Onorato808182d2010-07-09 18:52:06 -04002298 return false;
2299 }
2300
Daniel Sandler08d05e32012-08-08 16:39:54 -04002301 public GestureRecorder getGestureRecorder() {
2302 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07002303 }
2304
John Spurlock56d007b2013-10-28 18:40:56 -04002305 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04002306 if (hints == mNavigationIconHints) return;
2307
2308 mNavigationIconHints = hints;
2309
2310 if (mNavigationBarView != null) {
2311 mNavigationBarView.setNavigationIconHints(hints);
2312 }
John Spurlockd4e65752013-08-28 14:17:09 -04002313 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04002314 }
2315
2316 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04002317 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04002318 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04002319 if (mStatusBarWindow != null
2320 && window == StatusBarManager.WINDOW_STATUS_BAR
2321 && mStatusBarWindowState != state) {
2322 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002323 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
Jorim Jaggi449981b2014-10-03 14:24:55 -07002324 if (!showing && mState == StatusBarState.SHADE) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002325 mStatusBarView.collapseAllPanels(false /* animate */, false /* delayed */,
2326 1.0f /* speedUpFactor */);
John Spurlock97642182013-07-29 17:58:39 -04002327 }
2328 }
2329 if (mNavigationBarView != null
2330 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
2331 && mNavigationBarWindowState != state) {
2332 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002333 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04002334 }
2335 }
2336
John Spurlock97642182013-07-29 17:58:39 -04002337 @Override // CommandQueue
John Spurlockcad57682014-07-26 17:09:56 -04002338 public void buzzBeepBlinked() {
2339 if (mDozeServiceHost != null) {
2340 mDozeServiceHost.fireBuzzBeepBlinked();
2341 }
2342 }
2343
John Spurlockcb566aa2014-08-03 22:58:28 -04002344 @Override
2345 public void notificationLightOff() {
2346 if (mDozeServiceHost != null) {
2347 mDozeServiceHost.fireNotificationLight(false);
2348 }
2349 }
2350
2351 @Override
2352 public void notificationLightPulse(int argb, int onMillis, int offMillis) {
2353 if (mDozeServiceHost != null) {
2354 mDozeServiceHost.fireNotificationLight(true);
2355 }
2356 }
2357
John Spurlockcad57682014-07-26 17:09:56 -04002358 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002359 public void setSystemUiVisibility(int vis, int mask) {
2360 final int oldVal = mSystemUiVisibility;
2361 final int newVal = (oldVal&~mask) | (vis&mask);
2362 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04002363 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04002364 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
2365 Integer.toHexString(vis), Integer.toHexString(mask),
2366 Integer.toHexString(oldVal), Integer.toHexString(newVal),
2367 Integer.toHexString(diff)));
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002368 if (diff != 0) {
Winson Chung9214eff2014-06-12 13:59:25 -07002369 // we never set the recents bit via this method, so save the prior state to prevent
2370 // clobbering the bit below
2371 final boolean wasRecentsVisible = (mSystemUiVisibility & View.RECENT_APPS_VISIBLE) > 0;
2372
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002373 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04002374
John Spurlocke1f366f2013-08-05 12:22:40 -04002375 // update low profile
2376 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
2377 final boolean lightsOut = (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002378 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002379 animateCollapsePanels();
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002380 }
Jim Millera073e572012-05-23 17:03:27 -07002381
John Spurlock7edfbca2013-09-14 11:58:55 -04002382 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04002383 }
2384
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002385 // ready to unhide
2386 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
2387 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
2388 mNoAnimationOnNextBarModeChange = true;
2389 }
2390
John Spurlocke1f366f2013-08-05 12:22:40 -04002391 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002392 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04002393 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04002394
2395 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002396 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04002397 oldVal, newVal, mNavigationBarView.getBarTransitions(),
John Spurlockbd957402013-10-03 11:38:39 -04002398 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT);
John Spurlockd4e65752013-08-28 14:17:09 -04002399 final boolean sbModeChanged = sbMode != -1;
2400 final boolean nbModeChanged = nbMode != -1;
2401 boolean checkBarModes = false;
2402 if (sbModeChanged && sbMode != mStatusBarMode) {
2403 mStatusBarMode = sbMode;
2404 checkBarModes = true;
2405 }
2406 if (nbModeChanged && nbMode != mNavigationBarMode) {
2407 mNavigationBarMode = nbMode;
2408 checkBarModes = true;
2409 }
2410 if (checkBarModes) {
2411 checkBarModes();
2412 }
2413 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002414 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05002415 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04002416 scheduleAutohide();
2417 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04002418 cancelAutohide();
2419 }
2420 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002421
John Spurlock5b9145b2013-08-20 15:13:47 -04002422 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
2423 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
2424 }
2425
Adrian Roos75fa3852015-01-27 20:21:44 +01002426 if ((diff & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0 || sbModeChanged) {
Adrian Roos761c1562015-02-04 14:35:23 +01002427 boolean isTransparentBar = (mStatusBarMode == MODE_TRANSPARENT
2428 || mStatusBarMode == MODE_LIGHTS_OUT_TRANSPARENT);
2429 boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave();
Adrian Roos75fa3852015-01-27 20:21:44 +01002430 boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
2431
Jorim Jaggi5443cc52015-03-20 14:39:24 -07002432 mIconController.setIconsDark(allowLight && light);
Adrian Roos75fa3852015-01-27 20:21:44 +01002433 }
Winson Chung9214eff2014-06-12 13:59:25 -07002434 // restore the recents bit
2435 if (wasRecentsVisible) {
2436 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
2437 }
2438
John Spurlocke1f366f2013-08-05 12:22:40 -04002439 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04002440 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04002441 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002442 }
2443
John Spurlockd4e65752013-08-28 14:17:09 -04002444 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
John Spurlockbd957402013-10-03 11:38:39 -04002445 int transientFlag, int translucentFlag) {
2446 final int oldMode = barMode(oldVis, transientFlag, translucentFlag);
2447 final int newMode = barMode(newVis, transientFlag, translucentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04002448 if (oldMode == newMode) {
2449 return -1; // no mode change
2450 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002451 return newMode;
2452 }
2453
John Spurlockbd957402013-10-03 11:38:39 -04002454 private int barMode(int vis, int transientFlag, int translucentFlag) {
Adrian Roosc0f0a742014-10-28 16:39:56 +01002455 int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_TRANSPARENT;
John Spurlock89835dd2013-08-16 15:06:51 -04002456 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04002457 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
Adrian Roosc0f0a742014-10-28 16:39:56 +01002458 : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
Adrian Roosea562512014-05-05 13:33:03 +02002459 : (vis & View.SYSTEM_UI_TRANSPARENT) != 0 ? MODE_TRANSPARENT
John Spurlock7edfbca2013-09-14 11:58:55 -04002460 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04002461 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04002462 }
2463
John Spurlockd4e65752013-08-28 14:17:09 -04002464 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04002465 if (mDemoMode) return;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002466 checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions(),
2467 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04002468 if (mNavigationBarView != null) {
2469 checkBarMode(mNavigationBarMode,
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002470 mNavigationBarWindowState, mNavigationBarView.getBarTransitions(),
2471 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04002472 }
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002473 mNoAnimationOnNextBarModeChange = false;
John Spurlockd4e65752013-08-28 14:17:09 -04002474 }
2475
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002476 private void checkBarMode(int mode, int windowState, BarTransitions transitions,
2477 boolean noAnimation) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002478 final boolean powerSave = mBatteryController.isPowerSave();
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07002479 final boolean anim = !noAnimation && mDeviceInteractive
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002480 && windowState != WINDOW_STATE_HIDDEN && !powerSave;
John Spurlock1bb480a2014-08-02 17:12:43 -04002481 if (powerSave && getBarState() == StatusBarState.SHADE) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002482 mode = MODE_WARNING;
2483 }
John Spurlockc68d5772013-10-08 11:47:58 -04002484 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04002485 }
2486
John Spurlock42197262013-10-21 09:32:25 -04002487 private void finishBarAnimations() {
2488 mStatusBarView.getBarTransitions().finishAnimations();
2489 if (mNavigationBarView != null) {
2490 mNavigationBarView.getBarTransitions().finishAnimations();
2491 }
2492 }
2493
John Spurlockd4e65752013-08-28 14:17:09 -04002494 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04002495 @Override
2496 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04002497 checkBarModes();
John Spurlock0ff62e02014-07-22 16:15:08 -04002498 }
2499 };
John Spurlock5b9145b2013-08-20 15:13:47 -04002500
John Spurlockad3e6cb2013-04-30 08:47:43 -04002501 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04002502 public void setInteracting(int barWindow, boolean interacting) {
John Spurlock7fbf5732014-11-18 11:40:22 -05002503 final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
John Spurlockcfc359a2013-09-05 10:42:03 -04002504 mInteractingWindows = interacting
2505 ? (mInteractingWindows | barWindow)
2506 : (mInteractingWindows & ~barWindow);
2507 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04002508 suspendAutohide();
2509 } else {
2510 resumeSuspendedAutohide();
2511 }
John Spurlock7fbf5732014-11-18 11:40:22 -05002512 // manually dismiss the volume panel when interacting with the nav bar
2513 if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
John Spurlockb349af572015-04-29 12:24:19 -04002514 dismissVolumeDialog();
John Spurlock7fbf5732014-11-18 11:40:22 -05002515 }
John Spurlockd4e65752013-08-28 14:17:09 -04002516 checkBarModes();
2517 }
2518
John Spurlockb349af572015-04-29 12:24:19 -04002519 private void dismissVolumeDialog() {
2520 if (mVolumeComponent != null) {
2521 mVolumeComponent.dismissNow();
2522 }
2523 }
2524
John Spurlockd4e65752013-08-28 14:17:09 -04002525 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04002526 if (mAutohideSuspended) {
2527 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04002528 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04002529 }
2530 }
2531
John Spurlockd4e65752013-08-28 14:17:09 -04002532 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04002533 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04002534 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04002535 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04002536 }
2537
2538 private void cancelAutohide() {
2539 mAutohideSuspended = false;
2540 mHandler.removeCallbacks(mAutohide);
2541 }
2542
2543 private void scheduleAutohide() {
2544 cancelAutohide();
2545 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
2546 }
2547
John Spurlock9deaa282013-07-25 13:03:47 -04002548 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002549 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04002550 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
2551 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
2552 ) {
2553 userAutohide();
2554 }
2555 }
2556
2557 private void userAutohide() {
2558 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04002559 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04002560 }
2561
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002562 private boolean areLightsOn() {
2563 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
2564 }
Jim Millera073e572012-05-23 17:03:27 -07002565
Daniel Sandler60ee2562011-07-22 12:34:33 -04002566 public void setLightsOn(boolean on) {
2567 Log.v(TAG, "setLightsOn(" + on + ")");
2568 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002569 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002570 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002571 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002572 }
2573 }
2574
John Spurlock32beb2c2013-03-11 10:16:47 -04002575 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002576 try {
Adrian Roos389beec2015-05-12 13:33:25 -07002577 if (mLastDispatchedSystemUiVisibility != vis) {
2578 mWindowManagerService.statusBarVisibilityChanged(vis);
2579 mLastDispatchedSystemUiVisibility = vis;
2580 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002581 } catch (RemoteException ex) {
2582 }
Joe Onorato93056472010-09-10 10:30:46 -04002583 }
2584
Daniel Sandler5c8da942011-06-28 00:29:04 -04002585 public void topAppWindowChanged(boolean showMenu) {
2586 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002587 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04002588 }
2589 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04002590 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04002591 }
2592
2593 // See above re: lights-out policy for legacy apps.
2594 if (showMenu) setLightsOn(true);
2595 }
2596
Daniel Sandler328310c2011-09-23 15:56:52 -04002597 @Override
Jason Monkb605fec2014-05-02 17:04:10 -04002598 public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
2599 boolean showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002600 boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
2601 int flags = mNavigationIconHints;
2602 if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
2603 flags |= NAVIGATION_HINT_BACK_ALT;
2604 } else {
2605 flags &= ~NAVIGATION_HINT_BACK_ALT;
2606 }
Jason Monkb605fec2014-05-02 17:04:10 -04002607 if (showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002608 flags |= NAVIGATION_HINT_IME_SHOWN;
2609 } else {
2610 flags &= ~NAVIGATION_HINT_IME_SHOWN;
2611 }
Daniel Sandler328310c2011-09-23 15:56:52 -04002612
Jason Monkf1ff2092014-04-29 16:50:53 -04002613 setNavigationIconHints(flags);
Daniel Sandler328310c2011-09-23 15:56:52 -04002614 }
2615
Daniel Sandler48852952011-12-01 14:34:23 -05002616 public static String viewInfo(View v) {
2617 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
2618 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04002619 }
2620
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002621 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04002622 synchronized (mQueueLock) {
2623 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002624 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04002625 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04002626 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04002627 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002628 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002629 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
2630 + " scroll " + mStackScroller.getScrollX()
2631 + "," + mStackScroller.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04002632 }
Joe Onorato808182d2010-07-09 18:52:06 -04002633
John Spurlockcfc359a2013-09-05 10:42:03 -04002634 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04002635 pw.print(" mStatusBarWindowState=");
2636 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002637 pw.print(" mStatusBarMode=");
2638 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlockbf370992014-06-17 13:58:31 -04002639 pw.print(" mDozing="); pw.println(mDozing);
John Spurlocke677d712014-02-13 12:52:19 -05002640 pw.print(" mZenMode=");
2641 pw.println(Settings.Global.zenModeToString(mZenMode));
Chris Wren3b6745b2014-03-07 14:34:35 -05002642 pw.print(" mUseHeadsUp=");
2643 pw.println(mUseHeadsUp);
John Spurlock0ec64c62013-08-26 15:37:58 -04002644 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
2645 if (mNavigationBarView != null) {
2646 pw.print(" mNavigationBarWindowState=");
2647 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002648 pw.print(" mNavigationBarMode=");
2649 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002650 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
2651 }
2652
Daniel Sandler48852952011-12-01 14:34:23 -05002653 pw.print(" mNavigationBarView=");
2654 if (mNavigationBarView == null) {
2655 pw.println("null");
2656 } else {
2657 mNavigationBarView.dump(fd, pw, args);
2658 }
2659
Dan Sandler16128f42014-05-21 12:48:22 -04002660 pw.print(" mMediaSessionManager=");
2661 pw.println(mMediaSessionManager);
2662 pw.print(" mMediaNotificationKey=");
2663 pw.println(mMediaNotificationKey);
2664 pw.print(" mMediaController=");
2665 pw.print(mMediaController);
2666 if (mMediaController != null) {
2667 pw.print(" state=" + mMediaController.getPlaybackState());
2668 }
2669 pw.println();
2670 pw.print(" mMediaMetadata=");
2671 pw.print(mMediaMetadata);
2672 if (mMediaMetadata != null) {
RoboErik75847b92014-07-29 13:10:17 -07002673 pw.print(" title=" + mMediaMetadata.getText(MediaMetadata.METADATA_KEY_TITLE));
Dan Sandler16128f42014-05-21 12:48:22 -04002674 }
2675 pw.println();
2676
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002677 pw.println(" Panels: ");
2678 if (mNotificationPanel != null) {
2679 pw.println(" mNotificationPanel=" +
2680 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
2681 pw.print (" ");
2682 mNotificationPanel.dump(fd, pw, args);
2683 }
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002684
John Spurlock813552c2014-09-19 08:30:21 -04002685 DozeLog.dump(pw);
2686
Daniel Sandler7579bca2011-08-18 15:47:26 -04002687 if (DUMPTRUCK) {
2688 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002689 mNotificationData.dump(pw, " ");
Daniel Sandler7579bca2011-08-18 15:47:26 -04002690 }
2691
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002692 mIconController.dump(pw);
Jim Miller5e6af442011-12-02 18:24:26 -08002693
Daniel Sandler89d97132011-09-08 15:31:57 -04002694 if (false) {
2695 pw.println("see the logcat for a dump of the views we have created.");
2696 // must happen on ui thread
2697 mHandler.post(new Runnable() {
2698 public void run() {
2699 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04002700 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04002701 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002702 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002703 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002704 }
2705 });
2706 }
Joe Onorato808182d2010-07-09 18:52:06 -04002707 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002708
Daniel Sandler151f00d2012-10-02 22:33:08 -04002709 if (DEBUG_GESTURES) {
2710 pw.print(" status bar gestures: ");
2711 mGestureRec.dump(fd, pw, args);
2712 }
Selim Cinek7025f262015-07-13 16:22:48 -07002713 if (mStatusBarWindowManager != null) {
2714 mStatusBarWindowManager.dump(fd, pw, args);
2715 }
John Spurlock486b78e2014-07-07 08:37:56 -04002716 if (mNetworkController != null) {
2717 mNetworkController.dump(fd, pw, args);
2718 }
2719 if (mBluetoothController != null) {
2720 mBluetoothController.dump(fd, pw, args);
2721 }
Jason Monkdd5bdc62015-07-20 12:18:38 -04002722 if (mHotspotController != null) {
2723 mHotspotController.dump(fd, pw, args);
2724 }
John Spurlock1e6eb172014-07-13 11:59:50 -04002725 if (mCastController != null) {
2726 mCastController.dump(fd, pw, args);
2727 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +02002728 if (mUserSwitcherController != null) {
2729 mUserSwitcherController.dump(fd, pw, args);
2730 }
John Spurlock0ff62e02014-07-22 16:15:08 -04002731 if (mBatteryController != null) {
2732 mBatteryController.dump(fd, pw, args);
2733 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02002734 if (mNextAlarmController != null) {
2735 mNextAlarmController.dump(fd, pw, args);
2736 }
Adrian Roose9175082015-06-15 13:23:14 -07002737 if (mAssistManager != null) {
2738 mAssistManager.dump(fd, pw, args);
2739 }
Jason Monk3d5f5512014-07-25 11:17:28 -04002740 if (mSecurityController != null) {
2741 mSecurityController.dump(fd, pw, args);
2742 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002743 if (mHeadsUpManager != null) {
2744 mHeadsUpManager.dump(fd, pw, args);
Chris Wren428c6b62014-12-05 16:07:06 -05002745 } else {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002746 pw.println(" mHeadsUpManager: null");
Chris Wren428c6b62014-12-05 16:07:06 -05002747 }
Jason Monkab525272015-07-13 17:02:49 -04002748 if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
2749 KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
2750 }
Chris Wren428c6b62014-12-05 16:07:06 -05002751
John Spurlock7bbb9f62014-10-21 12:15:28 -04002752 pw.println("SharedPreferences:");
Andrew Flynn82862572015-04-01 14:22:37 -04002753 for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
John Spurlock7bbb9f62014-10-21 12:15:28 -04002754 pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
2755 }
Joe Onorato808182d2010-07-09 18:52:06 -04002756 }
2757
Chris Wren3b6745b2014-03-07 14:34:35 -05002758 private String hunStateToString(Entry entry) {
2759 if (entry == null) return "null";
2760 if (entry.notification == null) return "corrupt";
2761 return entry.notification.getPackageName();
2762 }
2763
John Spurlock0ec64c62013-08-26 15:37:58 -04002764 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
2765 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
2766 pw.println(BarTransitions.modeToString(transitions.getMode()));
2767 }
2768
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002769 @Override
2770 public void createAndAddWindows() {
2771 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04002772 }
Jim Millere898ac52012-04-06 17:10:57 -07002773
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002774 private void addStatusBarWindow() {
Daniel Sandlera310af82012-04-24 01:20:13 -04002775 makeStatusBarView();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002776 mStatusBarWindowManager = new StatusBarWindowManager(mContext);
2777 mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
Joe Onorato808182d2010-07-09 18:52:06 -04002778 }
2779
Daniel Sandler747a9e92012-08-10 16:39:19 -04002780 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002781 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04002782 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002783 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04002784 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04002785 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04002786 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2787 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002788 }
2789
Christoph Studerb0183992014-12-22 21:02:26 +01002790 float getDisplayDensity() {
2791 return mDisplayMetrics.density;
2792 }
2793
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002794 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
Jorim Jaggid9449862015-05-29 14:49:08 -07002795 boolean dismissShade) {
2796 startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, null /* callback */);
2797 }
2798
2799 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
2800 final boolean dismissShade, final Callback callback) {
Daniel Sandler3679bf52012-10-16 21:30:28 -04002801 if (onlyProvisioned && !isDeviceProvisioned()) return;
Adrian Roos4314f6d2014-05-28 14:10:27 +02002802
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002803 final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
2804 mContext, intent, mCurrentUserId);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02002805 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Selim Cineke70d6532015-04-24 16:46:13 -07002806 Runnable runnable = new Runnable() {
2807 public void run() {
Jorim Jaggib835dd72015-06-08 12:28:42 -07002808 mAssistManager.hideAssist();
Selim Cineke70d6532015-04-24 16:46:13 -07002809 intent.setFlags(
2810 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Jorim Jaggid9449862015-05-29 14:49:08 -07002811 int result = ActivityManager.START_CANCELED;
2812 try {
2813 result = ActivityManagerNative.getDefault().startActivityAsUser(
2814 null, mContext.getBasePackageName(),
2815 intent,
2816 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2817 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
2818 UserHandle.CURRENT.getIdentifier());
2819 } catch (RemoteException e) {
2820 Log.w(TAG, "Unable to start activity", e);
2821 }
Selim Cineke70d6532015-04-24 16:46:13 -07002822 overrideActivityPendingAppTransition(
2823 keyguardShowing && !afterKeyguardGone);
Jorim Jaggid9449862015-05-29 14:49:08 -07002824 if (callback != null) {
2825 callback.onActivityStarted(result);
2826 }
Selim Cineke70d6532015-04-24 16:46:13 -07002827 }
2828 };
Jorim Jaggid9449862015-05-29 14:49:08 -07002829 Runnable cancelRunnable = new Runnable() {
2830 @Override
2831 public void run() {
Jorim Jaggi5cc86592015-06-08 14:48:28 -07002832 if (callback != null) {
2833 callback.onActivityStarted(ActivityManager.START_CANCELED);
2834 }
Jorim Jaggid9449862015-05-29 14:49:08 -07002835 }
2836 };
Jorim Jaggib835dd72015-06-08 12:28:42 -07002837 executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShade,
2838 afterKeyguardGone);
Selim Cineke70d6532015-04-24 16:46:13 -07002839 }
2840
2841 public void executeRunnableDismissingKeyguard(final Runnable runnable,
Jorim Jaggid9449862015-05-29 14:49:08 -07002842 final Runnable cancelAction,
Selim Cineke70d6532015-04-24 16:46:13 -07002843 final boolean dismissShade,
2844 final boolean afterKeyguardGone) {
2845 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Adrian Roos4314f6d2014-05-28 14:10:27 +02002846 dismissKeyguardThenExecute(new OnDismissAction() {
2847 @Override
2848 public boolean onDismiss() {
Selim Cinekbaa23272014-07-08 18:01:07 +02002849 AsyncTask.execute(new Runnable() {
2850 public void run() {
2851 try {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002852 if (keyguardShowing && !afterKeyguardGone) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002853 ActivityManagerNative.getDefault()
2854 .keyguardWaitingForActivityDrawn();
2855 }
Selim Cineke70d6532015-04-24 16:46:13 -07002856 if (runnable != null) {
2857 runnable.run();
2858 }
Selim Cinekbaa23272014-07-08 18:01:07 +02002859 } catch (RemoteException e) {
2860 }
2861 }
2862 });
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002863 if (dismissShade) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002864 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
2865 true /* delayed*/);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002866 }
2867 return true;
Adrian Roos4314f6d2014-05-28 14:10:27 +02002868 }
Jorim Jaggid9449862015-05-29 14:49:08 -07002869 }, cancelAction, afterKeyguardGone);
Daniel Sandler3679bf52012-10-16 21:30:28 -04002870 }
2871
Joe Onorato808182d2010-07-09 18:52:06 -04002872 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2873 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04002874 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04002875 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04002876 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Kenny Guy44fc65f2014-11-28 22:18:14 +00002877 if (isCurrentProfile(getSendingUserId())) {
2878 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
2879 String reason = intent.getStringExtra("reason");
2880 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
2881 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
2882 }
2883 animateCollapsePanels(flags);
Michael Jurka3b1fc472011-06-13 10:54:40 -07002884 }
Joe Onorato808182d2010-07-09 18:52:06 -04002885 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002886 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04002887 notifyNavigationBarScreenOn(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002888 notifyHeadsUpScreenOff();
John Spurlock42197262013-10-21 09:32:25 -04002889 finishBarAnimations();
Selim Cinekccd14fb2014-08-12 18:53:24 +02002890 resetUserExpandedStates();
Daniel Sandlered930e52012-07-03 14:31:22 -04002891 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04002892 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04002893 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002894 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07002895 }
2896 };
2897
2898 private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
2899 public void onReceive(Context context, Intent intent) {
2900 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
2901 String action = intent.getAction();
2902 if (ACTION_DEMO.equals(action)) {
John Spurlock3c875662013-08-31 15:07:25 -04002903 Bundle bundle = intent.getExtras();
2904 if (bundle != null) {
2905 String command = bundle.getString("command", "").trim().toLowerCase();
2906 if (command.length() > 0) {
2907 try {
2908 dispatchDemoCommand(command, bundle);
2909 } catch (Throwable t) {
2910 Log.w(TAG, "Error running demo command, intent=" + intent, t);
2911 }
2912 }
2913 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07002914 } else if (ACTION_FAKE_ARTWORK.equals(action)) {
Dan Sandler16128f42014-05-21 12:48:22 -04002915 if (DEBUG_MEDIA_FAKE_ARTWORK) {
2916 updateMediaMetaData(true);
2917 }
John Spurlock3c875662013-08-31 15:07:25 -04002918 }
Joe Onorato808182d2010-07-09 18:52:06 -04002919 }
2920 };
2921
Selim Cinekccd14fb2014-08-12 18:53:24 +02002922 private void resetUserExpandedStates() {
2923 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
2924 final int notificationCount = activeNotifications.size();
2925 for (int i = 0; i < notificationCount; i++) {
2926 NotificationData.Entry entry = activeNotifications.get(i);
2927 if (entry.row != null) {
2928 entry.row.resetUserExpansion();
2929 }
2930 }
2931 }
2932
Adrian Roos7d7090d2014-05-21 13:10:23 +02002933 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07002934 protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
2935 dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
2936 }
2937
2938 private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02002939 boolean afterKeyguardGone) {
Adrian Roos7d7090d2014-05-21 13:10:23 +02002940 if (mStatusBarKeyguardViewManager.isShowing()) {
Jorim Jaggid9449862015-05-29 14:49:08 -07002941 mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
2942 afterKeyguardGone);
Adrian Roos7d7090d2014-05-21 13:10:23 +02002943 } else {
2944 action.onDismiss();
2945 }
2946 }
2947
Daniel Sandler777dcde2013-09-30 10:21:45 -04002948 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
2949 @Override
2950 protected void onConfigurationChanged(Configuration newConfig) {
2951 super.onConfigurationChanged(newConfig); // calls refreshLayout
2952
2953 if (DEBUG) {
2954 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
2955 }
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002956 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04002957
2958 updateResources();
2959 repositionNavigationBar();
Jorim Jaggif6411742014-08-05 17:10:43 +00002960 updateRowStates();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002961 mIconController.updateResources();
Jason Monk18f99d92014-09-11 13:36:42 -04002962 mScreenPinningRequest.onConfigurationChanged();
Jason Monk1c040db2015-07-20 09:45:54 -04002963 mNetworkController.onConfigurationChanged();
Daniel Sandler777dcde2013-09-30 10:21:45 -04002964 }
2965
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002966 @Override
2967 public void userSwitched(int newUserId) {
Chris Wrena6d4fb62014-11-20 14:46:23 -05002968 super.userSwitched(newUserId);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002969 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002970 animateCollapsePanels();
Adrian Roos31b844b2014-11-21 13:55:09 +01002971 updatePublicMode();
Christoph Studer37fe6932014-05-26 13:10:30 +02002972 updateNotifications();
John Spurlock919adac2012-10-02 16:41:12 -04002973 resetUserSetupObserver();
John Spurlock89f060a2014-07-16 21:03:15 -04002974 setControllerUsers();
Selim Cinek9a634992015-06-23 01:10:07 -04002975 mAssistManager.onUserSwitched(newUserId);
John Spurlock89f060a2014-07-16 21:03:15 -04002976 }
2977
2978 private void setControllerUsers() {
2979 if (mZenModeController != null) {
2980 mZenModeController.setUserId(mCurrentUserId);
2981 }
Robin Lee63204ee2015-06-04 01:53:01 +01002982 if (mSecurityController != null) {
2983 mSecurityController.onUserSwitched(mCurrentUserId);
2984 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04002985 }
John Spurlock919adac2012-10-02 16:41:12 -04002986
2987 private void resetUserSetupObserver() {
2988 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
2989 mUserSetupObserver.onChange(false);
2990 mContext.getContentResolver().registerContentObserver(
2991 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002992 mUserSetupObserver, mCurrentUserId);
John Spurlock919adac2012-10-02 16:41:12 -04002993 }
2994
Joe Onorato808182d2010-07-09 18:52:06 -04002995 /**
2996 * Reload some of our resources when the configuration changes.
2997 *
2998 * We don't reload everything when the configuration changes -- we probably
2999 * should, but getting that smooth is tough. Someday we'll fix that. In the
3000 * meantime, just update the things that we know change.
3001 */
3002 void updateResources() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003003 // Update the quick setting tiles
John Spurlock7e6809a2014-08-06 16:03:14 -04003004 if (mQSPanel != null) {
3005 mQSPanel.updateResources();
3006 }
Winson Chungd63c59782012-09-05 17:34:41 -07003007
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003008 loadDimens();
John Spurlock7e6809a2014-08-06 16:03:14 -04003009
3010 if (mNotificationPanel != null) {
3011 mNotificationPanel.updateResources();
3012 }
Adrian Roos5fd872e2014-08-12 17:28:58 +02003013 if (mBrightnessMirrorController != null) {
3014 mBrightnessMirrorController.updateResources();
3015 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003016 }
Jim Miller5e6af442011-12-02 18:24:26 -08003017
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003018 protected void loadDimens() {
3019 final Resources res = mContext.getResources();
3020
3021 mNaturalBarHeight = res.getDimensionPixelSize(
3022 com.android.internal.R.dimen.status_bar_height);
3023
Jorim Jaggife40f7d2014-04-28 15:20:04 +02003024 mRowMinHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
3025 mRowMaxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
Chris Wren51c75102013-07-16 20:49:17 -04003026
Jorim Jaggid4a57442014-04-10 02:45:55 +02003027 mKeyguardMaxNotificationCount = res.getInteger(R.integer.keyguard_max_notification_count);
3028
John Spurlock7e6809a2014-08-06 16:03:14 -04003029 if (DEBUG) Log.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04003030 }
3031
Christoph Studer92b389d2014-04-01 18:44:40 +02003032 // Visibility reporting
3033
3034 @Override
Christoph Studere8e28652014-10-29 17:27:53 +01003035 protected void handleVisibleToUserChanged(boolean visibleToUser) {
3036 if (visibleToUser) {
3037 super.handleVisibleToUserChanged(visibleToUser);
3038 startNotificationLogging();
Christoph Studer92b389d2014-04-01 18:44:40 +02003039 } else {
Christoph Studer037e34c2014-04-30 20:06:04 +02003040 stopNotificationLogging();
Christoph Studere8e28652014-10-29 17:27:53 +01003041 super.handleVisibleToUserChanged(visibleToUser);
Christoph Studer92b389d2014-04-01 18:44:40 +02003042 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003043 }
3044
Christoph Studer037e34c2014-04-30 20:06:04 +02003045 private void stopNotificationLogging() {
3046 // Report all notifications as invisible and turn down the
3047 // reporter.
3048 if (!mCurrentlyVisibleNotifications.isEmpty()) {
Chris Wrend1dbc922015-06-19 17:51:16 -04003049 logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(),
3050 mCurrentlyVisibleNotifications);
3051 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer037e34c2014-04-30 20:06:04 +02003052 }
3053 mHandler.removeCallbacks(mVisibilityReporter);
3054 mStackScroller.setChildLocationsChangedListener(null);
3055 }
3056
Christoph Studere8e28652014-10-29 17:27:53 +01003057 private void startNotificationLogging() {
3058 mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
3059 // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
3060 // cause the scroller to emit child location events. Hence generate
3061 // one ourselves to guarantee that we're reporting visible
3062 // notifications.
3063 // (Note that in cases where the scroller does emit events, this
3064 // additional event doesn't break anything.)
3065 mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
Christoph Studer037e34c2014-04-30 20:06:04 +02003066 }
3067
Christoph Studer92b389d2014-04-01 18:44:40 +02003068 private void logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -04003069 Collection<NotificationVisibility> newlyVisible,
3070 Collection<NotificationVisibility> noLongerVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +02003071 if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
3072 return;
3073 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003074 NotificationVisibility[] newlyVisibleAr =
3075 newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]);
3076 NotificationVisibility[] noLongerVisibleAr =
3077 noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]);
Christoph Studer92b389d2014-04-01 18:44:40 +02003078 try {
3079 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
3080 } catch (RemoteException e) {
3081 // Ignore.
3082 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003083
3084 final int N = newlyVisible.size();
Amith Yamasani76495672015-07-07 15:22:54 -07003085 if (N > 0) {
3086 String[] newlyVisibleKeyAr = new String[N];
3087 for (int i = 0; i < N; i++) {
3088 newlyVisibleKeyAr[i] = newlyVisibleAr[i].key;
3089 }
3090
3091 setNotificationsShown(newlyVisibleKeyAr);
Chris Wrend1dbc922015-06-19 17:51:16 -04003092 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003093 }
3094
Christoph Studer2231c6e2014-12-19 12:40:13 +01003095 // State logging
3096
3097 private void logStateToEventlog() {
3098 boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
3099 boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
3100 boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
3101 boolean isSecure = mUnlockMethodCache.isMethodSecure();
Selim Cineke8bae622015-07-15 13:24:06 -07003102 boolean canSkipBouncer = mUnlockMethodCache.canSkipBouncer();
Christoph Studer2231c6e2014-12-19 12:40:13 +01003103 int stateFingerprint = getLoggingFingerprint(mState,
3104 isShowing,
3105 isOccluded,
3106 isBouncerShowing,
3107 isSecure,
Selim Cineke8bae622015-07-15 13:24:06 -07003108 canSkipBouncer);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003109 if (stateFingerprint != mLastLoggedStateFingerprint) {
3110 EventLogTags.writeSysuiStatusBarState(mState,
3111 isShowing ? 1 : 0,
3112 isOccluded ? 1 : 0,
3113 isBouncerShowing ? 1 : 0,
3114 isSecure ? 1 : 0,
Selim Cineke8bae622015-07-15 13:24:06 -07003115 canSkipBouncer ? 1 : 0);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003116 mLastLoggedStateFingerprint = stateFingerprint;
3117 }
3118 }
3119
3120 /**
3121 * Returns a fingerprint of fields logged to eventlog
3122 */
3123 private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
3124 boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
3125 boolean currentlyInsecure) {
3126 // Reserve 8 bits for statusBarState. We'll never go higher than
3127 // that, right? Riiiight.
3128 return (statusBarState & 0xFF)
3129 | ((keyguardShowing ? 1 : 0) << 8)
3130 | ((keyguardOccluded ? 1 : 0) << 9)
3131 | ((bouncerShowing ? 1 : 0) << 10)
3132 | ((secure ? 1 : 0) << 11)
3133 | ((currentlyInsecure ? 1 : 0) << 12);
3134 }
3135
Joe Onorato808182d2010-07-09 18:52:06 -04003136 //
3137 // tracing
3138 //
3139
3140 void postStartTracing() {
3141 mHandler.postDelayed(mStartTracing, 3000);
3142 }
3143
3144 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04003145 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
3146 Context.VIBRATOR_SERVICE);
John Spurlock7b414672014-07-18 13:02:39 -04003147 vib.vibrate(250, VIBRATION_ATTRIBUTES);
Joe Onorato808182d2010-07-09 18:52:06 -04003148 }
3149
3150 Runnable mStartTracing = new Runnable() {
3151 public void run() {
3152 vibrate();
3153 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04003154 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003155 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
3156 mHandler.postDelayed(mStopTracing, 10000);
3157 }
3158 };
3159
3160 Runnable mStopTracing = new Runnable() {
3161 public void run() {
3162 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04003163 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003164 vibrate();
3165 }
3166 };
Chris Wren0c8275b2012-05-08 13:36:48 -04003167
3168 @Override
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07003169 public boolean shouldDisableNavbarGestures() {
Jorim Jaggi18976a52015-07-24 13:18:19 -07003170 return !isDeviceProvisioned() || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07003171 }
Joe Onorato808182d2010-07-09 18:52:06 -04003172
Jason Monkee43cdf2015-06-19 14:20:46 -04003173 public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
John Spurlockd47a3f32014-05-18 19:14:14 -04003174 mHandler.postDelayed(new Runnable() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003175 @Override
3176 public void run() {
Jason Monkee43cdf2015-06-19 14:20:46 -04003177 handleStartActivityDismissingKeyguard(intent, true /*onlyProvisioned*/);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003178 }
John Spurlockd47a3f32014-05-18 19:14:14 -04003179 }, delay);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003180 }
3181
Jason Monkee43cdf2015-06-19 14:20:46 -04003182 private void handleStartActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003183 startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
John Spurlockde547002014-02-28 17:50:39 -05003184 }
3185
Romain Guy648342f2012-05-25 10:44:45 -07003186 private static class FastColorDrawable extends Drawable {
3187 private final int mColor;
3188
3189 public FastColorDrawable(int color) {
3190 mColor = 0xff000000 | color;
3191 }
3192
3193 @Override
3194 public void draw(Canvas canvas) {
3195 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
3196 }
3197
3198 @Override
3199 public void setAlpha(int alpha) {
3200 }
3201
3202 @Override
Chris Craikbd3bfc52015-03-02 10:43:29 -08003203 public void setColorFilter(ColorFilter colorFilter) {
Romain Guy648342f2012-05-25 10:44:45 -07003204 }
3205
3206 @Override
3207 public int getOpacity() {
3208 return PixelFormat.OPAQUE;
3209 }
3210
3211 @Override
3212 public void setBounds(int left, int top, int right, int bottom) {
3213 }
3214
3215 @Override
3216 public void setBounds(Rect bounds) {
3217 }
3218 }
John Spurlock5c454122013-06-17 07:35:46 -04003219
3220 @Override
3221 public void destroy() {
3222 super.destroy();
3223 if (mStatusBarWindow != null) {
3224 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05003225 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04003226 }
3227 if (mNavigationBarView != null) {
3228 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05003229 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04003230 }
Jason Monk4ae97d32014-12-17 10:14:33 -05003231 if (mHandlerThread != null) {
3232 mHandlerThread.quitSafely();
3233 mHandlerThread = null;
3234 }
John Spurlock5c454122013-06-17 07:35:46 -04003235 mContext.unregisterReceiver(mBroadcastReceiver);
Adrian Roos8e3e8362015-07-16 19:42:22 -07003236 mContext.unregisterReceiver(mDemoReceiver);
Selim Cineke70d6532015-04-24 16:46:13 -07003237 mAssistManager.destroy();
Jason Monk07b75fe2015-05-14 16:47:03 -04003238
3239 final SignalClusterView signalCluster =
3240 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
3241 final SignalClusterView signalClusterKeyguard =
3242 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
3243 final SignalClusterView signalClusterQs =
3244 (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
Jason Monk5e745172015-06-02 19:14:44 -04003245 mNetworkController.removeSignalCallback(signalCluster);
3246 mNetworkController.removeSignalCallback(signalClusterKeyguard);
3247 mNetworkController.removeSignalCallback(signalClusterQs);
3248 if (mQSPanel != null && mQSPanel.getHost() != null) {
3249 mQSPanel.getHost().destroy();
3250 }
John Spurlock5c454122013-06-17 07:35:46 -04003251 }
John Spurlock3c875662013-08-31 15:07:25 -04003252
3253 private boolean mDemoModeAllowed;
3254 private boolean mDemoMode;
John Spurlock3c875662013-08-31 15:07:25 -04003255
3256 @Override
3257 public void dispatchDemoCommand(String command, Bundle args) {
3258 if (!mDemoModeAllowed) {
3259 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
Jason Monk431ad732015-07-16 08:58:15 -04003260 DEMO_MODE_ALLOWED, 0) != 0;
John Spurlock3c875662013-08-31 15:07:25 -04003261 }
3262 if (!mDemoModeAllowed) return;
3263 if (command.equals(COMMAND_ENTER)) {
3264 mDemoMode = true;
3265 } else if (command.equals(COMMAND_EXIT)) {
3266 mDemoMode = false;
3267 checkBarModes();
3268 } else if (!mDemoMode) {
3269 // automatically enter demo mode on first demo command
3270 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
3271 }
3272 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
John Spurlockbb4a7022014-11-08 12:40:19 -05003273 if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
3274 mVolumeComponent.dispatchDemoCommand(command, args);
3275 }
John Spurlock3c875662013-08-31 15:07:25 -04003276 if (modeChange || command.equals(COMMAND_CLOCK)) {
3277 dispatchDemoCommandToView(command, args, R.id.clock);
3278 }
3279 if (modeChange || command.equals(COMMAND_BATTERY)) {
3280 dispatchDemoCommandToView(command, args, R.id.battery);
3281 }
3282 if (modeChange || command.equals(COMMAND_STATUS)) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003283 mIconController.dispatchDemoCommand(command, args);
3284
John Spurlock3c875662013-08-31 15:07:25 -04003285 }
3286 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
3287 mNetworkController.dispatchDemoCommand(command, args);
3288 }
John Spurlock7f42fc52014-01-14 16:20:39 -05003289 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
3290 View notifications = mStatusBarView == null ? null
3291 : mStatusBarView.findViewById(R.id.notification_icon_area);
3292 if (notifications != null) {
3293 String visible = args.getString("visible");
3294 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
3295 notifications.setVisibility(vis);
3296 }
3297 }
John Spurlock3c875662013-08-31 15:07:25 -04003298 if (command.equals(COMMAND_BARS)) {
3299 String mode = args.getString("mode");
3300 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04003301 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04003302 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
John Spurlock0ff62e02014-07-22 16:15:08 -04003303 "transparent".equals(mode) ? MODE_TRANSPARENT :
3304 "warning".equals(mode) ? MODE_WARNING :
John Spurlock3c875662013-08-31 15:07:25 -04003305 -1;
3306 if (barMode != -1) {
3307 boolean animate = true;
3308 if (mStatusBarView != null) {
3309 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
3310 }
3311 if (mNavigationBarView != null) {
3312 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
3313 }
3314 }
3315 }
3316 }
3317
3318 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
3319 if (mStatusBarView == null) return;
3320 View v = mStatusBarView.findViewById(id);
3321 if (v instanceof DemoMode) {
3322 ((DemoMode)v).dispatchDemoCommand(command, args);
3323 }
3324 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003325
Jorim Jaggiecbab362014-04-23 16:13:15 +02003326 /**
3327 * @return The {@link StatusBarState} the status bar is in.
3328 */
3329 public int getBarState() {
3330 return mState;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003331 }
3332
Chris Wren16895942015-06-23 11:22:20 -04003333 @Override
3334 protected boolean isPanelFullyCollapsed() {
3335 return mNotificationPanel.isFullyCollapsed();
3336 }
3337
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003338 public void showKeyguard() {
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003339 if (mLaunchTransitionFadingAway) {
3340 mNotificationPanel.animate().cancel();
Selim Cinek37c110f2015-05-22 12:38:44 -07003341 onLaunchTransitionFadingEnded();
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003342 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003343 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003344 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003345 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003346 if (!mDeviceInteractive) {
Jorim Jaggid41083a2014-09-12 02:54:40 +02003347
3348 // If the screen is off already, we need to disable touch events because these might
3349 // collapse the panel after we expanded it, and thus we would end up with a blank
3350 // Keyguard.
3351 mNotificationPanel.setTouchDisabled(true);
3352 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003353 instantExpandNotificationsPanel();
Jorim Jaggiecbab362014-04-23 16:13:15 +02003354 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003355 if (mDraggedDownRow != null) {
3356 mDraggedDownRow.setUserLocked(false);
Selim Cinekb5605e52015-02-20 18:21:41 +01003357 mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003358 mDraggedDownRow = null;
3359 }
Jorim Jaggi19695d92015-07-20 15:51:40 -07003360 mAssistManager.onLockscreenShown();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003361 }
3362
Selim Cinek37c110f2015-05-22 12:38:44 -07003363 private void onLaunchTransitionFadingEnded() {
3364 mNotificationPanel.setAlpha(1.0f);
3365 runLaunchTransitionEndRunnable();
3366 mLaunchTransitionFadingAway = false;
3367 mScrimController.forceHideScrims(false /* hide */);
3368 updateMediaMetaData(true /* metaDataChanged */);
3369 }
3370
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003371 public boolean isCollapsing() {
3372 return mNotificationPanel.isCollapsing();
3373 }
3374
3375 public void addPostCollapseAction(Runnable r) {
3376 mPostCollapseRunnables.add(r);
3377 }
3378
Selim Cinekbaa23272014-07-08 18:01:07 +02003379 public boolean isInLaunchTransition() {
3380 return mNotificationPanel.isLaunchTransitionRunning()
3381 || mNotificationPanel.isLaunchTransitionFinished();
3382 }
3383
3384 /**
3385 * Fades the content of the keyguard away after the launch transition is done.
3386 *
3387 * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
3388 * starts
3389 * @param endRunnable the runnable to be run when the transition is done
3390 */
3391 public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003392 Runnable endRunnable) {
Jorim Jaggi826730a2014-12-08 21:05:13 +01003393 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003394 mLaunchTransitionEndRunnable = endRunnable;
Selim Cinekbaa23272014-07-08 18:01:07 +02003395 Runnable hideRunnable = new Runnable() {
3396 @Override
3397 public void run() {
3398 mLaunchTransitionFadingAway = true;
3399 if (beforeFading != null) {
3400 beforeFading.run();
3401 }
Selim Cinek37c110f2015-05-22 12:38:44 -07003402 mScrimController.forceHideScrims(true /* hide */);
3403 updateMediaMetaData(false);
Selim Cinekbaa23272014-07-08 18:01:07 +02003404 mNotificationPanel.setAlpha(1);
3405 mNotificationPanel.animate()
3406 .alpha(0)
3407 .setStartDelay(FADE_KEYGUARD_START_DELAY)
3408 .setDuration(FADE_KEYGUARD_DURATION)
3409 .withLayer()
3410 .withEndAction(new Runnable() {
3411 @Override
3412 public void run() {
Selim Cinek37c110f2015-05-22 12:38:44 -07003413 onLaunchTransitionFadingEnded();
Selim Cinekbaa23272014-07-08 18:01:07 +02003414 }
3415 });
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003416 mIconController.appTransitionStarting(SystemClock.uptimeMillis(),
3417 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Selim Cinekbaa23272014-07-08 18:01:07 +02003418 }
3419 };
3420 if (mNotificationPanel.isLaunchTransitionRunning()) {
3421 mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
3422 } else {
3423 hideRunnable.run();
3424 }
3425 }
3426
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003427 /**
Jorim Jaggi826730a2014-12-08 21:05:13 +01003428 * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
3429 * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
3430 * because the launched app crashed or something else went wrong.
3431 */
3432 public void startLaunchTransitionTimeout() {
3433 mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
3434 LAUNCH_TRANSITION_TIMEOUT_MS);
3435 }
3436
3437 private void onLaunchTransitionTimeout() {
3438 Log.w(TAG, "Launch transition: Timeout!");
3439 mNotificationPanel.resetViews();
3440 }
3441
3442 private void runLaunchTransitionEndRunnable() {
3443 if (mLaunchTransitionEndRunnable != null) {
3444 Runnable r = mLaunchTransitionEndRunnable;
3445
3446 // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
3447 // which would lead to infinite recursion. Protect against it.
3448 mLaunchTransitionEndRunnable = null;
3449 r.run();
3450 }
3451 }
3452
3453 /**
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003454 * @return true if we would like to stay in the shade, false if it should go away entirely
3455 */
3456 public boolean hideKeyguard() {
3457 boolean staying = mLeaveOpenOnKeyguardHide;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003458 setBarState(StatusBarState.SHADE);
3459 if (mLeaveOpenOnKeyguardHide) {
3460 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003461 mNotificationPanel.animateToFullShade(calculateGoingToFullShadeDelay());
3462 if (mDraggedDownRow != null) {
3463 mDraggedDownRow.setUserLocked(false);
3464 mDraggedDownRow = null;
3465 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003466 } else {
3467 instantCollapseNotificationPanel();
3468 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02003469 updateKeyguardState(staying, false /* fromShadeLocked */);
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01003470
3471 // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
3472 // visibilities so next time we open the panel we know the correct height already.
3473 if (mQSPanel != null) {
3474 mQSPanel.refreshAllTiles();
3475 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003476 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003477 return staying;
3478 }
3479
3480 public long calculateGoingToFullShadeDelay() {
3481 return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
Jorim Jaggi15682502014-04-23 12:01:36 +02003482 }
3483
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003484 /**
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003485 * Notifies the status bar that Keyguard is going away very soon.
3486 */
3487 public void keyguardGoingAway() {
3488
3489 // Treat Keyguard exit animation as an app transition to achieve nice transition for status
3490 // bar.
3491 mIconController.appTransitionPending();
3492 }
3493
3494 /**
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003495 * Notifies the status bar the Keyguard is fading away with the specified timings.
3496 *
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003497 * @param startTime the start time of the animations in uptime millis
3498 * @param delay the precalculated animation delay in miliseconds
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003499 * @param fadeoutDuration the duration of the exit animation, in milliseconds
3500 */
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003501 public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003502 mKeyguardFadingAway = true;
3503 mKeyguardFadingAwayDelay = delay;
3504 mKeyguardFadingAwayDuration = fadeoutDuration;
3505 mWaitingForKeyguardExit = false;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003506 mIconController.appTransitionStarting(
3507 startTime + fadeoutDuration
3508 - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
3509 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Jorim Jaggi740452e2015-07-09 12:13:59 -07003510 disable(mDisabledUnmodified1, mDisabledUnmodified2, fadeoutDuration > 0 /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003511 }
3512
Jorim Jaggi416493b2014-09-13 03:57:32 +02003513 public boolean isKeyguardFadingAway() {
3514 return mKeyguardFadingAway;
3515 }
3516
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003517 /**
3518 * Notifies that the Keyguard fading away animation is done.
3519 */
3520 public void finishKeyguardFadingAway() {
3521 mKeyguardFadingAway = false;
3522 }
3523
Adrian Roosd322f1a2015-04-23 15:19:45 -07003524 public void stopWaitingForKeyguardExit() {
3525 mWaitingForKeyguardExit = false;
3526 }
3527
Jorim Jaggi15682502014-04-23 12:01:36 +02003528 private void updatePublicMode() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003529 setLockscreenPublicMode(
3530 mStatusBarKeyguardViewManager.isShowing() && mStatusBarKeyguardViewManager
3531 .isSecure(mCurrentUserId));
Jorim Jaggi15682502014-04-23 12:01:36 +02003532 }
3533
Jorim Jaggi98f85302014-08-07 17:45:04 +02003534 private void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003535 if (mState == StatusBarState.KEYGUARD) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003536 mKeyguardIndicationController.setVisible(true);
Selim Cinek4c6969a2014-05-26 19:22:17 +02003537 mNotificationPanel.resetViews();
Jorim Jaggi98f85302014-08-07 17:45:04 +02003538 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
Selim Cinek80c2abe2015-06-17 15:37:30 -07003539 mStatusBarView.removePendingHideExpandedRunnables();
Jorim Jaggi15682502014-04-23 12:01:36 +02003540 } else {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003541 mKeyguardIndicationController.setVisible(false);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003542 mKeyguardUserSwitcher.setKeyguard(false,
3543 goingToFullShade || mState == StatusBarState.SHADE_LOCKED || fromShadeLocked);
Jorim Jaggi15682502014-04-23 12:01:36 +02003544 }
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003545 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003546 mScrimController.setKeyguardShowing(true);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003547 mIconPolicy.setKeyguardShowing(true);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003548 } else {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003549 mScrimController.setKeyguardShowing(false);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003550 mIconPolicy.setKeyguardShowing(false);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003551 }
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003552 mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
John Spurlockbf370992014-06-17 13:58:31 -04003553 updateDozingState();
Jorim Jaggi15682502014-04-23 12:01:36 +02003554 updatePublicMode();
Jorim Jaggiae441282014-08-01 02:45:18 +02003555 updateStackScrollerState(goingToFullShade);
Christoph Studer37fe6932014-05-26 13:10:30 +02003556 updateNotifications();
Jorim Jaggia6310292014-04-16 14:11:52 +02003557 checkBarModes();
Dan Sandler16128f42014-05-21 12:48:22 -04003558 updateMediaMetaData(false);
John Spurlock657c62c2014-07-22 12:18:09 -04003559 mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
3560 mStatusBarKeyguardViewManager.isSecure());
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003561 }
3562
John Spurlockbf370992014-06-17 13:58:31 -04003563 private void updateDozingState() {
Jorim Jaggi4e857f42014-11-17 19:14:04 +01003564 boolean animate = !mDozing && mDozeScrimController.isPulsing();
3565 mNotificationPanel.setDozing(mDozing, animate);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003566 mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
Jorim Jaggi048af1f2014-11-11 22:51:10 +01003567 mScrimController.setDozing(mDozing);
Jorim Jaggi4e857f42014-11-17 19:14:04 +01003568 mDozeScrimController.setDozing(mDozing, animate);
John Spurlockbf370992014-06-17 13:58:31 -04003569 }
3570
Jorim Jaggiae441282014-08-01 02:45:18 +02003571 public void updateStackScrollerState(boolean goingToFullShade) {
John Spurlock4b3bda22014-05-22 14:32:20 -04003572 if (mStackScroller == null) return;
Selim Cinek1408eb52014-06-02 14:45:38 +02003573 boolean onKeyguard = mState == StatusBarState.KEYGUARD;
Jorim Jaggiae441282014-08-01 02:45:18 +02003574 mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
Selim Cinek1408eb52014-06-02 14:45:38 +02003575 mStackScroller.setDimmed(onKeyguard, false /* animate */);
Selim Cinek1408eb52014-06-02 14:45:38 +02003576 mStackScroller.setExpandingEnabled(!onKeyguard);
Selim Cineka32ab602014-06-11 15:06:01 +02003577 ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
3578 mStackScroller.setActivatedChild(null);
3579 if (activatedChild != null) {
3580 activatedChild.makeInactive(false /* animate */);
3581 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003582 }
3583
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003584 public void userActivity() {
Jorim Jaggib690f0d2014-07-03 23:25:44 +02003585 if (mState == StatusBarState.KEYGUARD) {
3586 mKeyguardViewMediatorCallback.userActivity();
3587 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003588 }
3589
Jorim Jaggidf993512014-05-13 23:06:35 +02003590 public boolean interceptMediaKey(KeyEvent event) {
3591 return mState == StatusBarState.KEYGUARD
3592 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
3593 }
3594
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003595 public boolean onMenuPressed() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003596 return mState == StatusBarState.KEYGUARD && mStatusBarKeyguardViewManager.onMenuPressed();
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003597 }
3598
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003599 public boolean onBackPressed() {
Adrian Roos0002a452014-07-03 13:46:07 +02003600 if (mStatusBarKeyguardViewManager.onBackPressed()) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003601 return true;
3602 }
Adrian Roos0002a452014-07-03 13:46:07 +02003603 if (mNotificationPanel.isQsExpanded()) {
John Spurlockf7ae4422014-08-01 12:45:18 -04003604 if (mNotificationPanel.isQsDetailShowing()) {
3605 mNotificationPanel.closeQsDetail();
3606 } else {
3607 mNotificationPanel.animateCloseQs();
3608 }
Adrian Roos0002a452014-07-03 13:46:07 +02003609 return true;
3610 }
3611 if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
3612 animateCollapsePanels();
3613 return true;
3614 }
3615 return false;
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003616 }
3617
Jorim Jaggi34250762014-07-03 23:51:19 +02003618 public boolean onSpacePressed() {
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003619 if (mDeviceInteractive
Jorim Jaggi2c33d5d2014-08-29 16:28:20 +02003620 && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
Jorim Jaggi4eedc1d2014-10-27 13:45:56 +01003621 animateCollapsePanels(
3622 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
Jorim Jaggi34250762014-07-03 23:51:19 +02003623 return true;
3624 }
3625 return false;
3626 }
3627
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003628 private void showBouncer() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003629 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekbaa23272014-07-08 18:01:07 +02003630 mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003631 mStatusBarKeyguardViewManager.dismiss();
3632 }
3633 }
3634
3635 private void instantExpandNotificationsPanel() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02003636
Jorim Jaggi0a27be82014-06-11 03:22:39 +02003637 // Make our window larger and the panel expanded.
Jorim Jaggifa505a72014-04-28 20:04:11 +02003638 makeExpandedVisible(true);
Jorim Jaggi0a27be82014-06-11 03:22:39 +02003639 mNotificationPanel.instantExpand();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003640 }
Adrian Roos5a46cd32014-04-03 16:51:58 +02003641
Jorim Jaggia005f1b2014-04-16 19:06:10 +02003642 private void instantCollapseNotificationPanel() {
Selim Cinek6bb4a9b2014-10-09 17:48:05 -07003643 mNotificationPanel.instantCollapse();
Jorim Jaggia005f1b2014-04-16 19:06:10 +02003644 }
3645
Jorim Jaggid4a57442014-04-10 02:45:55 +02003646 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02003647 public void onActivated(ActivatableNotificationView view) {
Christoph Studerb0183992014-12-22 21:02:26 +01003648 EventLogTags.writeSysuiLockscreenGesture(
3649 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
3650 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
Adrian Roos12c1ef52014-06-04 13:54:08 +02003651 mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
Selim Cineka32ab602014-06-11 15:06:01 +02003652 ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
3653 if (previousView != null) {
3654 previousView.makeInactive(true /* animate */);
3655 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003656 mStackScroller.setActivatedChild(view);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02003657 }
3658
Jorim Jaggiecbab362014-04-23 16:13:15 +02003659 /**
3660 * @param state The {@link StatusBarState} to set.
3661 */
3662 public void setBarState(int state) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01003663 // If we're visible and switched to SHADE_LOCKED (the user dragged
3664 // down on the lockscreen), clear notification LED, vibration,
3665 // ringing.
3666 // Other transitions are covered in handleVisibleToUserChanged().
3667 if (state != mState && mVisible && state == StatusBarState.SHADE_LOCKED) {
3668 try {
3669 mBarService.clearNotificationEffects();
3670 } catch (RemoteException e) {
3671 // Ignore.
Christoph Studer1f32c652014-11-26 15:32:20 +01003672 }
3673 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003674 mState = state;
Selim Cinek25fd4e2b2015-02-20 17:46:07 +01003675 mGroupManager.setStatusBarState(state);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003676 mStatusBarWindowManager.setStatusBarState(state);
Jorim Jaggi83969702015-06-05 14:59:24 -07003677 updateDozing();
Jorim Jaggiecbab362014-04-23 16:13:15 +02003678 }
3679
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02003680 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02003681 public void onActivationReset(ActivatableNotificationView view) {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003682 if (view == mStackScroller.getActivatedChild()) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003683 mKeyguardIndicationController.hideTransientIndication();
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003684 mStackScroller.setActivatedChild(null);
3685 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003686 }
3687
3688 public void onTrackingStarted() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003689 runPostCollapseRunnables();
Jorim Jaggi90129582014-06-02 14:44:49 +02003690 }
3691
Selim Cinekdbbcfbe2014-10-24 17:52:35 +02003692 public void onClosingFinished() {
3693 runPostCollapseRunnables();
3694 }
3695
Jorim Jaggi90129582014-06-02 14:44:49 +02003696 public void onUnlockHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003697 mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
Jorim Jaggi90129582014-06-02 14:44:49 +02003698 }
3699
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003700 public void onHintFinished() {
Jorim Jaggi93a2bb22014-06-02 19:57:28 +02003701 // Delay the reset a bit so the user can read the text.
Adrian Roos12c1ef52014-06-04 13:54:08 +02003702 mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003703 }
3704
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003705 public void onCameraHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003706 mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003707 }
3708
Selim Cineke70d6532015-04-24 16:46:13 -07003709 public void onVoiceAssistHintStarted() {
3710 mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
3711 }
3712
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003713 public void onPhoneHintStarted() {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003714 mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02003715 }
3716
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003717 public void onTrackingStopped(boolean expand) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003718 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cineke8bae622015-07-15 13:24:06 -07003719 if (!expand && !mUnlockMethodCache.canSkipBouncer()) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02003720 showBouncer();
3721 }
3722 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003723 }
3724
3725 @Override
Jorim Jaggid4a57442014-04-10 02:45:55 +02003726 protected int getMaxKeyguardNotifications() {
3727 return mKeyguardMaxNotificationCount;
3728 }
3729
Jorim Jaggia6310292014-04-16 14:11:52 +02003730 public NavigationBarView getNavigationBarView() {
3731 return mNavigationBarView;
3732 }
3733
Jorim Jaggiecbab362014-04-23 16:13:15 +02003734 // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
3735
3736 @Override
Christoph Studerb0183992014-12-22 21:02:26 +01003737 public boolean onDraggedDown(View startingChild, int dragLengthY) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02003738 if (hasActiveNotifications()) {
Christoph Studerb0183992014-12-22 21:02:26 +01003739 EventLogTags.writeSysuiLockscreenGesture(
3740 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
3741 (int) (dragLengthY / mDisplayMetrics.density),
3742 0 /* velocityDp - N/A */);
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003743
3744 // We have notifications, go to locked shade.
3745 goToLockedShade(startingChild);
3746 return true;
3747 } else {
3748
3749 // No notifications - abort gesture.
3750 return false;
3751 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003752 }
3753
3754 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003755 public void onDragDownReset() {
3756 mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003757 }
3758
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003759 @Override
Jorim Jaggiecbab362014-04-23 16:13:15 +02003760 public void onThresholdReached() {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003761 mStackScroller.setDimmed(false /* dimmed */, true /* animate */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003762 }
3763
Selim Cinek1408eb52014-06-02 14:45:38 +02003764 @Override
3765 public void onTouchSlopExceeded() {
3766 mStackScroller.removeLongPressCallback();
3767 }
3768
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003769 @Override
3770 public void setEmptyDragAmount(float amount) {
3771 mNotificationPanel.setEmptyDragAmount(amount);
3772 }
3773
Jorim Jaggiecbab362014-04-23 16:13:15 +02003774 /**
3775 * If secure with redaction: Show bouncer, go to unlocked shade.
3776 *
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003777 * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
Jorim Jaggiecbab362014-04-23 16:13:15 +02003778 *
3779 * @param expandView The view to expand after going to the shade.
3780 */
3781 public void goToLockedShade(View expandView) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003782 ExpandableNotificationRow row = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003783 if (expandView instanceof ExpandableNotificationRow) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003784 row = (ExpandableNotificationRow) expandView;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003785 row.setUserExpanded(true);
3786 }
Adrian Roosaee70462014-09-03 16:27:39 +02003787 boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
3788 || !mShowLockscreenNotifications;
3789 if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003790 mLeaveOpenOnKeyguardHide = true;
3791 showBouncer();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003792 mDraggedDownRow = row;
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003793 } else {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003794 mNotificationPanel.animateToFullShade(0 /* delay */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003795 setBarState(StatusBarState.SHADE_LOCKED);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003796 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003797 if (row != null) {
3798 row.setUserLocked(false);
3799 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003800 }
3801 }
3802
Adrian Roos5a46cd32014-04-03 16:51:58 +02003803 /**
Jorim Jaggi6539a832014-06-03 23:33:09 +02003804 * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
3805 */
3806 public void goToKeyguard() {
3807 if (mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekd9acca52014-09-01 22:33:25 +02003808 mStackScroller.onGoToKeyguard();
Jorim Jaggi6539a832014-06-03 23:33:09 +02003809 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02003810 updateKeyguardState(false /* goingToFullShade */, true /* fromShadeLocked*/);
Jorim Jaggi6539a832014-06-03 23:33:09 +02003811 }
3812 }
3813
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003814 public long getKeyguardFadingAwayDelay() {
3815 return mKeyguardFadingAwayDelay;
3816 }
3817
3818 public long getKeyguardFadingAwayDuration() {
3819 return mKeyguardFadingAwayDuration;
3820 }
3821
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003822 @Override
3823 public void setBouncerShowing(boolean bouncerShowing) {
3824 super.setBouncerShowing(bouncerShowing);
Adrian Roosd0b2f7d2015-04-29 13:36:12 -07003825 mStatusBarView.setBouncerShowing(bouncerShowing);
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01003826 disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003827 }
3828
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003829 public void onFinishedGoingToSleep() {
3830 mDeviceInteractive = false;
3831 mWakeUpComingFromTouch = false;
3832 mWakeUpTouchLocation = null;
Jorim Jaggi75c95042014-05-16 19:09:59 +02003833 mStackScroller.setAnimationsEnabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01003834 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02003835 }
3836
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003837 public void onStartedWakingUp() {
3838 mDeviceInteractive = true;
Jorim Jaggi75c95042014-05-16 19:09:59 +02003839 mStackScroller.setAnimationsEnabled(true);
Jorim Jaggid41083a2014-09-12 02:54:40 +02003840 mNotificationPanel.setTouchDisabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01003841 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02003842 }
John Spurlockd08f91f2014-05-23 11:00:34 -04003843
Jorim Jaggi93739112015-08-13 15:53:14 -07003844 public void onScreenTurningOn() {
3845 mNotificationPanel.onScreenTurningOn();
3846 }
3847
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003848 public void onScreenTurnedOn() {
3849 mDozeScrimController.onScreenTurnedOn();
3850 }
3851
Jason Monk815e0572014-08-12 17:26:36 -04003852 /**
3853 * This handles long-press of both back and recents. They are
3854 * handled together to capture them both being long-pressed
3855 * at the same time to exit screen pinning (lock task).
3856 *
3857 * When accessibility mode is on, only a long-press from recents
3858 * is required to exit.
3859 *
3860 * In all other circumstances we try to pass through long-press events
3861 * for Back, so that apps can still use it. Which can be from two things.
3862 * 1) Not currently in screen pinning (lock task).
3863 * 2) Back is long-pressed without recents.
3864 */
3865 private void handleLongPressBackRecents(View v) {
Jason Monk62515be2014-05-21 16:06:19 -04003866 try {
Jason Monk815e0572014-08-12 17:26:36 -04003867 boolean sendBackLongPress = false;
Jason Monk62515be2014-05-21 16:06:19 -04003868 IActivityManager activityManager = ActivityManagerNative.getDefault();
Jason Monk815e0572014-08-12 17:26:36 -04003869 boolean isAccessiblityEnabled = mAccessibilityManager.isEnabled();
3870 if (activityManager.isInLockTaskMode() && !isAccessiblityEnabled) {
3871 long time = System.currentTimeMillis();
3872 // If we recently long-pressed the other button then they were
3873 // long-pressed 'together'
3874 if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) {
3875 activityManager.stopLockTaskModeOnCurrent();
Jason Monk17488b92014-11-06 11:26:14 -05003876 // When exiting refresh disabled flags.
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01003877 mNavigationBarView.setDisabledFlags(mDisabled1, true);
Jason Monk815e0572014-08-12 17:26:36 -04003878 } else if ((v.getId() == R.id.back)
3879 && !mNavigationBarView.getRecentsButton().isPressed()) {
3880 // If we aren't pressing recents right now then they presses
3881 // won't be together, so send the standard long-press action.
3882 sendBackLongPress = true;
3883 }
3884 mLastLockToAppLongPress = time;
3885 } else {
3886 // If this is back still need to handle sending the long-press event.
3887 if (v.getId() == R.id.back) {
3888 sendBackLongPress = true;
3889 } else if (isAccessiblityEnabled && activityManager.isInLockTaskMode()) {
3890 // When in accessibility mode a long press that is recents (not back)
3891 // should stop lock task.
3892 activityManager.stopLockTaskModeOnCurrent();
Jason Monk17488b92014-11-06 11:26:14 -05003893 // When exiting refresh disabled flags.
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01003894 mNavigationBarView.setDisabledFlags(mDisabled1, true);
Jason Monk815e0572014-08-12 17:26:36 -04003895 }
3896 }
3897 if (sendBackLongPress) {
3898 KeyButtonView keyButtonView = (KeyButtonView) v;
3899 keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
3900 keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
Jason Monk62515be2014-05-21 16:06:19 -04003901 }
3902 } catch (RemoteException e) {
Jason Monk815e0572014-08-12 17:26:36 -04003903 Log.d(TAG, "Unable to reach activity manager", e);
Jason Monk62515be2014-05-21 16:06:19 -04003904 }
3905 }
3906
Winson Chungd42a6cf2014-06-03 16:24:04 -07003907 // Recents
3908
3909 @Override
3910 protected void showRecents(boolean triggeredFromAltTab) {
3911 // Set the recents visibility flag
3912 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
3913 notifyUiVisibilityChanged(mSystemUiVisibility);
3914 super.showRecents(triggeredFromAltTab);
3915 }
3916
3917 @Override
Winson Chungcdcd4872014-08-05 18:00:13 -07003918 protected void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
Winson Chungd42a6cf2014-06-03 16:24:04 -07003919 // Unset the recents visibility flag
3920 mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
3921 notifyUiVisibilityChanged(mSystemUiVisibility);
Winson Chungcdcd4872014-08-05 18:00:13 -07003922 super.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
Winson Chungd42a6cf2014-06-03 16:24:04 -07003923 }
3924
3925 @Override
3926 protected void toggleRecents() {
3927 // Toggle the recents visibility flag
3928 mSystemUiVisibility ^= View.RECENT_APPS_VISIBLE;
3929 notifyUiVisibilityChanged(mSystemUiVisibility);
3930 super.toggleRecents();
3931 }
Winson Chung9214eff2014-06-12 13:59:25 -07003932
3933 @Override
3934 public void onVisibilityChanged(boolean visible) {
3935 // Update the recents visibility flag
3936 if (visible) {
3937 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
3938 } else {
3939 mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
3940 }
3941 notifyUiVisibilityChanged(mSystemUiVisibility);
3942 }
John Spurlockbf370992014-06-17 13:58:31 -04003943
Jason Monk5565cb42014-09-12 10:59:21 -04003944 @Override
3945 public void showScreenPinningRequest() {
Jason Monk18f99d92014-09-11 13:36:42 -04003946 if (mKeyguardMonitor.isShowing()) {
3947 // Don't allow apps to trigger this from keyguard.
3948 return;
3949 }
3950 // Show screen pinning request, since this comes from an app, show 'no thanks', button.
3951 showScreenPinningRequest(true);
3952 }
3953
3954 public void showScreenPinningRequest(boolean allowCancel) {
3955 mScreenPinningRequest.showPrompt(allowCancel);
Jason Monk5565cb42014-09-12 10:59:21 -04003956 }
3957
Christoph Studerc8db24b2014-07-25 17:50:30 +02003958 public boolean hasActiveNotifications() {
3959 return !mNotificationData.getActiveNotifications().isEmpty();
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02003960 }
3961
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003962 public void wakeUpIfDozing(long time, MotionEvent event) {
Jorim Jaggi048af1f2014-11-11 22:51:10 +01003963 if (mDozing && mDozeScrimController.isPulsing()) {
John Spurlock8b12f222014-09-09 11:54:11 -04003964 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
Dianne Hackborn280a64e2015-07-13 14:48:08 -07003965 pm.wakeUp(time, "com.android.systemui:NODOZE");
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003966 mWakeUpComingFromTouch = true;
3967 mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01003968 mNotificationPanel.setTouchDisabled(false);
Jorim Jaggi0d210f62015-07-10 14:24:44 -07003969 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
John Spurlock8b12f222014-09-09 11:54:11 -04003970 }
3971 }
3972
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01003973 @Override
3974 public void appTransitionPending() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003975
3976 // Use own timings when Keyguard is going away, see keyguardGoingAway and
3977 // setKeyguardFadingAway
3978 if (!mKeyguardFadingAway) {
3979 mIconController.appTransitionPending();
3980 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01003981 }
3982
3983 @Override
3984 public void appTransitionCancelled() {
3985 mIconController.appTransitionCancelled();
3986 }
3987
3988 @Override
3989 public void appTransitionStarting(long startTime, long duration) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003990
3991 // Use own timings when Keyguard is going away, see keyguardGoingAway and
3992 // setKeyguardFadingAway
3993 if (!mKeyguardFadingAway) {
3994 mIconController.appTransitionStarting(startTime, duration);
3995 }
Kenny Guy3094d4a2015-04-01 19:14:10 +01003996 if (mIconPolicy != null) {
3997 mIconPolicy.appTransitionStarting(startTime, duration);
3998 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01003999 }
4000
Jorim Jaggi83969702015-06-05 14:59:24 -07004001 private void updateDozing() {
4002 mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD;
4003 updateDozingState();
4004 }
4005
John Spurlockbf370992014-06-17 13:58:31 -04004006 private final class ShadeUpdates {
4007 private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
4008 private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
4009
4010 public void check() {
4011 mNewVisibleNotifications.clear();
Christoph Studerc8db24b2014-07-25 17:50:30 +02004012 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
4013 for (int i = 0; i < activeNotifications.size(); i++) {
4014 final Entry entry = activeNotifications.get(i);
John Spurlockbf370992014-06-17 13:58:31 -04004015 final boolean visible = entry.row != null
4016 && entry.row.getVisibility() == View.VISIBLE;
4017 if (visible) {
4018 mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
4019 }
4020 }
4021 final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
4022 mVisibleNotifications.clear();
Dianne Hackborn497175b2014-07-01 12:56:08 -07004023 mVisibleNotifications.addAll(mNewVisibleNotifications);
John Spurlockbf370992014-06-17 13:58:31 -04004024
4025 // We have new notifications
4026 if (updates && mDozeServiceHost != null) {
4027 mDozeServiceHost.fireNewNotifications();
4028 }
4029 }
4030 }
4031
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004032 private final class DozeServiceHost extends KeyguardUpdateMonitorCallback implements DozeHost {
John Spurlockbf370992014-06-17 13:58:31 -04004033 // Amount of time to allow to update the time shown on the screen before releasing
4034 // the wakelock. This timeout is design to compensate for the fact that we don't
4035 // currently have a way to know when time display contents have actually been
4036 // refreshed once we've finished rendering a new frame.
4037 private static final long PROCESSING_TIME = 500;
4038
4039 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
4040 private final H mHandler = new H();
4041
Christoph Studer1f32c652014-11-26 15:32:20 +01004042 // Keeps the last reported state by fireNotificationLight.
4043 private boolean mNotificationLightOn;
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004044 private boolean mWakeAndUnlocking;
Christoph Studer1f32c652014-11-26 15:32:20 +01004045
John Spurlockc6eed842014-08-25 12:19:41 -04004046 @Override
4047 public String toString() {
Jeff Brown4d69e222014-09-18 15:27:50 -07004048 return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
John Spurlock8b12f222014-09-09 11:54:11 -04004049 }
4050
John Spurlockd96179e2014-08-21 16:43:45 -04004051 public void firePowerSaveChanged(boolean active) {
4052 for (Callback callback : mCallbacks) {
4053 callback.onPowerSaveChanged(active);
4054 }
4055 }
4056
John Spurlockcad57682014-07-26 17:09:56 -04004057 public void fireBuzzBeepBlinked() {
4058 for (Callback callback : mCallbacks) {
4059 callback.onBuzzBeepBlinked();
4060 }
4061 }
4062
John Spurlockcb566aa2014-08-03 22:58:28 -04004063 public void fireNotificationLight(boolean on) {
Christoph Studer1f32c652014-11-26 15:32:20 +01004064 mNotificationLightOn = on;
John Spurlockcb566aa2014-08-03 22:58:28 -04004065 for (Callback callback : mCallbacks) {
4066 callback.onNotificationLight(on);
4067 }
4068 }
4069
John Spurlockbf370992014-06-17 13:58:31 -04004070 public void fireNewNotifications() {
4071 for (Callback callback : mCallbacks) {
4072 callback.onNewNotifications();
4073 }
4074 }
4075
4076 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004077 public void addCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04004078 mCallbacks.add(callback);
4079 }
4080
4081 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004082 public void removeCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04004083 mCallbacks.remove(callback);
4084 }
4085
4086 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004087 public void startDozing(@NonNull Runnable ready) {
4088 mHandler.obtainMessage(H.MSG_START_DOZING, ready).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004089 }
4090
4091 @Override
John Spurlockeab28e62014-11-29 11:33:49 -05004092 public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
4093 mHandler.obtainMessage(H.MSG_PULSE_WHILE_DOZING, reason, 0, callback).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004094 }
4095
4096 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004097 public void stopDozing() {
4098 mHandler.obtainMessage(H.MSG_STOP_DOZING).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004099 }
4100
John Spurlockd96179e2014-08-21 16:43:45 -04004101 @Override
4102 public boolean isPowerSaveActive() {
4103 return mBatteryController != null && mBatteryController.isPowerSave();
4104 }
4105
Christoph Studer1f32c652014-11-26 15:32:20 +01004106 @Override
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004107 public boolean isPulsingBlocked() {
4108 return mWakeAndUnlocking;
4109 }
4110
4111 @Override
4112 public void onFingerprintWakeAndUnlockingStarted() {
4113 mWakeAndUnlocking = true;
4114 mDozeScrimController.abortPulsing();
4115 }
4116
4117 @Override
4118 public void onFingerprintWakeAndUnlockingFinished() {
4119 mWakeAndUnlocking = false;
4120 }
4121
4122 @Override
Christoph Studer1f32c652014-11-26 15:32:20 +01004123 public boolean isNotificationLightOn() {
4124 return mNotificationLightOn;
4125 }
4126
Jeff Brown4d69e222014-09-18 15:27:50 -07004127 private void handleStartDozing(@NonNull Runnable ready) {
Jorim Jaggi83969702015-06-05 14:59:24 -07004128 if (!mDozingRequested) {
4129 mDozingRequested = true;
John Spurlock813552c2014-09-19 08:30:21 -04004130 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07004131 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04004132 }
Jeff Brown4d69e222014-09-18 15:27:50 -07004133 ready.run();
John Spurlockbf370992014-06-17 13:58:31 -04004134 }
4135
John Spurlockeab28e62014-11-29 11:33:49 -05004136 private void handlePulseWhileDozing(@NonNull PulseCallback callback, int reason) {
4137 mDozeScrimController.pulse(callback, reason);
John Spurlockbf370992014-06-17 13:58:31 -04004138 }
4139
Jeff Brown4d69e222014-09-18 15:27:50 -07004140 private void handleStopDozing() {
Jorim Jaggi83969702015-06-05 14:59:24 -07004141 if (mDozingRequested) {
4142 mDozingRequested = false;
John Spurlock813552c2014-09-19 08:30:21 -04004143 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07004144 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04004145 }
4146 }
4147
4148 private final class H extends Handler {
Jeff Brown4d69e222014-09-18 15:27:50 -07004149 private static final int MSG_START_DOZING = 1;
4150 private static final int MSG_PULSE_WHILE_DOZING = 2;
4151 private static final int MSG_STOP_DOZING = 3;
John Spurlockbf370992014-06-17 13:58:31 -04004152
4153 @Override
4154 public void handleMessage(Message msg) {
Jeff Brown4d69e222014-09-18 15:27:50 -07004155 switch (msg.what) {
4156 case MSG_START_DOZING:
4157 handleStartDozing((Runnable) msg.obj);
4158 break;
4159 case MSG_PULSE_WHILE_DOZING:
John Spurlockeab28e62014-11-29 11:33:49 -05004160 handlePulseWhileDozing((PulseCallback) msg.obj, msg.arg1);
Jeff Brown4d69e222014-09-18 15:27:50 -07004161 break;
4162 case MSG_STOP_DOZING:
4163 handleStopDozing();
4164 break;
John Spurlockbf370992014-06-17 13:58:31 -04004165 }
4166 }
4167 }
4168 }
Romain Guy648342f2012-05-25 10:44:45 -07004169}