blob: c563eb60666369ced49e378d1eeba19f22ee24cb [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;
Jorim Jaggie6e108e2016-03-28 13:38:45 -070024import android.app.ActivityManager.StackId;
Joe Onorato808182d2010-07-09 18:52:06 -040025import android.app.ActivityManagerNative;
Jorim Jaggie6e108e2016-03-28 13:38:45 -070026import android.app.ActivityOptions;
Jason Monk62515be2014-05-21 16:06:19 -040027import android.app.IActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040028import android.app.Notification;
29import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040030import android.app.StatusBarManager;
31import android.content.BroadcastReceiver;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020032import android.content.ComponentCallbacks2;
Jason Monk7e53f202016-01-28 10:40:20 -050033import android.content.ComponentName;
Joe Onorato808182d2010-07-09 18:52:06 -040034import android.content.Context;
35import android.content.Intent;
36import android.content.IntentFilter;
Adrian Roos21d2a252015-06-01 13:59:59 -070037import android.content.pm.IPackageManager;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -070038import android.content.pm.PackageManager;
Daniel Sandler777dcde2013-09-30 10:21:45 -040039import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070040import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040041import android.database.ContentObserver;
Dan Sandler16128f42014-05-21 12:48:22 -040042import android.graphics.Bitmap;
Romain Guy648342f2012-05-25 10:44:45 -070043import android.graphics.Canvas;
44import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040045import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040046import android.graphics.Point;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +010047import android.graphics.PointF;
Romain Guy648342f2012-05-25 10:44:45 -070048import android.graphics.PorterDuff;
Selim Cineka0fad3b2014-09-19 17:20:05 +020049import android.graphics.PorterDuffXfermode;
Joe Onorato808182d2010-07-09 18:52:06 -040050import android.graphics.Rect;
Dan Sandler16128f42014-05-21 12:48:22 -040051import android.graphics.drawable.ColorDrawable;
Romain Guy648342f2012-05-25 10:44:45 -070052import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070053import android.inputmethodservice.InputMethodService;
John Spurlock7b414672014-07-18 13:02:39 -040054import android.media.AudioAttributes;
Dan Sandler16128f42014-05-21 12:48:22 -040055import android.media.MediaMetadata;
56import android.media.session.MediaController;
57import android.media.session.MediaSession;
58import android.media.session.MediaSessionManager;
59import android.media.session.PlaybackState;
Selim Cinekbaa23272014-07-08 18:01:07 +020060import android.os.AsyncTask;
John Spurlock3c875662013-08-31 15:07:25 -040061import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040062import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050063import android.os.HandlerThread;
Joe Onorato808182d2010-07-09 18:52:06 -040064import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040065import android.os.Message;
John Spurlock56d007b2013-10-28 18:40:56 -040066import android.os.PowerManager;
Jason Monk4ae97d32014-12-17 10:14:33 -050067import android.os.Process;
Michael Jurka7f2668c2012-03-27 07:49:52 -070068import android.os.RemoteException;
Adrian Roos21d2a252015-06-01 13:59:59 -070069import android.os.ServiceManager;
Joe Onorato808182d2010-07-09 18:52:06 -040070import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070071import android.os.UserHandle;
Adrian Roos2b154a92014-11-17 15:18:39 +010072import android.os.UserManager;
Selim Cinek69ff8af2015-08-25 19:03:48 -070073import android.os.Vibrator;
Daniel Sandlerd3090562011-08-09 00:28:44 -040074import android.provider.Settings;
Chris Wren3ad4e3a2014-09-02 17:23:51 -040075import android.service.notification.NotificationListenerService;
Christoph Studerd0694b62014-06-04 16:36:01 +020076import android.service.notification.NotificationListenerService.RankingMap;
John Spurlockde84f0e2013-06-12 12:41:00 -040077import android.service.notification.StatusBarNotification;
Christoph Studer92b389d2014-04-01 18:44:40 +020078import android.util.ArraySet;
Daniel Sandler36412a72011-08-04 09:35:13 -040079import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -050080import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -040081import android.util.Log;
82import android.view.Display;
Jorim Jaggidf993512014-05-13 23:06:35 +020083import android.view.KeyEvent;
Jorim Jaggid4a57442014-04-10 02:45:55 +020084import android.view.LayoutInflater;
Joe Onorato808182d2010-07-09 18:52:06 -040085import android.view.MotionEvent;
Chris Craik2507c342015-05-04 14:36:49 -070086import android.view.ThreadedRenderer;
Joe Onorato808182d2010-07-09 18:52:06 -040087import android.view.View;
Xiyuan Xia1b30f792016-01-06 08:50:30 -080088import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -070089import android.view.ViewGroup.LayoutParams;
Dan Sandler44c0dfd2014-06-09 11:26:16 -040090import android.view.ViewStub;
Joe Onorato808182d2010-07-09 18:52:06 -040091import android.view.WindowManager;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020092import android.view.WindowManagerGlobal;
Daniel Sandlerd7e96862012-04-26 01:10:29 -040093import android.view.animation.AccelerateInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +020094import android.view.animation.Interpolator;
Dan Sandler16128f42014-05-21 12:48:22 -040095import android.widget.ImageView;
Joe Onorato808182d2010-07-09 18:52:06 -040096import android.widget.TextView;
Chris Wren9763d422015-04-30 15:24:05 -040097import com.android.internal.logging.MetricsLogger;
Chris Wrenf6e9228b2016-01-26 18:04:35 -050098import com.android.internal.logging.MetricsProto.MetricsEvent;
Chris Wrend1dbc922015-06-19 17:51:16 -040099import com.android.internal.statusbar.NotificationVisibility;
Joe Onorato808182d2010-07-09 18:52:06 -0400100import com.android.internal.statusbar.StatusBarIcon;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100101import com.android.keyguard.KeyguardHostView.OnDismissAction;
Jason Monkab525272015-07-13 17:02:49 -0400102import com.android.keyguard.KeyguardUpdateMonitor;
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700103import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200104import com.android.keyguard.ViewMediatorCallback;
Jorim Jaggi708f7722014-08-20 17:30:38 +0200105import com.android.systemui.BatteryMeterView;
John Spurlock3c875662013-08-31 15:07:25 -0400106import com.android.systemui.DemoMode;
Jason Monk46dbfb42016-02-25 14:59:20 -0500107import com.android.systemui.DensityContainer;
108import com.android.systemui.DensityContainer.InflateListener;
Christoph Studerb0183992014-12-22 21:02:26 +0100109import com.android.systemui.EventLogConstants;
Chris Wren64161cc2012-12-17 16:49:30 -0500110import com.android.systemui.EventLogTags;
Winsonc0d70582016-01-29 10:24:39 -0800111import com.android.systemui.Interpolators;
Andrew Flynn82862572015-04-01 14:22:37 -0400112import com.android.systemui.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -0400113import com.android.systemui.R;
Xiaohui Chen5da71352016-02-22 10:04:41 -0800114import com.android.systemui.SystemUIFactory;
Selim Cineke70d6532015-04-24 16:46:13 -0700115import com.android.systemui.assist.AssistManager;
Adrian Roos401caae2016-03-04 13:35:21 -0800116import com.android.systemui.classifier.FalsingLog;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800117import com.android.systemui.classifier.FalsingManager;
Jeff Brown4d69e222014-09-18 15:27:50 -0700118import com.android.systemui.doze.DozeHost;
John Spurlock813552c2014-09-19 08:30:21 -0400119import com.android.systemui.doze.DozeLog;
Jorim Jaggicff0acb2014-03-31 16:35:15 +0200120import com.android.systemui.keyguard.KeyguardViewMediator;
Jason Monk162011e2016-02-19 08:11:55 -0500121import com.android.systemui.qs.QSContainer;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400122import com.android.systemui.qs.QSPanel;
Jorim Jaggid61f2272014-12-19 20:35:35 +0100123import com.android.systemui.recents.ScreenPinningRequest;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800124import com.android.systemui.recents.events.EventBus;
Jorim Jaggi2adba072016-03-03 13:43:39 +0100125import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800126import com.android.systemui.recents.events.activity.UndockingTaskEvent;
Jorim Jaggidd98d412015-11-18 15:57:38 -0800127import com.android.systemui.stackdivider.Divider;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800128import com.android.systemui.stackdivider.WindowManagerProxy;
Selim Cineka32ab602014-06-11 15:06:01 +0200129import com.android.systemui.statusbar.ActivatableNotificationView;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200130import com.android.systemui.statusbar.BackDropView;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500131import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700132import com.android.systemui.statusbar.CommandQueue;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400133import com.android.systemui.statusbar.DismissView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200134import com.android.systemui.statusbar.DragDownHelper;
Jorim Jaggia2052ea2014-08-05 16:22:30 +0200135import com.android.systemui.statusbar.EmptyShadeView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200136import com.android.systemui.statusbar.ExpandableNotificationRow;
Daniel Sandler33805342012-07-23 15:45:12 -0400137import com.android.systemui.statusbar.GestureRecorder;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200138import com.android.systemui.statusbar.KeyguardIndicationController;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700139import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -0400140import com.android.systemui.statusbar.NotificationData.Entry;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200141import com.android.systemui.statusbar.NotificationOverflowContainer;
Adrian Roos1c0ca502015-10-07 12:20:42 -0700142import com.android.systemui.statusbar.RemoteInputController;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200143import com.android.systemui.statusbar.ScrimView;
Christian Robertson2e347422011-08-11 14:01:04 -0700144import com.android.systemui.statusbar.SignalClusterView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200145import com.android.systemui.statusbar.StatusBarState;
Christoph Studer2231c6e2014-12-19 12:40:13 +0100146import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200147import com.android.systemui.statusbar.policy.AccessibilityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400148import com.android.systemui.statusbar.policy.BatteryController;
John Spurlock0ff62e02014-07-22 16:15:08 -0400149import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400150import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200151import com.android.systemui.statusbar.policy.BrightnessMirrorController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400152import com.android.systemui.statusbar.policy.CastControllerImpl;
Adrian Roosb83777b2014-06-30 15:11:53 +0200153import com.android.systemui.statusbar.policy.FlashlightController;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700154import com.android.systemui.statusbar.policy.HeadsUpManager;
Jason Monk3d5f5512014-07-25 11:17:28 -0400155import com.android.systemui.statusbar.policy.HotspotControllerImpl;
John Spurlock657c62c2014-07-22 12:18:09 -0400156import com.android.systemui.statusbar.policy.KeyguardMonitor;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700157import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400158import com.android.systemui.statusbar.policy.LocationControllerImpl;
159import com.android.systemui.statusbar.policy.NetworkControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400160import com.android.systemui.statusbar.policy.NextAlarmController;
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200161import com.android.systemui.statusbar.policy.PreviewInflater;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400162import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400163import com.android.systemui.statusbar.policy.SecurityControllerImpl;
164import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200165import com.android.systemui.statusbar.policy.UserSwitcherController;
John Spurlock86005342014-05-23 11:58:00 -0400166import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek67b22602014-03-10 15:40:16 +0100167import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Christoph Studer92b389d2014-04-01 18:44:40 +0200168import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
Jorim Jaggi37c11802015-08-18 20:27:54 -0700169import com.android.systemui.statusbar.stack.StackStateAnimator;
Selim Cinekb036ca42015-02-20 15:56:28 +0100170import com.android.systemui.statusbar.stack.StackViewState;
John Spurlock86005342014-05-23 11:58:00 -0400171import com.android.systemui.volume.VolumeComponent;
Selim Cinek67b22602014-03-10 15:40:16 +0100172
Daniel Sandler6a858c32012-03-12 14:38:58 -0400173import java.io.FileDescriptor;
174import java.io.PrintWriter;
175import java.util.ArrayList;
Christoph Studer92b389d2014-04-01 18:44:40 +0200176import java.util.Collection;
177import java.util.Collections;
Selim Cinekb5605e52015-02-20 18:21:41 +0100178import java.util.HashMap;
Dan Sandler16128f42014-05-21 12:48:22 -0400179import java.util.List;
John Spurlock7bbb9f62014-10-21 12:15:28 -0400180import java.util.Map;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700181
182import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
183import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
184import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
185import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
186import static android.app.StatusBarManager.windowStateToString;
187import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
188import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
189import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
190import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
191import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
192import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
193import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
Daniel Sandler6a858c32012-03-12 14:38:58 -0400194
Jorim Jaggiecbab362014-04-23 16:13:15 +0200195public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Selim Cinek8d490d42015-04-10 00:05:50 -0700196 DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
197 HeadsUpManager.OnHeadsUpChangedListener {
Joe Onoratofd52b182010-11-10 18:00:52 -0800198 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400199 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400200 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400201 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400202 public static final boolean DEBUG_GESTURES = false;
Dan Sandler16128f42014-05-21 12:48:22 -0400203 public static final boolean DEBUG_MEDIA = false;
204 public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400205
John Spurlock342cad72013-10-08 09:36:50 -0400206 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400207
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400208 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400209 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400210
Dan Sandler16128f42014-05-21 12:48:22 -0400211 public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
212
Adrian Roos8e3e8362015-07-16 19:42:22 -0700213 public static final String ACTION_FAKE_ARTWORK = "fake_artwork";
214
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400215 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400216 private static final int MSG_CLOSE_PANELS = 1001;
217 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Jorim Jaggi826730a2014-12-08 21:05:13 +0100218 private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
Winson Chungb1f74992014-08-08 12:53:09 -0700219 // 1020-1040 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400220
Jorim Jaggi826730a2014-12-08 21:05:13 +0100221 // Time after we abort the launch transition.
222 private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
223
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400224 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
225
John Spurlocke1f366f2013-08-05 12:22:40 -0400226 private static final int STATUS_OR_NAV_TRANSIENT =
227 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400228 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400229
Christoph Studer92b389d2014-04-01 18:44:40 +0200230 /** The minimum delay in ms between reports of notification visibility. */
231 private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
232
Jorim Jaggi93a2bb22014-06-02 19:57:28 +0200233 /**
234 * The delay to reset the hint text when the hint animation is finished running.
235 */
236 private static final int HINT_RESET_DELAY_MS = 1200;
237
John Spurlock7b414672014-07-18 13:02:39 -0400238 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
239 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
240 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
241 .build();
242
Selim Cinekbaa23272014-07-08 18:01:07 +0200243 public static final int FADE_KEYGUARD_START_DELAY = 100;
244 public static final int FADE_KEYGUARD_DURATION = 300;
Jorim Jaggi90978852015-08-18 19:55:53 -0700245 public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
Selim Cinekbaa23272014-07-08 18:01:07 +0200246
Jason Monk815e0572014-08-12 17:26:36 -0400247 /** Allow some time inbetween the long press for back and recents. */
248 private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
249
Adrian Roos2f2bd9a2015-06-04 18:11:14 -0700250 /** If true, the system is in the half-boot-to-decryption-screen state.
251 * Prudently disable QS and notifications. */
Adrian Roos21d2a252015-06-01 13:59:59 -0700252 private static final boolean ONLY_CORE_APPS;
253
Adrian Roos52738322016-01-29 08:49:21 -0800254 /** If true, the lockscreen will show a distinct wallpaper */
Adrian Roose381c162016-02-11 15:26:42 -0800255 private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
Adrian Roos52738322016-01-29 08:49:21 -0800256
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700257 /* If true, the device supports freeform window management.
258 * This affects the status bar UI. */
259 private static final boolean FREEFORM_WINDOW_MANAGEMENT;
260
Adrian Roos21d2a252015-06-01 13:59:59 -0700261 static {
262 boolean onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700263 boolean freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700264 try {
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700265 IPackageManager packageManager =
266 IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
267 onlyCoreApps = packageManager.isOnlyCoreApps();
268 freeformWindowManagement = packageManager.hasSystemFeature(
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700269 PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT, 0);
Adrian Roos21d2a252015-06-01 13:59:59 -0700270 } catch (RemoteException e) {
271 onlyCoreApps = false;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700272 freeformWindowManagement = false;
Adrian Roos21d2a252015-06-01 13:59:59 -0700273 }
274 ONLY_CORE_APPS = onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700275 FREEFORM_WINDOW_MANAGEMENT = freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700276 }
277
Joe Onoratofd52b182010-11-10 18:00:52 -0800278 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400279
Daniel Sandler2b697352011-07-22 16:23:09 -0400280 // These are no longer handled by the policy, because we need custom strategies for them
John Spurlockaf8d6c42014-05-07 17:49:08 -0400281 BluetoothControllerImpl mBluetoothController;
Jason Monk3d5f5512014-07-25 11:17:28 -0400282 SecurityControllerImpl mSecurityController;
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -0800283 protected BatteryController mBatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400284 LocationControllerImpl mLocationController;
285 NetworkControllerImpl mNetworkController;
Jason Monk51e4dc02014-07-22 12:00:47 -0400286 HotspotControllerImpl mHotspotController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400287 RotationLockControllerImpl mRotationLockController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200288 UserInfoController mUserInfoController;
Muyuan Li40e11352016-03-23 11:43:58 -0700289 protected ZenModeController mZenModeController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400290 CastControllerImpl mCastController;
John Spurlock86005342014-05-23 11:58:00 -0400291 VolumeComponent mVolumeComponent;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700292 KeyguardUserSwitcher mKeyguardUserSwitcher;
Adrian Roosb83777b2014-06-30 15:11:53 +0200293 FlashlightController mFlashlightController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800294 protected UserSwitcherController mUserSwitcherController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200295 NextAlarmController mNextAlarmController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800296 protected KeyguardMonitor mKeyguardMonitor;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200297 BrightnessMirrorController mBrightnessMirrorController;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200298 AccessibilityController mAccessibilityController;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700299 FingerprintUnlockController mFingerprintUnlockController;
Jorim Jaggi86905582016-02-09 21:36:09 -0800300 LightStatusBarController mLightStatusBarController;
Vadim Tryshev12a30e82016-02-12 15:39:28 -0800301 protected LockscreenWallpaper mLockscreenWallpaper;
Jim Miller5e6af442011-12-02 18:24:26 -0800302
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400303 int mNaturalBarHeight = -1;
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100304
Joe Onorato808182d2010-07-09 18:52:06 -0400305 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400306 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400307
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800308 protected StatusBarWindowView mStatusBarWindow;
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700309 protected PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400310 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800311 protected StatusBarWindowManager mStatusBarWindowManager;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200312 private UnlockMethodCache mUnlockMethodCache;
John Spurlockbf370992014-06-17 13:58:31 -0400313 private DozeServiceHost mDozeServiceHost;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -0700314 private boolean mWakeUpComingFromTouch;
315 private PointF mWakeUpTouchLocation;
Selim Cinek1b6f8192015-09-03 16:01:53 -0700316 private boolean mScreenTurningOn;
Daniel Sandlera310af82012-04-24 01:20:13 -0400317
Joe Onorato808182d2010-07-09 18:52:06 -0400318 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400319 Object mQueueLock = new Object();
320
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700321 protected StatusBarIconController mIconController;
Joe Onorato808182d2010-07-09 18:52:06 -0400322
323 // expanded notifications
Xiaohui Chenea4b6ba2016-02-18 10:53:17 -0800324 protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400325 View mExpandedContents;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400326 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400327
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400328 // settings
John Spurlockaf8d6c42014-05-07 17:49:08 -0400329 private QSPanel mQSPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400330
Joe Onorato808182d2010-07-09 18:52:06 -0400331 // top bar
Jason Monk0e1101d2015-10-07 13:06:09 -0400332 BaseStatusBarHeader mHeader;
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700333 protected KeyguardStatusBarView mKeyguardStatusBar;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200334 View mKeyguardStatusView;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200335 KeyguardBottomAreaView mKeyguardBottomArea;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200336 boolean mLeaveOpenOnKeyguardHide;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200337 KeyguardIndicationController mKeyguardIndicationController;
Jorim Jaggie70d31f2014-04-24 22:08:30 +0200338
Adrian Roos46df1ca2015-09-11 12:38:43 -0700339 // Keyguard is going away soon.
340 private boolean mKeyguardGoingAway;
341 // Keyguard is actually fading away now.
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700342 private boolean mKeyguardFadingAway;
343 private long mKeyguardFadingAwayDelay;
344 private long mKeyguardFadingAwayDuration;
345
Adrian Roos3aec6382016-02-05 14:19:01 -0800346 // RemoteInputView to be activated after unlock
347 private View mPendingRemoteInputView;
348
Selim Cinek5f71bee2015-11-18 10:25:23 -0800349 int mMaxAllowedKeyguardNotifications;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400350
Joe Onorato808182d2010-07-09 18:52:06 -0400351 boolean mExpandedVisible;
352
John Spurlockd4e65752013-08-28 14:17:09 -0400353 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400354
Joe Onorato808182d2010-07-09 18:52:06 -0400355 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400356 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400357
Joe Onorato808182d2010-07-09 18:52:06 -0400358 // Tracking finger for opening/closing.
Joe Onorato808182d2010-07-09 18:52:06 -0400359 boolean mTracking;
Joe Onorato808182d2010-07-09 18:52:06 -0400360
Joe Onorato808182d2010-07-09 18:52:06 -0400361 int[] mAbsPos = new int[2];
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200362 ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
Chet Haase2f2022a2011-10-11 06:41:59 -0700363
Joe Onorato808182d2010-07-09 18:52:06 -0400364 // for disabling the status bar
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100365 int mDisabled1 = 0;
366 int mDisabled2 = 0;
Joe Onorato808182d2010-07-09 18:52:06 -0400367
Daniel Sandler60ee2562011-07-22 12:34:33 -0400368 // tracking calls to View.setSystemUiVisibility()
369 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
Jorim Jaggi86905582016-02-09 21:36:09 -0800370 private final Rect mLastFullscreenStackBounds = new Rect();
371 private final Rect mLastDockedStackBounds = new Rect();
Daniel Sandler60ee2562011-07-22 12:34:33 -0400372
Adrian Roos389beec2015-05-12 13:33:25 -0700373 // last value sent to window manager
374 private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
375
Daniel Sandler36412a72011-08-04 09:35:13 -0400376 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700377
Daniel Sandler33805342012-07-23 15:45:12 -0400378 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400379 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400380 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400381 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400382
Jason Monk18f99d92014-09-11 13:36:42 -0400383 private ScreenPinningRequest mScreenPinningRequest;
384
Daniel Sandler328310c2011-09-23 15:56:52 -0400385 private int mNavigationIconHints = 0;
Jason Monk4ae97d32014-12-17 10:14:33 -0500386 private HandlerThread mHandlerThread;
Daniel Sandler328310c2011-09-23 15:56:52 -0400387
John Spurlock919adac2012-10-02 16:41:12 -0400388 // ensure quick settings is disabled until the current user makes it through the setup wizard
389 private boolean mUserSetup = false;
390 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
391 @Override
392 public void onChange(boolean selfChange) {
393 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
394 mContext.getContentResolver(),
395 Settings.Secure.USER_SETUP_COMPLETE,
396 0 /*default */,
397 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400398 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400399 "selfChange=%s userSetup=%s mUserSetup=%s",
400 selfChange, userSetup, mUserSetup));
John Spurlock73203eb2014-04-15 16:14:46 -0400401
John Spurlock919adac2012-10-02 16:41:12 -0400402 if (userSetup != mUserSetup) {
403 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400404 if (!mUserSetup && mStatusBarView != null)
405 animateCollapseQuickSettings();
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700406 if (mKeyguardBottomArea != null) {
407 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
408 }
John Spurlock919adac2012-10-02 16:41:12 -0400409 }
John Spurlock604a5ee2015-06-01 12:27:22 -0400410 if (mIconPolicy != null) {
411 mIconPolicy.setCurrentUserSetup(mUserSetup);
412 }
John Spurlock919adac2012-10-02 16:41:12 -0400413 }
414 };
415
Chris Wrenf6e83f42013-09-11 14:02:59 -0400416 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
417 @Override
418 public void onChange(boolean selfChange) {
419 boolean wasUsing = mUseHeadsUp;
Jason Monkf7019542014-07-31 12:42:25 -0400420 mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
421 && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
Chris Wren10d82df2014-03-01 10:34:51 -0500422 mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Chris Wren7bd241232014-02-28 16:25:05 -0500423 Settings.Global.HEADS_UP_OFF);
Chris Wren22ae46e2014-02-26 18:08:09 -0500424 mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
425 mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400426 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
427 if (wasUsing != mUseHeadsUp) {
428 if (!mUseHeadsUp) {
429 Log.d(TAG, "dismissing any existing heads up notification on disable event");
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700430 mHeadsUpManager.releaseAllImmediately();
Chris Wrenf6e83f42013-09-11 14:02:59 -0400431 }
432 }
433 }
434 };
435
John Spurlockcfc359a2013-09-05 10:42:03 -0400436 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400437 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400438 private int mStatusBarMode;
439 private int mNavigationBarMode;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800440 private int mMaxKeyguardNotifications;
Jorim Jaggid41083a2014-09-12 02:54:40 +0200441
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200442 private ViewMediatorCallback mKeyguardViewMediatorCallback;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800443 protected ScrimController mScrimController;
444 protected DozeScrimController mDozeScrimController;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200445
John Spurlock32beb2c2013-03-11 10:16:47 -0400446 private final Runnable mAutohide = new Runnable() {
447 @Override
448 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400449 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400450 if (mSystemUiVisibility != requested) {
451 notifyUiVisibilityChanged(requested);
452 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400453 }};
454
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700455 private boolean mWaitingForKeyguardExit;
John Spurlockbf370992014-06-17 13:58:31 -0400456 private boolean mDozing;
Jorim Jaggi83969702015-06-05 14:59:24 -0700457 private boolean mDozingRequested;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800458 protected boolean mScrimSrcModeEnabled;
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100459
Selim Cinekc18010f2016-01-20 13:41:30 -0800460 public static final Interpolator ALPHA_IN = Interpolators.ALPHA_IN;
461 public static final Interpolator ALPHA_OUT = Interpolators.ALPHA_OUT;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200462
Selim Cineka0fad3b2014-09-19 17:20:05 +0200463 private BackDropView mBackdrop;
Dan Sandler16128f42014-05-21 12:48:22 -0400464 private ImageView mBackdropFront, mBackdropBack;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200465 private PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
466 private PorterDuffXfermode mSrcOverXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
Dan Sandler16128f42014-05-21 12:48:22 -0400467
468 private MediaSessionManager mMediaSessionManager;
469 private MediaController mMediaController;
470 private String mMediaNotificationKey;
471 private MediaMetadata mMediaMetadata;
472 private MediaController.Callback mMediaListener
473 = new MediaController.Callback() {
474 @Override
475 public void onPlaybackStateChanged(PlaybackState state) {
476 super.onPlaybackStateChanged(state);
477 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400478 if (state != null) {
479 if (!isPlaybackActive(state.getState())) {
480 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -0800481 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400482 }
483 }
Dan Sandler16128f42014-05-21 12:48:22 -0400484 }
485
486 @Override
487 public void onMetadataChanged(MediaMetadata metadata) {
488 super.onMetadataChanged(metadata);
489 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
490 mMediaMetadata = metadata;
Adrian Roos52738322016-01-29 08:49:21 -0800491 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -0400492 }
493 };
494
495 private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
496 new OnChildLocationsChangedListener() {
497 @Override
498 public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
499 userActivity();
500 }
501 };
502
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100503 private int mDisabledUnmodified1;
504 private int mDisabledUnmodified2;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200505
Christoph Studer92b389d2014-04-01 18:44:40 +0200506 /** Keys of notifications currently visible to the user. */
Chris Wrend1dbc922015-06-19 17:51:16 -0400507 private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications =
508 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200509 private long mLastVisibilityReportUptimeMs;
510
John Spurlockbf370992014-06-17 13:58:31 -0400511 private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
512
Selim Cinekbaa23272014-07-08 18:01:07 +0200513 private Runnable mLaunchTransitionEndRunnable;
514 private boolean mLaunchTransitionFadingAway;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +0200515 private ExpandableNotificationRow mDraggedDownRow;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700516 private boolean mLaunchCameraOnScreenTurningOn;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700517 private boolean mLaunchCameraOnFinishedGoingToSleep;
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700518 private int mLastCameraLaunchSource;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700519 private PowerManager.WakeLock mGestureWakeLock;
Selim Cinek69ff8af2015-08-25 19:03:48 -0700520 private Vibrator mVibrator;
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200521
Christoph Studer2231c6e2014-12-19 12:40:13 +0100522 // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
523 private int mLastLoggedStateFingerprint;
524
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700525 /**
526 * If set, the device has started going to sleep but isn't fully non-interactive yet.
527 */
528 protected boolean mStartedGoingToSleep;
529
Selim Cinek3776fe02016-02-04 13:32:43 -0800530 private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_HUN
Chris Wren35a7c922015-06-22 16:31:01 -0400531 | StackViewState.LOCATION_MAIN_AREA;
Christoph Studer92b389d2014-04-01 18:44:40 +0200532
533 private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
534 new OnChildLocationsChangedListener() {
535 @Override
536 public void onChildLocationsChanged(
537 NotificationStackScrollLayout stackScrollLayout) {
538 if (mHandler.hasCallbacks(mVisibilityReporter)) {
539 // Visibilities will be reported when the existing
540 // callback is executed.
541 return;
542 }
543 // Calculate when we're allowed to run the visibility
544 // reporter. Note that this timestamp might already have
545 // passed. That's OK, the callback will just be executed
546 // ASAP.
547 long nextReportUptimeMs =
548 mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
549 mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
550 }
551 };
552
553 // Tracks notifications currently visible in mNotificationStackScroller and
554 // emits visibility events via NoMan on changes.
555 private final Runnable mVisibilityReporter = new Runnable() {
Chris Wrend1dbc922015-06-19 17:51:16 -0400556 private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
557 new ArraySet<>();
558 private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
559 new ArraySet<>();
560 private final ArraySet<NotificationVisibility> mTmpNoLongerVisibleNotifications =
561 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200562
563 @Override
564 public void run() {
565 mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
Chris Wrend1dbc922015-06-19 17:51:16 -0400566 final String mediaKey = getCurrentMediaNotificationKey();
Christoph Studer92b389d2014-04-01 18:44:40 +0200567
568 // 1. Loop over mNotificationData entries:
569 // A. Keep list of visible notifications.
570 // B. Keep list of previously hidden, now visible notifications.
571 // 2. Compute no-longer visible notifications by removing currently
572 // visible notifications from the set of previously visible
573 // notifications.
574 // 3. Report newly visible and no-longer visible notifications.
575 // 4. Keep currently visible notifications for next report.
Christoph Studerc8db24b2014-07-25 17:50:30 +0200576 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
577 int N = activeNotifications.size();
Christoph Studer92b389d2014-04-01 18:44:40 +0200578 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +0200579 Entry entry = activeNotifications.get(i);
Christoph Studer92b389d2014-04-01 18:44:40 +0200580 String key = entry.notification.getKey();
Chris Wrend1dbc922015-06-19 17:51:16 -0400581 boolean isVisible =
Christoph Studer92b389d2014-04-01 18:44:40 +0200582 (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
Chris Wrend1dbc922015-06-19 17:51:16 -0400583 NotificationVisibility visObj = NotificationVisibility.obtain(key, i, isVisible);
584 boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(visObj);
585 if (isVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +0200586 // Build new set of visible notifications.
Chris Wrend1dbc922015-06-19 17:51:16 -0400587 mTmpCurrentlyVisibleNotifications.add(visObj);
588 if (!previouslyVisible) {
589 mTmpNewlyVisibleNotifications.add(visObj);
590 }
591 } else {
592 // release object
593 visObj.recycle();
Christoph Studer92b389d2014-04-01 18:44:40 +0200594 }
595 }
Chris Wrend1dbc922015-06-19 17:51:16 -0400596 mTmpNoLongerVisibleNotifications.addAll(mCurrentlyVisibleNotifications);
597 mTmpNoLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200598
599 logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -0400600 mTmpNewlyVisibleNotifications, mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200601
Chris Wrend1dbc922015-06-19 17:51:16 -0400602 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200603 mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
604
Chris Wrend1dbc922015-06-19 17:51:16 -0400605 recycleAllVisibilityObjects(mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200606 mTmpCurrentlyVisibleNotifications.clear();
Chris Wrend1dbc922015-06-19 17:51:16 -0400607 mTmpNewlyVisibleNotifications.clear();
608 mTmpNoLongerVisibleNotifications.clear();
Christoph Studer92b389d2014-04-01 18:44:40 +0200609 }
610 };
611
Chris Wrend1dbc922015-06-19 17:51:16 -0400612 private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
613 final int N = array.size();
614 for (int i = 0 ; i < N; i++) {
615 array.valueAt(i).recycle();
616 }
617 array.clear();
618 }
619
Jorim Jaggiecbab362014-04-23 16:13:15 +0200620 private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
621 @Override
622 public void onClick(View v) {
623 goToLockedShade(null);
624 }
625 };
Selim Cinekb5605e52015-02-20 18:21:41 +0100626 private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
627 = new HashMap<>();
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700628 private RankingMap mLatestRankingMap;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700629 private boolean mNoAnimationOnNextBarModeChange;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700630 private FalsingManager mFalsingManager;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200631
Joe Onorato808182d2010-07-09 18:52:06 -0400632 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400633 public void start() {
634 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
635 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400636 updateDisplaySize();
Jorim Jaggi0e664392014-09-27 01:30:22 +0200637 mScrimSrcModeEnabled = mContext.getResources().getBoolean(
638 R.bool.config_status_bar_scrim_behind_use_src);
Adrian Roos75fa3852015-01-27 20:21:44 +0100639
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500640 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400641
Dan Sandler16128f42014-05-21 12:48:22 -0400642 mMediaSessionManager
643 = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
644 // TODO: use MediaSessionManager.SessionListener to hook us up to future updates
645 // in session state
646
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400647 addNavigationBar();
648
Joe Onorato808182d2010-07-09 18:52:06 -0400649 // Lastly, call to the icon policy to install/update all the icons.
Jason Monk07473ce2016-01-05 14:59:19 -0500650 mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCastController,
Jason Monk3e189872016-01-12 09:10:34 -0500651 mHotspotController, mUserInfoController, mBluetoothController,
Jason Monkf23aa992016-01-22 16:45:21 -0500652 mRotationLockController, mNetworkController.getDataSaverController());
John Spurlock604a5ee2015-06-01 12:27:22 -0400653 mIconPolicy.setCurrentUserSetup(mUserSetup);
John Spurlocke677d712014-02-13 12:52:19 -0500654 mSettingsObserver.onChange(false); // set up
Chris Wrenf6e83f42013-09-11 14:02:59 -0400655
656 mHeadsUpObserver.onChange(true); // set up
657 if (ENABLE_HEADS_UP) {
658 mContext.getContentResolver().registerContentObserver(
Chris Wren10d82df2014-03-01 10:34:51 -0500659 Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
Chris Wrenf6e83f42013-09-11 14:02:59 -0400660 mHeadsUpObserver);
Chris Wren22ae46e2014-02-26 18:08:09 -0500661 mContext.getContentResolver().registerContentObserver(
662 Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
663 mHeadsUpObserver);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400664 }
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200665 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Christoph Studer2231c6e2014-12-19 12:40:13 +0100666 mUnlockMethodCache.addListener(this);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100667 startKeyguard();
John Spurlockbf370992014-06-17 13:58:31 -0400668
669 mDozeServiceHost = new DozeServiceHost();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700670 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mDozeServiceHost);
Jeff Brown4d69e222014-09-18 15:27:50 -0700671 putComponent(DozeHost.class, mDozeServiceHost);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200672 putComponent(PhoneStatusBar.class, this);
John Spurlock89f060a2014-07-16 21:03:15 -0400673
674 setControllerUsers();
Chris Wrencd8f4f72014-08-27 18:48:13 -0400675
676 notifyUserAboutHiddenNotifications();
Jason Monk18f99d92014-09-11 13:36:42 -0400677
678 mScreenPinningRequest = new ScreenPinningRequest(mContext);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700679 mFalsingManager = FalsingManager.getInstance(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400680 }
681
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700682 protected void createIconController() {
683 mIconController = new StatusBarIconController(
684 mContext, mStatusBarView, mKeyguardStatusBar, this);
685 }
686
Joe Onorato808182d2010-07-09 18:52:06 -0400687 // ================================================================================
688 // Constructing the view
689 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700690 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400691 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400692
Daniel Sandler6e8db882011-10-26 15:40:51 -0400693 updateDisplaySize(); // populates mDisplayMetrics
Jorim Jaggi2e115c52014-07-01 21:27:58 +0200694 updateResources();
Joe Onorato808182d2010-07-09 18:52:06 -0400695
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800696 inflateStatusBarWindow(context);
Selim Cinek4e6b2d32015-06-25 20:15:33 -0400697 mStatusBarWindow.setService(this);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400698 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
699 @Override
700 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400701 checkUserAutohide(v, event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400702 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500703 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400704 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400705 }
706 }
Chris Wren5de6e942012-05-16 14:22:21 -0400707 return mStatusBarWindow.onTouchEvent(event);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700708 }
709 });
Daniel Sandler21b274e2012-05-02 15:07:51 -0400710
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100711 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
712 R.id.notification_panel);
Daniel Sandler040c2e42012-10-17 00:56:33 -0400713 mNotificationPanel.setStatusBar(this);
Selim Cinek53f8e7d2016-03-25 02:28:01 -0700714 mNotificationPanel.setGroupManager(mGroupManager);
Joe Onorato808182d2010-07-09 18:52:06 -0400715
Xiaohui Chen9f967112016-01-07 14:14:06 -0800716 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
717 mStatusBarView.setBar(this);
718 mStatusBarView.setPanel(mNotificationPanel);
719
Jeff Brown98365d72012-08-19 20:30:52 -0700720 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700721 mStatusBarWindow.setBackground(null);
Alan Viverette4a357cd2015-03-18 18:37:18 -0700722 mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
Romain Guy648342f2012-05-25 10:44:45 -0700723 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700724 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700725
Selim Cinek83bc7832015-10-22 13:26:54 -0700726 mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700727 mHeadsUpManager.setBar(this);
728 mHeadsUpManager.addListener(this);
729 mHeadsUpManager.addListener(mNotificationPanel);
Selim Cinekef5127e2015-12-21 16:55:58 -0800730 mHeadsUpManager.addListener(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700731 mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
Selim Cinekfbe9a442015-04-13 16:09:49 -0700732 mNotificationData.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700733
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400734 if (MULTIUSER_DEBUG) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100735 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
736 R.id.header_debug_info);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400737 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
738 }
Joe Onorato808182d2010-07-09 18:52:06 -0400739
Daniel Sandler0129b312011-05-11 11:54:11 -0400740 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700741 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400742 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400743 if (showNav) {
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800744 createNavigationBarView(context);
Daniel Sandler0129b312011-05-11 11:54:11 -0400745 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400746 } catch (RemoteException ex) {
747 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400748 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400749
Selim Cineke70d6532015-04-24 16:46:13 -0700750 mAssistManager = new AssistManager(this, context);
751
Joe Onorato808182d2010-07-09 18:52:06 -0400752 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400753 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400754
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100755 mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
756 R.id.notification_stack_scroller);
757 mStackScroller.setLongPressListener(getNotificationLongClicker());
Mady Mellor4b80b102016-01-22 08:03:58 -0800758 mStackScroller.setGearDisplayedListener(getGearDisplayedListener());
Selim Cinek19c8c702014-08-25 22:09:19 +0200759 mStackScroller.setPhoneStatusBar(this);
Selim Cinekb5605e52015-02-20 18:21:41 +0100760 mStackScroller.setGroupManager(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700761 mStackScroller.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb5605e52015-02-20 18:21:41 +0100762 mGroupManager.setOnGroupChangeListener(mStackScroller);
Selim Cinek80a14e52014-03-27 16:58:04 +0100763
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200764 mKeyguardIconOverflowContainer =
765 (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
766 R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
767 mKeyguardIconOverflowContainer.setOnActivatedListener(this);
Jorim Jaggie96fcd12014-05-07 21:10:35 +0200768 mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
Selim Cinek2cd45df2015-06-09 18:00:07 -0700769 mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
Jorim Jaggid4a57442014-04-10 02:45:55 +0200770
Selim Cinek4fd5dfc2016-01-19 15:16:15 -0800771
Selim Cinek01af3342016-02-09 19:25:31 -0800772 inflateEmptyShadeView();
773 inflateDismissView();
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100774 mExpandedContents = mStackScroller;
Selim Cinek67b22602014-03-10 15:40:16 +0100775
Selim Cineka0fad3b2014-09-19 17:20:05 +0200776 mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
777 mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
778 mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
779
780 ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
781 ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
Selim Cinekaac93252015-04-14 20:04:12 -0700782 View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
Xiaohui Chen5da71352016-02-22 10:04:41 -0800783 mScrimController = SystemUIFactory.getInstance().createScrimController(
Selim Cinek25503252016-03-03 15:31:43 -0800784 scrimBehind, scrimInFront, headsUpScrim);
785 if (mScrimSrcModeEnabled) {
786 Runnable runnable = new Runnable() {
787 @Override
788 public void run() {
789 boolean asSrc = mBackdrop.getVisibility() != View.VISIBLE;
790 mScrimController.setDrawBehindAsSrc(asSrc);
791 mStackScroller.setDrawBackgroundAsSrc(asSrc);
792 }
793 };
794 mBackdrop.setOnVisibilityChangedRunnable(runnable);
795 runnable.run();
796 }
Selim Cinekaac93252015-04-14 20:04:12 -0700797 mHeadsUpManager.addListener(mScrimController);
798 mStackScroller.setScrimController(mScrimController);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200799 mStatusBarView.setScrimController(mScrimController);
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100800 mDozeScrimController = new DozeScrimController(mScrimController, context);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200801
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200802 mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200803 mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200804 mKeyguardBottomArea =
805 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
806 mKeyguardBottomArea.setActivityStarter(this);
Selim Cineke70d6532015-04-24 16:46:13 -0700807 mKeyguardBottomArea.setAssistManager(mAssistManager);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200808 mKeyguardIndicationController = new KeyguardIndicationController(mContext,
809 (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700810 R.id.keyguard_indication_text),
811 mKeyguardBottomArea.getLockIcon());
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200812 mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400813
Adrian Roose381c162016-02-11 15:26:42 -0800814 if (ENABLE_LOCKSCREEN_WALLPAPER) {
815 mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
816 }
817
Xiaohui Chenf43491f2016-02-01 12:19:35 -0800818 // set the initial view visibility
Joe Onorato808182d2010-07-09 18:52:06 -0400819 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400820
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700821 createIconController();
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100822
Jason Monk4ae97d32014-12-17 10:14:33 -0500823 // Background thread for any controllers that need it.
824 mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
825 mHandlerThread.start();
826
Daniel Sandler2b697352011-07-22 16:23:09 -0400827 // Other icons
Jason Monk05b86bc2015-05-19 14:21:28 -0400828 mLocationController = new LocationControllerImpl(mContext,
829 mHandlerThread.getLooper()); // will post a notification
Daniel Sandler2b697352011-07-22 16:23:09 -0400830 mBatteryController = new BatteryController(mContext);
John Spurlock0ff62e02014-07-22 16:15:08 -0400831 mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
832 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500833 public void onPowerSaveChanged(boolean isPowerSave) {
John Spurlock0ff62e02014-07-22 16:15:08 -0400834 mHandler.post(mCheckBarModes);
John Spurlockd96179e2014-08-21 16:43:45 -0400835 if (mDozeServiceHost != null) {
Jason Monkc06fbb12016-01-08 14:12:18 -0500836 mDozeServiceHost.firePowerSaveChanged(isPowerSave);
John Spurlockd96179e2014-08-21 16:43:45 -0400837 }
John Spurlock0ff62e02014-07-22 16:15:08 -0400838 }
839 @Override
840 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
841 // noop
842 }
843 });
Jason Monk30d80042015-05-08 16:54:18 -0400844 mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk51e4dc02014-07-22 12:00:47 -0400845 mHotspotController = new HotspotControllerImpl(mContext);
Jason Monk4ae97d32014-12-17 10:14:33 -0500846 mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk3d5f5512014-07-25 11:17:28 -0400847 mSecurityController = new SecurityControllerImpl(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400848 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
849 mRotationLockController = new RotationLockControllerImpl(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500850 }
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200851 mUserInfoController = new UserInfoController(mContext);
John Spurlock86005342014-05-23 11:58:00 -0400852 mVolumeComponent = getComponent(VolumeComponent.class);
John Spurlockf2565a82014-10-23 20:16:22 -0400853 if (mVolumeComponent != null) {
854 mZenModeController = mVolumeComponent.getZenController();
855 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400856 mCastController = new CastControllerImpl(mContext);
Xiaohui Chen10942302015-12-16 16:38:13 -0800857
858 initSignalCluster(mStatusBarView);
859 initSignalCluster(mKeyguardStatusBar);
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400860
Adrian Roosb83777b2014-06-30 15:11:53 +0200861 mFlashlightController = new FlashlightController(mContext);
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200862 mKeyguardBottomArea.setFlashlightController(mFlashlightController);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200863 mKeyguardBottomArea.setPhoneStatusBar(this);
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700864 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200865 mAccessibilityController = new AccessibilityController(mContext);
866 mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200867 mNextAlarmController = new NextAlarmController(mContext);
Jorim Jaggi86905582016-02-09 21:36:09 -0800868 mLightStatusBarController = new LightStatusBarController(mIconController,
869 mBatteryController);
Jason Monk8a3a9642015-06-05 11:01:30 -0400870 mKeyguardMonitor = new KeyguardMonitor(mContext);
Fyodor Kupolovcd86ebf2015-09-29 17:06:50 -0700871 if (UserManager.get(mContext).isUserSwitcherEnabled()) {
Adrian Roos88b11932015-07-22 14:59:48 -0700872 mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
Sudheer Shanka1c7cda82015-12-31 14:46:02 +0000873 mHandler, this);
Rakesh Iyer2790a372016-01-22 15:33:39 -0800874 createUserSwitcher();
Adrian Roos2b154a92014-11-17 15:18:39 +0100875 }
Adrian Roos723632e2014-07-23 21:13:21 +0200876
John Spurlockaf8d6c42014-05-07 17:49:08 -0400877 // Set up the quick settings tile panel
Jason Monk46dbfb42016-02-25 14:59:20 -0500878 DensityContainer container = (DensityContainer) mStatusBarWindow.findViewById(
879 R.id.qs_density_container);
880 if (container != null) {
Xiaohui Chen311b98e2016-03-30 11:55:54 -0700881 final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
John Spurlockaf8d6c42014-05-07 17:49:08 -0400882 mBluetoothController, mLocationController, mRotationLockController,
Jason Monk51e4dc02014-07-22 12:00:47 -0400883 mNetworkController, mZenModeController, mHotspotController,
John Spurlock657c62c2014-07-22 12:18:09 -0400884 mCastController, mFlashlightController,
Jason Monkabe19742015-09-29 09:47:06 -0400885 mUserSwitcherController, mUserInfoController, mKeyguardMonitor,
Jason Monk46dbfb42016-02-25 14:59:20 -0500886 mSecurityController, mBatteryController, mIconController,
887 mNextAlarmController);
Adrian Roos5fd872e2014-08-12 17:28:58 +0200888 mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
Jason Monk46dbfb42016-02-25 14:59:20 -0500889 container.addInflateListener(new InflateListener() {
John Spurlockbceed062014-08-10 18:04:16 -0400890 @Override
Jason Monk46dbfb42016-02-25 14:59:20 -0500891 public void onInflated(View v) {
892 QSContainer qsContainer = (QSContainer) v.findViewById(
893 R.id.quick_settings_container);
894 qsContainer.setHost(qsh);
895 mQSPanel = qsContainer.getQsPanel();
896 mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
897 mHeader = qsContainer.getHeader();
898 initSignalCluster(mHeader);
899 mHeader.setActivityStarter(PhoneStatusBar.this);
John Spurlockbceed062014-08-10 18:04:16 -0400900 }
901 });
Siva Velusamy537421b2012-09-14 14:45:02 -0700902 }
903
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200904 // User info. Trigger first load.
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200905 mKeyguardStatusBar.setUserInfoController(mUserInfoController);
Adrian Roosffc90972015-06-09 18:09:49 -0700906 mKeyguardStatusBar.setUserSwitcherController(mUserSwitcherController);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200907 mUserInfoController.reloadUserInfo();
908
Jorim Jaggi708f7722014-08-20 17:30:38 +0200909 ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
910 mBatteryController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200911 mKeyguardStatusBar.setBatteryController(mBatteryController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200912
John Spurlock56d007b2013-10-28 18:40:56 -0400913 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
914 mBroadcastReceiver.onReceive(mContext,
915 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
Selim Cinek372d1bd2015-08-14 13:19:37 -0700916 mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
917 "GestureWakeLock");
Selim Cinek69ff8af2015-08-25 19:03:48 -0700918 mVibrator = mContext.getSystemService(Vibrator.class);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700919
Joe Onorato808182d2010-07-09 18:52:06 -0400920 // receive broadcasts
921 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400922 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
923 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400924 filter.addAction(Intent.ACTION_SCREEN_ON);
Kenny Guy44fc65f2014-11-28 22:18:14 +0000925 context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400926
Adrian Roos8e3e8362015-07-16 19:42:22 -0700927 IntentFilter demoFilter = new IntentFilter();
928 if (DEBUG_MEDIA_FAKE_ARTWORK) {
929 demoFilter.addAction(ACTION_FAKE_ARTWORK);
930 }
931 demoFilter.addAction(ACTION_DEMO);
932 context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
933 android.Manifest.permission.DUMP, null);
934
John Spurlock919adac2012-10-02 16:41:12 -0400935 // listen for USER_SETUP_COMPLETE setting (per-user)
936 resetUserSetupObserver();
937
Chris Craik2507c342015-05-04 14:36:49 -0700938 // disable profiling bars, since they overlap and clutter the output on app windows
939 ThreadedRenderer.overrideProperty("disableProfileBars", "true");
940
941 // Private API call to make the shadows look better for Recents
942 ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
943
Daniel Sandlera310af82012-04-24 01:20:13 -0400944 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -0400945 }
946
Selim Cinek01af3342016-02-09 19:25:31 -0800947 @Override
948 protected void reInflateViews() {
949 super.reInflateViews();
950 inflateDismissView();
951 updateClearAll();
952 inflateEmptyShadeView();
953 updateEmptyShadeView();
954 }
955
956 private void inflateEmptyShadeView() {
957 mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
958 R.layout.status_bar_no_notifications, mStackScroller, false);
959 mStackScroller.setEmptyShadeView(mEmptyShadeView);
960 }
961
962 private void inflateDismissView() {
963 mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
964 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
965 mDismissView.setOnButtonClickListener(new View.OnClickListener() {
966 @Override
967 public void onClick(View v) {
968 MetricsLogger.action(mContext, MetricsEvent.ACTION_DISMISS_ALL_NOTES);
969 clearAllNotifications();
970 }
971 });
972 mStackScroller.setDismissView(mDismissView);
973 }
974
Rakesh Iyer2790a372016-01-22 15:33:39 -0800975 protected void createUserSwitcher() {
976 mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
977 (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
978 mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
979 }
980
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800981 protected void inflateStatusBarWindow(Context context) {
982 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
983 R.layout.super_status_bar, null);
984 }
985
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800986 protected void createNavigationBarView(Context context) {
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -0800987 inflateNavigationBarView(context);
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800988 mNavigationBarView.setDisabledFlags(mDisabled1);
989 mNavigationBarView.setComponents(mRecents, getComponent(Divider.class));
990 mNavigationBarView.setOnVerticalChangedListener(
991 new NavigationBarView.OnVerticalChangedListener() {
992 @Override
993 public void onVerticalChanged(boolean isVertical) {
994 if (mAssistManager != null) {
995 mAssistManager.onConfigurationChanged();
996 }
997 mNotificationPanel.setQsScrimEnabled(!isVertical);
998 }
999 });
1000 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
1001 @Override
1002 public boolean onTouch(View v, MotionEvent event) {
1003 checkUserAutohide(v, event);
1004 return false;
1005 }});
1006 }
1007
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001008 protected void inflateNavigationBarView(Context context) {
Jason Monk4f878ef2016-01-23 14:37:38 -05001009 mNavigationBarView = (NavigationBarView) View.inflate(
1010 context, R.layout.navigation_bar, null);
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001011 }
1012
1013 protected void initSignalCluster(View containerView) {
Xiaohui Chen10942302015-12-16 16:38:13 -08001014 SignalClusterView signalCluster =
1015 (SignalClusterView) containerView.findViewById(R.id.signal_cluster);
1016 if (signalCluster != null) {
Xiaohui Chen10942302015-12-16 16:38:13 -08001017 signalCluster.setSecurityController(mSecurityController);
1018 signalCluster.setNetworkController(mNetworkController);
1019 }
1020 }
1021
Muyuan Lic510b5e2016-03-09 17:15:05 -08001022 public void clearAllNotifications() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001023
1024 // animate-swipe all dismissable notifications, then animate the shade closed
1025 int numChildren = mStackScroller.getChildCount();
1026
1027 final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
1028 for (int i = 0; i < numChildren; i++) {
1029 final View child = mStackScroller.getChildAt(i);
Selim Cinekb5605e52015-02-20 18:21:41 +01001030 if (child instanceof ExpandableNotificationRow) {
1031 if (mStackScroller.canChildBeDismissed(child)) {
1032 if (child.getVisibility() == View.VISIBLE) {
1033 viewsToHide.add(child);
1034 }
1035 }
1036 ExpandableNotificationRow row = (ExpandableNotificationRow) child;
1037 List<ExpandableNotificationRow> children = row.getNotificationChildren();
1038 if (row.areChildrenExpanded() && children != null) {
1039 for (ExpandableNotificationRow childRow : children) {
1040 if (childRow.getVisibility() == View.VISIBLE) {
1041 viewsToHide.add(childRow);
1042 }
1043 }
Dan Sandlereceda3d2014-07-21 15:35:01 -04001044 }
1045 }
1046 }
1047 if (viewsToHide.isEmpty()) {
1048 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1049 return;
1050 }
1051
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001052 addPostCollapseAction(new Runnable() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001053 @Override
1054 public void run() {
Selim Cinek9c17b772015-07-07 20:37:09 -07001055 mStackScroller.setDismissAllInProgress(false);
Dan Sandlereceda3d2014-07-21 15:35:01 -04001056 try {
1057 mBarService.onClearAllNotifications(mCurrentUserId);
1058 } catch (Exception ex) { }
1059 }
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001060 });
Dan Sandlereceda3d2014-07-21 15:35:01 -04001061
1062 performDismissAllAnimations(viewsToHide);
1063
1064 }
1065
1066 private void performDismissAllAnimations(ArrayList<View> hideAnimatedList) {
1067 Runnable animationFinishAction = new Runnable() {
1068 @Override
1069 public void run() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001070 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1071 }
1072 };
1073
1074 // let's disable our normal animations
1075 mStackScroller.setDismissAllInProgress(true);
1076
1077 // Decrease the delay for every row we animate to give the sense of
1078 // accelerating the swipes
1079 int rowDelayDecrement = 10;
1080 int currentDelay = 140;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001081 int totalDelay = 180;
Dan Sandlereceda3d2014-07-21 15:35:01 -04001082 int numItems = hideAnimatedList.size();
Selim Cinek7d5f3742014-11-07 18:07:49 +01001083 for (int i = numItems - 1; i >= 0; i--) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001084 View view = hideAnimatedList.get(i);
1085 Runnable endRunnable = null;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001086 if (i == 0) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001087 endRunnable = animationFinishAction;
1088 }
1089 mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
1090 currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
1091 totalDelay += currentDelay;
1092 }
1093 }
1094
John Spurlockae641c92014-06-30 18:11:40 -04001095 @Override
1096 protected void setZenMode(int mode) {
1097 super.setZenMode(mode);
1098 if (mIconPolicy != null) {
1099 mIconPolicy.setZenMode(mode);
1100 }
1101 }
1102
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001103 protected void startKeyguard() {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001104 KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001105 mFingerprintUnlockController = new FingerprintUnlockController(mContext,
1106 mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator,
1107 mScrimController, this);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001108 mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001109 getBouncerContainer(), mStatusBarWindowManager, mScrimController,
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001110 mFingerprintUnlockController);
Selim Cinekcfafe4e2015-08-11 14:58:44 -07001111 mKeyguardIndicationController.setStatusBarKeyguardViewManager(
1112 mStatusBarKeyguardViewManager);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001113 mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
Adrian Roosd28ccd72016-01-06 15:23:14 +01001114 mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
Adrian Roosc0a579e2016-03-30 16:43:58 -07001115
1116 if (FORCE_REMOTE_INPUT_HISTORY) {
1117 mRemoteInputController.addCallback(new RemoteInputController.Callback() {
1118 @Override
1119 public void onRemoteInputSent(Entry entry) {
1120 if (mKeysKeptForRemoteInput.contains(entry.key)) {
1121 removeNotification(entry.key, null);
1122 }
1123 }
1124 });
1125 }
1126
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001127 mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
Jorim Jaggi86905582016-02-09 21:36:09 -08001128 mLightStatusBarController.setFingerprintUnlockController(mFingerprintUnlockController);
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001129 }
1130
Michael Jurka7f2668c2012-03-27 07:49:52 -07001131 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -07001132 protected View getStatusBarView() {
1133 return mStatusBarView;
1134 }
1135
Jorim Jaggi0a27be82014-06-11 03:22:39 +02001136 public StatusBarWindowView getStatusBarWindow() {
1137 return mStatusBarWindow;
1138 }
1139
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001140 protected ViewGroup getBouncerContainer() {
1141 return mStatusBarWindow;
1142 }
1143
Joe Onoratodc100302011-01-11 17:07:41 -08001144 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -04001145 if (mNaturalBarHeight < 0) {
1146 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -07001147 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -04001148 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
1149 }
1150 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -08001151 }
1152
Daniel Sandler5c8da942011-06-28 00:29:04 -04001153 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
1154 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -04001155 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001156 toggleRecentApps();
1157 }
1158 };
Chris Wren0c8275b2012-05-08 13:36:48 -04001159
Jorim Jaggi75b25972015-10-21 14:51:10 +02001160 private View.OnLongClickListener mLongPressBackListener = new View.OnLongClickListener() {
Jason Monk62515be2014-05-21 16:06:19 -04001161 @Override
1162 public boolean onLongClick(View v) {
Jorim Jaggi75b25972015-10-21 14:51:10 +02001163 return handleLongPressBack();
1164 }
1165 };
1166
1167 private View.OnLongClickListener mRecentsLongClickListener = new View.OnLongClickListener() {
1168
1169 @Override
1170 public boolean onLongClick(View v) {
Winsonc694a502016-03-10 16:35:03 -08001171 if (mRecents == null || !ActivityManager.supportsMultiWindow()) {
Phil Weaver315c34e2016-02-19 15:12:29 -08001172 return false;
1173 }
Winsonc694a502016-03-10 16:35:03 -08001174
Phil Weaver315c34e2016-02-19 15:12:29 -08001175 boolean initiallyDocked = WindowManagerProxy.getInstance().getDockSide()
1176 == WindowManager.DOCKED_INVALID;
1177 boolean dockedAtEnd = toggleSplitScreenMode();
1178 if (dockedAtEnd != initiallyDocked) {
1179 int logAction = dockedAtEnd ? MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS
1180 : MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS;
1181 MetricsLogger.action(mContext, logAction);
1182 return true;
Jorim Jaggi75b25972015-10-21 14:51:10 +02001183 }
1184 return false;
Jason Monk62515be2014-05-21 16:06:19 -04001185 }
1186 };
1187
Phil Weaver315c34e2016-02-19 15:12:29 -08001188 @Override
1189 protected boolean toggleSplitScreenMode() {
1190 if (mRecents == null) {
1191 return false;
1192 }
1193 int dockSide = WindowManagerProxy.getInstance().getDockSide();
1194 if (dockSide == WindowManager.DOCKED_INVALID) {
Phil Weaver315c34e2016-02-19 15:12:29 -08001195 return mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
Muyuan Lia2129992016-03-03 18:30:39 -08001196 ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null);
Phil Weaver315c34e2016-02-19 15:12:29 -08001197 } else {
1198 EventBus.getDefault().send(new UndockingTaskEvent());
1199 return false;
1200 }
1201 }
1202
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001203 private final View.OnLongClickListener mLongPressHomeListener
1204 = new View.OnLongClickListener() {
1205 @Override
1206 public boolean onLongClick(View v) {
1207 if (shouldDisableNavbarGestures()) {
1208 return false;
1209 }
Chris Wrenf6e9228b2016-01-26 18:04:35 -05001210 MetricsLogger.action(mContext, MetricsEvent.ACTION_ASSIST_LONG_PRESS);
Jorim Jaggi165ce062015-07-06 16:18:11 -07001211 mAssistManager.startAssist(new Bundle() /* args */);
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001212 awakenDreams();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001213 if (mNavigationBarView != null) {
Xiyuan Xiaee7dd052015-05-15 09:46:27 -07001214 mNavigationBarView.abortCurrentGesture();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001215 }
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001216 return true;
Jim Miller9a720f52012-05-30 03:19:43 -07001217 }
1218 };
1219
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001220 private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
Jim Millere898ac52012-04-06 17:10:57 -07001221 public boolean onTouch(View v, MotionEvent event) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001222 switch (event.getAction()) {
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001223 case MotionEvent.ACTION_UP:
1224 case MotionEvent.ACTION_CANCEL:
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001225 awakenDreams();
1226 break;
1227 }
1228 return false;
Jim Millere898ac52012-04-06 17:10:57 -07001229 }
1230 };
Daniel Sandler5c8da942011-06-28 00:29:04 -04001231
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001232 private void awakenDreams() {
1233 if (mDreamManager != null) {
1234 try {
1235 mDreamManager.awaken();
1236 } catch (RemoteException e) {
1237 // fine, stay asleep then
1238 }
1239 }
1240 }
1241
Michael Jurka412cba82011-10-17 09:05:00 -07001242 private void prepareNavigationBarView() {
1243 mNavigationBarView.reorient();
1244
Jason Monka2081822016-01-18 14:41:03 -05001245 ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
1246 recentsButton.setOnClickListener(mRecentsClickListener);
1247 recentsButton.setOnTouchListener(mRecentsPreloadOnTouchListener);
1248 recentsButton.setLongClickable(true);
1249 recentsButton.setOnLongClickListener(mRecentsLongClickListener);
Anthony Chenada13042016-01-19 16:57:20 -08001250
Jason Monka2081822016-01-18 14:41:03 -05001251 ButtonDispatcher backButton = mNavigationBarView.getBackButton();
1252 backButton.setLongClickable(true);
1253 backButton.setOnLongClickListener(mLongPressBackListener);
Anthony Chenada13042016-01-19 16:57:20 -08001254
Jason Monka2081822016-01-18 14:41:03 -05001255 ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
1256 homeButton.setOnTouchListener(mHomeActionListener);
1257 homeButton.setOnLongClickListener(mLongPressHomeListener);
Anthony Chenada13042016-01-19 16:57:20 -08001258
Selim Cineke70d6532015-04-24 16:46:13 -07001259 mAssistManager.onConfigurationChanged();
Michael Jurka412cba82011-10-17 09:05:00 -07001260 }
1261
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001262 // For small-screen devices (read: phones) that lack hardware navigation buttons
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001263 protected void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -04001264 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -04001265 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001266
Michael Jurka412cba82011-10-17 09:05:00 -07001267 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001268
Jeff Brown98365d72012-08-19 20:30:52 -07001269 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001270 }
1271
Victor Chanecdb8b02016-01-07 18:32:43 -08001272 protected void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -04001273 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001274
Michael Jurka412cba82011-10-17 09:05:00 -07001275 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001276
Jeff Brown98365d72012-08-19 20:30:52 -07001277 mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001278 }
1279
John Spurlock1bbd49d2012-10-19 11:09:32 -04001280 private void notifyNavigationBarScreenOn(boolean screenOn) {
1281 if (mNavigationBarView == null) return;
1282 mNavigationBarView.notifyScreenOn(screenOn);
1283 }
1284
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001285 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001286 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001287 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001288 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
1289 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001290 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1291 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -07001292 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -04001293 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jim Millerd99e7fd2012-05-08 16:30:42 -07001294 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
John Spurlockad3e6cb2013-04-30 08:47:43 -04001295 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001296 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -07001297 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001298 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
1299 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001300
1301 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001302 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001303 return lp;
1304 }
1305
Jason Monk07473ce2016-01-05 14:59:19 -05001306 @Override
1307 public void setIcon(String slot, StatusBarIcon icon) {
1308 mIconController.setIcon(slot, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001309 }
1310
Jason Monk07473ce2016-01-05 14:59:19 -05001311 @Override
1312 public void removeIcon(String slot) {
1313 mIconController.removeIcon(slot);
Joe Onorato808182d2010-07-09 18:52:06 -04001314 }
1315
John Spurlockbf20eab2014-04-09 16:40:39 -04001316 public UserHandle getCurrentUserHandle() {
1317 return new UserHandle(mCurrentUserId);
1318 }
1319
Christoph Studer71f18fd2014-05-20 17:02:04 +02001320 @Override
Selim Cinek379ff8f2015-02-20 17:03:16 +01001321 public void addNotification(StatusBarNotification notification, RankingMap ranking,
1322 Entry oldEntry) {
Chris Wrenaaa58d12014-06-03 14:29:12 -04001323 if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
Chris Wrend4db6cb2013-08-07 16:05:23 -04001324
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001325 mNotificationData.updateRanking(ranking);
Selim Cinek8d490d42015-04-10 00:05:50 -07001326 Entry shadeEntry = createNotificationViews(notification);
Chris Wrena4ef6202014-06-09 18:07:30 -04001327 if (shadeEntry == null) {
1328 return;
1329 }
Chris Wrenbdf33762015-12-04 15:50:51 -05001330 boolean isHeadsUped = mUseHeadsUp && shouldPeek(shadeEntry);
Selim Cinek31d9ef72015-04-15 19:29:49 -07001331 if (isHeadsUped) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001332 mHeadsUpManager.showNotification(shadeEntry);
Amith Yamasanif47e51e2015-04-17 10:02:15 -07001333 // Mark as seen immediately
1334 setNotificationShown(notification);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001335 }
Chris Wrena4ef6202014-06-09 18:07:30 -04001336
Selim Cinek31d9ef72015-04-15 19:29:49 -07001337 if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
Julia Reynoldsd5607292016-02-05 15:25:58 -05001338 if (shouldSuppressFullScreenIntent(notification.getKey())) {
Julia Reynolds61721582016-01-05 08:35:25 -05001339 if (DEBUG) {
1340 Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + notification.getKey());
1341 }
Julia Reynoldsf0f629f2016-02-25 09:34:04 -05001342 } else if (mNotificationData.getImportance(notification.getKey())
1343 < NotificationListenerService.Ranking.IMPORTANCE_MAX) {
1344 if (DEBUG) {
1345 Log.d(TAG, "No Fullscreen intent: not important enough: "
1346 + notification.getKey());
1347 }
Julia Reynolds61721582016-01-05 08:35:25 -05001348 } else {
1349 // Stop screensaver if the notification has a full-screen intent.
1350 // (like an incoming phone call)
1351 awakenDreams();
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -04001352
Julia Reynolds61721582016-01-05 08:35:25 -05001353 // not immersive & a full-screen alert should be shown
1354 if (DEBUG)
1355 Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
1356 try {
1357 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
1358 notification.getKey());
1359 notification.getNotification().fullScreenIntent.send();
1360 shadeEntry.notifyFullScreenIntentLaunched();
1361 MetricsLogger.count(mContext, "note_fullscreen", 1);
1362 } catch (PendingIntent.CanceledException e) {
1363 }
John Spurlockbf20eab2014-04-09 16:40:39 -04001364 }
Joe Onorato808182d2010-07-09 18:52:06 -04001365 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001366 addNotificationViews(shadeEntry, ranking);
Joe Onorato808182d2010-07-09 18:52:06 -04001367 // Recalculate the position of the sliding windows and the titles.
1368 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001369 }
1370
Julia Reynoldsd5607292016-02-05 15:25:58 -05001371 private boolean shouldSuppressFullScreenIntent(String key) {
Julia Reynolds0971cb02016-01-26 17:00:22 -05001372 if (mPowerManager.isInteractive()) {
Julia Reynolds0971cb02016-01-26 17:00:22 -05001373 return mNotificationData.shouldSuppressScreenOn(key);
Julia Reynoldsd5607292016-02-05 15:25:58 -05001374 } else {
1375 return mNotificationData.shouldSuppressScreenOff(key);
Julia Reynolds0971cb02016-01-26 17:00:22 -05001376 }
1377 }
1378
Chris Wren51c75102013-07-16 20:49:17 -04001379 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001380 protected void updateNotificationRanking(RankingMap ranking) {
Chris Wren333a61c2014-05-28 16:40:57 -04001381 mNotificationData.updateRanking(ranking);
Chris Wren333a61c2014-05-28 16:40:57 -04001382 updateNotifications();
1383 }
1384
1385 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001386 public void removeNotification(String key, RankingMap ranking) {
Selim Cinek684a4422015-04-15 16:18:39 -07001387 boolean deferRemoval = false;
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001388 if (mHeadsUpManager.isHeadsUp(key)) {
Selim Cinek684a4422015-04-15 16:18:39 -07001389 deferRemoval = !mHeadsUpManager.removeNotification(key);
Chris Wrena4ef6202014-06-09 18:07:30 -04001390 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001391 if (key.equals(mMediaNotificationKey)) {
1392 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -08001393 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001394 }
Adrian Roosc0a579e2016-03-30 16:43:58 -07001395 if (FORCE_REMOTE_INPUT_HISTORY && mRemoteInputController.isSpinning(key)) {
1396 Entry entry = mNotificationData.get(key);
1397 StatusBarNotification sbn = entry.notification;
1398
1399 Notification.Builder b = Notification.Builder
1400 .recoverBuilder(mContext, sbn.getNotification().clone());
1401 CharSequence[] oldHistory = sbn.getNotification().extras
1402 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
1403 CharSequence[] newHistory;
1404 if (oldHistory == null) {
1405 newHistory = new CharSequence[1];
1406 } else {
1407 newHistory = new CharSequence[oldHistory.length + 1];
1408 for (int i = 0; i < oldHistory.length; i++) {
1409 newHistory[i + 1] = oldHistory[i];
1410 }
1411 }
1412 newHistory[0] = String.valueOf(entry.remoteInputText);
1413 b.setRemoteInputHistory(newHistory);
1414
1415 Notification newNotification = b.build();
1416
1417 // Undo any compatibility view inflation
1418 newNotification.contentView = sbn.getNotification().contentView;
1419 newNotification.bigContentView = sbn.getNotification().bigContentView;
1420 newNotification.headsUpContentView = sbn.getNotification().headsUpContentView;
1421
1422 StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(),
1423 sbn.getOpPkg(),
1424 sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
1425 0, newNotification, sbn.getUser(), sbn.getPostTime());
1426
1427 updateNotification(newSbn, null);
1428 mKeysKeptForRemoteInput.add(entry.key);
1429 return;
1430 }
Selim Cinek684a4422015-04-15 16:18:39 -07001431 if (deferRemoval) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001432 mLatestRankingMap = ranking;
1433 mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
1434 return;
1435 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001436 StatusBarNotification old = removeNotificationViews(key, ranking);
John Spurlockcd686b52013-06-05 10:13:46 -04001437 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -04001438
1439 if (old != null) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001440 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
Jorim Jaggiba94f882014-08-20 19:23:55 +02001441 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001442 if (mState == StatusBarState.SHADE) {
1443 animateCollapsePanels();
1444 } else if (mState == StatusBarState.SHADE_LOCKED) {
1445 goToKeyguard();
1446 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001447 }
Joe Onorato808182d2010-07-09 18:52:06 -04001448 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001449 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001450 }
1451
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001452 @Override
1453 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001454 if (mNavigationBarView != null) {
1455 mNavigationBarView.setLayoutDirection(layoutDirection);
1456 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001457 }
1458
Christoph Studer37fe6932014-05-26 13:10:30 +02001459 private void updateNotificationShade() {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001460 if (mStackScroller == null) return;
Daniel Sandler26cda272012-05-22 15:44:08 -04001461
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001462 // Do not modify the notifications during collapse.
1463 if (isCollapsing()) {
1464 addPostCollapseAction(new Runnable() {
1465 @Override
1466 public void run() {
1467 updateNotificationShade();
1468 }
1469 });
1470 return;
1471 }
1472
Christoph Studerc8db24b2014-07-25 17:50:30 +02001473 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
Jorim Jaggif6411742014-08-05 17:10:43 +00001474 ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
Christoph Studerc8db24b2014-07-25 17:50:30 +02001475 final int N = activeNotifications.size();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001476 for (int i=0; i<N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001477 Entry ent = activeNotifications.get(i);
1478 int vis = ent.notification.getNotification().visibility;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001479
Christoph Studerc8db24b2014-07-25 17:50:30 +02001480 // Display public version of the notification if we need to redact.
Jorim Jaggiae441282014-08-01 02:45:18 +02001481 final boolean hideSensitive =
1482 !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId());
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001483 boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE;
1484 boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey());
1485 boolean sensitive = (sensitiveNote && hideSensitive) || sensitivePackage;
1486 boolean showingPublic = sensitive && isLockscreenPublicMode();
Sudheer Shankaf5b850e2016-01-25 19:58:59 +00001487 if (showingPublic) {
1488 updatePublicContentView(ent, ent.notification);
1489 }
Selim Cinek3c76d502016-02-19 15:16:33 -08001490 ent.row.setSensitive(sensitive, hideSensitive);
Dan Sandler1b718782014-07-18 12:43:45 -04001491 if (ent.autoRedacted && ent.legacy) {
Jorim Jaggiae441282014-08-01 02:45:18 +02001492 // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
1493 // for legacy auto redacted notifications.
Dan Sandler1b718782014-07-18 12:43:45 -04001494 if (showingPublic) {
1495 ent.row.setShowingLegacyBackground(false);
1496 } else {
1497 ent.row.setShowingLegacyBackground(true);
1498 }
1499 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001500 if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
1501 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
1502 ent.row.getStatusBarNotification());
1503 List<ExpandableNotificationRow> orderedChildren =
1504 mTmpChildOrderMap.get(summary);
1505 if (orderedChildren == null) {
1506 orderedChildren = new ArrayList<>();
1507 mTmpChildOrderMap.put(summary, orderedChildren);
1508 }
1509 orderedChildren.add(ent.row);
1510 } else {
1511 toShow.add(ent.row);
1512 }
1513
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001514 }
1515
Selim Cinekef5127e2015-12-21 16:55:58 -08001516 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001517 for (int i=0; i< mStackScroller.getChildCount(); i++) {
1518 View child = mStackScroller.getChildAt(i);
Jorim Jaggif6411742014-08-05 17:10:43 +00001519 if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
Selim Cinekef5127e2015-12-21 16:55:58 -08001520 toRemove.add((ExpandableNotificationRow) child);
Joe Onorato808182d2010-07-09 18:52:06 -04001521 }
1522 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001523
Selim Cinekef5127e2015-12-21 16:55:58 -08001524 for (ExpandableNotificationRow remove : toRemove) {
1525 if (mGroupManager.isChildInGroupWithSummary(remove.getStatusBarNotification())) {
1526 // we are only transfering this notification to its parent, don't generate an animation
1527 mStackScroller.setChildTransferInProgress(true);
1528 }
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001529 mStackScroller.removeView(remove);
Selim Cinekef5127e2015-12-21 16:55:58 -08001530 mStackScroller.setChildTransferInProgress(false);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001531 }
Selim Cinek2b542422016-03-04 18:10:37 -08001532
1533 removeNotificationChildren();
1534
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001535 for (int i=0; i<toShow.size(); i++) {
1536 View v = toShow.get(i);
1537 if (v.getParent() == null) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001538 mStackScroller.addView(v);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001539 }
1540 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001541
Selim Cinek2b542422016-03-04 18:10:37 -08001542 addNotificationChildrenAndSort();
1543
Christoph Studer37fe6932014-05-26 13:10:30 +02001544 // So after all this work notifications still aren't sorted correctly.
1545 // Let's do that now by advancing through toShow and mStackScroller in
1546 // lock-step, making sure mStackScroller matches what we see in toShow.
1547 int j = 0;
1548 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1549 View child = mStackScroller.getChildAt(i);
1550 if (!(child instanceof ExpandableNotificationRow)) {
1551 // We don't care about non-notification views.
1552 continue;
1553 }
1554
Selim Cinekb5605e52015-02-20 18:21:41 +01001555 ExpandableNotificationRow targetChild = toShow.get(j);
1556 if (child != targetChild) {
1557 // Oops, wrong notification at this position. Put the right one
1558 // here and advance both lists.
1559 mStackScroller.changeViewPosition(targetChild, i);
Christoph Studer37fe6932014-05-26 13:10:30 +02001560 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001561 j++;
Selim Cinekb5605e52015-02-20 18:21:41 +01001562
Christoph Studer37fe6932014-05-26 13:10:30 +02001563 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001564
Selim Cinekb5605e52015-02-20 18:21:41 +01001565 // clear the map again for the next usage
1566 mTmpChildOrderMap.clear();
1567
Christoph Studer37fe6932014-05-26 13:10:30 +02001568 updateRowStates();
Jorim Jaggif6411742014-08-05 17:10:43 +00001569 updateSpeedbump();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001570 updateClearAll();
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001571 updateEmptyShadeView();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001572
Benjamin Franz27cf1462015-04-23 19:36:42 +01001573 updateQsExpansionEnabled();
1574 mShadeUpdates.check();
1575 }
1576
1577 /**
1578 * Disable QS if device not provisioned.
1579 * If the user switcher is simple then disable QS during setup because
1580 * the user intends to use the lock screen user switcher, QS in not needed.
1581 */
1582 private void updateQsExpansionEnabled() {
Jason Monk3ad242d2014-09-15 11:13:35 -04001583 mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
Adrian Roos2b154a92014-11-17 15:18:39 +01001584 && (mUserSetup || mUserSwitcherController == null
Benjamin Franz27cf1462015-04-23 19:36:42 +01001585 || !mUserSwitcherController.isSimpleUserSwitcher())
Adrian Roos21d2a252015-06-01 13:59:59 -07001586 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
1587 && !ONLY_CORE_APPS);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001588 }
1589
Selim Cinek2b542422016-03-04 18:10:37 -08001590 private void addNotificationChildrenAndSort() {
Selim Cinek322ec7e2016-02-11 14:47:06 -08001591 // Let's now add all notification children which are missing
1592 boolean orderChanged = false;
1593 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1594 View view = mStackScroller.getChildAt(i);
1595 if (!(view instanceof ExpandableNotificationRow)) {
1596 // We don't care about non-notification views.
1597 continue;
1598 }
1599
1600 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1601 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1602 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1603
Selim Cinekb5605e52015-02-20 18:21:41 +01001604 for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
1605 childIndex++) {
1606 ExpandableNotificationRow childView = orderedChildren.get(childIndex);
1607 if (children == null || !children.contains(childView)) {
1608 parent.addChildNotification(childView, childIndex);
1609 mStackScroller.notifyGroupChildAdded(childView);
1610 }
1611 }
1612
1613 // Finally after removing and adding has been beformed we can apply the order.
1614 orderChanged |= parent.applyChildOrder(orderedChildren);
1615 }
1616 if (orderChanged) {
1617 mStackScroller.generateChildOrderChangedEvent();
1618 }
1619 }
1620
Selim Cinek2b542422016-03-04 18:10:37 -08001621 private void removeNotificationChildren() {
1622 // First let's remove all children which don't belong in the parents
1623 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
1624 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1625 View view = mStackScroller.getChildAt(i);
1626 if (!(view instanceof ExpandableNotificationRow)) {
1627 // We don't care about non-notification views.
1628 continue;
1629 }
1630
1631 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1632 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1633 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1634
1635 if (children != null) {
1636 toRemove.clear();
1637 for (ExpandableNotificationRow childRow : children) {
1638 if (orderedChildren == null || !orderedChildren.contains(childRow)) {
1639 toRemove.add(childRow);
1640 }
1641 }
1642 for (ExpandableNotificationRow remove : toRemove) {
1643 parent.removeChildNotification(remove);
1644 if (mNotificationData.get(remove.getStatusBarNotification().getKey()) == null) {
1645 // We only want to add an animation if the view is completely removed
1646 // otherwise it's just a transfer
1647 mStackScroller.notifyGroupChildRemoved(remove);
1648 }
1649 }
1650 }
1651 }
1652 }
1653
Jason Monk7e53f202016-01-28 10:40:20 -05001654 @Override
1655 public void addQsTile(ComponentName tile) {
1656 mQSPanel.getHost().addTile(tile);
1657 }
1658
1659 @Override
1660 public void remQsTile(ComponentName tile) {
1661 mQSPanel.getHost().removeTile(tile);
1662 }
1663
1664 @Override
1665 public void clickTile(ComponentName tile) {
1666 mQSPanel.clickTile(tile);
1667 }
1668
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001669 private boolean packageHasVisibilityOverride(String key) {
Julia Reynolds26fa8a52016-02-24 08:31:22 -05001670 return mNotificationData.getVisibilityOverride(key) == Notification.VISIBILITY_PRIVATE;
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001671 }
1672
Dan Sandlereceda3d2014-07-21 15:35:01 -04001673 private void updateClearAll() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001674 boolean showDismissView =
1675 mState != StatusBarState.KEYGUARD &&
1676 mNotificationData.hasActiveClearableNotifications();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001677 mStackScroller.updateDismissView(showDismissView);
1678 }
1679
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001680 private void updateEmptyShadeView() {
1681 boolean showEmptyShade =
1682 mState != StatusBarState.KEYGUARD &&
1683 mNotificationData.getActiveNotifications().size() == 0;
1684 mNotificationPanel.setShadeEmpty(showEmptyShade);
1685 }
1686
Jorim Jaggif6411742014-08-05 17:10:43 +00001687 private void updateSpeedbump() {
1688 int speedbumpIndex = -1;
1689 int currentIndex = 0;
Selim Cinek2a739342016-03-17 10:28:55 -07001690 final int N = mStackScroller.getChildCount();
Jorim Jaggif6411742014-08-05 17:10:43 +00001691 for (int i = 0; i < N; i++) {
Selim Cinek2a739342016-03-17 10:28:55 -07001692 View view = mStackScroller.getChildAt(i);
1693 if (view.getVisibility() == View.GONE || !(view instanceof ExpandableNotificationRow)) {
Selim Cinekb5605e52015-02-20 18:21:41 +01001694 continue;
1695 }
Selim Cinek2a739342016-03-17 10:28:55 -07001696 ExpandableNotificationRow row = (ExpandableNotificationRow) view;
1697 if (mNotificationData.isAmbient(row.getStatusBarNotification().getKey())) {
Jorim Jaggif6411742014-08-05 17:10:43 +00001698 speedbumpIndex = currentIndex;
1699 break;
1700 }
1701 currentIndex++;
1702 }
1703 mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
1704 }
1705
Selim Cinekb5605e52015-02-20 18:21:41 +01001706 public static boolean isTopLevelChild(Entry entry) {
1707 return entry.row.getParent() instanceof NotificationStackScrollLayout;
1708 }
1709
Chris Wren0c8275b2012-05-08 13:36:48 -04001710 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001711 protected void updateNotifications() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001712 mNotificationData.filterAndSort();
1713
Christoph Studer37fe6932014-05-26 13:10:30 +02001714 updateNotificationShade();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001715 mIconController.updateNotificationIcons(mNotificationData);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001716 }
1717
Selim Cinekef5127e2015-12-21 16:55:58 -08001718 public void requestNotificationUpdate() {
1719 updateNotifications();
1720 }
1721
Jorim Jaggi54045422014-07-03 18:30:40 +02001722 @Override
Chris Wren0c8275b2012-05-08 13:36:48 -04001723 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001724
Chris Wren6d15a362013-08-20 18:46:29 -04001725 if (SPEW) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001726 final boolean clearable = hasActiveNotifications() &&
1727 mNotificationData.hasActiveClearableNotifications();
1728 Log.d(TAG, "setAreThereNotifications: N=" +
1729 mNotificationData.getActiveNotifications().size() + " any=" +
1730 hasActiveNotifications() + " clearable=" + clearable);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001731 }
1732
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001733 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
Christoph Studerc8db24b2014-07-25 17:50:30 +02001734 final boolean showDot = hasActiveNotifications() && !areLightsOn();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04001735 if (showDot != (nlo.getAlpha() == 1.0f)) {
1736 if (showDot) {
1737 nlo.setAlpha(0f);
1738 nlo.setVisibility(View.VISIBLE);
1739 }
1740 nlo.animate()
1741 .alpha(showDot?1:0)
1742 .setDuration(showDot?750:250)
1743 .setInterpolator(new AccelerateInterpolator(2.0f))
1744 .setListener(showDot ? null : new AnimatorListenerAdapter() {
1745 @Override
1746 public void onAnimationEnd(Animator _a) {
1747 nlo.setVisibility(View.GONE);
1748 }
1749 })
1750 .start();
1751 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04001752
Dan Sandler16128f42014-05-21 12:48:22 -04001753 findAndUpdateMediaNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001754 }
1755
Dan Sandler16128f42014-05-21 12:48:22 -04001756 public void findAndUpdateMediaNotifications() {
1757 boolean metaDataChanged = false;
1758
1759 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001760 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
1761 final int N = activeNotifications.size();
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001762
1763 // Promote the media notification with a controller in 'playing' state, if any.
Dan Sandler16128f42014-05-21 12:48:22 -04001764 Entry mediaNotification = null;
1765 MediaController controller = null;
Christoph Studerc8db24b2014-07-25 17:50:30 +02001766 for (int i = 0; i < N; i++) {
1767 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04001768 if (isMediaNotification(entry)) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001769 final MediaSession.Token token =
1770 entry.notification.getNotification().extras
Dan Sandler16128f42014-05-21 12:48:22 -04001771 .getParcelable(Notification.EXTRA_MEDIA_SESSION);
1772 if (token != null) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001773 MediaController aController = new MediaController(mContext, token);
1774 if (PlaybackState.STATE_PLAYING ==
1775 getMediaControllerPlaybackState(aController)) {
1776 if (DEBUG_MEDIA) {
1777 Log.v(TAG, "DEBUG_MEDIA: found mediastyle controller matching "
1778 + entry.notification.getKey());
1779 }
Dan Sandler16128f42014-05-21 12:48:22 -04001780 mediaNotification = entry;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001781 controller = aController;
1782 break;
Dan Sandler16128f42014-05-21 12:48:22 -04001783 }
1784 }
1785 }
1786 }
Dan Sandler16128f42014-05-21 12:48:22 -04001787 if (mediaNotification == null) {
1788 // Still nothing? OK, let's just look for live media sessions and see if they match
1789 // one of our notifications. This will catch apps that aren't (yet!) using media
1790 // notifications.
1791
1792 if (mMediaSessionManager != null) {
1793 final List<MediaController> sessions
1794 = mMediaSessionManager.getActiveSessionsForUser(
1795 null,
1796 UserHandle.USER_ALL);
1797
1798 for (MediaController aController : sessions) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001799 if (PlaybackState.STATE_PLAYING ==
1800 getMediaControllerPlaybackState(aController)) {
1801 // now to see if we have one like this
1802 final String pkg = aController.getPackageName();
Dan Sandler16128f42014-05-21 12:48:22 -04001803
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001804 for (int i = 0; i < N; i++) {
1805 final Entry entry = activeNotifications.get(i);
1806 if (entry.notification.getPackageName().equals(pkg)) {
1807 if (DEBUG_MEDIA) {
1808 Log.v(TAG, "DEBUG_MEDIA: found controller matching "
1809 + entry.notification.getKey());
Dan Sandler16128f42014-05-21 12:48:22 -04001810 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001811 controller = aController;
1812 mediaNotification = entry;
1813 break;
Dan Sandler16128f42014-05-21 12:48:22 -04001814 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001815 }
Dan Sandler16128f42014-05-21 12:48:22 -04001816 }
1817 }
1818 }
1819 }
1820
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001821 if (controller != null && !sameSessions(mMediaController, controller)) {
Dan Sandler16128f42014-05-21 12:48:22 -04001822 // We have a new media session
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001823 clearCurrentMediaNotification();
Dan Sandler16128f42014-05-21 12:48:22 -04001824 mMediaController = controller;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001825 mMediaController.registerCallback(mMediaListener);
1826 mMediaMetadata = mMediaController.getMetadata();
Dan Sandler16128f42014-05-21 12:48:22 -04001827 if (DEBUG_MEDIA) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001828 Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: "
1829 + mMediaMetadata);
Dan Sandler16128f42014-05-21 12:48:22 -04001830 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001831
1832 if (mediaNotification != null) {
1833 mMediaNotificationKey = mediaNotification.notification.getKey();
1834 if (DEBUG_MEDIA) {
1835 Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
1836 + mMediaNotificationKey + " controller=" + mMediaController);
1837 }
1838 }
1839 metaDataChanged = true;
Dan Sandler16128f42014-05-21 12:48:22 -04001840 }
1841 }
1842
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001843 if (metaDataChanged) {
1844 updateNotifications();
1845 }
Adrian Roos52738322016-01-29 08:49:21 -08001846 updateMediaMetaData(metaDataChanged, true);
Dan Sandler16128f42014-05-21 12:48:22 -04001847 }
1848
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001849 private int getMediaControllerPlaybackState(MediaController controller) {
1850 if (controller != null) {
1851 final PlaybackState playbackState = controller.getPlaybackState();
1852 if (playbackState != null) {
1853 return playbackState.getState();
1854 }
1855 }
1856 return PlaybackState.STATE_NONE;
1857 }
1858
1859 private boolean isPlaybackActive(int state) {
1860 if (state != PlaybackState.STATE_STOPPED
1861 && state != PlaybackState.STATE_ERROR
1862 && state != PlaybackState.STATE_NONE) {
1863 return true;
1864 }
1865 return false;
1866 }
1867
1868 private void clearCurrentMediaNotification() {
1869 mMediaNotificationKey = null;
1870 mMediaMetadata = null;
1871 if (mMediaController != null) {
1872 if (DEBUG_MEDIA) {
1873 Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
1874 + mMediaController.getPackageName());
1875 }
1876 mMediaController.unregisterCallback(mMediaListener);
1877 }
1878 mMediaController = null;
1879 }
1880
Christoph Studerb5245d82014-09-19 16:54:36 +02001881 private boolean sameSessions(MediaController a, MediaController b) {
1882 if (a == b) return true;
1883 if (a == null) return false;
1884 return a.controlsSameSession(b);
1885 }
1886
Dan Sandler16128f42014-05-21 12:48:22 -04001887 /**
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001888 * Hide the album artwork that is fading out and release its bitmap.
Dan Sandler16128f42014-05-21 12:48:22 -04001889 */
1890 private Runnable mHideBackdropFront = new Runnable() {
1891 @Override
1892 public void run() {
1893 if (DEBUG_MEDIA) {
1894 Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
1895 }
1896 mBackdropFront.setVisibility(View.INVISIBLE);
Dan Sandler7dea0ee2014-07-21 21:07:15 -04001897 mBackdropFront.animate().cancel();
1898 mBackdropFront.setImageDrawable(null);
Dan Sandler16128f42014-05-21 12:48:22 -04001899 }
1900 };
1901
1902 /**
Adrian Roose381c162016-02-11 15:26:42 -08001903 * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
Dan Sandler16128f42014-05-21 12:48:22 -04001904 */
Adrian Roos52738322016-01-29 08:49:21 -08001905 public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
Dan Sandler16128f42014-05-21 12:48:22 -04001906 if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) return;
1907
1908 if (mBackdrop == null) return; // called too early
1909
Selim Cinek37c110f2015-05-22 12:38:44 -07001910 if (mLaunchTransitionFadingAway) {
1911 mBackdrop.setVisibility(View.INVISIBLE);
1912 return;
1913 }
1914
Dan Sandler16128f42014-05-21 12:48:22 -04001915 if (DEBUG_MEDIA) {
1916 Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey
Selim Cinek131c1e22015-05-11 19:04:49 -07001917 + " metadata=" + mMediaMetadata
1918 + " metaDataChanged=" + metaDataChanged
1919 + " state=" + mState);
Dan Sandler16128f42014-05-21 12:48:22 -04001920 }
1921
1922 Bitmap artworkBitmap = null;
1923 if (mMediaMetadata != null) {
1924 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
1925 if (artworkBitmap == null) {
1926 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
1927 // might still be null
1928 }
1929 }
Adrian Roos52738322016-01-29 08:49:21 -08001930 if (ENABLE_LOCKSCREEN_WALLPAPER && artworkBitmap == null) {
Adrian Roose381c162016-02-11 15:26:42 -08001931 artworkBitmap = mLockscreenWallpaper.getBitmap();
Adrian Roos52738322016-01-29 08:49:21 -08001932 }
Dan Sandler16128f42014-05-21 12:48:22 -04001933
1934 final boolean hasArtwork = artworkBitmap != null;
1935
Jorim Jaggi95d16bf2015-08-24 17:42:02 -07001936 if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK) && mState != StatusBarState.SHADE
Jorim Jaggid94d3a22015-08-21 16:52:55 -07001937 && mFingerprintUnlockController.getMode()
1938 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
Dan Sandler16128f42014-05-21 12:48:22 -04001939 // time to show some art!
1940 if (mBackdrop.getVisibility() != View.VISIBLE) {
1941 mBackdrop.setVisibility(View.VISIBLE);
Adrian Roos52738322016-01-29 08:49:21 -08001942 if (allowEnterAnimation) {
Adrian Roosd5c2db62016-03-08 16:11:31 -08001943 mBackdrop.animate().alpha(1f).withEndAction(new Runnable() {
1944 @Override
1945 public void run() {
1946 mStatusBarWindowManager.setBackdropShowing(true);
1947 }
1948 });
Adrian Roos52738322016-01-29 08:49:21 -08001949 } else {
1950 mBackdrop.animate().cancel();
1951 mBackdrop.setAlpha(1f);
Adrian Roosd5c2db62016-03-08 16:11:31 -08001952 mStatusBarWindowManager.setBackdropShowing(true);
Adrian Roos52738322016-01-29 08:49:21 -08001953 }
Dan Sandler16128f42014-05-21 12:48:22 -04001954 metaDataChanged = true;
1955 if (DEBUG_MEDIA) {
1956 Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
1957 }
1958 }
1959 if (metaDataChanged) {
1960 if (mBackdropBack.getDrawable() != null) {
Julia Reynolds4b9658a2015-07-22 17:07:42 -04001961 Drawable drawable =
1962 mBackdropBack.getDrawable().getConstantState().newDrawable().mutate();
Selim Cineka0fad3b2014-09-19 17:20:05 +02001963 mBackdropFront.setImageDrawable(drawable);
Jorim Jaggi0e664392014-09-27 01:30:22 +02001964 if (mScrimSrcModeEnabled) {
1965 mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
1966 }
Dan Sandler16128f42014-05-21 12:48:22 -04001967 mBackdropFront.setAlpha(1f);
1968 mBackdropFront.setVisibility(View.VISIBLE);
1969 } else {
1970 mBackdropFront.setVisibility(View.INVISIBLE);
1971 }
1972
1973 if (DEBUG_MEDIA_FAKE_ARTWORK) {
1974 final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
1975 Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
1976 mBackdropBack.setBackgroundColor(0xFFFFFFFF);
1977 mBackdropBack.setImageDrawable(new ColorDrawable(c));
1978 } else {
1979 mBackdropBack.setImageBitmap(artworkBitmap);
1980 }
Jorim Jaggi0e664392014-09-27 01:30:22 +02001981 if (mScrimSrcModeEnabled) {
1982 mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
1983 }
Dan Sandler16128f42014-05-21 12:48:22 -04001984
1985 if (mBackdropFront.getVisibility() == View.VISIBLE) {
1986 if (DEBUG_MEDIA) {
1987 Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
1988 + mBackdropFront.getDrawable()
1989 + " to "
1990 + mBackdropBack.getDrawable());
1991 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02001992 mBackdropFront.animate()
Dan Sandler16128f42014-05-21 12:48:22 -04001993 .setDuration(250)
1994 .alpha(0f).withEndAction(mHideBackdropFront);
1995 }
1996 }
1997 } else {
1998 // need to hide the album art, either because we are unlocked or because
1999 // the metadata isn't there to support it
2000 if (mBackdrop.getVisibility() != View.GONE) {
2001 if (DEBUG_MEDIA) {
2002 Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
2003 }
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002004 if (mFingerprintUnlockController.getMode()
2005 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002006
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002007 // We are unlocking directly - no animation!
2008 mBackdrop.setVisibility(View.GONE);
Vadim Trysheve7d7d572016-03-09 16:44:30 -08002009 mBackdropBack.setImageDrawable(null);
Adrian Roosd5c2db62016-03-08 16:11:31 -08002010 mStatusBarWindowManager.setBackdropShowing(false);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002011 } else {
Adrian Roosd5c2db62016-03-08 16:11:31 -08002012 mStatusBarWindowManager.setBackdropShowing(false);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002013 mBackdrop.animate()
2014 // Never let the alpha become zero - otherwise the RenderNode
2015 // won't draw anything and uninitialized memory will show through
2016 // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
2017 // libhwui.
2018 .alpha(0.002f)
Selim Cinekc18010f2016-01-20 13:41:30 -08002019 .setInterpolator(Interpolators.ACCELERATE_DECELERATE)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002020 .setDuration(300)
2021 .setStartDelay(0)
2022 .withEndAction(new Runnable() {
2023 @Override
2024 public void run() {
2025 mBackdrop.setVisibility(View.GONE);
2026 mBackdropFront.animate().cancel();
Vadim Trysheve7d7d572016-03-09 16:44:30 -08002027 mBackdropBack.setImageDrawable(null);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002028 mHandler.post(mHideBackdropFront);
2029 }
2030 });
2031 if (mKeyguardFadingAway) {
2032 mBackdrop.animate()
2033
2034 // Make it disappear faster, as the focus should be on the activity
2035 // behind.
2036 .setDuration(mKeyguardFadingAwayDuration / 2)
2037 .setStartDelay(mKeyguardFadingAwayDelay)
Selim Cinekc18010f2016-01-20 13:41:30 -08002038 .setInterpolator(Interpolators.LINEAR)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002039 .start();
2040 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002041 }
Dan Sandler16128f42014-05-21 12:48:22 -04002042 }
2043 }
2044 }
2045
Xiaohui Cheneb04a992016-03-22 14:58:03 -07002046 protected int adjustDisableFlags(int state) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07002047 if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway
Selim Cinekbaa23272014-07-08 18:01:07 +02002048 && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02002049 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
2050 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
2051 }
2052 return state;
2053 }
2054
Joe Onorato808182d2010-07-09 18:52:06 -04002055 /**
2056 * State is one or more of the DISABLE constants from StatusBarManager.
2057 */
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002058 public void disable(int state1, int state2, boolean animate) {
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002059 animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002060 mDisabledUnmodified1 = state1;
2061 mDisabledUnmodified2 = state2;
2062 state1 = adjustDisableFlags(state1);
2063 final int old1 = mDisabled1;
2064 final int diff1 = state1 ^ old1;
2065 mDisabled1 = state1;
2066
2067 final int old2 = mDisabled2;
2068 final int diff2 = state2 ^ old2;
2069 mDisabled2 = state2;
Joe Onorato808182d2010-07-09 18:52:06 -04002070
Daniel Sandlere21f2882011-08-18 10:14:59 -04002071 if (DEBUG) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002072 Log.d(TAG, String.format("disable1: 0x%08x -> 0x%08x (diff1: 0x%08x)",
2073 old1, state1, diff1));
2074 Log.d(TAG, String.format("disable2: 0x%08x -> 0x%08x (diff2: 0x%08x)",
2075 old2, state2, diff2));
Daniel Sandlere21f2882011-08-18 10:14:59 -04002076 }
2077
Daniel Sandler6da2b762011-09-14 16:04:59 -04002078 StringBuilder flagdbg = new StringBuilder();
2079 flagdbg.append("disable: < ");
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002080 flagdbg.append(((state1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
2081 flagdbg.append(((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
2082 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
2083 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
2084 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
2085 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
2086 flagdbg.append(((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
2087 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
2088 flagdbg.append(((state1 & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
2089 flagdbg.append(((diff1 & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
2090 flagdbg.append(((state1 & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
2091 flagdbg.append(((diff1 & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
2092 flagdbg.append(((state1 & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
2093 flagdbg.append(((diff1 & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
2094 flagdbg.append(((state1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
2095 flagdbg.append(((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
2096 flagdbg.append(((state1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
2097 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Benjamin Franz27cf1462015-04-23 19:36:42 +01002098 flagdbg.append(((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "QUICK_SETTINGS"
2099 : "quick_settings");
2100 flagdbg.append(((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04002101 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04002102 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07002103
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002104 if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
2105 if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002106 mIconController.hideSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002107 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002108 mIconController.showSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002109 }
2110 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04002111
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002112 if ((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) {
2113 boolean visible = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002114 mIconController.setClockVisibility(visible);
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07002115 }
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002116 if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
2117 if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002118 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04002119 }
2120 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002121
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002122 if ((diff1 & (StatusBarManager.DISABLE_HOME
Jim Miller5e6af442011-12-02 18:24:26 -08002123 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002124 | StatusBarManager.DISABLE_BACK
2125 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04002126 // the nav bar will take care of these
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002127 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002128
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002129 if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04002130 // close recents if it's visible
Winson Chung1e8d71b2014-05-16 17:05:22 -07002131 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2132 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002133 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002134 }
2135
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002136 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
2137 if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002138 mIconController.hideNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002139 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002140 mIconController.showNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002141 }
Joe Onorato808182d2010-07-09 18:52:06 -04002142 }
Jason Monkf7019542014-07-31 12:42:25 -04002143
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002144 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
Jason Monkf7019542014-07-31 12:42:25 -04002145 mDisableNotificationAlerts =
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002146 (state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
Jason Monkf7019542014-07-31 12:42:25 -04002147 mHeadsUpObserver.onChange(true);
2148 }
Benjamin Franz27cf1462015-04-23 19:36:42 +01002149
2150 if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
2151 updateQsExpansionEnabled();
2152 }
Joe Onorato808182d2010-07-09 18:52:06 -04002153 }
2154
Michael Jurka7f2668c2012-03-27 07:49:52 -07002155 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07002156 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002157 return new PhoneStatusBar.H();
2158 }
2159
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002160 @Override
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002161 public void startActivity(Intent intent, boolean dismissShade) {
2162 startActivityDismissingKeyguard(intent, false, dismissShade);
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002163 }
2164
Selim Cineke70d6532015-04-24 16:46:13 -07002165 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07002166 public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
2167 startActivityDismissingKeyguard(intent, false, dismissShade, callback);
2168 }
2169
2170 @Override
Selim Cineke70d6532015-04-24 16:46:13 -07002171 public void preventNextAnimation() {
2172 overrideActivityPendingAppTransition(true /* keyguardShowing */);
2173 }
2174
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002175 public void setQsExpanded(boolean expanded) {
2176 mStatusBarWindowManager.setQsExpanded(expanded);
Adrian Roos4c7d9602015-06-10 13:44:48 -07002177 mKeyguardStatusView.setImportantForAccessibility(expanded
2178 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
2179 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002180 }
2181
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02002182 public boolean isGoingToNotificationShade() {
2183 return mLeaveOpenOnKeyguardHide;
2184 }
2185
Jorim Jaggid692dd02014-08-14 20:57:42 +02002186 public boolean isQsExpanded() {
2187 return mNotificationPanel.isQsExpanded();
2188 }
2189
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07002190 public boolean isWakeUpComingFromTouch() {
2191 return mWakeUpComingFromTouch;
Selim Cinek29ed3c92014-09-23 20:44:35 +02002192 }
2193
Selim Cinek19c8c702014-08-25 22:09:19 +02002194 public boolean isFalsingThresholdNeeded() {
Selim Cinek9db71052015-04-24 18:54:30 -07002195 return getBarState() == StatusBarState.KEYGUARD;
Selim Cinek19c8c702014-08-25 22:09:19 +02002196 }
2197
John Spurlock0b99ea92014-10-01 15:32:22 -04002198 public boolean isDozing() {
2199 return mDozing;
2200 }
2201
Christoph Studer2e731b52014-08-22 16:01:51 +02002202 @Override // NotificationData.Environment
2203 public String getCurrentMediaNotificationKey() {
2204 return mMediaNotificationKey;
2205 }
2206
Jorim Jaggi0e664392014-09-27 01:30:22 +02002207 public boolean isScrimSrcModeEnabled() {
2208 return mScrimSrcModeEnabled;
2209 }
2210
Joe Onorato808182d2010-07-09 18:52:06 -04002211 /**
Christoph Studer2231c6e2014-12-19 12:40:13 +01002212 * To be called when there's a state change in StatusBarKeyguardViewManager.
2213 */
2214 public void onKeyguardViewManagerStatesUpdated() {
2215 logStateToEventlog();
2216 }
2217
2218 @Override // UnlockMethodCache.OnUnlockMethodChangedListener
2219 public void onUnlockMethodStateChanged() {
2220 logStateToEventlog();
2221 }
2222
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002223 @Override
John Spurlockb349af572015-04-29 12:24:19 -04002224 public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
Selim Cinek684a4422015-04-15 16:18:39 -07002225 if (inPinnedMode) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002226 mStatusBarWindowManager.setHeadsUpShowing(true);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002227 mStatusBarWindowManager.setForceStatusBarVisible(true);
Selim Cinek131c1e22015-05-11 19:04:49 -07002228 if (mNotificationPanel.isFullyCollapsed()) {
2229 // We need to ensure that the touchable region is updated before the window will be
2230 // resized, in order to not catch any touches. A layout will ensure that
2231 // onComputeInternalInsets will be called and after that we can resize the layout. Let's
2232 // make sure that the window stays small for one frame until the touchableRegion is set.
2233 mNotificationPanel.requestLayout();
2234 mStatusBarWindowManager.setForceWindowCollapsed(true);
2235 mNotificationPanel.post(new Runnable() {
2236 @Override
2237 public void run() {
2238 mStatusBarWindowManager.setForceWindowCollapsed(false);
2239 }
2240 });
2241 }
Selim Cinek737bff32015-05-08 16:08:35 -07002242 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002243 if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) {
2244 // We are currently tracking or is open and the shade doesn't need to be kept
2245 // open artificially.
Selim Cinek737bff32015-05-08 16:08:35 -07002246 mStatusBarWindowManager.setHeadsUpShowing(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002247 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002248 // we need to keep the panel open artificially, let's wait until the animation
2249 // is finished.
Selim Cinek737bff32015-05-08 16:08:35 -07002250 mHeadsUpManager.setHeadsUpGoingAway(true);
2251 mStackScroller.runAfterAnimationFinished(new Runnable() {
2252 @Override
2253 public void run() {
2254 if (!mHeadsUpManager.hasPinnedHeadsUp()) {
2255 mStatusBarWindowManager.setHeadsUpShowing(false);
2256 mHeadsUpManager.setHeadsUpGoingAway(false);
2257 }
2258 }
2259 });
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002260 }
2261 }
2262 }
2263
2264 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002265 public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
John Spurlockb349af572015-04-29 12:24:19 -04002266 dismissVolumeDialog();
Selim Cinek1f3f5442015-04-10 17:54:46 -07002267 }
2268
2269 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002270 public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
2271 }
2272
2273 @Override
2274 public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002275 if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
2276 removeNotification(entry.key, mLatestRankingMap);
2277 mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
2278 if (mHeadsUpEntriesToRemoveOnSwitch.isEmpty()) {
2279 mLatestRankingMap = null;
2280 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002281 } else {
2282 updateNotificationRanking(null);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002283 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002284
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002285 }
2286
Chris Wrenbdf33762015-12-04 15:50:51 -05002287 protected void updateHeadsUp(String key, Entry entry, boolean shouldPeek,
Selim Cinek29fa89b2015-04-17 10:39:11 -07002288 boolean alertAgain) {
2289 final boolean wasHeadsUp = isHeadsUp(key);
2290 if (wasHeadsUp) {
Chris Wrenbdf33762015-12-04 15:50:51 -05002291 if (!shouldPeek) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002292 // We don't want this to be interrupting anymore, lets remove it
2293 mHeadsUpManager.removeNotification(key);
Selim Cinek684a4422015-04-15 16:18:39 -07002294 } else {
2295 mHeadsUpManager.updateNotification(entry, alertAgain);
Selim Cinek29fa89b2015-04-17 10:39:11 -07002296 }
Chris Wrenbdf33762015-12-04 15:50:51 -05002297 } else if (shouldPeek && alertAgain) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002298 // This notification was updated to be a heads-up, show it!
2299 mHeadsUpManager.showNotification(entry);
2300 }
2301 }
2302
2303 protected void setHeadsUpUser(int newUserId) {
2304 if (mHeadsUpManager != null) {
2305 mHeadsUpManager.setUser(newUserId);
2306 }
2307 }
2308
2309 public boolean isHeadsUp(String key) {
2310 return mHeadsUpManager.isHeadsUp(key);
2311 }
2312
2313 protected boolean isSnoozedPackage(StatusBarNotification sbn) {
2314 return mHeadsUpManager.isSnoozed(sbn.getPackageName());
2315 }
2316
Selim Cineke70d6532015-04-24 16:46:13 -07002317 public boolean isKeyguardCurrentlySecure() {
Selim Cineke8bae622015-07-15 13:24:06 -07002318 return !mUnlockMethodCache.canSkipBouncer();
Selim Cineke70d6532015-04-24 16:46:13 -07002319 }
2320
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002321 public void setPanelExpanded(boolean isExpanded) {
2322 mStatusBarWindowManager.setPanelExpanded(isExpanded);
2323 }
2324
Adrian Roos401caae2016-03-04 13:35:21 -08002325 public void onScreenTurnedOff() {
2326 mFalsingManager.onScreenOff();
2327 }
2328
Christoph Studer2231c6e2014-12-19 12:40:13 +01002329 /**
Joe Onorato808182d2010-07-09 18:52:06 -04002330 * All changes to the status bar and notifications funnel through here and are batched.
2331 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07002332 private class H extends BaseStatusBar.H {
Joe Onorato808182d2010-07-09 18:52:06 -04002333 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002334 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04002335 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002336 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04002337 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002338 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04002339 case MSG_OPEN_SETTINGS_PANEL:
Jason Monka9927322015-12-13 16:22:37 -05002340 animateExpandSettingsPanel((String) m.obj);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002341 break;
2342 case MSG_CLOSE_PANELS:
2343 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002344 break;
Jorim Jaggi826730a2014-12-08 21:05:13 +01002345 case MSG_LAUNCH_TRANSITION_TIMEOUT:
2346 onLaunchTransitionTimeout();
2347 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04002348 }
2349 }
2350 }
2351
Chris Wren930ecca2014-11-12 17:43:41 -05002352 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002353 public void maybeEscalateHeadsUp() {
Selim Cinek3362c132016-02-11 15:43:03 -08002354 Collection<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getAllEntries();
Selim Cineka59ecc32015-04-07 10:51:49 -07002355 for (HeadsUpManager.HeadsUpEntry entry : entries) {
2356 final StatusBarNotification sbn = entry.entry.notification;
Chris Wrene97f90b2013-08-07 17:39:35 -04002357 final Notification notification = sbn.getNotification();
2358 if (notification.fullScreenIntent != null) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002359 if (DEBUG) {
Chris Wrene97f90b2013-08-07 17:39:35 -04002360 Log.d(TAG, "converting a heads up to fullScreen");
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002361 }
Chris Wrene97f90b2013-08-07 17:39:35 -04002362 try {
Chris Wren223c66b62014-11-10 16:00:09 -05002363 EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
2364 sbn.getKey());
Chris Wrene97f90b2013-08-07 17:39:35 -04002365 notification.fullScreenIntent.send();
Selim Cinekb18a20f2015-06-04 17:08:35 +02002366 entry.entry.notifyFullScreenIntentLaunched();
Chris Wrene97f90b2013-08-07 17:39:35 -04002367 } catch (PendingIntent.CanceledException e) {
2368 }
Joe Onorato808182d2010-07-09 18:52:06 -04002369 }
2370 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002371 mHeadsUpManager.releaseAllImmediately();
Joe Onorato808182d2010-07-09 18:52:06 -04002372 }
2373
John Spurlock97642182013-07-29 17:58:39 -04002374 boolean panelsEnabled() {
Adrian Roos21d2a252015-06-01 13:59:59 -07002375 return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && !ONLY_CORE_APPS;
John Spurlock97642182013-07-29 17:58:39 -04002376 }
2377
Jorim Jaggifa505a72014-04-28 20:04:11 +02002378 void makeExpandedVisible(boolean force) {
John Spurlockcd686b52013-06-05 10:13:46 -04002379 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
Jorim Jaggifa505a72014-04-28 20:04:11 +02002380 if (!force && (mExpandedVisible || !panelsEnabled())) {
Joe Onorato808182d2010-07-09 18:52:06 -04002381 return;
2382 }
Jim Millera073e572012-05-23 17:03:27 -07002383
Joe Onorato808182d2010-07-09 18:52:06 -04002384 mExpandedVisible = true;
John Spurlockd5ef5462012-06-13 11:19:51 -04002385 if (mNavigationBarView != null)
2386 mNavigationBarView.setSlippery(true);
Joe Onorato808182d2010-07-09 18:52:06 -04002387
Daniel Sandlera310af82012-04-24 01:20:13 -04002388 // Expand the window to encompass the full screen in anticipation of the drag.
2389 // 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 -07002390 mStatusBarWindowManager.setPanelVisible(true);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002391
2392 visibilityChanged(true);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07002393 mWaitingForKeyguardExit = false;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002394 disable(mDisabledUnmodified1, mDisabledUnmodified2, !force /* animate */);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002395 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2396 }
2397
Daniel Sandler11cf1782012-09-27 14:03:08 -04002398 public void animateCollapsePanels() {
2399 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07002400 }
2401
John Spurlockaf8d6c42014-05-07 17:49:08 -04002402 private final Runnable mAnimateCollapsePanels = new Runnable() {
2403 @Override
2404 public void run() {
2405 animateCollapsePanels();
2406 }
2407 };
2408
2409 public void postAnimateCollapsePanels() {
2410 mHandler.post(mAnimateCollapsePanels);
2411 }
2412
Jason Monkba2318e2015-12-08 09:04:23 -05002413 public void postAnimateOpenPanels() {
2414 mHandler.sendEmptyMessage(MSG_OPEN_SETTINGS_PANEL);
2415 }
2416
Daniel Sandler11cf1782012-09-27 14:03:08 -04002417 public void animateCollapsePanels(int flags) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002418 animateCollapsePanels(flags, false /* force */, false /* delayed */,
2419 1.0f /* speedUpFactor */);
Jorim Jaggi34250762014-07-03 23:51:19 +02002420 }
2421
2422 public void animateCollapsePanels(int flags, boolean force) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002423 animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002424 }
2425
2426 public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002427 animateCollapsePanels(flags, force, delayed, 1.0f /* speedUpFactor */);
2428 }
2429
2430 public void animateCollapsePanels(int flags, boolean force, boolean delayed,
2431 float speedUpFactor) {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07002432 if (!force && mState != StatusBarState.SHADE) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002433 runPostCollapseRunnables();
Jorim Jaggic1cf1ae2014-05-02 21:19:17 +02002434 return;
2435 }
Joe Onorato808182d2010-07-09 18:52:06 -04002436 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04002437 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04002438 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07002439 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002440 }
2441
Jim Miller9a720f52012-05-30 03:19:43 -07002442 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Winson Chungcdcd4872014-08-05 18:00:13 -07002443 if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
2444 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2445 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
2446 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07002447 }
Jim Miller9a720f52012-05-30 03:19:43 -07002448
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002449 if (mStatusBarWindow != null) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002450 // release focus immediately to kick off focus change transition
2451 mStatusBarWindowManager.setStatusBarFocusable(false);
2452
John Spurlockab847cf2014-01-15 14:13:59 -05002453 mStatusBarWindow.cancelExpandHelper();
Xiaohui Chen9f967112016-01-07 14:14:06 -08002454 mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
John Spurlockab847cf2014-01-15 14:13:59 -05002455 }
Joe Onorato808182d2010-07-09 18:52:06 -04002456 }
2457
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002458 private void runPostCollapseRunnables() {
Selim Cinekae77f8e2015-07-07 18:43:59 -07002459 ArrayList<Runnable> clonedList = new ArrayList<>(mPostCollapseRunnables);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002460 mPostCollapseRunnables.clear();
Selim Cinekae77f8e2015-07-07 18:43:59 -07002461 int size = clonedList.size();
2462 for (int i = 0; i < size; i++) {
2463 clonedList.get(i).run();
2464 }
2465
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002466 }
2467
Daniel Sandler08d05e32012-08-08 16:39:54 -04002468 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002469 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002470 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002471 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04002472 return ;
2473 }
Joe Onorato808182d2010-07-09 18:52:06 -04002474
Oren Blasberg8d3fea12015-07-10 14:21:44 -07002475 mNotificationPanel.expand(true /* animate */);
Joe Onorato808182d2010-07-09 18:52:06 -04002476
2477 if (false) postStartTracing();
2478 }
2479
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002480 @Override
Jason Monka9927322015-12-13 16:22:37 -05002481 public void animateExpandSettingsPanel(String subPanel) {
John Spurlockcd686b52013-06-05 10:13:46 -04002482 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002483 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002484 return;
2485 }
2486
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05002487 // Settings are not available in setup
2488 if (!mUserSetup) return;
2489
Jason Monka9927322015-12-13 16:22:37 -05002490
2491 if (subPanel != null) {
2492 mQSPanel.openDetails(subPanel);
2493 }
Jason Monk3c68ca22015-01-30 11:30:29 -05002494 mNotificationPanel.expandWithQs();
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002495
2496 if (false) postStartTracing();
2497 }
2498
2499 public void animateCollapseQuickSettings() {
Jorim Jaggi449981b2014-10-03 14:24:55 -07002500 if (mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08002501 mStatusBarView.collapsePanel(true, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi449981b2014-10-03 14:24:55 -07002502 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002503 }
2504
Daniel Sandler08d05e32012-08-08 16:39:54 -04002505 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04002506 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04002507 + " mExpandedVisible=" + mExpandedVisible);
2508
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002509 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002510 return;
2511 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002512
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04002513 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
Xiaohui Chen9f967112016-01-07 14:14:06 -08002514 mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002515 1.0f /* speedUpFactor */);
Daniel Sandlered930e52012-07-03 14:31:22 -04002516
Jorim Jaggid7daab72014-05-06 22:22:20 +02002517 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04002518
Joe Onorato808182d2010-07-09 18:52:06 -04002519 mExpandedVisible = false;
John Spurlockd5ef5462012-06-13 11:19:51 -04002520 if (mNavigationBarView != null)
2521 mNavigationBarView.setSlippery(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002522 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04002523
2524 // Shrink the window to the size of the status bar only
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002525 mStatusBarWindowManager.setPanelVisible(false);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002526 mStatusBarWindowManager.setForceStatusBarVisible(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002527
Daniel Sandler469e96e2012-05-04 15:56:19 -04002528 // Close any "App info" popups that might have snuck on-screen
2529 dismissPopups();
2530
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002531 runPostCollapseRunnables();
John Spurlockcfc359a2013-09-05 10:42:03 -04002532 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002533 showBouncer();
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002534 disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
Jorim Jaggi786afcb2014-09-25 02:41:29 +02002535
2536 // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
2537 // the bouncer appear animation.
2538 if (!mStatusBarKeyguardViewManager.isShowing()) {
2539 WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
2540 }
Joe Onorato808182d2010-07-09 18:52:06 -04002541 }
2542
Daniel Sandlerb17a7262012-10-05 14:32:50 -04002543 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05002544 if (DEBUG_GESTURES) {
2545 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
2546 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002547 event.getActionMasked(), (int) event.getX(), (int) event.getY(),
2548 mDisabled1, mDisabled2);
Chris Wren64161cc2012-12-17 16:49:30 -05002549 }
2550
2551 }
2552
Joe Onorato808182d2010-07-09 18:52:06 -04002553 if (SPEW) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002554 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
2555 + mDisabled1 + " mDisabled2=" + mDisabled2 + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002556 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002557 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04002558 Log.d(TAG, String.format(
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002559 "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002560 MotionEvent.actionToString(event.getAction()),
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002561 event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002562 }
Joe Onorato808182d2010-07-09 18:52:06 -04002563 }
2564
Daniel Sandler151f00d2012-10-02 22:33:08 -04002565 if (DEBUG_GESTURES) {
2566 mGestureRec.add(event);
2567 }
Daniel Sandler33805342012-07-23 15:45:12 -04002568
John Spurlock686820a2013-09-03 14:44:16 -04002569 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04002570 final boolean upOrCancel =
2571 event.getAction() == MotionEvent.ACTION_UP ||
2572 event.getAction() == MotionEvent.ACTION_CANCEL;
2573 if (upOrCancel && !mExpandedVisible) {
2574 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
2575 } else {
2576 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2577 }
John Spurlock686820a2013-09-03 14:44:16 -04002578 }
Joe Onorato808182d2010-07-09 18:52:06 -04002579 return false;
2580 }
2581
Daniel Sandler08d05e32012-08-08 16:39:54 -04002582 public GestureRecorder getGestureRecorder() {
2583 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07002584 }
2585
John Spurlock56d007b2013-10-28 18:40:56 -04002586 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04002587 if (hints == mNavigationIconHints) return;
2588
2589 mNavigationIconHints = hints;
2590
2591 if (mNavigationBarView != null) {
2592 mNavigationBarView.setNavigationIconHints(hints);
2593 }
John Spurlockd4e65752013-08-28 14:17:09 -04002594 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04002595 }
2596
2597 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04002598 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04002599 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04002600 if (mStatusBarWindow != null
2601 && window == StatusBarManager.WINDOW_STATUS_BAR
2602 && mStatusBarWindowState != state) {
2603 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002604 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
Jorim Jaggi449981b2014-10-03 14:24:55 -07002605 if (!showing && mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08002606 mStatusBarView.collapsePanel(false /* animate */, false /* delayed */,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002607 1.0f /* speedUpFactor */);
John Spurlock97642182013-07-29 17:58:39 -04002608 }
2609 }
2610 if (mNavigationBarView != null
2611 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
2612 && mNavigationBarWindowState != state) {
2613 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002614 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04002615 }
2616 }
2617
John Spurlock97642182013-07-29 17:58:39 -04002618 @Override // CommandQueue
John Spurlockcad57682014-07-26 17:09:56 -04002619 public void buzzBeepBlinked() {
2620 if (mDozeServiceHost != null) {
2621 mDozeServiceHost.fireBuzzBeepBlinked();
2622 }
2623 }
2624
John Spurlockcb566aa2014-08-03 22:58:28 -04002625 @Override
2626 public void notificationLightOff() {
2627 if (mDozeServiceHost != null) {
2628 mDozeServiceHost.fireNotificationLight(false);
2629 }
2630 }
2631
2632 @Override
2633 public void notificationLightPulse(int argb, int onMillis, int offMillis) {
2634 if (mDozeServiceHost != null) {
2635 mDozeServiceHost.fireNotificationLight(true);
2636 }
2637 }
2638
John Spurlockcad57682014-07-26 17:09:56 -04002639 @Override // CommandQueue
Jorim Jaggi86905582016-02-09 21:36:09 -08002640 public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
2641 int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002642 final int oldVal = mSystemUiVisibility;
2643 final int newVal = (oldVal&~mask) | (vis&mask);
2644 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04002645 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04002646 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
2647 Integer.toHexString(vis), Integer.toHexString(mask),
2648 Integer.toHexString(oldVal), Integer.toHexString(newVal),
2649 Integer.toHexString(diff)));
Jorim Jaggi86905582016-02-09 21:36:09 -08002650 boolean sbModeChanged = false;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002651 if (diff != 0) {
Winson Chung9214eff2014-06-12 13:59:25 -07002652 // we never set the recents bit via this method, so save the prior state to prevent
2653 // clobbering the bit below
2654 final boolean wasRecentsVisible = (mSystemUiVisibility & View.RECENT_APPS_VISIBLE) > 0;
2655
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002656 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04002657
John Spurlocke1f366f2013-08-05 12:22:40 -04002658 // update low profile
2659 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
2660 final boolean lightsOut = (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002661 if (lightsOut) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002662 animateCollapsePanels();
Daniel Sandlere137a1e2011-08-17 16:47:19 -04002663 }
Jim Millera073e572012-05-23 17:03:27 -07002664
John Spurlock7edfbca2013-09-14 11:58:55 -04002665 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04002666 }
2667
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002668 // ready to unhide
2669 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
2670 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
2671 mNoAnimationOnNextBarModeChange = true;
2672 }
2673
John Spurlocke1f366f2013-08-05 12:22:40 -04002674 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002675 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002676 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT,
2677 View.STATUS_BAR_TRANSPARENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04002678
2679 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04002680 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04002681 oldVal, newVal, mNavigationBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002682 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
2683 View.NAVIGATION_BAR_TRANSPARENT);
Jorim Jaggi86905582016-02-09 21:36:09 -08002684 sbModeChanged = sbMode != -1;
John Spurlockd4e65752013-08-28 14:17:09 -04002685 final boolean nbModeChanged = nbMode != -1;
2686 boolean checkBarModes = false;
2687 if (sbModeChanged && sbMode != mStatusBarMode) {
2688 mStatusBarMode = sbMode;
2689 checkBarModes = true;
2690 }
2691 if (nbModeChanged && nbMode != mNavigationBarMode) {
2692 mNavigationBarMode = nbMode;
2693 checkBarModes = true;
2694 }
2695 if (checkBarModes) {
2696 checkBarModes();
2697 }
2698 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002699 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05002700 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04002701 scheduleAutohide();
2702 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04002703 cancelAutohide();
2704 }
2705 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002706
John Spurlock5b9145b2013-08-20 15:13:47 -04002707 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
2708 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
2709 }
2710
Winson Chung9214eff2014-06-12 13:59:25 -07002711 // restore the recents bit
2712 if (wasRecentsVisible) {
2713 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
2714 }
2715
John Spurlocke1f366f2013-08-05 12:22:40 -04002716 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04002717 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04002718 }
Jorim Jaggi86905582016-02-09 21:36:09 -08002719
2720 mLightStatusBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,
2721 mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002722 }
2723
John Spurlockd4e65752013-08-28 14:17:09 -04002724 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002725 int transientFlag, int translucentFlag, int transparentFlag) {
2726 final int oldMode = barMode(oldVis, transientFlag, translucentFlag, transparentFlag);
2727 final int newMode = barMode(newVis, transientFlag, translucentFlag, transparentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04002728 if (oldMode == newMode) {
2729 return -1; // no mode change
2730 }
John Spurlocke1f366f2013-08-05 12:22:40 -04002731 return newMode;
2732 }
2733
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002734 private int barMode(int vis, int transientFlag, int translucentFlag, int transparentFlag) {
2735 int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | transparentFlag;
John Spurlock89835dd2013-08-16 15:06:51 -04002736 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04002737 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
Adrian Roosc0f0a742014-10-28 16:39:56 +01002738 : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
Jorim Jaggi4fa78922015-11-30 17:13:56 -08002739 : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
John Spurlock7edfbca2013-09-14 11:58:55 -04002740 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04002741 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04002742 }
2743
John Spurlockd4e65752013-08-28 14:17:09 -04002744 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04002745 if (mDemoMode) return;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002746 checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions(),
2747 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04002748 if (mNavigationBarView != null) {
2749 checkBarMode(mNavigationBarMode,
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002750 mNavigationBarWindowState, mNavigationBarView.getBarTransitions(),
2751 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04002752 }
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002753 mNoAnimationOnNextBarModeChange = false;
John Spurlockd4e65752013-08-28 14:17:09 -04002754 }
2755
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002756 private void checkBarMode(int mode, int windowState, BarTransitions transitions,
2757 boolean noAnimation) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002758 final boolean powerSave = mBatteryController.isPowerSave();
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07002759 final boolean anim = !noAnimation && mDeviceInteractive
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002760 && windowState != WINDOW_STATE_HIDDEN && !powerSave;
John Spurlock1bb480a2014-08-02 17:12:43 -04002761 if (powerSave && getBarState() == StatusBarState.SHADE) {
John Spurlock0ff62e02014-07-22 16:15:08 -04002762 mode = MODE_WARNING;
2763 }
John Spurlockc68d5772013-10-08 11:47:58 -04002764 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04002765 }
2766
John Spurlock42197262013-10-21 09:32:25 -04002767 private void finishBarAnimations() {
2768 mStatusBarView.getBarTransitions().finishAnimations();
2769 if (mNavigationBarView != null) {
2770 mNavigationBarView.getBarTransitions().finishAnimations();
2771 }
2772 }
2773
John Spurlockd4e65752013-08-28 14:17:09 -04002774 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04002775 @Override
2776 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04002777 checkBarModes();
John Spurlock0ff62e02014-07-22 16:15:08 -04002778 }
2779 };
John Spurlock5b9145b2013-08-20 15:13:47 -04002780
John Spurlockad3e6cb2013-04-30 08:47:43 -04002781 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04002782 public void setInteracting(int barWindow, boolean interacting) {
John Spurlock7fbf5732014-11-18 11:40:22 -05002783 final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
John Spurlockcfc359a2013-09-05 10:42:03 -04002784 mInteractingWindows = interacting
2785 ? (mInteractingWindows | barWindow)
2786 : (mInteractingWindows & ~barWindow);
2787 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04002788 suspendAutohide();
2789 } else {
2790 resumeSuspendedAutohide();
2791 }
John Spurlock7fbf5732014-11-18 11:40:22 -05002792 // manually dismiss the volume panel when interacting with the nav bar
2793 if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
John Spurlockb349af572015-04-29 12:24:19 -04002794 dismissVolumeDialog();
John Spurlock7fbf5732014-11-18 11:40:22 -05002795 }
John Spurlockd4e65752013-08-28 14:17:09 -04002796 checkBarModes();
2797 }
2798
John Spurlockb349af572015-04-29 12:24:19 -04002799 private void dismissVolumeDialog() {
2800 if (mVolumeComponent != null) {
2801 mVolumeComponent.dismissNow();
2802 }
2803 }
2804
John Spurlockd4e65752013-08-28 14:17:09 -04002805 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04002806 if (mAutohideSuspended) {
2807 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04002808 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04002809 }
2810 }
2811
John Spurlockd4e65752013-08-28 14:17:09 -04002812 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04002813 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04002814 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04002815 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04002816 }
2817
2818 private void cancelAutohide() {
2819 mAutohideSuspended = false;
2820 mHandler.removeCallbacks(mAutohide);
2821 }
2822
2823 private void scheduleAutohide() {
2824 cancelAutohide();
2825 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
2826 }
2827
John Spurlock9deaa282013-07-25 13:03:47 -04002828 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04002829 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04002830 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
2831 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
2832 ) {
2833 userAutohide();
2834 }
2835 }
2836
2837 private void userAutohide() {
2838 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04002839 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04002840 }
2841
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002842 private boolean areLightsOn() {
2843 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
2844 }
Jim Millera073e572012-05-23 17:03:27 -07002845
Daniel Sandler60ee2562011-07-22 12:34:33 -04002846 public void setLightsOn(boolean on) {
2847 Log.v(TAG, "setLightsOn(" + on + ")");
2848 if (on) {
Jorim Jaggi86905582016-02-09 21:36:09 -08002849 setSystemUiVisibility(0, 0, 0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
2850 mLastFullscreenStackBounds, mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002851 } else {
Jorim Jaggi86905582016-02-09 21:36:09 -08002852 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, 0, 0,
2853 View.SYSTEM_UI_FLAG_LOW_PROFILE, mLastFullscreenStackBounds,
2854 mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04002855 }
2856 }
2857
John Spurlock32beb2c2013-03-11 10:16:47 -04002858 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002859 try {
Adrian Roos389beec2015-05-12 13:33:25 -07002860 if (mLastDispatchedSystemUiVisibility != vis) {
2861 mWindowManagerService.statusBarVisibilityChanged(vis);
2862 mLastDispatchedSystemUiVisibility = vis;
2863 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04002864 } catch (RemoteException ex) {
2865 }
Joe Onorato93056472010-09-10 10:30:46 -04002866 }
2867
Daniel Sandler5c8da942011-06-28 00:29:04 -04002868 public void topAppWindowChanged(boolean showMenu) {
2869 if (DEBUG) {
John Spurlockcd686b52013-06-05 10:13:46 -04002870 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04002871 }
2872 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04002873 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04002874 }
2875
2876 // See above re: lights-out policy for legacy apps.
2877 if (showMenu) setLightsOn(true);
2878 }
2879
Daniel Sandler328310c2011-09-23 15:56:52 -04002880 @Override
Jason Monkb605fec2014-05-02 17:04:10 -04002881 public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
2882 boolean showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002883 boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
2884 int flags = mNavigationIconHints;
2885 if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
2886 flags |= NAVIGATION_HINT_BACK_ALT;
2887 } else {
2888 flags &= ~NAVIGATION_HINT_BACK_ALT;
2889 }
Jason Monkb605fec2014-05-02 17:04:10 -04002890 if (showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04002891 flags |= NAVIGATION_HINT_IME_SHOWN;
2892 } else {
2893 flags &= ~NAVIGATION_HINT_IME_SHOWN;
2894 }
Daniel Sandler328310c2011-09-23 15:56:52 -04002895
Jason Monkf1ff2092014-04-29 16:50:53 -04002896 setNavigationIconHints(flags);
Daniel Sandler328310c2011-09-23 15:56:52 -04002897 }
2898
Daniel Sandler48852952011-12-01 14:34:23 -05002899 public static String viewInfo(View v) {
2900 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
2901 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04002902 }
2903
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04002904 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04002905 synchronized (mQueueLock) {
2906 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04002907 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04002908 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04002909 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04002910 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002911 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
Selim Cinekb6d85eb2014-03-28 20:21:01 +01002912 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
2913 + " scroll " + mStackScroller.getScrollX()
2914 + "," + mStackScroller.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04002915 }
Joe Onorato808182d2010-07-09 18:52:06 -04002916
John Spurlockcfc359a2013-09-05 10:42:03 -04002917 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04002918 pw.print(" mStatusBarWindowState=");
2919 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002920 pw.print(" mStatusBarMode=");
2921 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlockbf370992014-06-17 13:58:31 -04002922 pw.print(" mDozing="); pw.println(mDozing);
John Spurlocke677d712014-02-13 12:52:19 -05002923 pw.print(" mZenMode=");
2924 pw.println(Settings.Global.zenModeToString(mZenMode));
Chris Wren3b6745b2014-03-07 14:34:35 -05002925 pw.print(" mUseHeadsUp=");
2926 pw.println(mUseHeadsUp);
John Spurlock0ec64c62013-08-26 15:37:58 -04002927 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
2928 if (mNavigationBarView != null) {
2929 pw.print(" mNavigationBarWindowState=");
2930 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04002931 pw.print(" mNavigationBarMode=");
2932 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04002933 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
2934 }
2935
Daniel Sandler48852952011-12-01 14:34:23 -05002936 pw.print(" mNavigationBarView=");
2937 if (mNavigationBarView == null) {
2938 pw.println("null");
2939 } else {
2940 mNavigationBarView.dump(fd, pw, args);
2941 }
2942
Dan Sandler16128f42014-05-21 12:48:22 -04002943 pw.print(" mMediaSessionManager=");
2944 pw.println(mMediaSessionManager);
2945 pw.print(" mMediaNotificationKey=");
2946 pw.println(mMediaNotificationKey);
2947 pw.print(" mMediaController=");
2948 pw.print(mMediaController);
2949 if (mMediaController != null) {
2950 pw.print(" state=" + mMediaController.getPlaybackState());
2951 }
2952 pw.println();
2953 pw.print(" mMediaMetadata=");
2954 pw.print(mMediaMetadata);
2955 if (mMediaMetadata != null) {
RoboErik75847b92014-07-29 13:10:17 -07002956 pw.print(" title=" + mMediaMetadata.getText(MediaMetadata.METADATA_KEY_TITLE));
Dan Sandler16128f42014-05-21 12:48:22 -04002957 }
2958 pw.println();
2959
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002960 pw.println(" Panels: ");
2961 if (mNotificationPanel != null) {
2962 pw.println(" mNotificationPanel=" +
2963 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
2964 pw.print (" ");
2965 mNotificationPanel.dump(fd, pw, args);
2966 }
Daniel Sandler37a38aa2013-02-13 17:15:57 -05002967
John Spurlock813552c2014-09-19 08:30:21 -04002968 DozeLog.dump(pw);
2969
Daniel Sandler7579bca2011-08-18 15:47:26 -04002970 if (DUMPTRUCK) {
2971 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002972 mNotificationData.dump(pw, " ");
Daniel Sandler7579bca2011-08-18 15:47:26 -04002973 }
2974
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002975 mIconController.dump(pw);
Jim Miller5e6af442011-12-02 18:24:26 -08002976
Daniel Sandler89d97132011-09-08 15:31:57 -04002977 if (false) {
2978 pw.println("see the logcat for a dump of the views we have created.");
2979 // must happen on ui thread
2980 mHandler.post(new Runnable() {
2981 public void run() {
2982 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04002983 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04002984 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04002985 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04002986 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04002987 }
2988 });
2989 }
Joe Onorato808182d2010-07-09 18:52:06 -04002990 }
Daniel Sandler89d97132011-09-08 15:31:57 -04002991
Daniel Sandler151f00d2012-10-02 22:33:08 -04002992 if (DEBUG_GESTURES) {
2993 pw.print(" status bar gestures: ");
2994 mGestureRec.dump(fd, pw, args);
2995 }
Selim Cinek7025f262015-07-13 16:22:48 -07002996 if (mStatusBarWindowManager != null) {
2997 mStatusBarWindowManager.dump(fd, pw, args);
2998 }
John Spurlock486b78e2014-07-07 08:37:56 -04002999 if (mNetworkController != null) {
3000 mNetworkController.dump(fd, pw, args);
3001 }
3002 if (mBluetoothController != null) {
3003 mBluetoothController.dump(fd, pw, args);
3004 }
Jason Monkdd5bdc62015-07-20 12:18:38 -04003005 if (mHotspotController != null) {
3006 mHotspotController.dump(fd, pw, args);
3007 }
John Spurlock1e6eb172014-07-13 11:59:50 -04003008 if (mCastController != null) {
3009 mCastController.dump(fd, pw, args);
3010 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +02003011 if (mUserSwitcherController != null) {
3012 mUserSwitcherController.dump(fd, pw, args);
3013 }
John Spurlock0ff62e02014-07-22 16:15:08 -04003014 if (mBatteryController != null) {
3015 mBatteryController.dump(fd, pw, args);
3016 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02003017 if (mNextAlarmController != null) {
3018 mNextAlarmController.dump(fd, pw, args);
3019 }
Jason Monk3d5f5512014-07-25 11:17:28 -04003020 if (mSecurityController != null) {
3021 mSecurityController.dump(fd, pw, args);
3022 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003023 if (mHeadsUpManager != null) {
3024 mHeadsUpManager.dump(fd, pw, args);
Chris Wren428c6b62014-12-05 16:07:06 -05003025 } else {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003026 pw.println(" mHeadsUpManager: null");
Chris Wren428c6b62014-12-05 16:07:06 -05003027 }
Jason Monkab525272015-07-13 17:02:49 -04003028 if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
3029 KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
3030 }
Chris Wren428c6b62014-12-05 16:07:06 -05003031
Adrian Roos401caae2016-03-04 13:35:21 -08003032 FalsingManager.getInstance(mContext).dump(pw);
3033 FalsingLog.dump(pw);
3034
John Spurlock7bbb9f62014-10-21 12:15:28 -04003035 pw.println("SharedPreferences:");
Andrew Flynn82862572015-04-01 14:22:37 -04003036 for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
John Spurlock7bbb9f62014-10-21 12:15:28 -04003037 pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
3038 }
Joe Onorato808182d2010-07-09 18:52:06 -04003039 }
3040
John Spurlock0ec64c62013-08-26 15:37:58 -04003041 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
3042 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
3043 pw.println(BarTransitions.modeToString(transitions.getMode()));
3044 }
3045
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05003046 @Override
3047 public void createAndAddWindows() {
3048 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04003049 }
Jim Millere898ac52012-04-06 17:10:57 -07003050
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05003051 private void addStatusBarWindow() {
Daniel Sandlera310af82012-04-24 01:20:13 -04003052 makeStatusBarView();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01003053 mStatusBarWindowManager = new StatusBarWindowManager(mContext);
Adrian Roos1c0ca502015-10-07 12:20:42 -07003054 mRemoteInputController = new RemoteInputController(mStatusBarWindowManager,
3055 mHeadsUpManager);
Jorim Jaggi5cf17872014-03-26 18:31:48 +01003056 mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
Joe Onorato808182d2010-07-09 18:52:06 -04003057 }
3058
Daniel Sandler747a9e92012-08-10 16:39:19 -04003059 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07003060 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04003061 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04003062 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04003063 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04003064 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04003065 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
3066 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07003067 }
3068
Christoph Studerb0183992014-12-22 21:02:26 +01003069 float getDisplayDensity() {
3070 return mDisplayMetrics.density;
3071 }
3072
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003073 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
Jorim Jaggid9449862015-05-29 14:49:08 -07003074 boolean dismissShade) {
3075 startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, null /* callback */);
3076 }
3077
3078 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
3079 final boolean dismissShade, final Callback callback) {
Daniel Sandler3679bf52012-10-16 21:30:28 -04003080 if (onlyProvisioned && !isDeviceProvisioned()) return;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003081
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003082 final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
3083 mContext, intent, mCurrentUserId);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02003084 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Selim Cineke70d6532015-04-24 16:46:13 -07003085 Runnable runnable = new Runnable() {
3086 public void run() {
Jorim Jaggib835dd72015-06-08 12:28:42 -07003087 mAssistManager.hideAssist();
Selim Cineke70d6532015-04-24 16:46:13 -07003088 intent.setFlags(
3089 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Jorim Jaggid9449862015-05-29 14:49:08 -07003090 int result = ActivityManager.START_CANCELED;
3091 try {
3092 result = ActivityManagerNative.getDefault().startActivityAsUser(
3093 null, mContext.getBasePackageName(),
3094 intent,
3095 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Jorim Jaggie6e108e2016-03-28 13:38:45 -07003096 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
3097 getActivityOptions(), UserHandle.CURRENT.getIdentifier());
Jorim Jaggid9449862015-05-29 14:49:08 -07003098 } catch (RemoteException e) {
3099 Log.w(TAG, "Unable to start activity", e);
3100 }
Selim Cineke70d6532015-04-24 16:46:13 -07003101 overrideActivityPendingAppTransition(
3102 keyguardShowing && !afterKeyguardGone);
Jorim Jaggid9449862015-05-29 14:49:08 -07003103 if (callback != null) {
3104 callback.onActivityStarted(result);
3105 }
Selim Cineke70d6532015-04-24 16:46:13 -07003106 }
3107 };
Jorim Jaggid9449862015-05-29 14:49:08 -07003108 Runnable cancelRunnable = new Runnable() {
3109 @Override
3110 public void run() {
Jorim Jaggi5cc86592015-06-08 14:48:28 -07003111 if (callback != null) {
3112 callback.onActivityStarted(ActivityManager.START_CANCELED);
3113 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003114 }
3115 };
Jorim Jaggib835dd72015-06-08 12:28:42 -07003116 executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShade,
3117 afterKeyguardGone);
Selim Cineke70d6532015-04-24 16:46:13 -07003118 }
3119
3120 public void executeRunnableDismissingKeyguard(final Runnable runnable,
Jorim Jaggid9449862015-05-29 14:49:08 -07003121 final Runnable cancelAction,
Selim Cineke70d6532015-04-24 16:46:13 -07003122 final boolean dismissShade,
3123 final boolean afterKeyguardGone) {
3124 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Adrian Roos4314f6d2014-05-28 14:10:27 +02003125 dismissKeyguardThenExecute(new OnDismissAction() {
3126 @Override
3127 public boolean onDismiss() {
Selim Cinekbaa23272014-07-08 18:01:07 +02003128 AsyncTask.execute(new Runnable() {
3129 public void run() {
3130 try {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003131 if (keyguardShowing && !afterKeyguardGone) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003132 ActivityManagerNative.getDefault()
3133 .keyguardWaitingForActivityDrawn();
3134 }
Selim Cineke70d6532015-04-24 16:46:13 -07003135 if (runnable != null) {
3136 runnable.run();
3137 }
Selim Cinekbaa23272014-07-08 18:01:07 +02003138 } catch (RemoteException e) {
3139 }
3140 }
3141 });
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003142 if (dismissShade) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07003143 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
3144 true /* delayed*/);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003145 }
3146 return true;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003147 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003148 }, cancelAction, afterKeyguardGone);
Daniel Sandler3679bf52012-10-16 21:30:28 -04003149 }
3150
Joe Onorato808182d2010-07-09 18:52:06 -04003151 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
3152 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04003153 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04003154 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04003155 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Andrei Stingaceanu9d9294c2015-08-24 17:19:06 +01003156 getKeyboardShortcuts().dismissKeyboardShortcutsDialog();
Kenny Guy44fc65f2014-11-28 22:18:14 +00003157 if (isCurrentProfile(getSendingUserId())) {
3158 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
3159 String reason = intent.getStringExtra("reason");
3160 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
3161 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
3162 }
3163 animateCollapsePanels(flags);
Michael Jurka3b1fc472011-06-13 10:54:40 -07003164 }
Joe Onorato808182d2010-07-09 18:52:06 -04003165 }
Daniel Sandlered930e52012-07-03 14:31:22 -04003166 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003167 notifyNavigationBarScreenOn(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003168 notifyHeadsUpScreenOff();
John Spurlock42197262013-10-21 09:32:25 -04003169 finishBarAnimations();
Selim Cinekccd14fb2014-08-12 18:53:24 +02003170 resetUserExpandedStates();
Daniel Sandlered930e52012-07-03 14:31:22 -04003171 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04003172 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003173 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04003174 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003175 }
3176 };
3177
3178 private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
3179 public void onReceive(Context context, Intent intent) {
3180 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
3181 String action = intent.getAction();
3182 if (ACTION_DEMO.equals(action)) {
John Spurlock3c875662013-08-31 15:07:25 -04003183 Bundle bundle = intent.getExtras();
3184 if (bundle != null) {
3185 String command = bundle.getString("command", "").trim().toLowerCase();
3186 if (command.length() > 0) {
3187 try {
3188 dispatchDemoCommand(command, bundle);
3189 } catch (Throwable t) {
3190 Log.w(TAG, "Error running demo command, intent=" + intent, t);
3191 }
3192 }
3193 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003194 } else if (ACTION_FAKE_ARTWORK.equals(action)) {
Dan Sandler16128f42014-05-21 12:48:22 -04003195 if (DEBUG_MEDIA_FAKE_ARTWORK) {
Adrian Roos52738322016-01-29 08:49:21 -08003196 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -04003197 }
John Spurlock3c875662013-08-31 15:07:25 -04003198 }
Joe Onorato808182d2010-07-09 18:52:06 -04003199 }
3200 };
3201
Selim Cinek78f40082016-03-10 18:06:27 -08003202 public void resetUserExpandedStates() {
Selim Cinekccd14fb2014-08-12 18:53:24 +02003203 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
3204 final int notificationCount = activeNotifications.size();
3205 for (int i = 0; i < notificationCount; i++) {
3206 NotificationData.Entry entry = activeNotifications.get(i);
3207 if (entry.row != null) {
3208 entry.row.resetUserExpansion();
3209 }
3210 }
3211 }
3212
Adrian Roos7d7090d2014-05-21 13:10:23 +02003213 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07003214 protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
3215 dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
3216 }
3217
Jason Monkabe19742015-09-29 09:47:06 -04003218 public void dismissKeyguard() {
3219 mStatusBarKeyguardViewManager.dismiss();
3220 }
3221
Jorim Jaggid9449862015-05-29 14:49:08 -07003222 private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003223 boolean afterKeyguardGone) {
Adrian Roos7d7090d2014-05-21 13:10:23 +02003224 if (mStatusBarKeyguardViewManager.isShowing()) {
Jorim Jaggid9449862015-05-29 14:49:08 -07003225 mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
3226 afterKeyguardGone);
Adrian Roos7d7090d2014-05-21 13:10:23 +02003227 } else {
3228 action.onDismiss();
3229 }
3230 }
3231
Daniel Sandler777dcde2013-09-30 10:21:45 -04003232 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
3233 @Override
3234 protected void onConfigurationChanged(Configuration newConfig) {
3235 super.onConfigurationChanged(newConfig); // calls refreshLayout
3236
3237 if (DEBUG) {
3238 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
3239 }
Daniel Sandler7e8ae502013-10-10 23:38:19 -04003240 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04003241
3242 updateResources();
3243 repositionNavigationBar();
Jorim Jaggif6411742014-08-05 17:10:43 +00003244 updateRowStates();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003245 mIconController.updateResources();
Jason Monk18f99d92014-09-11 13:36:42 -04003246 mScreenPinningRequest.onConfigurationChanged();
Jason Monk1c040db2015-07-20 09:45:54 -04003247 mNetworkController.onConfigurationChanged();
Daniel Sandler777dcde2013-09-30 10:21:45 -04003248 }
3249
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003250 @Override
3251 public void userSwitched(int newUserId) {
Chris Wrena6d4fb62014-11-20 14:46:23 -05003252 super.userSwitched(newUserId);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003253 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04003254 animateCollapsePanels();
Adrian Roos31b844b2014-11-21 13:55:09 +01003255 updatePublicMode();
Christoph Studer37fe6932014-05-26 13:10:30 +02003256 updateNotifications();
John Spurlock919adac2012-10-02 16:41:12 -04003257 resetUserSetupObserver();
John Spurlock89f060a2014-07-16 21:03:15 -04003258 setControllerUsers();
Julia Reynolds86ef8e22015-09-09 16:42:38 -04003259 clearCurrentMediaNotification();
Vadim Tryshev12a30e82016-02-12 15:39:28 -08003260 mLockscreenWallpaper.setCurrentUser(newUserId);
Adrian Roos52738322016-01-29 08:49:21 -08003261 updateMediaMetaData(true, false);
John Spurlock89f060a2014-07-16 21:03:15 -04003262 }
3263
3264 private void setControllerUsers() {
3265 if (mZenModeController != null) {
3266 mZenModeController.setUserId(mCurrentUserId);
3267 }
Robin Lee63204ee2015-06-04 01:53:01 +01003268 if (mSecurityController != null) {
3269 mSecurityController.onUserSwitched(mCurrentUserId);
3270 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003271 }
John Spurlock919adac2012-10-02 16:41:12 -04003272
3273 private void resetUserSetupObserver() {
3274 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
3275 mUserSetupObserver.onChange(false);
3276 mContext.getContentResolver().registerContentObserver(
3277 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003278 mUserSetupObserver, mCurrentUserId);
John Spurlock919adac2012-10-02 16:41:12 -04003279 }
3280
Joe Onorato808182d2010-07-09 18:52:06 -04003281 /**
3282 * Reload some of our resources when the configuration changes.
3283 *
3284 * We don't reload everything when the configuration changes -- we probably
3285 * should, but getting that smooth is tough. Someday we'll fix that. In the
3286 * meantime, just update the things that we know change.
3287 */
3288 void updateResources() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003289 // Update the quick setting tiles
John Spurlock7e6809a2014-08-06 16:03:14 -04003290 if (mQSPanel != null) {
3291 mQSPanel.updateResources();
3292 }
Winson Chungd63c59782012-09-05 17:34:41 -07003293
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003294 loadDimens();
John Spurlock7e6809a2014-08-06 16:03:14 -04003295
3296 if (mNotificationPanel != null) {
3297 mNotificationPanel.updateResources();
3298 }
Adrian Roos5fd872e2014-08-12 17:28:58 +02003299 if (mBrightnessMirrorController != null) {
3300 mBrightnessMirrorController.updateResources();
3301 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003302 }
Jim Miller5e6af442011-12-02 18:24:26 -08003303
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003304 protected void loadDimens() {
3305 final Resources res = mContext.getResources();
3306
3307 mNaturalBarHeight = res.getDimensionPixelSize(
3308 com.android.internal.R.dimen.status_bar_height);
3309
Selim Cinek5f71bee2015-11-18 10:25:23 -08003310 mMaxAllowedKeyguardNotifications = res.getInteger(R.integer.keyguard_max_notification_count);
Jorim Jaggid4a57442014-04-10 02:45:55 +02003311
John Spurlock7e6809a2014-08-06 16:03:14 -04003312 if (DEBUG) Log.v(TAG, "updateResources");
John Spurlock804df702012-06-01 15:34:27 -04003313 }
3314
Christoph Studer92b389d2014-04-01 18:44:40 +02003315 // Visibility reporting
3316
3317 @Override
Christoph Studere8e28652014-10-29 17:27:53 +01003318 protected void handleVisibleToUserChanged(boolean visibleToUser) {
3319 if (visibleToUser) {
3320 super.handleVisibleToUserChanged(visibleToUser);
3321 startNotificationLogging();
Christoph Studer92b389d2014-04-01 18:44:40 +02003322 } else {
Christoph Studer037e34c2014-04-30 20:06:04 +02003323 stopNotificationLogging();
Christoph Studere8e28652014-10-29 17:27:53 +01003324 super.handleVisibleToUserChanged(visibleToUser);
Christoph Studer92b389d2014-04-01 18:44:40 +02003325 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003326 }
3327
Christoph Studer037e34c2014-04-30 20:06:04 +02003328 private void stopNotificationLogging() {
3329 // Report all notifications as invisible and turn down the
3330 // reporter.
3331 if (!mCurrentlyVisibleNotifications.isEmpty()) {
Chris Wrend1dbc922015-06-19 17:51:16 -04003332 logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(),
3333 mCurrentlyVisibleNotifications);
3334 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer037e34c2014-04-30 20:06:04 +02003335 }
3336 mHandler.removeCallbacks(mVisibilityReporter);
3337 mStackScroller.setChildLocationsChangedListener(null);
3338 }
3339
Christoph Studere8e28652014-10-29 17:27:53 +01003340 private void startNotificationLogging() {
3341 mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
3342 // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
3343 // cause the scroller to emit child location events. Hence generate
3344 // one ourselves to guarantee that we're reporting visible
3345 // notifications.
3346 // (Note that in cases where the scroller does emit events, this
3347 // additional event doesn't break anything.)
3348 mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
Christoph Studer037e34c2014-04-30 20:06:04 +02003349 }
3350
Christoph Studer92b389d2014-04-01 18:44:40 +02003351 private void logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -04003352 Collection<NotificationVisibility> newlyVisible,
3353 Collection<NotificationVisibility> noLongerVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +02003354 if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
3355 return;
3356 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003357 NotificationVisibility[] newlyVisibleAr =
3358 newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]);
3359 NotificationVisibility[] noLongerVisibleAr =
3360 noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]);
Christoph Studer92b389d2014-04-01 18:44:40 +02003361 try {
3362 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
3363 } catch (RemoteException e) {
3364 // Ignore.
3365 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003366
3367 final int N = newlyVisible.size();
Amith Yamasani76495672015-07-07 15:22:54 -07003368 if (N > 0) {
3369 String[] newlyVisibleKeyAr = new String[N];
3370 for (int i = 0; i < N; i++) {
3371 newlyVisibleKeyAr[i] = newlyVisibleAr[i].key;
3372 }
3373
3374 setNotificationsShown(newlyVisibleKeyAr);
Chris Wrend1dbc922015-06-19 17:51:16 -04003375 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003376 }
3377
Christoph Studer2231c6e2014-12-19 12:40:13 +01003378 // State logging
3379
3380 private void logStateToEventlog() {
3381 boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
3382 boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
3383 boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
3384 boolean isSecure = mUnlockMethodCache.isMethodSecure();
Selim Cineke8bae622015-07-15 13:24:06 -07003385 boolean canSkipBouncer = mUnlockMethodCache.canSkipBouncer();
Christoph Studer2231c6e2014-12-19 12:40:13 +01003386 int stateFingerprint = getLoggingFingerprint(mState,
3387 isShowing,
3388 isOccluded,
3389 isBouncerShowing,
3390 isSecure,
Selim Cineke8bae622015-07-15 13:24:06 -07003391 canSkipBouncer);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003392 if (stateFingerprint != mLastLoggedStateFingerprint) {
3393 EventLogTags.writeSysuiStatusBarState(mState,
3394 isShowing ? 1 : 0,
3395 isOccluded ? 1 : 0,
3396 isBouncerShowing ? 1 : 0,
3397 isSecure ? 1 : 0,
Selim Cineke8bae622015-07-15 13:24:06 -07003398 canSkipBouncer ? 1 : 0);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003399 mLastLoggedStateFingerprint = stateFingerprint;
3400 }
3401 }
3402
3403 /**
3404 * Returns a fingerprint of fields logged to eventlog
3405 */
3406 private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
3407 boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
3408 boolean currentlyInsecure) {
3409 // Reserve 8 bits for statusBarState. We'll never go higher than
3410 // that, right? Riiiight.
3411 return (statusBarState & 0xFF)
3412 | ((keyguardShowing ? 1 : 0) << 8)
3413 | ((keyguardOccluded ? 1 : 0) << 9)
3414 | ((bouncerShowing ? 1 : 0) << 10)
3415 | ((secure ? 1 : 0) << 11)
3416 | ((currentlyInsecure ? 1 : 0) << 12);
3417 }
3418
Joe Onorato808182d2010-07-09 18:52:06 -04003419 //
3420 // tracing
3421 //
3422
3423 void postStartTracing() {
3424 mHandler.postDelayed(mStartTracing, 3000);
3425 }
3426
3427 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04003428 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
3429 Context.VIBRATOR_SERVICE);
John Spurlock7b414672014-07-18 13:02:39 -04003430 vib.vibrate(250, VIBRATION_ATTRIBUTES);
Joe Onorato808182d2010-07-09 18:52:06 -04003431 }
3432
3433 Runnable mStartTracing = new Runnable() {
3434 public void run() {
3435 vibrate();
3436 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04003437 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003438 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
3439 mHandler.postDelayed(mStopTracing, 10000);
3440 }
3441 };
3442
3443 Runnable mStopTracing = new Runnable() {
3444 public void run() {
3445 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04003446 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003447 vibrate();
3448 }
3449 };
Chris Wren0c8275b2012-05-08 13:36:48 -04003450
3451 @Override
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07003452 public boolean shouldDisableNavbarGestures() {
Jorim Jaggi18976a52015-07-24 13:18:19 -07003453 return !isDeviceProvisioned() || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07003454 }
Joe Onorato808182d2010-07-09 18:52:06 -04003455
Jason Monkba2318e2015-12-08 09:04:23 -05003456 public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
3457 mHandler.post(new Runnable() {
3458 @Override
3459 public void run() {
3460 mLeaveOpenOnKeyguardHide = true;
3461 executeRunnableDismissingKeyguard(runnable, null, false, true);
3462 }
3463 });
3464 }
3465
Adrian Roos62692b22015-09-11 17:46:23 -07003466 public void postStartActivityDismissingKeyguard(final PendingIntent intent) {
3467 mHandler.post(new Runnable() {
3468 @Override
3469 public void run() {
3470 startPendingIntentDismissingKeyguard(intent);
3471 }
3472 });
3473 }
3474
Jason Monkee43cdf2015-06-19 14:20:46 -04003475 public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
John Spurlockd47a3f32014-05-18 19:14:14 -04003476 mHandler.postDelayed(new Runnable() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003477 @Override
3478 public void run() {
Jason Monkee43cdf2015-06-19 14:20:46 -04003479 handleStartActivityDismissingKeyguard(intent, true /*onlyProvisioned*/);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003480 }
John Spurlockd47a3f32014-05-18 19:14:14 -04003481 }, delay);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003482 }
3483
Jason Monkee43cdf2015-06-19 14:20:46 -04003484 private void handleStartActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003485 startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
John Spurlockde547002014-02-28 17:50:39 -05003486 }
3487
Romain Guy648342f2012-05-25 10:44:45 -07003488 private static class FastColorDrawable extends Drawable {
3489 private final int mColor;
3490
3491 public FastColorDrawable(int color) {
3492 mColor = 0xff000000 | color;
3493 }
3494
3495 @Override
3496 public void draw(Canvas canvas) {
3497 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
3498 }
3499
3500 @Override
3501 public void setAlpha(int alpha) {
3502 }
3503
3504 @Override
Chris Craikbd3bfc52015-03-02 10:43:29 -08003505 public void setColorFilter(ColorFilter colorFilter) {
Romain Guy648342f2012-05-25 10:44:45 -07003506 }
3507
3508 @Override
3509 public int getOpacity() {
3510 return PixelFormat.OPAQUE;
3511 }
3512
3513 @Override
3514 public void setBounds(int left, int top, int right, int bottom) {
3515 }
3516
3517 @Override
3518 public void setBounds(Rect bounds) {
3519 }
3520 }
John Spurlock5c454122013-06-17 07:35:46 -04003521
3522 @Override
3523 public void destroy() {
3524 super.destroy();
3525 if (mStatusBarWindow != null) {
3526 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05003527 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04003528 }
3529 if (mNavigationBarView != null) {
3530 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05003531 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04003532 }
Jason Monk4ae97d32014-12-17 10:14:33 -05003533 if (mHandlerThread != null) {
3534 mHandlerThread.quitSafely();
3535 mHandlerThread = null;
3536 }
John Spurlock5c454122013-06-17 07:35:46 -04003537 mContext.unregisterReceiver(mBroadcastReceiver);
Adrian Roos8e3e8362015-07-16 19:42:22 -07003538 mContext.unregisterReceiver(mDemoReceiver);
Selim Cineke70d6532015-04-24 16:46:13 -07003539 mAssistManager.destroy();
Jason Monk07b75fe2015-05-14 16:47:03 -04003540
3541 final SignalClusterView signalCluster =
3542 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
3543 final SignalClusterView signalClusterKeyguard =
3544 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
3545 final SignalClusterView signalClusterQs =
3546 (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
Jason Monk5e745172015-06-02 19:14:44 -04003547 mNetworkController.removeSignalCallback(signalCluster);
3548 mNetworkController.removeSignalCallback(signalClusterKeyguard);
3549 mNetworkController.removeSignalCallback(signalClusterQs);
3550 if (mQSPanel != null && mQSPanel.getHost() != null) {
3551 mQSPanel.getHost().destroy();
3552 }
John Spurlock5c454122013-06-17 07:35:46 -04003553 }
John Spurlock3c875662013-08-31 15:07:25 -04003554
3555 private boolean mDemoModeAllowed;
3556 private boolean mDemoMode;
John Spurlock3c875662013-08-31 15:07:25 -04003557
3558 @Override
3559 public void dispatchDemoCommand(String command, Bundle args) {
3560 if (!mDemoModeAllowed) {
3561 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
Jason Monk431ad732015-07-16 08:58:15 -04003562 DEMO_MODE_ALLOWED, 0) != 0;
John Spurlock3c875662013-08-31 15:07:25 -04003563 }
3564 if (!mDemoModeAllowed) return;
3565 if (command.equals(COMMAND_ENTER)) {
3566 mDemoMode = true;
3567 } else if (command.equals(COMMAND_EXIT)) {
3568 mDemoMode = false;
3569 checkBarModes();
3570 } else if (!mDemoMode) {
3571 // automatically enter demo mode on first demo command
3572 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
3573 }
3574 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
John Spurlockbb4a7022014-11-08 12:40:19 -05003575 if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
3576 mVolumeComponent.dispatchDemoCommand(command, args);
3577 }
John Spurlock3c875662013-08-31 15:07:25 -04003578 if (modeChange || command.equals(COMMAND_CLOCK)) {
3579 dispatchDemoCommandToView(command, args, R.id.clock);
3580 }
3581 if (modeChange || command.equals(COMMAND_BATTERY)) {
3582 dispatchDemoCommandToView(command, args, R.id.battery);
3583 }
3584 if (modeChange || command.equals(COMMAND_STATUS)) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003585 mIconController.dispatchDemoCommand(command, args);
3586
John Spurlock3c875662013-08-31 15:07:25 -04003587 }
3588 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
3589 mNetworkController.dispatchDemoCommand(command, args);
3590 }
John Spurlock7f42fc52014-01-14 16:20:39 -05003591 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
3592 View notifications = mStatusBarView == null ? null
3593 : mStatusBarView.findViewById(R.id.notification_icon_area);
3594 if (notifications != null) {
3595 String visible = args.getString("visible");
3596 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
3597 notifications.setVisibility(vis);
3598 }
3599 }
John Spurlock3c875662013-08-31 15:07:25 -04003600 if (command.equals(COMMAND_BARS)) {
3601 String mode = args.getString("mode");
3602 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04003603 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04003604 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
John Spurlock0ff62e02014-07-22 16:15:08 -04003605 "transparent".equals(mode) ? MODE_TRANSPARENT :
3606 "warning".equals(mode) ? MODE_WARNING :
John Spurlock3c875662013-08-31 15:07:25 -04003607 -1;
3608 if (barMode != -1) {
3609 boolean animate = true;
3610 if (mStatusBarView != null) {
3611 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
3612 }
3613 if (mNavigationBarView != null) {
3614 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
3615 }
3616 }
3617 }
3618 }
3619
3620 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
3621 if (mStatusBarView == null) return;
3622 View v = mStatusBarView.findViewById(id);
3623 if (v instanceof DemoMode) {
3624 ((DemoMode)v).dispatchDemoCommand(command, args);
3625 }
3626 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003627
Jorim Jaggiecbab362014-04-23 16:13:15 +02003628 /**
3629 * @return The {@link StatusBarState} the status bar is in.
3630 */
3631 public int getBarState() {
3632 return mState;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003633 }
3634
Chris Wren16895942015-06-23 11:22:20 -04003635 @Override
Yorke Leee4ea6ab2016-03-03 14:51:49 -08003636 public boolean isPanelFullyCollapsed() {
Chris Wren16895942015-06-23 11:22:20 -04003637 return mNotificationPanel.isFullyCollapsed();
3638 }
3639
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003640 public void showKeyguard() {
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003641 if (mLaunchTransitionFadingAway) {
3642 mNotificationPanel.animate().cancel();
Selim Cinek37c110f2015-05-22 12:38:44 -07003643 onLaunchTransitionFadingEnded();
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003644 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003645 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003646 if (mUserSwitcherController != null && mUserSwitcherController.useFullscreenUserSwitcher()) {
3647 setBarState(StatusBarState.FULLSCREEN_USER_SWITCHER);
3648 } else {
3649 setBarState(StatusBarState.KEYGUARD);
3650 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02003651 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003652 if (!mDeviceInteractive) {
Jorim Jaggid41083a2014-09-12 02:54:40 +02003653
3654 // If the screen is off already, we need to disable touch events because these might
3655 // collapse the panel after we expanded it, and thus we would end up with a blank
3656 // Keyguard.
3657 mNotificationPanel.setTouchDisabled(true);
3658 }
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003659 if (mState == StatusBarState.KEYGUARD) {
3660 instantExpandNotificationsPanel();
3661 } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
3662 instantCollapseNotificationPanel();
3663 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003664 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003665 if (mDraggedDownRow != null) {
3666 mDraggedDownRow.setUserLocked(false);
Selim Cinekb5605e52015-02-20 18:21:41 +01003667 mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003668 mDraggedDownRow = null;
3669 }
Adrian Roos3aec6382016-02-05 14:19:01 -08003670 mPendingRemoteInputView = null;
Jorim Jaggi19695d92015-07-20 15:51:40 -07003671 mAssistManager.onLockscreenShown();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003672 }
3673
Selim Cinek37c110f2015-05-22 12:38:44 -07003674 private void onLaunchTransitionFadingEnded() {
3675 mNotificationPanel.setAlpha(1.0f);
Selim Cinek372d1bd2015-08-14 13:19:37 -07003676 mNotificationPanel.onAffordanceLaunchEnded();
3677 releaseGestureWakeLock();
Selim Cinek37c110f2015-05-22 12:38:44 -07003678 runLaunchTransitionEndRunnable();
3679 mLaunchTransitionFadingAway = false;
3680 mScrimController.forceHideScrims(false /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08003681 updateMediaMetaData(true /* metaDataChanged */, true);
Selim Cinek37c110f2015-05-22 12:38:44 -07003682 }
3683
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003684 public boolean isCollapsing() {
3685 return mNotificationPanel.isCollapsing();
3686 }
3687
3688 public void addPostCollapseAction(Runnable r) {
3689 mPostCollapseRunnables.add(r);
3690 }
3691
Selim Cinekbaa23272014-07-08 18:01:07 +02003692 public boolean isInLaunchTransition() {
3693 return mNotificationPanel.isLaunchTransitionRunning()
3694 || mNotificationPanel.isLaunchTransitionFinished();
3695 }
3696
3697 /**
3698 * Fades the content of the keyguard away after the launch transition is done.
3699 *
3700 * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
3701 * starts
3702 * @param endRunnable the runnable to be run when the transition is done
3703 */
3704 public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003705 Runnable endRunnable) {
Jorim Jaggi826730a2014-12-08 21:05:13 +01003706 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggi5e08e692014-10-03 15:17:20 -07003707 mLaunchTransitionEndRunnable = endRunnable;
Selim Cinekbaa23272014-07-08 18:01:07 +02003708 Runnable hideRunnable = new Runnable() {
3709 @Override
3710 public void run() {
3711 mLaunchTransitionFadingAway = true;
3712 if (beforeFading != null) {
3713 beforeFading.run();
3714 }
Selim Cinek37c110f2015-05-22 12:38:44 -07003715 mScrimController.forceHideScrims(true /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08003716 updateMediaMetaData(false, true);
Selim Cinekbaa23272014-07-08 18:01:07 +02003717 mNotificationPanel.setAlpha(1);
3718 mNotificationPanel.animate()
3719 .alpha(0)
3720 .setStartDelay(FADE_KEYGUARD_START_DELAY)
3721 .setDuration(FADE_KEYGUARD_DURATION)
3722 .withLayer()
3723 .withEndAction(new Runnable() {
3724 @Override
3725 public void run() {
Selim Cinek37c110f2015-05-22 12:38:44 -07003726 onLaunchTransitionFadingEnded();
Selim Cinekbaa23272014-07-08 18:01:07 +02003727 }
3728 });
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003729 mIconController.appTransitionStarting(SystemClock.uptimeMillis(),
3730 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Selim Cinekbaa23272014-07-08 18:01:07 +02003731 }
3732 };
3733 if (mNotificationPanel.isLaunchTransitionRunning()) {
3734 mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
3735 } else {
3736 hideRunnable.run();
3737 }
3738 }
3739
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003740 /**
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07003741 * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
3742 * fading.
3743 */
3744 public void fadeKeyguardWhilePulsing() {
3745 mNotificationPanel.animate()
3746 .alpha(0f)
3747 .setStartDelay(0)
3748 .setDuration(FADE_KEYGUARD_DURATION_PULSING)
Jorim Jaggiab45a212015-08-20 16:59:44 -07003749 .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
3750 .start();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07003751 }
3752
3753 /**
Jorim Jaggi826730a2014-12-08 21:05:13 +01003754 * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
3755 * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
3756 * because the launched app crashed or something else went wrong.
3757 */
3758 public void startLaunchTransitionTimeout() {
3759 mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
3760 LAUNCH_TRANSITION_TIMEOUT_MS);
3761 }
3762
3763 private void onLaunchTransitionTimeout() {
3764 Log.w(TAG, "Launch transition: Timeout!");
Selim Cinek372d1bd2015-08-14 13:19:37 -07003765 mNotificationPanel.onAffordanceLaunchEnded();
3766 releaseGestureWakeLock();
Jorim Jaggi826730a2014-12-08 21:05:13 +01003767 mNotificationPanel.resetViews();
3768 }
3769
3770 private void runLaunchTransitionEndRunnable() {
3771 if (mLaunchTransitionEndRunnable != null) {
3772 Runnable r = mLaunchTransitionEndRunnable;
3773
3774 // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
3775 // which would lead to infinite recursion. Protect against it.
3776 mLaunchTransitionEndRunnable = null;
3777 r.run();
3778 }
3779 }
3780
3781 /**
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003782 * @return true if we would like to stay in the shade, false if it should go away entirely
3783 */
3784 public boolean hideKeyguard() {
3785 boolean staying = mLeaveOpenOnKeyguardHide;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003786 setBarState(StatusBarState.SHADE);
Adrian Roos3aec6382016-02-05 14:19:01 -08003787 View viewToClick = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02003788 if (mLeaveOpenOnKeyguardHide) {
3789 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggi37c11802015-08-18 20:27:54 -07003790 long delay = calculateGoingToFullShadeDelay();
3791 mNotificationPanel.animateToFullShade(delay);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003792 if (mDraggedDownRow != null) {
3793 mDraggedDownRow.setUserLocked(false);
3794 mDraggedDownRow = null;
3795 }
Adrian Roos3aec6382016-02-05 14:19:01 -08003796 viewToClick = mPendingRemoteInputView;
3797 mPendingRemoteInputView = null;
Jorim Jaggi37c11802015-08-18 20:27:54 -07003798
3799 // Disable layout transitions in navbar for this transition because the load is just
3800 // too heavy for the CPU and GPU on any device.
3801 if (mNavigationBarView != null) {
3802 mNavigationBarView.setLayoutTransitionsEnabled(false);
3803 mNavigationBarView.postDelayed(new Runnable() {
3804 @Override
3805 public void run() {
3806 mNavigationBarView.setLayoutTransitionsEnabled(true);
3807 }
3808 }, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
3809 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02003810 } else {
3811 instantCollapseNotificationPanel();
3812 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02003813 updateKeyguardState(staying, false /* fromShadeLocked */);
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01003814
Adrian Roos3aec6382016-02-05 14:19:01 -08003815 if (viewToClick != null) {
3816 viewToClick.callOnClick();
3817 }
3818
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01003819 // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
3820 // visibilities so next time we open the panel we know the correct height already.
3821 if (mQSPanel != null) {
3822 mQSPanel.refreshAllTiles();
3823 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01003824 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Selim Cinek372d1bd2015-08-14 13:19:37 -07003825 releaseGestureWakeLock();
3826 mNotificationPanel.onAffordanceLaunchEnded();
Jorim Jaggi52429b42015-09-03 19:58:19 -07003827 mNotificationPanel.animate().cancel();
Jorim Jaggi90978852015-08-18 19:55:53 -07003828 mNotificationPanel.setAlpha(1f);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003829 return staying;
3830 }
3831
Selim Cinek372d1bd2015-08-14 13:19:37 -07003832 private void releaseGestureWakeLock() {
3833 if (mGestureWakeLock.isHeld()) {
3834 mGestureWakeLock.release();
3835 }
3836 }
3837
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003838 public long calculateGoingToFullShadeDelay() {
3839 return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
Jorim Jaggi15682502014-04-23 12:01:36 +02003840 }
3841
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003842 /**
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003843 * Notifies the status bar that Keyguard is going away very soon.
3844 */
3845 public void keyguardGoingAway() {
3846
3847 // Treat Keyguard exit animation as an app transition to achieve nice transition for status
3848 // bar.
Adrian Roos46df1ca2015-09-11 12:38:43 -07003849 mKeyguardGoingAway = true;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003850 mIconController.appTransitionPending();
3851 }
3852
3853 /**
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003854 * Notifies the status bar the Keyguard is fading away with the specified timings.
3855 *
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003856 * @param startTime the start time of the animations in uptime millis
3857 * @param delay the precalculated animation delay in miliseconds
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003858 * @param fadeoutDuration the duration of the exit animation, in milliseconds
3859 */
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003860 public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003861 mKeyguardFadingAway = true;
3862 mKeyguardFadingAwayDelay = delay;
3863 mKeyguardFadingAwayDuration = fadeoutDuration;
3864 mWaitingForKeyguardExit = false;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003865 mIconController.appTransitionStarting(
3866 startTime + fadeoutDuration
3867 - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
3868 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07003869 disable(mDisabledUnmodified1, mDisabledUnmodified2, fadeoutDuration > 0 /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003870 }
3871
Jorim Jaggi416493b2014-09-13 03:57:32 +02003872 public boolean isKeyguardFadingAway() {
3873 return mKeyguardFadingAway;
3874 }
3875
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003876 /**
3877 * Notifies that the Keyguard fading away animation is done.
3878 */
3879 public void finishKeyguardFadingAway() {
3880 mKeyguardFadingAway = false;
Adrian Roos46df1ca2015-09-11 12:38:43 -07003881 mKeyguardGoingAway = false;
Jorim Jaggi44cf9192014-06-17 19:16:00 -07003882 }
3883
Adrian Roosd322f1a2015-04-23 15:19:45 -07003884 public void stopWaitingForKeyguardExit() {
3885 mWaitingForKeyguardExit = false;
3886 }
3887
Jorim Jaggi15682502014-04-23 12:01:36 +02003888 private void updatePublicMode() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01003889 setLockscreenPublicMode(
3890 mStatusBarKeyguardViewManager.isShowing() && mStatusBarKeyguardViewManager
3891 .isSecure(mCurrentUserId));
Jorim Jaggi15682502014-04-23 12:01:36 +02003892 }
3893
Rakesh Iyer2790a372016-01-22 15:33:39 -08003894 protected void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02003895 if (mState == StatusBarState.KEYGUARD) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003896 mKeyguardIndicationController.setVisible(true);
Selim Cinek4c6969a2014-05-26 19:22:17 +02003897 mNotificationPanel.resetViews();
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003898 if (mKeyguardUserSwitcher != null) {
3899 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
3900 }
Selim Cinek80c2abe2015-06-17 15:37:30 -07003901 mStatusBarView.removePendingHideExpandedRunnables();
Jorim Jaggi15682502014-04-23 12:01:36 +02003902 } else {
Adrian Roos12c1ef52014-06-04 13:54:08 +02003903 mKeyguardIndicationController.setVisible(false);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07003904 if (mKeyguardUserSwitcher != null) {
3905 mKeyguardUserSwitcher.setKeyguard(false,
3906 goingToFullShade ||
3907 mState == StatusBarState.SHADE_LOCKED ||
3908 fromShadeLocked);
3909 }
Jorim Jaggi15682502014-04-23 12:01:36 +02003910 }
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003911 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003912 mScrimController.setKeyguardShowing(true);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003913 mIconPolicy.setKeyguardShowing(true);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003914 } else {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02003915 mScrimController.setKeyguardShowing(false);
Kenny Guy3094d4a2015-04-01 19:14:10 +01003916 mIconPolicy.setKeyguardShowing(false);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02003917 }
Rakesh Iyer2790a372016-01-22 15:33:39 -08003918
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02003919 mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
John Spurlockbf370992014-06-17 13:58:31 -04003920 updateDozingState();
Jorim Jaggi15682502014-04-23 12:01:36 +02003921 updatePublicMode();
Selim Cinekd35c2792016-01-21 13:20:57 -08003922 updateStackScrollerState(goingToFullShade, fromShadeLocked);
Christoph Studer37fe6932014-05-26 13:10:30 +02003923 updateNotifications();
Jorim Jaggia6310292014-04-16 14:11:52 +02003924 checkBarModes();
Adrian Roos52738322016-01-29 08:49:21 -08003925 updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
John Spurlock657c62c2014-07-22 12:18:09 -04003926 mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
3927 mStatusBarKeyguardViewManager.isSecure());
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003928 }
3929
John Spurlockbf370992014-06-17 13:58:31 -04003930 private void updateDozingState() {
Jorim Jaggi4e857f42014-11-17 19:14:04 +01003931 boolean animate = !mDozing && mDozeScrimController.isPulsing();
3932 mNotificationPanel.setDozing(mDozing, animate);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003933 mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
Jorim Jaggi048af1f2014-11-11 22:51:10 +01003934 mScrimController.setDozing(mDozing);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07003935
3936 // Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock
3937 // for pulsing so the Keyguard fade-out animation scrim can take over.
3938 mDozeScrimController.setDozing(mDozing &&
3939 mFingerprintUnlockController.getMode()
3940 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate);
John Spurlockbf370992014-06-17 13:58:31 -04003941 }
3942
Selim Cinekd35c2792016-01-21 13:20:57 -08003943 public void updateStackScrollerState(boolean goingToFullShade, boolean fromShadeLocked) {
John Spurlock4b3bda22014-05-22 14:32:20 -04003944 if (mStackScroller == null) return;
Selim Cinek1408eb52014-06-02 14:45:38 +02003945 boolean onKeyguard = mState == StatusBarState.KEYGUARD;
Jorim Jaggiae441282014-08-01 02:45:18 +02003946 mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
Selim Cinekd35c2792016-01-21 13:20:57 -08003947 mStackScroller.setDimmed(onKeyguard, fromShadeLocked /* animate */);
Selim Cinek1408eb52014-06-02 14:45:38 +02003948 mStackScroller.setExpandingEnabled(!onKeyguard);
Selim Cineka32ab602014-06-11 15:06:01 +02003949 ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
3950 mStackScroller.setActivatedChild(null);
3951 if (activatedChild != null) {
3952 activatedChild.makeInactive(false /* animate */);
3953 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02003954 }
3955
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003956 public void userActivity() {
Jorim Jaggib690f0d2014-07-03 23:25:44 +02003957 if (mState == StatusBarState.KEYGUARD) {
3958 mKeyguardViewMediatorCallback.userActivity();
3959 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02003960 }
3961
Jorim Jaggidf993512014-05-13 23:06:35 +02003962 public boolean interceptMediaKey(KeyEvent event) {
3963 return mState == StatusBarState.KEYGUARD
3964 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
3965 }
3966
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003967 public boolean onMenuPressed() {
Selim Cinek28540192016-02-19 17:25:08 -08003968 if (mDeviceInteractive && mState != StatusBarState.SHADE
3969 && mStatusBarKeyguardViewManager.shouldDismissOnMenuPressed()) {
3970 animateCollapsePanels(
3971 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
3972 return true;
3973 }
3974 return false;
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02003975 }
3976
Selim Cinek372d1bd2015-08-14 13:19:37 -07003977 public void endAffordanceLaunch() {
3978 releaseGestureWakeLock();
3979 mNotificationPanel.onAffordanceLaunchEnded();
3980 }
3981
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003982 public boolean onBackPressed() {
Adrian Roos0002a452014-07-03 13:46:07 +02003983 if (mStatusBarKeyguardViewManager.onBackPressed()) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003984 return true;
3985 }
Adrian Roos0002a452014-07-03 13:46:07 +02003986 if (mNotificationPanel.isQsExpanded()) {
John Spurlockf7ae4422014-08-01 12:45:18 -04003987 if (mNotificationPanel.isQsDetailShowing()) {
3988 mNotificationPanel.closeQsDetail();
3989 } else {
3990 mNotificationPanel.animateCloseQs();
3991 }
Adrian Roos0002a452014-07-03 13:46:07 +02003992 return true;
3993 }
3994 if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
3995 animateCollapsePanels();
3996 return true;
3997 }
3998 return false;
Jorim Jaggie5c7a892014-04-10 20:37:32 +02003999 }
4000
Jorim Jaggi34250762014-07-03 23:51:19 +02004001 public boolean onSpacePressed() {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004002 if (mDeviceInteractive && mState != StatusBarState.SHADE) {
Jorim Jaggi4eedc1d2014-10-27 13:45:56 +01004003 animateCollapsePanels(
4004 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
Jorim Jaggi34250762014-07-03 23:51:19 +02004005 return true;
4006 }
4007 return false;
4008 }
4009
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004010 private void showBouncer() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004011 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekbaa23272014-07-08 18:01:07 +02004012 mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004013 mStatusBarKeyguardViewManager.dismiss();
4014 }
4015 }
4016
4017 private void instantExpandNotificationsPanel() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02004018
Jorim Jaggi0a27be82014-06-11 03:22:39 +02004019 // Make our window larger and the panel expanded.
Jorim Jaggifa505a72014-04-28 20:04:11 +02004020 makeExpandedVisible(true);
Oren Blasberg8d3fea12015-07-10 14:21:44 -07004021 mNotificationPanel.expand(false /* animate */);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004022 }
Adrian Roos5a46cd32014-04-03 16:51:58 +02004023
Jorim Jaggia005f1b2014-04-16 19:06:10 +02004024 private void instantCollapseNotificationPanel() {
Selim Cinek6bb4a9b2014-10-09 17:48:05 -07004025 mNotificationPanel.instantCollapse();
Jorim Jaggia005f1b2014-04-16 19:06:10 +02004026 }
4027
Jorim Jaggid4a57442014-04-10 02:45:55 +02004028 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02004029 public void onActivated(ActivatableNotificationView view) {
Christoph Studerb0183992014-12-22 21:02:26 +01004030 EventLogTags.writeSysuiLockscreenGesture(
4031 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
4032 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
Adrian Roos12c1ef52014-06-04 13:54:08 +02004033 mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
Selim Cineka32ab602014-06-11 15:06:01 +02004034 ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
4035 if (previousView != null) {
4036 previousView.makeInactive(true /* animate */);
4037 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004038 mStackScroller.setActivatedChild(view);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02004039 }
4040
Jorim Jaggiecbab362014-04-23 16:13:15 +02004041 /**
4042 * @param state The {@link StatusBarState} to set.
4043 */
4044 public void setBarState(int state) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01004045 // If we're visible and switched to SHADE_LOCKED (the user dragged
4046 // down on the lockscreen), clear notification LED, vibration,
4047 // ringing.
4048 // Other transitions are covered in handleVisibleToUserChanged().
Selim Cinek6577cae2015-08-31 16:15:49 -07004049 if (state != mState && mVisible && (state == StatusBarState.SHADE_LOCKED
4050 || (state == StatusBarState.SHADE && isGoingToNotificationShade()))) {
4051 clearNotificationEffects();
Christoph Studer1f32c652014-11-26 15:32:20 +01004052 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004053 mState = state;
Selim Cinek9c4c4142015-12-04 16:44:56 -08004054 mGroupManager.setStatusBarState(state);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004055 mFalsingManager.setStatusBarState(state);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004056 mStatusBarWindowManager.setStatusBarState(state);
Jorim Jaggi83969702015-06-05 14:59:24 -07004057 updateDozing();
Jorim Jaggiecbab362014-04-23 16:13:15 +02004058 }
4059
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02004060 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02004061 public void onActivationReset(ActivatableNotificationView view) {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004062 if (view == mStackScroller.getActivatedChild()) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004063 mKeyguardIndicationController.hideTransientIndication();
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004064 mStackScroller.setActivatedChild(null);
4065 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004066 }
4067
4068 public void onTrackingStarted() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02004069 runPostCollapseRunnables();
Jorim Jaggi90129582014-06-02 14:44:49 +02004070 }
4071
Selim Cinekdbbcfbe2014-10-24 17:52:35 +02004072 public void onClosingFinished() {
4073 runPostCollapseRunnables();
4074 }
4075
Jorim Jaggi90129582014-06-02 14:44:49 +02004076 public void onUnlockHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004077 mFalsingManager.onUnlockHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004078 mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
Jorim Jaggi90129582014-06-02 14:44:49 +02004079 }
4080
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004081 public void onHintFinished() {
Jorim Jaggi93a2bb22014-06-02 19:57:28 +02004082 // Delay the reset a bit so the user can read the text.
Adrian Roos12c1ef52014-06-04 13:54:08 +02004083 mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004084 }
4085
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004086 public void onCameraHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004087 mFalsingManager.onCameraHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004088 mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004089 }
4090
Selim Cineke70d6532015-04-24 16:46:13 -07004091 public void onVoiceAssistHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004092 mFalsingManager.onLeftAffordanceHintStarted();
Selim Cineke70d6532015-04-24 16:46:13 -07004093 mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
4094 }
4095
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004096 public void onPhoneHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004097 mFalsingManager.onLeftAffordanceHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004098 mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004099 }
4100
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004101 public void onTrackingStopped(boolean expand) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004102 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cineke8bae622015-07-15 13:24:06 -07004103 if (!expand && !mUnlockMethodCache.canSkipBouncer()) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004104 showBouncer();
4105 }
4106 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004107 }
4108
4109 @Override
Selim Cinek5f71bee2015-11-18 10:25:23 -08004110 protected int getMaxKeyguardNotifications(boolean recompute) {
4111 if (recompute) {
4112 mMaxKeyguardNotifications = Math.max(1,
4113 mNotificationPanel.computeMaxKeyguardNotifications(
4114 mMaxAllowedKeyguardNotifications));
4115 return mMaxKeyguardNotifications;
4116 }
4117 return mMaxKeyguardNotifications;
4118 }
4119
4120 public int getMaxKeyguardNotifications() {
4121 return getMaxKeyguardNotifications(false /* recompute */);
Jorim Jaggid4a57442014-04-10 02:45:55 +02004122 }
4123
Jorim Jaggia6310292014-04-16 14:11:52 +02004124 public NavigationBarView getNavigationBarView() {
4125 return mNavigationBarView;
4126 }
4127
Jorim Jaggiecbab362014-04-23 16:13:15 +02004128 // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
4129
4130 @Override
Christoph Studerb0183992014-12-22 21:02:26 +01004131 public boolean onDraggedDown(View startingChild, int dragLengthY) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02004132 if (hasActiveNotifications()) {
Christoph Studerb0183992014-12-22 21:02:26 +01004133 EventLogTags.writeSysuiLockscreenGesture(
4134 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
4135 (int) (dragLengthY / mDisplayMetrics.density),
4136 0 /* velocityDp - N/A */);
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004137
4138 // We have notifications, go to locked shade.
4139 goToLockedShade(startingChild);
4140 return true;
4141 } else {
4142
4143 // No notifications - abort gesture.
4144 return false;
4145 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004146 }
4147
4148 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004149 public void onDragDownReset() {
4150 mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
Selim Cinek177fd432015-11-18 11:53:47 -08004151 mStackScroller.resetScrollPosition();
Jorim Jaggiecbab362014-04-23 16:13:15 +02004152 }
4153
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004154 @Override
Selim Cinek177fd432015-11-18 11:53:47 -08004155 public void onCrossedThreshold(boolean above) {
4156 mStackScroller.setDimmed(!above /* dimmed */, true /* animate */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004157 }
4158
Selim Cinek1408eb52014-06-02 14:45:38 +02004159 @Override
4160 public void onTouchSlopExceeded() {
4161 mStackScroller.removeLongPressCallback();
4162 }
4163
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004164 @Override
4165 public void setEmptyDragAmount(float amount) {
4166 mNotificationPanel.setEmptyDragAmount(amount);
4167 }
4168
Jorim Jaggiecbab362014-04-23 16:13:15 +02004169 /**
4170 * If secure with redaction: Show bouncer, go to unlocked shade.
4171 *
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004172 * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
Jorim Jaggiecbab362014-04-23 16:13:15 +02004173 *
4174 * @param expandView The view to expand after going to the shade.
4175 */
4176 public void goToLockedShade(View expandView) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004177 ExpandableNotificationRow row = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02004178 if (expandView instanceof ExpandableNotificationRow) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004179 row = (ExpandableNotificationRow) expandView;
Selim Cinekcb24ab82016-02-25 12:49:08 -08004180 row.setUserExpanded(true /* userExpanded */, true /* allowChildExpansion */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004181 }
Adrian Roosaee70462014-09-03 16:27:39 +02004182 boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004183 || !mShowLockscreenNotifications || mFalsingManager.shouldEnforceBouncer();
Adrian Roosaee70462014-09-03 16:27:39 +02004184 if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004185 mLeaveOpenOnKeyguardHide = true;
4186 showBouncer();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004187 mDraggedDownRow = row;
Adrian Roos3aec6382016-02-05 14:19:01 -08004188 mPendingRemoteInputView = null;
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004189 } else {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004190 mNotificationPanel.animateToFullShade(0 /* delay */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004191 setBarState(StatusBarState.SHADE_LOCKED);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004192 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004193 }
4194 }
4195
Selim Cinek570981d2015-12-01 11:37:01 -08004196 @Override
Adrian Roos3aec6382016-02-05 14:19:01 -08004197 protected void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
4198 mLeaveOpenOnKeyguardHide = true;
4199 showBouncer();
4200 mPendingRemoteInputView = clicked;
4201 }
4202
4203 @Override
Selim Cinek31aada42015-12-18 17:51:15 -08004204 public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
4205 mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
Selim Cinek570981d2015-12-01 11:37:01 -08004206 if (mState == StatusBarState.KEYGUARD && nowExpanded) {
Selim Cinek31aada42015-12-18 17:51:15 -08004207 goToLockedShade(clickedEntry.row);
Selim Cinek570981d2015-12-01 11:37:01 -08004208 }
4209 }
4210
Adrian Roos5a46cd32014-04-03 16:51:58 +02004211 /**
Jorim Jaggi6539a832014-06-03 23:33:09 +02004212 * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
4213 */
4214 public void goToKeyguard() {
4215 if (mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekd9acca52014-09-01 22:33:25 +02004216 mStackScroller.onGoToKeyguard();
Jorim Jaggi6539a832014-06-03 23:33:09 +02004217 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004218 updateKeyguardState(false /* goingToFullShade */, true /* fromShadeLocked*/);
Jorim Jaggi6539a832014-06-03 23:33:09 +02004219 }
4220 }
4221
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004222 public long getKeyguardFadingAwayDelay() {
4223 return mKeyguardFadingAwayDelay;
4224 }
4225
4226 public long getKeyguardFadingAwayDuration() {
4227 return mKeyguardFadingAwayDuration;
4228 }
4229
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004230 @Override
4231 public void setBouncerShowing(boolean bouncerShowing) {
4232 super.setBouncerShowing(bouncerShowing);
Adrian Roosd0b2f7d2015-04-29 13:36:12 -07004233 mStatusBarView.setBouncerShowing(bouncerShowing);
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01004234 disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004235 }
4236
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004237 public void onStartedGoingToSleep() {
4238 mStartedGoingToSleep = true;
4239 }
4240
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004241 public void onFinishedGoingToSleep() {
Selim Cinek372d1bd2015-08-14 13:19:37 -07004242 mNotificationPanel.onAffordanceLaunchEnded();
4243 releaseGestureWakeLock();
4244 mLaunchCameraOnScreenTurningOn = false;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004245 mStartedGoingToSleep = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004246 mDeviceInteractive = false;
4247 mWakeUpComingFromTouch = false;
4248 mWakeUpTouchLocation = null;
Jorim Jaggi75c95042014-05-16 19:09:59 +02004249 mStackScroller.setAnimationsEnabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004250 updateVisibleToUser();
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004251 if (mLaunchCameraOnFinishedGoingToSleep) {
4252 mLaunchCameraOnFinishedGoingToSleep = false;
4253
4254 // This gets executed before we will show Keyguard, so post it in order that the state
4255 // is correct.
4256 mHandler.post(new Runnable() {
4257 @Override
4258 public void run() {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004259 onCameraLaunchGestureDetected(mLastCameraLaunchSource);
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004260 }
4261 });
4262 }
Jorim Jaggi75c95042014-05-16 19:09:59 +02004263 }
4264
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004265 public void onStartedWakingUp() {
4266 mDeviceInteractive = true;
Jorim Jaggi75c95042014-05-16 19:09:59 +02004267 mStackScroller.setAnimationsEnabled(true);
Jorim Jaggid41083a2014-09-12 02:54:40 +02004268 mNotificationPanel.setTouchDisabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004269 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02004270 }
John Spurlockd08f91f2014-05-23 11:00:34 -04004271
Jorim Jaggi93739112015-08-13 15:53:14 -07004272 public void onScreenTurningOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004273 mScreenTurningOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004274 mFalsingManager.onScreenTurningOn();
Jorim Jaggi93739112015-08-13 15:53:14 -07004275 mNotificationPanel.onScreenTurningOn();
Selim Cinek372d1bd2015-08-14 13:19:37 -07004276 if (mLaunchCameraOnScreenTurningOn) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004277 mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004278 mLaunchCameraOnScreenTurningOn = false;
4279 }
Jorim Jaggi93739112015-08-13 15:53:14 -07004280 }
4281
Selim Cinek69ff8af2015-08-25 19:03:48 -07004282 private void vibrateForCameraGesture() {
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004283 // Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
Jorim Jaggi75b25972015-10-21 14:51:10 +02004284 mVibrator.vibrate(new long[]{0, 750L}, -1 /* repeat */);
Selim Cinek69ff8af2015-08-25 19:03:48 -07004285 }
4286
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004287 public void onScreenTurnedOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004288 mScreenTurningOn = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004289 mDozeScrimController.onScreenTurnedOn();
4290 }
4291
Jason Monk815e0572014-08-12 17:26:36 -04004292 /**
Jorim Jaggi75b25972015-10-21 14:51:10 +02004293 * Handles long press for back button. This exits screen pinning.
Jason Monk815e0572014-08-12 17:26:36 -04004294 */
Jorim Jaggi75b25972015-10-21 14:51:10 +02004295 private boolean handleLongPressBack() {
Jason Monk62515be2014-05-21 16:06:19 -04004296 try {
4297 IActivityManager activityManager = ActivityManagerNative.getDefault();
Jorim Jaggi75b25972015-10-21 14:51:10 +02004298 if (activityManager.isInLockTaskMode()) {
4299 activityManager.stopLockTaskModeOnCurrent();
4300
4301 // When exiting refresh disabled flags.
4302 mNavigationBarView.setDisabledFlags(mDisabled1, true);
4303 return true;
Jason Monk62515be2014-05-21 16:06:19 -04004304 }
4305 } catch (RemoteException e) {
Jason Monk815e0572014-08-12 17:26:36 -04004306 Log.d(TAG, "Unable to reach activity manager", e);
Jason Monk62515be2014-05-21 16:06:19 -04004307 }
Jorim Jaggi75b25972015-10-21 14:51:10 +02004308 return false;
Jason Monk62515be2014-05-21 16:06:19 -04004309 }
4310
Winson3e7e3aa2015-09-22 14:22:58 -07004311 public void updateRecentsVisibility(boolean visible) {
Winson Chung9214eff2014-06-12 13:59:25 -07004312 // Update the recents visibility flag
4313 if (visible) {
4314 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
4315 } else {
4316 mSystemUiVisibility &= ~View.RECENT_APPS_VISIBLE;
4317 }
4318 notifyUiVisibilityChanged(mSystemUiVisibility);
4319 }
John Spurlockbf370992014-06-17 13:58:31 -04004320
Jason Monk5565cb42014-09-12 10:59:21 -04004321 @Override
4322 public void showScreenPinningRequest() {
Jason Monk18f99d92014-09-11 13:36:42 -04004323 if (mKeyguardMonitor.isShowing()) {
4324 // Don't allow apps to trigger this from keyguard.
4325 return;
4326 }
4327 // Show screen pinning request, since this comes from an app, show 'no thanks', button.
4328 showScreenPinningRequest(true);
4329 }
4330
4331 public void showScreenPinningRequest(boolean allowCancel) {
4332 mScreenPinningRequest.showPrompt(allowCancel);
Jason Monk5565cb42014-09-12 10:59:21 -04004333 }
4334
Christoph Studerc8db24b2014-07-25 17:50:30 +02004335 public boolean hasActiveNotifications() {
4336 return !mNotificationData.getActiveNotifications().isEmpty();
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004337 }
4338
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004339 public void wakeUpIfDozing(long time, MotionEvent event) {
Jorim Jaggi048af1f2014-11-11 22:51:10 +01004340 if (mDozing && mDozeScrimController.isPulsing()) {
John Spurlock8b12f222014-09-09 11:54:11 -04004341 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
Dianne Hackborn280a64e2015-07-13 14:48:08 -07004342 pm.wakeUp(time, "com.android.systemui:NODOZE");
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004343 mWakeUpComingFromTouch = true;
4344 mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004345 mNotificationPanel.setTouchDisabled(false);
Jorim Jaggi0d210f62015-07-10 14:24:44 -07004346 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004347 mFalsingManager.onScreenOnFromTouch();
John Spurlock8b12f222014-09-09 11:54:11 -04004348 }
4349 }
4350
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004351 @Override
4352 public void appTransitionPending() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004353
4354 // Use own timings when Keyguard is going away, see keyguardGoingAway and
4355 // setKeyguardFadingAway
4356 if (!mKeyguardFadingAway) {
4357 mIconController.appTransitionPending();
4358 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004359 }
4360
4361 @Override
4362 public void appTransitionCancelled() {
4363 mIconController.appTransitionCancelled();
Jorim Jaggi2adba072016-03-03 13:43:39 +01004364 EventBus.getDefault().send(new AppTransitionFinishedEvent());
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004365 }
4366
4367 @Override
4368 public void appTransitionStarting(long startTime, long duration) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004369
4370 // Use own timings when Keyguard is going away, see keyguardGoingAway and
Adrian Roos46df1ca2015-09-11 12:38:43 -07004371 // setKeyguardFadingAway.
4372 if (!mKeyguardGoingAway) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004373 mIconController.appTransitionStarting(startTime, duration);
4374 }
Kenny Guy3094d4a2015-04-01 19:14:10 +01004375 if (mIconPolicy != null) {
4376 mIconPolicy.appTransitionStarting(startTime, duration);
4377 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004378 }
4379
Selim Cinek372d1bd2015-08-14 13:19:37 -07004380 @Override
Jorim Jaggi2adba072016-03-03 13:43:39 +01004381 public void appTransitionFinished() {
4382 EventBus.getDefault().send(new AppTransitionFinishedEvent());
4383 }
4384
4385 @Override
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004386 public void onCameraLaunchGestureDetected(int source) {
4387 mLastCameraLaunchSource = source;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004388 if (mStartedGoingToSleep) {
4389 mLaunchCameraOnFinishedGoingToSleep = true;
4390 return;
4391 }
Zhentao Sun04f97402015-08-26 17:37:30 -07004392 if (!mNotificationPanel.canCameraGestureBeLaunched(
4393 mStatusBarKeyguardViewManager.isShowing() && mExpandedVisible)) {
Selim Cinek372d1bd2015-08-14 13:19:37 -07004394 return;
4395 }
4396 if (!mDeviceInteractive) {
4397 PowerManager pm = mContext.getSystemService(PowerManager.class);
4398 pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE");
4399 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
4400 }
Selim Cinek69ff8af2015-08-25 19:03:48 -07004401 vibrateForCameraGesture();
Selim Cinek372d1bd2015-08-14 13:19:37 -07004402 if (!mStatusBarKeyguardViewManager.isShowing()) {
4403 startActivity(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT,
4404 true /* dismissShade */);
4405 } else {
4406 if (!mDeviceInteractive) {
4407 // Avoid flickering of the scrim when we instant launch the camera and the bouncer
4408 // comes on.
4409 mScrimController.dontAnimateBouncerChangesUntilNextFrame();
4410 mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
4411 }
Selim Cinek1b6f8192015-09-03 16:01:53 -07004412 if (mScreenTurningOn || mStatusBarKeyguardViewManager.isScreenTurnedOn()) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004413 mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004414 } else {
4415 // We need to defer the camera launch until the screen comes on, since otherwise
4416 // we will dismiss us too early since we are waiting on an activity to be drawn and
4417 // incorrectly get notified because of the screen on event (which resumes and pauses
4418 // some activities)
4419 mLaunchCameraOnScreenTurningOn = true;
4420 }
4421 }
4422 }
4423
Jaewan Kimc552b042016-01-18 16:08:45 +09004424 @Override
4425 public void requestTvPictureInPicture() {
4426 // no-op.
4427 }
4428
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004429 public void notifyFpAuthModeChanged() {
4430 updateDozing();
4431 }
4432
Jorim Jaggi83969702015-06-05 14:59:24 -07004433 private void updateDozing() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004434 // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
4435 mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
4436 || mFingerprintUnlockController.getMode()
4437 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
Jorim Jaggi83969702015-06-05 14:59:24 -07004438 updateDozingState();
4439 }
4440
John Spurlockbf370992014-06-17 13:58:31 -04004441 private final class ShadeUpdates {
4442 private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
4443 private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
4444
4445 public void check() {
4446 mNewVisibleNotifications.clear();
Christoph Studerc8db24b2014-07-25 17:50:30 +02004447 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
4448 for (int i = 0; i < activeNotifications.size(); i++) {
4449 final Entry entry = activeNotifications.get(i);
John Spurlockbf370992014-06-17 13:58:31 -04004450 final boolean visible = entry.row != null
4451 && entry.row.getVisibility() == View.VISIBLE;
4452 if (visible) {
4453 mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
4454 }
4455 }
4456 final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
4457 mVisibleNotifications.clear();
Dianne Hackborn497175b2014-07-01 12:56:08 -07004458 mVisibleNotifications.addAll(mNewVisibleNotifications);
John Spurlockbf370992014-06-17 13:58:31 -04004459
4460 // We have new notifications
4461 if (updates && mDozeServiceHost != null) {
4462 mDozeServiceHost.fireNewNotifications();
4463 }
4464 }
4465 }
4466
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004467 private final class DozeServiceHost extends KeyguardUpdateMonitorCallback implements DozeHost {
John Spurlockbf370992014-06-17 13:58:31 -04004468 // Amount of time to allow to update the time shown on the screen before releasing
4469 // the wakelock. This timeout is design to compensate for the fact that we don't
4470 // currently have a way to know when time display contents have actually been
4471 // refreshed once we've finished rendering a new frame.
4472 private static final long PROCESSING_TIME = 500;
4473
4474 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
4475 private final H mHandler = new H();
4476
Christoph Studer1f32c652014-11-26 15:32:20 +01004477 // Keeps the last reported state by fireNotificationLight.
4478 private boolean mNotificationLightOn;
4479
John Spurlockc6eed842014-08-25 12:19:41 -04004480 @Override
4481 public String toString() {
Jeff Brown4d69e222014-09-18 15:27:50 -07004482 return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
John Spurlock8b12f222014-09-09 11:54:11 -04004483 }
4484
John Spurlockd96179e2014-08-21 16:43:45 -04004485 public void firePowerSaveChanged(boolean active) {
4486 for (Callback callback : mCallbacks) {
4487 callback.onPowerSaveChanged(active);
4488 }
4489 }
4490
John Spurlockcad57682014-07-26 17:09:56 -04004491 public void fireBuzzBeepBlinked() {
4492 for (Callback callback : mCallbacks) {
4493 callback.onBuzzBeepBlinked();
4494 }
4495 }
4496
John Spurlockcb566aa2014-08-03 22:58:28 -04004497 public void fireNotificationLight(boolean on) {
Christoph Studer1f32c652014-11-26 15:32:20 +01004498 mNotificationLightOn = on;
John Spurlockcb566aa2014-08-03 22:58:28 -04004499 for (Callback callback : mCallbacks) {
4500 callback.onNotificationLight(on);
4501 }
4502 }
4503
John Spurlockbf370992014-06-17 13:58:31 -04004504 public void fireNewNotifications() {
4505 for (Callback callback : mCallbacks) {
4506 callback.onNewNotifications();
4507 }
4508 }
4509
4510 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004511 public void addCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04004512 mCallbacks.add(callback);
4513 }
4514
4515 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004516 public void removeCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04004517 mCallbacks.remove(callback);
4518 }
4519
4520 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004521 public void startDozing(@NonNull Runnable ready) {
4522 mHandler.obtainMessage(H.MSG_START_DOZING, ready).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004523 }
4524
4525 @Override
John Spurlockeab28e62014-11-29 11:33:49 -05004526 public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
4527 mHandler.obtainMessage(H.MSG_PULSE_WHILE_DOZING, reason, 0, callback).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004528 }
4529
4530 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07004531 public void stopDozing() {
4532 mHandler.obtainMessage(H.MSG_STOP_DOZING).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04004533 }
4534
John Spurlockd96179e2014-08-21 16:43:45 -04004535 @Override
4536 public boolean isPowerSaveActive() {
4537 return mBatteryController != null && mBatteryController.isPowerSave();
4538 }
4539
Christoph Studer1f32c652014-11-26 15:32:20 +01004540 @Override
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004541 public boolean isPulsingBlocked() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004542 return mFingerprintUnlockController.getMode()
4543 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
Jorim Jaggi007f0e82015-08-14 13:56:01 -07004544 }
4545
4546 @Override
Christoph Studer1f32c652014-11-26 15:32:20 +01004547 public boolean isNotificationLightOn() {
4548 return mNotificationLightOn;
4549 }
4550
Jeff Brown4d69e222014-09-18 15:27:50 -07004551 private void handleStartDozing(@NonNull Runnable ready) {
Jorim Jaggi83969702015-06-05 14:59:24 -07004552 if (!mDozingRequested) {
4553 mDozingRequested = true;
John Spurlock813552c2014-09-19 08:30:21 -04004554 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07004555 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04004556 }
Jeff Brown4d69e222014-09-18 15:27:50 -07004557 ready.run();
John Spurlockbf370992014-06-17 13:58:31 -04004558 }
4559
John Spurlockeab28e62014-11-29 11:33:49 -05004560 private void handlePulseWhileDozing(@NonNull PulseCallback callback, int reason) {
Selim Cinekcd5b22f2016-03-08 16:15:41 -08004561 mDozeScrimController.pulse(new PulseCallback() {
4562
4563 @Override
4564 public void onPulseStarted() {
4565 callback.onPulseStarted();
4566 mStackScroller.setPulsing(true);
4567 }
4568
4569 @Override
4570 public void onPulseFinished() {
4571 callback.onPulseFinished();
4572 mStackScroller.setPulsing(false);
4573 }
4574 }, reason);
John Spurlockbf370992014-06-17 13:58:31 -04004575 }
4576
Jeff Brown4d69e222014-09-18 15:27:50 -07004577 private void handleStopDozing() {
Jorim Jaggi83969702015-06-05 14:59:24 -07004578 if (mDozingRequested) {
4579 mDozingRequested = false;
John Spurlock813552c2014-09-19 08:30:21 -04004580 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07004581 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04004582 }
4583 }
4584
4585 private final class H extends Handler {
Jeff Brown4d69e222014-09-18 15:27:50 -07004586 private static final int MSG_START_DOZING = 1;
4587 private static final int MSG_PULSE_WHILE_DOZING = 2;
4588 private static final int MSG_STOP_DOZING = 3;
John Spurlockbf370992014-06-17 13:58:31 -04004589
4590 @Override
4591 public void handleMessage(Message msg) {
Jeff Brown4d69e222014-09-18 15:27:50 -07004592 switch (msg.what) {
4593 case MSG_START_DOZING:
4594 handleStartDozing((Runnable) msg.obj);
4595 break;
4596 case MSG_PULSE_WHILE_DOZING:
John Spurlockeab28e62014-11-29 11:33:49 -05004597 handlePulseWhileDozing((PulseCallback) msg.obj, msg.arg1);
Jeff Brown4d69e222014-09-18 15:27:50 -07004598 break;
4599 case MSG_STOP_DOZING:
4600 handleStopDozing();
4601 break;
John Spurlockbf370992014-06-17 13:58:31 -04004602 }
4603 }
4604 }
4605 }
Romain Guy648342f2012-05-25 10:44:45 -07004606}