blob: e73994443491eee6b2e13015de193ba0eec25814 [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;
Jason Monk7e53f202016-01-28 10:40:20 -050031import android.content.ComponentName;
Joe Onorato808182d2010-07-09 18:52:06 -040032import android.content.Context;
33import android.content.Intent;
34import android.content.IntentFilter;
Adrian Roos21d2a252015-06-01 13:59:59 -070035import android.content.pm.IPackageManager;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -070036import android.content.pm.PackageManager;
Daniel Sandler777dcde2013-09-30 10:21:45 -040037import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070038import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040039import android.database.ContentObserver;
Dan Sandler16128f42014-05-21 12:48:22 -040040import android.graphics.Bitmap;
Romain Guy648342f2012-05-25 10:44:45 -070041import android.graphics.Canvas;
42import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040043import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040044import android.graphics.Point;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +010045import android.graphics.PointF;
Romain Guy648342f2012-05-25 10:44:45 -070046import android.graphics.PorterDuff;
Selim Cineka0fad3b2014-09-19 17:20:05 +020047import android.graphics.PorterDuffXfermode;
Joe Onorato808182d2010-07-09 18:52:06 -040048import android.graphics.Rect;
Dan Sandler16128f42014-05-21 12:48:22 -040049import android.graphics.drawable.ColorDrawable;
Romain Guy648342f2012-05-25 10:44:45 -070050import android.graphics.drawable.Drawable;
Jorim Jaggi11cc01d2016-01-22 19:39:23 -080051import android.hardware.display.DisplayManager;
Michael Jurka7f2668c2012-03-27 07:49:52 -070052import android.inputmethodservice.InputMethodService;
John Spurlock7b414672014-07-18 13:02:39 -040053import android.media.AudioAttributes;
Dan Sandler16128f42014-05-21 12:48:22 -040054import android.media.MediaMetadata;
55import android.media.session.MediaController;
56import android.media.session.MediaSession;
57import android.media.session.MediaSessionManager;
58import android.media.session.PlaybackState;
Selim Cinekbaa23272014-07-08 18:01:07 +020059import android.os.AsyncTask;
John Spurlock3c875662013-08-31 15:07:25 -040060import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040061import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050062import android.os.HandlerThread;
Joe Onorato808182d2010-07-09 18:52:06 -040063import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040064import android.os.Message;
John Spurlock56d007b2013-10-28 18:40:56 -040065import android.os.PowerManager;
Jason Monk4ae97d32014-12-17 10:14:33 -050066import android.os.Process;
Michael Jurka7f2668c2012-03-27 07:49:52 -070067import android.os.RemoteException;
Adrian Roos21d2a252015-06-01 13:59:59 -070068import android.os.ServiceManager;
Joe Onorato808182d2010-07-09 18:52:06 -040069import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070070import android.os.UserHandle;
Adrian Roos2b154a92014-11-17 15:18:39 +010071import android.os.UserManager;
Selim Cinek69ff8af2015-08-25 19:03:48 -070072import android.os.Vibrator;
Daniel Sandlerd3090562011-08-09 00:28:44 -040073import android.provider.Settings;
Chris Wren3ad4e3a2014-09-02 17:23:51 -040074import android.service.notification.NotificationListenerService;
Christoph Studerd0694b62014-06-04 16:36:01 +020075import android.service.notification.NotificationListenerService.RankingMap;
John Spurlockde84f0e2013-06-12 12:41:00 -040076import android.service.notification.StatusBarNotification;
Christoph Studer92b389d2014-04-01 18:44:40 +020077import android.util.ArraySet;
Daniel Sandler36412a72011-08-04 09:35:13 -040078import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -050079import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -040080import android.util.Log;
81import android.view.Display;
Jorim Jaggidf993512014-05-13 23:06:35 +020082import android.view.KeyEvent;
Jorim Jaggid4a57442014-04-10 02:45:55 +020083import android.view.LayoutInflater;
Joe Onorato808182d2010-07-09 18:52:06 -040084import android.view.MotionEvent;
Chris Craik2507c342015-05-04 14:36:49 -070085import android.view.ThreadedRenderer;
Joe Onorato808182d2010-07-09 18:52:06 -040086import android.view.View;
Xiyuan Xia1b30f792016-01-06 08:50:30 -080087import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -070088import android.view.ViewGroup.LayoutParams;
Dan Sandler44c0dfd2014-06-09 11:26:16 -040089import android.view.ViewStub;
Joe Onorato808182d2010-07-09 18:52:06 -040090import android.view.WindowManager;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020091import android.view.WindowManagerGlobal;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040092import android.view.animation.AccelerateInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020093import android.view.animation.Interpolator;
Dan Sandler16128f42014-05-21 12:48:22 -040094import android.widget.ImageView;
Joe Onorato808182d2010-07-09 18:52:06 -040095import android.widget.TextView;
Chris Wren9763d422015-04-30 15:24:05 -040096import com.android.internal.logging.MetricsLogger;
Chris Wrenf6e9228b2016-01-26 18:04:35 -050097import com.android.internal.logging.MetricsProto.MetricsEvent;
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;
Jason Monk46dbfb42016-02-25 14:59:20 -0500106import com.android.systemui.DensityContainer;
107import com.android.systemui.DensityContainer.InflateListener;
Christoph Studerb0183992014-12-22 21:02:26 +0100108import com.android.systemui.EventLogConstants;
Chris Wren64161cc2012-12-17 16:49:30 -0500109import com.android.systemui.EventLogTags;
Winsonc0d70582016-01-29 10:24:39 -0800110import com.android.systemui.Interpolators;
Andrew Flynn82862572015-04-01 14:22:37 -0400111import com.android.systemui.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -0400112import com.android.systemui.R;
Xiaohui Chen5da71352016-02-22 10:04:41 -0800113import com.android.systemui.SystemUIFactory;
Selim Cineke70d6532015-04-24 16:46:13 -0700114import com.android.systemui.assist.AssistManager;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800115import com.android.systemui.classifier.FalsingManager;
Jeff Brown4d69e222014-09-18 15:27:50 -0700116import com.android.systemui.doze.DozeHost;
John Spurlock813552c2014-09-19 08:30:21 -0400117import com.android.systemui.doze.DozeLog;
Jorim Jaggicff0acb2014-03-31 16:35:15 +0200118import com.android.systemui.keyguard.KeyguardViewMediator;
Jason Monk162011e2016-02-19 08:11:55 -0500119import com.android.systemui.qs.QSContainer;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400120import com.android.systemui.qs.QSPanel;
Jorim Jaggid61f2272014-12-19 20:35:35 +0100121import com.android.systemui.recents.ScreenPinningRequest;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800122import com.android.systemui.recents.events.EventBus;
123import com.android.systemui.recents.events.activity.UndockingTaskEvent;
Jorim Jaggidd98d412015-11-18 15:57:38 -0800124import com.android.systemui.stackdivider.Divider;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800125import com.android.systemui.stackdivider.WindowManagerProxy;
Selim Cineka32ab602014-06-11 15:06:01 +0200126import com.android.systemui.statusbar.ActivatableNotificationView;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200127import com.android.systemui.statusbar.BackDropView;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500128import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700129import com.android.systemui.statusbar.CommandQueue;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400130import com.android.systemui.statusbar.DismissView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200131import com.android.systemui.statusbar.DragDownHelper;
Jorim Jaggia2052ea2014-08-05 16:22:30 +0200132import com.android.systemui.statusbar.EmptyShadeView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200133import com.android.systemui.statusbar.ExpandableNotificationRow;
Daniel Sandler33805342012-07-23 15:45:12 -0400134import com.android.systemui.statusbar.GestureRecorder;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200135import com.android.systemui.statusbar.KeyguardIndicationController;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700136import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -0400137import com.android.systemui.statusbar.NotificationData.Entry;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200138import com.android.systemui.statusbar.NotificationOverflowContainer;
Adrian Roos1c0ca502015-10-07 12:20:42 -0700139import com.android.systemui.statusbar.RemoteInputController;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200140import com.android.systemui.statusbar.ScrimView;
Christian Robertson2e347422011-08-11 14:01:04 -0700141import com.android.systemui.statusbar.SignalClusterView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200142import com.android.systemui.statusbar.StatusBarState;
Christoph Studer2231c6e2014-12-19 12:40:13 +0100143import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200144import com.android.systemui.statusbar.policy.AccessibilityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400145import com.android.systemui.statusbar.policy.BatteryController;
John Spurlock0ff62e02014-07-22 16:15:08 -0400146import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400147import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200148import com.android.systemui.statusbar.policy.BrightnessMirrorController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400149import com.android.systemui.statusbar.policy.CastControllerImpl;
Adrian Roosb83777b2014-06-30 15:11:53 +0200150import com.android.systemui.statusbar.policy.FlashlightController;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700151import com.android.systemui.statusbar.policy.HeadsUpManager;
Jason Monk3d5f5512014-07-25 11:17:28 -0400152import com.android.systemui.statusbar.policy.HotspotControllerImpl;
John Spurlock657c62c2014-07-22 12:18:09 -0400153import com.android.systemui.statusbar.policy.KeyguardMonitor;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700154import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400155import com.android.systemui.statusbar.policy.LocationControllerImpl;
156import com.android.systemui.statusbar.policy.NetworkControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400157import com.android.systemui.statusbar.policy.NextAlarmController;
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200158import com.android.systemui.statusbar.policy.PreviewInflater;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400159import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400160import com.android.systemui.statusbar.policy.SecurityControllerImpl;
161import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200162import com.android.systemui.statusbar.policy.UserSwitcherController;
John Spurlock86005342014-05-23 11:58:00 -0400163import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek67b22602014-03-10 15:40:16 +0100164import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Christoph Studer92b389d2014-04-01 18:44:40 +0200165import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
Jorim Jaggi37c11802015-08-18 20:27:54 -0700166import com.android.systemui.statusbar.stack.StackStateAnimator;
Selim Cinekb036ca42015-02-20 15:56:28 +0100167import com.android.systemui.statusbar.stack.StackViewState;
John Spurlock86005342014-05-23 11:58:00 -0400168import com.android.systemui.volume.VolumeComponent;
Selim Cinek67b22602014-03-10 15:40:16 +0100169
Daniel Sandler6a858c32012-03-12 14:38:58 -0400170import java.io.FileDescriptor;
171import java.io.PrintWriter;
172import java.util.ArrayList;
Christoph Studer92b389d2014-04-01 18:44:40 +0200173import java.util.Collection;
174import java.util.Collections;
Selim Cinekb5605e52015-02-20 18:21:41 +0100175import java.util.HashMap;
Dan Sandler16128f42014-05-21 12:48:22 -0400176import java.util.List;
John Spurlock7bbb9f62014-10-21 12:15:28 -0400177import java.util.Map;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700178
179import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
180import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
181import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
182import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
183import static android.app.StatusBarManager.windowStateToString;
184import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
185import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
186import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
187import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
188import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
189import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
190import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
Daniel Sandler6a858c32012-03-12 14:38:58 -0400191
Jorim Jaggiecbab362014-04-23 16:13:15 +0200192public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Selim Cinek8d490d42015-04-10 00:05:50 -0700193 DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
194 HeadsUpManager.OnHeadsUpChangedListener {
Joe Onoratofd52b182010-11-10 18:00:52 -0800195 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400196 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400197 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400198 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400199 public static final boolean DEBUG_GESTURES = false;
Dan Sandler16128f42014-05-21 12:48:22 -0400200 public static final boolean DEBUG_MEDIA = false;
201 public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400202
John Spurlock342cad72013-10-08 09:36:50 -0400203 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400204
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400205 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400206 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400207
Dan Sandler16128f42014-05-21 12:48:22 -0400208 public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
209
Adrian Roos8e3e8362015-07-16 19:42:22 -0700210 public static final String ACTION_FAKE_ARTWORK = "fake_artwork";
211
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400212 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400213 private static final int MSG_CLOSE_PANELS = 1001;
214 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Jorim Jaggi826730a2014-12-08 21:05:13 +0100215 private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
Winson Chungb1f74992014-08-08 12:53:09 -0700216 // 1020-1040 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400217
Jorim Jaggi826730a2014-12-08 21:05:13 +0100218 // Time after we abort the launch transition.
219 private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
220
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400221 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
222
John Spurlocke1f366f2013-08-05 12:22:40 -0400223 private static final int STATUS_OR_NAV_TRANSIENT =
224 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400225 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400226
Christoph Studer92b389d2014-04-01 18:44:40 +0200227 /** The minimum delay in ms between reports of notification visibility. */
228 private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
229
Jorim Jaggi93a2bb22014-06-02 19:57:28 +0200230 /**
231 * The delay to reset the hint text when the hint animation is finished running.
232 */
233 private static final int HINT_RESET_DELAY_MS = 1200;
234
John Spurlock7b414672014-07-18 13:02:39 -0400235 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
236 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
237 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
238 .build();
239
Selim Cinekbaa23272014-07-08 18:01:07 +0200240 public static final int FADE_KEYGUARD_START_DELAY = 100;
241 public static final int FADE_KEYGUARD_DURATION = 300;
Jorim Jaggi90978852015-08-18 19:55:53 -0700242 public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
Selim Cinekbaa23272014-07-08 18:01:07 +0200243
Jason Monk815e0572014-08-12 17:26:36 -0400244 /** Allow some time inbetween the long press for back and recents. */
245 private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
246
Adrian Roos2f2bd9a2015-06-04 18:11:14 -0700247 /** If true, the system is in the half-boot-to-decryption-screen state.
248 * Prudently disable QS and notifications. */
Adrian Roos21d2a252015-06-01 13:59:59 -0700249 private static final boolean ONLY_CORE_APPS;
250
Adrian Roos52738322016-01-29 08:49:21 -0800251 /** If true, the lockscreen will show a distinct wallpaper */
Adrian Roose381c162016-02-11 15:26:42 -0800252 private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
Adrian Roos52738322016-01-29 08:49:21 -0800253
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700254 /* If true, the device supports freeform window management.
255 * This affects the status bar UI. */
256 private static final boolean FREEFORM_WINDOW_MANAGEMENT;
257
Adrian Roos21d2a252015-06-01 13:59:59 -0700258 static {
259 boolean onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700260 boolean freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700261 try {
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700262 IPackageManager packageManager =
263 IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
264 onlyCoreApps = packageManager.isOnlyCoreApps();
265 freeformWindowManagement = packageManager.hasSystemFeature(
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700266 PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT, 0);
Adrian Roos21d2a252015-06-01 13:59:59 -0700267 } catch (RemoteException e) {
268 onlyCoreApps = false;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700269 freeformWindowManagement = false;
Adrian Roos21d2a252015-06-01 13:59:59 -0700270 }
271 ONLY_CORE_APPS = onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700272 FREEFORM_WINDOW_MANAGEMENT = freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700273 }
274
Joe Onoratofd52b182010-11-10 18:00:52 -0800275 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400276
Daniel Sandler2b697352011-07-22 16:23:09 -0400277 // These are no longer handled by the policy, because we need custom strategies for them
John Spurlockaf8d6c42014-05-07 17:49:08 -0400278 BluetoothControllerImpl mBluetoothController;
Jason Monk3d5f5512014-07-25 11:17:28 -0400279 SecurityControllerImpl mSecurityController;
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -0800280 protected BatteryController mBatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400281 LocationControllerImpl mLocationController;
282 NetworkControllerImpl mNetworkController;
Jason Monk51e4dc02014-07-22 12:00:47 -0400283 HotspotControllerImpl mHotspotController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400284 RotationLockControllerImpl mRotationLockController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200285 UserInfoController mUserInfoController;
John Spurlock86005342014-05-23 11:58:00 -0400286 ZenModeController mZenModeController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400287 CastControllerImpl mCastController;
John Spurlock86005342014-05-23 11:58:00 -0400288 VolumeComponent mVolumeComponent;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700289 KeyguardUserSwitcher mKeyguardUserSwitcher;
Adrian Roosb83777b2014-06-30 15:11:53 +0200290 FlashlightController mFlashlightController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800291 protected UserSwitcherController mUserSwitcherController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200292 NextAlarmController mNextAlarmController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800293 protected KeyguardMonitor mKeyguardMonitor;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200294 BrightnessMirrorController mBrightnessMirrorController;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200295 AccessibilityController mAccessibilityController;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700296 FingerprintUnlockController mFingerprintUnlockController;
Jorim Jaggi86905582016-02-09 21:36:09 -0800297 LightStatusBarController mLightStatusBarController;
Vadim Tryshev12a30e82016-02-12 15:39:28 -0800298 protected LockscreenWallpaper mLockscreenWallpaper;
Jim Miller5e6af442011-12-02 18:24:26 -0800299
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400300 int mNaturalBarHeight = -1;
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100301
Joe Onorato808182d2010-07-09 18:52:06 -0400302 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400303 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400304
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800305 protected StatusBarWindowView mStatusBarWindow;
Joe Onoratofd52b182010-11-10 18:00:52 -0800306 PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400307 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800308 protected StatusBarWindowManager mStatusBarWindowManager;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200309 private UnlockMethodCache mUnlockMethodCache;
John Spurlockbf370992014-06-17 13:58:31 -0400310 private DozeServiceHost mDozeServiceHost;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -0700311 private boolean mWakeUpComingFromTouch;
312 private PointF mWakeUpTouchLocation;
Selim Cinek1b6f8192015-09-03 16:01:53 -0700313 private boolean mScreenTurningOn;
Daniel Sandlera310af82012-04-24 01:20:13 -0400314
Joe Onorato808182d2010-07-09 18:52:06 -0400315 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400316 Object mQueueLock = new Object();
317
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100318 StatusBarIconController mIconController;
Joe Onorato808182d2010-07-09 18:52:06 -0400319
320 // expanded notifications
Xiaohui Chenea4b6ba2016-02-18 10:53:17 -0800321 protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400322 View mExpandedContents;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400323 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400324
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400325 // settings
John Spurlockaf8d6c42014-05-07 17:49:08 -0400326 private QSPanel mQSPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400327
Joe Onorato808182d2010-07-09 18:52:06 -0400328 // top bar
Jason Monk0e1101d2015-10-07 13:06:09 -0400329 BaseStatusBarHeader mHeader;
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200330 KeyguardStatusBarView mKeyguardStatusBar;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200331 View mKeyguardStatusView;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200332 KeyguardBottomAreaView mKeyguardBottomArea;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200333 boolean mLeaveOpenOnKeyguardHide;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200334 KeyguardIndicationController mKeyguardIndicationController;
Jorim Jaggie70d31f2014-04-24 22:08:30 +0200335
Adrian Roos46df1ca2015-09-11 12:38:43 -0700336 // Keyguard is going away soon.
337 private boolean mKeyguardGoingAway;
338 // Keyguard is actually fading away now.
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700339 private boolean mKeyguardFadingAway;
340 private long mKeyguardFadingAwayDelay;
341 private long mKeyguardFadingAwayDuration;
342
Adrian Roos3aec6382016-02-05 14:19:01 -0800343 // RemoteInputView to be activated after unlock
344 private View mPendingRemoteInputView;
345
Selim Cinek5f71bee2015-11-18 10:25:23 -0800346 int mMaxAllowedKeyguardNotifications;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400347
Joe Onorato808182d2010-07-09 18:52:06 -0400348 boolean mExpandedVisible;
349
John Spurlockd4e65752013-08-28 14:17:09 -0400350 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400351
Joe Onorato808182d2010-07-09 18:52:06 -0400352 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400353 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400354
Joe Onorato808182d2010-07-09 18:52:06 -0400355 // Tracking finger for opening/closing.
Joe Onorato808182d2010-07-09 18:52:06 -0400356 boolean mTracking;
Joe Onorato808182d2010-07-09 18:52:06 -0400357
Joe Onorato808182d2010-07-09 18:52:06 -0400358 int[] mAbsPos = new int[2];
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200359 ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
Chet Haase2f2022a2011-10-11 06:41:59 -0700360
Joe Onorato808182d2010-07-09 18:52:06 -0400361 // for disabling the status bar
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100362 int mDisabled1 = 0;
363 int mDisabled2 = 0;
Joe Onorato808182d2010-07-09 18:52:06 -0400364
Daniel Sandler60ee2562011-07-22 12:34:33 -0400365 // tracking calls to View.setSystemUiVisibility()
366 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
Jorim Jaggi86905582016-02-09 21:36:09 -0800367 private final Rect mLastFullscreenStackBounds = new Rect();
368 private final Rect mLastDockedStackBounds = new Rect();
Daniel Sandler60ee2562011-07-22 12:34:33 -0400369
Adrian Roos389beec2015-05-12 13:33:25 -0700370 // last value sent to window manager
371 private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
372
Daniel Sandler36412a72011-08-04 09:35:13 -0400373 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700374
Daniel Sandler33805342012-07-23 15:45:12 -0400375 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400376 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400377 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400378 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400379
Jason Monk18f99d92014-09-11 13:36:42 -0400380 private ScreenPinningRequest mScreenPinningRequest;
381
Daniel Sandler328310c2011-09-23 15:56:52 -0400382 private int mNavigationIconHints = 0;
Jason Monk4ae97d32014-12-17 10:14:33 -0500383 private HandlerThread mHandlerThread;
Daniel Sandler328310c2011-09-23 15:56:52 -0400384
John Spurlock919adac2012-10-02 16:41:12 -0400385 // ensure quick settings is disabled until the current user makes it through the setup wizard
386 private boolean mUserSetup = false;
387 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
388 @Override
389 public void onChange(boolean selfChange) {
390 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
391 mContext.getContentResolver(),
392 Settings.Secure.USER_SETUP_COMPLETE,
393 0 /*default */,
394 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400395 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400396 "selfChange=%s userSetup=%s mUserSetup=%s",
397 selfChange, userSetup, mUserSetup));
John Spurlock73203eb2014-04-15 16:14:46 -0400398
John Spurlock919adac2012-10-02 16:41:12 -0400399 if (userSetup != mUserSetup) {
400 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400401 if (!mUserSetup && mStatusBarView != null)
402 animateCollapseQuickSettings();
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700403 if (mKeyguardBottomArea != null) {
404 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
405 }
John Spurlock919adac2012-10-02 16:41:12 -0400406 }
John Spurlock604a5ee2015-06-01 12:27:22 -0400407 if (mIconPolicy != null) {
408 mIconPolicy.setCurrentUserSetup(mUserSetup);
409 }
John Spurlock919adac2012-10-02 16:41:12 -0400410 }
411 };
412
Chris Wrenf6e83f42013-09-11 14:02:59 -0400413 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
414 @Override
415 public void onChange(boolean selfChange) {
416 boolean wasUsing = mUseHeadsUp;
Jason Monkf7019542014-07-31 12:42:25 -0400417 mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
418 && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
Chris Wren10d82df2014-03-01 10:34:51 -0500419 mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Chris Wren7bd241232014-02-28 16:25:05 -0500420 Settings.Global.HEADS_UP_OFF);
Chris Wren22ae46e2014-02-26 18:08:09 -0500421 mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
422 mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400423 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
424 if (wasUsing != mUseHeadsUp) {
425 if (!mUseHeadsUp) {
426 Log.d(TAG, "dismissing any existing heads up notification on disable event");
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700427 mHeadsUpManager.releaseAllImmediately();
Chris Wrenf6e83f42013-09-11 14:02:59 -0400428 }
429 }
430 }
431 };
432
John Spurlockcfc359a2013-09-05 10:42:03 -0400433 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400434 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400435 private int mStatusBarMode;
436 private int mNavigationBarMode;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800437 private int mMaxKeyguardNotifications;
Jorim Jaggid41083a2014-09-12 02:54:40 +0200438
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200439 private ViewMediatorCallback mKeyguardViewMediatorCallback;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800440 protected ScrimController mScrimController;
441 protected DozeScrimController mDozeScrimController;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200442
John Spurlock32beb2c2013-03-11 10:16:47 -0400443 private final Runnable mAutohide = new Runnable() {
444 @Override
445 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400446 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400447 if (mSystemUiVisibility != requested) {
448 notifyUiVisibilityChanged(requested);
449 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400450 }};
451
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700452 private boolean mWaitingForKeyguardExit;
John Spurlockbf370992014-06-17 13:58:31 -0400453 private boolean mDozing;
Jorim Jaggi83969702015-06-05 14:59:24 -0700454 private boolean mDozingRequested;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800455 protected boolean mScrimSrcModeEnabled;
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100456
Selim Cinekc18010f2016-01-20 13:41:30 -0800457 public static final Interpolator ALPHA_IN = Interpolators.ALPHA_IN;
458 public static final Interpolator ALPHA_OUT = Interpolators.ALPHA_OUT;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200459
Selim Cineka0fad3b2014-09-19 17:20:05 +0200460 private BackDropView mBackdrop;
Dan Sandler16128f42014-05-21 12:48:22 -0400461 private ImageView mBackdropFront, mBackdropBack;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200462 private PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
463 private PorterDuffXfermode mSrcOverXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
Dan Sandler16128f42014-05-21 12:48:22 -0400464
465 private MediaSessionManager mMediaSessionManager;
466 private MediaController mMediaController;
467 private String mMediaNotificationKey;
468 private MediaMetadata mMediaMetadata;
469 private MediaController.Callback mMediaListener
470 = new MediaController.Callback() {
471 @Override
472 public void onPlaybackStateChanged(PlaybackState state) {
473 super.onPlaybackStateChanged(state);
474 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400475 if (state != null) {
476 if (!isPlaybackActive(state.getState())) {
477 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -0800478 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400479 }
480 }
Dan Sandler16128f42014-05-21 12:48:22 -0400481 }
482
483 @Override
484 public void onMetadataChanged(MediaMetadata metadata) {
485 super.onMetadataChanged(metadata);
486 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
487 mMediaMetadata = metadata;
Adrian Roos52738322016-01-29 08:49:21 -0800488 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -0400489 }
490 };
491
492 private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
493 new OnChildLocationsChangedListener() {
494 @Override
495 public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
496 userActivity();
497 }
498 };
499
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100500 private int mDisabledUnmodified1;
501 private int mDisabledUnmodified2;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200502
Christoph Studer92b389d2014-04-01 18:44:40 +0200503 /** Keys of notifications currently visible to the user. */
Chris Wrend1dbc922015-06-19 17:51:16 -0400504 private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications =
505 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200506 private long mLastVisibilityReportUptimeMs;
507
John Spurlockbf370992014-06-17 13:58:31 -0400508 private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
509
Selim Cinekbaa23272014-07-08 18:01:07 +0200510 private Runnable mLaunchTransitionEndRunnable;
511 private boolean mLaunchTransitionFadingAway;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +0200512 private ExpandableNotificationRow mDraggedDownRow;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700513 private boolean mLaunchCameraOnScreenTurningOn;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700514 private boolean mLaunchCameraOnFinishedGoingToSleep;
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700515 private int mLastCameraLaunchSource;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700516 private PowerManager.WakeLock mGestureWakeLock;
Selim Cinek69ff8af2015-08-25 19:03:48 -0700517 private Vibrator mVibrator;
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200518
Christoph Studer2231c6e2014-12-19 12:40:13 +0100519 // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
520 private int mLastLoggedStateFingerprint;
521
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700522 /**
523 * If set, the device has started going to sleep but isn't fully non-interactive yet.
524 */
525 protected boolean mStartedGoingToSleep;
526
Selim Cinek3776fe02016-02-04 13:32:43 -0800527 private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_HUN
Chris Wren35a7c922015-06-22 16:31:01 -0400528 | StackViewState.LOCATION_MAIN_AREA;
Christoph Studer92b389d2014-04-01 18:44:40 +0200529
530 private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
531 new OnChildLocationsChangedListener() {
532 @Override
533 public void onChildLocationsChanged(
534 NotificationStackScrollLayout stackScrollLayout) {
535 if (mHandler.hasCallbacks(mVisibilityReporter)) {
536 // Visibilities will be reported when the existing
537 // callback is executed.
538 return;
539 }
540 // Calculate when we're allowed to run the visibility
541 // reporter. Note that this timestamp might already have
542 // passed. That's OK, the callback will just be executed
543 // ASAP.
544 long nextReportUptimeMs =
545 mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
546 mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
547 }
548 };
549
550 // Tracks notifications currently visible in mNotificationStackScroller and
551 // emits visibility events via NoMan on changes.
552 private final Runnable mVisibilityReporter = new Runnable() {
Chris Wrend1dbc922015-06-19 17:51:16 -0400553 private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
554 new ArraySet<>();
555 private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
556 new ArraySet<>();
557 private final ArraySet<NotificationVisibility> mTmpNoLongerVisibleNotifications =
558 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200559
560 @Override
561 public void run() {
562 mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
Chris Wrend1dbc922015-06-19 17:51:16 -0400563 final String mediaKey = getCurrentMediaNotificationKey();
Christoph Studer92b389d2014-04-01 18:44:40 +0200564
565 // 1. Loop over mNotificationData entries:
566 // A. Keep list of visible notifications.
567 // B. Keep list of previously hidden, now visible notifications.
568 // 2. Compute no-longer visible notifications by removing currently
569 // visible notifications from the set of previously visible
570 // notifications.
571 // 3. Report newly visible and no-longer visible notifications.
572 // 4. Keep currently visible notifications for next report.
Christoph Studerc8db24b2014-07-25 17:50:30 +0200573 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
574 int N = activeNotifications.size();
Christoph Studer92b389d2014-04-01 18:44:40 +0200575 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +0200576 Entry entry = activeNotifications.get(i);
Christoph Studer92b389d2014-04-01 18:44:40 +0200577 String key = entry.notification.getKey();
Chris Wrend1dbc922015-06-19 17:51:16 -0400578 boolean isVisible =
Christoph Studer92b389d2014-04-01 18:44:40 +0200579 (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
Chris Wrend1dbc922015-06-19 17:51:16 -0400580 NotificationVisibility visObj = NotificationVisibility.obtain(key, i, isVisible);
581 boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(visObj);
582 if (isVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +0200583 // Build new set of visible notifications.
Chris Wrend1dbc922015-06-19 17:51:16 -0400584 mTmpCurrentlyVisibleNotifications.add(visObj);
585 if (!previouslyVisible) {
586 mTmpNewlyVisibleNotifications.add(visObj);
587 }
588 } else {
589 // release object
590 visObj.recycle();
Christoph Studer92b389d2014-04-01 18:44:40 +0200591 }
592 }
Chris Wrend1dbc922015-06-19 17:51:16 -0400593 mTmpNoLongerVisibleNotifications.addAll(mCurrentlyVisibleNotifications);
594 mTmpNoLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200595
596 logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -0400597 mTmpNewlyVisibleNotifications, mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200598
Chris Wrend1dbc922015-06-19 17:51:16 -0400599 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200600 mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
601
Chris Wrend1dbc922015-06-19 17:51:16 -0400602 recycleAllVisibilityObjects(mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200603 mTmpCurrentlyVisibleNotifications.clear();
Chris Wrend1dbc922015-06-19 17:51:16 -0400604 mTmpNewlyVisibleNotifications.clear();
605 mTmpNoLongerVisibleNotifications.clear();
Christoph Studer92b389d2014-04-01 18:44:40 +0200606 }
607 };
608
Chris Wrend1dbc922015-06-19 17:51:16 -0400609 private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
610 final int N = array.size();
611 for (int i = 0 ; i < N; i++) {
612 array.valueAt(i).recycle();
613 }
614 array.clear();
615 }
616
Jorim Jaggiecbab362014-04-23 16:13:15 +0200617 private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
618 @Override
619 public void onClick(View v) {
620 goToLockedShade(null);
621 }
622 };
Selim Cinekb5605e52015-02-20 18:21:41 +0100623 private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
624 = new HashMap<>();
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700625 private RankingMap mLatestRankingMap;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700626 private boolean mNoAnimationOnNextBarModeChange;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700627 private FalsingManager mFalsingManager;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200628
Joe Onorato808182d2010-07-09 18:52:06 -0400629 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400630 public void start() {
631 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
632 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400633 updateDisplaySize();
Jorim Jaggi0e664392014-09-27 01:30:22 +0200634 mScrimSrcModeEnabled = mContext.getResources().getBoolean(
635 R.bool.config_status_bar_scrim_behind_use_src);
Adrian Roos75fa3852015-01-27 20:21:44 +0100636
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500637 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400638
Dan Sandler16128f42014-05-21 12:48:22 -0400639 mMediaSessionManager
640 = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
641 // TODO: use MediaSessionManager.SessionListener to hook us up to future updates
642 // in session state
643
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400644 addNavigationBar();
645
Joe Onorato808182d2010-07-09 18:52:06 -0400646 // Lastly, call to the icon policy to install/update all the icons.
Jason Monk07473ce2016-01-05 14:59:19 -0500647 mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCastController,
Jason Monk3e189872016-01-12 09:10:34 -0500648 mHotspotController, mUserInfoController, mBluetoothController,
Jason Monkf23aa992016-01-22 16:45:21 -0500649 mRotationLockController, mNetworkController.getDataSaverController());
John Spurlock604a5ee2015-06-01 12:27:22 -0400650 mIconPolicy.setCurrentUserSetup(mUserSetup);
John Spurlocke677d712014-02-13 12:52:19 -0500651 mSettingsObserver.onChange(false); // set up
Chris Wrenf6e83f42013-09-11 14:02:59 -0400652
653 mHeadsUpObserver.onChange(true); // set up
654 if (ENABLE_HEADS_UP) {
655 mContext.getContentResolver().registerContentObserver(
Chris Wren10d82df2014-03-01 10:34:51 -0500656 Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
Chris Wrenf6e83f42013-09-11 14:02:59 -0400657 mHeadsUpObserver);
Chris Wren22ae46e2014-02-26 18:08:09 -0500658 mContext.getContentResolver().registerContentObserver(
659 Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
660 mHeadsUpObserver);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400661 }
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200662 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Christoph Studer2231c6e2014-12-19 12:40:13 +0100663 mUnlockMethodCache.addListener(this);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100664 startKeyguard();
John Spurlockbf370992014-06-17 13:58:31 -0400665
666 mDozeServiceHost = new DozeServiceHost();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700667 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mDozeServiceHost);
Jeff Brown4d69e222014-09-18 15:27:50 -0700668 putComponent(DozeHost.class, mDozeServiceHost);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200669 putComponent(PhoneStatusBar.class, this);
John Spurlock89f060a2014-07-16 21:03:15 -0400670
671 setControllerUsers();
Chris Wrencd8f4f72014-08-27 18:48:13 -0400672
673 notifyUserAboutHiddenNotifications();
Jason Monk18f99d92014-09-11 13:36:42 -0400674
675 mScreenPinningRequest = new ScreenPinningRequest(mContext);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700676 mFalsingManager = FalsingManager.getInstance(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400677 }
678
679 // ================================================================================
680 // Constructing the view
681 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700682 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400683 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400684
Daniel Sandler6e8db882011-10-26 15:40:51 -0400685 updateDisplaySize(); // populates mDisplayMetrics
Jorim Jaggi2e115c52014-07-01 21:27:58 +0200686 updateResources();
Joe Onorato808182d2010-07-09 18:52:06 -0400687
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800688 inflateStatusBarWindow(context);
Selim Cinek4e6b2d32015-06-25 20:15:33 -0400689 mStatusBarWindow.setService(this);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400690 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
691 @Override
692 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400693 checkUserAutohide(v, event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400694 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500695 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400696 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400697 }
698 }
Chris Wren5de6e942012-05-16 14:22:21 -0400699 return mStatusBarWindow.onTouchEvent(event);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700700 }
701 });
Daniel Sandler21b274e2012-05-02 15:07:51 -0400702
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100703 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
704 R.id.notification_panel);
Daniel Sandler040c2e42012-10-17 00:56:33 -0400705 mNotificationPanel.setStatusBar(this);
Joe Onorato808182d2010-07-09 18:52:06 -0400706
Xiaohui Chen9f967112016-01-07 14:14:06 -0800707 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
708 mStatusBarView.setBar(this);
709 mStatusBarView.setPanel(mNotificationPanel);
710
Jeff Brown98365d72012-08-19 20:30:52 -0700711 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700712 mStatusBarWindow.setBackground(null);
Alan Viverette4a357cd2015-03-18 18:37:18 -0700713 mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
Romain Guy648342f2012-05-25 10:44:45 -0700714 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700715 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700716
Selim Cinek83bc7832015-10-22 13:26:54 -0700717 mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700718 mHeadsUpManager.setBar(this);
719 mHeadsUpManager.addListener(this);
720 mHeadsUpManager.addListener(mNotificationPanel);
Selim Cinekef5127e2015-12-21 16:55:58 -0800721 mHeadsUpManager.addListener(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700722 mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
Selim Cinekfbe9a442015-04-13 16:09:49 -0700723 mNotificationData.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700724
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400725 if (MULTIUSER_DEBUG) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100726 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
727 R.id.header_debug_info);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400728 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
729 }
Joe Onorato808182d2010-07-09 18:52:06 -0400730
Daniel Sandler0129b312011-05-11 11:54:11 -0400731 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700732 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400733 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400734 if (showNav) {
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800735 createNavigationBarView(context);
Daniel Sandler0129b312011-05-11 11:54:11 -0400736 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400737 } catch (RemoteException ex) {
738 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400739 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400740
Selim Cineke70d6532015-04-24 16:46:13 -0700741 mAssistManager = new AssistManager(this, context);
742
Joe Onorato808182d2010-07-09 18:52:06 -0400743 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400744 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400745
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100746 mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
747 R.id.notification_stack_scroller);
748 mStackScroller.setLongPressListener(getNotificationLongClicker());
Mady Mellor4b80b102016-01-22 08:03:58 -0800749 mStackScroller.setGearDisplayedListener(getGearDisplayedListener());
Selim Cinek19c8c702014-08-25 22:09:19 +0200750 mStackScroller.setPhoneStatusBar(this);
Selim Cinekb5605e52015-02-20 18:21:41 +0100751 mStackScroller.setGroupManager(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700752 mStackScroller.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb5605e52015-02-20 18:21:41 +0100753 mGroupManager.setOnGroupChangeListener(mStackScroller);
Selim Cinek80a14e52014-03-27 16:58:04 +0100754
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200755 mKeyguardIconOverflowContainer =
756 (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
757 R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
758 mKeyguardIconOverflowContainer.setOnActivatedListener(this);
Jorim Jaggie96fcd12014-05-07 21:10:35 +0200759 mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
Selim Cinek2cd45df2015-06-09 18:00:07 -0700760 mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
Jorim Jaggid4a57442014-04-10 02:45:55 +0200761
Selim Cinek4fd5dfc2016-01-19 15:16:15 -0800762
Selim Cinek01af3342016-02-09 19:25:31 -0800763 inflateEmptyShadeView();
764 inflateDismissView();
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100765 mExpandedContents = mStackScroller;
Selim Cinek67b22602014-03-10 15:40:16 +0100766
Selim Cineka0fad3b2014-09-19 17:20:05 +0200767 mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
768 mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
769 mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
770
771 ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
772 ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
Selim Cinekaac93252015-04-14 20:04:12 -0700773 View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
Xiaohui Chen5da71352016-02-22 10:04:41 -0800774 mScrimController = SystemUIFactory.getInstance().createScrimController(
775 scrimBehind, scrimInFront, headsUpScrim, mScrimSrcModeEnabled);
Selim Cinekaac93252015-04-14 20:04:12 -0700776 mHeadsUpManager.addListener(mScrimController);
777 mStackScroller.setScrimController(mScrimController);
Selim Cineka0fad3b2014-09-19 17:20:05 +0200778 mScrimController.setBackDropView(mBackdrop);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200779 mStatusBarView.setScrimController(mScrimController);
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100780 mDozeScrimController = new DozeScrimController(mScrimController, context);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200781
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200782 mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200783 mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200784 mKeyguardBottomArea =
785 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
786 mKeyguardBottomArea.setActivityStarter(this);
Selim Cineke70d6532015-04-24 16:46:13 -0700787 mKeyguardBottomArea.setAssistManager(mAssistManager);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200788 mKeyguardIndicationController = new KeyguardIndicationController(mContext,
789 (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700790 R.id.keyguard_indication_text),
791 mKeyguardBottomArea.getLockIcon());
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200792 mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400793
Adrian Roose381c162016-02-11 15:26:42 -0800794 if (ENABLE_LOCKSCREEN_WALLPAPER) {
795 mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
796 }
797
Xiaohui Chenf43491f2016-02-01 12:19:35 -0800798 // set the initial view visibility
Joe Onorato808182d2010-07-09 18:52:06 -0400799 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400800
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100801 mIconController = new StatusBarIconController(
802 mContext, mStatusBarView, mKeyguardStatusBar, this);
803
Jason Monk4ae97d32014-12-17 10:14:33 -0500804 // Background thread for any controllers that need it.
805 mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
806 mHandlerThread.start();
807
Daniel Sandler2b697352011-07-22 16:23:09 -0400808 // Other icons
Jason Monk05b86bc2015-05-19 14:21:28 -0400809 mLocationController = new LocationControllerImpl(mContext,
810 mHandlerThread.getLooper()); // will post a notification
Daniel Sandler2b697352011-07-22 16:23:09 -0400811 mBatteryController = new BatteryController(mContext);
John Spurlock0ff62e02014-07-22 16:15:08 -0400812 mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
813 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500814 public void onPowerSaveChanged(boolean isPowerSave) {
John Spurlock0ff62e02014-07-22 16:15:08 -0400815 mHandler.post(mCheckBarModes);
John Spurlockd96179e2014-08-21 16:43:45 -0400816 if (mDozeServiceHost != null) {
Jason Monkc06fbb12016-01-08 14:12:18 -0500817 mDozeServiceHost.firePowerSaveChanged(isPowerSave);
John Spurlockd96179e2014-08-21 16:43:45 -0400818 }
John Spurlock0ff62e02014-07-22 16:15:08 -0400819 }
820 @Override
821 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
822 // noop
823 }
824 });
Jason Monk30d80042015-05-08 16:54:18 -0400825 mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk51e4dc02014-07-22 12:00:47 -0400826 mHotspotController = new HotspotControllerImpl(mContext);
Jason Monk4ae97d32014-12-17 10:14:33 -0500827 mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk3d5f5512014-07-25 11:17:28 -0400828 mSecurityController = new SecurityControllerImpl(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400829 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
830 mRotationLockController = new RotationLockControllerImpl(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500831 }
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200832 mUserInfoController = new UserInfoController(mContext);
John Spurlock86005342014-05-23 11:58:00 -0400833 mVolumeComponent = getComponent(VolumeComponent.class);
John Spurlockf2565a82014-10-23 20:16:22 -0400834 if (mVolumeComponent != null) {
835 mZenModeController = mVolumeComponent.getZenController();
836 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400837 mCastController = new CastControllerImpl(mContext);
Xiaohui Chen10942302015-12-16 16:38:13 -0800838
839 initSignalCluster(mStatusBarView);
840 initSignalCluster(mKeyguardStatusBar);
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400841
Adrian Roosb83777b2014-06-30 15:11:53 +0200842 mFlashlightController = new FlashlightController(mContext);
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200843 mKeyguardBottomArea.setFlashlightController(mFlashlightController);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200844 mKeyguardBottomArea.setPhoneStatusBar(this);
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700845 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200846 mAccessibilityController = new AccessibilityController(mContext);
847 mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200848 mNextAlarmController = new NextAlarmController(mContext);
Jorim Jaggi86905582016-02-09 21:36:09 -0800849 mLightStatusBarController = new LightStatusBarController(mIconController,
850 mBatteryController);
Jason Monk8a3a9642015-06-05 11:01:30 -0400851 mKeyguardMonitor = new KeyguardMonitor(mContext);
Fyodor Kupolovcd86ebf2015-09-29 17:06:50 -0700852 if (UserManager.get(mContext).isUserSwitcherEnabled()) {
Adrian Roos88b11932015-07-22 14:59:48 -0700853 mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
Sudheer Shanka1c7cda82015-12-31 14:46:02 +0000854 mHandler, this);
Rakesh Iyer2790a372016-01-22 15:33:39 -0800855 createUserSwitcher();
Adrian Roos2b154a92014-11-17 15:18:39 +0100856 }
Adrian Roos723632e2014-07-23 21:13:21 +0200857
John Spurlockaf8d6c42014-05-07 17:49:08 -0400858 // Set up the quick settings tile panel
Jason Monk46dbfb42016-02-25 14:59:20 -0500859 DensityContainer container = (DensityContainer) mStatusBarWindow.findViewById(
860 R.id.qs_density_container);
861 if (container != null) {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400862 final QSTileHost qsh = new QSTileHost(mContext, this,
863 mBluetoothController, mLocationController, mRotationLockController,
Jason Monk51e4dc02014-07-22 12:00:47 -0400864 mNetworkController, mZenModeController, mHotspotController,
John Spurlock657c62c2014-07-22 12:18:09 -0400865 mCastController, mFlashlightController,
Jason Monkabe19742015-09-29 09:47:06 -0400866 mUserSwitcherController, mUserInfoController, mKeyguardMonitor,
Jason Monk46dbfb42016-02-25 14:59:20 -0500867 mSecurityController, mBatteryController, mIconController,
868 mNextAlarmController);
Adrian Roos5fd872e2014-08-12 17:28:58 +0200869 mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
Jason Monk46dbfb42016-02-25 14:59:20 -0500870 container.addInflateListener(new InflateListener() {
John Spurlockbceed062014-08-10 18:04:16 -0400871 @Override
Jason Monk46dbfb42016-02-25 14:59:20 -0500872 public void onInflated(View v) {
873 QSContainer qsContainer = (QSContainer) v.findViewById(
874 R.id.quick_settings_container);
875 qsContainer.setHost(qsh);
876 mQSPanel = qsContainer.getQsPanel();
877 mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
878 mHeader = qsContainer.getHeader();
879 initSignalCluster(mHeader);
880 mHeader.setActivityStarter(PhoneStatusBar.this);
John Spurlockbceed062014-08-10 18:04:16 -0400881 }
882 });
Siva Velusamy537421b2012-09-14 14:45:02 -0700883 }
884
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200885 // User info. Trigger first load.
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200886 mKeyguardStatusBar.setUserInfoController(mUserInfoController);
Adrian Roosffc90972015-06-09 18:09:49 -0700887 mKeyguardStatusBar.setUserSwitcherController(mUserSwitcherController);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200888 mUserInfoController.reloadUserInfo();
889
Jorim Jaggi708f7722014-08-20 17:30:38 +0200890 ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
891 mBatteryController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200892 mKeyguardStatusBar.setBatteryController(mBatteryController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200893
John Spurlock56d007b2013-10-28 18:40:56 -0400894 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
895 mBroadcastReceiver.onReceive(mContext,
896 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
Selim Cinek372d1bd2015-08-14 13:19:37 -0700897 mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
898 "GestureWakeLock");
Selim Cinek69ff8af2015-08-25 19:03:48 -0700899 mVibrator = mContext.getSystemService(Vibrator.class);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700900
Joe Onorato808182d2010-07-09 18:52:06 -0400901 // receive broadcasts
902 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400903 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
904 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400905 filter.addAction(Intent.ACTION_SCREEN_ON);
Kenny Guy44fc65f2014-11-28 22:18:14 +0000906 context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400907
Adrian Roos8e3e8362015-07-16 19:42:22 -0700908 IntentFilter demoFilter = new IntentFilter();
909 if (DEBUG_MEDIA_FAKE_ARTWORK) {
910 demoFilter.addAction(ACTION_FAKE_ARTWORK);
911 }
912 demoFilter.addAction(ACTION_DEMO);
913 context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
914 android.Manifest.permission.DUMP, null);
915
John Spurlock919adac2012-10-02 16:41:12 -0400916 // listen for USER_SETUP_COMPLETE setting (per-user)
917 resetUserSetupObserver();
918
Chris Craik2507c342015-05-04 14:36:49 -0700919 // disable profiling bars, since they overlap and clutter the output on app windows
920 ThreadedRenderer.overrideProperty("disableProfileBars", "true");
921
922 // Private API call to make the shadows look better for Recents
923 ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
924
Daniel Sandlera310af82012-04-24 01:20:13 -0400925 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400926 }
927
Selim Cinek01af3342016-02-09 19:25:31 -0800928 @Override
929 protected void reInflateViews() {
930 super.reInflateViews();
931 inflateDismissView();
932 updateClearAll();
933 inflateEmptyShadeView();
934 updateEmptyShadeView();
935 }
936
937 private void inflateEmptyShadeView() {
938 mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
939 R.layout.status_bar_no_notifications, mStackScroller, false);
940 mStackScroller.setEmptyShadeView(mEmptyShadeView);
941 }
942
943 private void inflateDismissView() {
944 mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
945 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
946 mDismissView.setOnButtonClickListener(new View.OnClickListener() {
947 @Override
948 public void onClick(View v) {
949 MetricsLogger.action(mContext, MetricsEvent.ACTION_DISMISS_ALL_NOTES);
950 clearAllNotifications();
951 }
952 });
953 mStackScroller.setDismissView(mDismissView);
954 }
955
Rakesh Iyer2790a372016-01-22 15:33:39 -0800956 protected void createUserSwitcher() {
957 mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
958 (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
959 mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
960 }
961
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800962 protected void inflateStatusBarWindow(Context context) {
963 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
964 R.layout.super_status_bar, null);
965 }
966
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800967 protected void createNavigationBarView(Context context) {
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -0800968 inflateNavigationBarView(context);
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800969 mNavigationBarView.setDisabledFlags(mDisabled1);
970 mNavigationBarView.setComponents(mRecents, getComponent(Divider.class));
971 mNavigationBarView.setOnVerticalChangedListener(
972 new NavigationBarView.OnVerticalChangedListener() {
973 @Override
974 public void onVerticalChanged(boolean isVertical) {
975 if (mAssistManager != null) {
976 mAssistManager.onConfigurationChanged();
977 }
978 mNotificationPanel.setQsScrimEnabled(!isVertical);
979 }
980 });
981 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
982 @Override
983 public boolean onTouch(View v, MotionEvent event) {
984 checkUserAutohide(v, event);
985 return false;
986 }});
987 }
988
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -0800989 protected void inflateNavigationBarView(Context context) {
Jason Monk4f878ef2016-01-23 14:37:38 -0500990 mNavigationBarView = (NavigationBarView) View.inflate(
991 context, R.layout.navigation_bar, null);
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -0800992 }
993
994 protected void initSignalCluster(View containerView) {
Xiaohui Chen10942302015-12-16 16:38:13 -0800995 SignalClusterView signalCluster =
996 (SignalClusterView) containerView.findViewById(R.id.signal_cluster);
997 if (signalCluster != null) {
998 mNetworkController.addSignalCallback(signalCluster);
999 signalCluster.setSecurityController(mSecurityController);
1000 signalCluster.setNetworkController(mNetworkController);
1001 }
1002 }
1003
Dan Sandlereceda3d2014-07-21 15:35:01 -04001004 private void clearAllNotifications() {
1005
1006 // animate-swipe all dismissable notifications, then animate the shade closed
1007 int numChildren = mStackScroller.getChildCount();
1008
1009 final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
1010 for (int i = 0; i < numChildren; i++) {
1011 final View child = mStackScroller.getChildAt(i);
Selim Cinekb5605e52015-02-20 18:21:41 +01001012 if (child instanceof ExpandableNotificationRow) {
1013 if (mStackScroller.canChildBeDismissed(child)) {
1014 if (child.getVisibility() == View.VISIBLE) {
1015 viewsToHide.add(child);
1016 }
1017 }
1018 ExpandableNotificationRow row = (ExpandableNotificationRow) child;
1019 List<ExpandableNotificationRow> children = row.getNotificationChildren();
1020 if (row.areChildrenExpanded() && children != null) {
1021 for (ExpandableNotificationRow childRow : children) {
1022 if (childRow.getVisibility() == View.VISIBLE) {
1023 viewsToHide.add(childRow);
1024 }
1025 }
Dan Sandlereceda3d2014-07-21 15:35:01 -04001026 }
1027 }
1028 }
1029 if (viewsToHide.isEmpty()) {
1030 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1031 return;
1032 }
1033
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001034 addPostCollapseAction(new Runnable() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001035 @Override
1036 public void run() {
Selim Cinek9c17b772015-07-07 20:37:09 -07001037 mStackScroller.setDismissAllInProgress(false);
Dan Sandlereceda3d2014-07-21 15:35:01 -04001038 try {
1039 mBarService.onClearAllNotifications(mCurrentUserId);
1040 } catch (Exception ex) { }
1041 }
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001042 });
Dan Sandlereceda3d2014-07-21 15:35:01 -04001043
1044 performDismissAllAnimations(viewsToHide);
1045
1046 }
1047
1048 private void performDismissAllAnimations(ArrayList<View> hideAnimatedList) {
1049 Runnable animationFinishAction = new Runnable() {
1050 @Override
1051 public void run() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001052 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1053 }
1054 };
1055
1056 // let's disable our normal animations
1057 mStackScroller.setDismissAllInProgress(true);
1058
1059 // Decrease the delay for every row we animate to give the sense of
1060 // accelerating the swipes
1061 int rowDelayDecrement = 10;
1062 int currentDelay = 140;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001063 int totalDelay = 180;
Dan Sandlereceda3d2014-07-21 15:35:01 -04001064 int numItems = hideAnimatedList.size();
Selim Cinek7d5f3742014-11-07 18:07:49 +01001065 for (int i = numItems - 1; i >= 0; i--) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001066 View view = hideAnimatedList.get(i);
1067 Runnable endRunnable = null;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001068 if (i == 0) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001069 endRunnable = animationFinishAction;
1070 }
1071 mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
1072 currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
1073 totalDelay += currentDelay;
1074 }
1075 }
1076
John Spurlockae641c92014-06-30 18:11:40 -04001077 @Override
1078 protected void setZenMode(int mode) {
1079 super.setZenMode(mode);
1080 if (mIconPolicy != null) {
1081 mIconPolicy.setZenMode(mode);
1082 }
1083 }
1084
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001085 protected void startKeyguard() {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001086 KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001087 mFingerprintUnlockController = new FingerprintUnlockController(mContext,
1088 mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator,
1089 mScrimController, this);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001090 mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001091 getBouncerContainer(), mStatusBarWindowManager, mScrimController,
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001092 mFingerprintUnlockController);
Selim Cinekcfafe4e2015-08-11 14:58:44 -07001093 mKeyguardIndicationController.setStatusBarKeyguardViewManager(
1094 mStatusBarKeyguardViewManager);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001095 mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
Adrian Roosd28ccd72016-01-06 15:23:14 +01001096 mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001097 mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
Jorim Jaggi86905582016-02-09 21:36:09 -08001098 mLightStatusBarController.setFingerprintUnlockController(mFingerprintUnlockController);
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001099 }
1100
Michael Jurka7f2668c2012-03-27 07:49:52 -07001101 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -07001102 protected View getStatusBarView() {
1103 return mStatusBarView;
1104 }
1105
Jorim Jaggi0a27be82014-06-11 03:22:39 +02001106 public StatusBarWindowView getStatusBarWindow() {
1107 return mStatusBarWindow;
1108 }
1109
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001110 protected ViewGroup getBouncerContainer() {
1111 return mStatusBarWindow;
1112 }
1113
Joe Onoratodc100302011-01-11 17:07:41 -08001114 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -04001115 if (mNaturalBarHeight < 0) {
1116 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -07001117 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -04001118 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
1119 }
1120 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -08001121 }
1122
Daniel Sandler5c8da942011-06-28 00:29:04 -04001123 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
1124 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -04001125 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001126 toggleRecentApps();
1127 }
1128 };
Chris Wren0c8275b2012-05-08 13:36:48 -04001129
Jorim Jaggi75b25972015-10-21 14:51:10 +02001130 private View.OnLongClickListener mLongPressBackListener = new View.OnLongClickListener() {
Jason Monk62515be2014-05-21 16:06:19 -04001131 @Override
1132 public boolean onLongClick(View v) {
Jorim Jaggi75b25972015-10-21 14:51:10 +02001133 return handleLongPressBack();
1134 }
1135 };
1136
1137 private View.OnLongClickListener mRecentsLongClickListener = new View.OnLongClickListener() {
1138
1139 @Override
1140 public boolean onLongClick(View v) {
Phil Weaver315c34e2016-02-19 15:12:29 -08001141 if (mRecents == null) {
1142 return false;
1143 }
1144 boolean initiallyDocked = WindowManagerProxy.getInstance().getDockSide()
1145 == WindowManager.DOCKED_INVALID;
1146 boolean dockedAtEnd = toggleSplitScreenMode();
1147 if (dockedAtEnd != initiallyDocked) {
1148 int logAction = dockedAtEnd ? MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS
1149 : MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS;
1150 MetricsLogger.action(mContext, logAction);
1151 return true;
Jorim Jaggi75b25972015-10-21 14:51:10 +02001152 }
1153 return false;
Jason Monk62515be2014-05-21 16:06:19 -04001154 }
1155 };
1156
Phil Weaver315c34e2016-02-19 15:12:29 -08001157 @Override
1158 protected boolean toggleSplitScreenMode() {
1159 if (mRecents == null) {
1160 return false;
1161 }
1162 int dockSide = WindowManagerProxy.getInstance().getDockSide();
1163 if (dockSide == WindowManager.DOCKED_INVALID) {
1164 Point realSize = new Point();
1165 mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY)
1166 .getRealSize(realSize);
1167 Rect initialBounds= new Rect(0, 0, realSize.x, realSize.y);
1168 return mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
1169 ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
1170 initialBounds);
1171 } else {
1172 EventBus.getDefault().send(new UndockingTaskEvent());
1173 return false;
1174 }
1175 }
1176
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001177 private final View.OnLongClickListener mLongPressHomeListener
1178 = new View.OnLongClickListener() {
1179 @Override
1180 public boolean onLongClick(View v) {
1181 if (shouldDisableNavbarGestures()) {
1182 return false;
1183 }
Chris Wrenf6e9228b2016-01-26 18:04:35 -05001184 MetricsLogger.action(mContext, MetricsEvent.ACTION_ASSIST_LONG_PRESS);
Jorim Jaggi165ce062015-07-06 16:18:11 -07001185 mAssistManager.startAssist(new Bundle() /* args */);
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001186 awakenDreams();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001187 if (mNavigationBarView != null) {
Xiyuan Xiaee7dd052015-05-15 09:46:27 -07001188 mNavigationBarView.abortCurrentGesture();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001189 }
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001190 return true;
Jim Miller9a720f52012-05-30 03:19:43 -07001191 }
1192 };
1193
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001194 private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
Jim Millere898ac52012-04-06 17:10:57 -07001195 public boolean onTouch(View v, MotionEvent event) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001196 switch (event.getAction()) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001197 case MotionEvent.ACTION_UP:
1198 case MotionEvent.ACTION_CANCEL:
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001199 awakenDreams();
1200 break;
1201 }
1202 return false;
Jim Millere898ac52012-04-06 17:10:57 -07001203 }
1204 };
Daniel Sandler5c8da942011-06-28 00:29:04 -04001205
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001206 private void awakenDreams() {
1207 if (mDreamManager != null) {
1208 try {
1209 mDreamManager.awaken();
1210 } catch (RemoteException e) {
1211 // fine, stay asleep then
1212 }
1213 }
1214 }
1215
Michael Jurka412cba82011-10-17 09:05:00 -07001216 private void prepareNavigationBarView() {
1217 mNavigationBarView.reorient();
1218
Jason Monka2081822016-01-18 14:41:03 -05001219 ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
1220 recentsButton.setOnClickListener(mRecentsClickListener);
1221 recentsButton.setOnTouchListener(mRecentsPreloadOnTouchListener);
1222 recentsButton.setLongClickable(true);
1223 recentsButton.setOnLongClickListener(mRecentsLongClickListener);
Anthony Chenada13042016-01-19 16:57:20 -08001224
Jason Monka2081822016-01-18 14:41:03 -05001225 ButtonDispatcher backButton = mNavigationBarView.getBackButton();
1226 backButton.setLongClickable(true);
1227 backButton.setOnLongClickListener(mLongPressBackListener);
Anthony Chenada13042016-01-19 16:57:20 -08001228
Jason Monka2081822016-01-18 14:41:03 -05001229 ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
1230 homeButton.setOnTouchListener(mHomeActionListener);
1231 homeButton.setOnLongClickListener(mLongPressHomeListener);
Anthony Chenada13042016-01-19 16:57:20 -08001232
Selim Cineke70d6532015-04-24 16:46:13 -07001233 mAssistManager.onConfigurationChanged();
Michael Jurka412cba82011-10-17 09:05:00 -07001234 }
1235
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001236 // For small-screen devices (read: phones) that lack hardware navigation buttons
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001237 protected void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -04001238 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -04001239 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001240
Michael Jurka412cba82011-10-17 09:05:00 -07001241 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001242
Jeff Brown98365d72012-08-19 20:30:52 -07001243 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001244 }
1245
Victor Chanecdb8b02016-01-07 18:32:43 -08001246 protected void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -04001247 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001248
Michael Jurka412cba82011-10-17 09:05:00 -07001249 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001250
Jeff Brown98365d72012-08-19 20:30:52 -07001251 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001252 }
1253
John Spurlock1bbd49d2012-10-19 11:09:32 -04001254 private void notifyNavigationBarScreenOn(boolean screenOn) {
1255 if (mNavigationBarView == null) return;
1256 mNavigationBarView.notifyScreenOn(screenOn);
1257 }
1258
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001259 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001260 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001261 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001262 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
1263 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001264 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1265 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -07001266 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -04001267 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -07001268 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
John Spurlockad3e6cb2013-04-30 08:47:43 -04001269 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001270 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -07001271 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001272 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
1273 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001274
1275 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001276 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001277 return lp;
1278 }
1279
Jason Monk07473ce2016-01-05 14:59:19 -05001280 @Override
1281 public void setIcon(String slot, StatusBarIcon icon) {
1282 mIconController.setIcon(slot, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001283 }
1284
Jason Monk07473ce2016-01-05 14:59:19 -05001285 @Override
1286 public void removeIcon(String slot) {
1287 mIconController.removeIcon(slot);
Joe Onorato808182d2010-07-09 18:52:06 -04001288 }
1289
John Spurlockbf20eab2014-04-09 16:40:39 -04001290 public UserHandle getCurrentUserHandle() {
1291 return new UserHandle(mCurrentUserId);
1292 }
1293
Christoph Studer71f18fd2014-05-20 17:02:04 +02001294 @Override
Selim Cinek379ff8f2015-02-20 17:03:16 +01001295 public void addNotification(StatusBarNotification notification, RankingMap ranking,
1296 Entry oldEntry) {
Chris Wrenaaa58d12014-06-03 14:29:12 -04001297 if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
Chris Wrend4db6cb2013-08-07 16:05:23 -04001298
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001299 mNotificationData.updateRanking(ranking);
Selim Cinek8d490d42015-04-10 00:05:50 -07001300 Entry shadeEntry = createNotificationViews(notification);
Chris Wrena4ef6202014-06-09 18:07:30 -04001301 if (shadeEntry == null) {
1302 return;
1303 }
Chris Wrenbdf33762015-12-04 15:50:51 -05001304 boolean isHeadsUped = mUseHeadsUp && shouldPeek(shadeEntry);
Selim Cinek31d9ef72015-04-15 19:29:49 -07001305 if (isHeadsUped) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001306 mHeadsUpManager.showNotification(shadeEntry);
Amith Yamasanif47e51e2015-04-17 10:02:15 -07001307 // Mark as seen immediately
1308 setNotificationShown(notification);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001309 }
Chris Wrena4ef6202014-06-09 18:07:30 -04001310
Selim Cinek31d9ef72015-04-15 19:29:49 -07001311 if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
Julia Reynoldsd5607292016-02-05 15:25:58 -05001312 if (shouldSuppressFullScreenIntent(notification.getKey())) {
Julia Reynolds61721582016-01-05 08:35:25 -05001313 if (DEBUG) {
1314 Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + notification.getKey());
1315 }
Julia Reynoldsf0f629f2016-02-25 09:34:04 -05001316 } else if (mNotificationData.getImportance(notification.getKey())
1317 < NotificationListenerService.Ranking.IMPORTANCE_MAX) {
1318 if (DEBUG) {
1319 Log.d(TAG, "No Fullscreen intent: not important enough: "
1320 + notification.getKey());
1321 }
Julia Reynolds61721582016-01-05 08:35:25 -05001322 } else {
1323 // Stop screensaver if the notification has a full-screen intent.
1324 // (like an incoming phone call)
1325 awakenDreams();
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -04001326
Julia Reynolds61721582016-01-05 08:35:25 -05001327 // not immersive & a full-screen alert should be shown
1328 if (DEBUG)
1329 Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
1330 try {
1331 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
1332 notification.getKey());
1333 notification.getNotification().fullScreenIntent.send();
1334 shadeEntry.notifyFullScreenIntentLaunched();
1335 MetricsLogger.count(mContext, "note_fullscreen", 1);
1336 } catch (PendingIntent.CanceledException e) {
1337 }
John Spurlockbf20eab2014-04-09 16:40:39 -04001338 }
Joe Onorato808182d2010-07-09 18:52:06 -04001339 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001340 addNotificationViews(shadeEntry, ranking);
Joe Onorato808182d2010-07-09 18:52:06 -04001341 // Recalculate the position of the sliding windows and the titles.
1342 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001343 }
1344
Julia Reynoldsd5607292016-02-05 15:25:58 -05001345 private boolean shouldSuppressFullScreenIntent(String key) {
Julia Reynolds0971cb02016-01-26 17:00:22 -05001346 if (mPowerManager.isInteractive()) {
Julia Reynolds0971cb02016-01-26 17:00:22 -05001347 return mNotificationData.shouldSuppressScreenOn(key);
Julia Reynoldsd5607292016-02-05 15:25:58 -05001348 } else {
1349 return mNotificationData.shouldSuppressScreenOff(key);
Julia Reynolds0971cb02016-01-26 17:00:22 -05001350 }
1351 }
1352
Chris Wren51c75102013-07-16 20:49:17 -04001353 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001354 protected void updateNotificationRanking(RankingMap ranking) {
Chris Wren333a61c2014-05-28 16:40:57 -04001355 mNotificationData.updateRanking(ranking);
Chris Wren333a61c2014-05-28 16:40:57 -04001356 updateNotifications();
1357 }
1358
1359 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001360 public void removeNotification(String key, RankingMap ranking) {
Selim Cinek684a4422015-04-15 16:18:39 -07001361 boolean deferRemoval = false;
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001362 if (mHeadsUpManager.isHeadsUp(key)) {
Selim Cinek684a4422015-04-15 16:18:39 -07001363 deferRemoval = !mHeadsUpManager.removeNotification(key);
Chris Wrena4ef6202014-06-09 18:07:30 -04001364 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001365 if (key.equals(mMediaNotificationKey)) {
1366 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -08001367 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001368 }
Selim Cinek684a4422015-04-15 16:18:39 -07001369 if (deferRemoval) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001370 mLatestRankingMap = ranking;
1371 mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
1372 return;
1373 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001374 StatusBarNotification old = removeNotificationViews(key, ranking);
John Spurlockcd686b52013-06-05 10:13:46 -04001375 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -04001376
1377 if (old != null) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001378 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
Jorim Jaggiba94f882014-08-20 19:23:55 +02001379 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001380 if (mState == StatusBarState.SHADE) {
1381 animateCollapsePanels();
1382 } else if (mState == StatusBarState.SHADE_LOCKED) {
1383 goToKeyguard();
1384 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001385 }
Joe Onorato808182d2010-07-09 18:52:06 -04001386 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001387 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001388 }
1389
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001390 @Override
1391 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001392 if (mNavigationBarView != null) {
1393 mNavigationBarView.setLayoutDirection(layoutDirection);
1394 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001395 }
1396
Christoph Studer37fe6932014-05-26 13:10:30 +02001397 private void updateNotificationShade() {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001398 if (mStackScroller == null) return;
Daniel Sandler26cda272012-05-22 15:44:08 -04001399
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001400 // Do not modify the notifications during collapse.
1401 if (isCollapsing()) {
1402 addPostCollapseAction(new Runnable() {
1403 @Override
1404 public void run() {
1405 updateNotificationShade();
1406 }
1407 });
1408 return;
1409 }
1410
Christoph Studerc8db24b2014-07-25 17:50:30 +02001411 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
Jorim Jaggif6411742014-08-05 17:10:43 +00001412 ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
Christoph Studerc8db24b2014-07-25 17:50:30 +02001413 final int N = activeNotifications.size();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001414 for (int i=0; i<N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001415 Entry ent = activeNotifications.get(i);
1416 int vis = ent.notification.getNotification().visibility;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001417
Christoph Studerc8db24b2014-07-25 17:50:30 +02001418 // Display public version of the notification if we need to redact.
Jorim Jaggiae441282014-08-01 02:45:18 +02001419 final boolean hideSensitive =
1420 !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId());
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001421 boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE;
1422 boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey());
1423 boolean sensitive = (sensitiveNote && hideSensitive) || sensitivePackage;
1424 boolean showingPublic = sensitive && isLockscreenPublicMode();
Sudheer Shankaf5b850e2016-01-25 19:58:59 +00001425 if (showingPublic) {
1426 updatePublicContentView(ent, ent.notification);
1427 }
Selim Cinek3c76d502016-02-19 15:16:33 -08001428 ent.row.setSensitive(sensitive, hideSensitive);
Dan Sandler1b718782014-07-18 12:43:45 -04001429 if (ent.autoRedacted && ent.legacy) {
Jorim Jaggiae441282014-08-01 02:45:18 +02001430 // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
1431 // for legacy auto redacted notifications.
Dan Sandler1b718782014-07-18 12:43:45 -04001432 if (showingPublic) {
1433 ent.row.setShowingLegacyBackground(false);
1434 } else {
1435 ent.row.setShowingLegacyBackground(true);
1436 }
1437 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001438 if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
1439 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
1440 ent.row.getStatusBarNotification());
1441 List<ExpandableNotificationRow> orderedChildren =
1442 mTmpChildOrderMap.get(summary);
1443 if (orderedChildren == null) {
1444 orderedChildren = new ArrayList<>();
1445 mTmpChildOrderMap.put(summary, orderedChildren);
1446 }
1447 orderedChildren.add(ent.row);
1448 } else {
1449 toShow.add(ent.row);
1450 }
1451
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001452 }
1453
Selim Cinekef5127e2015-12-21 16:55:58 -08001454 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001455 for (int i=0; i< mStackScroller.getChildCount(); i++) {
1456 View child = mStackScroller.getChildAt(i);
Jorim Jaggif6411742014-08-05 17:10:43 +00001457 if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
Selim Cinekef5127e2015-12-21 16:55:58 -08001458 toRemove.add((ExpandableNotificationRow) child);
Joe Onorato808182d2010-07-09 18:52:06 -04001459 }
1460 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001461
Selim Cinekef5127e2015-12-21 16:55:58 -08001462 for (ExpandableNotificationRow remove : toRemove) {
1463 if (mGroupManager.isChildInGroupWithSummary(remove.getStatusBarNotification())) {
1464 // we are only transfering this notification to its parent, don't generate an animation
1465 mStackScroller.setChildTransferInProgress(true);
1466 }
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001467 mStackScroller.removeView(remove);
Selim Cinekef5127e2015-12-21 16:55:58 -08001468 mStackScroller.setChildTransferInProgress(false);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001469 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001470 for (int i=0; i<toShow.size(); i++) {
1471 View v = toShow.get(i);
1472 if (v.getParent() == null) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001473 mStackScroller.addView(v);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001474 }
1475 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001476
Christoph Studer37fe6932014-05-26 13:10:30 +02001477 // So after all this work notifications still aren't sorted correctly.
1478 // Let's do that now by advancing through toShow and mStackScroller in
1479 // lock-step, making sure mStackScroller matches what we see in toShow.
1480 int j = 0;
1481 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1482 View child = mStackScroller.getChildAt(i);
1483 if (!(child instanceof ExpandableNotificationRow)) {
1484 // We don't care about non-notification views.
1485 continue;
1486 }
1487
Selim Cinekb5605e52015-02-20 18:21:41 +01001488 ExpandableNotificationRow targetChild = toShow.get(j);
1489 if (child != targetChild) {
1490 // Oops, wrong notification at this position. Put the right one
1491 // here and advance both lists.
1492 mStackScroller.changeViewPosition(targetChild, i);
Christoph Studer37fe6932014-05-26 13:10:30 +02001493 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001494 j++;
Selim Cinekb5605e52015-02-20 18:21:41 +01001495
Christoph Studer37fe6932014-05-26 13:10:30 +02001496 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001497
1498 // lets handle the child notifications now
1499 updateNotificationShadeForChildren();
1500
1501 // clear the map again for the next usage
1502 mTmpChildOrderMap.clear();
1503
Christoph Studer37fe6932014-05-26 13:10:30 +02001504 updateRowStates();
Jorim Jaggif6411742014-08-05 17:10:43 +00001505 updateSpeedbump();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001506 updateClearAll();
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001507 updateEmptyShadeView();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001508
Benjamin Franz27cf1462015-04-23 19:36:42 +01001509 updateQsExpansionEnabled();
1510 mShadeUpdates.check();
1511 }
1512
1513 /**
1514 * Disable QS if device not provisioned.
1515 * If the user switcher is simple then disable QS during setup because
1516 * the user intends to use the lock screen user switcher, QS in not needed.
1517 */
1518 private void updateQsExpansionEnabled() {
Jason Monk3ad242d2014-09-15 11:13:35 -04001519 mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
Adrian Roos2b154a92014-11-17 15:18:39 +01001520 && (mUserSetup || mUserSwitcherController == null
Benjamin Franz27cf1462015-04-23 19:36:42 +01001521 || !mUserSwitcherController.isSimpleUserSwitcher())
Adrian Roos21d2a252015-06-01 13:59:59 -07001522 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
1523 && !ONLY_CORE_APPS);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001524 }
1525
Selim Cinekb5605e52015-02-20 18:21:41 +01001526 private void updateNotificationShadeForChildren() {
Selim Cinek322ec7e2016-02-11 14:47:06 -08001527 // First let's remove all children which don't belong in the parents
Selim Cinekb5605e52015-02-20 18:21:41 +01001528 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
Selim Cinekb5605e52015-02-20 18:21:41 +01001529 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1530 View view = mStackScroller.getChildAt(i);
1531 if (!(view instanceof ExpandableNotificationRow)) {
1532 // We don't care about non-notification views.
1533 continue;
1534 }
1535
1536 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1537 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1538 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1539
Selim Cinekb5605e52015-02-20 18:21:41 +01001540 if (children != null) {
1541 toRemove.clear();
1542 for (ExpandableNotificationRow childRow : children) {
1543 if (orderedChildren == null || !orderedChildren.contains(childRow)) {
1544 toRemove.add(childRow);
1545 }
1546 }
1547 for (ExpandableNotificationRow remove : toRemove) {
1548 parent.removeChildNotification(remove);
1549 mStackScroller.notifyGroupChildRemoved(remove);
1550 }
1551 }
Selim Cinek322ec7e2016-02-11 14:47:06 -08001552 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001553
Selim Cinek322ec7e2016-02-11 14:47:06 -08001554 // Let's now add all notification children which are missing
1555 boolean orderChanged = false;
1556 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1557 View view = mStackScroller.getChildAt(i);
1558 if (!(view instanceof ExpandableNotificationRow)) {
1559 // We don't care about non-notification views.
1560 continue;
1561 }
1562
1563 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1564 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1565 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1566
Selim Cinekb5605e52015-02-20 18:21:41 +01001567 for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
1568 childIndex++) {
1569 ExpandableNotificationRow childView = orderedChildren.get(childIndex);
1570 if (children == null || !children.contains(childView)) {
1571 parent.addChildNotification(childView, childIndex);
1572 mStackScroller.notifyGroupChildAdded(childView);
1573 }
1574 }
1575
1576 // Finally after removing and adding has been beformed we can apply the order.
1577 orderChanged |= parent.applyChildOrder(orderedChildren);
1578 }
1579 if (orderChanged) {
1580 mStackScroller.generateChildOrderChangedEvent();
1581 }
1582 }
1583
Jason Monk7e53f202016-01-28 10:40:20 -05001584 @Override
1585 public void addQsTile(ComponentName tile) {
1586 mQSPanel.getHost().addTile(tile);
1587 }
1588
1589 @Override
1590 public void remQsTile(ComponentName tile) {
1591 mQSPanel.getHost().removeTile(tile);
1592 }
1593
1594 @Override
1595 public void clickTile(ComponentName tile) {
1596 mQSPanel.clickTile(tile);
1597 }
1598
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001599 private boolean packageHasVisibilityOverride(String key) {
1600 return mNotificationData.getVisibilityOverride(key)
1601 != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
1602 }
1603
Dan Sandlereceda3d2014-07-21 15:35:01 -04001604 private void updateClearAll() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001605 boolean showDismissView =
1606 mState != StatusBarState.KEYGUARD &&
1607 mNotificationData.hasActiveClearableNotifications();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001608 mStackScroller.updateDismissView(showDismissView);
1609 }
1610
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001611 private void updateEmptyShadeView() {
1612 boolean showEmptyShade =
1613 mState != StatusBarState.KEYGUARD &&
1614 mNotificationData.getActiveNotifications().size() == 0;
1615 mNotificationPanel.setShadeEmpty(showEmptyShade);
1616 }
1617
Jorim Jaggif6411742014-08-05 17:10:43 +00001618 private void updateSpeedbump() {
1619 int speedbumpIndex = -1;
1620 int currentIndex = 0;
1621 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1622 final int N = activeNotifications.size();
1623 for (int i = 0; i < N; i++) {
1624 Entry entry = activeNotifications.get(i);
Selim Cinekb5605e52015-02-20 18:21:41 +01001625 boolean isChild = !isTopLevelChild(entry);
1626 if (isChild) {
1627 continue;
1628 }
Jorim Jaggif6411742014-08-05 17:10:43 +00001629 if (entry.row.getVisibility() != View.GONE &&
1630 mNotificationData.isAmbient(entry.key)) {
1631 speedbumpIndex = currentIndex;
1632 break;
1633 }
1634 currentIndex++;
1635 }
1636 mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
1637 }
1638
Selim Cinekb5605e52015-02-20 18:21:41 +01001639 public static boolean isTopLevelChild(Entry entry) {
1640 return entry.row.getParent() instanceof NotificationStackScrollLayout;
1641 }
1642
Chris Wren0c8275b2012-05-08 13:36:48 -04001643 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001644 protected void updateNotifications() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001645 mNotificationData.filterAndSort();
1646
Christoph Studer37fe6932014-05-26 13:10:30 +02001647 updateNotificationShade();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001648 mIconController.updateNotificationIcons(mNotificationData);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001649 }
1650
Selim Cinekef5127e2015-12-21 16:55:58 -08001651 public void requestNotificationUpdate() {
1652 updateNotifications();
1653 }
1654
Jorim Jaggi54045422014-07-03 18:30:40 +02001655 @Override
Chris Wren0c8275b2012-05-08 13:36:48 -04001656 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001657
Chris Wren6d15a362013-08-20 18:46:29 -04001658 if (SPEW) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001659 final boolean clearable = hasActiveNotifications() &&
1660 mNotificationData.hasActiveClearableNotifications();
1661 Log.d(TAG, "setAreThereNotifications: N=" +
1662 mNotificationData.getActiveNotifications().size() + " any=" +
1663 hasActiveNotifications() + " clearable=" + clearable);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001664 }
1665
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001666 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
Christoph Studerc8db24b2014-07-25 17:50:30 +02001667 final boolean showDot = hasActiveNotifications() && !areLightsOn();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001668 if (showDot != (nlo.getAlpha() == 1.0f)) {
1669 if (showDot) {
1670 nlo.setAlpha(0f);
1671 nlo.setVisibility(View.VISIBLE);
1672 }
1673 nlo.animate()
1674 .alpha(showDot?1:0)
1675 .setDuration(showDot?750:250)
1676 .setInterpolator(new AccelerateInterpolator(2.0f))
1677 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1678 @Override
1679 public void onAnimationEnd(Animator _a) {
1680 nlo.setVisibility(View.GONE);
1681 }
1682 })
1683 .start();
1684 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001685
Dan Sandler16128f42014-05-21 12:48:22 -04001686 findAndUpdateMediaNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001687 }
1688
Dan Sandler16128f42014-05-21 12:48:22 -04001689 public void findAndUpdateMediaNotifications() {
1690 boolean metaDataChanged = false;
1691
1692 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001693 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1694 final int N = activeNotifications.size();
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001695
1696 // Promote the media notification with a controller in 'playing' state, if any.
Dan Sandler16128f42014-05-21 12:48:22 -04001697 Entry mediaNotification = null;
1698 MediaController controller = null;
Christoph Studerc8db24b2014-07-25 17:50:30 +02001699 for (int i = 0; i < N; i++) {
1700 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04001701 if (isMediaNotification(entry)) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001702 final MediaSession.Token token =
1703 entry.notification.getNotification().extras
Dan Sandler16128f42014-05-21 12:48:22 -04001704 .getParcelable(Notification.EXTRA_MEDIA_SESSION);
1705 if (token != null) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001706 MediaController aController = new MediaController(mContext, token);
1707 if (PlaybackState.STATE_PLAYING ==
1708 getMediaControllerPlaybackState(aController)) {
1709 if (DEBUG_MEDIA) {
1710 Log.v(TAG, "DEBUG_MEDIA: found mediastyle controller matching "
1711 + entry.notification.getKey());
1712 }
Dan Sandler16128f42014-05-21 12:48:22 -04001713 mediaNotification = entry;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001714 controller = aController;
1715 break;
Dan Sandler16128f42014-05-21 12:48:22 -04001716 }
1717 }
1718 }
1719 }
Dan Sandler16128f42014-05-21 12:48:22 -04001720 if (mediaNotification == null) {
1721 // Still nothing? OK, let's just look for live media sessions and see if they match
1722 // one of our notifications. This will catch apps that aren't (yet!) using media
1723 // notifications.
1724
1725 if (mMediaSessionManager != null) {
1726 final List<MediaController> sessions
1727 = mMediaSessionManager.getActiveSessionsForUser(
1728 null,
1729 UserHandle.USER_ALL);
1730
1731 for (MediaController aController : sessions) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001732 if (PlaybackState.STATE_PLAYING ==
1733 getMediaControllerPlaybackState(aController)) {
1734 // now to see if we have one like this
1735 final String pkg = aController.getPackageName();
Dan Sandler16128f42014-05-21 12:48:22 -04001736
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001737 for (int i = 0; i < N; i++) {
1738 final Entry entry = activeNotifications.get(i);
1739 if (entry.notification.getPackageName().equals(pkg)) {
1740 if (DEBUG_MEDIA) {
1741 Log.v(TAG, "DEBUG_MEDIA: found controller matching "
1742 + entry.notification.getKey());
Dan Sandler16128f42014-05-21 12:48:22 -04001743 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001744 controller = aController;
1745 mediaNotification = entry;
1746 break;
Dan Sandler16128f42014-05-21 12:48:22 -04001747 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001748 }
Dan Sandler16128f42014-05-21 12:48:22 -04001749 }
1750 }
1751 }
1752 }
1753
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001754 if (controller != null && !sameSessions(mMediaController, controller)) {
Dan Sandler16128f42014-05-21 12:48:22 -04001755 // We have a new media session
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001756 clearCurrentMediaNotification();
Dan Sandler16128f42014-05-21 12:48:22 -04001757 mMediaController = controller;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001758 mMediaController.registerCallback(mMediaListener);
1759 mMediaMetadata = mMediaController.getMetadata();
Dan Sandler16128f42014-05-21 12:48:22 -04001760 if (DEBUG_MEDIA) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001761 Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: "
1762 + mMediaMetadata);
Dan Sandler16128f42014-05-21 12:48:22 -04001763 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001764
1765 if (mediaNotification != null) {
1766 mMediaNotificationKey = mediaNotification.notification.getKey();
1767 if (DEBUG_MEDIA) {
1768 Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
1769 + mMediaNotificationKey + " controller=" + mMediaController);
1770 }
1771 }
1772 metaDataChanged = true;
Dan Sandler16128f42014-05-21 12:48:22 -04001773 }
1774 }
1775
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001776 if (metaDataChanged) {
1777 updateNotifications();
1778 }
Adrian Roos52738322016-01-29 08:49:21 -08001779 updateMediaMetaData(metaDataChanged, true);
Dan Sandler16128f42014-05-21 12:48:22 -04001780 }
1781
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001782 private int getMediaControllerPlaybackState(MediaController controller) {
1783 if (controller != null) {
1784 final PlaybackState playbackState = controller.getPlaybackState();
1785 if (playbackState != null) {
1786 return playbackState.getState();
1787 }
1788 }
1789 return PlaybackState.STATE_NONE;
1790 }
1791
1792 private boolean isPlaybackActive(int state) {
1793 if (state != PlaybackState.STATE_STOPPED
1794 && state != PlaybackState.STATE_ERROR
1795 && state != PlaybackState.STATE_NONE) {
1796 return true;
1797 }
1798 return false;
1799 }
1800
1801 private void clearCurrentMediaNotification() {
1802 mMediaNotificationKey = null;
1803 mMediaMetadata = null;
1804 if (mMediaController != null) {
1805 if (DEBUG_MEDIA) {
1806 Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
1807 + mMediaController.getPackageName());
1808 }
1809 mMediaController.unregisterCallback(mMediaListener);
1810 }
1811 mMediaController = null;
1812 }
1813
Christoph Studerb5245d82014-09-19 16:54:36 +02001814 private boolean sameSessions(MediaController a, MediaController b) {
1815 if (a == b) return true;
1816 if (a == null) return false;
1817 return a.controlsSameSession(b);
1818 }
1819
Dan Sandler16128f42014-05-21 12:48:22 -04001820 /**
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001821 * Hide the album artwork that is fading out and release its bitmap.
Dan Sandler16128f42014-05-21 12:48:22 -04001822 */
1823 private Runnable mHideBackdropFront = new Runnable() {
1824 @Override
1825 public void run() {
1826 if (DEBUG_MEDIA) {
1827 Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
1828 }
1829 mBackdropFront.setVisibility(View.INVISIBLE);
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001830 mBackdropFront.animate().cancel();
1831 mBackdropFront.setImageDrawable(null);
Dan Sandler16128f42014-05-21 12:48:22 -04001832 }
1833 };
1834
1835 /**
Adrian Roose381c162016-02-11 15:26:42 -08001836 * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
Dan Sandler16128f42014-05-21 12:48:22 -04001837 */
Adrian Roos52738322016-01-29 08:49:21 -08001838 public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
Dan Sandler16128f42014-05-21 12:48:22 -04001839 if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) return;
1840
1841 if (mBackdrop == null) return; // called too early
1842
Selim Cinek37c110f2015-05-22 12:38:44 -07001843 if (mLaunchTransitionFadingAway) {
1844 mBackdrop.setVisibility(View.INVISIBLE);
1845 return;
1846 }
1847
Dan Sandler16128f42014-05-21 12:48:22 -04001848 if (DEBUG_MEDIA) {
1849 Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey
Selim Cinek131c1e22015-05-11 19:04:49 -07001850 + " metadata=" + mMediaMetadata
1851 + " metaDataChanged=" + metaDataChanged
1852 + " state=" + mState);
Dan Sandler16128f42014-05-21 12:48:22 -04001853 }
1854
1855 Bitmap artworkBitmap = null;
1856 if (mMediaMetadata != null) {
1857 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
1858 if (artworkBitmap == null) {
1859 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
1860 // might still be null
1861 }
1862 }
Adrian Roos52738322016-01-29 08:49:21 -08001863 if (ENABLE_LOCKSCREEN_WALLPAPER && artworkBitmap == null) {
Adrian Roose381c162016-02-11 15:26:42 -08001864 artworkBitmap = mLockscreenWallpaper.getBitmap();
Adrian Roos52738322016-01-29 08:49:21 -08001865 }
Dan Sandler16128f42014-05-21 12:48:22 -04001866
1867 final boolean hasArtwork = artworkBitmap != null;
1868
Jorim Jaggi95d16bf2015-08-24 17:42:02 -07001869 if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK) && mState != StatusBarState.SHADE
Jorim Jaggid94d3a22015-08-21 16:52:55 -07001870 && mFingerprintUnlockController.getMode()
1871 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
Dan Sandler16128f42014-05-21 12:48:22 -04001872 // time to show some art!
1873 if (mBackdrop.getVisibility() != View.VISIBLE) {
1874 mBackdrop.setVisibility(View.VISIBLE);
Adrian Roos52738322016-01-29 08:49:21 -08001875 if (allowEnterAnimation) {
1876 mBackdrop.animate().alpha(1f);
1877 } else {
1878 mBackdrop.animate().cancel();
1879 mBackdrop.setAlpha(1f);
1880 }
Dan Sandler16128f42014-05-21 12:48:22 -04001881 metaDataChanged = true;
1882 if (DEBUG_MEDIA) {
1883 Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
1884 }
1885 }
1886 if (metaDataChanged) {
1887 if (mBackdropBack.getDrawable() != null) {
Julia Reynolds4b9658a2015-07-22 17:07:42 -04001888 Drawable drawable =
1889 mBackdropBack.getDrawable().getConstantState().newDrawable().mutate();
Selim Cineka0fad3b2014-09-19 17:20:05 +02001890 mBackdropFront.setImageDrawable(drawable);
Jorim Jaggi0e664392014-09-27 01:30:22 +02001891 if (mScrimSrcModeEnabled) {
1892 mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
1893 }
Dan Sandler16128f42014-05-21 12:48:22 -04001894 mBackdropFront.setAlpha(1f);
1895 mBackdropFront.setVisibility(View.VISIBLE);
1896 } else {
1897 mBackdropFront.setVisibility(View.INVISIBLE);
1898 }
1899
1900 if (DEBUG_MEDIA_FAKE_ARTWORK) {
1901 final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
1902 Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
1903 mBackdropBack.setBackgroundColor(0xFFFFFFFF);
1904 mBackdropBack.setImageDrawable(new ColorDrawable(c));
1905 } else {
1906 mBackdropBack.setImageBitmap(artworkBitmap);
1907 }
Jorim Jaggi0e664392014-09-27 01:30:22 +02001908 if (mScrimSrcModeEnabled) {
1909 mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
1910 }
Dan Sandler16128f42014-05-21 12:48:22 -04001911
1912 if (mBackdropFront.getVisibility() == View.VISIBLE) {
1913 if (DEBUG_MEDIA) {
1914 Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
1915 + mBackdropFront.getDrawable()
1916 + " to "
1917 + mBackdropBack.getDrawable());
1918 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001919 mBackdropFront.animate()
Dan Sandler16128f42014-05-21 12:48:22 -04001920 .setDuration(250)
1921 .alpha(0f).withEndAction(mHideBackdropFront);
1922 }
1923 }
1924 } else {
1925 // need to hide the album art, either because we are unlocked or because
1926 // the metadata isn't there to support it
1927 if (mBackdrop.getVisibility() != View.GONE) {
1928 if (DEBUG_MEDIA) {
1929 Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
1930 }
Jorim Jaggid94d3a22015-08-21 16:52:55 -07001931 if (mFingerprintUnlockController.getMode()
1932 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001933
Jorim Jaggid94d3a22015-08-21 16:52:55 -07001934 // We are unlocking directly - no animation!
1935 mBackdrop.setVisibility(View.GONE);
1936 } else {
1937 mBackdrop.animate()
1938 // Never let the alpha become zero - otherwise the RenderNode
1939 // won't draw anything and uninitialized memory will show through
1940 // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
1941 // libhwui.
1942 .alpha(0.002f)
Selim Cinekc18010f2016-01-20 13:41:30 -08001943 .setInterpolator(Interpolators.ACCELERATE_DECELERATE)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07001944 .setDuration(300)
1945 .setStartDelay(0)
1946 .withEndAction(new Runnable() {
1947 @Override
1948 public void run() {
1949 mBackdrop.setVisibility(View.GONE);
1950 mBackdropFront.animate().cancel();
1951 mBackdropBack.animate().cancel();
1952 mHandler.post(mHideBackdropFront);
1953 }
1954 });
1955 if (mKeyguardFadingAway) {
1956 mBackdrop.animate()
1957
1958 // Make it disappear faster, as the focus should be on the activity
1959 // behind.
1960 .setDuration(mKeyguardFadingAwayDuration / 2)
1961 .setStartDelay(mKeyguardFadingAwayDelay)
Selim Cinekc18010f2016-01-20 13:41:30 -08001962 .setInterpolator(Interpolators.LINEAR)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07001963 .start();
1964 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001965 }
Dan Sandler16128f42014-05-21 12:48:22 -04001966 }
1967 }
1968 }
1969
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001970 private int adjustDisableFlags(int state) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001971 if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway
Selim Cinekbaa23272014-07-08 18:01:07 +02001972 && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02001973 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
1974 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
1975 }
1976 return state;
1977 }
1978
Joe Onorato808182d2010-07-09 18:52:06 -04001979 /**
1980 * State is one or more of the DISABLE constants from StatusBarManager.
1981 */
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001982 public void disable(int state1, int state2, boolean animate) {
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07001983 animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001984 mDisabledUnmodified1 = state1;
1985 mDisabledUnmodified2 = state2;
1986 state1 = adjustDisableFlags(state1);
1987 final int old1 = mDisabled1;
1988 final int diff1 = state1 ^ old1;
1989 mDisabled1 = state1;
1990
1991 final int old2 = mDisabled2;
1992 final int diff2 = state2 ^ old2;
1993 mDisabled2 = state2;
Joe Onorato808182d2010-07-09 18:52:06 -04001994
Daniel Sandlere21f2882011-08-18 10:14:59 -04001995 if (DEBUG) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01001996 Log.d(TAG, String.format("disable1: 0x%08x -> 0x%08x (diff1: 0x%08x)",
1997 old1, state1, diff1));
1998 Log.d(TAG, String.format("disable2: 0x%08x -> 0x%08x (diff2: 0x%08x)",
1999 old2, state2, diff2));
Daniel Sandlere21f2882011-08-18 10:14:59 -04002000 }
2001
Daniel Sandler6da2b762011-09-14 16:04:59 -04002002 StringBuilder flagdbg = new StringBuilder();
2003 flagdbg.append("disable: < ");
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002004 flagdbg.append(((state1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
2005 flagdbg.append(((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
2006 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
2007 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
2008 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
2009 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
2010 flagdbg.append(((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
2011 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
2012 flagdbg.append(((state1 & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
2013 flagdbg.append(((diff1 & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
2014 flagdbg.append(((state1 & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
2015 flagdbg.append(((diff1 & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
2016 flagdbg.append(((state1 & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
2017 flagdbg.append(((diff1 & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
2018 flagdbg.append(((state1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
2019 flagdbg.append(((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
2020 flagdbg.append(((state1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
2021 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Benjamin Franz27cf1462015-04-23 19:36:42 +01002022 flagdbg.append(((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "QUICK_SETTINGS"
2023 : "quick_settings");
2024 flagdbg.append(((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04002025 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04002026 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07002027
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002028 if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
2029 if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002030 mIconController.hideSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002031 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002032 mIconController.showSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002033 }
2034 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04002035
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002036 if ((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) {
2037 boolean visible = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002038 mIconController.setClockVisibility(visible);
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07002039 }
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002040 if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
2041 if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002042 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04002043 }
2044 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002045
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002046 if ((diff1 & (StatusBarManager.DISABLE_HOME
Jim Miller5e6af442011-12-02 18:24:26 -08002047 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002048 | StatusBarManager.DISABLE_BACK
2049 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04002050 // the nav bar will take care of these
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002051 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002052
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002053 if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04002054 // close recents if it's visible
Winson Chung1e8d71b2014-05-16 17:05:22 -07002055 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2056 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002057 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002058 }
2059
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002060 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
2061 if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002062 mIconController.hideNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002063 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002064 mIconController.showNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002065 }
Joe Onorato808182d2010-07-09 18:52:06 -04002066 }
Jason Monkf7019542014-07-31 12:42:25 -04002067
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002068 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
Jason Monkf7019542014-07-31 12:42:25 -04002069 mDisableNotificationAlerts =
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002070 (state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
Jason Monkf7019542014-07-31 12:42:25 -04002071 mHeadsUpObserver.onChange(true);
2072 }
Benjamin Franz27cf1462015-04-23 19:36:42 +01002073
2074 if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
2075 updateQsExpansionEnabled();
2076 }
Joe Onorato808182d2010-07-09 18:52:06 -04002077 }
2078
Michael Jurka7f2668c2012-03-27 07:49:52 -07002079 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07002080 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002081 return new PhoneStatusBar.H();
2082 }
2083
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002084 @Override
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002085 public void startActivity(Intent intent, boolean dismissShade) {
2086 startActivityDismissingKeyguard(intent, false, dismissShade);
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002087 }
2088
Selim Cineke70d6532015-04-24 16:46:13 -07002089 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07002090 public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
2091 startActivityDismissingKeyguard(intent, false, dismissShade, callback);
2092 }
2093
2094 @Override
Selim Cineke70d6532015-04-24 16:46:13 -07002095 public void preventNextAnimation() {
2096 overrideActivityPendingAppTransition(true /* keyguardShowing */);
2097 }
2098
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002099 public void setQsExpanded(boolean expanded) {
2100 mStatusBarWindowManager.setQsExpanded(expanded);
Adrian Roos4c7d9602015-06-10 13:44:48 -07002101 mKeyguardStatusView.setImportantForAccessibility(expanded
2102 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
2103 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002104 }
2105
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02002106 public boolean isGoingToNotificationShade() {
2107 return mLeaveOpenOnKeyguardHide;
2108 }
2109
Jorim Jaggid692dd02014-08-14 20:57:42 +02002110 public boolean isQsExpanded() {
2111 return mNotificationPanel.isQsExpanded();
2112 }
2113
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07002114 public boolean isWakeUpComingFromTouch() {
2115 return mWakeUpComingFromTouch;
Selim Cinek29ed3c92014-09-23 20:44:35 +02002116 }
2117
Selim Cinek19c8c702014-08-25 22:09:19 +02002118 public boolean isFalsingThresholdNeeded() {
Selim Cinek9db71052015-04-24 18:54:30 -07002119 return getBarState() == StatusBarState.KEYGUARD;
Selim Cinek19c8c702014-08-25 22:09:19 +02002120 }
2121
John Spurlock0b99ea92014-10-01 15:32:22 -04002122 public boolean isDozing() {
2123 return mDozing;
2124 }
2125
Christoph Studer2e731b52014-08-22 16:01:51 +02002126 @Override // NotificationData.Environment
2127 public String getCurrentMediaNotificationKey() {
2128 return mMediaNotificationKey;
2129 }
2130
Jorim Jaggi0e664392014-09-27 01:30:22 +02002131 public boolean isScrimSrcModeEnabled() {
2132 return mScrimSrcModeEnabled;
2133 }
2134
Joe Onorato808182d2010-07-09 18:52:06 -04002135 /**
Christoph Studer2231c6e2014-12-19 12:40:13 +01002136 * To be called when there's a state change in StatusBarKeyguardViewManager.
2137 */
2138 public void onKeyguardViewManagerStatesUpdated() {
2139 logStateToEventlog();
2140 }
2141
2142 @Override // UnlockMethodCache.OnUnlockMethodChangedListener
2143 public void onUnlockMethodStateChanged() {
2144 logStateToEventlog();
2145 }
2146
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002147 @Override
John Spurlockb349af572015-04-29 12:24:19 -04002148 public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
Selim Cinek684a4422015-04-15 16:18:39 -07002149 if (inPinnedMode) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002150 mStatusBarWindowManager.setHeadsUpShowing(true);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002151 mStatusBarWindowManager.setForceStatusBarVisible(true);
Selim Cinek131c1e22015-05-11 19:04:49 -07002152 if (mNotificationPanel.isFullyCollapsed()) {
2153 // We need to ensure that the touchable region is updated before the window will be
2154 // resized, in order to not catch any touches. A layout will ensure that
2155 // onComputeInternalInsets will be called and after that we can resize the layout. Let's
2156 // make sure that the window stays small for one frame until the touchableRegion is set.
2157 mNotificationPanel.requestLayout();
2158 mStatusBarWindowManager.setForceWindowCollapsed(true);
2159 mNotificationPanel.post(new Runnable() {
2160 @Override
2161 public void run() {
2162 mStatusBarWindowManager.setForceWindowCollapsed(false);
2163 }
2164 });
2165 }
Selim Cinek737bff32015-05-08 16:08:35 -07002166 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002167 if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) {
2168 // We are currently tracking or is open and the shade doesn't need to be kept
2169 // open artificially.
Selim Cinek737bff32015-05-08 16:08:35 -07002170 mStatusBarWindowManager.setHeadsUpShowing(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002171 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002172 // we need to keep the panel open artificially, let's wait until the animation
2173 // is finished.
Selim Cinek737bff32015-05-08 16:08:35 -07002174 mHeadsUpManager.setHeadsUpGoingAway(true);
2175 mStackScroller.runAfterAnimationFinished(new Runnable() {
2176 @Override
2177 public void run() {
2178 if (!mHeadsUpManager.hasPinnedHeadsUp()) {
2179 mStatusBarWindowManager.setHeadsUpShowing(false);
2180 mHeadsUpManager.setHeadsUpGoingAway(false);
2181 }
2182 }
2183 });
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002184 }
2185 }
2186 }
2187
2188 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002189 public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
John Spurlockb349af572015-04-29 12:24:19 -04002190 dismissVolumeDialog();
Selim Cinek1f3f5442015-04-10 17:54:46 -07002191 }
2192
2193 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002194 public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
2195 }
2196
2197 @Override
2198 public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002199 if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
2200 removeNotification(entry.key, mLatestRankingMap);
2201 mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
2202 if (mHeadsUpEntriesToRemoveOnSwitch.isEmpty()) {
2203 mLatestRankingMap = null;
2204 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002205 } else {
2206 updateNotificationRanking(null);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002207 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002208
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002209 }
2210
Chris Wrenbdf33762015-12-04 15:50:51 -05002211 protected void updateHeadsUp(String key, Entry entry, boolean shouldPeek,
Selim Cinek29fa89b2015-04-17 10:39:11 -07002212 boolean alertAgain) {
2213 final boolean wasHeadsUp = isHeadsUp(key);
2214 if (wasHeadsUp) {
Chris Wrenbdf33762015-12-04 15:50:51 -05002215 if (!shouldPeek) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002216 // We don't want this to be interrupting anymore, lets remove it
2217 mHeadsUpManager.removeNotification(key);
Selim Cinek684a4422015-04-15 16:18:39 -07002218 } else {
2219 mHeadsUpManager.updateNotification(entry, alertAgain);
Selim Cinek29fa89b2015-04-17 10:39:11 -07002220 }
Chris Wrenbdf33762015-12-04 15:50:51 -05002221 } else if (shouldPeek && alertAgain) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002222 // This notification was updated to be a heads-up, show it!
2223 mHeadsUpManager.showNotification(entry);
2224 }
2225 }
2226
2227 protected void setHeadsUpUser(int newUserId) {
2228 if (mHeadsUpManager != null) {
2229 mHeadsUpManager.setUser(newUserId);
2230 }
2231 }
2232
2233 public boolean isHeadsUp(String key) {
2234 return mHeadsUpManager.isHeadsUp(key);
2235 }
2236
2237 protected boolean isSnoozedPackage(StatusBarNotification sbn) {
2238 return mHeadsUpManager.isSnoozed(sbn.getPackageName());
2239 }
2240
Selim Cineke70d6532015-04-24 16:46:13 -07002241 public boolean isKeyguardCurrentlySecure() {
Selim Cineke8bae622015-07-15 13:24:06 -07002242 return !mUnlockMethodCache.canSkipBouncer();
Selim Cineke70d6532015-04-24 16:46:13 -07002243 }
2244
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002245 public void setPanelExpanded(boolean isExpanded) {
2246 mStatusBarWindowManager.setPanelExpanded(isExpanded);
2247 }
2248
Christoph Studer2231c6e2014-12-19 12:40:13 +01002249 /**
Joe Onorato808182d2010-07-09 18:52:06 -04002250 * All changes to the status bar and notifications funnel through here and are batched.
2251 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07002252 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04002253 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002254 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04002255 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002256 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04002257 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002258 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04002259 case MSG_OPEN_SETTINGS_PANEL:
Jason Monka9927322015-12-13 16:22:37 -05002260 animateExpandSettingsPanel((String) m.obj);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002261 break;
2262 case MSG_CLOSE_PANELS:
2263 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002264 break;
Jorim Jaggi826730a2014-12-08 21:05:13 +01002265 case MSG_LAUNCH_TRANSITION_TIMEOUT:
2266 onLaunchTransitionTimeout();
2267 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04002268 }
2269 }
2270 }
2271
Chris Wren930ecca2014-11-12 17:43:41 -05002272 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002273 public void maybeEscalateHeadsUp() {
Selim Cinek3362c132016-02-11 15:43:03 -08002274 Collection<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getAllEntries();
Selim Cineka59ecc32015-04-07 10:51:49 -07002275 for (HeadsUpManager.HeadsUpEntry entry : entries) {
2276 final StatusBarNotification sbn = entry.entry.notification;
Chris Wrene97f90b2013-08-07 17:39:35 -04002277 final Notification notification = sbn.getNotification();
2278 if (notification.fullScreenIntent != null) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002279 if (DEBUG) {
Chris Wrene97f90b2013-08-07 17:39:35 -04002280 Log.d(TAG, "converting a heads up to fullScreen");
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002281 }
Chris Wrene97f90b2013-08-07 17:39:35 -04002282 try {
Chris Wren223c66b62014-11-10 16:00:09 -05002283 EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
2284 sbn.getKey());
Chris Wrene97f90b2013-08-07 17:39:35 -04002285 notification.fullScreenIntent.send();
Selim Cinekb18a20f2015-06-04 17:08:35 +02002286 entry.entry.notifyFullScreenIntentLaunched();
Chris Wrene97f90b2013-08-07 17:39:35 -04002287 } catch (PendingIntent.CanceledException e) {
2288 }
Joe Onorato808182d2010-07-09 18:52:06 -04002289 }
2290 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002291 mHeadsUpManager.releaseAllImmediately();
Joe Onorato808182d2010-07-09 18:52:06 -04002292 }
2293
John Spurlock97642182013-07-29 17:58:39 -04002294 boolean panelsEnabled() {
Adrian Roos21d2a252015-06-01 13:59:59 -07002295 return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && !ONLY_CORE_APPS;
John Spurlock97642182013-07-29 17:58:39 -04002296 }
2297
Jorim Jaggifa505a72014-04-28 20:04:11 +02002298 void makeExpandedVisible(boolean force) {
John Spurlockcd686b52013-06-05 10:13:46 -04002299 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
Jorim Jaggifa505a72014-04-28 20:04:11 +02002300 if (!force && (mExpandedVisible || !panelsEnabled())) {
Joe Onorato808182d2010-07-09 18:52:06 -04002301 return;
2302 }
Jim Millera073e572012-05-23 17:03:27 -07002303
Joe Onorato808182d2010-07-09 18:52:06 -04002304 mExpandedVisible = true;
John Spurlockd5ef5462012-06-13 11:19:51 -04002305 if (mNavigationBarView != null)
2306 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002307
Daniel Sandlera310af82012-04-24 01:20:13 -04002308 // Expand the window to encompass the full screen in anticipation of the drag.
2309 // 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 -07002310 mStatusBarWindowManager.setPanelVisible(true);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002311
2312 visibilityChanged(true);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07002313 mWaitingForKeyguardExit = false;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002314 disable(mDisabledUnmodified1, mDisabledUnmodified2, !force /* animate */);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002315 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2316 }
2317
Daniel Sandler11cf1782012-09-27 14:03:08 -04002318 public void animateCollapsePanels() {
2319 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07002320 }
2321
John Spurlockaf8d6c42014-05-07 17:49:08 -04002322 private final Runnable mAnimateCollapsePanels = new Runnable() {
2323 @Override
2324 public void run() {
2325 animateCollapsePanels();
2326 }
2327 };
2328
2329 public void postAnimateCollapsePanels() {
2330 mHandler.post(mAnimateCollapsePanels);
2331 }
2332
Jason Monkba2318e2015-12-08 09:04:23 -05002333 public void postAnimateOpenPanels() {
2334 mHandler.sendEmptyMessage(MSG_OPEN_SETTINGS_PANEL);
2335 }
2336
Daniel Sandler11cf1782012-09-27 14:03:08 -04002337 public void animateCollapsePanels(int flags) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002338 animateCollapsePanels(flags, false /* force */, false /* delayed */,
2339 1.0f /* speedUpFactor */);
Jorim Jaggi34250762014-07-03 23:51:19 +02002340 }
2341
2342 public void animateCollapsePanels(int flags, boolean force) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002343 animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002344 }
2345
2346 public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002347 animateCollapsePanels(flags, force, delayed, 1.0f /* speedUpFactor */);
2348 }
2349
2350 public void animateCollapsePanels(int flags, boolean force, boolean delayed,
2351 float speedUpFactor) {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07002352 if (!force && mState != StatusBarState.SHADE) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002353 runPostCollapseRunnables();
Jorim Jaggic1cf1ae2014-05-02 21:19:17 +02002354 return;
2355 }
Joe Onorato808182d2010-07-09 18:52:06 -04002356 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04002357 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04002358 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07002359 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002360 }
2361
Jim Miller9a720f52012-05-30 03:19:43 -07002362 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Winson Chungcdcd4872014-08-05 18:00:13 -07002363 if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
2364 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2365 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
2366 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07002367 }
Jim Miller9a720f52012-05-30 03:19:43 -07002368
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002369 if (mStatusBarWindow != null) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002370 // release focus immediately to kick off focus change transition
2371 mStatusBarWindowManager.setStatusBarFocusable(false);
2372
John Spurlockab847cf2014-01-15 14:13:59 -05002373 mStatusBarWindow.cancelExpandHelper();
Xiaohui Chen9f967112016-01-07 14:14:06 -08002374 mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
John Spurlockab847cf2014-01-15 14:13:59 -05002375 }
Joe Onorato808182d2010-07-09 18:52:06 -04002376 }
2377
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002378 private void runPostCollapseRunnables() {
Selim Cinekae77f8e2015-07-07 18:43:59 -07002379 ArrayList<Runnable> clonedList = new ArrayList<>(mPostCollapseRunnables);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002380 mPostCollapseRunnables.clear();
Selim Cinekae77f8e2015-07-07 18:43:59 -07002381 int size = clonedList.size();
2382 for (int i = 0; i < size; i++) {
2383 clonedList.get(i).run();
2384 }
2385
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002386 }
2387
Daniel Sandler08d05e32012-08-08 16:39:54 -04002388 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002389 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002390 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002391 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04002392 return ;
2393 }
Joe Onorato808182d2010-07-09 18:52:06 -04002394
Oren Blasberg8d3fea12015-07-10 14:21:44 -07002395 mNotificationPanel.expand(true /* animate */);
Joe Onorato808182d2010-07-09 18:52:06 -04002396
2397 if (false) postStartTracing();
2398 }
2399
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002400 @Override
Jason Monka9927322015-12-13 16:22:37 -05002401 public void animateExpandSettingsPanel(String subPanel) {
John Spurlockcd686b52013-06-05 10:13:46 -04002402 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002403 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002404 return;
2405 }
2406
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05002407 // Settings are not available in setup
2408 if (!mUserSetup) return;
2409
Jason Monka9927322015-12-13 16:22:37 -05002410
2411 if (subPanel != null) {
2412 mQSPanel.openDetails(subPanel);
2413 }
Jason Monk3c68ca22015-01-30 11:30:29 -05002414 mNotificationPanel.expandWithQs();
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002415
2416 if (false) postStartTracing();
2417 }
2418
2419 public void animateCollapseQuickSettings() {
Jorim Jaggi449981b2014-10-03 14:24:55 -07002420 if (mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08002421 mStatusBarView.collapsePanel(true, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi449981b2014-10-03 14:24:55 -07002422 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002423 }
2424
Daniel Sandler08d05e32012-08-08 16:39:54 -04002425 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04002426 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04002427 + " mExpandedVisible=" + mExpandedVisible);
2428
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002429 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002430 return;
2431 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002432
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04002433 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
Xiaohui Chen9f967112016-01-07 14:14:06 -08002434 mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002435 1.0f /* speedUpFactor */);
Daniel Sandlered930e52012-07-03 14:31:22 -04002436
Jorim Jaggid7daab72014-05-06 22:22:20 +02002437 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04002438
Joe Onorato808182d2010-07-09 18:52:06 -04002439 mExpandedVisible = false;
John Spurlockd5ef5462012-06-13 11:19:51 -04002440 if (mNavigationBarView != null)
2441 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002442 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04002443
2444 // Shrink the window to the size of the status bar only
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002445 mStatusBarWindowManager.setPanelVisible(false);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002446 mStatusBarWindowManager.setForceStatusBarVisible(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002447
Daniel Sandler469e96e2012-05-04 15:56:19 -04002448 // Close any "App info" popups that might have snuck on-screen
2449 dismissPopups();
2450
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002451 runPostCollapseRunnables();
John Spurlockcfc359a2013-09-05 10:42:03 -04002452 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002453 showBouncer();
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002454 disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
Jorim Jaggi786afcb2014-09-25 02:41:29 +02002455
2456 // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
2457 // the bouncer appear animation.
2458 if (!mStatusBarKeyguardViewManager.isShowing()) {
2459 WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
2460 }
Joe Onorato808182d2010-07-09 18:52:06 -04002461 }
2462
Daniel Sandlerb17a7262012-10-05 14:32:50 -04002463 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05002464 if (DEBUG_GESTURES) {
2465 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
2466 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002467 event.getActionMasked(), (int) event.getX(), (int) event.getY(),
2468 mDisabled1, mDisabled2);
Chris Wren64161cc2012-12-17 16:49:30 -05002469 }
2470
2471 }
2472
Joe Onorato808182d2010-07-09 18:52:06 -04002473 if (SPEW) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002474 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
2475 + mDisabled1 + " mDisabled2=" + mDisabled2 + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002476 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002477 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04002478 Log.d(TAG, String.format(
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002479 "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002480 MotionEvent.actionToString(event.getAction()),
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002481 event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002482 }
Joe Onorato808182d2010-07-09 18:52:06 -04002483 }
2484
Daniel Sandler151f00d2012-10-02 22:33:08 -04002485 if (DEBUG_GESTURES) {
2486 mGestureRec.add(event);
2487 }
Daniel Sandler33805342012-07-23 15:45:12 -04002488
John Spurlock686820a2013-09-03 14:44:16 -04002489 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04002490 final boolean upOrCancel =
2491 event.getAction() == MotionEvent.ACTION_UP ||
2492 event.getAction() == MotionEvent.ACTION_CANCEL;
2493 if (upOrCancel && !mExpandedVisible) {
2494 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
2495 } else {
2496 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2497 }
John Spurlock686820a2013-09-03 14:44:16 -04002498 }
Joe Onorato808182d2010-07-09 18:52:06 -04002499 return false;
2500 }
2501
Daniel Sandler08d05e32012-08-08 16:39:54 -04002502 public GestureRecorder getGestureRecorder() {
2503 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07002504 }
2505
John Spurlock56d007b2013-10-28 18:40:56 -04002506 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04002507 if (hints == mNavigationIconHints) return;
2508
2509 mNavigationIconHints = hints;
2510
2511 if (mNavigationBarView != null) {
2512 mNavigationBarView.setNavigationIconHints(hints);
2513 }
John Spurlockd4e65752013-08-28 14:17:09 -04002514 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04002515 }
2516
2517 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04002518 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04002519 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04002520 if (mStatusBarWindow != null
2521 && window == StatusBarManager.WINDOW_STATUS_BAR
2522 && mStatusBarWindowState != state) {
2523 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002524 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
Jorim Jaggi449981b2014-10-03 14:24:55 -07002525 if (!showing && mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08002526 mStatusBarView.collapsePanel(false /* animate */, false /* delayed */,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002527 1.0f /* speedUpFactor */);
John Spurlock97642182013-07-29 17:58:39 -04002528 }
2529 }
2530 if (mNavigationBarView != null
2531 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
2532 && mNavigationBarWindowState != state) {
2533 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002534 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04002535 }
2536 }
2537
John Spurlock97642182013-07-29 17:58:39 -04002538 @Override // CommandQueue
John Spurlockcad57682014-07-26 17:09:56 -04002539 public void buzzBeepBlinked() {
2540 if (mDozeServiceHost != null) {
2541 mDozeServiceHost.fireBuzzBeepBlinked();
2542 }
2543 }
2544
John Spurlockcb566aa2014-08-03 22:58:28 -04002545 @Override
2546 public void notificationLightOff() {
2547 if (mDozeServiceHost != null) {
2548 mDozeServiceHost.fireNotificationLight(false);
2549 }
2550 }
2551
2552 @Override
2553 public void notificationLightPulse(int argb, int onMillis, int offMillis) {
2554 if (mDozeServiceHost != null) {
2555 mDozeServiceHost.fireNotificationLight(true);
2556 }
2557 }
2558
John Spurlockcad57682014-07-26 17:09:56 -04002559 @Override // CommandQueue
Jorim Jaggi86905582016-02-09 21:36:09 -08002560 public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
2561 int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002562 final int oldVal = mSystemUiVisibility;
2563 final int newVal = (oldVal&~mask) | (vis&mask);
2564 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04002565 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04002566 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
2567 Integer.toHexString(vis), Integer.toHexString(mask),
2568 Integer.toHexString(oldVal), Integer.toHexString(newVal),
2569 Integer.toHexString(diff)));
Jorim Jaggi86905582016-02-09 21:36:09 -08002570 boolean sbModeChanged = false;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002571 if (diff != 0) {
Winson Chung9214eff2014-06-12 13:59:25 -07002572 // we never set the recents bit via this method, so save the prior state to prevent
2573 // clobbering the bit below
2574 final boolean wasRecentsVisible = (mSystemUiVisibility & View.RECENT_APPS_VISIBLE) > 0;
2575
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002576 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04002577
John Spurlocke1f366f2013-08-05 12:22:40 -04002578 // update low profile
2579 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
2580 final boolean lightsOut = (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002581 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002582 animateCollapsePanels();
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002583 }
Jim Millera073e572012-05-23 17:03:27 -07002584
John Spurlock7edfbca2013-09-14 11:58:55 -04002585 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04002586 }
2587
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002588 // ready to unhide
2589 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
2590 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
2591 mNoAnimationOnNextBarModeChange = true;
2592 }
2593
John Spurlocke1f366f2013-08-05 12:22:40 -04002594 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002595 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002596 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT,
2597 View.STATUS_BAR_TRANSPARENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04002598
2599 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002600 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04002601 oldVal, newVal, mNavigationBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002602 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
2603 View.NAVIGATION_BAR_TRANSPARENT);
Jorim Jaggi86905582016-02-09 21:36:09 -08002604 sbModeChanged = sbMode != -1;
John Spurlockd4e65752013-08-28 14:17:09 -04002605 final boolean nbModeChanged = nbMode != -1;
2606 boolean checkBarModes = false;
2607 if (sbModeChanged && sbMode != mStatusBarMode) {
2608 mStatusBarMode = sbMode;
2609 checkBarModes = true;
2610 }
2611 if (nbModeChanged && nbMode != mNavigationBarMode) {
2612 mNavigationBarMode = nbMode;
2613 checkBarModes = true;
2614 }
2615 if (checkBarModes) {
2616 checkBarModes();
2617 }
2618 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002619 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05002620 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04002621 scheduleAutohide();
2622 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04002623 cancelAutohide();
2624 }
2625 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002626
John Spurlock5b9145b2013-08-20 15:13:47 -04002627 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
2628 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
2629 }
2630
Winson Chung9214eff2014-06-12 13:59:25 -07002631 // restore the recents bit
2632 if (wasRecentsVisible) {
2633 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
2634 }
2635
John Spurlocke1f366f2013-08-05 12:22:40 -04002636 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04002637 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04002638 }
Jorim Jaggi86905582016-02-09 21:36:09 -08002639
2640 mLightStatusBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,
2641 mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002642 }
2643
John Spurlockd4e65752013-08-28 14:17:09 -04002644 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002645 int transientFlag, int translucentFlag, int transparentFlag) {
2646 final int oldMode = barMode(oldVis, transientFlag, translucentFlag, transparentFlag);
2647 final int newMode = barMode(newVis, transientFlag, translucentFlag, transparentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04002648 if (oldMode == newMode) {
2649 return -1; // no mode change
2650 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002651 return newMode;
2652 }
2653
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002654 private int barMode(int vis, int transientFlag, int translucentFlag, int transparentFlag) {
2655 int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | transparentFlag;
John Spurlock89835dd2013-08-16 15:06:51 -04002656 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04002657 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
Adrian Roosc0f0a742014-10-28 16:39:56 +01002658 : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002659 : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
John Spurlock7edfbca2013-09-14 11:58:55 -04002660 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04002661 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04002662 }
2663
John Spurlockd4e65752013-08-28 14:17:09 -04002664 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04002665 if (mDemoMode) return;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002666 checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions(),
2667 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04002668 if (mNavigationBarView != null) {
2669 checkBarMode(mNavigationBarMode,
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002670 mNavigationBarWindowState, mNavigationBarView.getBarTransitions(),
2671 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04002672 }
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002673 mNoAnimationOnNextBarModeChange = false;
John Spurlockd4e65752013-08-28 14:17:09 -04002674 }
2675
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002676 private void checkBarMode(int mode, int windowState, BarTransitions transitions,
2677 boolean noAnimation) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002678 final boolean powerSave = mBatteryController.isPowerSave();
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07002679 final boolean anim = !noAnimation && mDeviceInteractive
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002680 && windowState != WINDOW_STATE_HIDDEN && !powerSave;
John Spurlock1bb480a2014-08-02 17:12:43 -04002681 if (powerSave && getBarState() == StatusBarState.SHADE) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002682 mode = MODE_WARNING;
2683 }
John Spurlockc68d5772013-10-08 11:47:58 -04002684 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04002685 }
2686
John Spurlock42197262013-10-21 09:32:25 -04002687 private void finishBarAnimations() {
2688 mStatusBarView.getBarTransitions().finishAnimations();
2689 if (mNavigationBarView != null) {
2690 mNavigationBarView.getBarTransitions().finishAnimations();
2691 }
2692 }
2693
John Spurlockd4e65752013-08-28 14:17:09 -04002694 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04002695 @Override
2696 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04002697 checkBarModes();
John Spurlock0ff62e02014-07-22 16:15:08 -04002698 }
2699 };
John Spurlock5b9145b2013-08-20 15:13:47 -04002700
John Spurlockad3e6cb2013-04-30 08:47:43 -04002701 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04002702 public void setInteracting(int barWindow, boolean interacting) {
John Spurlock7fbf5732014-11-18 11:40:22 -05002703 final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
John Spurlockcfc359a2013-09-05 10:42:03 -04002704 mInteractingWindows = interacting
2705 ? (mInteractingWindows | barWindow)
2706 : (mInteractingWindows & ~barWindow);
2707 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04002708 suspendAutohide();
2709 } else {
2710 resumeSuspendedAutohide();
2711 }
John Spurlock7fbf5732014-11-18 11:40:22 -05002712 // manually dismiss the volume panel when interacting with the nav bar
2713 if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
John Spurlockb349af572015-04-29 12:24:19 -04002714 dismissVolumeDialog();
John Spurlock7fbf5732014-11-18 11:40:22 -05002715 }
John Spurlockd4e65752013-08-28 14:17:09 -04002716 checkBarModes();
2717 }
2718
John Spurlockb349af572015-04-29 12:24:19 -04002719 private void dismissVolumeDialog() {
2720 if (mVolumeComponent != null) {
2721 mVolumeComponent.dismissNow();
2722 }
2723 }
2724
John Spurlockd4e65752013-08-28 14:17:09 -04002725 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04002726 if (mAutohideSuspended) {
2727 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04002728 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04002729 }
2730 }
2731
John Spurlockd4e65752013-08-28 14:17:09 -04002732 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04002733 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04002734 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04002735 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04002736 }
2737
2738 private void cancelAutohide() {
2739 mAutohideSuspended = false;
2740 mHandler.removeCallbacks(mAutohide);
2741 }
2742
2743 private void scheduleAutohide() {
2744 cancelAutohide();
2745 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
2746 }
2747
John Spurlock9deaa282013-07-25 13:03:47 -04002748 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002749 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04002750 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
2751 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
2752 ) {
2753 userAutohide();
2754 }
2755 }
2756
2757 private void userAutohide() {
2758 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04002759 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04002760 }
2761
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002762 private boolean areLightsOn() {
2763 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
2764 }
Jim Millera073e572012-05-23 17:03:27 -07002765
Daniel Sandler60ee2562011-07-22 12:34:33 -04002766 public void setLightsOn(boolean on) {
2767 Log.v(TAG, "setLightsOn(" + on + ")");
2768 if (on) {
Jorim Jaggi86905582016-02-09 21:36:09 -08002769 setSystemUiVisibility(0, 0, 0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
2770 mLastFullscreenStackBounds, mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002771 } else {
Jorim Jaggi86905582016-02-09 21:36:09 -08002772 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, 0, 0,
2773 View.SYSTEM_UI_FLAG_LOW_PROFILE, mLastFullscreenStackBounds,
2774 mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002775 }
2776 }
2777
John Spurlock32beb2c2013-03-11 10:16:47 -04002778 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002779 try {
Adrian Roos389beec2015-05-12 13:33:25 -07002780 if (mLastDispatchedSystemUiVisibility != vis) {
2781 mWindowManagerService.statusBarVisibilityChanged(vis);
2782 mLastDispatchedSystemUiVisibility = vis;
2783 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002784 } catch (RemoteException ex) {
2785 }
Joe Onorato93056472010-09-10 10:30:46 -04002786 }
2787
Daniel Sandler5c8da942011-06-28 00:29:04 -04002788 public void topAppWindowChanged(boolean showMenu) {
2789 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002790 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04002791 }
2792 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04002793 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04002794 }
2795
2796 // See above re: lights-out policy for legacy apps.
2797 if (showMenu) setLightsOn(true);
2798 }
2799
Daniel Sandler328310c2011-09-23 15:56:52 -04002800 @Override
Jason Monkb605fec2014-05-02 17:04:10 -04002801 public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
2802 boolean showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002803 boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
2804 int flags = mNavigationIconHints;
2805 if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
2806 flags |= NAVIGATION_HINT_BACK_ALT;
2807 } else {
2808 flags &= ~NAVIGATION_HINT_BACK_ALT;
2809 }
Jason Monkb605fec2014-05-02 17:04:10 -04002810 if (showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002811 flags |= NAVIGATION_HINT_IME_SHOWN;
2812 } else {
2813 flags &= ~NAVIGATION_HINT_IME_SHOWN;
2814 }
Daniel Sandler328310c2011-09-23 15:56:52 -04002815
Jason Monkf1ff2092014-04-29 16:50:53 -04002816 setNavigationIconHints(flags);
Daniel Sandler328310c2011-09-23 15:56:52 -04002817 }
2818
Daniel Sandler48852952011-12-01 14:34:23 -05002819 public static String viewInfo(View v) {
2820 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
2821 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04002822 }
2823
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002824 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04002825 synchronized (mQueueLock) {
2826 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002827 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04002828 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04002829 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04002830 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002831 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002832 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
2833 + " scroll " + mStackScroller.getScrollX()
2834 + "," + mStackScroller.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04002835 }
Joe Onorato808182d2010-07-09 18:52:06 -04002836
John Spurlockcfc359a2013-09-05 10:42:03 -04002837 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04002838 pw.print(" mStatusBarWindowState=");
2839 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002840 pw.print(" mStatusBarMode=");
2841 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlockbf370992014-06-17 13:58:31 -04002842 pw.print(" mDozing="); pw.println(mDozing);
John Spurlocke677d712014-02-13 12:52:19 -05002843 pw.print(" mZenMode=");
2844 pw.println(Settings.Global.zenModeToString(mZenMode));
Chris Wren3b6745b2014-03-07 14:34:35 -05002845 pw.print(" mUseHeadsUp=");
2846 pw.println(mUseHeadsUp);
John Spurlock0ec64c62013-08-26 15:37:58 -04002847 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
2848 if (mNavigationBarView != null) {
2849 pw.print(" mNavigationBarWindowState=");
2850 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002851 pw.print(" mNavigationBarMode=");
2852 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002853 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
2854 }
2855
Daniel Sandler48852952011-12-01 14:34:23 -05002856 pw.print(" mNavigationBarView=");
2857 if (mNavigationBarView == null) {
2858 pw.println("null");
2859 } else {
2860 mNavigationBarView.dump(fd, pw, args);
2861 }
2862
Dan Sandler16128f42014-05-21 12:48:22 -04002863 pw.print(" mMediaSessionManager=");
2864 pw.println(mMediaSessionManager);
2865 pw.print(" mMediaNotificationKey=");
2866 pw.println(mMediaNotificationKey);
2867 pw.print(" mMediaController=");
2868 pw.print(mMediaController);
2869 if (mMediaController != null) {
2870 pw.print(" state=" + mMediaController.getPlaybackState());
2871 }
2872 pw.println();
2873 pw.print(" mMediaMetadata=");
2874 pw.print(mMediaMetadata);
2875 if (mMediaMetadata != null) {
RoboErik75847b92014-07-29 13:10:17 -07002876 pw.print(" title=" + mMediaMetadata.getText(MediaMetadata.METADATA_KEY_TITLE));
Dan Sandler16128f42014-05-21 12:48:22 -04002877 }
2878 pw.println();
2879
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002880 pw.println(" Panels: ");
2881 if (mNotificationPanel != null) {
2882 pw.println(" mNotificationPanel=" +
2883 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
2884 pw.print (" ");
2885 mNotificationPanel.dump(fd, pw, args);
2886 }
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002887
John Spurlock813552c2014-09-19 08:30:21 -04002888 DozeLog.dump(pw);
2889
Daniel Sandler7579bca2011-08-18 15:47:26 -04002890 if (DUMPTRUCK) {
2891 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002892 mNotificationData.dump(pw, " ");
Daniel Sandler7579bca2011-08-18 15:47:26 -04002893 }
2894
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002895 mIconController.dump(pw);
Jim Miller5e6af442011-12-02 18:24:26 -08002896
Daniel Sandler89d97132011-09-08 15:31:57 -04002897 if (false) {
2898 pw.println("see the logcat for a dump of the views we have created.");
2899 // must happen on ui thread
2900 mHandler.post(new Runnable() {
2901 public void run() {
2902 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04002903 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04002904 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002905 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002906 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002907 }
2908 });
2909 }
Joe Onorato808182d2010-07-09 18:52:06 -04002910 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002911
Daniel Sandler151f00d2012-10-02 22:33:08 -04002912 if (DEBUG_GESTURES) {
2913 pw.print(" status bar gestures: ");
2914 mGestureRec.dump(fd, pw, args);
2915 }
Selim Cinek7025f262015-07-13 16:22:48 -07002916 if (mStatusBarWindowManager != null) {
2917 mStatusBarWindowManager.dump(fd, pw, args);
2918 }
John Spurlock486b78e2014-07-07 08:37:56 -04002919 if (mNetworkController != null) {
2920 mNetworkController.dump(fd, pw, args);
2921 }
2922 if (mBluetoothController != null) {
2923 mBluetoothController.dump(fd, pw, args);
2924 }
Jason Monkdd5bdc62015-07-20 12:18:38 -04002925 if (mHotspotController != null) {
2926 mHotspotController.dump(fd, pw, args);
2927 }
John Spurlock1e6eb172014-07-13 11:59:50 -04002928 if (mCastController != null) {
2929 mCastController.dump(fd, pw, args);
2930 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +02002931 if (mUserSwitcherController != null) {
2932 mUserSwitcherController.dump(fd, pw, args);
2933 }
John Spurlock0ff62e02014-07-22 16:15:08 -04002934 if (mBatteryController != null) {
2935 mBatteryController.dump(fd, pw, args);
2936 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02002937 if (mNextAlarmController != null) {
2938 mNextAlarmController.dump(fd, pw, args);
2939 }
Jason Monk3d5f5512014-07-25 11:17:28 -04002940 if (mSecurityController != null) {
2941 mSecurityController.dump(fd, pw, args);
2942 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002943 if (mHeadsUpManager != null) {
2944 mHeadsUpManager.dump(fd, pw, args);
Chris Wren428c6b62014-12-05 16:07:06 -05002945 } else {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002946 pw.println(" mHeadsUpManager: null");
Chris Wren428c6b62014-12-05 16:07:06 -05002947 }
Jason Monkab525272015-07-13 17:02:49 -04002948 if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
2949 KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
2950 }
Chris Wren428c6b62014-12-05 16:07:06 -05002951
John Spurlock7bbb9f62014-10-21 12:15:28 -04002952 pw.println("SharedPreferences:");
Andrew Flynn82862572015-04-01 14:22:37 -04002953 for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
John Spurlock7bbb9f62014-10-21 12:15:28 -04002954 pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
2955 }
Joe Onorato808182d2010-07-09 18:52:06 -04002956 }
2957
Chris Wren3b6745b2014-03-07 14:34:35 -05002958 private String hunStateToString(Entry entry) {
2959 if (entry == null) return "null";
2960 if (entry.notification == null) return "corrupt";
2961 return entry.notification.getPackageName();
2962 }
2963
John Spurlock0ec64c62013-08-26 15:37:58 -04002964 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
2965 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
2966 pw.println(BarTransitions.modeToString(transitions.getMode()));
2967 }
2968
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002969 @Override
2970 public void createAndAddWindows() {
2971 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04002972 }
Jim Millere898ac52012-04-06 17:10:57 -07002973
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05002974 private void addStatusBarWindow() {
Daniel Sandlera310af82012-04-24 01:20:13 -04002975 makeStatusBarView();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002976 mStatusBarWindowManager = new StatusBarWindowManager(mContext);
Adrian Roos1c0ca502015-10-07 12:20:42 -07002977 mRemoteInputController = new RemoteInputController(mStatusBarWindowManager,
2978 mHeadsUpManager);
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002979 mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
Joe Onorato808182d2010-07-09 18:52:06 -04002980 }
2981
Daniel Sandler747a9e92012-08-10 16:39:19 -04002982 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002983 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04002984 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04002985 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04002986 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04002987 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04002988 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
2989 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07002990 }
2991
Christoph Studerb0183992014-12-22 21:02:26 +01002992 float getDisplayDensity() {
2993 return mDisplayMetrics.density;
2994 }
2995
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002996 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
Jorim Jaggid9449862015-05-29 14:49:08 -07002997 boolean dismissShade) {
2998 startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, null /* callback */);
2999 }
3000
3001 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
3002 final boolean dismissShade, final Callback callback) {
Daniel Sandler3679bf52012-10-16 21:30:28 -04003003 if (onlyProvisioned && !isDeviceProvisioned()) return;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003004
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003005 final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
3006 mContext, intent, mCurrentUserId);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02003007 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Selim Cineke70d6532015-04-24 16:46:13 -07003008 Runnable runnable = new Runnable() {
3009 public void run() {
Jorim Jaggib835dd72015-06-08 12:28:42 -07003010 mAssistManager.hideAssist();
Selim Cineke70d6532015-04-24 16:46:13 -07003011 intent.setFlags(
3012 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Jorim Jaggid9449862015-05-29 14:49:08 -07003013 int result = ActivityManager.START_CANCELED;
3014 try {
3015 result = ActivityManagerNative.getDefault().startActivityAsUser(
3016 null, mContext.getBasePackageName(),
3017 intent,
3018 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3019 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
3020 UserHandle.CURRENT.getIdentifier());
3021 } catch (RemoteException e) {
3022 Log.w(TAG, "Unable to start activity", e);
3023 }
Selim Cineke70d6532015-04-24 16:46:13 -07003024 overrideActivityPendingAppTransition(
3025 keyguardShowing && !afterKeyguardGone);
Jorim Jaggid9449862015-05-29 14:49:08 -07003026 if (callback != null) {
3027 callback.onActivityStarted(result);
3028 }
Selim Cineke70d6532015-04-24 16:46:13 -07003029 }
3030 };
Jorim Jaggid9449862015-05-29 14:49:08 -07003031 Runnable cancelRunnable = new Runnable() {
3032 @Override
3033 public void run() {
Jorim Jaggi5cc86592015-06-08 14:48:28 -07003034 if (callback != null) {
3035 callback.onActivityStarted(ActivityManager.START_CANCELED);
3036 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003037 }
3038 };
Jorim Jaggib835dd72015-06-08 12:28:42 -07003039 executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShade,
3040 afterKeyguardGone);
Selim Cineke70d6532015-04-24 16:46:13 -07003041 }
3042
3043 public void executeRunnableDismissingKeyguard(final Runnable runnable,
Jorim Jaggid9449862015-05-29 14:49:08 -07003044 final Runnable cancelAction,
Selim Cineke70d6532015-04-24 16:46:13 -07003045 final boolean dismissShade,
3046 final boolean afterKeyguardGone) {
3047 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Adrian Roos4314f6d2014-05-28 14:10:27 +02003048 dismissKeyguardThenExecute(new OnDismissAction() {
3049 @Override
3050 public boolean onDismiss() {
Selim Cinekbaa23272014-07-08 18:01:07 +02003051 AsyncTask.execute(new Runnable() {
3052 public void run() {
3053 try {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003054 if (keyguardShowing && !afterKeyguardGone) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003055 ActivityManagerNative.getDefault()
3056 .keyguardWaitingForActivityDrawn();
3057 }
Selim Cineke70d6532015-04-24 16:46:13 -07003058 if (runnable != null) {
3059 runnable.run();
3060 }
Selim Cinekbaa23272014-07-08 18:01:07 +02003061 } catch (RemoteException e) {
3062 }
3063 }
3064 });
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003065 if (dismissShade) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07003066 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
3067 true /* delayed*/);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003068 }
3069 return true;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003070 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003071 }, cancelAction, afterKeyguardGone);
Daniel Sandler3679bf52012-10-16 21:30:28 -04003072 }
3073
Joe Onorato808182d2010-07-09 18:52:06 -04003074 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
3075 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04003076 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04003077 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04003078 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Andrei Stingaceanu9d9294c2015-08-24 17:19:06 +01003079 getKeyboardShortcuts().dismissKeyboardShortcutsDialog();
Kenny Guy44fc65f2014-11-28 22:18:14 +00003080 if (isCurrentProfile(getSendingUserId())) {
3081 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
3082 String reason = intent.getStringExtra("reason");
3083 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
3084 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
3085 }
3086 animateCollapsePanels(flags);
Michael Jurka3b1fc472011-06-13 10:54:40 -07003087 }
Joe Onorato808182d2010-07-09 18:52:06 -04003088 }
Daniel Sandlered930e52012-07-03 14:31:22 -04003089 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003090 notifyNavigationBarScreenOn(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003091 notifyHeadsUpScreenOff();
John Spurlock42197262013-10-21 09:32:25 -04003092 finishBarAnimations();
Selim Cinekccd14fb2014-08-12 18:53:24 +02003093 resetUserExpandedStates();
Daniel Sandlered930e52012-07-03 14:31:22 -04003094 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04003095 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003096 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04003097 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003098 }
3099 };
3100
3101 private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
3102 public void onReceive(Context context, Intent intent) {
3103 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
3104 String action = intent.getAction();
3105 if (ACTION_DEMO.equals(action)) {
John Spurlock3c875662013-08-31 15:07:25 -04003106 Bundle bundle = intent.getExtras();
3107 if (bundle != null) {
3108 String command = bundle.getString("command", "").trim().toLowerCase();
3109 if (command.length() > 0) {
3110 try {
3111 dispatchDemoCommand(command, bundle);
3112 } catch (Throwable t) {
3113 Log.w(TAG, "Error running demo command, intent=" + intent, t);
3114 }
3115 }
3116 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003117 } else if (ACTION_FAKE_ARTWORK.equals(action)) {
Dan Sandler16128f42014-05-21 12:48:22 -04003118 if (DEBUG_MEDIA_FAKE_ARTWORK) {
Adrian Roos52738322016-01-29 08:49:21 -08003119 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -04003120 }
John Spurlock3c875662013-08-31 15:07:25 -04003121 }
Joe Onorato808182d2010-07-09 18:52:06 -04003122 }
3123 };
3124
Selim Cinekccd14fb2014-08-12 18:53:24 +02003125 private void resetUserExpandedStates() {
3126 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
3127 final int notificationCount = activeNotifications.size();
3128 for (int i = 0; i < notificationCount; i++) {
3129 NotificationData.Entry entry = activeNotifications.get(i);
3130 if (entry.row != null) {
3131 entry.row.resetUserExpansion();
3132 }
3133 }
3134 }
3135
Adrian Roos7d7090d2014-05-21 13:10:23 +02003136 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07003137 protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
3138 dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
3139 }
3140
Jason Monkabe19742015-09-29 09:47:06 -04003141 public void dismissKeyguard() {
3142 mStatusBarKeyguardViewManager.dismiss();
3143 }
3144
Jorim Jaggid9449862015-05-29 14:49:08 -07003145 private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003146 boolean afterKeyguardGone) {
Adrian Roos7d7090d2014-05-21 13:10:23 +02003147 if (mStatusBarKeyguardViewManager.isShowing()) {
Jorim Jaggid9449862015-05-29 14:49:08 -07003148 mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
3149 afterKeyguardGone);
Adrian Roos7d7090d2014-05-21 13:10:23 +02003150 } else {
3151 action.onDismiss();
3152 }
3153 }
3154
Daniel Sandler777dcde2013-09-30 10:21:45 -04003155 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
3156 @Override
3157 protected void onConfigurationChanged(Configuration newConfig) {
3158 super.onConfigurationChanged(newConfig); // calls refreshLayout
3159
3160 if (DEBUG) {
3161 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
3162 }
Daniel Sandler7e8ae502013-10-10 23:38:19 -04003163 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04003164
3165 updateResources();
3166 repositionNavigationBar();
Jorim Jaggif6411742014-08-05 17:10:43 +00003167 updateRowStates();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003168 mIconController.updateResources();
Jason Monk18f99d92014-09-11 13:36:42 -04003169 mScreenPinningRequest.onConfigurationChanged();
Jason Monk1c040db2015-07-20 09:45:54 -04003170 mNetworkController.onConfigurationChanged();
Daniel Sandler777dcde2013-09-30 10:21:45 -04003171 }
3172
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003173 @Override
3174 public void userSwitched(int newUserId) {
Chris Wrena6d4fb62014-11-20 14:46:23 -05003175 super.userSwitched(newUserId);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003176 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04003177 animateCollapsePanels();
Adrian Roos31b844b2014-11-21 13:55:09 +01003178 updatePublicMode();
Christoph Studer37fe6932014-05-26 13:10:30 +02003179 updateNotifications();
John Spurlock919adac2012-10-02 16:41:12 -04003180 resetUserSetupObserver();
John Spurlock89f060a2014-07-16 21:03:15 -04003181 setControllerUsers();
Julia Reynolds86ef8e22015-09-09 16:42:38 -04003182 clearCurrentMediaNotification();
Vadim Tryshev12a30e82016-02-12 15:39:28 -08003183 mLockscreenWallpaper.setCurrentUser(newUserId);
Adrian Roos52738322016-01-29 08:49:21 -08003184 updateMediaMetaData(true, false);
John Spurlock89f060a2014-07-16 21:03:15 -04003185 }
3186
3187 private void setControllerUsers() {
3188 if (mZenModeController != null) {
3189 mZenModeController.setUserId(mCurrentUserId);
3190 }
Robin Lee63204ee2015-06-04 01:53:01 +01003191 if (mSecurityController != null) {
3192 mSecurityController.onUserSwitched(mCurrentUserId);
3193 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003194 }
John Spurlock919adac2012-10-02 16:41:12 -04003195
3196 private void resetUserSetupObserver() {
3197 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
3198 mUserSetupObserver.onChange(false);
3199 mContext.getContentResolver().registerContentObserver(
3200 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003201 mUserSetupObserver, mCurrentUserId);
John Spurlock919adac2012-10-02 16:41:12 -04003202 }
3203
Joe Onorato808182d2010-07-09 18:52:06 -04003204 /**
3205 * Reload some of our resources when the configuration changes.
3206 *
3207 * We don't reload everything when the configuration changes -- we probably
3208 * should, but getting that smooth is tough. Someday we'll fix that. In the
3209 * meantime, just update the things that we know change.
3210 */
3211 void updateResources() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003212 // Update the quick setting tiles
John Spurlock7e6809a2014-08-06 16:03:14 -04003213 if (mQSPanel != null) {
3214 mQSPanel.updateResources();
3215 }
Winson Chungd63c59782012-09-05 17:34:41 -07003216
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003217 loadDimens();
John Spurlock7e6809a2014-08-06 16:03:14 -04003218
3219 if (mNotificationPanel != null) {
3220 mNotificationPanel.updateResources();
3221 }
Adrian Roos5fd872e2014-08-12 17:28:58 +02003222 if (mBrightnessMirrorController != null) {
3223 mBrightnessMirrorController.updateResources();
3224 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003225 }
Jim Miller5e6af442011-12-02 18:24:26 -08003226
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003227 protected void loadDimens() {
3228 final Resources res = mContext.getResources();
3229
3230 mNaturalBarHeight = res.getDimensionPixelSize(
3231 com.android.internal.R.dimen.status_bar_height);
3232
Selim Cinek5f71bee2015-11-18 10:25:23 -08003233 mMaxAllowedKeyguardNotifications = res.getInteger(R.integer.keyguard_max_notification_count);
Jorim Jaggid4a57442014-04-10 02:45:55 +02003234
John Spurlock7e6809a2014-08-06 16:03:14 -04003235 if (DEBUG) Log.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04003236 }
3237
Christoph Studer92b389d2014-04-01 18:44:40 +02003238 // Visibility reporting
3239
3240 @Override
Christoph Studere8e28652014-10-29 17:27:53 +01003241 protected void handleVisibleToUserChanged(boolean visibleToUser) {
3242 if (visibleToUser) {
3243 super.handleVisibleToUserChanged(visibleToUser);
3244 startNotificationLogging();
Christoph Studer92b389d2014-04-01 18:44:40 +02003245 } else {
Christoph Studer037e34c2014-04-30 20:06:04 +02003246 stopNotificationLogging();
Christoph Studere8e28652014-10-29 17:27:53 +01003247 super.handleVisibleToUserChanged(visibleToUser);
Christoph Studer92b389d2014-04-01 18:44:40 +02003248 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003249 }
3250
Christoph Studer037e34c2014-04-30 20:06:04 +02003251 private void stopNotificationLogging() {
3252 // Report all notifications as invisible and turn down the
3253 // reporter.
3254 if (!mCurrentlyVisibleNotifications.isEmpty()) {
Chris Wrend1dbc922015-06-19 17:51:16 -04003255 logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(),
3256 mCurrentlyVisibleNotifications);
3257 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer037e34c2014-04-30 20:06:04 +02003258 }
3259 mHandler.removeCallbacks(mVisibilityReporter);
3260 mStackScroller.setChildLocationsChangedListener(null);
3261 }
3262
Christoph Studere8e28652014-10-29 17:27:53 +01003263 private void startNotificationLogging() {
3264 mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
3265 // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
3266 // cause the scroller to emit child location events. Hence generate
3267 // one ourselves to guarantee that we're reporting visible
3268 // notifications.
3269 // (Note that in cases where the scroller does emit events, this
3270 // additional event doesn't break anything.)
3271 mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
Christoph Studer037e34c2014-04-30 20:06:04 +02003272 }
3273
Christoph Studer92b389d2014-04-01 18:44:40 +02003274 private void logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -04003275 Collection<NotificationVisibility> newlyVisible,
3276 Collection<NotificationVisibility> noLongerVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +02003277 if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
3278 return;
3279 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003280 NotificationVisibility[] newlyVisibleAr =
3281 newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]);
3282 NotificationVisibility[] noLongerVisibleAr =
3283 noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]);
Christoph Studer92b389d2014-04-01 18:44:40 +02003284 try {
3285 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
3286 } catch (RemoteException e) {
3287 // Ignore.
3288 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003289
3290 final int N = newlyVisible.size();
Amith Yamasani76495672015-07-07 15:22:54 -07003291 if (N > 0) {
3292 String[] newlyVisibleKeyAr = new String[N];
3293 for (int i = 0; i < N; i++) {
3294 newlyVisibleKeyAr[i] = newlyVisibleAr[i].key;
3295 }
3296
3297 setNotificationsShown(newlyVisibleKeyAr);
Chris Wrend1dbc922015-06-19 17:51:16 -04003298 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003299 }
3300
Christoph Studer2231c6e2014-12-19 12:40:13 +01003301 // State logging
3302
3303 private void logStateToEventlog() {
3304 boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
3305 boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
3306 boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
3307 boolean isSecure = mUnlockMethodCache.isMethodSecure();
Selim Cineke8bae622015-07-15 13:24:06 -07003308 boolean canSkipBouncer = mUnlockMethodCache.canSkipBouncer();
Christoph Studer2231c6e2014-12-19 12:40:13 +01003309 int stateFingerprint = getLoggingFingerprint(mState,
3310 isShowing,
3311 isOccluded,
3312 isBouncerShowing,
3313 isSecure,
Selim Cineke8bae622015-07-15 13:24:06 -07003314 canSkipBouncer);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003315 if (stateFingerprint != mLastLoggedStateFingerprint) {
3316 EventLogTags.writeSysuiStatusBarState(mState,
3317 isShowing ? 1 : 0,
3318 isOccluded ? 1 : 0,
3319 isBouncerShowing ? 1 : 0,
3320 isSecure ? 1 : 0,
Selim Cineke8bae622015-07-15 13:24:06 -07003321 canSkipBouncer ? 1 : 0);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003322 mLastLoggedStateFingerprint = stateFingerprint;
3323 }
3324 }
3325
3326 /**
3327 * Returns a fingerprint of fields logged to eventlog
3328 */
3329 private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
3330 boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
3331 boolean currentlyInsecure) {
3332 // Reserve 8 bits for statusBarState. We'll never go higher than
3333 // that, right? Riiiight.
3334 return (statusBarState & 0xFF)
3335 | ((keyguardShowing ? 1 : 0) << 8)
3336 | ((keyguardOccluded ? 1 : 0) << 9)
3337 | ((bouncerShowing ? 1 : 0) << 10)
3338 | ((secure ? 1 : 0) << 11)
3339 | ((currentlyInsecure ? 1 : 0) << 12);
3340 }
3341
Joe Onorato808182d2010-07-09 18:52:06 -04003342 //
3343 // tracing
3344 //
3345
3346 void postStartTracing() {
3347 mHandler.postDelayed(mStartTracing, 3000);
3348 }
3349
3350 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04003351 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
3352 Context.VIBRATOR_SERVICE);
John Spurlock7b414672014-07-18 13:02:39 -04003353 vib.vibrate(250, VIBRATION_ATTRIBUTES);
Joe Onorato808182d2010-07-09 18:52:06 -04003354 }
3355
3356 Runnable mStartTracing = new Runnable() {
3357 public void run() {
3358 vibrate();
3359 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04003360 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003361 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
3362 mHandler.postDelayed(mStopTracing, 10000);
3363 }
3364 };
3365
3366 Runnable mStopTracing = new Runnable() {
3367 public void run() {
3368 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04003369 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003370 vibrate();
3371 }
3372 };
Chris Wren0c8275b2012-05-08 13:36:48 -04003373
3374 @Override
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07003375 public boolean shouldDisableNavbarGestures() {
Jorim Jaggi18976a52015-07-24 13:18:19 -07003376 return !isDeviceProvisioned() || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07003377 }
Joe Onorato808182d2010-07-09 18:52:06 -04003378
Jason Monkba2318e2015-12-08 09:04:23 -05003379 public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
3380 mHandler.post(new Runnable() {
3381 @Override
3382 public void run() {
3383 mLeaveOpenOnKeyguardHide = true;
3384 executeRunnableDismissingKeyguard(runnable, null, false, true);
3385 }
3386 });
3387 }
3388
Adrian Roos62692b22015-09-11 17:46:23 -07003389 public void postStartActivityDismissingKeyguard(final PendingIntent intent) {
3390 mHandler.post(new Runnable() {
3391 @Override
3392 public void run() {
3393 startPendingIntentDismissingKeyguard(intent);
3394 }
3395 });
3396 }
3397
Jason Monkee43cdf2015-06-19 14:20:46 -04003398 public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
John Spurlockd47a3f32014-05-18 19:14:14 -04003399 mHandler.postDelayed(new Runnable() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003400 @Override
3401 public void run() {
Jason Monkee43cdf2015-06-19 14:20:46 -04003402 handleStartActivityDismissingKeyguard(intent, true /*onlyProvisioned*/);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003403 }
John Spurlockd47a3f32014-05-18 19:14:14 -04003404 }, delay);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003405 }
3406
Jason Monkee43cdf2015-06-19 14:20:46 -04003407 private void handleStartActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003408 startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
John Spurlockde547002014-02-28 17:50:39 -05003409 }
3410
Romain Guy648342f2012-05-25 10:44:45 -07003411 private static class FastColorDrawable extends Drawable {
3412 private final int mColor;
3413
3414 public FastColorDrawable(int color) {
3415 mColor = 0xff000000 | color;
3416 }
3417
3418 @Override
3419 public void draw(Canvas canvas) {
3420 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
3421 }
3422
3423 @Override
3424 public void setAlpha(int alpha) {
3425 }
3426
3427 @Override
Chris Craikbd3bfc52015-03-02 10:43:29 -08003428 public void setColorFilter(ColorFilter colorFilter) {
Romain Guy648342f2012-05-25 10:44:45 -07003429 }
3430
3431 @Override
3432 public int getOpacity() {
3433 return PixelFormat.OPAQUE;
3434 }
3435
3436 @Override
3437 public void setBounds(int left, int top, int right, int bottom) {
3438 }
3439
3440 @Override
3441 public void setBounds(Rect bounds) {
3442 }
3443 }
John Spurlock5c454122013-06-17 07:35:46 -04003444
3445 @Override
3446 public void destroy() {
3447 super.destroy();
3448 if (mStatusBarWindow != null) {
3449 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05003450 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04003451 }
3452 if (mNavigationBarView != null) {
3453 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05003454 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04003455 }
Jason Monk4ae97d32014-12-17 10:14:33 -05003456 if (mHandlerThread != null) {
3457 mHandlerThread.quitSafely();
3458 mHandlerThread = null;
3459 }
John Spurlock5c454122013-06-17 07:35:46 -04003460 mContext.unregisterReceiver(mBroadcastReceiver);
Adrian Roos8e3e8362015-07-16 19:42:22 -07003461 mContext.unregisterReceiver(mDemoReceiver);
Selim Cineke70d6532015-04-24 16:46:13 -07003462 mAssistManager.destroy();
Jason Monk07b75fe2015-05-14 16:47:03 -04003463
3464 final SignalClusterView signalCluster =
3465 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
3466 final SignalClusterView signalClusterKeyguard =
3467 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
3468 final SignalClusterView signalClusterQs =
3469 (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
Jason Monk5e745172015-06-02 19:14:44 -04003470 mNetworkController.removeSignalCallback(signalCluster);
3471 mNetworkController.removeSignalCallback(signalClusterKeyguard);
3472 mNetworkController.removeSignalCallback(signalClusterQs);
3473 if (mQSPanel != null && mQSPanel.getHost() != null) {
3474 mQSPanel.getHost().destroy();
3475 }
John Spurlock5c454122013-06-17 07:35:46 -04003476 }
John Spurlock3c875662013-08-31 15:07:25 -04003477
3478 private boolean mDemoModeAllowed;
3479 private boolean mDemoMode;
John Spurlock3c875662013-08-31 15:07:25 -04003480
3481 @Override
3482 public void dispatchDemoCommand(String command, Bundle args) {
3483 if (!mDemoModeAllowed) {
3484 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
Jason Monk431ad732015-07-16 08:58:15 -04003485 DEMO_MODE_ALLOWED, 0) != 0;
John Spurlock3c875662013-08-31 15:07:25 -04003486 }
3487 if (!mDemoModeAllowed) return;
3488 if (command.equals(COMMAND_ENTER)) {
3489 mDemoMode = true;
3490 } else if (command.equals(COMMAND_EXIT)) {
3491 mDemoMode = false;
3492 checkBarModes();
3493 } else if (!mDemoMode) {
3494 // automatically enter demo mode on first demo command
3495 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
3496 }
3497 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
John Spurlockbb4a7022014-11-08 12:40:19 -05003498 if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
3499 mVolumeComponent.dispatchDemoCommand(command, args);
3500 }
John Spurlock3c875662013-08-31 15:07:25 -04003501 if (modeChange || command.equals(COMMAND_CLOCK)) {
3502 dispatchDemoCommandToView(command, args, R.id.clock);
3503 }
3504 if (modeChange || command.equals(COMMAND_BATTERY)) {
3505 dispatchDemoCommandToView(command, args, R.id.battery);
3506 }
3507 if (modeChange || command.equals(COMMAND_STATUS)) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003508 mIconController.dispatchDemoCommand(command, args);
3509
John Spurlock3c875662013-08-31 15:07:25 -04003510 }
3511 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
3512 mNetworkController.dispatchDemoCommand(command, args);
3513 }
John Spurlock7f42fc52014-01-14 16:20:39 -05003514 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
3515 View notifications = mStatusBarView == null ? null
3516 : mStatusBarView.findViewById(R.id.notification_icon_area);
3517 if (notifications != null) {
3518 String visible = args.getString("visible");
3519 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
3520 notifications.setVisibility(vis);
3521 }
3522 }
John Spurlock3c875662013-08-31 15:07:25 -04003523 if (command.equals(COMMAND_BARS)) {
3524 String mode = args.getString("mode");
3525 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04003526 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04003527 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
John Spurlock0ff62e02014-07-22 16:15:08 -04003528 "transparent".equals(mode) ? MODE_TRANSPARENT :
3529 "warning".equals(mode) ? MODE_WARNING :
John Spurlock3c875662013-08-31 15:07:25 -04003530 -1;
3531 if (barMode != -1) {
3532 boolean animate = true;
3533 if (mStatusBarView != null) {
3534 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
3535 }
3536 if (mNavigationBarView != null) {
3537 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
3538 }
3539 }
3540 }
3541 }
3542
3543 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
3544 if (mStatusBarView == null) return;
3545 View v = mStatusBarView.findViewById(id);
3546 if (v instanceof DemoMode) {
3547 ((DemoMode)v).dispatchDemoCommand(command, args);
3548 }
3549 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003550
Jorim Jaggiecbab362014-04-23 16:13:15 +02003551 /**
3552 * @return The {@link StatusBarState} the status bar is in.
3553 */
3554 public int getBarState() {
3555 return mState;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003556 }
3557
Chris Wren16895942015-06-23 11:22:20 -04003558 @Override
3559 protected boolean isPanelFullyCollapsed() {
3560 return mNotificationPanel.isFullyCollapsed();
3561 }
3562
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003563 public void showKeyguard() {
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003564 if (mLaunchTransitionFadingAway) {
3565 mNotificationPanel.animate().cancel();
Selim Cinek37c110f2015-05-22 12:38:44 -07003566 onLaunchTransitionFadingEnded();
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003567 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003568 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003569 if (mUserSwitcherController != null && mUserSwitcherController.useFullscreenUserSwitcher()) {
3570 setBarState(StatusBarState.FULLSCREEN_USER_SWITCHER);
3571 } else {
3572 setBarState(StatusBarState.KEYGUARD);
3573 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02003574 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003575 if (!mDeviceInteractive) {
Jorim Jaggid41083a2014-09-12 02:54:40 +02003576
3577 // If the screen is off already, we need to disable touch events because these might
3578 // collapse the panel after we expanded it, and thus we would end up with a blank
3579 // Keyguard.
3580 mNotificationPanel.setTouchDisabled(true);
3581 }
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003582 if (mState == StatusBarState.KEYGUARD) {
3583 instantExpandNotificationsPanel();
3584 } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
3585 instantCollapseNotificationPanel();
3586 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003587 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003588 if (mDraggedDownRow != null) {
3589 mDraggedDownRow.setUserLocked(false);
Selim Cinekb5605e52015-02-20 18:21:41 +01003590 mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003591 mDraggedDownRow = null;
3592 }
Adrian Roos3aec6382016-02-05 14:19:01 -08003593 mPendingRemoteInputView = null;
Jorim Jaggi19695d92015-07-20 15:51:40 -07003594 mAssistManager.onLockscreenShown();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003595 }
3596
Selim Cinek37c110f2015-05-22 12:38:44 -07003597 private void onLaunchTransitionFadingEnded() {
3598 mNotificationPanel.setAlpha(1.0f);
Selim Cinek372d1bd2015-08-14 13:19:37 -07003599 mNotificationPanel.onAffordanceLaunchEnded();
3600 releaseGestureWakeLock();
Selim Cinek37c110f2015-05-22 12:38:44 -07003601 runLaunchTransitionEndRunnable();
3602 mLaunchTransitionFadingAway = false;
3603 mScrimController.forceHideScrims(false /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08003604 updateMediaMetaData(true /* metaDataChanged */, true);
Selim Cinek37c110f2015-05-22 12:38:44 -07003605 }
3606
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003607 public boolean isCollapsing() {
3608 return mNotificationPanel.isCollapsing();
3609 }
3610
3611 public void addPostCollapseAction(Runnable r) {
3612 mPostCollapseRunnables.add(r);
3613 }
3614
Selim Cinekbaa23272014-07-08 18:01:07 +02003615 public boolean isInLaunchTransition() {
3616 return mNotificationPanel.isLaunchTransitionRunning()
3617 || mNotificationPanel.isLaunchTransitionFinished();
3618 }
3619
3620 /**
3621 * Fades the content of the keyguard away after the launch transition is done.
3622 *
3623 * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
3624 * starts
3625 * @param endRunnable the runnable to be run when the transition is done
3626 */
3627 public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003628 Runnable endRunnable) {
Jorim Jaggi826730a2014-12-08 21:05:13 +01003629 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003630 mLaunchTransitionEndRunnable = endRunnable;
Selim Cinekbaa23272014-07-08 18:01:07 +02003631 Runnable hideRunnable = new Runnable() {
3632 @Override
3633 public void run() {
3634 mLaunchTransitionFadingAway = true;
3635 if (beforeFading != null) {
3636 beforeFading.run();
3637 }
Selim Cinek37c110f2015-05-22 12:38:44 -07003638 mScrimController.forceHideScrims(true /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08003639 updateMediaMetaData(false, true);
Selim Cinekbaa23272014-07-08 18:01:07 +02003640 mNotificationPanel.setAlpha(1);
3641 mNotificationPanel.animate()
3642 .alpha(0)
3643 .setStartDelay(FADE_KEYGUARD_START_DELAY)
3644 .setDuration(FADE_KEYGUARD_DURATION)
3645 .withLayer()
3646 .withEndAction(new Runnable() {
3647 @Override
3648 public void run() {
Selim Cinek37c110f2015-05-22 12:38:44 -07003649 onLaunchTransitionFadingEnded();
Selim Cinekbaa23272014-07-08 18:01:07 +02003650 }
3651 });
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003652 mIconController.appTransitionStarting(SystemClock.uptimeMillis(),
3653 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Selim Cinekbaa23272014-07-08 18:01:07 +02003654 }
3655 };
3656 if (mNotificationPanel.isLaunchTransitionRunning()) {
3657 mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
3658 } else {
3659 hideRunnable.run();
3660 }
3661 }
3662
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003663 /**
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07003664 * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
3665 * fading.
3666 */
3667 public void fadeKeyguardWhilePulsing() {
3668 mNotificationPanel.animate()
3669 .alpha(0f)
3670 .setStartDelay(0)
3671 .setDuration(FADE_KEYGUARD_DURATION_PULSING)
Jorim Jaggiab45a212015-08-20 16:59:44 -07003672 .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
3673 .start();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07003674 }
3675
3676 /**
Jorim Jaggi826730a2014-12-08 21:05:13 +01003677 * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
3678 * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
3679 * because the launched app crashed or something else went wrong.
3680 */
3681 public void startLaunchTransitionTimeout() {
3682 mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
3683 LAUNCH_TRANSITION_TIMEOUT_MS);
3684 }
3685
3686 private void onLaunchTransitionTimeout() {
3687 Log.w(TAG, "Launch transition: Timeout!");
Selim Cinek372d1bd2015-08-14 13:19:37 -07003688 mNotificationPanel.onAffordanceLaunchEnded();
3689 releaseGestureWakeLock();
Jorim Jaggi826730a2014-12-08 21:05:13 +01003690 mNotificationPanel.resetViews();
3691 }
3692
3693 private void runLaunchTransitionEndRunnable() {
3694 if (mLaunchTransitionEndRunnable != null) {
3695 Runnable r = mLaunchTransitionEndRunnable;
3696
3697 // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
3698 // which would lead to infinite recursion. Protect against it.
3699 mLaunchTransitionEndRunnable = null;
3700 r.run();
3701 }
3702 }
3703
3704 /**
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003705 * @return true if we would like to stay in the shade, false if it should go away entirely
3706 */
3707 public boolean hideKeyguard() {
3708 boolean staying = mLeaveOpenOnKeyguardHide;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003709 setBarState(StatusBarState.SHADE);
Adrian Roos3aec6382016-02-05 14:19:01 -08003710 View viewToClick = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003711 if (mLeaveOpenOnKeyguardHide) {
3712 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggi37c11802015-08-18 20:27:54 -07003713 long delay = calculateGoingToFullShadeDelay();
3714 mNotificationPanel.animateToFullShade(delay);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003715 if (mDraggedDownRow != null) {
3716 mDraggedDownRow.setUserLocked(false);
3717 mDraggedDownRow = null;
3718 }
Adrian Roos3aec6382016-02-05 14:19:01 -08003719 viewToClick = mPendingRemoteInputView;
3720 mPendingRemoteInputView = null;
Jorim Jaggi37c11802015-08-18 20:27:54 -07003721
3722 // Disable layout transitions in navbar for this transition because the load is just
3723 // too heavy for the CPU and GPU on any device.
3724 if (mNavigationBarView != null) {
3725 mNavigationBarView.setLayoutTransitionsEnabled(false);
3726 mNavigationBarView.postDelayed(new Runnable() {
3727 @Override
3728 public void run() {
3729 mNavigationBarView.setLayoutTransitionsEnabled(true);
3730 }
3731 }, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
3732 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003733 } else {
3734 instantCollapseNotificationPanel();
3735 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02003736 updateKeyguardState(staying, false /* fromShadeLocked */);
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01003737
Adrian Roos3aec6382016-02-05 14:19:01 -08003738 if (viewToClick != null) {
3739 viewToClick.callOnClick();
3740 }
3741
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01003742 // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
3743 // visibilities so next time we open the panel we know the correct height already.
3744 if (mQSPanel != null) {
3745 mQSPanel.refreshAllTiles();
3746 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003747 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Selim Cinek372d1bd2015-08-14 13:19:37 -07003748 releaseGestureWakeLock();
3749 mNotificationPanel.onAffordanceLaunchEnded();
Jorim Jaggi52429b42015-09-03 19:58:19 -07003750 mNotificationPanel.animate().cancel();
Jorim Jaggi90978852015-08-18 19:55:53 -07003751 mNotificationPanel.setAlpha(1f);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003752 return staying;
3753 }
3754
Selim Cinek372d1bd2015-08-14 13:19:37 -07003755 private void releaseGestureWakeLock() {
3756 if (mGestureWakeLock.isHeld()) {
3757 mGestureWakeLock.release();
3758 }
3759 }
3760
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003761 public long calculateGoingToFullShadeDelay() {
3762 return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
Jorim Jaggi15682502014-04-23 12:01:36 +02003763 }
3764
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003765 /**
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003766 * Notifies the status bar that Keyguard is going away very soon.
3767 */
3768 public void keyguardGoingAway() {
3769
3770 // Treat Keyguard exit animation as an app transition to achieve nice transition for status
3771 // bar.
Adrian Roos46df1ca2015-09-11 12:38:43 -07003772 mKeyguardGoingAway = true;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003773 mIconController.appTransitionPending();
3774 }
3775
3776 /**
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003777 * Notifies the status bar the Keyguard is fading away with the specified timings.
3778 *
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003779 * @param startTime the start time of the animations in uptime millis
3780 * @param delay the precalculated animation delay in miliseconds
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003781 * @param fadeoutDuration the duration of the exit animation, in milliseconds
3782 */
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003783 public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003784 mKeyguardFadingAway = true;
3785 mKeyguardFadingAwayDelay = delay;
3786 mKeyguardFadingAwayDuration = fadeoutDuration;
3787 mWaitingForKeyguardExit = false;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003788 mIconController.appTransitionStarting(
3789 startTime + fadeoutDuration
3790 - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
3791 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07003792 disable(mDisabledUnmodified1, mDisabledUnmodified2, fadeoutDuration > 0 /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003793 }
3794
Jorim Jaggi416493b2014-09-13 03:57:32 +02003795 public boolean isKeyguardFadingAway() {
3796 return mKeyguardFadingAway;
3797 }
3798
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003799 /**
3800 * Notifies that the Keyguard fading away animation is done.
3801 */
3802 public void finishKeyguardFadingAway() {
3803 mKeyguardFadingAway = false;
Adrian Roos46df1ca2015-09-11 12:38:43 -07003804 mKeyguardGoingAway = false;
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003805 }
3806
Adrian Roosd322f1a2015-04-23 15:19:45 -07003807 public void stopWaitingForKeyguardExit() {
3808 mWaitingForKeyguardExit = false;
3809 }
3810
Jorim Jaggi15682502014-04-23 12:01:36 +02003811 private void updatePublicMode() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003812 setLockscreenPublicMode(
3813 mStatusBarKeyguardViewManager.isShowing() && mStatusBarKeyguardViewManager
3814 .isSecure(mCurrentUserId));
Jorim Jaggi15682502014-04-23 12:01:36 +02003815 }
3816
Rakesh Iyer2790a372016-01-22 15:33:39 -08003817 protected void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003818 if (mState == StatusBarState.KEYGUARD) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003819 mKeyguardIndicationController.setVisible(true);
Selim Cinek4c6969a2014-05-26 19:22:17 +02003820 mNotificationPanel.resetViews();
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003821 if (mKeyguardUserSwitcher != null) {
3822 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
3823 }
Selim Cinek80c2abe2015-06-17 15:37:30 -07003824 mStatusBarView.removePendingHideExpandedRunnables();
Jorim Jaggi15682502014-04-23 12:01:36 +02003825 } else {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003826 mKeyguardIndicationController.setVisible(false);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003827 if (mKeyguardUserSwitcher != null) {
3828 mKeyguardUserSwitcher.setKeyguard(false,
3829 goingToFullShade ||
3830 mState == StatusBarState.SHADE_LOCKED ||
3831 fromShadeLocked);
3832 }
Jorim Jaggi15682502014-04-23 12:01:36 +02003833 }
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003834 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003835 mScrimController.setKeyguardShowing(true);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003836 mIconPolicy.setKeyguardShowing(true);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003837 } else {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003838 mScrimController.setKeyguardShowing(false);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003839 mIconPolicy.setKeyguardShowing(false);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003840 }
Rakesh Iyer2790a372016-01-22 15:33:39 -08003841
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003842 mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
John Spurlockbf370992014-06-17 13:58:31 -04003843 updateDozingState();
Jorim Jaggi15682502014-04-23 12:01:36 +02003844 updatePublicMode();
Selim Cinekd35c2792016-01-21 13:20:57 -08003845 updateStackScrollerState(goingToFullShade, fromShadeLocked);
Christoph Studer37fe6932014-05-26 13:10:30 +02003846 updateNotifications();
Jorim Jaggia6310292014-04-16 14:11:52 +02003847 checkBarModes();
Adrian Roos52738322016-01-29 08:49:21 -08003848 updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
John Spurlock657c62c2014-07-22 12:18:09 -04003849 mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
3850 mStatusBarKeyguardViewManager.isSecure());
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003851 }
3852
John Spurlockbf370992014-06-17 13:58:31 -04003853 private void updateDozingState() {
Jorim Jaggi4e857f42014-11-17 19:14:04 +01003854 boolean animate = !mDozing && mDozeScrimController.isPulsing();
3855 mNotificationPanel.setDozing(mDozing, animate);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003856 mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
Jorim Jaggi048af1f2014-11-11 22:51:10 +01003857 mScrimController.setDozing(mDozing);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07003858
3859 // Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock
3860 // for pulsing so the Keyguard fade-out animation scrim can take over.
3861 mDozeScrimController.setDozing(mDozing &&
3862 mFingerprintUnlockController.getMode()
3863 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate);
John Spurlockbf370992014-06-17 13:58:31 -04003864 }
3865
Selim Cinekd35c2792016-01-21 13:20:57 -08003866 public void updateStackScrollerState(boolean goingToFullShade, boolean fromShadeLocked) {
John Spurlock4b3bda22014-05-22 14:32:20 -04003867 if (mStackScroller == null) return;
Selim Cinek1408eb52014-06-02 14:45:38 +02003868 boolean onKeyguard = mState == StatusBarState.KEYGUARD;
Jorim Jaggiae441282014-08-01 02:45:18 +02003869 mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
Selim Cinekd35c2792016-01-21 13:20:57 -08003870 mStackScroller.setDimmed(onKeyguard, fromShadeLocked /* animate */);
Selim Cinek1408eb52014-06-02 14:45:38 +02003871 mStackScroller.setExpandingEnabled(!onKeyguard);
Selim Cineka32ab602014-06-11 15:06:01 +02003872 ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
3873 mStackScroller.setActivatedChild(null);
3874 if (activatedChild != null) {
3875 activatedChild.makeInactive(false /* animate */);
3876 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003877 }
3878
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003879 public void userActivity() {
Jorim Jaggib690f0d2014-07-03 23:25:44 +02003880 if (mState == StatusBarState.KEYGUARD) {
3881 mKeyguardViewMediatorCallback.userActivity();
3882 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003883 }
3884
Jorim Jaggidf993512014-05-13 23:06:35 +02003885 public boolean interceptMediaKey(KeyEvent event) {
3886 return mState == StatusBarState.KEYGUARD
3887 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
3888 }
3889
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003890 public boolean onMenuPressed() {
Selim Cinek28540192016-02-19 17:25:08 -08003891 if (mDeviceInteractive && mState != StatusBarState.SHADE
3892 && mStatusBarKeyguardViewManager.shouldDismissOnMenuPressed()) {
3893 animateCollapsePanels(
3894 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
3895 return true;
3896 }
3897 return false;
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003898 }
3899
Selim Cinek372d1bd2015-08-14 13:19:37 -07003900 public void endAffordanceLaunch() {
3901 releaseGestureWakeLock();
3902 mNotificationPanel.onAffordanceLaunchEnded();
3903 }
3904
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003905 public boolean onBackPressed() {
Adrian Roos0002a452014-07-03 13:46:07 +02003906 if (mStatusBarKeyguardViewManager.onBackPressed()) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003907 return true;
3908 }
Adrian Roos0002a452014-07-03 13:46:07 +02003909 if (mNotificationPanel.isQsExpanded()) {
John Spurlockf7ae4422014-08-01 12:45:18 -04003910 if (mNotificationPanel.isQsDetailShowing()) {
3911 mNotificationPanel.closeQsDetail();
3912 } else {
3913 mNotificationPanel.animateCloseQs();
3914 }
Adrian Roos0002a452014-07-03 13:46:07 +02003915 return true;
3916 }
3917 if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
3918 animateCollapsePanels();
3919 return true;
3920 }
3921 return false;
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003922 }
3923
Jorim Jaggi34250762014-07-03 23:51:19 +02003924 public boolean onSpacePressed() {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003925 if (mDeviceInteractive && mState != StatusBarState.SHADE) {
Jorim Jaggi4eedc1d2014-10-27 13:45:56 +01003926 animateCollapsePanels(
3927 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
Jorim Jaggi34250762014-07-03 23:51:19 +02003928 return true;
3929 }
3930 return false;
3931 }
3932
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003933 private void showBouncer() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003934 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekbaa23272014-07-08 18:01:07 +02003935 mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003936 mStatusBarKeyguardViewManager.dismiss();
3937 }
3938 }
3939
3940 private void instantExpandNotificationsPanel() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02003941
Jorim Jaggi0a27be82014-06-11 03:22:39 +02003942 // Make our window larger and the panel expanded.
Jorim Jaggifa505a72014-04-28 20:04:11 +02003943 makeExpandedVisible(true);
Oren Blasberg8d3fea12015-07-10 14:21:44 -07003944 mNotificationPanel.expand(false /* animate */);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003945 }
Adrian Roos5a46cd32014-04-03 16:51:58 +02003946
Jorim Jaggia005f1b2014-04-16 19:06:10 +02003947 private void instantCollapseNotificationPanel() {
Selim Cinek6bb4a9b2014-10-09 17:48:05 -07003948 mNotificationPanel.instantCollapse();
Jorim Jaggia005f1b2014-04-16 19:06:10 +02003949 }
3950
Jorim Jaggid4a57442014-04-10 02:45:55 +02003951 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02003952 public void onActivated(ActivatableNotificationView view) {
Christoph Studerb0183992014-12-22 21:02:26 +01003953 EventLogTags.writeSysuiLockscreenGesture(
3954 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
3955 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
Adrian Roos12c1ef52014-06-04 13:54:08 +02003956 mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
Selim Cineka32ab602014-06-11 15:06:01 +02003957 ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
3958 if (previousView != null) {
3959 previousView.makeInactive(true /* animate */);
3960 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003961 mStackScroller.setActivatedChild(view);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02003962 }
3963
Jorim Jaggiecbab362014-04-23 16:13:15 +02003964 /**
3965 * @param state The {@link StatusBarState} to set.
3966 */
3967 public void setBarState(int state) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01003968 // If we're visible and switched to SHADE_LOCKED (the user dragged
3969 // down on the lockscreen), clear notification LED, vibration,
3970 // ringing.
3971 // Other transitions are covered in handleVisibleToUserChanged().
Selim Cinek6577cae2015-08-31 16:15:49 -07003972 if (state != mState && mVisible && (state == StatusBarState.SHADE_LOCKED
3973 || (state == StatusBarState.SHADE && isGoingToNotificationShade()))) {
3974 clearNotificationEffects();
Christoph Studer1f32c652014-11-26 15:32:20 +01003975 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003976 mState = state;
Selim Cinek9c4c4142015-12-04 16:44:56 -08003977 mGroupManager.setStatusBarState(state);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07003978 mFalsingManager.setStatusBarState(state);
Jorim Jaggiecbab362014-04-23 16:13:15 +02003979 mStatusBarWindowManager.setStatusBarState(state);
Jorim Jaggi83969702015-06-05 14:59:24 -07003980 updateDozing();
Jorim Jaggiecbab362014-04-23 16:13:15 +02003981 }
3982
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02003983 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02003984 public void onActivationReset(ActivatableNotificationView view) {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003985 if (view == mStackScroller.getActivatedChild()) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003986 mKeyguardIndicationController.hideTransientIndication();
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003987 mStackScroller.setActivatedChild(null);
3988 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02003989 }
3990
3991 public void onTrackingStarted() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003992 runPostCollapseRunnables();
Jorim Jaggi90129582014-06-02 14:44:49 +02003993 }
3994
Selim Cinekdbbcfbe2014-10-24 17:52:35 +02003995 public void onClosingFinished() {
3996 runPostCollapseRunnables();
3997 }
3998
Jorim Jaggi90129582014-06-02 14:44:49 +02003999 public void onUnlockHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004000 mFalsingManager.onUnlockHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004001 mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
Jorim Jaggi90129582014-06-02 14:44:49 +02004002 }
4003
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004004 public void onHintFinished() {
Jorim Jaggi93a2bb22014-06-02 19:57:28 +02004005 // Delay the reset a bit so the user can read the text.
Adrian Roos12c1ef52014-06-04 13:54:08 +02004006 mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004007 }
4008
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004009 public void onCameraHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004010 mFalsingManager.onCameraHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004011 mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004012 }
4013
Selim Cineke70d6532015-04-24 16:46:13 -07004014 public void onVoiceAssistHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004015 mFalsingManager.onLeftAffordanceHintStarted();
Selim Cineke70d6532015-04-24 16:46:13 -07004016 mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
4017 }
4018
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004019 public void onPhoneHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004020 mFalsingManager.onLeftAffordanceHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004021 mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004022 }
4023
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004024 public void onTrackingStopped(boolean expand) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004025 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cineke8bae622015-07-15 13:24:06 -07004026 if (!expand && !mUnlockMethodCache.canSkipBouncer()) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004027 showBouncer();
4028 }
4029 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004030 }
4031
4032 @Override
Selim Cinek5f71bee2015-11-18 10:25:23 -08004033 protected int getMaxKeyguardNotifications(boolean recompute) {
4034 if (recompute) {
4035 mMaxKeyguardNotifications = Math.max(1,
4036 mNotificationPanel.computeMaxKeyguardNotifications(
4037 mMaxAllowedKeyguardNotifications));
4038 return mMaxKeyguardNotifications;
4039 }
4040 return mMaxKeyguardNotifications;
4041 }
4042
4043 public int getMaxKeyguardNotifications() {
4044 return getMaxKeyguardNotifications(false /* recompute */);
Jorim Jaggid4a57442014-04-10 02:45:55 +02004045 }
4046
Jorim Jaggia6310292014-04-16 14:11:52 +02004047 public NavigationBarView getNavigationBarView() {
4048 return mNavigationBarView;
4049 }
4050
Jorim Jaggiecbab362014-04-23 16:13:15 +02004051 // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
4052
4053 @Override
Christoph Studerb0183992014-12-22 21:02:26 +01004054 public boolean onDraggedDown(View startingChild, int dragLengthY) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02004055 if (hasActiveNotifications()) {
Christoph Studerb0183992014-12-22 21:02:26 +01004056 EventLogTags.writeSysuiLockscreenGesture(
4057 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
4058 (int) (dragLengthY / mDisplayMetrics.density),
4059 0 /* velocityDp - N/A */);
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004060
4061 // We have notifications, go to locked shade.
4062 goToLockedShade(startingChild);
4063 return true;
4064 } else {
4065
4066 // No notifications - abort gesture.
4067 return false;
4068 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004069 }
4070
4071 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004072 public void onDragDownReset() {
4073 mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
Selim Cinek177fd432015-11-18 11:53:47 -08004074 mStackScroller.resetScrollPosition();
Jorim Jaggiecbab362014-04-23 16:13:15 +02004075 }
4076
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004077 @Override
Selim Cinek177fd432015-11-18 11:53:47 -08004078 public void onCrossedThreshold(boolean above) {
4079 mStackScroller.setDimmed(!above /* dimmed */, true /* animate */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004080 }
4081
Selim Cinek1408eb52014-06-02 14:45:38 +02004082 @Override
4083 public void onTouchSlopExceeded() {
4084 mStackScroller.removeLongPressCallback();
4085 }
4086
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004087 @Override
4088 public void setEmptyDragAmount(float amount) {
4089 mNotificationPanel.setEmptyDragAmount(amount);
4090 }
4091
Jorim Jaggiecbab362014-04-23 16:13:15 +02004092 /**
4093 * If secure with redaction: Show bouncer, go to unlocked shade.
4094 *
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004095 * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
Jorim Jaggiecbab362014-04-23 16:13:15 +02004096 *
4097 * @param expandView The view to expand after going to the shade.
4098 */
4099 public void goToLockedShade(View expandView) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004100 ExpandableNotificationRow row = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02004101 if (expandView instanceof ExpandableNotificationRow) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004102 row = (ExpandableNotificationRow) expandView;
Selim Cinekcb24ab82016-02-25 12:49:08 -08004103 row.setUserExpanded(true /* userExpanded */, true /* allowChildExpansion */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004104 }
Adrian Roosaee70462014-09-03 16:27:39 +02004105 boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004106 || !mShowLockscreenNotifications || mFalsingManager.shouldEnforceBouncer();
Adrian Roosaee70462014-09-03 16:27:39 +02004107 if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004108 mLeaveOpenOnKeyguardHide = true;
4109 showBouncer();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004110 mDraggedDownRow = row;
Adrian Roos3aec6382016-02-05 14:19:01 -08004111 mPendingRemoteInputView = null;
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004112 } else {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004113 mNotificationPanel.animateToFullShade(0 /* delay */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004114 setBarState(StatusBarState.SHADE_LOCKED);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004115 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004116 }
4117 }
4118
Selim Cinek570981d2015-12-01 11:37:01 -08004119 @Override
Adrian Roos3aec6382016-02-05 14:19:01 -08004120 protected void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
4121 mLeaveOpenOnKeyguardHide = true;
4122 showBouncer();
4123 mPendingRemoteInputView = clicked;
4124 }
4125
4126 @Override
Selim Cinek31aada42015-12-18 17:51:15 -08004127 public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
4128 mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
Selim Cinek570981d2015-12-01 11:37:01 -08004129 if (mState == StatusBarState.KEYGUARD && nowExpanded) {
Selim Cinek31aada42015-12-18 17:51:15 -08004130 goToLockedShade(clickedEntry.row);
Selim Cinek570981d2015-12-01 11:37:01 -08004131 }
4132 }
4133
Adrian Roos5a46cd32014-04-03 16:51:58 +02004134 /**
Jorim Jaggi6539a832014-06-03 23:33:09 +02004135 * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
4136 */
4137 public void goToKeyguard() {
4138 if (mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekd9acca52014-09-01 22:33:25 +02004139 mStackScroller.onGoToKeyguard();
Jorim Jaggi6539a832014-06-03 23:33:09 +02004140 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004141 updateKeyguardState(false /* goingToFullShade */, true /* fromShadeLocked*/);
Jorim Jaggi6539a832014-06-03 23:33:09 +02004142 }
4143 }
4144
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004145 public long getKeyguardFadingAwayDelay() {
4146 return mKeyguardFadingAwayDelay;
4147 }
4148
4149 public long getKeyguardFadingAwayDuration() {
4150 return mKeyguardFadingAwayDuration;
4151 }
4152
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004153 @Override
4154 public void setBouncerShowing(boolean bouncerShowing) {
4155 super.setBouncerShowing(bouncerShowing);
Adrian Roosd0b2f7d2015-04-29 13:36:12 -07004156 mStatusBarView.setBouncerShowing(bouncerShowing);
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01004157 disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004158 }
4159
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004160 public void onStartedGoingToSleep() {
4161 mStartedGoingToSleep = true;
4162 }
4163
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004164 public void onFinishedGoingToSleep() {
Selim Cinek372d1bd2015-08-14 13:19:37 -07004165 mNotificationPanel.onAffordanceLaunchEnded();
4166 releaseGestureWakeLock();
4167 mLaunchCameraOnScreenTurningOn = false;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004168 mStartedGoingToSleep = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004169 mDeviceInteractive = false;
4170 mWakeUpComingFromTouch = false;
4171 mWakeUpTouchLocation = null;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004172 mFalsingManager.onScreenOff();
Jorim Jaggi75c95042014-05-16 19:09:59 +02004173 mStackScroller.setAnimationsEnabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004174 updateVisibleToUser();
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004175 if (mLaunchCameraOnFinishedGoingToSleep) {
4176 mLaunchCameraOnFinishedGoingToSleep = false;
4177
4178 // This gets executed before we will show Keyguard, so post it in order that the state
4179 // is correct.
4180 mHandler.post(new Runnable() {
4181 @Override
4182 public void run() {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004183 onCameraLaunchGestureDetected(mLastCameraLaunchSource);
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004184 }
4185 });
4186 }
Jorim Jaggi75c95042014-05-16 19:09:59 +02004187 }
4188
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004189 public void onStartedWakingUp() {
4190 mDeviceInteractive = true;
Jorim Jaggi75c95042014-05-16 19:09:59 +02004191 mStackScroller.setAnimationsEnabled(true);
Jorim Jaggid41083a2014-09-12 02:54:40 +02004192 mNotificationPanel.setTouchDisabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004193 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02004194 }
John Spurlockd08f91f2014-05-23 11:00:34 -04004195
Jorim Jaggi93739112015-08-13 15:53:14 -07004196 public void onScreenTurningOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004197 mScreenTurningOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004198 mFalsingManager.onScreenTurningOn();
Jorim Jaggi93739112015-08-13 15:53:14 -07004199 mNotificationPanel.onScreenTurningOn();
Selim Cinek372d1bd2015-08-14 13:19:37 -07004200 if (mLaunchCameraOnScreenTurningOn) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004201 mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004202 mLaunchCameraOnScreenTurningOn = false;
4203 }
Jorim Jaggi93739112015-08-13 15:53:14 -07004204 }
4205
Selim Cinek69ff8af2015-08-25 19:03:48 -07004206 private void vibrateForCameraGesture() {
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004207 // Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
Jorim Jaggi75b25972015-10-21 14:51:10 +02004208 mVibrator.vibrate(new long[]{0, 750L}, -1 /* repeat */);
Selim Cinek69ff8af2015-08-25 19:03:48 -07004209 }
4210
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004211 public void onScreenTurnedOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004212 mScreenTurningOn = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004213 mDozeScrimController.onScreenTurnedOn();
4214 }
4215
Jason Monk815e0572014-08-12 17:26:36 -04004216 /**
Jorim Jaggi75b25972015-10-21 14:51:10 +02004217 * Handles long press for back button. This exits screen pinning.
Jason Monk815e0572014-08-12 17:26:36 -04004218 */
Jorim Jaggi75b25972015-10-21 14:51:10 +02004219 private boolean handleLongPressBack() {
Jason Monk62515be2014-05-21 16:06:19 -04004220 try {
4221 IActivityManager activityManager = ActivityManagerNative.getDefault();
Jorim Jaggi75b25972015-10-21 14:51:10 +02004222 if (activityManager.isInLockTaskMode()) {
4223 activityManager.stopLockTaskModeOnCurrent();
4224
4225 // When exiting refresh disabled flags.
4226 mNavigationBarView.setDisabledFlags(mDisabled1, true);
4227 return true;
Jason Monk62515be2014-05-21 16:06:19 -04004228 }
4229 } catch (RemoteException e) {
Jason Monk815e0572014-08-12 17:26:36 -04004230 Log.d(TAG, "Unable to reach activity manager", e);
Jason Monk62515be2014-05-21 16:06:19 -04004231 }
Jorim Jaggi75b25972015-10-21 14:51:10 +02004232 return false;
Jason Monk62515be2014-05-21 16:06:19 -04004233 }
4234
Winson3e7e3aa2015-09-22 14:22:58 -07004235 public void updateRecentsVisibility(boolean visible) {
Winson Chung9214eff2014-06-12 13:59:25 -07004236 // Update the recents visibility flag
4237 if (visible) {
4238 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
4239 } else {
4240 mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
4241 }
4242 notifyUiVisibilityChanged(mSystemUiVisibility);
4243 }
John Spurlockbf370992014-06-17 13:58:31 -04004244
Jason Monk5565cb42014-09-12 10:59:21 -04004245 @Override
4246 public void showScreenPinningRequest() {
Jason Monk18f99d92014-09-11 13:36:42 -04004247 if (mKeyguardMonitor.isShowing()) {
4248 // Don't allow apps to trigger this from keyguard.
4249 return;
4250 }
4251 // Show screen pinning request, since this comes from an app, show 'no thanks', button.
4252 showScreenPinningRequest(true);
4253 }
4254
4255 public void showScreenPinningRequest(boolean allowCancel) {
4256 mScreenPinningRequest.showPrompt(allowCancel);
Jason Monk5565cb42014-09-12 10:59:21 -04004257 }
4258
Christoph Studerc8db24b2014-07-25 17:50:30 +02004259 public boolean hasActiveNotifications() {
4260 return !mNotificationData.getActiveNotifications().isEmpty();
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004261 }
4262
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004263 public void wakeUpIfDozing(long time, MotionEvent event) {
Jorim Jaggi048af1f2014-11-11 22:51:10 +01004264 if (mDozing && mDozeScrimController.isPulsing()) {
John Spurlock8b12f222014-09-09 11:54:11 -04004265 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
Dianne Hackborn280a64e2015-07-13 14:48:08 -07004266 pm.wakeUp(time, "com.android.systemui:NODOZE");
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004267 mWakeUpComingFromTouch = true;
4268 mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004269 mNotificationPanel.setTouchDisabled(false);
Jorim Jaggi0d210f62015-07-10 14:24:44 -07004270 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004271 mFalsingManager.onScreenOnFromTouch();
John Spurlock8b12f222014-09-09 11:54:11 -04004272 }
4273 }
4274
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004275 @Override
4276 public void appTransitionPending() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004277
4278 // Use own timings when Keyguard is going away, see keyguardGoingAway and
4279 // setKeyguardFadingAway
4280 if (!mKeyguardFadingAway) {
4281 mIconController.appTransitionPending();
4282 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004283 }
4284
4285 @Override
4286 public void appTransitionCancelled() {
4287 mIconController.appTransitionCancelled();
4288 }
4289
4290 @Override
4291 public void appTransitionStarting(long startTime, long duration) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004292
4293 // Use own timings when Keyguard is going away, see keyguardGoingAway and
Adrian Roos46df1ca2015-09-11 12:38:43 -07004294 // setKeyguardFadingAway.
4295 if (!mKeyguardGoingAway) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004296 mIconController.appTransitionStarting(startTime, duration);
4297 }
Kenny Guy3094d4a2015-04-01 19:14:10 +01004298 if (mIconPolicy != null) {
4299 mIconPolicy.appTransitionStarting(startTime, duration);
4300 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004301 }
4302
Selim Cinek372d1bd2015-08-14 13:19:37 -07004303 @Override
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004304 public void onCameraLaunchGestureDetected(int source) {
4305 mLastCameraLaunchSource = source;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004306 if (mStartedGoingToSleep) {
4307 mLaunchCameraOnFinishedGoingToSleep = true;
4308 return;
4309 }
Zhentao Sun04f97402015-08-26 17:37:30 -07004310 if (!mNotificationPanel.canCameraGestureBeLaunched(
4311 mStatusBarKeyguardViewManager.isShowing() && mExpandedVisible)) {
Selim Cinek372d1bd2015-08-14 13:19:37 -07004312 return;
4313 }
4314 if (!mDeviceInteractive) {
4315 PowerManager pm = mContext.getSystemService(PowerManager.class);
4316 pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE");
4317 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
4318 }
Selim Cinek69ff8af2015-08-25 19:03:48 -07004319 vibrateForCameraGesture();
Selim Cinek372d1bd2015-08-14 13:19:37 -07004320 if (!mStatusBarKeyguardViewManager.isShowing()) {
4321 startActivity(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT,
4322 true /* dismissShade */);
4323 } else {
4324 if (!mDeviceInteractive) {
4325 // Avoid flickering of the scrim when we instant launch the camera and the bouncer
4326 // comes on.
4327 mScrimController.dontAnimateBouncerChangesUntilNextFrame();
4328 mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
4329 }
Selim Cinek1b6f8192015-09-03 16:01:53 -07004330 if (mScreenTurningOn || mStatusBarKeyguardViewManager.isScreenTurnedOn()) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004331 mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004332 } else {
4333 // We need to defer the camera launch until the screen comes on, since otherwise
4334 // we will dismiss us too early since we are waiting on an activity to be drawn and
4335 // incorrectly get notified because of the screen on event (which resumes and pauses
4336 // some activities)
4337 mLaunchCameraOnScreenTurningOn = true;
4338 }
4339 }
4340 }
4341
Jaewan Kimc552b042016-01-18 16:08:45 +09004342 @Override
4343 public void requestTvPictureInPicture() {
4344 // no-op.
4345 }
4346
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004347 public void notifyFpAuthModeChanged() {
4348 updateDozing();
4349 }
4350
Jorim Jaggi83969702015-06-05 14:59:24 -07004351 private void updateDozing() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004352 // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
4353 mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
4354 || mFingerprintUnlockController.getMode()
4355 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
Jorim Jaggi83969702015-06-05 14:59:24 -07004356 updateDozingState();
4357 }
4358
John Spurlockbf370992014-06-17 13:58:31 -04004359 private final class ShadeUpdates {
4360 private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
4361 private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
4362
4363 public void check() {
4364 mNewVisibleNotifications.clear();
Christoph Studerc8db24b2014-07-25 17:50:30 +02004365 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
4366 for (int i = 0; i < activeNotifications.size(); i++) {
4367 final Entry entry = activeNotifications.get(i);
John Spurlockbf370992014-06-17 13:58:31 -04004368 final boolean visible = entry.row != null
4369 && entry.row.getVisibility() == View.VISIBLE;
4370 if (visible) {
4371 mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
4372 }
4373 }
4374 final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
4375 mVisibleNotifications.clear();
Dianne Hackborn497175b2014-07-01 12:56:08 -07004376 mVisibleNotifications.addAll(mNewVisibleNotifications);
John Spurlockbf370992014-06-17 13:58:31 -04004377
4378 // We have new notifications
4379 if (updates && mDozeServiceHost != null) {
4380 mDozeServiceHost.fireNewNotifications();
4381 }
4382 }
4383 }
4384
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004385 private final class DozeServiceHost extends KeyguardUpdateMonitorCallback implements DozeHost {
John Spurlockbf370992014-06-17 13:58:31 -04004386 // Amount of time to allow to update the time shown on the screen before releasing
4387 // the wakelock. This timeout is design to compensate for the fact that we don't
4388 // currently have a way to know when time display contents have actually been
4389 // refreshed once we've finished rendering a new frame.
4390 private static final long PROCESSING_TIME = 500;
4391
4392 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
4393 private final H mHandler = new H();
4394
Christoph Studer1f32c652014-11-26 15:32:20 +01004395 // Keeps the last reported state by fireNotificationLight.
4396 private boolean mNotificationLightOn;
4397
John Spurlockc6eed842014-08-25 12:19:41 -04004398 @Override
4399 public String toString() {
Jeff Brown4d69e222014-09-18 15:27:50 -07004400 return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
John Spurlock8b12f222014-09-09 11:54:11 -04004401 }
4402
John Spurlockd96179e2014-08-21 16:43:45 -04004403 public void firePowerSaveChanged(boolean active) {
4404 for (Callback callback : mCallbacks) {
4405 callback.onPowerSaveChanged(active);
4406 }
4407 }
4408
John Spurlockcad57682014-07-26 17:09:56 -04004409 public void fireBuzzBeepBlinked() {
4410 for (Callback callback : mCallbacks) {
4411 callback.onBuzzBeepBlinked();
4412 }
4413 }
4414
John Spurlockcb566aa2014-08-03 22:58:28 -04004415 public void fireNotificationLight(boolean on) {
Christoph Studer1f32c652014-11-26 15:32:20 +01004416 mNotificationLightOn = on;
John Spurlockcb566aa2014-08-03 22:58:28 -04004417 for (Callback callback : mCallbacks) {
4418 callback.onNotificationLight(on);
4419 }
4420 }
4421
John Spurlockbf370992014-06-17 13:58:31 -04004422 public void fireNewNotifications() {
4423 for (Callback callback : mCallbacks) {
4424 callback.onNewNotifications();
4425 }
4426 }
4427
4428 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004429 public void addCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04004430 mCallbacks.add(callback);
4431 }
4432
4433 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004434 public void removeCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04004435 mCallbacks.remove(callback);
4436 }
4437
4438 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004439 public void startDozing(@NonNull Runnable ready) {
4440 mHandler.obtainMessage(H.MSG_START_DOZING, ready).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004441 }
4442
4443 @Override
John Spurlockeab28e62014-11-29 11:33:49 -05004444 public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
4445 mHandler.obtainMessage(H.MSG_PULSE_WHILE_DOZING, reason, 0, callback).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004446 }
4447
4448 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004449 public void stopDozing() {
4450 mHandler.obtainMessage(H.MSG_STOP_DOZING).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004451 }
4452
John Spurlockd96179e2014-08-21 16:43:45 -04004453 @Override
4454 public boolean isPowerSaveActive() {
4455 return mBatteryController != null && mBatteryController.isPowerSave();
4456 }
4457
Christoph Studer1f32c652014-11-26 15:32:20 +01004458 @Override
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004459 public boolean isPulsingBlocked() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004460 return mFingerprintUnlockController.getMode()
4461 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004462 }
4463
4464 @Override
Christoph Studer1f32c652014-11-26 15:32:20 +01004465 public boolean isNotificationLightOn() {
4466 return mNotificationLightOn;
4467 }
4468
Jeff Brown4d69e222014-09-18 15:27:50 -07004469 private void handleStartDozing(@NonNull Runnable ready) {
Jorim Jaggi83969702015-06-05 14:59:24 -07004470 if (!mDozingRequested) {
4471 mDozingRequested = true;
John Spurlock813552c2014-09-19 08:30:21 -04004472 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07004473 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04004474 }
Jeff Brown4d69e222014-09-18 15:27:50 -07004475 ready.run();
John Spurlockbf370992014-06-17 13:58:31 -04004476 }
4477
John Spurlockeab28e62014-11-29 11:33:49 -05004478 private void handlePulseWhileDozing(@NonNull PulseCallback callback, int reason) {
4479 mDozeScrimController.pulse(callback, reason);
John Spurlockbf370992014-06-17 13:58:31 -04004480 }
4481
Jeff Brown4d69e222014-09-18 15:27:50 -07004482 private void handleStopDozing() {
Jorim Jaggi83969702015-06-05 14:59:24 -07004483 if (mDozingRequested) {
4484 mDozingRequested = false;
John Spurlock813552c2014-09-19 08:30:21 -04004485 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07004486 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04004487 }
4488 }
4489
4490 private final class H extends Handler {
Jeff Brown4d69e222014-09-18 15:27:50 -07004491 private static final int MSG_START_DOZING = 1;
4492 private static final int MSG_PULSE_WHILE_DOZING = 2;
4493 private static final int MSG_STOP_DOZING = 3;
John Spurlockbf370992014-06-17 13:58:31 -04004494
4495 @Override
4496 public void handleMessage(Message msg) {
Jeff Brown4d69e222014-09-18 15:27:50 -07004497 switch (msg.what) {
4498 case MSG_START_DOZING:
4499 handleStartDozing((Runnable) msg.obj);
4500 break;
4501 case MSG_PULSE_WHILE_DOZING:
John Spurlockeab28e62014-11-29 11:33:49 -05004502 handlePulseWhileDozing((PulseCallback) msg.obj, msg.arg1);
Jeff Brown4d69e222014-09-18 15:27:50 -07004503 break;
4504 case MSG_STOP_DOZING:
4505 handleStopDozing();
4506 break;
John Spurlockbf370992014-06-17 13:58:31 -04004507 }
4508 }
4509 }
4510 }
Romain Guy648342f2012-05-25 10:44:45 -07004511}