blob: 89a5bc84ece6f7d17b31fa187ec7df43c0606264 [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
Selim Cinek64be7722016-07-22 13:28:16 -070020import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
21import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
22import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
23import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
24import static android.app.StatusBarManager.windowStateToString;
25import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
26import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
27import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
28import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
29import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
30import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
31import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
32
Daniel Sandlerd7e96862012-04-26 01:10:29 -040033import android.animation.Animator;
34import android.animation.AnimatorListenerAdapter;
Jeff Brown4d69e222014-09-18 15:27:50 -070035import android.annotation.NonNull;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070036import android.app.ActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040037import android.app.ActivityManagerNative;
Robert Carrfd10cd12016-06-29 16:41:50 -070038import android.app.ActivityOptions;
Jason Monk62515be2014-05-21 16:06:19 -040039import android.app.IActivityManager;
Joe Onorato808182d2010-07-09 18:52:06 -040040import android.app.Notification;
41import android.app.PendingIntent;
Joe Onorato808182d2010-07-09 18:52:06 -040042import android.app.StatusBarManager;
43import android.content.BroadcastReceiver;
Jorim Jaggi786afcb2014-09-25 02:41:29 +020044import android.content.ComponentCallbacks2;
Jason Monk7e53f202016-01-28 10:40:20 -050045import android.content.ComponentName;
Joe Onorato808182d2010-07-09 18:52:06 -040046import android.content.Context;
47import android.content.Intent;
48import android.content.IntentFilter;
Ricky Waicd35def2016-05-03 11:07:07 +010049import android.content.IntentSender;
Adrian Roos21d2a252015-06-01 13:59:59 -070050import android.content.pm.IPackageManager;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -070051import android.content.pm.PackageManager;
Tony Mak92c989d2016-04-19 14:02:44 +010052import android.content.pm.UserInfo;
Daniel Sandler777dcde2013-09-30 10:21:45 -040053import android.content.res.Configuration;
Michael Jurka7f2668c2012-03-27 07:49:52 -070054import android.content.res.Resources;
John Spurlock919adac2012-10-02 16:41:12 -040055import android.database.ContentObserver;
Dan Sandler16128f42014-05-21 12:48:22 -040056import android.graphics.Bitmap;
Romain Guy648342f2012-05-25 10:44:45 -070057import android.graphics.Canvas;
58import android.graphics.ColorFilter;
Joe Onorato808182d2010-07-09 18:52:06 -040059import android.graphics.PixelFormat;
Daniel Sandlere680f542012-09-28 12:22:27 -040060import android.graphics.Point;
Jorim Jaggi2a5e4522014-11-24 21:45:20 +010061import android.graphics.PointF;
Romain Guy648342f2012-05-25 10:44:45 -070062import android.graphics.PorterDuff;
Selim Cineka0fad3b2014-09-19 17:20:05 +020063import android.graphics.PorterDuffXfermode;
Joe Onorato808182d2010-07-09 18:52:06 -040064import android.graphics.Rect;
Adrian Roos3b777cb2016-04-14 12:04:28 -070065import android.graphics.drawable.BitmapDrawable;
Dan Sandler16128f42014-05-21 12:48:22 -040066import android.graphics.drawable.ColorDrawable;
Romain Guy648342f2012-05-25 10:44:45 -070067import android.graphics.drawable.Drawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070068import android.inputmethodservice.InputMethodService;
John Spurlock7b414672014-07-18 13:02:39 -040069import android.media.AudioAttributes;
Dan Sandler16128f42014-05-21 12:48:22 -040070import android.media.MediaMetadata;
71import android.media.session.MediaController;
72import android.media.session.MediaSession;
73import android.media.session.MediaSessionManager;
74import android.media.session.PlaybackState;
Adrian Roos7bb38a92016-07-21 11:44:01 -070075import android.net.Uri;
Selim Cinekbaa23272014-07-08 18:01:07 +020076import android.os.AsyncTask;
John Spurlock3c875662013-08-31 15:07:25 -040077import android.os.Bundle;
John Spurlock919adac2012-10-02 16:41:12 -040078import android.os.Handler;
Jason Monk4ae97d32014-12-17 10:14:33 -050079import android.os.HandlerThread;
Joe Onorato808182d2010-07-09 18:52:06 -040080import android.os.IBinder;
Joe Onorato808182d2010-07-09 18:52:06 -040081import android.os.Message;
John Spurlock56d007b2013-10-28 18:40:56 -040082import android.os.PowerManager;
Jason Monk4ae97d32014-12-17 10:14:33 -050083import android.os.Process;
Michael Jurka7f2668c2012-03-27 07:49:52 -070084import android.os.RemoteException;
Adrian Roos21d2a252015-06-01 13:59:59 -070085import android.os.ServiceManager;
Joe Onorato808182d2010-07-09 18:52:06 -040086import android.os.SystemClock;
Nick Desaulniers1d396752016-07-25 15:05:33 -070087import android.os.Trace;
Adrian Roos7bb38a92016-07-21 11:44:01 -070088import android.os.SystemProperties;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070089import android.os.UserHandle;
Adrian Roos2b154a92014-11-17 15:18:39 +010090import android.os.UserManager;
Selim Cinek69ff8af2015-08-25 19:03:48 -070091import android.os.Vibrator;
Daniel Sandlerd3090562011-08-09 00:28:44 -040092import android.provider.Settings;
Chris Wren3ad4e3a2014-09-02 17:23:51 -040093import android.service.notification.NotificationListenerService;
Christoph Studerd0694b62014-06-04 16:36:01 +020094import android.service.notification.NotificationListenerService.RankingMap;
John Spurlockde84f0e2013-06-12 12:41:00 -040095import android.service.notification.StatusBarNotification;
Selim Cinek64be7722016-07-22 13:28:16 -070096import android.telecom.TelecomManager;
Christoph Studer92b389d2014-04-01 18:44:40 +020097import android.util.ArraySet;
Daniel Sandler36412a72011-08-04 09:35:13 -040098import android.util.DisplayMetrics;
Chris Wren64161cc2012-12-17 16:49:30 -050099import android.util.EventLog;
Joe Onorato808182d2010-07-09 18:52:06 -0400100import android.util.Log;
101import android.view.Display;
Adrian Roosa98b32c2016-08-11 10:41:08 -0700102import android.view.IRotationWatcher;
Jorim Jaggidf993512014-05-13 23:06:35 +0200103import android.view.KeyEvent;
Jorim Jaggid4a57442014-04-10 02:45:55 +0200104import android.view.LayoutInflater;
Joe Onorato808182d2010-07-09 18:52:06 -0400105import android.view.MotionEvent;
Chris Craik2507c342015-05-04 14:36:49 -0700106import android.view.ThreadedRenderer;
Joe Onorato808182d2010-07-09 18:52:06 -0400107import android.view.View;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800108import android.view.ViewGroup;
Jim Millerf2a16b22011-07-06 17:32:48 -0700109import android.view.ViewGroup.LayoutParams;
Selim Cinek3e7592d2016-04-11 09:35:54 +0800110import android.view.ViewParent;
Dan Sandler44c0dfd2014-06-09 11:26:16 -0400111import android.view.ViewStub;
Ricky Waicd35def2016-05-03 11:07:07 +0100112import android.view.ViewTreeObserver;
Joe Onorato808182d2010-07-09 18:52:06 -0400113import android.view.WindowManager;
Jorim Jaggi786afcb2014-09-25 02:41:29 +0200114import android.view.WindowManagerGlobal;
Daniel Sandlerd7e96862012-04-26 01:10:29 -0400115import android.view.animation.AccelerateInterpolator;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200116import android.view.animation.Interpolator;
Dan Sandler16128f42014-05-21 12:48:22 -0400117import android.widget.ImageView;
Joe Onorato808182d2010-07-09 18:52:06 -0400118import android.widget.TextView;
Selim Cinek64be7722016-07-22 13:28:16 -0700119
Chris Wren9763d422015-04-30 15:24:05 -0400120import com.android.internal.logging.MetricsLogger;
Tamas Berghammercbd3f0c2016-06-22 15:21:38 +0100121import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Chris Wrend1dbc922015-06-19 17:51:16 -0400122import com.android.internal.statusbar.NotificationVisibility;
Joe Onorato808182d2010-07-09 18:52:06 -0400123import com.android.internal.statusbar.StatusBarIcon;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100124import com.android.keyguard.KeyguardHostView.OnDismissAction;
Jason Monkab525272015-07-13 17:02:49 -0400125import com.android.keyguard.KeyguardUpdateMonitor;
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700126import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200127import com.android.keyguard.ViewMediatorCallback;
Clara Bayarri9b1fdff2016-04-21 14:28:47 +0100128import com.android.systemui.AutoReinflateContainer;
129import com.android.systemui.AutoReinflateContainer.InflateListener;
Jorim Jaggi708f7722014-08-20 17:30:38 +0200130import com.android.systemui.BatteryMeterView;
John Spurlock3c875662013-08-31 15:07:25 -0400131import com.android.systemui.DemoMode;
Christoph Studerb0183992014-12-22 21:02:26 +0100132import com.android.systemui.EventLogConstants;
Chris Wren64161cc2012-12-17 16:49:30 -0500133import com.android.systemui.EventLogTags;
Winsonc0d70582016-01-29 10:24:39 -0800134import com.android.systemui.Interpolators;
Andrew Flynn82862572015-04-01 14:22:37 -0400135import com.android.systemui.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -0400136import com.android.systemui.R;
Xiaohui Chen5da71352016-02-22 10:04:41 -0800137import com.android.systemui.SystemUIFactory;
Adrian Roos401caae2016-03-04 13:35:21 -0800138import com.android.systemui.classifier.FalsingLog;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800139import com.android.systemui.classifier.FalsingManager;
Jeff Brown4d69e222014-09-18 15:27:50 -0700140import com.android.systemui.doze.DozeHost;
John Spurlock813552c2014-09-19 08:30:21 -0400141import com.android.systemui.doze.DozeLog;
Jorim Jaggicff0acb2014-03-31 16:35:15 +0200142import com.android.systemui.keyguard.KeyguardViewMediator;
Jason Monk162011e2016-02-19 08:11:55 -0500143import com.android.systemui.qs.QSContainer;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400144import com.android.systemui.qs.QSPanel;
Jorim Jaggid61f2272014-12-19 20:35:35 +0100145import com.android.systemui.recents.ScreenPinningRequest;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800146import com.android.systemui.recents.events.EventBus;
Jorim Jaggi2adba072016-03-03 13:43:39 +0100147import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800148import com.android.systemui.recents.events.activity.UndockingTaskEvent;
Jorim Jaggidd98d412015-11-18 15:57:38 -0800149import com.android.systemui.stackdivider.Divider;
Jorim Jaggiea4a19f2016-02-03 21:31:27 -0800150import com.android.systemui.stackdivider.WindowManagerProxy;
Selim Cineka32ab602014-06-11 15:06:01 +0200151import com.android.systemui.statusbar.ActivatableNotificationView;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200152import com.android.systemui.statusbar.BackDropView;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500153import com.android.systemui.statusbar.BaseStatusBar;
Michael Jurkaa600fd92012-06-25 15:57:05 -0700154import com.android.systemui.statusbar.CommandQueue;
Dan Sandlereceda3d2014-07-21 15:35:01 -0400155import com.android.systemui.statusbar.DismissView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200156import com.android.systemui.statusbar.DragDownHelper;
Jorim Jaggia2052ea2014-08-05 16:22:30 +0200157import com.android.systemui.statusbar.EmptyShadeView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200158import com.android.systemui.statusbar.ExpandableNotificationRow;
Daniel Sandler33805342012-07-23 15:45:12 -0400159import com.android.systemui.statusbar.GestureRecorder;
Andrei Stingaceanuf86bc972016-04-12 15:29:25 +0100160import com.android.systemui.statusbar.KeyboardShortcuts;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200161import com.android.systemui.statusbar.KeyguardIndicationController;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700162import com.android.systemui.statusbar.NotificationData;
Daniel Sandler58b173b2012-05-03 11:25:29 -0400163import com.android.systemui.statusbar.NotificationData.Entry;
Jorim Jaggic5dc0d02014-04-15 15:42:55 +0200164import com.android.systemui.statusbar.NotificationOverflowContainer;
Adrian Roos1c0ca502015-10-07 12:20:42 -0700165import com.android.systemui.statusbar.RemoteInputController;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200166import com.android.systemui.statusbar.ScrimView;
Christian Robertson2e347422011-08-11 14:01:04 -0700167import com.android.systemui.statusbar.SignalClusterView;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200168import com.android.systemui.statusbar.StatusBarState;
Christoph Studer2231c6e2014-12-19 12:40:13 +0100169import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200170import com.android.systemui.statusbar.policy.AccessibilityController;
Daniel Sandler2b697352011-07-22 16:23:09 -0400171import com.android.systemui.statusbar.policy.BatteryController;
John Spurlock0ff62e02014-07-22 16:15:08 -0400172import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700173import com.android.systemui.statusbar.policy.BatteryControllerImpl;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400174import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200175import com.android.systemui.statusbar.policy.BrightnessMirrorController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400176import com.android.systemui.statusbar.policy.CastControllerImpl;
Adrian Roos316bf542016-08-23 17:53:07 +0200177import com.android.systemui.statusbar.policy.EncryptionHelper;
Adrian Roosb83777b2014-06-30 15:11:53 +0200178import com.android.systemui.statusbar.policy.FlashlightController;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700179import com.android.systemui.statusbar.policy.HeadsUpManager;
Jason Monk3d5f5512014-07-25 11:17:28 -0400180import com.android.systemui.statusbar.policy.HotspotControllerImpl;
John Spurlock657c62c2014-07-22 12:18:09 -0400181import com.android.systemui.statusbar.policy.KeyguardMonitor;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700182import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400183import com.android.systemui.statusbar.policy.LocationControllerImpl;
Adrian Roos316bf542016-08-23 17:53:07 +0200184import com.android.systemui.statusbar.policy.NetworkController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400185import com.android.systemui.statusbar.policy.NetworkControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400186import com.android.systemui.statusbar.policy.NextAlarmController;
Jorim Jaggi85dc23c2014-09-08 14:42:29 +0200187import com.android.systemui.statusbar.policy.PreviewInflater;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400188import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
Jason Monk3d5f5512014-07-25 11:17:28 -0400189import com.android.systemui.statusbar.policy.SecurityControllerImpl;
190import com.android.systemui.statusbar.policy.UserInfoController;
Adrian Roos00a0b1f2014-07-16 16:44:49 +0200191import com.android.systemui.statusbar.policy.UserSwitcherController;
John Spurlock86005342014-05-23 11:58:00 -0400192import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek67b22602014-03-10 15:40:16 +0100193import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Selim Cinek64be7722016-07-22 13:28:16 -0700194import com.android.systemui.statusbar.stack.NotificationStackScrollLayout
195 .OnChildLocationsChangedListener;
Jorim Jaggi37c11802015-08-18 20:27:54 -0700196import com.android.systemui.statusbar.stack.StackStateAnimator;
Selim Cinekb036ca42015-02-20 15:56:28 +0100197import com.android.systemui.statusbar.stack.StackViewState;
John Spurlock86005342014-05-23 11:58:00 -0400198import com.android.systemui.volume.VolumeComponent;
Selim Cinek67b22602014-03-10 15:40:16 +0100199
Daniel Sandler6a858c32012-03-12 14:38:58 -0400200import java.io.FileDescriptor;
201import java.io.PrintWriter;
Adrian Roos7bb38a92016-07-21 11:44:01 -0700202import java.io.StringWriter;
Daniel Sandler6a858c32012-03-12 14:38:58 -0400203import java.util.ArrayList;
Christoph Studer92b389d2014-04-01 18:44:40 +0200204import java.util.Collection;
205import java.util.Collections;
Selim Cinekb5605e52015-02-20 18:21:41 +0100206import java.util.HashMap;
Dan Sandler16128f42014-05-21 12:48:22 -0400207import java.util.List;
John Spurlock7bbb9f62014-10-21 12:15:28 -0400208import java.util.Map;
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700209
Jorim Jaggiecbab362014-04-23 16:13:15 +0200210public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Selim Cinek8d490d42015-04-10 00:05:50 -0700211 DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
Adrian Roosa98b32c2016-08-11 10:41:08 -0700212 HeadsUpManager.OnHeadsUpChangedListener {
Joe Onoratofd52b182010-11-10 18:00:52 -0800213 static final String TAG = "PhoneStatusBar";
Daniel Sandler198a0302012-08-17 16:04:31 -0400214 public static final boolean DEBUG = BaseStatusBar.DEBUG;
Chris Wren6d15a362013-08-20 18:46:29 -0400215 public static final boolean SPEW = false;
Daniel Sandler7579bca2011-08-18 15:47:26 -0400216 public static final boolean DUMPTRUCK = true; // extra dumpsys info
Daniel Sandlerfa027f52013-04-11 22:01:47 -0400217 public static final boolean DEBUG_GESTURES = false;
Dan Sandler16128f42014-05-21 12:48:22 -0400218 public static final boolean DEBUG_MEDIA = false;
219 public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
Joe Onorato808182d2010-07-09 18:52:06 -0400220
John Spurlock342cad72013-10-08 09:36:50 -0400221 public static final boolean DEBUG_WINDOW_STATE = false;
Daniel Sandlerb17a7262012-10-05 14:32:50 -0400222
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400223 // additional instrumentation for testing purposes; intended to be left on during development
Daniel Sandler7c351742011-10-17 10:48:06 -0400224 public static final boolean CHATTY = DEBUG;
Daniel Sandler96e61c3c82011-08-04 22:49:06 -0400225
Dan Sandler16128f42014-05-21 12:48:22 -0400226 public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
227
Adrian Roos8e3e8362015-07-16 19:42:22 -0700228 public static final String ACTION_FAKE_ARTWORK = "fake_artwork";
229
Daniel Sandler8ba33c92011-10-04 21:49:30 -0400230 private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
Daniel Sandler11cf1782012-09-27 14:03:08 -0400231 private static final int MSG_CLOSE_PANELS = 1001;
232 private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
Jorim Jaggi826730a2014-12-08 21:05:13 +0100233 private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
Winson Chungb1f74992014-08-08 12:53:09 -0700234 // 1020-1040 reserved for BaseStatusBar
Joe Onorato808182d2010-07-09 18:52:06 -0400235
Jorim Jaggi826730a2014-12-08 21:05:13 +0100236 // Time after we abort the launch transition.
237 private static final long LAUNCH_TRANSITION_TIMEOUT_MS = 5000;
238
Daniel Sandler8cc36e52011-10-17 14:18:46 -0400239 private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
240
John Spurlocke1f366f2013-08-05 12:22:40 -0400241 private static final int STATUS_OR_NAV_TRANSIENT =
242 View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
John Spurlock32beb2c2013-03-11 10:16:47 -0400243 private static final long AUTOHIDE_TIMEOUT_MS = 3000;
John Spurlocke1f366f2013-08-05 12:22:40 -0400244
Christoph Studer92b389d2014-04-01 18:44:40 +0200245 /** The minimum delay in ms between reports of notification visibility. */
246 private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
247
Jorim Jaggi93a2bb22014-06-02 19:57:28 +0200248 /**
249 * The delay to reset the hint text when the hint animation is finished running.
250 */
251 private static final int HINT_RESET_DELAY_MS = 1200;
252
John Spurlock7b414672014-07-18 13:02:39 -0400253 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
254 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
255 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
256 .build();
257
Selim Cinekbaa23272014-07-08 18:01:07 +0200258 public static final int FADE_KEYGUARD_START_DELAY = 100;
259 public static final int FADE_KEYGUARD_DURATION = 300;
Jorim Jaggi90978852015-08-18 19:55:53 -0700260 public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
Selim Cinekbaa23272014-07-08 18:01:07 +0200261
Jason Monk815e0572014-08-12 17:26:36 -0400262 /** Allow some time inbetween the long press for back and recents. */
263 private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
264
Adrian Roos2f2bd9a2015-06-04 18:11:14 -0700265 /** If true, the system is in the half-boot-to-decryption-screen state.
266 * Prudently disable QS and notifications. */
Adrian Roos21d2a252015-06-01 13:59:59 -0700267 private static final boolean ONLY_CORE_APPS;
268
Adrian Roos52738322016-01-29 08:49:21 -0800269 /** If true, the lockscreen will show a distinct wallpaper */
Adrian Roose381c162016-02-11 15:26:42 -0800270 private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
Adrian Roos52738322016-01-29 08:49:21 -0800271
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700272 /* If true, the device supports freeform window management.
273 * This affects the status bar UI. */
274 private static final boolean FREEFORM_WINDOW_MANAGEMENT;
275
Adrian Roos18d099a2016-05-19 15:28:18 -0700276 /**
277 * How long to wait before auto-dismissing a notification that was kept for remote input, and
278 * has now sent a remote input. We auto-dismiss, because the app may not see a reason to cancel
279 * these given that they technically don't exist anymore. We wait a bit in case the app issues
280 * an update.
281 */
282 private static final int REMOTE_INPUT_KEPT_ENTRY_AUTO_CANCEL_DELAY = 200;
283
Jorim Jaggi6626f542016-08-22 13:08:44 -0700284 /**
285 * Never let the alpha become zero for surfaces that draw with SRC - otherwise the RenderNode
286 * won't draw anything and uninitialized memory will show through
287 * if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
288 * libhwui.
289 */
290 private static final float SRC_MIN_ALPHA = 0.002f;
291
Adrian Roos21d2a252015-06-01 13:59:59 -0700292 static {
293 boolean onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700294 boolean freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700295 try {
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700296 IPackageManager packageManager =
297 IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
298 onlyCoreApps = packageManager.isOnlyCoreApps();
299 freeformWindowManagement = packageManager.hasSystemFeature(
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700300 PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT, 0);
Adrian Roos21d2a252015-06-01 13:59:59 -0700301 } catch (RemoteException e) {
302 onlyCoreApps = false;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700303 freeformWindowManagement = false;
Adrian Roos21d2a252015-06-01 13:59:59 -0700304 }
305 ONLY_CORE_APPS = onlyCoreApps;
Vladislav Kaznacheev38f426c2015-10-28 15:48:12 -0700306 FREEFORM_WINDOW_MANAGEMENT = freeformWindowManagement;
Adrian Roos21d2a252015-06-01 13:59:59 -0700307 }
308
Joe Onoratofd52b182010-11-10 18:00:52 -0800309 PhoneStatusBarPolicy mIconPolicy;
Joe Onorato808182d2010-07-09 18:52:06 -0400310
Daniel Sandler2b697352011-07-22 16:23:09 -0400311 // These are no longer handled by the policy, because we need custom strategies for them
John Spurlockaf8d6c42014-05-07 17:49:08 -0400312 BluetoothControllerImpl mBluetoothController;
Jason Monk3d5f5512014-07-25 11:17:28 -0400313 SecurityControllerImpl mSecurityController;
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -0800314 protected BatteryController mBatteryController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400315 LocationControllerImpl mLocationController;
316 NetworkControllerImpl mNetworkController;
Jason Monk51e4dc02014-07-22 12:00:47 -0400317 HotspotControllerImpl mHotspotController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400318 RotationLockControllerImpl mRotationLockController;
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200319 UserInfoController mUserInfoController;
Muyuan Li40e11352016-03-23 11:43:58 -0700320 protected ZenModeController mZenModeController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400321 CastControllerImpl mCastController;
John Spurlock86005342014-05-23 11:58:00 -0400322 VolumeComponent mVolumeComponent;
Adrian Roos8ddb2da2014-06-16 18:56:22 -0700323 KeyguardUserSwitcher mKeyguardUserSwitcher;
Adrian Roosb83777b2014-06-30 15:11:53 +0200324 FlashlightController mFlashlightController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800325 protected UserSwitcherController mUserSwitcherController;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200326 NextAlarmController mNextAlarmController;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800327 protected KeyguardMonitor mKeyguardMonitor;
Adrian Roos5fd872e2014-08-12 17:28:58 +0200328 BrightnessMirrorController mBrightnessMirrorController;
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200329 AccessibilityController mAccessibilityController;
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700330 FingerprintUnlockController mFingerprintUnlockController;
Jorim Jaggi86905582016-02-09 21:36:09 -0800331 LightStatusBarController mLightStatusBarController;
Vadim Tryshev12a30e82016-02-12 15:39:28 -0800332 protected LockscreenWallpaper mLockscreenWallpaper;
Jim Miller5e6af442011-12-02 18:24:26 -0800333
Daniel Sandler7c3e39d2011-07-29 16:30:49 -0400334 int mNaturalBarHeight = -1;
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100335
Joe Onorato808182d2010-07-09 18:52:06 -0400336 Display mDisplay;
Daniel Sandlere680f542012-09-28 12:22:27 -0400337 Point mCurrentDisplaySize = new Point();
Joe Onorato808182d2010-07-09 18:52:06 -0400338
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800339 protected StatusBarWindowView mStatusBarWindow;
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700340 protected PhoneStatusBarView mStatusBarView;
John Spurlockd4e65752013-08-28 14:17:09 -0400341 private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800342 protected StatusBarWindowManager mStatusBarWindowManager;
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200343 private UnlockMethodCache mUnlockMethodCache;
John Spurlockbf370992014-06-17 13:58:31 -0400344 private DozeServiceHost mDozeServiceHost;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -0700345 private boolean mWakeUpComingFromTouch;
346 private PointF mWakeUpTouchLocation;
Selim Cinek1b6f8192015-09-03 16:01:53 -0700347 private boolean mScreenTurningOn;
Daniel Sandlera310af82012-04-24 01:20:13 -0400348
Joe Onorato808182d2010-07-09 18:52:06 -0400349 int mPixelFormat;
Joe Onorato808182d2010-07-09 18:52:06 -0400350 Object mQueueLock = new Object();
351
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700352 protected StatusBarIconController mIconController;
Joe Onorato808182d2010-07-09 18:52:06 -0400353
354 // expanded notifications
Xiaohui Chenea4b6ba2016-02-18 10:53:17 -0800355 protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
Joe Onorato808182d2010-07-09 18:52:06 -0400356 View mExpandedContents;
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400357 TextView mNotificationPanelDebugText;
Daniel Sandler21b274e2012-05-02 15:07:51 -0400358
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400359 // settings
John Spurlockaf8d6c42014-05-07 17:49:08 -0400360 private QSPanel mQSPanel;
Daniel Sandler8e72c9e2012-08-15 00:09:26 -0400361
Joe Onorato808182d2010-07-09 18:52:06 -0400362 // top bar
Jason Monk0e1101d2015-10-07 13:06:09 -0400363 BaseStatusBarHeader mHeader;
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700364 protected KeyguardStatusBarView mKeyguardStatusBar;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200365 View mKeyguardStatusView;
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200366 KeyguardBottomAreaView mKeyguardBottomArea;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200367 boolean mLeaveOpenOnKeyguardHide;
Adrian Roos12c1ef52014-06-04 13:54:08 +0200368 KeyguardIndicationController mKeyguardIndicationController;
Jorim Jaggie70d31f2014-04-24 22:08:30 +0200369
Adrian Roos46df1ca2015-09-11 12:38:43 -0700370 // Keyguard is going away soon.
371 private boolean mKeyguardGoingAway;
372 // Keyguard is actually fading away now.
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700373 private boolean mKeyguardFadingAway;
374 private long mKeyguardFadingAwayDelay;
375 private long mKeyguardFadingAwayDuration;
376
Adrian Roos3aec6382016-02-05 14:19:01 -0800377 // RemoteInputView to be activated after unlock
378 private View mPendingRemoteInputView;
Ricky Waicd35def2016-05-03 11:07:07 +0100379 private View mPendingWorkRemoteInputView;
Adrian Roos3aec6382016-02-05 14:19:01 -0800380
Adrian Roos7bb38a92016-07-21 11:44:01 -0700381 private View mReportRejectedTouch;
382
Selim Cinek5f71bee2015-11-18 10:25:23 -0800383 int mMaxAllowedKeyguardNotifications;
Daniel Sandlerd3090562011-08-09 00:28:44 -0400384
Joe Onorato808182d2010-07-09 18:52:06 -0400385 boolean mExpandedVisible;
386
John Spurlockd4e65752013-08-28 14:17:09 -0400387 private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400388
Joe Onorato808182d2010-07-09 18:52:06 -0400389 // the tracker view
Joe Onorato808182d2010-07-09 18:52:06 -0400390 int mTrackingPosition; // the position of the top of the tracking view.
Joe Onorato808182d2010-07-09 18:52:06 -0400391
Joe Onorato808182d2010-07-09 18:52:06 -0400392 // Tracking finger for opening/closing.
Joe Onorato808182d2010-07-09 18:52:06 -0400393 boolean mTracking;
Joe Onorato808182d2010-07-09 18:52:06 -0400394
Joe Onorato808182d2010-07-09 18:52:06 -0400395 int[] mAbsPos = new int[2];
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200396 ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
Chet Haase2f2022a2011-10-11 06:41:59 -0700397
Joe Onorato808182d2010-07-09 18:52:06 -0400398 // for disabling the status bar
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100399 int mDisabled1 = 0;
400 int mDisabled2 = 0;
Joe Onorato808182d2010-07-09 18:52:06 -0400401
Daniel Sandler60ee2562011-07-22 12:34:33 -0400402 // tracking calls to View.setSystemUiVisibility()
403 int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
Jorim Jaggi86905582016-02-09 21:36:09 -0800404 private final Rect mLastFullscreenStackBounds = new Rect();
405 private final Rect mLastDockedStackBounds = new Rect();
Daniel Sandler60ee2562011-07-22 12:34:33 -0400406
Adrian Roos389beec2015-05-12 13:33:25 -0700407 // last value sent to window manager
408 private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
409
Daniel Sandler36412a72011-08-04 09:35:13 -0400410 DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Dianne Hackborn1dacf272011-08-02 15:01:22 -0700411
Daniel Sandler33805342012-07-23 15:45:12 -0400412 // XXX: gesture research
Daniel Sandler151f00d2012-10-02 22:33:08 -0400413 private final GestureRecorder mGestureRec = DEBUG_GESTURES
John Spurlock209bede2013-07-17 12:23:27 -0400414 ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
Daniel Sandler151f00d2012-10-02 22:33:08 -0400415 : null;
Daniel Sandler33805342012-07-23 15:45:12 -0400416
Jason Monk18f99d92014-09-11 13:36:42 -0400417 private ScreenPinningRequest mScreenPinningRequest;
418
Daniel Sandler328310c2011-09-23 15:56:52 -0400419 private int mNavigationIconHints = 0;
Jason Monk4ae97d32014-12-17 10:14:33 -0500420 private HandlerThread mHandlerThread;
Daniel Sandler328310c2011-09-23 15:56:52 -0400421
John Spurlock919adac2012-10-02 16:41:12 -0400422 // ensure quick settings is disabled until the current user makes it through the setup wizard
423 private boolean mUserSetup = false;
424 private ContentObserver mUserSetupObserver = new ContentObserver(new Handler()) {
425 @Override
426 public void onChange(boolean selfChange) {
427 final boolean userSetup = 0 != Settings.Secure.getIntForUser(
428 mContext.getContentResolver(),
429 Settings.Secure.USER_SETUP_COMPLETE,
430 0 /*default */,
431 mCurrentUserId);
John Spurlockcd686b52013-06-05 10:13:46 -0400432 if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
John Spurlocke4e8c562012-10-04 09:55:01 -0400433 "selfChange=%s userSetup=%s mUserSetup=%s",
434 selfChange, userSetup, mUserSetup));
John Spurlock73203eb2014-04-15 16:14:46 -0400435
John Spurlock919adac2012-10-02 16:41:12 -0400436 if (userSetup != mUserSetup) {
437 mUserSetup = userSetup;
John Spurlock919adac2012-10-02 16:41:12 -0400438 if (!mUserSetup && mStatusBarView != null)
439 animateCollapseQuickSettings();
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700440 if (mKeyguardBottomArea != null) {
441 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
442 }
Jason Monkfd57ea72016-04-29 13:37:58 -0400443 if (mNetworkController != null) {
444 mNetworkController.setUserSetupComplete(mUserSetup);
445 }
John Spurlock919adac2012-10-02 16:41:12 -0400446 }
John Spurlock604a5ee2015-06-01 12:27:22 -0400447 if (mIconPolicy != null) {
448 mIconPolicy.setCurrentUserSetup(mUserSetup);
449 }
John Spurlock919adac2012-10-02 16:41:12 -0400450 }
451 };
452
Chris Wrenf6e83f42013-09-11 14:02:59 -0400453 final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
454 @Override
455 public void onChange(boolean selfChange) {
456 boolean wasUsing = mUseHeadsUp;
Jason Monkf7019542014-07-31 12:42:25 -0400457 mUseHeadsUp = ENABLE_HEADS_UP && !mDisableNotificationAlerts
458 && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
Chris Wren10d82df2014-03-01 10:34:51 -0500459 mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Chris Wren7bd241232014-02-28 16:25:05 -0500460 Settings.Global.HEADS_UP_OFF);
Chris Wren22ae46e2014-02-26 18:08:09 -0500461 mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
462 mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400463 Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
464 if (wasUsing != mUseHeadsUp) {
465 if (!mUseHeadsUp) {
466 Log.d(TAG, "dismissing any existing heads up notification on disable event");
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700467 mHeadsUpManager.releaseAllImmediately();
Chris Wrenf6e83f42013-09-11 14:02:59 -0400468 }
469 }
470 }
471 };
472
John Spurlockcfc359a2013-09-05 10:42:03 -0400473 private int mInteractingWindows;
John Spurlock32beb2c2013-03-11 10:16:47 -0400474 private boolean mAutohideSuspended;
John Spurlockd4e65752013-08-28 14:17:09 -0400475 private int mStatusBarMode;
476 private int mNavigationBarMode;
Selim Cinek5f71bee2015-11-18 10:25:23 -0800477 private int mMaxKeyguardNotifications;
Jorim Jaggid41083a2014-09-12 02:54:40 +0200478
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200479 private ViewMediatorCallback mKeyguardViewMediatorCallback;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800480 protected ScrimController mScrimController;
481 protected DozeScrimController mDozeScrimController;
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200482
John Spurlock32beb2c2013-03-11 10:16:47 -0400483 private final Runnable mAutohide = new Runnable() {
484 @Override
485 public void run() {
John Spurlocke1f366f2013-08-05 12:22:40 -0400486 int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
John Spurlock9deaa282013-07-25 13:03:47 -0400487 if (mSystemUiVisibility != requested) {
488 notifyUiVisibilityChanged(requested);
489 }
John Spurlock32beb2c2013-03-11 10:16:47 -0400490 }};
491
Jorim Jaggi44cf9192014-06-17 19:16:00 -0700492 private boolean mWaitingForKeyguardExit;
John Spurlockbf370992014-06-17 13:58:31 -0400493 private boolean mDozing;
Jorim Jaggi83969702015-06-05 14:59:24 -0700494 private boolean mDozingRequested;
Xiyuan Xia1b30f792016-01-06 08:50:30 -0800495 protected boolean mScrimSrcModeEnabled;
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100496
Selim Cinekc18010f2016-01-20 13:41:30 -0800497 public static final Interpolator ALPHA_IN = Interpolators.ALPHA_IN;
498 public static final Interpolator ALPHA_OUT = Interpolators.ALPHA_OUT;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200499
Selim Cineka0fad3b2014-09-19 17:20:05 +0200500 private BackDropView mBackdrop;
Dan Sandler16128f42014-05-21 12:48:22 -0400501 private ImageView mBackdropFront, mBackdropBack;
Selim Cineka0fad3b2014-09-19 17:20:05 +0200502 private PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
503 private PorterDuffXfermode mSrcOverXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
Dan Sandler16128f42014-05-21 12:48:22 -0400504
505 private MediaSessionManager mMediaSessionManager;
506 private MediaController mMediaController;
507 private String mMediaNotificationKey;
508 private MediaMetadata mMediaMetadata;
509 private MediaController.Callback mMediaListener
510 = new MediaController.Callback() {
511 @Override
512 public void onPlaybackStateChanged(PlaybackState state) {
513 super.onPlaybackStateChanged(state);
514 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400515 if (state != null) {
516 if (!isPlaybackActive(state.getState())) {
517 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -0800518 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -0400519 }
520 }
Dan Sandler16128f42014-05-21 12:48:22 -0400521 }
522
523 @Override
524 public void onMetadataChanged(MediaMetadata metadata) {
525 super.onMetadataChanged(metadata);
526 if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
527 mMediaMetadata = metadata;
Adrian Roos52738322016-01-29 08:49:21 -0800528 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -0400529 }
530 };
531
532 private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
533 new OnChildLocationsChangedListener() {
534 @Override
535 public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
536 userActivity();
537 }
538 };
539
Benjamin Franzcde0a2a2015-04-23 17:19:48 +0100540 private int mDisabledUnmodified1;
541 private int mDisabledUnmodified2;
Jorim Jaggib13d36d2014-06-06 18:03:52 +0200542
Christoph Studer92b389d2014-04-01 18:44:40 +0200543 /** Keys of notifications currently visible to the user. */
Chris Wrend1dbc922015-06-19 17:51:16 -0400544 private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications =
545 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200546 private long mLastVisibilityReportUptimeMs;
547
John Spurlockbf370992014-06-17 13:58:31 -0400548 private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
549
Selim Cinekbaa23272014-07-08 18:01:07 +0200550 private Runnable mLaunchTransitionEndRunnable;
551 private boolean mLaunchTransitionFadingAway;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +0200552 private ExpandableNotificationRow mDraggedDownRow;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700553 private boolean mLaunchCameraOnScreenTurningOn;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700554 private boolean mLaunchCameraOnFinishedGoingToSleep;
Jorim Jaggi40aa8812015-09-23 12:59:22 -0700555 private int mLastCameraLaunchSource;
Selim Cinek372d1bd2015-08-14 13:19:37 -0700556 private PowerManager.WakeLock mGestureWakeLock;
Selim Cinek69ff8af2015-08-25 19:03:48 -0700557 private Vibrator mVibrator;
Jorim Jaggi362dd6d2014-07-09 19:04:07 +0200558
Christoph Studer2231c6e2014-12-19 12:40:13 +0100559 // Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
560 private int mLastLoggedStateFingerprint;
561
Jorim Jaggi18f18ae2015-09-10 15:48:21 -0700562 /**
563 * If set, the device has started going to sleep but isn't fully non-interactive yet.
564 */
565 protected boolean mStartedGoingToSleep;
566
Selim Cinek3776fe02016-02-04 13:32:43 -0800567 private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_HUN
Chris Wren35a7c922015-06-22 16:31:01 -0400568 | StackViewState.LOCATION_MAIN_AREA;
Christoph Studer92b389d2014-04-01 18:44:40 +0200569
570 private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
571 new OnChildLocationsChangedListener() {
572 @Override
573 public void onChildLocationsChanged(
574 NotificationStackScrollLayout stackScrollLayout) {
575 if (mHandler.hasCallbacks(mVisibilityReporter)) {
576 // Visibilities will be reported when the existing
577 // callback is executed.
578 return;
579 }
580 // Calculate when we're allowed to run the visibility
581 // reporter. Note that this timestamp might already have
582 // passed. That's OK, the callback will just be executed
583 // ASAP.
584 long nextReportUptimeMs =
585 mLastVisibilityReportUptimeMs + VISIBILITY_REPORT_MIN_DELAY_MS;
586 mHandler.postAtTime(mVisibilityReporter, nextReportUptimeMs);
587 }
588 };
589
590 // Tracks notifications currently visible in mNotificationStackScroller and
591 // emits visibility events via NoMan on changes.
592 private final Runnable mVisibilityReporter = new Runnable() {
Chris Wrend1dbc922015-06-19 17:51:16 -0400593 private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
594 new ArraySet<>();
595 private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
596 new ArraySet<>();
597 private final ArraySet<NotificationVisibility> mTmpNoLongerVisibleNotifications =
598 new ArraySet<>();
Christoph Studer92b389d2014-04-01 18:44:40 +0200599
600 @Override
601 public void run() {
602 mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
Chris Wrend1dbc922015-06-19 17:51:16 -0400603 final String mediaKey = getCurrentMediaNotificationKey();
Christoph Studer92b389d2014-04-01 18:44:40 +0200604
605 // 1. Loop over mNotificationData entries:
606 // A. Keep list of visible notifications.
607 // B. Keep list of previously hidden, now visible notifications.
608 // 2. Compute no-longer visible notifications by removing currently
609 // visible notifications from the set of previously visible
610 // notifications.
611 // 3. Report newly visible and no-longer visible notifications.
612 // 4. Keep currently visible notifications for next report.
Christoph Studerc8db24b2014-07-25 17:50:30 +0200613 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
614 int N = activeNotifications.size();
Christoph Studer92b389d2014-04-01 18:44:40 +0200615 for (int i = 0; i < N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +0200616 Entry entry = activeNotifications.get(i);
Christoph Studer92b389d2014-04-01 18:44:40 +0200617 String key = entry.notification.getKey();
Chris Wrend1dbc922015-06-19 17:51:16 -0400618 boolean isVisible =
Christoph Studer92b389d2014-04-01 18:44:40 +0200619 (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0;
Chris Wrend1dbc922015-06-19 17:51:16 -0400620 NotificationVisibility visObj = NotificationVisibility.obtain(key, i, isVisible);
621 boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(visObj);
622 if (isVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +0200623 // Build new set of visible notifications.
Chris Wrend1dbc922015-06-19 17:51:16 -0400624 mTmpCurrentlyVisibleNotifications.add(visObj);
625 if (!previouslyVisible) {
626 mTmpNewlyVisibleNotifications.add(visObj);
627 }
628 } else {
629 // release object
630 visObj.recycle();
Christoph Studer92b389d2014-04-01 18:44:40 +0200631 }
632 }
Chris Wrend1dbc922015-06-19 17:51:16 -0400633 mTmpNoLongerVisibleNotifications.addAll(mCurrentlyVisibleNotifications);
634 mTmpNoLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200635
636 logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -0400637 mTmpNewlyVisibleNotifications, mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200638
Chris Wrend1dbc922015-06-19 17:51:16 -0400639 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200640 mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications);
641
Chris Wrend1dbc922015-06-19 17:51:16 -0400642 recycleAllVisibilityObjects(mTmpNoLongerVisibleNotifications);
Christoph Studer92b389d2014-04-01 18:44:40 +0200643 mTmpCurrentlyVisibleNotifications.clear();
Chris Wrend1dbc922015-06-19 17:51:16 -0400644 mTmpNewlyVisibleNotifications.clear();
645 mTmpNoLongerVisibleNotifications.clear();
Christoph Studer92b389d2014-04-01 18:44:40 +0200646 }
647 };
648
Chris Wrend1dbc922015-06-19 17:51:16 -0400649 private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
650 final int N = array.size();
651 for (int i = 0 ; i < N; i++) {
652 array.valueAt(i).recycle();
653 }
654 array.clear();
655 }
656
Jorim Jaggiecbab362014-04-23 16:13:15 +0200657 private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() {
658 @Override
659 public void onClick(View v) {
660 goToLockedShade(null);
661 }
662 };
Selim Cinekb5605e52015-02-20 18:21:41 +0100663 private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
664 = new HashMap<>();
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700665 private RankingMap mLatestRankingMap;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -0700666 private boolean mNoAnimationOnNextBarModeChange;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700667 private FalsingManager mFalsingManager;
Jorim Jaggiecbab362014-04-23 16:13:15 +0200668
Selim Cinek99415392016-09-09 14:58:41 -0700669 private KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
670 @Override
671 public void onDreamingStateChanged(boolean dreaming) {
672 if (dreaming) {
673 maybeEscalateHeadsUp();
674 }
675 }
676 };
677
Joe Onorato808182d2010-07-09 18:52:06 -0400678 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400679 public void start() {
680 mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
681 .getDefaultDisplay();
Daniel Sandler7e8ae502013-10-10 23:38:19 -0400682 updateDisplaySize();
Jorim Jaggi0e664392014-09-27 01:30:22 +0200683 mScrimSrcModeEnabled = mContext.getResources().getBoolean(
684 R.bool.config_status_bar_scrim_behind_use_src);
Adrian Roos75fa3852015-01-27 20:21:44 +0100685
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500686 super.start(); // calls createAndAddWindows()
Joe Onorato808182d2010-07-09 18:52:06 -0400687
Dan Sandler16128f42014-05-21 12:48:22 -0400688 mMediaSessionManager
689 = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
690 // TODO: use MediaSessionManager.SessionListener to hook us up to future updates
691 // in session state
692
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400693 addNavigationBar();
694
Joe Onorato808182d2010-07-09 18:52:06 -0400695 // Lastly, call to the icon policy to install/update all the icons.
Jason Monk07473ce2016-01-05 14:59:19 -0500696 mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCastController,
Jason Monk3e189872016-01-12 09:10:34 -0500697 mHotspotController, mUserInfoController, mBluetoothController,
Julia Reynolds4e6024b2016-04-26 16:12:26 -0400698 mRotationLockController, mNetworkController.getDataSaverController(), mNextAlarmController);
John Spurlock604a5ee2015-06-01 12:27:22 -0400699 mIconPolicy.setCurrentUserSetup(mUserSetup);
John Spurlocke677d712014-02-13 12:52:19 -0500700 mSettingsObserver.onChange(false); // set up
Chris Wrenf6e83f42013-09-11 14:02:59 -0400701
702 mHeadsUpObserver.onChange(true); // set up
703 if (ENABLE_HEADS_UP) {
704 mContext.getContentResolver().registerContentObserver(
Chris Wren10d82df2014-03-01 10:34:51 -0500705 Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
Chris Wrenf6e83f42013-09-11 14:02:59 -0400706 mHeadsUpObserver);
Chris Wren22ae46e2014-02-26 18:08:09 -0500707 mContext.getContentResolver().registerContentObserver(
708 Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
709 mHeadsUpObserver);
Chris Wrenf6e83f42013-09-11 14:02:59 -0400710 }
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +0200711 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Christoph Studer2231c6e2014-12-19 12:40:13 +0100712 mUnlockMethodCache.addListener(this);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100713 startKeyguard();
John Spurlockbf370992014-06-17 13:58:31 -0400714
Selim Cinek99415392016-09-09 14:58:41 -0700715 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback);
John Spurlockbf370992014-06-17 13:58:31 -0400716 mDozeServiceHost = new DozeServiceHost();
Jeff Brown4d69e222014-09-18 15:27:50 -0700717 putComponent(DozeHost.class, mDozeServiceHost);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200718 putComponent(PhoneStatusBar.class, this);
John Spurlock89f060a2014-07-16 21:03:15 -0400719
720 setControllerUsers();
Chris Wrencd8f4f72014-08-27 18:48:13 -0400721
722 notifyUserAboutHiddenNotifications();
Jason Monk18f99d92014-09-11 13:36:42 -0400723
724 mScreenPinningRequest = new ScreenPinningRequest(mContext);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700725 mFalsingManager = FalsingManager.getInstance(mContext);
Joe Onorato808182d2010-07-09 18:52:06 -0400726 }
727
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700728 protected void createIconController() {
729 mIconController = new StatusBarIconController(
730 mContext, mStatusBarView, mKeyguardStatusBar, this);
731 }
732
Joe Onorato808182d2010-07-09 18:52:06 -0400733 // ================================================================================
734 // Constructing the view
735 // ================================================================================
Jim Millere898ac52012-04-06 17:10:57 -0700736 protected PhoneStatusBarView makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400737 final Context context = mContext;
Joe Onorato808182d2010-07-09 18:52:06 -0400738
Daniel Sandler6e8db882011-10-26 15:40:51 -0400739 updateDisplaySize(); // populates mDisplayMetrics
Jorim Jaggi2e115c52014-07-01 21:27:58 +0200740 updateResources();
Joe Onorato808182d2010-07-09 18:52:06 -0400741
Xiaohui Chend839d1a2016-01-21 13:05:02 -0800742 inflateStatusBarWindow(context);
Selim Cinek4e6b2d32015-06-25 20:15:33 -0400743 mStatusBarWindow.setService(this);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400744 mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
745 @Override
746 public boolean onTouch(View v, MotionEvent event) {
John Spurlock9deaa282013-07-25 13:03:47 -0400747 checkUserAutohide(v, event);
Daniel Sandler21b274e2012-05-02 15:07:51 -0400748 if (event.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandler37a38aa2013-02-13 17:15:57 -0500749 if (mExpandedVisible) {
Daniel Sandler11cf1782012-09-27 14:03:08 -0400750 animateCollapsePanels();
Daniel Sandler21b274e2012-05-02 15:07:51 -0400751 }
752 }
Chris Wren5de6e942012-05-16 14:22:21 -0400753 return mStatusBarWindow.onTouchEvent(event);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700754 }
755 });
Daniel Sandler21b274e2012-05-02 15:07:51 -0400756
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100757 mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
758 R.id.notification_panel);
Daniel Sandler040c2e42012-10-17 00:56:33 -0400759 mNotificationPanel.setStatusBar(this);
Selim Cinek53f8e7d2016-03-25 02:28:01 -0700760 mNotificationPanel.setGroupManager(mGroupManager);
Joe Onorato808182d2010-07-09 18:52:06 -0400761
Xiaohui Chen9f967112016-01-07 14:14:06 -0800762 mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
763 mStatusBarView.setBar(this);
764 mStatusBarView.setPanel(mNotificationPanel);
765
Jeff Brown98365d72012-08-19 20:30:52 -0700766 if (!ActivityManager.isHighEndGfx()) {
Romain Guy328b3582012-05-08 15:30:57 -0700767 mStatusBarWindow.setBackground(null);
Alan Viverette4a357cd2015-03-18 18:37:18 -0700768 mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
Romain Guy648342f2012-05-25 10:44:45 -0700769 R.color.notification_panel_solid_background)));
Romain Guy328b3582012-05-08 15:30:57 -0700770 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700771
Selim Cinek83bc7832015-10-22 13:26:54 -0700772 mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700773 mHeadsUpManager.setBar(this);
774 mHeadsUpManager.addListener(this);
775 mHeadsUpManager.addListener(mNotificationPanel);
Selim Cinekef5127e2015-12-21 16:55:58 -0800776 mHeadsUpManager.addListener(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700777 mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
Selim Cinekfbe9a442015-04-13 16:09:49 -0700778 mNotificationData.setHeadsUpManager(mHeadsUpManager);
Selim Cinek967ed2a2016-04-08 18:29:11 -0700779 mGroupManager.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700780
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400781 if (MULTIUSER_DEBUG) {
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100782 mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
783 R.id.header_debug_info);
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400784 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
785 }
Joe Onorato808182d2010-07-09 18:52:06 -0400786
Daniel Sandler0129b312011-05-11 11:54:11 -0400787 try {
Jeff Brown98365d72012-08-19 20:30:52 -0700788 boolean showNav = mWindowManagerService.hasNavigationBar();
John Spurlockcd686b52013-06-05 10:13:46 -0400789 if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
Daniel Sandler0129b312011-05-11 11:54:11 -0400790 if (showNav) {
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800791 createNavigationBarView(context);
Daniel Sandler0129b312011-05-11 11:54:11 -0400792 }
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400793 } catch (RemoteException ex) {
794 // no window manager? good luck with that
Daniel Sandler0129b312011-05-11 11:54:11 -0400795 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400796
Annie Chin937a9912016-05-31 10:14:23 -0700797 mAssistManager = SystemUIFactory.getInstance().createAssistManager(this, context);
Selim Cineke70d6532015-04-24 16:46:13 -0700798
Joe Onorato808182d2010-07-09 18:52:06 -0400799 // figure out which pixel-format to use for the status bar.
Daniel Sandlerf733c2a2011-09-25 15:03:40 -0400800 mPixelFormat = PixelFormat.OPAQUE;
Daniel Sandler173bae22012-09-25 14:37:42 -0400801
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100802 mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
803 R.id.notification_stack_scroller);
804 mStackScroller.setLongPressListener(getNotificationLongClicker());
Selim Cinek19c8c702014-08-25 22:09:19 +0200805 mStackScroller.setPhoneStatusBar(this);
Selim Cinekb5605e52015-02-20 18:21:41 +0100806 mStackScroller.setGroupManager(mGroupManager);
Selim Cinekb8f09cf2015-03-16 17:09:28 -0700807 mStackScroller.setHeadsUpManager(mHeadsUpManager);
Selim Cinekb5605e52015-02-20 18:21:41 +0100808 mGroupManager.setOnGroupChangeListener(mStackScroller);
Selim Cinek80a14e52014-03-27 16:58:04 +0100809
Selim Cinek3e7592d2016-04-11 09:35:54 +0800810 inflateOverflowContainer();
Selim Cinek01af3342016-02-09 19:25:31 -0800811 inflateEmptyShadeView();
812 inflateDismissView();
Selim Cinekb6d85eb2014-03-28 20:21:01 +0100813 mExpandedContents = mStackScroller;
Selim Cinek67b22602014-03-10 15:40:16 +0100814
Selim Cineka0fad3b2014-09-19 17:20:05 +0200815 mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
816 mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
817 mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
818
Jorim Jaggie31f6b82016-07-01 16:15:09 -0700819 if (ENABLE_LOCKSCREEN_WALLPAPER) {
820 mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
821 }
822
Selim Cineka0fad3b2014-09-19 17:20:05 +0200823 ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
824 ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
Selim Cinekaac93252015-04-14 20:04:12 -0700825 View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
Xiaohui Chen5da71352016-02-22 10:04:41 -0800826 mScrimController = SystemUIFactory.getInstance().createScrimController(
Jorim Jaggie31f6b82016-07-01 16:15:09 -0700827 scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper);
Selim Cinek25503252016-03-03 15:31:43 -0800828 if (mScrimSrcModeEnabled) {
829 Runnable runnable = new Runnable() {
830 @Override
831 public void run() {
832 boolean asSrc = mBackdrop.getVisibility() != View.VISIBLE;
833 mScrimController.setDrawBehindAsSrc(asSrc);
834 mStackScroller.setDrawBackgroundAsSrc(asSrc);
835 }
836 };
837 mBackdrop.setOnVisibilityChangedRunnable(runnable);
838 runnable.run();
839 }
Selim Cinekaac93252015-04-14 20:04:12 -0700840 mHeadsUpManager.addListener(mScrimController);
841 mStackScroller.setScrimController(mScrimController);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200842 mStatusBarView.setScrimController(mScrimController);
Jorim Jaggi048af1f2014-11-11 22:51:10 +0100843 mDozeScrimController = new DozeScrimController(mScrimController, context);
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200844
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200845 mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
Jorim Jaggi03c701e2014-04-02 12:39:51 +0200846 mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200847 mKeyguardBottomArea =
848 (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
849 mKeyguardBottomArea.setActivityStarter(this);
Selim Cineke70d6532015-04-24 16:46:13 -0700850 mKeyguardBottomArea.setAssistManager(mAssistManager);
Adrian Roos12c1ef52014-06-04 13:54:08 +0200851 mKeyguardIndicationController = new KeyguardIndicationController(mContext,
852 (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700853 R.id.keyguard_indication_text),
854 mKeyguardBottomArea.getLockIcon());
Adrian Roos4ebcdfd2014-08-12 23:33:49 +0200855 mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
Daniel Sandlere111ad32012-10-13 15:17:45 -0400856
Xiaohui Chenf43491f2016-02-01 12:19:35 -0800857 // set the initial view visibility
Joe Onorato808182d2010-07-09 18:52:06 -0400858 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400859
Xiaohui Cheneb04a992016-03-22 14:58:03 -0700860 createIconController();
Jorim Jaggi66ac1332015-01-21 19:22:26 +0100861
Jason Monk4ae97d32014-12-17 10:14:33 -0500862 // Background thread for any controllers that need it.
863 mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
864 mHandlerThread.start();
865
Daniel Sandler2b697352011-07-22 16:23:09 -0400866 // Other icons
Jason Monk05b86bc2015-05-19 14:21:28 -0400867 mLocationController = new LocationControllerImpl(mContext,
868 mHandlerThread.getLooper()); // will post a notification
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700869 mBatteryController = createBatteryController();
John Spurlock0ff62e02014-07-22 16:15:08 -0400870 mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
871 @Override
Jason Monkc06fbb12016-01-08 14:12:18 -0500872 public void onPowerSaveChanged(boolean isPowerSave) {
John Spurlock0ff62e02014-07-22 16:15:08 -0400873 mHandler.post(mCheckBarModes);
John Spurlockd96179e2014-08-21 16:43:45 -0400874 if (mDozeServiceHost != null) {
Jason Monkc06fbb12016-01-08 14:12:18 -0500875 mDozeServiceHost.firePowerSaveChanged(isPowerSave);
John Spurlockd96179e2014-08-21 16:43:45 -0400876 }
John Spurlock0ff62e02014-07-22 16:15:08 -0400877 }
878 @Override
879 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
880 // noop
881 }
882 });
Jason Monk30d80042015-05-08 16:54:18 -0400883 mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monkfd57ea72016-04-29 13:37:58 -0400884 mNetworkController.setUserSetupComplete(mUserSetup);
Jason Monk51e4dc02014-07-22 12:00:47 -0400885 mHotspotController = new HotspotControllerImpl(mContext);
Jason Monk4ae97d32014-12-17 10:14:33 -0500886 mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
Jason Monk3d5f5512014-07-25 11:17:28 -0400887 mSecurityController = new SecurityControllerImpl(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400888 if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
889 mRotationLockController = new RotationLockControllerImpl(mContext);
John Spurlock8ab172e2013-12-19 16:39:23 -0500890 }
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200891 mUserInfoController = new UserInfoController(mContext);
John Spurlock86005342014-05-23 11:58:00 -0400892 mVolumeComponent = getComponent(VolumeComponent.class);
John Spurlockf2565a82014-10-23 20:16:22 -0400893 if (mVolumeComponent != null) {
894 mZenModeController = mVolumeComponent.getZenController();
895 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400896 mCastController = new CastControllerImpl(mContext);
Xiaohui Chen10942302015-12-16 16:38:13 -0800897
898 initSignalCluster(mStatusBarView);
899 initSignalCluster(mKeyguardStatusBar);
Adrian Roos316bf542016-08-23 17:53:07 +0200900 initEmergencyCryptkeeperText();
Daniel Sandlerdd4ef492012-07-27 11:19:52 -0400901
Adrian Roosb83777b2014-06-30 15:11:53 +0200902 mFlashlightController = new FlashlightController(mContext);
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200903 mKeyguardBottomArea.setFlashlightController(mFlashlightController);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200904 mKeyguardBottomArea.setPhoneStatusBar(this);
Adrian Roosa4eba9f2015-07-22 18:13:04 -0700905 mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
Jorim Jaggib2e104f2014-08-15 18:12:36 +0200906 mAccessibilityController = new AccessibilityController(mContext);
907 mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200908 mNextAlarmController = new NextAlarmController(mContext);
Jorim Jaggi86905582016-02-09 21:36:09 -0800909 mLightStatusBarController = new LightStatusBarController(mIconController,
910 mBatteryController);
Jason Monk8a3a9642015-06-05 11:01:30 -0400911 mKeyguardMonitor = new KeyguardMonitor(mContext);
Amith Yamasani69476362016-07-13 11:59:16 -0700912 mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
913 mHandler, this);
Fyodor Kupolovcd86ebf2015-09-29 17:06:50 -0700914 if (UserManager.get(mContext).isUserSwitcherEnabled()) {
Rakesh Iyer2790a372016-01-22 15:33:39 -0800915 createUserSwitcher();
Adrian Roos2b154a92014-11-17 15:18:39 +0100916 }
Adrian Roos723632e2014-07-23 21:13:21 +0200917
John Spurlockaf8d6c42014-05-07 17:49:08 -0400918 // Set up the quick settings tile panel
Clara Bayarri9b1fdff2016-04-21 14:28:47 +0100919 AutoReinflateContainer container = (AutoReinflateContainer) mStatusBarWindow.findViewById(
920 R.id.qs_auto_reinflate_container);
Jason Monk46dbfb42016-02-25 14:59:20 -0500921 if (container != null) {
Xiaohui Chen311b98e2016-03-30 11:55:54 -0700922 final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
John Spurlockaf8d6c42014-05-07 17:49:08 -0400923 mBluetoothController, mLocationController, mRotationLockController,
Jason Monk51e4dc02014-07-22 12:00:47 -0400924 mNetworkController, mZenModeController, mHotspotController,
John Spurlock657c62c2014-07-22 12:18:09 -0400925 mCastController, mFlashlightController,
Jason Monkabe19742015-09-29 09:47:06 -0400926 mUserSwitcherController, mUserInfoController, mKeyguardMonitor,
Jason Monk46dbfb42016-02-25 14:59:20 -0500927 mSecurityController, mBatteryController, mIconController,
928 mNextAlarmController);
Adrian Roos5fd872e2014-08-12 17:28:58 +0200929 mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
Jason Monk46dbfb42016-02-25 14:59:20 -0500930 container.addInflateListener(new InflateListener() {
John Spurlockbceed062014-08-10 18:04:16 -0400931 @Override
Jason Monk46dbfb42016-02-25 14:59:20 -0500932 public void onInflated(View v) {
933 QSContainer qsContainer = (QSContainer) v.findViewById(
934 R.id.quick_settings_container);
935 qsContainer.setHost(qsh);
936 mQSPanel = qsContainer.getQsPanel();
937 mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
Kaori Katouccf08d72015-05-26 16:25:04 +0900938 mKeyguardStatusBar.setQSPanel(mQSPanel);
Jason Monk46dbfb42016-02-25 14:59:20 -0500939 mHeader = qsContainer.getHeader();
940 initSignalCluster(mHeader);
941 mHeader.setActivityStarter(PhoneStatusBar.this);
John Spurlockbceed062014-08-10 18:04:16 -0400942 }
943 });
Siva Velusamy537421b2012-09-14 14:45:02 -0700944 }
945
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200946 // User info. Trigger first load.
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200947 mKeyguardStatusBar.setUserInfoController(mUserInfoController);
Adrian Roosffc90972015-06-09 18:09:49 -0700948 mKeyguardStatusBar.setUserSwitcherController(mUserSwitcherController);
Jorim Jaggi3d878be2014-05-10 03:22:32 +0200949 mUserInfoController.reloadUserInfo();
950
Jorim Jaggi708f7722014-08-20 17:30:38 +0200951 ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
952 mBatteryController);
Jorim Jaggi4538027d2014-07-30 15:43:13 +0200953 mKeyguardStatusBar.setBatteryController(mBatteryController);
Jorim Jaggi853b0702014-07-05 04:31:14 +0200954
Adrian Roos7bb38a92016-07-21 11:44:01 -0700955 mReportRejectedTouch = mStatusBarWindow.findViewById(R.id.report_rejected_touch);
956 if (mReportRejectedTouch != null) {
957 updateReportRejectedTouchVisibility();
958 mReportRejectedTouch.setOnClickListener(v -> {
959 Uri session = mFalsingManager.reportRejectedTouch();
960 if (session == null) { return; }
961
962 StringWriter message = new StringWriter();
963 message.write("Build info: ");
964 message.write(SystemProperties.get("ro.build.description"));
965 message.write("\nSerial number: ");
966 message.write(SystemProperties.get("ro.serialno"));
967 message.write("\n");
968
969 PrintWriter falsingPw = new PrintWriter(message);
970 FalsingLog.dump(falsingPw);
971 falsingPw.flush();
972
973 startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
974 .setType("*/*")
975 .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
976 .putExtra(Intent.EXTRA_STREAM, session)
977 .putExtra(Intent.EXTRA_TEXT, message.toString()),
978 "Share rejected touch report")
979 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
980 true /* onlyProvisioned */, true /* dismissShade */);
981 });
982 }
983
984
John Spurlock56d007b2013-10-28 18:40:56 -0400985 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
986 mBroadcastReceiver.onReceive(mContext,
987 new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
Selim Cinek372d1bd2015-08-14 13:19:37 -0700988 mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
989 "GestureWakeLock");
Selim Cinek69ff8af2015-08-25 19:03:48 -0700990 mVibrator = mContext.getSystemService(Vibrator.class);
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -0700991
Joe Onorato808182d2010-07-09 18:52:06 -0400992 // receive broadcasts
993 IntentFilter filter = new IntentFilter();
Joe Onorato808182d2010-07-09 18:52:06 -0400994 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
995 filter.addAction(Intent.ACTION_SCREEN_OFF);
Daniel Sandler7f3cf952012-08-31 14:57:09 -0400996 filter.addAction(Intent.ACTION_SCREEN_ON);
Kenny Guy44fc65f2014-11-28 22:18:14 +0000997 context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400998
Adrian Roos8e3e8362015-07-16 19:42:22 -0700999 IntentFilter demoFilter = new IntentFilter();
1000 if (DEBUG_MEDIA_FAKE_ARTWORK) {
1001 demoFilter.addAction(ACTION_FAKE_ARTWORK);
1002 }
1003 demoFilter.addAction(ACTION_DEMO);
1004 context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
1005 android.Manifest.permission.DUMP, null);
1006
John Spurlock919adac2012-10-02 16:41:12 -04001007 // listen for USER_SETUP_COMPLETE setting (per-user)
1008 resetUserSetupObserver();
1009
Chris Craik2507c342015-05-04 14:36:49 -07001010 // disable profiling bars, since they overlap and clutter the output on app windows
1011 ThreadedRenderer.overrideProperty("disableProfileBars", "true");
1012
1013 // Private API call to make the shadows look better for Recents
1014 ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
1015
Daniel Sandlera310af82012-04-24 01:20:13 -04001016 return mStatusBarView;
Joe Onorato808182d2010-07-09 18:52:06 -04001017 }
1018
Adrian Roos316bf542016-08-23 17:53:07 +02001019 private void initEmergencyCryptkeeperText() {
1020 View emergencyViewStub = mStatusBarWindow.findViewById(R.id.emergency_cryptkeeper_text);
1021 if (mNetworkController.hasEmergencyCryptKeeperText()) {
1022 if (emergencyViewStub != null) {
1023 ((ViewStub) emergencyViewStub).inflate();
1024 }
1025 mNetworkController.addSignalCallback(new NetworkController.SignalCallback() {
1026 @Override
1027 public void setIsAirplaneMode(NetworkController.IconState icon) {
1028 recomputeDisableFlags(true /* animate */);
1029 }
1030 });
1031 } else if (emergencyViewStub != null) {
1032 ViewGroup parent = (ViewGroup) emergencyViewStub.getParent();
1033 parent.removeView(emergencyViewStub);
1034 }
1035 }
1036
Anthony Chenda62fdcd52016-04-06 16:15:14 -07001037 protected BatteryController createBatteryController() {
1038 return new BatteryControllerImpl(mContext);
1039 }
1040
Selim Cinek3e7592d2016-04-11 09:35:54 +08001041 private void inflateOverflowContainer() {
1042 mKeyguardIconOverflowContainer =
1043 (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
1044 R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
1045 mKeyguardIconOverflowContainer.setOnActivatedListener(this);
1046 mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
1047 mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
1048 }
1049
Selim Cinek01af3342016-02-09 19:25:31 -08001050 @Override
Selim Cinek3e7592d2016-04-11 09:35:54 +08001051 protected void onDensityOrFontScaleChanged() {
1052 super.onDensityOrFontScaleChanged();
1053 mScrimController.onDensityOrFontScaleChanged();
1054 mStatusBarView.onDensityOrFontScaleChanged();
Adrian Roosd390b892016-05-05 10:50:49 -04001055 if (mBrightnessMirrorController != null) {
1056 mBrightnessMirrorController.onDensityOrFontScaleChanged();
1057 }
Selim Cinek3e7592d2016-04-11 09:35:54 +08001058 inflateSignalClusters();
1059 mIconController.onDensityOrFontScaleChanged();
Selim Cinek01af3342016-02-09 19:25:31 -08001060 inflateDismissView();
1061 updateClearAll();
1062 inflateEmptyShadeView();
1063 updateEmptyShadeView();
Selim Cinek3e7592d2016-04-11 09:35:54 +08001064 inflateOverflowContainer();
Selim Cinekaa8bbf12016-05-04 14:13:20 -07001065 mStatusBarKeyguardViewManager.onDensityOrFontScaleChanged();
Adrian Roosd390b892016-05-05 10:50:49 -04001066 mUserInfoController.onDensityOrFontScaleChanged();
1067 if (mUserSwitcherController != null) {
1068 mUserSwitcherController.onDensityOrFontScaleChanged();
1069 }
1070 if (mKeyguardUserSwitcher != null) {
1071 mKeyguardUserSwitcher.onDensityOrFontScaleChanged();
1072 }
Selim Cinek3e7592d2016-04-11 09:35:54 +08001073 }
1074
1075 private void inflateSignalClusters() {
1076 SignalClusterView signalClusterView = reinflateSignalCluster(mStatusBarView);
1077 mIconController.setSignalCluster(signalClusterView);
Selim Cinek6ebba592016-05-31 15:28:28 -07001078 reinflateSignalCluster(mKeyguardStatusBar);
Selim Cinek3e7592d2016-04-11 09:35:54 +08001079 }
1080
1081 private SignalClusterView reinflateSignalCluster(View view) {
1082 SignalClusterView signalCluster =
1083 (SignalClusterView) view.findViewById(R.id.signal_cluster);
1084 if (signalCluster != null) {
1085 ViewParent parent = signalCluster.getParent();
1086 if (parent instanceof ViewGroup) {
1087 ViewGroup viewParent = (ViewGroup) parent;
1088 int index = viewParent.indexOfChild(signalCluster);
1089 viewParent.removeView(signalCluster);
1090 SignalClusterView newCluster = (SignalClusterView) LayoutInflater.from(mContext)
1091 .inflate(R.layout.signal_cluster_view, viewParent, false);
1092 ViewGroup.MarginLayoutParams layoutParams =
1093 (ViewGroup.MarginLayoutParams) viewParent.getLayoutParams();
1094 layoutParams.setMarginsRelative(
1095 mContext.getResources().getDimensionPixelSize(
1096 R.dimen.signal_cluster_margin_start),
1097 0, 0, 0);
1098 newCluster.setLayoutParams(layoutParams);
1099 newCluster.setSecurityController(mSecurityController);
1100 newCluster.setNetworkController(mNetworkController);
1101 viewParent.addView(newCluster, index);
1102 return newCluster;
1103 }
1104 return signalCluster;
1105 }
1106 return null;
Selim Cinek01af3342016-02-09 19:25:31 -08001107 }
1108
1109 private void inflateEmptyShadeView() {
1110 mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
1111 R.layout.status_bar_no_notifications, mStackScroller, false);
1112 mStackScroller.setEmptyShadeView(mEmptyShadeView);
1113 }
1114
1115 private void inflateDismissView() {
1116 mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
1117 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
1118 mDismissView.setOnButtonClickListener(new View.OnClickListener() {
1119 @Override
1120 public void onClick(View v) {
1121 MetricsLogger.action(mContext, MetricsEvent.ACTION_DISMISS_ALL_NOTES);
1122 clearAllNotifications();
1123 }
1124 });
1125 mStackScroller.setDismissView(mDismissView);
1126 }
1127
Rakesh Iyer2790a372016-01-22 15:33:39 -08001128 protected void createUserSwitcher() {
1129 mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
1130 (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
1131 mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
1132 }
1133
Xiaohui Chend839d1a2016-01-21 13:05:02 -08001134 protected void inflateStatusBarWindow(Context context) {
1135 mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
1136 R.layout.super_status_bar, null);
1137 }
1138
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001139 protected void createNavigationBarView(Context context) {
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001140 inflateNavigationBarView(context);
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001141 mNavigationBarView.setDisabledFlags(mDisabled1);
1142 mNavigationBarView.setComponents(mRecents, getComponent(Divider.class));
1143 mNavigationBarView.setOnVerticalChangedListener(
1144 new NavigationBarView.OnVerticalChangedListener() {
1145 @Override
1146 public void onVerticalChanged(boolean isVertical) {
1147 if (mAssistManager != null) {
1148 mAssistManager.onConfigurationChanged();
1149 }
1150 mNotificationPanel.setQsScrimEnabled(!isVertical);
1151 }
1152 });
1153 mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
1154 @Override
1155 public boolean onTouch(View v, MotionEvent event) {
1156 checkUserAutohide(v, event);
1157 return false;
1158 }});
1159 }
1160
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001161 protected void inflateNavigationBarView(Context context) {
Jason Monk4f878ef2016-01-23 14:37:38 -05001162 mNavigationBarView = (NavigationBarView) View.inflate(
1163 context, R.layout.navigation_bar, null);
Xiaohui Chen8bdcd1f2016-01-19 13:52:07 -08001164 }
1165
1166 protected void initSignalCluster(View containerView) {
Xiaohui Chen10942302015-12-16 16:38:13 -08001167 SignalClusterView signalCluster =
1168 (SignalClusterView) containerView.findViewById(R.id.signal_cluster);
1169 if (signalCluster != null) {
Xiaohui Chen10942302015-12-16 16:38:13 -08001170 signalCluster.setSecurityController(mSecurityController);
1171 signalCluster.setNetworkController(mNetworkController);
1172 }
1173 }
1174
Muyuan Lic510b5e2016-03-09 17:15:05 -08001175 public void clearAllNotifications() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001176
1177 // animate-swipe all dismissable notifications, then animate the shade closed
1178 int numChildren = mStackScroller.getChildCount();
1179
1180 final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
1181 for (int i = 0; i < numChildren; i++) {
1182 final View child = mStackScroller.getChildAt(i);
Selim Cinekb5605e52015-02-20 18:21:41 +01001183 if (child instanceof ExpandableNotificationRow) {
1184 if (mStackScroller.canChildBeDismissed(child)) {
1185 if (child.getVisibility() == View.VISIBLE) {
1186 viewsToHide.add(child);
1187 }
1188 }
1189 ExpandableNotificationRow row = (ExpandableNotificationRow) child;
1190 List<ExpandableNotificationRow> children = row.getNotificationChildren();
1191 if (row.areChildrenExpanded() && children != null) {
1192 for (ExpandableNotificationRow childRow : children) {
1193 if (childRow.getVisibility() == View.VISIBLE) {
1194 viewsToHide.add(childRow);
1195 }
1196 }
Dan Sandlereceda3d2014-07-21 15:35:01 -04001197 }
1198 }
1199 }
1200 if (viewsToHide.isEmpty()) {
1201 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1202 return;
1203 }
1204
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001205 addPostCollapseAction(new Runnable() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001206 @Override
1207 public void run() {
Selim Cinek9c17b772015-07-07 20:37:09 -07001208 mStackScroller.setDismissAllInProgress(false);
Dan Sandlereceda3d2014-07-21 15:35:01 -04001209 try {
1210 mBarService.onClearAllNotifications(mCurrentUserId);
1211 } catch (Exception ex) { }
1212 }
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001213 });
Dan Sandlereceda3d2014-07-21 15:35:01 -04001214
1215 performDismissAllAnimations(viewsToHide);
1216
1217 }
1218
1219 private void performDismissAllAnimations(ArrayList<View> hideAnimatedList) {
1220 Runnable animationFinishAction = new Runnable() {
1221 @Override
1222 public void run() {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001223 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
1224 }
1225 };
1226
1227 // let's disable our normal animations
1228 mStackScroller.setDismissAllInProgress(true);
1229
1230 // Decrease the delay for every row we animate to give the sense of
1231 // accelerating the swipes
1232 int rowDelayDecrement = 10;
1233 int currentDelay = 140;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001234 int totalDelay = 180;
Dan Sandlereceda3d2014-07-21 15:35:01 -04001235 int numItems = hideAnimatedList.size();
Selim Cinek7d5f3742014-11-07 18:07:49 +01001236 for (int i = numItems - 1; i >= 0; i--) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001237 View view = hideAnimatedList.get(i);
1238 Runnable endRunnable = null;
Selim Cinek7d5f3742014-11-07 18:07:49 +01001239 if (i == 0) {
Dan Sandlereceda3d2014-07-21 15:35:01 -04001240 endRunnable = animationFinishAction;
1241 }
1242 mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
1243 currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
1244 totalDelay += currentDelay;
1245 }
1246 }
1247
John Spurlockae641c92014-06-30 18:11:40 -04001248 @Override
1249 protected void setZenMode(int mode) {
1250 super.setZenMode(mode);
1251 if (mIconPolicy != null) {
1252 mIconPolicy.setZenMode(mode);
1253 }
1254 }
1255
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001256 protected void startKeyguard() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001257 Trace.beginSection("PhoneStatusBar#startKeyguard");
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001258 KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001259 mFingerprintUnlockController = new FingerprintUnlockController(mContext,
1260 mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator,
1261 mScrimController, this);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001262 mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001263 getBouncerContainer(), mStatusBarWindowManager, mScrimController,
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001264 mFingerprintUnlockController);
Selim Cinekcfafe4e2015-08-11 14:58:44 -07001265 mKeyguardIndicationController.setStatusBarKeyguardViewManager(
1266 mStatusBarKeyguardViewManager);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07001267 mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
Nicolas Prevot1dbbe7d2016-05-17 12:52:54 +01001268 mIconPolicy.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
Adrian Roosd28ccd72016-01-06 15:23:14 +01001269 mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
Adrian Roosc0a579e2016-03-30 16:43:58 -07001270
Adrian Roos18d099a2016-05-19 15:28:18 -07001271 mRemoteInputController.addCallback(new RemoteInputController.Callback() {
1272 @Override
1273 public void onRemoteInputSent(Entry entry) {
1274 if (FORCE_REMOTE_INPUT_HISTORY && mKeysKeptForRemoteInput.contains(entry.key)) {
1275 removeNotification(entry.key, null);
1276 } else if (mRemoteInputEntriesToRemoveOnCollapse.contains(entry)) {
1277 // We're currently holding onto this notification, but from the apps point of
1278 // view it is already canceled, so we'll need to cancel it on the apps behalf
1279 // after sending - unless the app posts an update in the mean time, so wait a
1280 // bit.
1281 mHandler.postDelayed(() -> {
1282 if (mRemoteInputEntriesToRemoveOnCollapse.remove(entry)) {
1283 removeNotification(entry.key, null);
1284 }
1285 }, REMOTE_INPUT_KEPT_ENTRY_AUTO_CANCEL_DELAY);
Adrian Roosc0a579e2016-03-30 16:43:58 -07001286 }
Adrian Roos18d099a2016-05-19 15:28:18 -07001287 }
1288 });
Adrian Roosc0a579e2016-03-30 16:43:58 -07001289
Jorim Jaggi03c701e2014-04-02 12:39:51 +02001290 mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
Jorim Jaggi86905582016-02-09 21:36:09 -08001291 mLightStatusBarController.setFingerprintUnlockController(mFingerprintUnlockController);
Nick Desaulniers1d396752016-07-25 15:05:33 -07001292 Trace.endSection();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001293 }
1294
Michael Jurka7f2668c2012-03-27 07:49:52 -07001295 @Override
Michael Jurkacb2522c2012-04-13 09:32:47 -07001296 protected View getStatusBarView() {
1297 return mStatusBarView;
1298 }
1299
Jorim Jaggi0a27be82014-06-11 03:22:39 +02001300 public StatusBarWindowView getStatusBarWindow() {
1301 return mStatusBarWindow;
1302 }
1303
Xiyuan Xia1b30f792016-01-06 08:50:30 -08001304 protected ViewGroup getBouncerContainer() {
1305 return mStatusBarWindow;
1306 }
1307
Joe Onoratodc100302011-01-11 17:07:41 -08001308 public int getStatusBarHeight() {
Daniel Sandlera310af82012-04-24 01:20:13 -04001309 if (mNaturalBarHeight < 0) {
1310 final Resources res = mContext.getResources();
Jim Millera073e572012-05-23 17:03:27 -07001311 mNaturalBarHeight =
Daniel Sandlera310af82012-04-24 01:20:13 -04001312 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
1313 }
1314 return mNaturalBarHeight;
Joe Onoratodc100302011-01-11 17:07:41 -08001315 }
1316
Daniel Sandler5c8da942011-06-28 00:29:04 -04001317 private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
Jim Miller07e03842016-06-22 15:18:13 -07001318 @Override
Daniel Sandler5c8da942011-06-28 00:29:04 -04001319 public void onClick(View v) {
John Spurlockc8b46ca2013-04-08 12:59:26 -04001320 awakenDreams();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001321 toggleRecentApps();
1322 }
1323 };
Chris Wren0c8275b2012-05-08 13:36:48 -04001324
Jorim Jaggi75b25972015-10-21 14:51:10 +02001325 private View.OnLongClickListener mLongPressBackListener = new View.OnLongClickListener() {
Jason Monk62515be2014-05-21 16:06:19 -04001326 @Override
1327 public boolean onLongClick(View v) {
Jorim Jaggi75b25972015-10-21 14:51:10 +02001328 return handleLongPressBack();
1329 }
1330 };
1331
1332 private View.OnLongClickListener mRecentsLongClickListener = new View.OnLongClickListener() {
1333
1334 @Override
1335 public boolean onLongClick(View v) {
Jorim Jaggi19cf2972016-04-07 23:26:10 -07001336 if (mRecents == null || !ActivityManager.supportsMultiWindow()
1337 || !getComponent(Divider.class).getView().getSnapAlgorithm()
1338 .isSplitScreenFeasible()) {
Phil Weaver315c34e2016-02-19 15:12:29 -08001339 return false;
1340 }
Winsonc694a502016-03-10 16:35:03 -08001341
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001342 toggleSplitScreenMode(MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS,
1343 MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
1344 return true;
Jason Monk62515be2014-05-21 16:06:19 -04001345 }
1346 };
1347
Phil Weaver315c34e2016-02-19 15:12:29 -08001348 @Override
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001349 protected void toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
Phil Weaver315c34e2016-02-19 15:12:29 -08001350 if (mRecents == null) {
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001351 return;
Phil Weaver315c34e2016-02-19 15:12:29 -08001352 }
1353 int dockSide = WindowManagerProxy.getInstance().getDockSide();
1354 if (dockSide == WindowManager.DOCKED_INVALID) {
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001355 mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
1356 ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null, metricsDockAction);
Phil Weaver315c34e2016-02-19 15:12:29 -08001357 } else {
1358 EventBus.getDefault().send(new UndockingTaskEvent());
Jorim Jaggi29379ec2016-04-11 23:43:42 -07001359 if (metricsUndockAction != -1) {
1360 MetricsLogger.action(mContext, metricsUndockAction);
1361 }
Phil Weaver315c34e2016-02-19 15:12:29 -08001362 }
1363 }
1364
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001365 private final View.OnLongClickListener mLongPressHomeListener
1366 = new View.OnLongClickListener() {
1367 @Override
1368 public boolean onLongClick(View v) {
1369 if (shouldDisableNavbarGestures()) {
1370 return false;
1371 }
Chris Wrenf6e9228b2016-01-26 18:04:35 -05001372 MetricsLogger.action(mContext, MetricsEvent.ACTION_ASSIST_LONG_PRESS);
Jorim Jaggi165ce062015-07-06 16:18:11 -07001373 mAssistManager.startAssist(new Bundle() /* args */);
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001374 awakenDreams();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001375 if (mNavigationBarView != null) {
Xiyuan Xiaee7dd052015-05-15 09:46:27 -07001376 mNavigationBarView.abortCurrentGesture();
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001377 }
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001378 return true;
Jim Miller9a720f52012-05-30 03:19:43 -07001379 }
1380 };
1381
Jorim Jaggi7e6571f2015-06-25 11:52:48 -07001382 private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
Selim Cinek64be7722016-07-22 13:28:16 -07001383 public boolean mBlockedThisTouch;
1384
Jim Miller07e03842016-06-22 15:18:13 -07001385 @Override
Jim Millere898ac52012-04-06 17:10:57 -07001386 public boolean onTouch(View v, MotionEvent event) {
Selim Cinek64be7722016-07-22 13:28:16 -07001387 if (mBlockedThisTouch && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
1388 return true;
1389 }
1390 // If an incoming call is ringing, HOME is totally disabled.
1391 // (The user is already on the InCallUI at this point,
1392 // and his ONLY options are to answer or reject the call.)
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001393 switch (event.getAction()) {
Selim Cinek64be7722016-07-22 13:28:16 -07001394 case MotionEvent.ACTION_DOWN:
1395 mBlockedThisTouch = false;
1396 TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
1397 if (telecomManager != null && telecomManager.isRinging()) {
1398 if (mStatusBarKeyguardViewManager.isShowing()) {
1399 Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
1400 "No heads up");
1401 mBlockedThisTouch = true;
1402 return true;
1403 }
1404 }
1405 break;
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001406 case MotionEvent.ACTION_UP:
1407 case MotionEvent.ACTION_CANCEL:
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07001408 awakenDreams();
1409 break;
1410 }
1411 return false;
Jim Millere898ac52012-04-06 17:10:57 -07001412 }
1413 };
Daniel Sandler5c8da942011-06-28 00:29:04 -04001414
Daniel Sandlera2fbe532012-08-10 01:19:03 -04001415 private void awakenDreams() {
1416 if (mDreamManager != null) {
1417 try {
1418 mDreamManager.awaken();
1419 } catch (RemoteException e) {
1420 // fine, stay asleep then
1421 }
1422 }
1423 }
1424
Michael Jurka412cba82011-10-17 09:05:00 -07001425 private void prepareNavigationBarView() {
1426 mNavigationBarView.reorient();
1427
Jason Monka2081822016-01-18 14:41:03 -05001428 ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
1429 recentsButton.setOnClickListener(mRecentsClickListener);
1430 recentsButton.setOnTouchListener(mRecentsPreloadOnTouchListener);
1431 recentsButton.setLongClickable(true);
1432 recentsButton.setOnLongClickListener(mRecentsLongClickListener);
Anthony Chenada13042016-01-19 16:57:20 -08001433
Jason Monka2081822016-01-18 14:41:03 -05001434 ButtonDispatcher backButton = mNavigationBarView.getBackButton();
1435 backButton.setLongClickable(true);
1436 backButton.setOnLongClickListener(mLongPressBackListener);
Anthony Chenada13042016-01-19 16:57:20 -08001437
Jason Monka2081822016-01-18 14:41:03 -05001438 ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
1439 homeButton.setOnTouchListener(mHomeActionListener);
1440 homeButton.setOnLongClickListener(mLongPressHomeListener);
Anthony Chenada13042016-01-19 16:57:20 -08001441
Selim Cineke70d6532015-04-24 16:46:13 -07001442 mAssistManager.onConfigurationChanged();
Michael Jurka412cba82011-10-17 09:05:00 -07001443 }
1444
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001445 // For small-screen devices (read: phones) that lack hardware navigation buttons
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001446 protected void addNavigationBar() {
John Spurlockcd686b52013-06-05 10:13:46 -04001447 if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
Daniel Sandler0129b312011-05-11 11:54:11 -04001448 if (mNavigationBarView == null) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001449
Adrian Roosa98b32c2016-08-11 10:41:08 -07001450 try {
1451 WindowManagerGlobal.getWindowManagerService()
1452 .watchRotation(new IRotationWatcher.Stub() {
1453 @Override
1454 public void onRotationChanged(int rotation) throws RemoteException {
1455 // We need this to be scheduled as early as possible to beat the redrawing of
1456 // window in response to the orientation change.
1457 Message msg = Message.obtain(mHandler, () -> {
1458 if (mNavigationBarView != null
1459 && mNavigationBarView.needsReorient(rotation)) {
1460 repositionNavigationBar();
1461 }
1462 });
1463 msg.setAsynchronous(true);
1464 mHandler.sendMessageAtFrontOfQueue(msg);
1465 }
1466 });
1467 } catch (RemoteException e) {
1468 throw e.rethrowFromSystemServer();
1469 }
1470
Michael Jurka412cba82011-10-17 09:05:00 -07001471 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001472
Jeff Brown98365d72012-08-19 20:30:52 -07001473 mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001474 }
1475
Victor Chanecdb8b02016-01-07 18:32:43 -08001476 protected void repositionNavigationBar() {
John Spurlock56d007b2013-10-28 18:40:56 -04001477 if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
Jim Miller17dfec72011-07-08 19:09:55 -07001478
Michael Jurka412cba82011-10-17 09:05:00 -07001479 prepareNavigationBarView();
Daniel Sandler5c8da942011-06-28 00:29:04 -04001480
Jorim Jaggi90dfb892016-07-25 15:57:36 +02001481 mWindowManager.updateViewLayout(mNavigationBarView, mNavigationBarView.getLayoutParams());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001482 }
1483
John Spurlock1bbd49d2012-10-19 11:09:32 -04001484 private void notifyNavigationBarScreenOn(boolean screenOn) {
1485 if (mNavigationBarView == null) return;
1486 mNavigationBarView.notifyScreenOn(screenOn);
1487 }
1488
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001489 private WindowManager.LayoutParams getNavigationBarLayoutParams() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001490 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001491 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001492 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
1493 0
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001494 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1495 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Dianne Hackborndf89e652011-10-06 22:35:11 -07001496 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
Daniel Sandlerc26185b2012-08-29 15:49:53 -04001497 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
Jorim Jaggic59a23f2016-05-24 14:53:36 -07001498 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
1499 | WindowManager.LayoutParams.FLAG_SLIPPERY,
John Spurlockad3e6cb2013-04-30 08:47:43 -04001500 PixelFormat.TRANSLUCENT);
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001501 // this will allow the navbar to run in an overlay on devices that support this
Jeff Brown98365d72012-08-19 20:30:52 -07001502 if (ActivityManager.isHighEndGfx()) {
Daniel Sandlerc638c1e2011-08-24 16:19:23 -07001503 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
1504 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001505
1506 lp.setTitle("NavigationBar");
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001507 lp.windowAnimations = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001508 return lp;
1509 }
1510
Jason Monk07473ce2016-01-05 14:59:19 -05001511 @Override
1512 public void setIcon(String slot, StatusBarIcon icon) {
1513 mIconController.setIcon(slot, icon);
Joe Onorato808182d2010-07-09 18:52:06 -04001514 }
1515
Jason Monk07473ce2016-01-05 14:59:19 -05001516 @Override
1517 public void removeIcon(String slot) {
1518 mIconController.removeIcon(slot);
Joe Onorato808182d2010-07-09 18:52:06 -04001519 }
1520
John Spurlockbf20eab2014-04-09 16:40:39 -04001521 public UserHandle getCurrentUserHandle() {
1522 return new UserHandle(mCurrentUserId);
1523 }
1524
Christoph Studer71f18fd2014-05-20 17:02:04 +02001525 @Override
Selim Cinek379ff8f2015-02-20 17:03:16 +01001526 public void addNotification(StatusBarNotification notification, RankingMap ranking,
1527 Entry oldEntry) {
Chris Wrenaaa58d12014-06-03 14:29:12 -04001528 if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
Chris Wrend4db6cb2013-08-07 16:05:23 -04001529
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001530 mNotificationData.updateRanking(ranking);
Selim Cinek8d490d42015-04-10 00:05:50 -07001531 Entry shadeEntry = createNotificationViews(notification);
Chris Wrena4ef6202014-06-09 18:07:30 -04001532 if (shadeEntry == null) {
1533 return;
1534 }
Adrian Roosf6967e062016-06-21 16:12:48 -07001535 boolean isHeadsUped = shouldPeek(shadeEntry);
Selim Cinek31d9ef72015-04-15 19:29:49 -07001536 if (isHeadsUped) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001537 mHeadsUpManager.showNotification(shadeEntry);
Amith Yamasanif47e51e2015-04-17 10:02:15 -07001538 // Mark as seen immediately
1539 setNotificationShown(notification);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001540 }
Chris Wrena4ef6202014-06-09 18:07:30 -04001541
Selim Cinek31d9ef72015-04-15 19:29:49 -07001542 if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
Julia Reynoldsd5607292016-02-05 15:25:58 -05001543 if (shouldSuppressFullScreenIntent(notification.getKey())) {
Julia Reynolds61721582016-01-05 08:35:25 -05001544 if (DEBUG) {
1545 Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + notification.getKey());
1546 }
Julia Reynoldsf0f629f2016-02-25 09:34:04 -05001547 } else if (mNotificationData.getImportance(notification.getKey())
1548 < NotificationListenerService.Ranking.IMPORTANCE_MAX) {
1549 if (DEBUG) {
1550 Log.d(TAG, "No Fullscreen intent: not important enough: "
1551 + notification.getKey());
1552 }
Julia Reynolds61721582016-01-05 08:35:25 -05001553 } else {
1554 // Stop screensaver if the notification has a full-screen intent.
1555 // (like an incoming phone call)
1556 awakenDreams();
Daniel Sandlerc9ce0ab2012-09-04 13:27:09 -04001557
Julia Reynolds61721582016-01-05 08:35:25 -05001558 // not immersive & a full-screen alert should be shown
1559 if (DEBUG)
1560 Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
1561 try {
1562 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
1563 notification.getKey());
1564 notification.getNotification().fullScreenIntent.send();
1565 shadeEntry.notifyFullScreenIntentLaunched();
1566 MetricsLogger.count(mContext, "note_fullscreen", 1);
1567 } catch (PendingIntent.CanceledException e) {
1568 }
John Spurlockbf20eab2014-04-09 16:40:39 -04001569 }
Joe Onorato808182d2010-07-09 18:52:06 -04001570 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001571 addNotificationViews(shadeEntry, ranking);
Joe Onorato808182d2010-07-09 18:52:06 -04001572 // Recalculate the position of the sliding windows and the titles.
1573 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001574 }
1575
Julia Reynoldsd5607292016-02-05 15:25:58 -05001576 private boolean shouldSuppressFullScreenIntent(String key) {
Dan Sandlerdc34df52016-04-07 21:04:46 -04001577 if (isDeviceInVrMode()) {
1578 return true;
1579 }
1580
Julia Reynolds0971cb02016-01-26 17:00:22 -05001581 if (mPowerManager.isInteractive()) {
Julia Reynolds0971cb02016-01-26 17:00:22 -05001582 return mNotificationData.shouldSuppressScreenOn(key);
Julia Reynoldsd5607292016-02-05 15:25:58 -05001583 } else {
1584 return mNotificationData.shouldSuppressScreenOff(key);
Julia Reynolds0971cb02016-01-26 17:00:22 -05001585 }
1586 }
1587
Chris Wren51c75102013-07-16 20:49:17 -04001588 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001589 protected void updateNotificationRanking(RankingMap ranking) {
Chris Wren333a61c2014-05-28 16:40:57 -04001590 mNotificationData.updateRanking(ranking);
Chris Wren333a61c2014-05-28 16:40:57 -04001591 updateNotifications();
1592 }
1593
1594 @Override
Christoph Studere71fefc2014-06-24 16:16:49 +02001595 public void removeNotification(String key, RankingMap ranking) {
Selim Cinek684a4422015-04-15 16:18:39 -07001596 boolean deferRemoval = false;
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001597 if (mHeadsUpManager.isHeadsUp(key)) {
Adrian Roosc721fcc52016-04-29 11:28:37 -07001598 // A cancel() in repsonse to a remote input shouldn't be delayed, as it makes the
1599 // sending look longer than it takes.
1600 boolean ignoreEarliestRemovalTime = mRemoteInputController.isSpinning(key)
1601 && !FORCE_REMOTE_INPUT_HISTORY;
1602 deferRemoval = !mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
Chris Wrena4ef6202014-06-09 18:07:30 -04001603 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001604 if (key.equals(mMediaNotificationKey)) {
1605 clearCurrentMediaNotification();
Adrian Roos52738322016-01-29 08:49:21 -08001606 updateMediaMetaData(true, true);
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04001607 }
Adrian Roosc0a579e2016-03-30 16:43:58 -07001608 if (FORCE_REMOTE_INPUT_HISTORY && mRemoteInputController.isSpinning(key)) {
1609 Entry entry = mNotificationData.get(key);
1610 StatusBarNotification sbn = entry.notification;
1611
1612 Notification.Builder b = Notification.Builder
1613 .recoverBuilder(mContext, sbn.getNotification().clone());
1614 CharSequence[] oldHistory = sbn.getNotification().extras
1615 .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
1616 CharSequence[] newHistory;
1617 if (oldHistory == null) {
1618 newHistory = new CharSequence[1];
1619 } else {
1620 newHistory = new CharSequence[oldHistory.length + 1];
1621 for (int i = 0; i < oldHistory.length; i++) {
1622 newHistory[i + 1] = oldHistory[i];
1623 }
1624 }
1625 newHistory[0] = String.valueOf(entry.remoteInputText);
1626 b.setRemoteInputHistory(newHistory);
1627
1628 Notification newNotification = b.build();
1629
1630 // Undo any compatibility view inflation
1631 newNotification.contentView = sbn.getNotification().contentView;
1632 newNotification.bigContentView = sbn.getNotification().bigContentView;
1633 newNotification.headsUpContentView = sbn.getNotification().headsUpContentView;
1634
1635 StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(),
1636 sbn.getOpPkg(),
1637 sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
1638 0, newNotification, sbn.getUser(), sbn.getPostTime());
1639
1640 updateNotification(newSbn, null);
1641 mKeysKeptForRemoteInput.add(entry.key);
1642 return;
1643 }
Selim Cinek684a4422015-04-15 16:18:39 -07001644 if (deferRemoval) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07001645 mLatestRankingMap = ranking;
1646 mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
1647 return;
1648 }
Selim Cineka5703182016-05-11 21:23:16 -04001649 Entry entry = mNotificationData.get(key);
Adrian Roos18d099a2016-05-19 15:28:18 -07001650
Adrian Roos9550f2e2016-08-23 18:23:01 +02001651 if (entry != null && mRemoteInputController.isRemoteInputActive(entry)
1652 && (entry.row != null && !entry.row.isDismissed())) {
Adrian Roos18d099a2016-05-19 15:28:18 -07001653 mLatestRankingMap = ranking;
1654 mRemoteInputEntriesToRemoveOnCollapse.add(entry);
1655 return;
1656 }
1657
Selim Cineka5703182016-05-11 21:23:16 -04001658 if (entry != null && entry.row != null) {
Adrian Roosd009ab12016-05-20 17:58:53 -07001659 entry.row.setRemoved();
Selim Cineka5703182016-05-11 21:23:16 -04001660 }
Selim Cinek3f19f602016-05-02 18:01:56 -07001661 // Let's remove the children if this was a summary
1662 handleGroupSummaryRemoved(key, ranking);
Christoph Studer37fe6932014-05-26 13:10:30 +02001663 StatusBarNotification old = removeNotificationViews(key, ranking);
John Spurlockcd686b52013-06-05 10:13:46 -04001664 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
Joe Onorato808182d2010-07-09 18:52:06 -04001665
1666 if (old != null) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001667 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
Jorim Jaggiba94f882014-08-20 19:23:55 +02001668 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001669 if (mState == StatusBarState.SHADE) {
1670 animateCollapsePanels();
Selim Cinek61b350c2016-08-05 14:26:51 -07001671 } else if (mState == StatusBarState.SHADE_LOCKED && !isCollapsing()) {
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02001672 goToKeyguard();
1673 }
Daniel Sandler8cc36e52011-10-17 14:18:46 -04001674 }
Joe Onorato808182d2010-07-09 18:52:06 -04001675 }
Daniel Sandler0761e4c2011-08-11 00:19:49 -04001676 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04001677 }
1678
Selim Cinek3f19f602016-05-02 18:01:56 -07001679 /**
1680 * Ensures that the group children are cancelled immediately when the group summary is cancelled
1681 * instead of waiting for the notification manager to send all cancels. Otherwise this could
1682 * lead to flickers.
1683 *
1684 * This also ensures that the animation looks nice and only consists of a single disappear
1685 * animation instead of multiple.
1686 *
1687 * @param key the key of the notification was removed
1688 * @param ranking the current ranking
1689 */
1690 private void handleGroupSummaryRemoved(String key,
1691 RankingMap ranking) {
1692 Entry entry = mNotificationData.get(key);
1693 if (entry != null && entry.row != null
1694 && entry.row.isSummaryWithChildren()) {
1695 if (entry.notification.getOverrideGroupKey() != null && !entry.row.isDismissed()) {
1696 // We don't want to remove children for autobundled notifications as they are not
1697 // always cancelled. We only remove them if they were dismissed by the user.
1698 return;
1699 }
Selim Cinek3f19f602016-05-02 18:01:56 -07001700 List<ExpandableNotificationRow> notificationChildren =
1701 entry.row.getNotificationChildren();
1702 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>(notificationChildren);
1703 for (int i = 0; i < toRemove.size(); i++) {
1704 toRemove.get(i).setKeepInParent(true);
Selim Cineka5703182016-05-11 21:23:16 -04001705 // we need to set this state earlier as otherwise we might generate some weird
1706 // animations
Adrian Roosd009ab12016-05-20 17:58:53 -07001707 toRemove.get(i).setRemoved();
Selim Cinek3f19f602016-05-02 18:01:56 -07001708 }
1709 for (int i = 0; i < toRemove.size(); i++) {
1710 removeNotification(toRemove.get(i).getStatusBarNotification().getKey(), ranking);
Selim Cinek7103fd42016-05-09 22:22:33 -04001711 // we need to ensure that the view is actually properly removed from the viewstate
1712 // as this won't happen anymore when kept in the parent.
1713 mStackScroller.removeViewStateForView(toRemove.get(i));
Selim Cinek3f19f602016-05-02 18:01:56 -07001714 }
1715 }
1716 }
1717
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001718 @Override
Adrian Roos18d099a2016-05-19 15:28:18 -07001719 protected void performRemoveNotification(StatusBarNotification n, boolean removeView) {
1720 Entry entry = mNotificationData.get(n.getKey());
1721 if (mRemoteInputController.isRemoteInputActive(entry)) {
Adrian Roos7813dd72016-09-23 17:12:17 -07001722 mRemoteInputController.removeRemoteInput(entry, null);
Adrian Roos18d099a2016-05-19 15:28:18 -07001723 }
1724 super.performRemoveNotification(n, removeView);
1725 }
1726
1727 @Override
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001728 protected void refreshLayout(int layoutDirection) {
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001729 if (mNavigationBarView != null) {
1730 mNavigationBarView.setLayoutDirection(layoutDirection);
1731 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -07001732 }
1733
Christoph Studer37fe6932014-05-26 13:10:30 +02001734 private void updateNotificationShade() {
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001735 if (mStackScroller == null) return;
Daniel Sandler26cda272012-05-22 15:44:08 -04001736
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02001737 // Do not modify the notifications during collapse.
1738 if (isCollapsing()) {
1739 addPostCollapseAction(new Runnable() {
1740 @Override
1741 public void run() {
1742 updateNotificationShade();
1743 }
1744 });
1745 return;
1746 }
1747
Christoph Studerc8db24b2014-07-25 17:50:30 +02001748 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
Jorim Jaggif6411742014-08-05 17:10:43 +00001749 ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
Christoph Studerc8db24b2014-07-25 17:50:30 +02001750 final int N = activeNotifications.size();
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001751 for (int i=0; i<N; i++) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001752 Entry ent = activeNotifications.get(i);
1753 int vis = ent.notification.getNotification().visibility;
Kenny Guy3a7c4a52014-03-03 18:24:03 +00001754
Christoph Studerc8db24b2014-07-25 17:50:30 +02001755 // Display public version of the notification if we need to redact.
Jorim Jaggiae441282014-08-01 02:45:18 +02001756 final boolean hideSensitive =
1757 !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId());
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001758 boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE;
1759 boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey());
1760 boolean sensitive = (sensitiveNote && hideSensitive) || sensitivePackage;
1761 boolean showingPublic = sensitive && isLockscreenPublicMode();
Sudheer Shankaf5b850e2016-01-25 19:58:59 +00001762 if (showingPublic) {
1763 updatePublicContentView(ent, ent.notification);
1764 }
Selim Cinek3c76d502016-02-19 15:16:33 -08001765 ent.row.setSensitive(sensitive, hideSensitive);
Dan Sandler1b718782014-07-18 12:43:45 -04001766 if (ent.autoRedacted && ent.legacy) {
Jorim Jaggiae441282014-08-01 02:45:18 +02001767 // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
1768 // for legacy auto redacted notifications.
Dan Sandler1b718782014-07-18 12:43:45 -04001769 if (showingPublic) {
1770 ent.row.setShowingLegacyBackground(false);
1771 } else {
1772 ent.row.setShowingLegacyBackground(true);
1773 }
1774 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001775 if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
1776 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
1777 ent.row.getStatusBarNotification());
1778 List<ExpandableNotificationRow> orderedChildren =
1779 mTmpChildOrderMap.get(summary);
1780 if (orderedChildren == null) {
1781 orderedChildren = new ArrayList<>();
1782 mTmpChildOrderMap.put(summary, orderedChildren);
1783 }
1784 orderedChildren.add(ent.row);
1785 } else {
1786 toShow.add(ent.row);
1787 }
1788
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001789 }
1790
Selim Cinekef5127e2015-12-21 16:55:58 -08001791 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001792 for (int i=0; i< mStackScroller.getChildCount(); i++) {
1793 View child = mStackScroller.getChildAt(i);
Jorim Jaggif6411742014-08-05 17:10:43 +00001794 if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
Selim Cinekef5127e2015-12-21 16:55:58 -08001795 toRemove.add((ExpandableNotificationRow) child);
Joe Onorato808182d2010-07-09 18:52:06 -04001796 }
1797 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001798
Selim Cinekef5127e2015-12-21 16:55:58 -08001799 for (ExpandableNotificationRow remove : toRemove) {
1800 if (mGroupManager.isChildInGroupWithSummary(remove.getStatusBarNotification())) {
1801 // we are only transfering this notification to its parent, don't generate an animation
1802 mStackScroller.setChildTransferInProgress(true);
1803 }
Selim Cinekc1e389d2016-04-07 11:02:57 -07001804 if (remove.isSummaryWithChildren()) {
1805 remove.removeAllChildren();
1806 }
Selim Cinekb6d85eb2014-03-28 20:21:01 +01001807 mStackScroller.removeView(remove);
Selim Cinekef5127e2015-12-21 16:55:58 -08001808 mStackScroller.setChildTransferInProgress(false);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001809 }
Selim Cinek2b542422016-03-04 18:10:37 -08001810
1811 removeNotificationChildren();
1812
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001813 for (int i=0; i<toShow.size(); i++) {
1814 View v = toShow.get(i);
1815 if (v.getParent() == null) {
Christoph Studer37fe6932014-05-26 13:10:30 +02001816 mStackScroller.addView(v);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001817 }
1818 }
Daniel Sandler26cda272012-05-22 15:44:08 -04001819
Selim Cinek2b542422016-03-04 18:10:37 -08001820 addNotificationChildrenAndSort();
1821
Christoph Studer37fe6932014-05-26 13:10:30 +02001822 // So after all this work notifications still aren't sorted correctly.
1823 // Let's do that now by advancing through toShow and mStackScroller in
1824 // lock-step, making sure mStackScroller matches what we see in toShow.
1825 int j = 0;
1826 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1827 View child = mStackScroller.getChildAt(i);
1828 if (!(child instanceof ExpandableNotificationRow)) {
1829 // We don't care about non-notification views.
1830 continue;
1831 }
1832
Selim Cinekb5605e52015-02-20 18:21:41 +01001833 ExpandableNotificationRow targetChild = toShow.get(j);
1834 if (child != targetChild) {
1835 // Oops, wrong notification at this position. Put the right one
1836 // here and advance both lists.
1837 mStackScroller.changeViewPosition(targetChild, i);
Christoph Studer37fe6932014-05-26 13:10:30 +02001838 }
Christoph Studer37fe6932014-05-26 13:10:30 +02001839 j++;
Selim Cinekb5605e52015-02-20 18:21:41 +01001840
Christoph Studer37fe6932014-05-26 13:10:30 +02001841 }
Selim Cinekb5605e52015-02-20 18:21:41 +01001842
Selim Cinekb5605e52015-02-20 18:21:41 +01001843 // clear the map again for the next usage
1844 mTmpChildOrderMap.clear();
1845
Christoph Studer37fe6932014-05-26 13:10:30 +02001846 updateRowStates();
Jorim Jaggif6411742014-08-05 17:10:43 +00001847 updateSpeedbump();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001848 updateClearAll();
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001849 updateEmptyShadeView();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001850
Benjamin Franz27cf1462015-04-23 19:36:42 +01001851 updateQsExpansionEnabled();
1852 mShadeUpdates.check();
1853 }
1854
1855 /**
1856 * Disable QS if device not provisioned.
1857 * If the user switcher is simple then disable QS during setup because
1858 * the user intends to use the lock screen user switcher, QS in not needed.
1859 */
1860 private void updateQsExpansionEnabled() {
Jason Monk3ad242d2014-09-15 11:13:35 -04001861 mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
Adrian Roos2b154a92014-11-17 15:18:39 +01001862 && (mUserSetup || mUserSwitcherController == null
Benjamin Franz27cf1462015-04-23 19:36:42 +01001863 || !mUserSwitcherController.isSimpleUserSwitcher())
Adrian Roos21d2a252015-06-01 13:59:59 -07001864 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
1865 && !ONLY_CORE_APPS);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001866 }
1867
Selim Cinek2b542422016-03-04 18:10:37 -08001868 private void addNotificationChildrenAndSort() {
Selim Cinek322ec7e2016-02-11 14:47:06 -08001869 // Let's now add all notification children which are missing
1870 boolean orderChanged = false;
1871 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1872 View view = mStackScroller.getChildAt(i);
1873 if (!(view instanceof ExpandableNotificationRow)) {
1874 // We don't care about non-notification views.
1875 continue;
1876 }
1877
1878 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1879 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1880 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1881
Selim Cinekb5605e52015-02-20 18:21:41 +01001882 for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
1883 childIndex++) {
1884 ExpandableNotificationRow childView = orderedChildren.get(childIndex);
1885 if (children == null || !children.contains(childView)) {
1886 parent.addChildNotification(childView, childIndex);
1887 mStackScroller.notifyGroupChildAdded(childView);
1888 }
1889 }
1890
1891 // Finally after removing and adding has been beformed we can apply the order.
1892 orderChanged |= parent.applyChildOrder(orderedChildren);
1893 }
1894 if (orderChanged) {
1895 mStackScroller.generateChildOrderChangedEvent();
1896 }
1897 }
1898
Selim Cinek2b542422016-03-04 18:10:37 -08001899 private void removeNotificationChildren() {
1900 // First let's remove all children which don't belong in the parents
1901 ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
1902 for (int i = 0; i < mStackScroller.getChildCount(); i++) {
1903 View view = mStackScroller.getChildAt(i);
1904 if (!(view instanceof ExpandableNotificationRow)) {
1905 // We don't care about non-notification views.
1906 continue;
1907 }
1908
1909 ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
1910 List<ExpandableNotificationRow> children = parent.getNotificationChildren();
1911 List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
1912
1913 if (children != null) {
1914 toRemove.clear();
1915 for (ExpandableNotificationRow childRow : children) {
Selim Cinek3f19f602016-05-02 18:01:56 -07001916 if ((orderedChildren == null
1917 || !orderedChildren.contains(childRow))
1918 && !childRow.keepInParent()) {
Selim Cinek2b542422016-03-04 18:10:37 -08001919 toRemove.add(childRow);
1920 }
1921 }
1922 for (ExpandableNotificationRow remove : toRemove) {
1923 parent.removeChildNotification(remove);
1924 if (mNotificationData.get(remove.getStatusBarNotification().getKey()) == null) {
1925 // We only want to add an animation if the view is completely removed
1926 // otherwise it's just a transfer
Selim Cinekd1395642016-04-28 12:22:42 -07001927 mStackScroller.notifyGroupChildRemoved(remove,
1928 parent.getChildrenContainer());
Selim Cinek2b542422016-03-04 18:10:37 -08001929 }
1930 }
1931 }
1932 }
1933 }
1934
Jason Monk7e53f202016-01-28 10:40:20 -05001935 @Override
1936 public void addQsTile(ComponentName tile) {
1937 mQSPanel.getHost().addTile(tile);
1938 }
1939
1940 @Override
1941 public void remQsTile(ComponentName tile) {
1942 mQSPanel.getHost().removeTile(tile);
1943 }
1944
1945 @Override
1946 public void clickTile(ComponentName tile) {
1947 mQSPanel.clickTile(tile);
1948 }
1949
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001950 private boolean packageHasVisibilityOverride(String key) {
Julia Reynolds26fa8a52016-02-24 08:31:22 -05001951 return mNotificationData.getVisibilityOverride(key) == Notification.VISIBILITY_PRIVATE;
Chris Wren3ad4e3a2014-09-02 17:23:51 -04001952 }
1953
Dan Sandlereceda3d2014-07-21 15:35:01 -04001954 private void updateClearAll() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001955 boolean showDismissView =
1956 mState != StatusBarState.KEYGUARD &&
1957 mNotificationData.hasActiveClearableNotifications();
Dan Sandlereceda3d2014-07-21 15:35:01 -04001958 mStackScroller.updateDismissView(showDismissView);
1959 }
1960
Jorim Jaggia2052ea2014-08-05 16:22:30 +02001961 private void updateEmptyShadeView() {
1962 boolean showEmptyShade =
1963 mState != StatusBarState.KEYGUARD &&
1964 mNotificationData.getActiveNotifications().size() == 0;
1965 mNotificationPanel.setShadeEmpty(showEmptyShade);
1966 }
1967
Jorim Jaggif6411742014-08-05 17:10:43 +00001968 private void updateSpeedbump() {
1969 int speedbumpIndex = -1;
1970 int currentIndex = 0;
Selim Cinek2a739342016-03-17 10:28:55 -07001971 final int N = mStackScroller.getChildCount();
Jorim Jaggif6411742014-08-05 17:10:43 +00001972 for (int i = 0; i < N; i++) {
Selim Cinek2a739342016-03-17 10:28:55 -07001973 View view = mStackScroller.getChildAt(i);
1974 if (view.getVisibility() == View.GONE || !(view instanceof ExpandableNotificationRow)) {
Selim Cinekb5605e52015-02-20 18:21:41 +01001975 continue;
1976 }
Selim Cinek2a739342016-03-17 10:28:55 -07001977 ExpandableNotificationRow row = (ExpandableNotificationRow) view;
1978 if (mNotificationData.isAmbient(row.getStatusBarNotification().getKey())) {
Jorim Jaggif6411742014-08-05 17:10:43 +00001979 speedbumpIndex = currentIndex;
1980 break;
1981 }
1982 currentIndex++;
1983 }
1984 mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
1985 }
1986
Selim Cinekb5605e52015-02-20 18:21:41 +01001987 public static boolean isTopLevelChild(Entry entry) {
1988 return entry.row.getParent() instanceof NotificationStackScrollLayout;
1989 }
1990
Chris Wren0c8275b2012-05-08 13:36:48 -04001991 @Override
Christoph Studer37fe6932014-05-26 13:10:30 +02001992 protected void updateNotifications() {
Christoph Studerc8db24b2014-07-25 17:50:30 +02001993 mNotificationData.filterAndSort();
1994
Christoph Studer37fe6932014-05-26 13:10:30 +02001995 updateNotificationShade();
Jorim Jaggi66ac1332015-01-21 19:22:26 +01001996 mIconController.updateNotificationIcons(mNotificationData);
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04001997 }
1998
Selim Cinekef5127e2015-12-21 16:55:58 -08001999 public void requestNotificationUpdate() {
2000 updateNotifications();
2001 }
2002
Jorim Jaggi54045422014-07-03 18:30:40 +02002003 @Override
Chris Wren0c8275b2012-05-08 13:36:48 -04002004 protected void setAreThereNotifications() {
Daniel Sandler0761e4c2011-08-11 00:19:49 -04002005
Chris Wren6d15a362013-08-20 18:46:29 -04002006 if (SPEW) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002007 final boolean clearable = hasActiveNotifications() &&
2008 mNotificationData.hasActiveClearableNotifications();
2009 Log.d(TAG, "setAreThereNotifications: N=" +
2010 mNotificationData.getActiveNotifications().size() + " any=" +
2011 hasActiveNotifications() + " clearable=" + clearable);
Daniel Sandler0761e4c2011-08-11 00:19:49 -04002012 }
2013
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002014 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
Christoph Studerc8db24b2014-07-25 17:50:30 +02002015 final boolean showDot = hasActiveNotifications() && !areLightsOn();
Daniel Sandlerd7e96862012-04-26 01:10:29 -04002016 if (showDot != (nlo.getAlpha() == 1.0f)) {
2017 if (showDot) {
2018 nlo.setAlpha(0f);
2019 nlo.setVisibility(View.VISIBLE);
2020 }
2021 nlo.animate()
2022 .alpha(showDot?1:0)
2023 .setDuration(showDot?750:250)
2024 .setInterpolator(new AccelerateInterpolator(2.0f))
2025 .setListener(showDot ? null : new AnimatorListenerAdapter() {
2026 @Override
2027 public void onAnimationEnd(Animator _a) {
2028 nlo.setVisibility(View.GONE);
2029 }
2030 })
2031 .start();
2032 }
Daniel Sandler3d32a242012-06-05 13:44:14 -04002033
Dan Sandler16128f42014-05-21 12:48:22 -04002034 findAndUpdateMediaNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -04002035 }
2036
Dan Sandler16128f42014-05-21 12:48:22 -04002037 public void findAndUpdateMediaNotifications() {
2038 boolean metaDataChanged = false;
2039
2040 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02002041 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
2042 final int N = activeNotifications.size();
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002043
2044 // Promote the media notification with a controller in 'playing' state, if any.
Dan Sandler16128f42014-05-21 12:48:22 -04002045 Entry mediaNotification = null;
2046 MediaController controller = null;
Christoph Studerc8db24b2014-07-25 17:50:30 +02002047 for (int i = 0; i < N; i++) {
2048 final Entry entry = activeNotifications.get(i);
Dan Sandler16128f42014-05-21 12:48:22 -04002049 if (isMediaNotification(entry)) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002050 final MediaSession.Token token =
2051 entry.notification.getNotification().extras
Dan Sandler16128f42014-05-21 12:48:22 -04002052 .getParcelable(Notification.EXTRA_MEDIA_SESSION);
2053 if (token != null) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002054 MediaController aController = new MediaController(mContext, token);
2055 if (PlaybackState.STATE_PLAYING ==
2056 getMediaControllerPlaybackState(aController)) {
2057 if (DEBUG_MEDIA) {
2058 Log.v(TAG, "DEBUG_MEDIA: found mediastyle controller matching "
2059 + entry.notification.getKey());
2060 }
Dan Sandler16128f42014-05-21 12:48:22 -04002061 mediaNotification = entry;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002062 controller = aController;
2063 break;
Dan Sandler16128f42014-05-21 12:48:22 -04002064 }
2065 }
2066 }
2067 }
Dan Sandler16128f42014-05-21 12:48:22 -04002068 if (mediaNotification == null) {
2069 // Still nothing? OK, let's just look for live media sessions and see if they match
2070 // one of our notifications. This will catch apps that aren't (yet!) using media
2071 // notifications.
2072
2073 if (mMediaSessionManager != null) {
2074 final List<MediaController> sessions
2075 = mMediaSessionManager.getActiveSessionsForUser(
2076 null,
2077 UserHandle.USER_ALL);
2078
2079 for (MediaController aController : sessions) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002080 if (PlaybackState.STATE_PLAYING ==
2081 getMediaControllerPlaybackState(aController)) {
2082 // now to see if we have one like this
2083 final String pkg = aController.getPackageName();
Dan Sandler16128f42014-05-21 12:48:22 -04002084
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002085 for (int i = 0; i < N; i++) {
2086 final Entry entry = activeNotifications.get(i);
2087 if (entry.notification.getPackageName().equals(pkg)) {
2088 if (DEBUG_MEDIA) {
2089 Log.v(TAG, "DEBUG_MEDIA: found controller matching "
2090 + entry.notification.getKey());
Dan Sandler16128f42014-05-21 12:48:22 -04002091 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002092 controller = aController;
2093 mediaNotification = entry;
2094 break;
Dan Sandler16128f42014-05-21 12:48:22 -04002095 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002096 }
Dan Sandler16128f42014-05-21 12:48:22 -04002097 }
2098 }
2099 }
2100 }
2101
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002102 if (controller != null && !sameSessions(mMediaController, controller)) {
Dan Sandler16128f42014-05-21 12:48:22 -04002103 // We have a new media session
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002104 clearCurrentMediaNotification();
Dan Sandler16128f42014-05-21 12:48:22 -04002105 mMediaController = controller;
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002106 mMediaController.registerCallback(mMediaListener);
2107 mMediaMetadata = mMediaController.getMetadata();
Dan Sandler16128f42014-05-21 12:48:22 -04002108 if (DEBUG_MEDIA) {
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002109 Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: "
2110 + mMediaMetadata);
Dan Sandler16128f42014-05-21 12:48:22 -04002111 }
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002112
2113 if (mediaNotification != null) {
2114 mMediaNotificationKey = mediaNotification.notification.getKey();
2115 if (DEBUG_MEDIA) {
2116 Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
2117 + mMediaNotificationKey + " controller=" + mMediaController);
2118 }
2119 }
2120 metaDataChanged = true;
Dan Sandler16128f42014-05-21 12:48:22 -04002121 }
2122 }
2123
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002124 if (metaDataChanged) {
2125 updateNotifications();
2126 }
Adrian Roos52738322016-01-29 08:49:21 -08002127 updateMediaMetaData(metaDataChanged, true);
Dan Sandler16128f42014-05-21 12:48:22 -04002128 }
2129
Julia Reynoldsd30e42d2015-07-20 17:02:14 -04002130 private int getMediaControllerPlaybackState(MediaController controller) {
2131 if (controller != null) {
2132 final PlaybackState playbackState = controller.getPlaybackState();
2133 if (playbackState != null) {
2134 return playbackState.getState();
2135 }
2136 }
2137 return PlaybackState.STATE_NONE;
2138 }
2139
2140 private boolean isPlaybackActive(int state) {
2141 if (state != PlaybackState.STATE_STOPPED
2142 && state != PlaybackState.STATE_ERROR
2143 && state != PlaybackState.STATE_NONE) {
2144 return true;
2145 }
2146 return false;
2147 }
2148
2149 private void clearCurrentMediaNotification() {
2150 mMediaNotificationKey = null;
2151 mMediaMetadata = null;
2152 if (mMediaController != null) {
2153 if (DEBUG_MEDIA) {
2154 Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
2155 + mMediaController.getPackageName());
2156 }
2157 mMediaController.unregisterCallback(mMediaListener);
2158 }
2159 mMediaController = null;
2160 }
2161
Christoph Studerb5245d82014-09-19 16:54:36 +02002162 private boolean sameSessions(MediaController a, MediaController b) {
2163 if (a == b) return true;
2164 if (a == null) return false;
2165 return a.controlsSameSession(b);
2166 }
2167
Dan Sandler16128f42014-05-21 12:48:22 -04002168 /**
Dan Sandler7dea0ee2014-07-21 21:07:15 -04002169 * Hide the album artwork that is fading out and release its bitmap.
Dan Sandler16128f42014-05-21 12:48:22 -04002170 */
2171 private Runnable mHideBackdropFront = new Runnable() {
2172 @Override
2173 public void run() {
2174 if (DEBUG_MEDIA) {
2175 Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
2176 }
2177 mBackdropFront.setVisibility(View.INVISIBLE);
Dan Sandler7dea0ee2014-07-21 21:07:15 -04002178 mBackdropFront.animate().cancel();
2179 mBackdropFront.setImageDrawable(null);
Dan Sandler16128f42014-05-21 12:48:22 -04002180 }
2181 };
2182
2183 /**
Adrian Roose381c162016-02-11 15:26:42 -08002184 * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
Dan Sandler16128f42014-05-21 12:48:22 -04002185 */
Adrian Roos52738322016-01-29 08:49:21 -08002186 public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07002187 Trace.beginSection("PhoneStatusBar#updateMediaMetaData");
2188 if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) {
2189 Trace.endSection();
2190 return;
2191 }
Dan Sandler16128f42014-05-21 12:48:22 -04002192
Nick Desaulniers1d396752016-07-25 15:05:33 -07002193 if (mBackdrop == null) {
2194 Trace.endSection();
2195 return; // called too early
2196 }
Dan Sandler16128f42014-05-21 12:48:22 -04002197
Selim Cinek37c110f2015-05-22 12:38:44 -07002198 if (mLaunchTransitionFadingAway) {
2199 mBackdrop.setVisibility(View.INVISIBLE);
Nick Desaulniers1d396752016-07-25 15:05:33 -07002200 Trace.endSection();
Selim Cinek37c110f2015-05-22 12:38:44 -07002201 return;
2202 }
2203
Dan Sandler16128f42014-05-21 12:48:22 -04002204 if (DEBUG_MEDIA) {
2205 Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey
Selim Cinek131c1e22015-05-11 19:04:49 -07002206 + " metadata=" + mMediaMetadata
2207 + " metaDataChanged=" + metaDataChanged
2208 + " state=" + mState);
Dan Sandler16128f42014-05-21 12:48:22 -04002209 }
2210
Adrian Roos3b777cb2016-04-14 12:04:28 -07002211 Drawable artworkDrawable = null;
Dan Sandler16128f42014-05-21 12:48:22 -04002212 if (mMediaMetadata != null) {
Adrian Roos3b777cb2016-04-14 12:04:28 -07002213 Bitmap artworkBitmap = null;
Dan Sandler16128f42014-05-21 12:48:22 -04002214 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
2215 if (artworkBitmap == null) {
2216 artworkBitmap = mMediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
2217 // might still be null
2218 }
Adrian Roos3b777cb2016-04-14 12:04:28 -07002219 if (artworkBitmap != null) {
2220 artworkDrawable = new BitmapDrawable(mBackdropBack.getResources(), artworkBitmap);
2221 }
Dan Sandler16128f42014-05-21 12:48:22 -04002222 }
Adrian Roosa3760a42016-04-25 16:21:06 -07002223 boolean allowWhenShade = false;
Adrian Roos3b777cb2016-04-14 12:04:28 -07002224 if (ENABLE_LOCKSCREEN_WALLPAPER && artworkDrawable == null) {
2225 Bitmap lockWallpaper = mLockscreenWallpaper.getBitmap();
2226 if (lockWallpaper != null) {
2227 artworkDrawable = new LockscreenWallpaper.WallpaperDrawable(
2228 mBackdropBack.getResources(), lockWallpaper);
Adrian Roosa3760a42016-04-25 16:21:06 -07002229 // We're in the SHADE mode on the SIM screen - yet we still need to show
2230 // the lockscreen wallpaper in that mode.
2231 allowWhenShade = mStatusBarKeyguardViewManager != null
2232 && mStatusBarKeyguardViewManager.isShowing();
Adrian Roos3b777cb2016-04-14 12:04:28 -07002233 }
Adrian Roos52738322016-01-29 08:49:21 -08002234 }
Dan Sandler16128f42014-05-21 12:48:22 -04002235
Adrian Roosa3760a42016-04-25 16:21:06 -07002236 boolean hideBecauseOccluded = mStatusBarKeyguardViewManager != null
2237 && mStatusBarKeyguardViewManager.isOccluded();
2238
Adrian Roos3b777cb2016-04-14 12:04:28 -07002239 final boolean hasArtwork = artworkDrawable != null;
Dan Sandler16128f42014-05-21 12:48:22 -04002240
Adrian Roosa3760a42016-04-25 16:21:06 -07002241 if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
2242 && (mState != StatusBarState.SHADE || allowWhenShade)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002243 && mFingerprintUnlockController.getMode()
Adrian Roosa3760a42016-04-25 16:21:06 -07002244 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
2245 && !hideBecauseOccluded) {
Dan Sandler16128f42014-05-21 12:48:22 -04002246 // time to show some art!
2247 if (mBackdrop.getVisibility() != View.VISIBLE) {
2248 mBackdrop.setVisibility(View.VISIBLE);
Adrian Roos52738322016-01-29 08:49:21 -08002249 if (allowEnterAnimation) {
Jorim Jaggi6626f542016-08-22 13:08:44 -07002250 mBackdrop.setAlpha(SRC_MIN_ALPHA);
2251 mBackdrop.animate().alpha(1f);
Adrian Roos52738322016-01-29 08:49:21 -08002252 } else {
2253 mBackdrop.animate().cancel();
2254 mBackdrop.setAlpha(1f);
2255 }
Jorim Jaggi6626f542016-08-22 13:08:44 -07002256 mStatusBarWindowManager.setBackdropShowing(true);
Dan Sandler16128f42014-05-21 12:48:22 -04002257 metaDataChanged = true;
2258 if (DEBUG_MEDIA) {
2259 Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
2260 }
2261 }
2262 if (metaDataChanged) {
2263 if (mBackdropBack.getDrawable() != null) {
Julia Reynolds4b9658a2015-07-22 17:07:42 -04002264 Drawable drawable =
Adrian Roos751f33f2016-04-19 16:41:18 -07002265 mBackdropBack.getDrawable().getConstantState()
2266 .newDrawable(mBackdropFront.getResources()).mutate();
Selim Cineka0fad3b2014-09-19 17:20:05 +02002267 mBackdropFront.setImageDrawable(drawable);
Jorim Jaggi0e664392014-09-27 01:30:22 +02002268 if (mScrimSrcModeEnabled) {
2269 mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
2270 }
Dan Sandler16128f42014-05-21 12:48:22 -04002271 mBackdropFront.setAlpha(1f);
2272 mBackdropFront.setVisibility(View.VISIBLE);
2273 } else {
2274 mBackdropFront.setVisibility(View.INVISIBLE);
2275 }
2276
2277 if (DEBUG_MEDIA_FAKE_ARTWORK) {
2278 final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
2279 Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
2280 mBackdropBack.setBackgroundColor(0xFFFFFFFF);
2281 mBackdropBack.setImageDrawable(new ColorDrawable(c));
2282 } else {
Adrian Roos3b777cb2016-04-14 12:04:28 -07002283 mBackdropBack.setImageDrawable(artworkDrawable);
Dan Sandler16128f42014-05-21 12:48:22 -04002284 }
Jorim Jaggi0e664392014-09-27 01:30:22 +02002285 if (mScrimSrcModeEnabled) {
2286 mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
2287 }
Dan Sandler16128f42014-05-21 12:48:22 -04002288
2289 if (mBackdropFront.getVisibility() == View.VISIBLE) {
2290 if (DEBUG_MEDIA) {
2291 Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
2292 + mBackdropFront.getDrawable()
2293 + " to "
2294 + mBackdropBack.getDrawable());
2295 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002296 mBackdropFront.animate()
Dan Sandler16128f42014-05-21 12:48:22 -04002297 .setDuration(250)
2298 .alpha(0f).withEndAction(mHideBackdropFront);
2299 }
2300 }
2301 } else {
2302 // need to hide the album art, either because we are unlocked or because
2303 // the metadata isn't there to support it
2304 if (mBackdrop.getVisibility() != View.GONE) {
2305 if (DEBUG_MEDIA) {
2306 Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
2307 }
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002308 if (mFingerprintUnlockController.getMode()
Adrian Roosa3760a42016-04-25 16:21:06 -07002309 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
2310 || hideBecauseOccluded) {
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002311
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002312 // We are unlocking directly - no animation!
2313 mBackdrop.setVisibility(View.GONE);
Vadim Trysheve7d7d572016-03-09 16:44:30 -08002314 mBackdropBack.setImageDrawable(null);
Adrian Roosd5c2db62016-03-08 16:11:31 -08002315 mStatusBarWindowManager.setBackdropShowing(false);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002316 } else {
Adrian Roosd5c2db62016-03-08 16:11:31 -08002317 mStatusBarWindowManager.setBackdropShowing(false);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002318 mBackdrop.animate()
Jorim Jaggi6626f542016-08-22 13:08:44 -07002319 .alpha(SRC_MIN_ALPHA)
Selim Cinekc18010f2016-01-20 13:41:30 -08002320 .setInterpolator(Interpolators.ACCELERATE_DECELERATE)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002321 .setDuration(300)
2322 .setStartDelay(0)
2323 .withEndAction(new Runnable() {
2324 @Override
2325 public void run() {
2326 mBackdrop.setVisibility(View.GONE);
2327 mBackdropFront.animate().cancel();
Vadim Trysheve7d7d572016-03-09 16:44:30 -08002328 mBackdropBack.setImageDrawable(null);
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002329 mHandler.post(mHideBackdropFront);
2330 }
2331 });
2332 if (mKeyguardFadingAway) {
2333 mBackdrop.animate()
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002334 // Make it disappear faster, as the focus should be on the activity
2335 // behind.
2336 .setDuration(mKeyguardFadingAwayDuration / 2)
2337 .setStartDelay(mKeyguardFadingAwayDelay)
Selim Cinekc18010f2016-01-20 13:41:30 -08002338 .setInterpolator(Interpolators.LINEAR)
Jorim Jaggid94d3a22015-08-21 16:52:55 -07002339 .start();
2340 }
Jorim Jaggi4e0880e2014-07-25 14:51:50 +02002341 }
Dan Sandler16128f42014-05-21 12:48:22 -04002342 }
2343 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07002344 Trace.endSection();
Dan Sandler16128f42014-05-21 12:48:22 -04002345 }
2346
Adrian Roos7bb38a92016-07-21 11:44:01 -07002347 private void updateReportRejectedTouchVisibility() {
2348 if (mReportRejectedTouch == null) {
2349 return;
2350 }
2351 mReportRejectedTouch.setVisibility(mState == StatusBarState.KEYGUARD
2352 && mFalsingManager.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE);
2353 }
2354
Xiaohui Cheneb04a992016-03-22 14:58:03 -07002355 protected int adjustDisableFlags(int state) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07002356 if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway
Selim Cinekbaa23272014-07-08 18:01:07 +02002357 && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
Jorim Jaggib13d36d2014-06-06 18:03:52 +02002358 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
2359 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
2360 }
Adrian Roos316bf542016-08-23 17:53:07 +02002361 if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
2362 if (mNetworkController.hasEmergencyCryptKeeperText()) {
2363 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
2364 }
2365 if (!mNetworkController.isRadioOn()) {
2366 state |= StatusBarManager.DISABLE_SYSTEM_INFO;
2367 }
2368 }
Jorim Jaggib13d36d2014-06-06 18:03:52 +02002369 return state;
2370 }
2371
Joe Onorato808182d2010-07-09 18:52:06 -04002372 /**
2373 * State is one or more of the DISABLE constants from StatusBarManager.
2374 */
Jim Miller07e03842016-06-22 15:18:13 -07002375 @Override
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002376 public void disable(int state1, int state2, boolean animate) {
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002377 animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002378 mDisabledUnmodified1 = state1;
2379 mDisabledUnmodified2 = state2;
2380 state1 = adjustDisableFlags(state1);
2381 final int old1 = mDisabled1;
2382 final int diff1 = state1 ^ old1;
2383 mDisabled1 = state1;
2384
2385 final int old2 = mDisabled2;
2386 final int diff2 = state2 ^ old2;
2387 mDisabled2 = state2;
Joe Onorato808182d2010-07-09 18:52:06 -04002388
Daniel Sandlere21f2882011-08-18 10:14:59 -04002389 if (DEBUG) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002390 Log.d(TAG, String.format("disable1: 0x%08x -> 0x%08x (diff1: 0x%08x)",
2391 old1, state1, diff1));
2392 Log.d(TAG, String.format("disable2: 0x%08x -> 0x%08x (diff2: 0x%08x)",
2393 old2, state2, diff2));
Daniel Sandlere21f2882011-08-18 10:14:59 -04002394 }
2395
Daniel Sandler6da2b762011-09-14 16:04:59 -04002396 StringBuilder flagdbg = new StringBuilder();
2397 flagdbg.append("disable: < ");
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002398 flagdbg.append(((state1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
2399 flagdbg.append(((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
2400 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
2401 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
2402 flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
2403 flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
2404 flagdbg.append(((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
2405 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
2406 flagdbg.append(((state1 & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
2407 flagdbg.append(((diff1 & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
2408 flagdbg.append(((state1 & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
2409 flagdbg.append(((diff1 & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
2410 flagdbg.append(((state1 & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
2411 flagdbg.append(((diff1 & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
2412 flagdbg.append(((state1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
2413 flagdbg.append(((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
2414 flagdbg.append(((state1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
2415 flagdbg.append(((diff1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
Benjamin Franz27cf1462015-04-23 19:36:42 +01002416 flagdbg.append(((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "QUICK_SETTINGS"
2417 : "quick_settings");
2418 flagdbg.append(((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "* " : " ");
Daniel Sandler6da2b762011-09-14 16:04:59 -04002419 flagdbg.append(">");
John Spurlockcd686b52013-06-05 10:13:46 -04002420 Log.d(TAG, flagdbg.toString());
Jim Millera073e572012-05-23 17:03:27 -07002421
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002422 if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
2423 if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002424 mIconController.hideSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002425 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002426 mIconController.showSystemIconArea(animate);
Daniel Sandler8e18dc72012-05-17 00:44:59 -04002427 }
2428 }
Daniel Sandler6da2b762011-09-14 16:04:59 -04002429
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002430 if ((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) {
2431 boolean visible = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002432 mIconController.setClockVisibility(visible);
Jeff Sharkeyf52c70b2011-08-30 22:05:47 -07002433 }
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002434 if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
2435 if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
Daniel Sandler11cf1782012-09-27 14:03:08 -04002436 animateCollapsePanels();
Joe Onorato808182d2010-07-09 18:52:06 -04002437 }
2438 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002439
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002440 if ((diff1 & (StatusBarManager.DISABLE_HOME
Jim Miller5e6af442011-12-02 18:24:26 -08002441 | StatusBarManager.DISABLE_RECENT
Daniel Sandlerd5483c32012-10-19 16:44:15 -04002442 | StatusBarManager.DISABLE_BACK
2443 | StatusBarManager.DISABLE_SEARCH)) != 0) {
Daniel Sandlerdba93562011-10-06 16:39:58 -04002444 // the nav bar will take care of these
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002445 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002446
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002447 if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
Daniel Sandler6da2b762011-09-14 16:04:59 -04002448 // close recents if it's visible
Winson Chung1e8d71b2014-05-16 17:05:22 -07002449 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2450 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
Daniel Sandler6da2b762011-09-14 16:04:59 -04002451 }
Daniel Sandlere21f2882011-08-18 10:14:59 -04002452 }
2453
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002454 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
2455 if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002456 mIconController.hideNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002457 } else {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01002458 mIconController.showNotificationIconArea(animate);
Joe Onorato808182d2010-07-09 18:52:06 -04002459 }
Joe Onorato808182d2010-07-09 18:52:06 -04002460 }
Jason Monkf7019542014-07-31 12:42:25 -04002461
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002462 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
Jason Monkf7019542014-07-31 12:42:25 -04002463 mDisableNotificationAlerts =
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002464 (state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
Jason Monkf7019542014-07-31 12:42:25 -04002465 mHeadsUpObserver.onChange(true);
2466 }
Benjamin Franz27cf1462015-04-23 19:36:42 +01002467
2468 if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
2469 updateQsExpansionEnabled();
2470 }
Joe Onorato808182d2010-07-09 18:52:06 -04002471 }
2472
Adrian Roos316bf542016-08-23 17:53:07 +02002473 /**
2474 * Reapplies the disable flags as last requested by StatusBarManager.
2475 *
2476 * This needs to be called if state used by {@link #adjustDisableFlags} changes.
2477 */
2478 private void recomputeDisableFlags(boolean animate) {
2479 disable(mDisabledUnmodified1, mDisabledUnmodified2, animate);
2480 }
2481
Michael Jurka7f2668c2012-03-27 07:49:52 -07002482 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -07002483 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002484 return new PhoneStatusBar.H();
2485 }
2486
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002487 @Override
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02002488 public void startActivity(Intent intent, boolean dismissShade) {
2489 startActivityDismissingKeyguard(intent, false, dismissShade);
Jorim Jaggi97b63c42014-05-02 23:03:34 +02002490 }
2491
Selim Cineke70d6532015-04-24 16:46:13 -07002492 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07002493 public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
2494 startActivityDismissingKeyguard(intent, false, dismissShade, callback);
2495 }
2496
2497 @Override
Selim Cineke70d6532015-04-24 16:46:13 -07002498 public void preventNextAnimation() {
2499 overrideActivityPendingAppTransition(true /* keyguardShowing */);
2500 }
2501
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002502 public void setQsExpanded(boolean expanded) {
2503 mStatusBarWindowManager.setQsExpanded(expanded);
Adrian Roos4c7d9602015-06-10 13:44:48 -07002504 mKeyguardStatusView.setImportantForAccessibility(expanded
2505 ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
2506 : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
Jorim Jaggib690f0d2014-07-03 23:25:44 +02002507 }
2508
Jorim Jaggi84a3e7a2014-08-13 17:58:58 +02002509 public boolean isGoingToNotificationShade() {
2510 return mLeaveOpenOnKeyguardHide;
2511 }
2512
Jorim Jaggid692dd02014-08-14 20:57:42 +02002513 public boolean isQsExpanded() {
2514 return mNotificationPanel.isQsExpanded();
2515 }
2516
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07002517 public boolean isWakeUpComingFromTouch() {
2518 return mWakeUpComingFromTouch;
Selim Cinek29ed3c92014-09-23 20:44:35 +02002519 }
2520
Selim Cinek19c8c702014-08-25 22:09:19 +02002521 public boolean isFalsingThresholdNeeded() {
Selim Cinek9db71052015-04-24 18:54:30 -07002522 return getBarState() == StatusBarState.KEYGUARD;
Selim Cinek19c8c702014-08-25 22:09:19 +02002523 }
2524
John Spurlock0b99ea92014-10-01 15:32:22 -04002525 public boolean isDozing() {
2526 return mDozing;
2527 }
2528
Christoph Studer2e731b52014-08-22 16:01:51 +02002529 @Override // NotificationData.Environment
2530 public String getCurrentMediaNotificationKey() {
2531 return mMediaNotificationKey;
2532 }
2533
Jorim Jaggi0e664392014-09-27 01:30:22 +02002534 public boolean isScrimSrcModeEnabled() {
2535 return mScrimSrcModeEnabled;
2536 }
2537
Joe Onorato808182d2010-07-09 18:52:06 -04002538 /**
Christoph Studer2231c6e2014-12-19 12:40:13 +01002539 * To be called when there's a state change in StatusBarKeyguardViewManager.
2540 */
2541 public void onKeyguardViewManagerStatesUpdated() {
2542 logStateToEventlog();
2543 }
2544
2545 @Override // UnlockMethodCache.OnUnlockMethodChangedListener
2546 public void onUnlockMethodStateChanged() {
2547 logStateToEventlog();
2548 }
2549
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002550 @Override
John Spurlockb349af572015-04-29 12:24:19 -04002551 public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
Selim Cinek684a4422015-04-15 16:18:39 -07002552 if (inPinnedMode) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002553 mStatusBarWindowManager.setHeadsUpShowing(true);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002554 mStatusBarWindowManager.setForceStatusBarVisible(true);
Selim Cinek131c1e22015-05-11 19:04:49 -07002555 if (mNotificationPanel.isFullyCollapsed()) {
2556 // We need to ensure that the touchable region is updated before the window will be
2557 // resized, in order to not catch any touches. A layout will ensure that
2558 // onComputeInternalInsets will be called and after that we can resize the layout. Let's
2559 // make sure that the window stays small for one frame until the touchableRegion is set.
2560 mNotificationPanel.requestLayout();
2561 mStatusBarWindowManager.setForceWindowCollapsed(true);
2562 mNotificationPanel.post(new Runnable() {
2563 @Override
2564 public void run() {
2565 mStatusBarWindowManager.setForceWindowCollapsed(false);
2566 }
2567 });
2568 }
Selim Cinek737bff32015-05-08 16:08:35 -07002569 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002570 if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) {
2571 // We are currently tracking or is open and the shade doesn't need to be kept
2572 // open artificially.
Selim Cinek737bff32015-05-08 16:08:35 -07002573 mStatusBarWindowManager.setHeadsUpShowing(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002574 } else {
Selim Cinek131c1e22015-05-11 19:04:49 -07002575 // we need to keep the panel open artificially, let's wait until the animation
2576 // is finished.
Selim Cinek737bff32015-05-08 16:08:35 -07002577 mHeadsUpManager.setHeadsUpGoingAway(true);
2578 mStackScroller.runAfterAnimationFinished(new Runnable() {
2579 @Override
2580 public void run() {
2581 if (!mHeadsUpManager.hasPinnedHeadsUp()) {
2582 mStatusBarWindowManager.setHeadsUpShowing(false);
2583 mHeadsUpManager.setHeadsUpGoingAway(false);
2584 }
Adrian Roos9550f2e2016-08-23 18:23:01 +02002585 removeRemoteInputEntriesKeptUntilCollapsed();
Selim Cinek737bff32015-05-08 16:08:35 -07002586 }
2587 });
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002588 }
2589 }
2590 }
2591
2592 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002593 public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
John Spurlockb349af572015-04-29 12:24:19 -04002594 dismissVolumeDialog();
Selim Cinek1f3f5442015-04-10 17:54:46 -07002595 }
2596
2597 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002598 public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
2599 }
2600
2601 @Override
2602 public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002603 if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
2604 removeNotification(entry.key, mLatestRankingMap);
2605 mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
2606 if (mHeadsUpEntriesToRemoveOnSwitch.isEmpty()) {
2607 mLatestRankingMap = null;
2608 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002609 } else {
2610 updateNotificationRanking(null);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002611 }
Selim Cinekfbe9a442015-04-13 16:09:49 -07002612
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002613 }
2614
Jim Miller07e03842016-06-22 15:18:13 -07002615 @Override
Chris Wrenbdf33762015-12-04 15:50:51 -05002616 protected void updateHeadsUp(String key, Entry entry, boolean shouldPeek,
Selim Cinek29fa89b2015-04-17 10:39:11 -07002617 boolean alertAgain) {
2618 final boolean wasHeadsUp = isHeadsUp(key);
2619 if (wasHeadsUp) {
Chris Wrenbdf33762015-12-04 15:50:51 -05002620 if (!shouldPeek) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002621 // We don't want this to be interrupting anymore, lets remove it
Adrian Roosc721fcc52016-04-29 11:28:37 -07002622 mHeadsUpManager.removeNotification(key, false /* ignoreEarliestRemovalTime */);
Selim Cinek684a4422015-04-15 16:18:39 -07002623 } else {
2624 mHeadsUpManager.updateNotification(entry, alertAgain);
Selim Cinek29fa89b2015-04-17 10:39:11 -07002625 }
Chris Wrenbdf33762015-12-04 15:50:51 -05002626 } else if (shouldPeek && alertAgain) {
Selim Cinek29fa89b2015-04-17 10:39:11 -07002627 // This notification was updated to be a heads-up, show it!
2628 mHeadsUpManager.showNotification(entry);
2629 }
2630 }
2631
Jim Miller07e03842016-06-22 15:18:13 -07002632 @Override
Selim Cinek29fa89b2015-04-17 10:39:11 -07002633 protected void setHeadsUpUser(int newUserId) {
2634 if (mHeadsUpManager != null) {
2635 mHeadsUpManager.setUser(newUserId);
2636 }
2637 }
2638
2639 public boolean isHeadsUp(String key) {
2640 return mHeadsUpManager.isHeadsUp(key);
2641 }
2642
Jim Miller07e03842016-06-22 15:18:13 -07002643 @Override
Selim Cinek29fa89b2015-04-17 10:39:11 -07002644 protected boolean isSnoozedPackage(StatusBarNotification sbn) {
2645 return mHeadsUpManager.isSnoozed(sbn.getPackageName());
2646 }
2647
Selim Cineke70d6532015-04-24 16:46:13 -07002648 public boolean isKeyguardCurrentlySecure() {
Selim Cineke8bae622015-07-15 13:24:06 -07002649 return !mUnlockMethodCache.canSkipBouncer();
Selim Cineke70d6532015-04-24 16:46:13 -07002650 }
2651
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002652 public void setPanelExpanded(boolean isExpanded) {
2653 mStatusBarWindowManager.setPanelExpanded(isExpanded);
Adrian Roos18d099a2016-05-19 15:28:18 -07002654
2655 if (isExpanded && getBarState() != StatusBarState.KEYGUARD) {
2656 if (DEBUG) {
2657 Log.v(TAG, "clearing notification effects from setPanelExpanded");
2658 }
2659 clearNotificationEffects();
2660 }
2661
2662 if (!isExpanded) {
2663 removeRemoteInputEntriesKeptUntilCollapsed();
2664 }
2665 }
2666
2667 private void removeRemoteInputEntriesKeptUntilCollapsed() {
2668 for (int i = 0; i < mRemoteInputEntriesToRemoveOnCollapse.size(); i++) {
2669 Entry entry = mRemoteInputEntriesToRemoveOnCollapse.valueAt(i);
Adrian Roos7813dd72016-09-23 17:12:17 -07002670 mRemoteInputController.removeRemoteInput(entry, null);
Adrian Roos18d099a2016-05-19 15:28:18 -07002671 removeNotification(entry.key, mLatestRankingMap);
2672 }
2673 mRemoteInputEntriesToRemoveOnCollapse.clear();
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002674 }
2675
Adrian Roos401caae2016-03-04 13:35:21 -08002676 public void onScreenTurnedOff() {
2677 mFalsingManager.onScreenOff();
2678 }
2679
Christoph Studer2231c6e2014-12-19 12:40:13 +01002680 /**
Joe Onorato808182d2010-07-09 18:52:06 -04002681 * All changes to the status bar and notifications funnel through here and are batched.
2682 */
Michael Jurka7f2668c2012-03-27 07:49:52 -07002683 private class H extends BaseStatusBar.H {
Jim Miller07e03842016-06-22 15:18:13 -07002684 @Override
Joe Onorato808182d2010-07-09 18:52:06 -04002685 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07002686 super.handleMessage(m);
Joe Onorato808182d2010-07-09 18:52:06 -04002687 switch (m.what) {
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002688 case MSG_OPEN_NOTIFICATION_PANEL:
Daniel Sandler11cf1782012-09-27 14:03:08 -04002689 animateExpandNotificationsPanel();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002690 break;
Daniel Sandler11cf1782012-09-27 14:03:08 -04002691 case MSG_OPEN_SETTINGS_PANEL:
Jason Monka9927322015-12-13 16:22:37 -05002692 animateExpandSettingsPanel((String) m.obj);
Daniel Sandler11cf1782012-09-27 14:03:08 -04002693 break;
2694 case MSG_CLOSE_PANELS:
2695 animateCollapsePanels();
Daniel Sandler8ba33c92011-10-04 21:49:30 -04002696 break;
Jorim Jaggi826730a2014-12-08 21:05:13 +01002697 case MSG_LAUNCH_TRANSITION_TIMEOUT:
2698 onLaunchTransitionTimeout();
2699 break;
Chris Wrene97f90b2013-08-07 17:39:35 -04002700 }
2701 }
2702 }
2703
Chris Wren930ecca2014-11-12 17:43:41 -05002704 @Override
Selim Cinek684a4422015-04-15 16:18:39 -07002705 public void maybeEscalateHeadsUp() {
Selim Cinek3362c132016-02-11 15:43:03 -08002706 Collection<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getAllEntries();
Selim Cineka59ecc32015-04-07 10:51:49 -07002707 for (HeadsUpManager.HeadsUpEntry entry : entries) {
2708 final StatusBarNotification sbn = entry.entry.notification;
Chris Wrene97f90b2013-08-07 17:39:35 -04002709 final Notification notification = sbn.getNotification();
2710 if (notification.fullScreenIntent != null) {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002711 if (DEBUG) {
Chris Wrene97f90b2013-08-07 17:39:35 -04002712 Log.d(TAG, "converting a heads up to fullScreen");
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002713 }
Chris Wrene97f90b2013-08-07 17:39:35 -04002714 try {
Chris Wren223c66b62014-11-10 16:00:09 -05002715 EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
2716 sbn.getKey());
Chris Wrene97f90b2013-08-07 17:39:35 -04002717 notification.fullScreenIntent.send();
Selim Cinekb18a20f2015-06-04 17:08:35 +02002718 entry.entry.notifyFullScreenIntentLaunched();
Chris Wrene97f90b2013-08-07 17:39:35 -04002719 } catch (PendingIntent.CanceledException e) {
2720 }
Joe Onorato808182d2010-07-09 18:52:06 -04002721 }
2722 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07002723 mHeadsUpManager.releaseAllImmediately();
Joe Onorato808182d2010-07-09 18:52:06 -04002724 }
2725
Jim Miller07e03842016-06-22 15:18:13 -07002726 /**
2727 * Called for system navigation gestures. First action opens the panel, second opens
2728 * settings. Down action closes the entire panel.
2729 */
2730 @Override
2731 public void handleSystemNavigationKey(int key) {
2732 if (SPEW) Log.d(TAG, "handleSystemNavigationKey: " + key);
Jim Miller1c21fc52016-08-02 16:12:58 -07002733 if (!panelsEnabled() || !mKeyguardMonitor.isDeviceInteractive()
Jim Miller69c12412016-10-06 19:11:03 -07002734 || mKeyguardMonitor.isShowing() && !mKeyguardMonitor.isOccluded()) {
Jim Miller07e03842016-06-22 15:18:13 -07002735 return;
2736 }
2737
2738 // Panels are not available in setup
2739 if (!mUserSetup) return;
2740
2741 if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP == key) {
Doris Ling3c00afb2016-07-19 17:04:21 -07002742 MetricsLogger.action(mContext, MetricsEvent.ACTION_SYSTEM_NAVIGATION_KEY_UP);
Jim Miller07e03842016-06-22 15:18:13 -07002743 mNotificationPanel.collapse(false /* delayed */, 1.0f /* speedUpFactor */);
2744 } else if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN == key) {
Doris Ling3c00afb2016-07-19 17:04:21 -07002745 MetricsLogger.action(mContext, MetricsEvent.ACTION_SYSTEM_NAVIGATION_KEY_DOWN);
Jim Miller07e03842016-06-22 15:18:13 -07002746 if (mNotificationPanel.isFullyCollapsed()) {
2747 mNotificationPanel.expand(true /* animate */);
Doris Ling3c00afb2016-07-19 17:04:21 -07002748 MetricsLogger.count(mContext, NotificationPanelView.COUNTER_PANEL_OPEN, 1);
Jim Miller07e03842016-06-22 15:18:13 -07002749 } else if (!mNotificationPanel.isInSettings() && !mNotificationPanel.isExpanding()){
2750 mNotificationPanel.flingSettings(0 /* velocity */, true /* expand */);
Doris Ling3c00afb2016-07-19 17:04:21 -07002751 MetricsLogger.count(mContext, NotificationPanelView.COUNTER_PANEL_OPEN_QS, 1);
Jim Miller07e03842016-06-22 15:18:13 -07002752 }
2753 }
2754
2755 }
2756
John Spurlock97642182013-07-29 17:58:39 -04002757 boolean panelsEnabled() {
Adrian Roos21d2a252015-06-01 13:59:59 -07002758 return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && !ONLY_CORE_APPS;
John Spurlock97642182013-07-29 17:58:39 -04002759 }
2760
Jorim Jaggifa505a72014-04-28 20:04:11 +02002761 void makeExpandedVisible(boolean force) {
John Spurlockcd686b52013-06-05 10:13:46 -04002762 if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
Jorim Jaggifa505a72014-04-28 20:04:11 +02002763 if (!force && (mExpandedVisible || !panelsEnabled())) {
Joe Onorato808182d2010-07-09 18:52:06 -04002764 return;
2765 }
Jim Millera073e572012-05-23 17:03:27 -07002766
Joe Onorato808182d2010-07-09 18:52:06 -04002767 mExpandedVisible = true;
Joe Onorato808182d2010-07-09 18:52:06 -04002768
Daniel Sandlera310af82012-04-24 01:20:13 -04002769 // Expand the window to encompass the full screen in anticipation of the drag.
2770 // 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 -07002771 mStatusBarWindowManager.setPanelVisible(true);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002772
2773 visibilityChanged(true);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07002774 mWaitingForKeyguardExit = false;
Adrian Roos316bf542016-08-23 17:53:07 +02002775 recomputeDisableFlags(!force /* animate */);
Jorim Jaggi380ecb82014-03-14 17:25:20 +01002776 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2777 }
2778
Daniel Sandler11cf1782012-09-27 14:03:08 -04002779 public void animateCollapsePanels() {
2780 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurka3b1fc472011-06-13 10:54:40 -07002781 }
2782
John Spurlockaf8d6c42014-05-07 17:49:08 -04002783 private final Runnable mAnimateCollapsePanels = new Runnable() {
2784 @Override
2785 public void run() {
2786 animateCollapsePanels();
2787 }
2788 };
2789
2790 public void postAnimateCollapsePanels() {
2791 mHandler.post(mAnimateCollapsePanels);
2792 }
2793
Jason Monkba2318e2015-12-08 09:04:23 -05002794 public void postAnimateOpenPanels() {
2795 mHandler.sendEmptyMessage(MSG_OPEN_SETTINGS_PANEL);
2796 }
2797
Jim Miller07e03842016-06-22 15:18:13 -07002798 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002799 public void animateCollapsePanels(int flags) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002800 animateCollapsePanels(flags, false /* force */, false /* delayed */,
2801 1.0f /* speedUpFactor */);
Jorim Jaggi34250762014-07-03 23:51:19 +02002802 }
2803
Jim Miller07e03842016-06-22 15:18:13 -07002804 @Override
Jorim Jaggi34250762014-07-03 23:51:19 +02002805 public void animateCollapsePanels(int flags, boolean force) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002806 animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002807 }
2808
Jim Miller07e03842016-06-22 15:18:13 -07002809 @Override
Jorim Jaggi27c9b742015-04-09 10:34:49 -07002810 public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002811 animateCollapsePanels(flags, force, delayed, 1.0f /* speedUpFactor */);
2812 }
2813
2814 public void animateCollapsePanels(int flags, boolean force, boolean delayed,
2815 float speedUpFactor) {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07002816 if (!force && mState != StatusBarState.SHADE) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002817 runPostCollapseRunnables();
Jorim Jaggic1cf1ae2014-05-02 21:19:17 +02002818 return;
2819 }
Joe Onorato808182d2010-07-09 18:52:06 -04002820 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04002821 Log.d(TAG, "animateCollapse():"
Joe Onorato808182d2010-07-09 18:52:06 -04002822 + " mExpandedVisible=" + mExpandedVisible
Jim Miller9a720f52012-05-30 03:19:43 -07002823 + " flags=" + flags);
Joe Onorato808182d2010-07-09 18:52:06 -04002824 }
2825
Jim Miller9a720f52012-05-30 03:19:43 -07002826 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Winson Chungcdcd4872014-08-05 18:00:13 -07002827 if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
2828 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
2829 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
2830 }
Michael Jurka3b1fc472011-06-13 10:54:40 -07002831 }
Jim Miller9a720f52012-05-30 03:19:43 -07002832
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002833 if (mStatusBarWindow != null) {
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002834 // release focus immediately to kick off focus change transition
2835 mStatusBarWindowManager.setStatusBarFocusable(false);
2836
John Spurlockab847cf2014-01-15 14:13:59 -05002837 mStatusBarWindow.cancelExpandHelper();
Xiaohui Chen9f967112016-01-07 14:14:06 -08002838 mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
John Spurlockab847cf2014-01-15 14:13:59 -05002839 }
Joe Onorato808182d2010-07-09 18:52:06 -04002840 }
2841
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002842 private void runPostCollapseRunnables() {
Selim Cinekae77f8e2015-07-07 18:43:59 -07002843 ArrayList<Runnable> clonedList = new ArrayList<>(mPostCollapseRunnables);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002844 mPostCollapseRunnables.clear();
Selim Cinekae77f8e2015-07-07 18:43:59 -07002845 int size = clonedList.size();
2846 for (int i = 0; i < size; i++) {
2847 clonedList.get(i).run();
2848 }
2849
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002850 }
2851
Daniel Sandler08d05e32012-08-08 16:39:54 -04002852 @Override
Daniel Sandler11cf1782012-09-27 14:03:08 -04002853 public void animateExpandNotificationsPanel() {
John Spurlockcd686b52013-06-05 10:13:46 -04002854 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002855 if (!panelsEnabled()) {
Joe Onorato808182d2010-07-09 18:52:06 -04002856 return ;
2857 }
Joe Onorato808182d2010-07-09 18:52:06 -04002858
Oren Blasberg8d3fea12015-07-10 14:21:44 -07002859 mNotificationPanel.expand(true /* animate */);
Joe Onorato808182d2010-07-09 18:52:06 -04002860
2861 if (false) postStartTracing();
2862 }
2863
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002864 @Override
Jason Monka9927322015-12-13 16:22:37 -05002865 public void animateExpandSettingsPanel(String subPanel) {
John Spurlockcd686b52013-06-05 10:13:46 -04002866 if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
John Spurlock97642182013-07-29 17:58:39 -04002867 if (!panelsEnabled()) {
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002868 return;
2869 }
2870
Daniel Sandlera8ef3b02012-11-29 15:52:39 -05002871 // Settings are not available in setup
2872 if (!mUserSetup) return;
2873
Jason Monka9927322015-12-13 16:22:37 -05002874
2875 if (subPanel != null) {
2876 mQSPanel.openDetails(subPanel);
2877 }
Jason Monk3c68ca22015-01-30 11:30:29 -05002878 mNotificationPanel.expandWithQs();
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002879
2880 if (false) postStartTracing();
2881 }
2882
2883 public void animateCollapseQuickSettings() {
Jorim Jaggi449981b2014-10-03 14:24:55 -07002884 if (mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08002885 mStatusBarView.collapsePanel(true, false /* delayed */, 1.0f /* speedUpFactor */);
Jorim Jaggi449981b2014-10-03 14:24:55 -07002886 }
Svetoslav Ganove20a1772012-09-25 16:07:46 -07002887 }
2888
Daniel Sandler08d05e32012-08-08 16:39:54 -04002889 void makeExpandedInvisible() {
John Spurlockcd686b52013-06-05 10:13:46 -04002890 if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
Joe Onorato808182d2010-07-09 18:52:06 -04002891 + " mExpandedVisible=" + mExpandedVisible);
2892
Jorim Jaggi5cf17872014-03-26 18:31:48 +01002893 if (!mExpandedVisible || mStatusBarWindow == null) {
Joe Onorato808182d2010-07-09 18:52:06 -04002894 return;
2895 }
Daniel Sandlered930e52012-07-03 14:31:22 -04002896
Daniel Sandlerc38bbc32012-10-05 12:21:38 -04002897 // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
Xiaohui Chen9f967112016-01-07 14:14:06 -08002898 mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002899 1.0f /* speedUpFactor */);
Daniel Sandlered930e52012-07-03 14:31:22 -04002900
Jorim Jaggid7daab72014-05-06 22:22:20 +02002901 mNotificationPanel.closeQs();
Daniel Sandler040c2e42012-10-17 00:56:33 -04002902
Joe Onorato808182d2010-07-09 18:52:06 -04002903 mExpandedVisible = false;
Jorim Jaggic59a23f2016-05-24 14:53:36 -07002904
Joe Onorato808182d2010-07-09 18:52:06 -04002905 visibilityChanged(false);
Daniel Sandlera310af82012-04-24 01:20:13 -04002906
2907 // Shrink the window to the size of the status bar only
Selim Cinek4a21a7f2015-05-19 11:00:38 -07002908 mStatusBarWindowManager.setPanelVisible(false);
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07002909 mStatusBarWindowManager.setForceStatusBarVisible(false);
Joe Onorato808182d2010-07-09 18:52:06 -04002910
Daniel Sandler469e96e2012-05-04 15:56:19 -04002911 // Close any "App info" popups that might have snuck on-screen
2912 dismissPopups();
2913
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02002914 runPostCollapseRunnables();
John Spurlockcfc359a2013-09-05 10:42:03 -04002915 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02002916 showBouncer();
Adrian Roos316bf542016-08-23 17:53:07 +02002917 recomputeDisableFlags(true /* animate */);
Jorim Jaggi786afcb2014-09-25 02:41:29 +02002918
2919 // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
2920 // the bouncer appear animation.
2921 if (!mStatusBarKeyguardViewManager.isShowing()) {
2922 WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
2923 }
Joe Onorato808182d2010-07-09 18:52:06 -04002924 }
2925
Daniel Sandlerb17a7262012-10-05 14:32:50 -04002926 public boolean interceptTouchEvent(MotionEvent event) {
Chris Wren64161cc2012-12-17 16:49:30 -05002927 if (DEBUG_GESTURES) {
2928 if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
2929 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002930 event.getActionMasked(), (int) event.getX(), (int) event.getY(),
2931 mDisabled1, mDisabled2);
Chris Wren64161cc2012-12-17 16:49:30 -05002932 }
2933
2934 }
2935
Joe Onorato808182d2010-07-09 18:52:06 -04002936 if (SPEW) {
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002937 Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
2938 + mDisabled1 + " mDisabled2=" + mDisabled2 + " mTracking=" + mTracking);
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002939 } else if (CHATTY) {
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002940 if (event.getAction() != MotionEvent.ACTION_MOVE) {
John Spurlockcd686b52013-06-05 10:13:46 -04002941 Log.d(TAG, String.format(
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002942 "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
Daniel Sandlerfe172cc2011-09-12 13:47:25 -04002943 MotionEvent.actionToString(event.getAction()),
Benjamin Franzcde0a2a2015-04-23 17:19:48 +01002944 event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
Daniel Sandler96e61c3c82011-08-04 22:49:06 -04002945 }
Joe Onorato808182d2010-07-09 18:52:06 -04002946 }
2947
Daniel Sandler151f00d2012-10-02 22:33:08 -04002948 if (DEBUG_GESTURES) {
2949 mGestureRec.add(event);
2950 }
Daniel Sandler33805342012-07-23 15:45:12 -04002951
John Spurlock686820a2013-09-03 14:44:16 -04002952 if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
John Spurlock5fee8362013-09-12 10:34:33 -04002953 final boolean upOrCancel =
2954 event.getAction() == MotionEvent.ACTION_UP ||
2955 event.getAction() == MotionEvent.ACTION_CANCEL;
2956 if (upOrCancel && !mExpandedVisible) {
2957 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
2958 } else {
2959 setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
2960 }
John Spurlock686820a2013-09-03 14:44:16 -04002961 }
Joe Onorato808182d2010-07-09 18:52:06 -04002962 return false;
2963 }
2964
Daniel Sandler08d05e32012-08-08 16:39:54 -04002965 public GestureRecorder getGestureRecorder() {
2966 return mGestureRec;
Jeff Brown911fe302011-09-12 14:21:17 -07002967 }
2968
John Spurlock56d007b2013-10-28 18:40:56 -04002969 private void setNavigationIconHints(int hints) {
Daniel Sandler328310c2011-09-23 15:56:52 -04002970 if (hints == mNavigationIconHints) return;
2971
2972 mNavigationIconHints = hints;
2973
2974 if (mNavigationBarView != null) {
2975 mNavigationBarView.setNavigationIconHints(hints);
2976 }
John Spurlockd4e65752013-08-28 14:17:09 -04002977 checkBarModes();
Daniel Sandler328310c2011-09-23 15:56:52 -04002978 }
2979
2980 @Override // CommandQueue
John Spurlock97642182013-07-29 17:58:39 -04002981 public void setWindowState(int window, int state) {
John Spurlockd4e65752013-08-28 14:17:09 -04002982 boolean showing = state == WINDOW_STATE_SHOWING;
John Spurlock97642182013-07-29 17:58:39 -04002983 if (mStatusBarWindow != null
2984 && window == StatusBarManager.WINDOW_STATUS_BAR
2985 && mStatusBarWindowState != state) {
2986 mStatusBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002987 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
Jorim Jaggi449981b2014-10-03 14:24:55 -07002988 if (!showing && mState == StatusBarState.SHADE) {
Xiaohui Chen9f967112016-01-07 14:14:06 -08002989 mStatusBarView.collapsePanel(false /* animate */, false /* delayed */,
Jorim Jaggif3b3bee2015-04-16 14:57:34 -07002990 1.0f /* speedUpFactor */);
John Spurlock97642182013-07-29 17:58:39 -04002991 }
2992 }
2993 if (mNavigationBarView != null
2994 && window == StatusBarManager.WINDOW_NAVIGATION_BAR
2995 && mNavigationBarWindowState != state) {
2996 mNavigationBarWindowState = state;
John Spurlock0ec64c62013-08-26 15:37:58 -04002997 if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
John Spurlock97642182013-07-29 17:58:39 -04002998 }
2999 }
3000
John Spurlock97642182013-07-29 17:58:39 -04003001 @Override // CommandQueue
John Spurlockcad57682014-07-26 17:09:56 -04003002 public void buzzBeepBlinked() {
3003 if (mDozeServiceHost != null) {
3004 mDozeServiceHost.fireBuzzBeepBlinked();
3005 }
3006 }
3007
John Spurlockcb566aa2014-08-03 22:58:28 -04003008 @Override
3009 public void notificationLightOff() {
3010 if (mDozeServiceHost != null) {
3011 mDozeServiceHost.fireNotificationLight(false);
3012 }
3013 }
3014
3015 @Override
3016 public void notificationLightPulse(int argb, int onMillis, int offMillis) {
3017 if (mDozeServiceHost != null) {
3018 mDozeServiceHost.fireNotificationLight(true);
3019 }
3020 }
3021
John Spurlockcad57682014-07-26 17:09:56 -04003022 @Override // CommandQueue
Jorim Jaggi86905582016-02-09 21:36:09 -08003023 public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
3024 int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07003025 final int oldVal = mSystemUiVisibility;
3026 final int newVal = (oldVal&~mask) | (vis&mask);
3027 final int diff = newVal ^ oldVal;
John Spurlockcd686b52013-06-05 10:13:46 -04003028 if (DEBUG) Log.d(TAG, String.format(
John Spurlockdcf4f212013-05-21 17:19:53 -04003029 "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
3030 Integer.toHexString(vis), Integer.toHexString(mask),
3031 Integer.toHexString(oldVal), Integer.toHexString(newVal),
3032 Integer.toHexString(diff)));
Jorim Jaggi86905582016-02-09 21:36:09 -08003033 boolean sbModeChanged = false;
Daniel Sandlere137a1e2011-08-17 16:47:19 -04003034 if (diff != 0) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07003035 mSystemUiVisibility = newVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04003036
John Spurlocke1f366f2013-08-05 12:22:40 -04003037 // update low profile
3038 if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
John Spurlock7edfbca2013-09-14 11:58:55 -04003039 setAreThereNotifications();
Daniel Sandler60ee2562011-07-22 12:34:33 -04003040 }
3041
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003042 // ready to unhide
3043 if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
3044 mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
3045 mNoAnimationOnNextBarModeChange = true;
3046 }
3047
John Spurlocke1f366f2013-08-05 12:22:40 -04003048 // update status bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04003049 final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003050 View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT,
3051 View.STATUS_BAR_TRANSPARENT);
John Spurlocke1f366f2013-08-05 12:22:40 -04003052
3053 // update navigation bar mode
John Spurlockd4e65752013-08-28 14:17:09 -04003054 final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
John Spurlockf6b63972013-08-27 16:08:28 -04003055 oldVal, newVal, mNavigationBarView.getBarTransitions(),
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003056 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
3057 View.NAVIGATION_BAR_TRANSPARENT);
Jorim Jaggi86905582016-02-09 21:36:09 -08003058 sbModeChanged = sbMode != -1;
John Spurlockd4e65752013-08-28 14:17:09 -04003059 final boolean nbModeChanged = nbMode != -1;
3060 boolean checkBarModes = false;
3061 if (sbModeChanged && sbMode != mStatusBarMode) {
3062 mStatusBarMode = sbMode;
3063 checkBarModes = true;
3064 }
3065 if (nbModeChanged && nbMode != mNavigationBarMode) {
3066 mNavigationBarMode = nbMode;
3067 checkBarModes = true;
3068 }
3069 if (checkBarModes) {
3070 checkBarModes();
3071 }
3072 if (sbModeChanged || nbModeChanged) {
John Spurlocke1f366f2013-08-05 12:22:40 -04003073 // update transient bar autohide
John Spurlockc6d1c602014-01-17 15:22:06 -05003074 if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
John Spurlock32beb2c2013-03-11 10:16:47 -04003075 scheduleAutohide();
3076 } else {
John Spurlock32beb2c2013-03-11 10:16:47 -04003077 cancelAutohide();
3078 }
3079 }
John Spurlocke1f366f2013-08-05 12:22:40 -04003080
John Spurlock5b9145b2013-08-20 15:13:47 -04003081 if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
3082 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
3083 }
3084
John Spurlocke1f366f2013-08-05 12:22:40 -04003085 // send updated sysui visibility to window manager
John Spurlock32beb2c2013-03-11 10:16:47 -04003086 notifyUiVisibilityChanged(mSystemUiVisibility);
Joe Onorato93056472010-09-10 10:30:46 -04003087 }
Jorim Jaggi86905582016-02-09 21:36:09 -08003088
3089 mLightStatusBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,
3090 mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04003091 }
3092
John Spurlockd4e65752013-08-28 14:17:09 -04003093 private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003094 int transientFlag, int translucentFlag, int transparentFlag) {
3095 final int oldMode = barMode(oldVis, transientFlag, translucentFlag, transparentFlag);
3096 final int newMode = barMode(newVis, transientFlag, translucentFlag, transparentFlag);
John Spurlocke1f366f2013-08-05 12:22:40 -04003097 if (oldMode == newMode) {
3098 return -1; // no mode change
3099 }
John Spurlocke1f366f2013-08-05 12:22:40 -04003100 return newMode;
3101 }
3102
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003103 private int barMode(int vis, int transientFlag, int translucentFlag, int transparentFlag) {
3104 int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | transparentFlag;
John Spurlock89835dd2013-08-16 15:06:51 -04003105 return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
John Spurlockbd957402013-10-03 11:38:39 -04003106 : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT
Adrian Roosc0f0a742014-10-28 16:39:56 +01003107 : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT
Jorim Jaggi4fa78922015-11-30 17:13:56 -08003108 : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
John Spurlock7edfbca2013-09-14 11:58:55 -04003109 : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
John Spurlock3b139a92013-08-17 17:18:08 -04003110 : MODE_OPAQUE;
John Spurlocke1f366f2013-08-05 12:22:40 -04003111 }
3112
John Spurlockd4e65752013-08-28 14:17:09 -04003113 private void checkBarModes() {
John Spurlock3c875662013-08-31 15:07:25 -04003114 if (mDemoMode) return;
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003115 checkBarMode(mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions(),
3116 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04003117 if (mNavigationBarView != null) {
3118 checkBarMode(mNavigationBarMode,
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003119 mNavigationBarWindowState, mNavigationBarView.getBarTransitions(),
3120 mNoAnimationOnNextBarModeChange);
John Spurlockd4e65752013-08-28 14:17:09 -04003121 }
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003122 mNoAnimationOnNextBarModeChange = false;
John Spurlockd4e65752013-08-28 14:17:09 -04003123 }
3124
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003125 private void checkBarMode(int mode, int windowState, BarTransitions transitions,
3126 boolean noAnimation) {
John Spurlock0ff62e02014-07-22 16:15:08 -04003127 final boolean powerSave = mBatteryController.isPowerSave();
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07003128 final boolean anim = !noAnimation && mDeviceInteractive
Selim Cinek4a4a2bddc2015-05-07 12:50:19 -07003129 && windowState != WINDOW_STATE_HIDDEN && !powerSave;
John Spurlock1bb480a2014-08-02 17:12:43 -04003130 if (powerSave && getBarState() == StatusBarState.SHADE) {
John Spurlock0ff62e02014-07-22 16:15:08 -04003131 mode = MODE_WARNING;
3132 }
John Spurlockc68d5772013-10-08 11:47:58 -04003133 transitions.transitionTo(mode, anim);
John Spurlockd4e65752013-08-28 14:17:09 -04003134 }
3135
John Spurlock42197262013-10-21 09:32:25 -04003136 private void finishBarAnimations() {
3137 mStatusBarView.getBarTransitions().finishAnimations();
3138 if (mNavigationBarView != null) {
3139 mNavigationBarView.getBarTransitions().finishAnimations();
3140 }
3141 }
3142
John Spurlockd4e65752013-08-28 14:17:09 -04003143 private final Runnable mCheckBarModes = new Runnable() {
John Spurlock5b9145b2013-08-20 15:13:47 -04003144 @Override
3145 public void run() {
John Spurlockd4e65752013-08-28 14:17:09 -04003146 checkBarModes();
John Spurlock0ff62e02014-07-22 16:15:08 -04003147 }
3148 };
John Spurlock5b9145b2013-08-20 15:13:47 -04003149
John Spurlockad3e6cb2013-04-30 08:47:43 -04003150 @Override
John Spurlockcfc359a2013-09-05 10:42:03 -04003151 public void setInteracting(int barWindow, boolean interacting) {
John Spurlock7fbf5732014-11-18 11:40:22 -05003152 final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
John Spurlockcfc359a2013-09-05 10:42:03 -04003153 mInteractingWindows = interacting
3154 ? (mInteractingWindows | barWindow)
3155 : (mInteractingWindows & ~barWindow);
3156 if (mInteractingWindows != 0) {
John Spurlockd4e65752013-08-28 14:17:09 -04003157 suspendAutohide();
3158 } else {
3159 resumeSuspendedAutohide();
3160 }
John Spurlock7fbf5732014-11-18 11:40:22 -05003161 // manually dismiss the volume panel when interacting with the nav bar
3162 if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) {
John Spurlockb349af572015-04-29 12:24:19 -04003163 dismissVolumeDialog();
John Spurlock7fbf5732014-11-18 11:40:22 -05003164 }
John Spurlockd4e65752013-08-28 14:17:09 -04003165 checkBarModes();
3166 }
3167
John Spurlockb349af572015-04-29 12:24:19 -04003168 private void dismissVolumeDialog() {
3169 if (mVolumeComponent != null) {
3170 mVolumeComponent.dismissNow();
3171 }
3172 }
3173
John Spurlockd4e65752013-08-28 14:17:09 -04003174 private void resumeSuspendedAutohide() {
John Spurlockad3e6cb2013-04-30 08:47:43 -04003175 if (mAutohideSuspended) {
3176 scheduleAutohide();
John Spurlockd4e65752013-08-28 14:17:09 -04003177 mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
John Spurlock3b139a92013-08-17 17:18:08 -04003178 }
3179 }
3180
John Spurlockd4e65752013-08-28 14:17:09 -04003181 private void suspendAutohide() {
John Spurlock32beb2c2013-03-11 10:16:47 -04003182 mHandler.removeCallbacks(mAutohide);
John Spurlockd4e65752013-08-28 14:17:09 -04003183 mHandler.removeCallbacks(mCheckBarModes);
John Spurlock5b9145b2013-08-20 15:13:47 -04003184 mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
John Spurlock32beb2c2013-03-11 10:16:47 -04003185 }
3186
3187 private void cancelAutohide() {
3188 mAutohideSuspended = false;
3189 mHandler.removeCallbacks(mAutohide);
3190 }
3191
3192 private void scheduleAutohide() {
3193 cancelAutohide();
3194 mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
3195 }
3196
John Spurlock9deaa282013-07-25 13:03:47 -04003197 private void checkUserAutohide(View v, MotionEvent event) {
John Spurlocke1f366f2013-08-05 12:22:40 -04003198 if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
John Spurlock9deaa282013-07-25 13:03:47 -04003199 && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
3200 && event.getX() == 0 && event.getY() == 0 // a touch outside both bars
Adrian Roos5e476452016-05-27 12:07:33 -07003201 && !mRemoteInputController.isRemoteInputActive()) { // not due to typing in IME
John Spurlock9deaa282013-07-25 13:03:47 -04003202 userAutohide();
3203 }
3204 }
3205
3206 private void userAutohide() {
3207 cancelAutohide();
John Spurlock5b9145b2013-08-20 15:13:47 -04003208 mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
John Spurlock9deaa282013-07-25 13:03:47 -04003209 }
3210
Daniel Sandlerd7e96862012-04-26 01:10:29 -04003211 private boolean areLightsOn() {
3212 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
3213 }
Jim Millera073e572012-05-23 17:03:27 -07003214
Daniel Sandler60ee2562011-07-22 12:34:33 -04003215 public void setLightsOn(boolean on) {
3216 Log.v(TAG, "setLightsOn(" + on + ")");
3217 if (on) {
Jorim Jaggi86905582016-02-09 21:36:09 -08003218 setSystemUiVisibility(0, 0, 0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
3219 mLastFullscreenStackBounds, mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04003220 } else {
Jorim Jaggi86905582016-02-09 21:36:09 -08003221 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, 0, 0,
3222 View.SYSTEM_UI_FLAG_LOW_PROFILE, mLastFullscreenStackBounds,
3223 mLastDockedStackBounds);
Daniel Sandler60ee2562011-07-22 12:34:33 -04003224 }
3225 }
3226
John Spurlock32beb2c2013-03-11 10:16:47 -04003227 private void notifyUiVisibilityChanged(int vis) {
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04003228 try {
Adrian Roos389beec2015-05-12 13:33:25 -07003229 if (mLastDispatchedSystemUiVisibility != vis) {
3230 mWindowManagerService.statusBarVisibilityChanged(vis);
3231 mLastDispatchedSystemUiVisibility = vis;
3232 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04003233 } catch (RemoteException ex) {
3234 }
Joe Onorato93056472010-09-10 10:30:46 -04003235 }
3236
Jim Miller07e03842016-06-22 15:18:13 -07003237 @Override
Daniel Sandler5c8da942011-06-28 00:29:04 -04003238 public void topAppWindowChanged(boolean showMenu) {
Chris Wren8a1638f2016-05-02 16:19:14 -04003239 if (SPEW) {
John Spurlockcd686b52013-06-05 10:13:46 -04003240 Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandler5c8da942011-06-28 00:29:04 -04003241 }
3242 if (mNavigationBarView != null) {
Daniel Sandlerf1ebcee2011-09-15 16:02:56 -04003243 mNavigationBarView.setMenuVisibility(showMenu);
Daniel Sandler5c8da942011-06-28 00:29:04 -04003244 }
3245
3246 // See above re: lights-out policy for legacy apps.
3247 if (showMenu) setLightsOn(true);
3248 }
3249
Daniel Sandler328310c2011-09-23 15:56:52 -04003250 @Override
Jason Monkb605fec2014-05-02 17:04:10 -04003251 public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
3252 boolean showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04003253 boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
3254 int flags = mNavigationIconHints;
3255 if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
3256 flags |= NAVIGATION_HINT_BACK_ALT;
3257 } else {
3258 flags &= ~NAVIGATION_HINT_BACK_ALT;
3259 }
Jason Monkb605fec2014-05-02 17:04:10 -04003260 if (showImeSwitcher) {
Jason Monkf1ff2092014-04-29 16:50:53 -04003261 flags |= NAVIGATION_HINT_IME_SHOWN;
3262 } else {
3263 flags &= ~NAVIGATION_HINT_IME_SHOWN;
3264 }
Daniel Sandler328310c2011-09-23 15:56:52 -04003265
Jason Monkf1ff2092014-04-29 16:50:53 -04003266 setNavigationIconHints(flags);
Daniel Sandler328310c2011-09-23 15:56:52 -04003267 }
3268
Daniel Sandler48852952011-12-01 14:34:23 -05003269 public static String viewInfo(View v) {
3270 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
3271 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Joe Onorato808182d2010-07-09 18:52:06 -04003272 }
3273
Jim Miller07e03842016-06-22 15:18:13 -07003274 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04003275 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato808182d2010-07-09 18:52:06 -04003276 synchronized (mQueueLock) {
3277 pw.println("Current Status Bar state:");
Daniel Sandlere7237fc2012-08-14 16:08:27 -04003278 pw.println(" mExpandedVisible=" + mExpandedVisible
Daniel Sandlerfdbac772012-07-03 14:30:10 -04003279 + ", mTrackingPosition=" + mTrackingPosition);
Joe Onorato808182d2010-07-09 18:52:06 -04003280 pw.println(" mTracking=" + mTracking);
Daniel Sandler36412a72011-08-04 09:35:13 -04003281 pw.println(" mDisplayMetrics=" + mDisplayMetrics);
Selim Cinekb6d85eb2014-03-28 20:21:01 +01003282 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
Selim Cinekb6d85eb2014-03-28 20:21:01 +01003283 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
3284 + " scroll " + mStackScroller.getScrollX()
3285 + "," + mStackScroller.getScrollY());
Joe Onorato808182d2010-07-09 18:52:06 -04003286 }
Joe Onorato808182d2010-07-09 18:52:06 -04003287
John Spurlockcfc359a2013-09-05 10:42:03 -04003288 pw.print(" mInteractingWindows="); pw.println(mInteractingWindows);
John Spurlock0ec64c62013-08-26 15:37:58 -04003289 pw.print(" mStatusBarWindowState=");
3290 pw.println(windowStateToString(mStatusBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04003291 pw.print(" mStatusBarMode=");
3292 pw.println(BarTransitions.modeToString(mStatusBarMode));
John Spurlockbf370992014-06-17 13:58:31 -04003293 pw.print(" mDozing="); pw.println(mDozing);
John Spurlocke677d712014-02-13 12:52:19 -05003294 pw.print(" mZenMode=");
3295 pw.println(Settings.Global.zenModeToString(mZenMode));
Chris Wren3b6745b2014-03-07 14:34:35 -05003296 pw.print(" mUseHeadsUp=");
3297 pw.println(mUseHeadsUp);
John Spurlock0ec64c62013-08-26 15:37:58 -04003298 dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
3299 if (mNavigationBarView != null) {
3300 pw.print(" mNavigationBarWindowState=");
3301 pw.println(windowStateToString(mNavigationBarWindowState));
John Spurlockd4e65752013-08-28 14:17:09 -04003302 pw.print(" mNavigationBarMode=");
3303 pw.println(BarTransitions.modeToString(mNavigationBarMode));
John Spurlock0ec64c62013-08-26 15:37:58 -04003304 dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
3305 }
3306
Daniel Sandler48852952011-12-01 14:34:23 -05003307 pw.print(" mNavigationBarView=");
3308 if (mNavigationBarView == null) {
3309 pw.println("null");
3310 } else {
3311 mNavigationBarView.dump(fd, pw, args);
3312 }
3313
Dan Sandler16128f42014-05-21 12:48:22 -04003314 pw.print(" mMediaSessionManager=");
3315 pw.println(mMediaSessionManager);
3316 pw.print(" mMediaNotificationKey=");
3317 pw.println(mMediaNotificationKey);
3318 pw.print(" mMediaController=");
3319 pw.print(mMediaController);
3320 if (mMediaController != null) {
3321 pw.print(" state=" + mMediaController.getPlaybackState());
3322 }
3323 pw.println();
3324 pw.print(" mMediaMetadata=");
3325 pw.print(mMediaMetadata);
3326 if (mMediaMetadata != null) {
RoboErik75847b92014-07-29 13:10:17 -07003327 pw.print(" title=" + mMediaMetadata.getText(MediaMetadata.METADATA_KEY_TITLE));
Dan Sandler16128f42014-05-21 12:48:22 -04003328 }
3329 pw.println();
3330
Daniel Sandler37a38aa2013-02-13 17:15:57 -05003331 pw.println(" Panels: ");
3332 if (mNotificationPanel != null) {
3333 pw.println(" mNotificationPanel=" +
3334 mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug(""));
3335 pw.print (" ");
3336 mNotificationPanel.dump(fd, pw, args);
3337 }
Daniel Sandler37a38aa2013-02-13 17:15:57 -05003338
John Spurlock813552c2014-09-19 08:30:21 -04003339 DozeLog.dump(pw);
3340
Daniel Sandler7579bca2011-08-18 15:47:26 -04003341 if (DUMPTRUCK) {
3342 synchronized (mNotificationData) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02003343 mNotificationData.dump(pw, " ");
Daniel Sandler7579bca2011-08-18 15:47:26 -04003344 }
3345
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003346 mIconController.dump(pw);
Jim Miller5e6af442011-12-02 18:24:26 -08003347
Daniel Sandler89d97132011-09-08 15:31:57 -04003348 if (false) {
3349 pw.println("see the logcat for a dump of the views we have created.");
3350 // must happen on ui thread
3351 mHandler.post(new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003352 @Override
Daniel Sandler89d97132011-09-08 15:31:57 -04003353 public void run() {
3354 mStatusBarView.getLocationOnScreen(mAbsPos);
John Spurlockcd686b52013-06-05 10:13:46 -04003355 Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
Daniel Sandler89d97132011-09-08 15:31:57 -04003356 + ") " + mStatusBarView.getWidth() + "x"
Daniel Sandlera310af82012-04-24 01:20:13 -04003357 + getStatusBarHeight());
Daniel Sandler89d97132011-09-08 15:31:57 -04003358 mStatusBarView.debug();
Daniel Sandler89d97132011-09-08 15:31:57 -04003359 }
3360 });
3361 }
Joe Onorato808182d2010-07-09 18:52:06 -04003362 }
Daniel Sandler89d97132011-09-08 15:31:57 -04003363
Daniel Sandler151f00d2012-10-02 22:33:08 -04003364 if (DEBUG_GESTURES) {
3365 pw.print(" status bar gestures: ");
3366 mGestureRec.dump(fd, pw, args);
3367 }
Selim Cinek7025f262015-07-13 16:22:48 -07003368 if (mStatusBarWindowManager != null) {
3369 mStatusBarWindowManager.dump(fd, pw, args);
3370 }
John Spurlock486b78e2014-07-07 08:37:56 -04003371 if (mNetworkController != null) {
3372 mNetworkController.dump(fd, pw, args);
3373 }
3374 if (mBluetoothController != null) {
3375 mBluetoothController.dump(fd, pw, args);
3376 }
Jason Monkdd5bdc62015-07-20 12:18:38 -04003377 if (mHotspotController != null) {
3378 mHotspotController.dump(fd, pw, args);
3379 }
John Spurlock1e6eb172014-07-13 11:59:50 -04003380 if (mCastController != null) {
3381 mCastController.dump(fd, pw, args);
3382 }
Adrian Roos00a0b1f2014-07-16 16:44:49 +02003383 if (mUserSwitcherController != null) {
3384 mUserSwitcherController.dump(fd, pw, args);
3385 }
John Spurlock0ff62e02014-07-22 16:15:08 -04003386 if (mBatteryController != null) {
3387 mBatteryController.dump(fd, pw, args);
3388 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02003389 if (mNextAlarmController != null) {
3390 mNextAlarmController.dump(fd, pw, args);
3391 }
Jason Monk3d5f5512014-07-25 11:17:28 -04003392 if (mSecurityController != null) {
3393 mSecurityController.dump(fd, pw, args);
3394 }
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003395 if (mHeadsUpManager != null) {
3396 mHeadsUpManager.dump(fd, pw, args);
Chris Wren428c6b62014-12-05 16:07:06 -05003397 } else {
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003398 pw.println(" mHeadsUpManager: null");
Chris Wren428c6b62014-12-05 16:07:06 -05003399 }
Selim Cinek52941c52016-05-07 18:29:32 -04003400 if (mGroupManager != null) {
3401 mGroupManager.dump(fd, pw, args);
3402 } else {
3403 pw.println(" mGroupManager: null");
3404 }
Jason Monkab525272015-07-13 17:02:49 -04003405 if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
3406 KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
3407 }
Jason Monkad32c552016-10-04 14:50:11 -04003408 if (mFlashlightController != null) {
3409 mFlashlightController.dump(fd, pw, args);
3410 }
Chris Wren428c6b62014-12-05 16:07:06 -05003411
Adrian Roos401caae2016-03-04 13:35:21 -08003412 FalsingManager.getInstance(mContext).dump(pw);
3413 FalsingLog.dump(pw);
3414
John Spurlock7bbb9f62014-10-21 12:15:28 -04003415 pw.println("SharedPreferences:");
Andrew Flynn82862572015-04-01 14:22:37 -04003416 for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
John Spurlock7bbb9f62014-10-21 12:15:28 -04003417 pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
3418 }
Joe Onorato808182d2010-07-09 18:52:06 -04003419 }
3420
John Spurlock0ec64c62013-08-26 15:37:58 -04003421 private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
3422 pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
3423 pw.println(BarTransitions.modeToString(transitions.getMode()));
3424 }
3425
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05003426 @Override
3427 public void createAndAddWindows() {
3428 addStatusBarWindow();
Joe Onorato808182d2010-07-09 18:52:06 -04003429 }
Jim Millere898ac52012-04-06 17:10:57 -07003430
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05003431 private void addStatusBarWindow() {
Daniel Sandlera310af82012-04-24 01:20:13 -04003432 makeStatusBarView();
Jorim Jaggi5cf17872014-03-26 18:31:48 +01003433 mStatusBarWindowManager = new StatusBarWindowManager(mContext);
Adrian Roos1c0ca502015-10-07 12:20:42 -07003434 mRemoteInputController = new RemoteInputController(mStatusBarWindowManager,
3435 mHeadsUpManager);
Jorim Jaggi5cf17872014-03-26 18:31:48 +01003436 mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
Joe Onorato808182d2010-07-09 18:52:06 -04003437 }
3438
Daniel Sandler747a9e92012-08-10 16:39:19 -04003439 // called by makeStatusbar and also by PhoneStatusBarView
Dianne Hackborn1dacf272011-08-02 15:01:22 -07003440 void updateDisplaySize() {
Daniel Sandler36412a72011-08-04 09:35:13 -04003441 mDisplay.getMetrics(mDisplayMetrics);
Daniel Sandler7e8ae502013-10-10 23:38:19 -04003442 mDisplay.getSize(mCurrentDisplaySize);
Daniel Sandler151f00d2012-10-02 22:33:08 -04003443 if (DEBUG_GESTURES) {
John Spurlock209bede2013-07-17 12:23:27 -04003444 mGestureRec.tag("display",
Daniel Sandler151f00d2012-10-02 22:33:08 -04003445 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
3446 }
Dianne Hackborn1dacf272011-08-02 15:01:22 -07003447 }
3448
Christoph Studerb0183992014-12-22 21:02:26 +01003449 float getDisplayDensity() {
3450 return mDisplayMetrics.density;
3451 }
3452
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003453 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
Jorim Jaggid9449862015-05-29 14:49:08 -07003454 boolean dismissShade) {
3455 startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, null /* callback */);
3456 }
3457
3458 public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
3459 final boolean dismissShade, final Callback callback) {
Daniel Sandler3679bf52012-10-16 21:30:28 -04003460 if (onlyProvisioned && !isDeviceProvisioned()) return;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003461
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003462 final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
3463 mContext, intent, mCurrentUserId);
Jorim Jaggic7dea6e2014-07-26 14:36:57 +02003464 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Selim Cineke70d6532015-04-24 16:46:13 -07003465 Runnable runnable = new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003466 @Override
Selim Cineke70d6532015-04-24 16:46:13 -07003467 public void run() {
Jorim Jaggib835dd72015-06-08 12:28:42 -07003468 mAssistManager.hideAssist();
Selim Cineke70d6532015-04-24 16:46:13 -07003469 intent.setFlags(
3470 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Jorim Jaggid9449862015-05-29 14:49:08 -07003471 int result = ActivityManager.START_CANCELED;
Robert Carrfd10cd12016-06-29 16:41:50 -07003472 ActivityOptions options = new ActivityOptions(getActivityOptions());
3473 if (intent == KeyguardBottomAreaView.INSECURE_CAMERA_INTENT) {
3474 // Normally an activity will set it's requested rotation
3475 // animation on its window. However when launching an activity
3476 // causes the orientation to change this is too late. In these cases
3477 // the default animation is used. This doesn't look good for
3478 // the camera (as it rotates the camera contents out of sync
3479 // with physical reality). So, we ask the WindowManager to
3480 // force the crossfade animation if an orientation change
3481 // happens to occur during the launch.
3482 options.setRotationAnimationHint(
Robert Carr57d9fbd2016-08-15 12:00:35 -07003483 WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
Robert Carrfd10cd12016-06-29 16:41:50 -07003484 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003485 try {
3486 result = ActivityManagerNative.getDefault().startActivityAsUser(
3487 null, mContext.getBasePackageName(),
3488 intent,
3489 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Jorim Jaggie6e108e2016-03-28 13:38:45 -07003490 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
Robert Carrfd10cd12016-06-29 16:41:50 -07003491 options.toBundle(), UserHandle.CURRENT.getIdentifier());
Jorim Jaggid9449862015-05-29 14:49:08 -07003492 } catch (RemoteException e) {
3493 Log.w(TAG, "Unable to start activity", e);
3494 }
Selim Cineke70d6532015-04-24 16:46:13 -07003495 overrideActivityPendingAppTransition(
3496 keyguardShowing && !afterKeyguardGone);
Jorim Jaggid9449862015-05-29 14:49:08 -07003497 if (callback != null) {
3498 callback.onActivityStarted(result);
3499 }
Selim Cineke70d6532015-04-24 16:46:13 -07003500 }
3501 };
Jorim Jaggid9449862015-05-29 14:49:08 -07003502 Runnable cancelRunnable = new Runnable() {
3503 @Override
3504 public void run() {
Jorim Jaggi5cc86592015-06-08 14:48:28 -07003505 if (callback != null) {
3506 callback.onActivityStarted(ActivityManager.START_CANCELED);
3507 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003508 }
3509 };
Jorim Jaggib835dd72015-06-08 12:28:42 -07003510 executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShade,
Felipe Lemeee5d6302016-04-22 16:11:19 -07003511 afterKeyguardGone, true /* deferred */);
Selim Cineke70d6532015-04-24 16:46:13 -07003512 }
3513
3514 public void executeRunnableDismissingKeyguard(final Runnable runnable,
Jorim Jaggid9449862015-05-29 14:49:08 -07003515 final Runnable cancelAction,
Selim Cineke70d6532015-04-24 16:46:13 -07003516 final boolean dismissShade,
Felipe Lemeee5d6302016-04-22 16:11:19 -07003517 final boolean afterKeyguardGone,
3518 final boolean deferred) {
Selim Cineke70d6532015-04-24 16:46:13 -07003519 final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Adrian Roos4314f6d2014-05-28 14:10:27 +02003520 dismissKeyguardThenExecute(new OnDismissAction() {
3521 @Override
3522 public boolean onDismiss() {
Selim Cinekbaa23272014-07-08 18:01:07 +02003523 AsyncTask.execute(new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003524 @Override
Selim Cinekbaa23272014-07-08 18:01:07 +02003525 public void run() {
3526 try {
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003527 if (keyguardShowing && !afterKeyguardGone) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003528 ActivityManagerNative.getDefault()
3529 .keyguardWaitingForActivityDrawn();
3530 }
Selim Cineke70d6532015-04-24 16:46:13 -07003531 if (runnable != null) {
3532 runnable.run();
3533 }
Selim Cinekbaa23272014-07-08 18:01:07 +02003534 } catch (RemoteException e) {
3535 }
3536 }
3537 });
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003538 if (dismissShade) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -07003539 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
3540 true /* delayed*/);
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02003541 }
Felipe Lemeee5d6302016-04-22 16:11:19 -07003542 return deferred;
Adrian Roos4314f6d2014-05-28 14:10:27 +02003543 }
Jorim Jaggid9449862015-05-29 14:49:08 -07003544 }, cancelAction, afterKeyguardGone);
Daniel Sandler3679bf52012-10-16 21:30:28 -04003545 }
3546
Joe Onorato808182d2010-07-09 18:52:06 -04003547 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Miller07e03842016-06-22 15:18:13 -07003548 @Override
Joe Onorato808182d2010-07-09 18:52:06 -04003549 public void onReceive(Context context, Intent intent) {
John Spurlockcd686b52013-06-05 10:13:46 -04003550 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
Joe Onorato808182d2010-07-09 18:52:06 -04003551 String action = intent.getAction();
Daniel Sandlered930e52012-07-03 14:31:22 -04003552 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
Andrei Stingaceanuf86bc972016-04-12 15:29:25 +01003553 KeyboardShortcuts.dismiss();
Adrian Roos07215352016-06-23 11:19:28 -07003554 if (mRemoteInputController != null) {
3555 mRemoteInputController.closeRemoteInputs();
3556 }
Kenny Guy44fc65f2014-11-28 22:18:14 +00003557 if (isCurrentProfile(getSendingUserId())) {
3558 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
3559 String reason = intent.getStringExtra("reason");
3560 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
3561 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
3562 }
3563 animateCollapsePanels(flags);
Michael Jurka3b1fc472011-06-13 10:54:40 -07003564 }
Joe Onorato808182d2010-07-09 18:52:06 -04003565 }
Daniel Sandlered930e52012-07-03 14:31:22 -04003566 else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003567 notifyNavigationBarScreenOn(false);
Selim Cinekb8f09cf2015-03-16 17:09:28 -07003568 notifyHeadsUpScreenOff();
John Spurlock42197262013-10-21 09:32:25 -04003569 finishBarAnimations();
Selim Cinekccd14fb2014-08-12 18:53:24 +02003570 resetUserExpandedStates();
Daniel Sandlered930e52012-07-03 14:31:22 -04003571 }
Daniel Sandler7f3cf952012-08-31 14:57:09 -04003572 else if (Intent.ACTION_SCREEN_ON.equals(action)) {
John Spurlock1bbd49d2012-10-19 11:09:32 -04003573 notifyNavigationBarScreenOn(true);
Joe Onorato808182d2010-07-09 18:52:06 -04003574 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003575 }
3576 };
3577
3578 private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
Jim Miller07e03842016-06-22 15:18:13 -07003579 @Override
Adrian Roos8e3e8362015-07-16 19:42:22 -07003580 public void onReceive(Context context, Intent intent) {
3581 if (DEBUG) Log.v(TAG, "onReceive: " + intent);
3582 String action = intent.getAction();
3583 if (ACTION_DEMO.equals(action)) {
John Spurlock3c875662013-08-31 15:07:25 -04003584 Bundle bundle = intent.getExtras();
3585 if (bundle != null) {
3586 String command = bundle.getString("command", "").trim().toLowerCase();
3587 if (command.length() > 0) {
3588 try {
3589 dispatchDemoCommand(command, bundle);
3590 } catch (Throwable t) {
3591 Log.w(TAG, "Error running demo command, intent=" + intent, t);
3592 }
3593 }
3594 }
Adrian Roos8e3e8362015-07-16 19:42:22 -07003595 } else if (ACTION_FAKE_ARTWORK.equals(action)) {
Dan Sandler16128f42014-05-21 12:48:22 -04003596 if (DEBUG_MEDIA_FAKE_ARTWORK) {
Adrian Roos52738322016-01-29 08:49:21 -08003597 updateMediaMetaData(true, true);
Dan Sandler16128f42014-05-21 12:48:22 -04003598 }
John Spurlock3c875662013-08-31 15:07:25 -04003599 }
Joe Onorato808182d2010-07-09 18:52:06 -04003600 }
3601 };
3602
Selim Cinek78f40082016-03-10 18:06:27 -08003603 public void resetUserExpandedStates() {
Selim Cinekccd14fb2014-08-12 18:53:24 +02003604 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
3605 final int notificationCount = activeNotifications.size();
3606 for (int i = 0; i < notificationCount; i++) {
3607 NotificationData.Entry entry = activeNotifications.get(i);
3608 if (entry.row != null) {
3609 entry.row.resetUserExpansion();
3610 }
3611 }
3612 }
3613
Adrian Roos7d7090d2014-05-21 13:10:23 +02003614 @Override
Jorim Jaggid9449862015-05-29 14:49:08 -07003615 protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
3616 dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
3617 }
3618
Jason Monkabe19742015-09-29 09:47:06 -04003619 public void dismissKeyguard() {
3620 mStatusBarKeyguardViewManager.dismiss();
3621 }
3622
Jorim Jaggid9449862015-05-29 14:49:08 -07003623 private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
Jorim Jaggi746f7fa2014-08-27 17:52:46 +02003624 boolean afterKeyguardGone) {
Adrian Roos7d7090d2014-05-21 13:10:23 +02003625 if (mStatusBarKeyguardViewManager.isShowing()) {
Jorim Jaggid9449862015-05-29 14:49:08 -07003626 mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
3627 afterKeyguardGone);
Adrian Roos7d7090d2014-05-21 13:10:23 +02003628 } else {
3629 action.onDismiss();
3630 }
3631 }
3632
Daniel Sandler777dcde2013-09-30 10:21:45 -04003633 // SystemUIService notifies SystemBars of configuration changes, which then calls down here
3634 @Override
3635 protected void onConfigurationChanged(Configuration newConfig) {
Selim Cinek3e7592d2016-04-11 09:35:54 +08003636 updateResources();
3637 updateDisplaySize(); // populates mDisplayMetrics
Daniel Sandler777dcde2013-09-30 10:21:45 -04003638 super.onConfigurationChanged(newConfig); // calls refreshLayout
3639
3640 if (DEBUG) {
3641 Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
3642 }
Daniel Sandler777dcde2013-09-30 10:21:45 -04003643
Daniel Sandler777dcde2013-09-30 10:21:45 -04003644 repositionNavigationBar();
Jorim Jaggif6411742014-08-05 17:10:43 +00003645 updateRowStates();
Jason Monk18f99d92014-09-11 13:36:42 -04003646 mScreenPinningRequest.onConfigurationChanged();
Jason Monk1c040db2015-07-20 09:45:54 -04003647 mNetworkController.onConfigurationChanged();
Daniel Sandler777dcde2013-09-30 10:21:45 -04003648 }
3649
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003650 @Override
3651 public void userSwitched(int newUserId) {
Chris Wrena6d4fb62014-11-20 14:46:23 -05003652 super.userSwitched(newUserId);
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003653 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
Daniel Sandler11cf1782012-09-27 14:03:08 -04003654 animateCollapsePanels();
Adrian Roos31b844b2014-11-21 13:55:09 +01003655 updatePublicMode();
Christoph Studer37fe6932014-05-26 13:10:30 +02003656 updateNotifications();
John Spurlock919adac2012-10-02 16:41:12 -04003657 resetUserSetupObserver();
John Spurlock89f060a2014-07-16 21:03:15 -04003658 setControllerUsers();
Julia Reynolds86ef8e22015-09-09 16:42:38 -04003659 clearCurrentMediaNotification();
Vadim Tryshev12a30e82016-02-12 15:39:28 -08003660 mLockscreenWallpaper.setCurrentUser(newUserId);
Jorim Jaggie31f6b82016-07-01 16:15:09 -07003661 mScrimController.setCurrentUser(newUserId);
Adrian Roos52738322016-01-29 08:49:21 -08003662 updateMediaMetaData(true, false);
John Spurlock89f060a2014-07-16 21:03:15 -04003663 }
3664
3665 private void setControllerUsers() {
3666 if (mZenModeController != null) {
3667 mZenModeController.setUserId(mCurrentUserId);
3668 }
Robin Lee63204ee2015-06-04 01:53:01 +01003669 if (mSecurityController != null) {
3670 mSecurityController.onUserSwitched(mCurrentUserId);
3671 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -04003672 }
John Spurlock919adac2012-10-02 16:41:12 -04003673
3674 private void resetUserSetupObserver() {
3675 mContext.getContentResolver().unregisterContentObserver(mUserSetupObserver);
3676 mUserSetupObserver.onChange(false);
3677 mContext.getContentResolver().registerContentObserver(
3678 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), true,
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003679 mUserSetupObserver, mCurrentUserId);
John Spurlock919adac2012-10-02 16:41:12 -04003680 }
3681
Joe Onorato808182d2010-07-09 18:52:06 -04003682 /**
3683 * Reload some of our resources when the configuration changes.
3684 *
3685 * We don't reload everything when the configuration changes -- we probably
3686 * should, but getting that smooth is tough. Someday we'll fix that. In the
3687 * meantime, just update the things that we know change.
3688 */
3689 void updateResources() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003690 // Update the quick setting tiles
John Spurlock7e6809a2014-08-06 16:03:14 -04003691 if (mQSPanel != null) {
3692 mQSPanel.updateResources();
3693 }
Winson Chungd63c59782012-09-05 17:34:41 -07003694
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003695 loadDimens();
John Spurlock7e6809a2014-08-06 16:03:14 -04003696
3697 if (mNotificationPanel != null) {
3698 mNotificationPanel.updateResources();
3699 }
Adrian Roos5fd872e2014-08-12 17:28:58 +02003700 if (mBrightnessMirrorController != null) {
3701 mBrightnessMirrorController.updateResources();
3702 }
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003703 }
Jim Miller5e6af442011-12-02 18:24:26 -08003704
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003705 protected void loadDimens() {
3706 final Resources res = mContext.getResources();
3707
Jorim Jaggi11c62e12016-04-05 20:41:21 -07003708 int oldBarHeight = mNaturalBarHeight;
Daniel Sandler7c3e39d2011-07-29 16:30:49 -04003709 mNaturalBarHeight = res.getDimensionPixelSize(
3710 com.android.internal.R.dimen.status_bar_height);
Jorim Jaggi11c62e12016-04-05 20:41:21 -07003711 if (mStatusBarWindowManager != null && mNaturalBarHeight != oldBarHeight) {
3712 mStatusBarWindowManager.setBarHeight(mNaturalBarHeight);
3713 }
3714 mMaxAllowedKeyguardNotifications = res.getInteger(
3715 R.integer.keyguard_max_notification_count);
Jorim Jaggid4a57442014-04-10 02:45:55 +02003716
Selim Cinek3e7592d2016-04-11 09:35:54 +08003717 if (DEBUG) Log.v(TAG, "defineSlots");
John Spurlock804df702012-06-01 15:34:27 -04003718 }
3719
Christoph Studer92b389d2014-04-01 18:44:40 +02003720 // Visibility reporting
3721
3722 @Override
Christoph Studere8e28652014-10-29 17:27:53 +01003723 protected void handleVisibleToUserChanged(boolean visibleToUser) {
3724 if (visibleToUser) {
3725 super.handleVisibleToUserChanged(visibleToUser);
3726 startNotificationLogging();
Christoph Studer92b389d2014-04-01 18:44:40 +02003727 } else {
Christoph Studer037e34c2014-04-30 20:06:04 +02003728 stopNotificationLogging();
Christoph Studere8e28652014-10-29 17:27:53 +01003729 super.handleVisibleToUserChanged(visibleToUser);
Christoph Studer92b389d2014-04-01 18:44:40 +02003730 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003731 }
3732
Christoph Studer037e34c2014-04-30 20:06:04 +02003733 private void stopNotificationLogging() {
3734 // Report all notifications as invisible and turn down the
3735 // reporter.
3736 if (!mCurrentlyVisibleNotifications.isEmpty()) {
Chris Wrend1dbc922015-06-19 17:51:16 -04003737 logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(),
3738 mCurrentlyVisibleNotifications);
3739 recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
Christoph Studer037e34c2014-04-30 20:06:04 +02003740 }
3741 mHandler.removeCallbacks(mVisibilityReporter);
3742 mStackScroller.setChildLocationsChangedListener(null);
3743 }
3744
Christoph Studere8e28652014-10-29 17:27:53 +01003745 private void startNotificationLogging() {
3746 mStackScroller.setChildLocationsChangedListener(mNotificationLocationsChangedListener);
3747 // Some transitions like mVisibleToUser=false -> mVisibleToUser=true don't
3748 // cause the scroller to emit child location events. Hence generate
3749 // one ourselves to guarantee that we're reporting visible
3750 // notifications.
3751 // (Note that in cases where the scroller does emit events, this
3752 // additional event doesn't break anything.)
3753 mNotificationLocationsChangedListener.onChildLocationsChanged(mStackScroller);
Christoph Studer037e34c2014-04-30 20:06:04 +02003754 }
3755
Christoph Studer92b389d2014-04-01 18:44:40 +02003756 private void logNotificationVisibilityChanges(
Chris Wrend1dbc922015-06-19 17:51:16 -04003757 Collection<NotificationVisibility> newlyVisible,
3758 Collection<NotificationVisibility> noLongerVisible) {
Christoph Studer92b389d2014-04-01 18:44:40 +02003759 if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
3760 return;
3761 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003762 NotificationVisibility[] newlyVisibleAr =
3763 newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]);
3764 NotificationVisibility[] noLongerVisibleAr =
3765 noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]);
Christoph Studer92b389d2014-04-01 18:44:40 +02003766 try {
3767 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
3768 } catch (RemoteException e) {
3769 // Ignore.
3770 }
Chris Wrend1dbc922015-06-19 17:51:16 -04003771
3772 final int N = newlyVisible.size();
Amith Yamasani76495672015-07-07 15:22:54 -07003773 if (N > 0) {
3774 String[] newlyVisibleKeyAr = new String[N];
3775 for (int i = 0; i < N; i++) {
3776 newlyVisibleKeyAr[i] = newlyVisibleAr[i].key;
3777 }
3778
3779 setNotificationsShown(newlyVisibleKeyAr);
Chris Wrend1dbc922015-06-19 17:51:16 -04003780 }
Christoph Studer92b389d2014-04-01 18:44:40 +02003781 }
3782
Christoph Studer2231c6e2014-12-19 12:40:13 +01003783 // State logging
3784
3785 private void logStateToEventlog() {
3786 boolean isShowing = mStatusBarKeyguardViewManager.isShowing();
3787 boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded();
3788 boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
3789 boolean isSecure = mUnlockMethodCache.isMethodSecure();
Selim Cineke8bae622015-07-15 13:24:06 -07003790 boolean canSkipBouncer = mUnlockMethodCache.canSkipBouncer();
Christoph Studer2231c6e2014-12-19 12:40:13 +01003791 int stateFingerprint = getLoggingFingerprint(mState,
3792 isShowing,
3793 isOccluded,
3794 isBouncerShowing,
3795 isSecure,
Selim Cineke8bae622015-07-15 13:24:06 -07003796 canSkipBouncer);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003797 if (stateFingerprint != mLastLoggedStateFingerprint) {
3798 EventLogTags.writeSysuiStatusBarState(mState,
3799 isShowing ? 1 : 0,
3800 isOccluded ? 1 : 0,
3801 isBouncerShowing ? 1 : 0,
3802 isSecure ? 1 : 0,
Selim Cineke8bae622015-07-15 13:24:06 -07003803 canSkipBouncer ? 1 : 0);
Christoph Studer2231c6e2014-12-19 12:40:13 +01003804 mLastLoggedStateFingerprint = stateFingerprint;
3805 }
3806 }
3807
3808 /**
3809 * Returns a fingerprint of fields logged to eventlog
3810 */
3811 private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing,
3812 boolean keyguardOccluded, boolean bouncerShowing, boolean secure,
3813 boolean currentlyInsecure) {
3814 // Reserve 8 bits for statusBarState. We'll never go higher than
3815 // that, right? Riiiight.
3816 return (statusBarState & 0xFF)
3817 | ((keyguardShowing ? 1 : 0) << 8)
3818 | ((keyguardOccluded ? 1 : 0) << 9)
3819 | ((bouncerShowing ? 1 : 0) << 10)
3820 | ((secure ? 1 : 0) << 11)
3821 | ((currentlyInsecure ? 1 : 0) << 12);
3822 }
3823
Joe Onorato808182d2010-07-09 18:52:06 -04003824 //
3825 // tracing
3826 //
3827
3828 void postStartTracing() {
3829 mHandler.postDelayed(mStartTracing, 3000);
3830 }
3831
3832 void vibrate() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04003833 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
3834 Context.VIBRATOR_SERVICE);
John Spurlock7b414672014-07-18 13:02:39 -04003835 vib.vibrate(250, VIBRATION_ATTRIBUTES);
Joe Onorato808182d2010-07-09 18:52:06 -04003836 }
3837
3838 Runnable mStartTracing = new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003839 @Override
Joe Onorato808182d2010-07-09 18:52:06 -04003840 public void run() {
3841 vibrate();
3842 SystemClock.sleep(250);
John Spurlockcd686b52013-06-05 10:13:46 -04003843 Log.d(TAG, "startTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003844 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
3845 mHandler.postDelayed(mStopTracing, 10000);
3846 }
3847 };
3848
3849 Runnable mStopTracing = new Runnable() {
Jim Miller07e03842016-06-22 15:18:13 -07003850 @Override
Joe Onorato808182d2010-07-09 18:52:06 -04003851 public void run() {
3852 android.os.Debug.stopMethodTracing();
John Spurlockcd686b52013-06-05 10:13:46 -04003853 Log.d(TAG, "stopTracing");
Joe Onorato808182d2010-07-09 18:52:06 -04003854 vibrate();
3855 }
3856 };
Chris Wren0c8275b2012-05-08 13:36:48 -04003857
3858 @Override
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -07003859 public boolean shouldDisableNavbarGestures() {
Jorim Jaggi18976a52015-07-24 13:18:19 -07003860 return !isDeviceProvisioned() || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07003861 }
Joe Onorato808182d2010-07-09 18:52:06 -04003862
Jason Monkba2318e2015-12-08 09:04:23 -05003863 public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
3864 mHandler.post(new Runnable() {
3865 @Override
3866 public void run() {
3867 mLeaveOpenOnKeyguardHide = true;
Felipe Lemeee5d6302016-04-22 16:11:19 -07003868 executeRunnableDismissingKeyguard(runnable, null, false, false, false);
Jason Monkba2318e2015-12-08 09:04:23 -05003869 }
3870 });
3871 }
3872
Adrian Roos62692b22015-09-11 17:46:23 -07003873 public void postStartActivityDismissingKeyguard(final PendingIntent intent) {
3874 mHandler.post(new Runnable() {
3875 @Override
3876 public void run() {
3877 startPendingIntentDismissingKeyguard(intent);
3878 }
3879 });
3880 }
3881
Jason Monkee43cdf2015-06-19 14:20:46 -04003882 public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
John Spurlockd47a3f32014-05-18 19:14:14 -04003883 mHandler.postDelayed(new Runnable() {
John Spurlockaf8d6c42014-05-07 17:49:08 -04003884 @Override
3885 public void run() {
Jason Monkee43cdf2015-06-19 14:20:46 -04003886 handleStartActivityDismissingKeyguard(intent, true /*onlyProvisioned*/);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003887 }
John Spurlockd47a3f32014-05-18 19:14:14 -04003888 }, delay);
John Spurlockaf8d6c42014-05-07 17:49:08 -04003889 }
3890
Jason Monkee43cdf2015-06-19 14:20:46 -04003891 private void handleStartActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
Jorim Jaggi85dc23c2014-09-08 14:42:29 +02003892 startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
John Spurlockde547002014-02-28 17:50:39 -05003893 }
3894
Romain Guy648342f2012-05-25 10:44:45 -07003895 private static class FastColorDrawable extends Drawable {
3896 private final int mColor;
3897
3898 public FastColorDrawable(int color) {
3899 mColor = 0xff000000 | color;
3900 }
3901
3902 @Override
3903 public void draw(Canvas canvas) {
3904 canvas.drawColor(mColor, PorterDuff.Mode.SRC);
3905 }
3906
3907 @Override
3908 public void setAlpha(int alpha) {
3909 }
3910
3911 @Override
Chris Craikbd3bfc52015-03-02 10:43:29 -08003912 public void setColorFilter(ColorFilter colorFilter) {
Romain Guy648342f2012-05-25 10:44:45 -07003913 }
3914
3915 @Override
3916 public int getOpacity() {
3917 return PixelFormat.OPAQUE;
3918 }
3919
3920 @Override
3921 public void setBounds(int left, int top, int right, int bottom) {
3922 }
3923
3924 @Override
3925 public void setBounds(Rect bounds) {
3926 }
3927 }
John Spurlock5c454122013-06-17 07:35:46 -04003928
3929 @Override
3930 public void destroy() {
3931 super.destroy();
3932 if (mStatusBarWindow != null) {
3933 mWindowManager.removeViewImmediate(mStatusBarWindow);
John Spurlockab847cf2014-01-15 14:13:59 -05003934 mStatusBarWindow = null;
John Spurlock5c454122013-06-17 07:35:46 -04003935 }
3936 if (mNavigationBarView != null) {
3937 mWindowManager.removeViewImmediate(mNavigationBarView);
John Spurlockab847cf2014-01-15 14:13:59 -05003938 mNavigationBarView = null;
John Spurlock5c454122013-06-17 07:35:46 -04003939 }
Jason Monk4ae97d32014-12-17 10:14:33 -05003940 if (mHandlerThread != null) {
3941 mHandlerThread.quitSafely();
3942 mHandlerThread = null;
3943 }
John Spurlock5c454122013-06-17 07:35:46 -04003944 mContext.unregisterReceiver(mBroadcastReceiver);
Adrian Roos8e3e8362015-07-16 19:42:22 -07003945 mContext.unregisterReceiver(mDemoReceiver);
Selim Cineke70d6532015-04-24 16:46:13 -07003946 mAssistManager.destroy();
Jason Monk07b75fe2015-05-14 16:47:03 -04003947
3948 final SignalClusterView signalCluster =
3949 (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
3950 final SignalClusterView signalClusterKeyguard =
3951 (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
3952 final SignalClusterView signalClusterQs =
3953 (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
Jason Monk5e745172015-06-02 19:14:44 -04003954 mNetworkController.removeSignalCallback(signalCluster);
3955 mNetworkController.removeSignalCallback(signalClusterKeyguard);
3956 mNetworkController.removeSignalCallback(signalClusterQs);
3957 if (mQSPanel != null && mQSPanel.getHost() != null) {
3958 mQSPanel.getHost().destroy();
3959 }
John Spurlock5c454122013-06-17 07:35:46 -04003960 }
John Spurlock3c875662013-08-31 15:07:25 -04003961
3962 private boolean mDemoModeAllowed;
3963 private boolean mDemoMode;
John Spurlock3c875662013-08-31 15:07:25 -04003964
3965 @Override
3966 public void dispatchDemoCommand(String command, Bundle args) {
3967 if (!mDemoModeAllowed) {
3968 mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
Jason Monk431ad732015-07-16 08:58:15 -04003969 DEMO_MODE_ALLOWED, 0) != 0;
John Spurlock3c875662013-08-31 15:07:25 -04003970 }
3971 if (!mDemoModeAllowed) return;
3972 if (command.equals(COMMAND_ENTER)) {
3973 mDemoMode = true;
3974 } else if (command.equals(COMMAND_EXIT)) {
3975 mDemoMode = false;
3976 checkBarModes();
3977 } else if (!mDemoMode) {
3978 // automatically enter demo mode on first demo command
3979 dispatchDemoCommand(COMMAND_ENTER, new Bundle());
3980 }
3981 boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
John Spurlockbb4a7022014-11-08 12:40:19 -05003982 if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
3983 mVolumeComponent.dispatchDemoCommand(command, args);
3984 }
John Spurlock3c875662013-08-31 15:07:25 -04003985 if (modeChange || command.equals(COMMAND_CLOCK)) {
3986 dispatchDemoCommandToView(command, args, R.id.clock);
3987 }
3988 if (modeChange || command.equals(COMMAND_BATTERY)) {
Jason Monk98d7c7a2016-04-12 13:08:31 -04003989 mBatteryController.dispatchDemoCommand(command, args);
John Spurlock3c875662013-08-31 15:07:25 -04003990 }
3991 if (modeChange || command.equals(COMMAND_STATUS)) {
Jorim Jaggi66ac1332015-01-21 19:22:26 +01003992 mIconController.dispatchDemoCommand(command, args);
John Spurlock3c875662013-08-31 15:07:25 -04003993 }
3994 if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
3995 mNetworkController.dispatchDemoCommand(command, args);
3996 }
John Spurlock7f42fc52014-01-14 16:20:39 -05003997 if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
3998 View notifications = mStatusBarView == null ? null
3999 : mStatusBarView.findViewById(R.id.notification_icon_area);
4000 if (notifications != null) {
4001 String visible = args.getString("visible");
4002 int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
4003 notifications.setVisibility(vis);
4004 }
4005 }
John Spurlock3c875662013-08-31 15:07:25 -04004006 if (command.equals(COMMAND_BARS)) {
4007 String mode = args.getString("mode");
4008 int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
John Spurlockbd957402013-10-03 11:38:39 -04004009 "translucent".equals(mode) ? MODE_TRANSLUCENT :
John Spurlock3c875662013-08-31 15:07:25 -04004010 "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
John Spurlock0ff62e02014-07-22 16:15:08 -04004011 "transparent".equals(mode) ? MODE_TRANSPARENT :
4012 "warning".equals(mode) ? MODE_WARNING :
John Spurlock3c875662013-08-31 15:07:25 -04004013 -1;
4014 if (barMode != -1) {
4015 boolean animate = true;
4016 if (mStatusBarView != null) {
4017 mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
4018 }
4019 if (mNavigationBarView != null) {
4020 mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
4021 }
4022 }
4023 }
4024 }
4025
4026 private void dispatchDemoCommandToView(String command, Bundle args, int id) {
4027 if (mStatusBarView == null) return;
4028 View v = mStatusBarView.findViewById(id);
4029 if (v instanceof DemoMode) {
4030 ((DemoMode)v).dispatchDemoCommand(command, args);
4031 }
4032 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004033
Jorim Jaggiecbab362014-04-23 16:13:15 +02004034 /**
4035 * @return The {@link StatusBarState} the status bar is in.
4036 */
4037 public int getBarState() {
4038 return mState;
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004039 }
4040
Chris Wren16895942015-06-23 11:22:20 -04004041 @Override
Yorke Leee4ea6ab2016-03-03 14:51:49 -08004042 public boolean isPanelFullyCollapsed() {
Chris Wren16895942015-06-23 11:22:20 -04004043 return mNotificationPanel.isFullyCollapsed();
4044 }
4045
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004046 public void showKeyguard() {
Jorim Jaggi5e08e692014-10-03 15:17:20 -07004047 if (mLaunchTransitionFadingAway) {
4048 mNotificationPanel.animate().cancel();
Selim Cinek37c110f2015-05-22 12:38:44 -07004049 onLaunchTransitionFadingEnded();
Jorim Jaggi5e08e692014-10-03 15:17:20 -07004050 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01004051 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004052 if (mUserSwitcherController != null && mUserSwitcherController.useFullscreenUserSwitcher()) {
4053 setBarState(StatusBarState.FULLSCREEN_USER_SWITCHER);
4054 } else {
4055 setBarState(StatusBarState.KEYGUARD);
4056 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02004057 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004058 if (!mDeviceInteractive) {
Jorim Jaggid41083a2014-09-12 02:54:40 +02004059
4060 // If the screen is off already, we need to disable touch events because these might
4061 // collapse the panel after we expanded it, and thus we would end up with a blank
4062 // Keyguard.
4063 mNotificationPanel.setTouchDisabled(true);
4064 }
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004065 if (mState == StatusBarState.KEYGUARD) {
4066 instantExpandNotificationsPanel();
4067 } else if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
4068 instantCollapseNotificationPanel();
4069 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004070 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004071 if (mDraggedDownRow != null) {
4072 mDraggedDownRow.setUserLocked(false);
Selim Cinekb5605e52015-02-20 18:21:41 +01004073 mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004074 mDraggedDownRow = null;
4075 }
Adrian Roos3aec6382016-02-05 14:19:01 -08004076 mPendingRemoteInputView = null;
Jorim Jaggi19695d92015-07-20 15:51:40 -07004077 mAssistManager.onLockscreenShown();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004078 }
4079
Selim Cinek37c110f2015-05-22 12:38:44 -07004080 private void onLaunchTransitionFadingEnded() {
4081 mNotificationPanel.setAlpha(1.0f);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004082 mNotificationPanel.onAffordanceLaunchEnded();
4083 releaseGestureWakeLock();
Selim Cinek37c110f2015-05-22 12:38:44 -07004084 runLaunchTransitionEndRunnable();
4085 mLaunchTransitionFadingAway = false;
4086 mScrimController.forceHideScrims(false /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08004087 updateMediaMetaData(true /* metaDataChanged */, true);
Selim Cinek37c110f2015-05-22 12:38:44 -07004088 }
4089
Selim Cinek36b02232016-05-11 23:07:05 -04004090 @Override
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02004091 public boolean isCollapsing() {
4092 return mNotificationPanel.isCollapsing();
4093 }
4094
Selim Cinek36b02232016-05-11 23:07:05 -04004095 @Override
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02004096 public void addPostCollapseAction(Runnable r) {
4097 mPostCollapseRunnables.add(r);
4098 }
4099
Selim Cinekbaa23272014-07-08 18:01:07 +02004100 public boolean isInLaunchTransition() {
4101 return mNotificationPanel.isLaunchTransitionRunning()
4102 || mNotificationPanel.isLaunchTransitionFinished();
4103 }
4104
4105 /**
4106 * Fades the content of the keyguard away after the launch transition is done.
4107 *
4108 * @param beforeFading the runnable to be run when the circle is fully expanded and the fading
4109 * starts
4110 * @param endRunnable the runnable to be run when the transition is done
4111 */
4112 public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Jorim Jaggi5e08e692014-10-03 15:17:20 -07004113 Runnable endRunnable) {
Jorim Jaggi826730a2014-12-08 21:05:13 +01004114 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Jorim Jaggi5e08e692014-10-03 15:17:20 -07004115 mLaunchTransitionEndRunnable = endRunnable;
Selim Cinekbaa23272014-07-08 18:01:07 +02004116 Runnable hideRunnable = new Runnable() {
4117 @Override
4118 public void run() {
4119 mLaunchTransitionFadingAway = true;
4120 if (beforeFading != null) {
4121 beforeFading.run();
4122 }
Selim Cinek37c110f2015-05-22 12:38:44 -07004123 mScrimController.forceHideScrims(true /* hide */);
Adrian Roos52738322016-01-29 08:49:21 -08004124 updateMediaMetaData(false, true);
Selim Cinekbaa23272014-07-08 18:01:07 +02004125 mNotificationPanel.setAlpha(1);
Selim Cinek07304f5222016-05-19 18:31:36 -07004126 mStackScroller.setParentFadingOut(true);
Selim Cinekbaa23272014-07-08 18:01:07 +02004127 mNotificationPanel.animate()
4128 .alpha(0)
4129 .setStartDelay(FADE_KEYGUARD_START_DELAY)
4130 .setDuration(FADE_KEYGUARD_DURATION)
4131 .withLayer()
4132 .withEndAction(new Runnable() {
4133 @Override
4134 public void run() {
Selim Cinek37c110f2015-05-22 12:38:44 -07004135 onLaunchTransitionFadingEnded();
Selim Cinekbaa23272014-07-08 18:01:07 +02004136 }
4137 });
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004138 mIconController.appTransitionStarting(SystemClock.uptimeMillis(),
4139 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Selim Cinekbaa23272014-07-08 18:01:07 +02004140 }
4141 };
4142 if (mNotificationPanel.isLaunchTransitionRunning()) {
4143 mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
4144 } else {
4145 hideRunnable.run();
4146 }
4147 }
4148
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004149 /**
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004150 * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
4151 * fading.
4152 */
4153 public void fadeKeyguardWhilePulsing() {
4154 mNotificationPanel.animate()
4155 .alpha(0f)
4156 .setStartDelay(0)
4157 .setDuration(FADE_KEYGUARD_DURATION_PULSING)
Jorim Jaggiab45a212015-08-20 16:59:44 -07004158 .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
4159 .start();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004160 }
4161
4162 /**
Jorim Jaggi6626f542016-08-22 13:08:44 -07004163 * Plays the animation when an activity that was occluding Keyguard goes away.
4164 */
4165 public void animateKeyguardUnoccluding() {
4166 mScrimController.animateKeyguardUnoccluding(500);
4167 mNotificationPanel.setExpandedFraction(0f);
4168 animateExpandNotificationsPanel();
4169 }
4170
4171 /**
Jorim Jaggi826730a2014-12-08 21:05:13 +01004172 * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
4173 * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
4174 * because the launched app crashed or something else went wrong.
4175 */
4176 public void startLaunchTransitionTimeout() {
4177 mHandler.sendEmptyMessageDelayed(MSG_LAUNCH_TRANSITION_TIMEOUT,
4178 LAUNCH_TRANSITION_TIMEOUT_MS);
4179 }
4180
4181 private void onLaunchTransitionTimeout() {
4182 Log.w(TAG, "Launch transition: Timeout!");
Selim Cinek372d1bd2015-08-14 13:19:37 -07004183 mNotificationPanel.onAffordanceLaunchEnded();
4184 releaseGestureWakeLock();
Jorim Jaggi826730a2014-12-08 21:05:13 +01004185 mNotificationPanel.resetViews();
4186 }
4187
4188 private void runLaunchTransitionEndRunnable() {
4189 if (mLaunchTransitionEndRunnable != null) {
4190 Runnable r = mLaunchTransitionEndRunnable;
4191
4192 // mLaunchTransitionEndRunnable might call showKeyguard, which would execute it again,
4193 // which would lead to infinite recursion. Protect against it.
4194 mLaunchTransitionEndRunnable = null;
4195 r.run();
4196 }
4197 }
4198
4199 /**
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004200 * @return true if we would like to stay in the shade, false if it should go away entirely
4201 */
4202 public boolean hideKeyguard() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07004203 Trace.beginSection("PhoneStatusBar#hideKeyguard");
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004204 boolean staying = mLeaveOpenOnKeyguardHide;
Jorim Jaggiecbab362014-04-23 16:13:15 +02004205 setBarState(StatusBarState.SHADE);
Adrian Roos3aec6382016-02-05 14:19:01 -08004206 View viewToClick = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02004207 if (mLeaveOpenOnKeyguardHide) {
4208 mLeaveOpenOnKeyguardHide = false;
Jorim Jaggi37c11802015-08-18 20:27:54 -07004209 long delay = calculateGoingToFullShadeDelay();
4210 mNotificationPanel.animateToFullShade(delay);
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004211 if (mDraggedDownRow != null) {
4212 mDraggedDownRow.setUserLocked(false);
4213 mDraggedDownRow = null;
4214 }
Adrian Roos3aec6382016-02-05 14:19:01 -08004215 viewToClick = mPendingRemoteInputView;
4216 mPendingRemoteInputView = null;
Jorim Jaggi37c11802015-08-18 20:27:54 -07004217
4218 // Disable layout transitions in navbar for this transition because the load is just
4219 // too heavy for the CPU and GPU on any device.
4220 if (mNavigationBarView != null) {
4221 mNavigationBarView.setLayoutTransitionsEnabled(false);
4222 mNavigationBarView.postDelayed(new Runnable() {
4223 @Override
4224 public void run() {
4225 mNavigationBarView.setLayoutTransitionsEnabled(true);
4226 }
4227 }, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
4228 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004229 } else {
4230 instantCollapseNotificationPanel();
4231 }
Jorim Jaggi98f85302014-08-07 17:45:04 +02004232 updateKeyguardState(staying, false /* fromShadeLocked */);
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01004233
Adrian Roosb22665d2016-10-17 15:08:03 -07004234 if (viewToClick != null && viewToClick.isAttachedToWindow()) {
Adrian Roos3aec6382016-02-05 14:19:01 -08004235 viewToClick.callOnClick();
4236 }
4237
Jorim Jaggi1ecd7cd2014-11-03 16:18:03 +01004238 // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
4239 // visibilities so next time we open the panel we know the correct height already.
4240 if (mQSPanel != null) {
4241 mQSPanel.refreshAllTiles();
4242 }
Jorim Jaggi826730a2014-12-08 21:05:13 +01004243 mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004244 releaseGestureWakeLock();
4245 mNotificationPanel.onAffordanceLaunchEnded();
Jorim Jaggi52429b42015-09-03 19:58:19 -07004246 mNotificationPanel.animate().cancel();
Jorim Jaggi90978852015-08-18 19:55:53 -07004247 mNotificationPanel.setAlpha(1f);
Nick Desaulniers1d396752016-07-25 15:05:33 -07004248 Trace.endSection();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004249 return staying;
4250 }
4251
Selim Cinek372d1bd2015-08-14 13:19:37 -07004252 private void releaseGestureWakeLock() {
4253 if (mGestureWakeLock.isHeld()) {
4254 mGestureWakeLock.release();
4255 }
4256 }
4257
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004258 public long calculateGoingToFullShadeDelay() {
4259 return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration;
Jorim Jaggi15682502014-04-23 12:01:36 +02004260 }
4261
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004262 /**
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004263 * Notifies the status bar that Keyguard is going away very soon.
4264 */
4265 public void keyguardGoingAway() {
4266
4267 // Treat Keyguard exit animation as an app transition to achieve nice transition for status
4268 // bar.
Adrian Roos46df1ca2015-09-11 12:38:43 -07004269 mKeyguardGoingAway = true;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004270 mIconController.appTransitionPending();
4271 }
4272
4273 /**
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004274 * Notifies the status bar the Keyguard is fading away with the specified timings.
4275 *
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004276 * @param startTime the start time of the animations in uptime millis
4277 * @param delay the precalculated animation delay in miliseconds
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004278 * @param fadeoutDuration the duration of the exit animation, in milliseconds
4279 */
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004280 public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004281 mKeyguardFadingAway = true;
4282 mKeyguardFadingAwayDelay = delay;
4283 mKeyguardFadingAwayDuration = fadeoutDuration;
4284 mWaitingForKeyguardExit = false;
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004285 mIconController.appTransitionStarting(
4286 startTime + fadeoutDuration
4287 - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
4288 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
Adrian Roos316bf542016-08-23 17:53:07 +02004289 recomputeDisableFlags(fadeoutDuration > 0 /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004290 }
4291
Jorim Jaggi416493b2014-09-13 03:57:32 +02004292 public boolean isKeyguardFadingAway() {
4293 return mKeyguardFadingAway;
4294 }
4295
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004296 /**
4297 * Notifies that the Keyguard fading away animation is done.
4298 */
4299 public void finishKeyguardFadingAway() {
4300 mKeyguardFadingAway = false;
Adrian Roos46df1ca2015-09-11 12:38:43 -07004301 mKeyguardGoingAway = false;
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004302 }
4303
Adrian Roosd322f1a2015-04-23 15:19:45 -07004304 public void stopWaitingForKeyguardExit() {
4305 mWaitingForKeyguardExit = false;
4306 }
4307
Jorim Jaggi15682502014-04-23 12:01:36 +02004308 private void updatePublicMode() {
Tony Mak92c989d2016-04-19 14:02:44 +01004309 boolean isPublic = false;
4310 if (mStatusBarKeyguardViewManager.isShowing()) {
4311 for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
4312 UserInfo userInfo = mCurrentProfiles.valueAt(i);
4313 if (mStatusBarKeyguardViewManager.isSecure(userInfo.id)) {
4314 isPublic = true;
4315 break;
4316 }
4317 }
4318 }
4319 setLockscreenPublicMode(isPublic);
Jorim Jaggi15682502014-04-23 12:01:36 +02004320 }
4321
Rakesh Iyer2790a372016-01-22 15:33:39 -08004322 protected void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07004323 Trace.beginSection("PhoneStatusBar#updateKeyguardState");
Jorim Jaggiecbab362014-04-23 16:13:15 +02004324 if (mState == StatusBarState.KEYGUARD) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004325 mKeyguardIndicationController.setVisible(true);
Selim Cinek4c6969a2014-05-26 19:22:17 +02004326 mNotificationPanel.resetViews();
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004327 if (mKeyguardUserSwitcher != null) {
4328 mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
4329 }
Selim Cinek80c2abe2015-06-17 15:37:30 -07004330 mStatusBarView.removePendingHideExpandedRunnables();
Jorim Jaggi15682502014-04-23 12:01:36 +02004331 } else {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004332 mKeyguardIndicationController.setVisible(false);
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004333 if (mKeyguardUserSwitcher != null) {
4334 mKeyguardUserSwitcher.setKeyguard(false,
4335 goingToFullShade ||
4336 mState == StatusBarState.SHADE_LOCKED ||
4337 fromShadeLocked);
4338 }
Jorim Jaggi15682502014-04-23 12:01:36 +02004339 }
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004340 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02004341 mScrimController.setKeyguardShowing(true);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004342 } else {
Jorim Jaggiecc798e2014-05-26 18:14:37 +02004343 mScrimController.setKeyguardShowing(false);
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004344 }
Nicolas Prevot1dbbe7d2016-05-17 12:52:54 +01004345 mIconPolicy.notifyKeyguardShowingChanged();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004346 mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
John Spurlockbf370992014-06-17 13:58:31 -04004347 updateDozingState();
Jorim Jaggi15682502014-04-23 12:01:36 +02004348 updatePublicMode();
Selim Cinekd35c2792016-01-21 13:20:57 -08004349 updateStackScrollerState(goingToFullShade, fromShadeLocked);
Christoph Studer37fe6932014-05-26 13:10:30 +02004350 updateNotifications();
Jorim Jaggia6310292014-04-16 14:11:52 +02004351 checkBarModes();
Adrian Roos52738322016-01-29 08:49:21 -08004352 updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
John Spurlock657c62c2014-07-22 12:18:09 -04004353 mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
Jim Miller69c12412016-10-06 19:11:03 -07004354 mStatusBarKeyguardViewManager.isSecure(),
4355 mStatusBarKeyguardViewManager.isOccluded());
Nick Desaulniers1d396752016-07-25 15:05:33 -07004356 Trace.endSection();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004357 }
4358
John Spurlockbf370992014-06-17 13:58:31 -04004359 private void updateDozingState() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07004360 Trace.beginSection("PhoneStatusBar#updateDozingState");
Jorim Jaggi4e857f42014-11-17 19:14:04 +01004361 boolean animate = !mDozing && mDozeScrimController.isPulsing();
4362 mNotificationPanel.setDozing(mDozing, animate);
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004363 mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
Jorim Jaggi048af1f2014-11-11 22:51:10 +01004364 mScrimController.setDozing(mDozing);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004365
4366 // Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock
4367 // for pulsing so the Keyguard fade-out animation scrim can take over.
4368 mDozeScrimController.setDozing(mDozing &&
4369 mFingerprintUnlockController.getMode()
4370 != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate);
Nick Desaulniers1d396752016-07-25 15:05:33 -07004371 Trace.endSection();
John Spurlockbf370992014-06-17 13:58:31 -04004372 }
4373
Selim Cinekd35c2792016-01-21 13:20:57 -08004374 public void updateStackScrollerState(boolean goingToFullShade, boolean fromShadeLocked) {
John Spurlock4b3bda22014-05-22 14:32:20 -04004375 if (mStackScroller == null) return;
Selim Cinek1408eb52014-06-02 14:45:38 +02004376 boolean onKeyguard = mState == StatusBarState.KEYGUARD;
Jorim Jaggiae441282014-08-01 02:45:18 +02004377 mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
Selim Cinekd35c2792016-01-21 13:20:57 -08004378 mStackScroller.setDimmed(onKeyguard, fromShadeLocked /* animate */);
Selim Cinek1408eb52014-06-02 14:45:38 +02004379 mStackScroller.setExpandingEnabled(!onKeyguard);
Selim Cineka32ab602014-06-11 15:06:01 +02004380 ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
4381 mStackScroller.setActivatedChild(null);
4382 if (activatedChild != null) {
4383 activatedChild.makeInactive(false /* animate */);
4384 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004385 }
4386
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004387 public void userActivity() {
Jorim Jaggib690f0d2014-07-03 23:25:44 +02004388 if (mState == StatusBarState.KEYGUARD) {
4389 mKeyguardViewMediatorCallback.userActivity();
4390 }
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004391 }
4392
Jorim Jaggidf993512014-05-13 23:06:35 +02004393 public boolean interceptMediaKey(KeyEvent event) {
4394 return mState == StatusBarState.KEYGUARD
4395 && mStatusBarKeyguardViewManager.interceptMediaKey(event);
4396 }
4397
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02004398 public boolean onMenuPressed() {
Selim Cinek28540192016-02-19 17:25:08 -08004399 if (mDeviceInteractive && mState != StatusBarState.SHADE
4400 && mStatusBarKeyguardViewManager.shouldDismissOnMenuPressed()) {
4401 animateCollapsePanels(
4402 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
4403 return true;
4404 }
4405 return false;
Jorim Jaggi8c8bcc12014-04-16 21:36:51 +02004406 }
4407
Selim Cinek372d1bd2015-08-14 13:19:37 -07004408 public void endAffordanceLaunch() {
4409 releaseGestureWakeLock();
4410 mNotificationPanel.onAffordanceLaunchEnded();
4411 }
4412
Jorim Jaggie5c7a892014-04-10 20:37:32 +02004413 public boolean onBackPressed() {
Adrian Roos0002a452014-07-03 13:46:07 +02004414 if (mStatusBarKeyguardViewManager.onBackPressed()) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +02004415 return true;
4416 }
Adrian Roos0002a452014-07-03 13:46:07 +02004417 if (mNotificationPanel.isQsExpanded()) {
John Spurlockf7ae4422014-08-01 12:45:18 -04004418 if (mNotificationPanel.isQsDetailShowing()) {
4419 mNotificationPanel.closeQsDetail();
4420 } else {
4421 mNotificationPanel.animateCloseQs();
4422 }
Adrian Roos0002a452014-07-03 13:46:07 +02004423 return true;
4424 }
4425 if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
4426 animateCollapsePanels();
4427 return true;
4428 }
4429 return false;
Jorim Jaggie5c7a892014-04-10 20:37:32 +02004430 }
4431
Jorim Jaggi34250762014-07-03 23:51:19 +02004432 public boolean onSpacePressed() {
Xiyuan Xiacc3a74f62015-07-22 14:16:34 -07004433 if (mDeviceInteractive && mState != StatusBarState.SHADE) {
Jorim Jaggi4eedc1d2014-10-27 13:45:56 +01004434 animateCollapsePanels(
4435 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
Jorim Jaggi34250762014-07-03 23:51:19 +02004436 return true;
4437 }
4438 return false;
4439 }
4440
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004441 private void showBouncer() {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004442 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekbaa23272014-07-08 18:01:07 +02004443 mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004444 mStatusBarKeyguardViewManager.dismiss();
4445 }
4446 }
4447
4448 private void instantExpandNotificationsPanel() {
Jorim Jaggic357ca22014-04-25 14:56:15 +02004449
Jorim Jaggi0a27be82014-06-11 03:22:39 +02004450 // Make our window larger and the panel expanded.
Jorim Jaggifa505a72014-04-28 20:04:11 +02004451 makeExpandedVisible(true);
Oren Blasberg8d3fea12015-07-10 14:21:44 -07004452 mNotificationPanel.expand(false /* animate */);
Jorim Jaggi03c701e2014-04-02 12:39:51 +02004453 }
Adrian Roos5a46cd32014-04-03 16:51:58 +02004454
Jorim Jaggia005f1b2014-04-16 19:06:10 +02004455 private void instantCollapseNotificationPanel() {
Selim Cinek6bb4a9b2014-10-09 17:48:05 -07004456 mNotificationPanel.instantCollapse();
Jorim Jaggia005f1b2014-04-16 19:06:10 +02004457 }
4458
Jorim Jaggid4a57442014-04-10 02:45:55 +02004459 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02004460 public void onActivated(ActivatableNotificationView view) {
Christoph Studerb0183992014-12-22 21:02:26 +01004461 EventLogTags.writeSysuiLockscreenGesture(
4462 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
4463 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
Adrian Roos12c1ef52014-06-04 13:54:08 +02004464 mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
Selim Cineka32ab602014-06-11 15:06:01 +02004465 ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
4466 if (previousView != null) {
4467 previousView.makeInactive(true /* animate */);
4468 }
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004469 mStackScroller.setActivatedChild(view);
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02004470 }
4471
Annie Chinedeb5172016-06-24 17:07:08 -07004472 public ButtonDispatcher getHomeButton() {
4473 return mNavigationBarView.getHomeButton();
4474 }
4475
Jorim Jaggiecbab362014-04-23 16:13:15 +02004476 /**
4477 * @param state The {@link StatusBarState} to set.
4478 */
4479 public void setBarState(int state) {
Christoph Studer2231c6e2014-12-19 12:40:13 +01004480 // If we're visible and switched to SHADE_LOCKED (the user dragged
4481 // down on the lockscreen), clear notification LED, vibration,
4482 // ringing.
4483 // Other transitions are covered in handleVisibleToUserChanged().
Selim Cinek6577cae2015-08-31 16:15:49 -07004484 if (state != mState && mVisible && (state == StatusBarState.SHADE_LOCKED
4485 || (state == StatusBarState.SHADE && isGoingToNotificationShade()))) {
4486 clearNotificationEffects();
Christoph Studer1f32c652014-11-26 15:32:20 +01004487 }
Adrian Roos18d099a2016-05-19 15:28:18 -07004488 if (state == StatusBarState.KEYGUARD) {
4489 removeRemoteInputEntriesKeptUntilCollapsed();
Selim Cinek99415392016-09-09 14:58:41 -07004490 maybeEscalateHeadsUp();
Adrian Roos18d099a2016-05-19 15:28:18 -07004491 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004492 mState = state;
Selim Cinek9c4c4142015-12-04 16:44:56 -08004493 mGroupManager.setStatusBarState(state);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004494 mFalsingManager.setStatusBarState(state);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004495 mStatusBarWindowManager.setStatusBarState(state);
Adrian Roos7bb38a92016-07-21 11:44:01 -07004496 updateReportRejectedTouchVisibility();
Jorim Jaggi83969702015-06-05 14:59:24 -07004497 updateDozing();
Jorim Jaggiecbab362014-04-23 16:13:15 +02004498 }
4499
Jorim Jaggic5dc0d02014-04-15 15:42:55 +02004500 @Override
Selim Cineka32ab602014-06-11 15:06:01 +02004501 public void onActivationReset(ActivatableNotificationView view) {
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004502 if (view == mStackScroller.getActivatedChild()) {
Adrian Roos12c1ef52014-06-04 13:54:08 +02004503 mKeyguardIndicationController.hideTransientIndication();
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004504 mStackScroller.setActivatedChild(null);
4505 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004506 }
4507
4508 public void onTrackingStarted() {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +02004509 runPostCollapseRunnables();
Jorim Jaggi90129582014-06-02 14:44:49 +02004510 }
4511
Selim Cinekdbbcfbe2014-10-24 17:52:35 +02004512 public void onClosingFinished() {
4513 runPostCollapseRunnables();
4514 }
4515
Jorim Jaggi90129582014-06-02 14:44:49 +02004516 public void onUnlockHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004517 mFalsingManager.onUnlockHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004518 mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
Jorim Jaggi90129582014-06-02 14:44:49 +02004519 }
4520
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004521 public void onHintFinished() {
Jorim Jaggi93a2bb22014-06-02 19:57:28 +02004522 // Delay the reset a bit so the user can read the text.
Adrian Roos12c1ef52014-06-04 13:54:08 +02004523 mKeyguardIndicationController.hideTransientIndicationDelayed(HINT_RESET_DELAY_MS);
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004524 }
4525
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004526 public void onCameraHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004527 mFalsingManager.onCameraHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004528 mKeyguardIndicationController.showTransientIndication(R.string.camera_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004529 }
4530
Selim Cineke70d6532015-04-24 16:46:13 -07004531 public void onVoiceAssistHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004532 mFalsingManager.onLeftAffordanceHintStarted();
Selim Cineke70d6532015-04-24 16:46:13 -07004533 mKeyguardIndicationController.showTransientIndication(R.string.voice_hint);
4534 }
4535
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004536 public void onPhoneHintStarted() {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004537 mFalsingManager.onLeftAffordanceHintStarted();
Adrian Roos12c1ef52014-06-04 13:54:08 +02004538 mKeyguardIndicationController.showTransientIndication(R.string.phone_hint);
Jorim Jaggib3f0a2f2014-06-02 19:29:39 +02004539 }
4540
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004541 public void onTrackingStopped(boolean expand) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004542 if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
Selim Cineke8bae622015-07-15 13:24:06 -07004543 if (!expand && !mUnlockMethodCache.canSkipBouncer()) {
Jorim Jaggi2fbad7b2014-05-26 22:38:00 +02004544 showBouncer();
4545 }
4546 }
Jorim Jaggie70d31f2014-04-24 22:08:30 +02004547 }
4548
4549 @Override
Selim Cinek5f71bee2015-11-18 10:25:23 -08004550 protected int getMaxKeyguardNotifications(boolean recompute) {
4551 if (recompute) {
4552 mMaxKeyguardNotifications = Math.max(1,
4553 mNotificationPanel.computeMaxKeyguardNotifications(
4554 mMaxAllowedKeyguardNotifications));
4555 return mMaxKeyguardNotifications;
4556 }
4557 return mMaxKeyguardNotifications;
4558 }
4559
4560 public int getMaxKeyguardNotifications() {
4561 return getMaxKeyguardNotifications(false /* recompute */);
Jorim Jaggid4a57442014-04-10 02:45:55 +02004562 }
4563
Jorim Jaggia6310292014-04-16 14:11:52 +02004564 public NavigationBarView getNavigationBarView() {
4565 return mNavigationBarView;
4566 }
4567
Jorim Jaggiecbab362014-04-23 16:13:15 +02004568 // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
4569
Chris Wren6abeeb92016-05-26 14:44:38 -04004570
4571 /* Only ever called as a consequence of a lockscreen expansion gesture. */
Jorim Jaggiecbab362014-04-23 16:13:15 +02004572 @Override
Christoph Studerb0183992014-12-22 21:02:26 +01004573 public boolean onDraggedDown(View startingChild, int dragLengthY) {
Christoph Studerc8db24b2014-07-25 17:50:30 +02004574 if (hasActiveNotifications()) {
Christoph Studerb0183992014-12-22 21:02:26 +01004575 EventLogTags.writeSysuiLockscreenGesture(
4576 EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
4577 (int) (dragLengthY / mDisplayMetrics.density),
4578 0 /* velocityDp - N/A */);
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004579
4580 // We have notifications, go to locked shade.
4581 goToLockedShade(startingChild);
Chris Wren6abeeb92016-05-26 14:44:38 -04004582 if (startingChild instanceof ExpandableNotificationRow) {
4583 ExpandableNotificationRow row = (ExpandableNotificationRow) startingChild;
4584 row.onExpandedByGesture(true /* drag down is always an open */);
4585 }
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004586 return true;
4587 } else {
4588
4589 // No notifications - abort gesture.
4590 return false;
4591 }
Jorim Jaggiecbab362014-04-23 16:13:15 +02004592 }
4593
4594 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +02004595 public void onDragDownReset() {
4596 mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
Selim Cinek177fd432015-11-18 11:53:47 -08004597 mStackScroller.resetScrollPosition();
Jorim Jaggiecbab362014-04-23 16:13:15 +02004598 }
4599
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004600 @Override
Selim Cinek177fd432015-11-18 11:53:47 -08004601 public void onCrossedThreshold(boolean above) {
4602 mStackScroller.setDimmed(!above /* dimmed */, true /* animate */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004603 }
4604
Selim Cinek1408eb52014-06-02 14:45:38 +02004605 @Override
4606 public void onTouchSlopExceeded() {
4607 mStackScroller.removeLongPressCallback();
4608 }
4609
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004610 @Override
4611 public void setEmptyDragAmount(float amount) {
4612 mNotificationPanel.setEmptyDragAmount(amount);
4613 }
4614
Jorim Jaggiecbab362014-04-23 16:13:15 +02004615 /**
4616 * If secure with redaction: Show bouncer, go to unlocked shade.
4617 *
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004618 * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
Jorim Jaggiecbab362014-04-23 16:13:15 +02004619 *
4620 * @param expandView The view to expand after going to the shade.
4621 */
4622 public void goToLockedShade(View expandView) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004623 ExpandableNotificationRow row = null;
Jorim Jaggiecbab362014-04-23 16:13:15 +02004624 if (expandView instanceof ExpandableNotificationRow) {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004625 row = (ExpandableNotificationRow) expandView;
Selim Cinekcb24ab82016-02-25 12:49:08 -08004626 row.setUserExpanded(true /* userExpanded */, true /* allowChildExpansion */);
Mady Mellorb0a82462016-04-30 17:31:02 -07004627 // Indicate that the group expansion is changing at this time -- this way the group
4628 // and children backgrounds / divider animations will look correct.
4629 row.setGroupExpansionChanging(true);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004630 }
Adrian Roosaee70462014-09-03 16:27:39 +02004631 boolean fullShadeNeedsBouncer = !userAllowsPrivateNotificationsInPublic(mCurrentUserId)
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004632 || !mShowLockscreenNotifications || mFalsingManager.shouldEnforceBouncer();
Adrian Roosaee70462014-09-03 16:27:39 +02004633 if (isLockscreenPublicMode() && fullShadeNeedsBouncer) {
Jorim Jaggiecbab362014-04-23 16:13:15 +02004634 mLeaveOpenOnKeyguardHide = true;
4635 showBouncer();
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004636 mDraggedDownRow = row;
Adrian Roos3aec6382016-02-05 14:19:01 -08004637 mPendingRemoteInputView = null;
Jorim Jaggi2042ef22014-05-13 21:55:18 +02004638 } else {
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004639 mNotificationPanel.animateToFullShade(0 /* delay */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004640 setBarState(StatusBarState.SHADE_LOCKED);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004641 updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
Jorim Jaggiecbab362014-04-23 16:13:15 +02004642 }
4643 }
4644
Selim Cinek570981d2015-12-01 11:37:01 -08004645 @Override
Mady Mellor8e8a69e2016-03-14 12:30:10 -07004646 public void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {
4647 mLeaveOpenOnKeyguardHide = true;
4648 dismissKeyguardThenExecute(dismissAction, true /* afterKeyguardGone */);
4649 }
4650
4651 @Override
Adrian Roos3aec6382016-02-05 14:19:01 -08004652 protected void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
4653 mLeaveOpenOnKeyguardHide = true;
4654 showBouncer();
4655 mPendingRemoteInputView = clicked;
4656 }
4657
4658 @Override
Ricky Waicd35def2016-05-03 11:07:07 +01004659 protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender,
4660 String notificationKey) {
4661 // Clear pending remote view, as we do not want to trigger pending remote input view when
4662 // it's called by other code
4663 mPendingWorkRemoteInputView = null;
4664 return super.startWorkChallengeIfNecessary(userId, intendSender, notificationKey);
4665 }
4666
4667 @Override
4668 protected void onLockedWorkRemoteInput(int userId, ExpandableNotificationRow row,
4669 View clicked) {
4670 // Collapse notification and show work challenge
4671 animateCollapsePanels();
4672 startWorkChallengeIfNecessary(userId, null, null);
4673 // Add pending remote input view after starting work challenge, as starting work challenge
4674 // will clear all previous pending review view
4675 mPendingWorkRemoteInputView = clicked;
4676 }
4677
4678 @Override
4679 protected void onWorkChallengeUnlocked() {
4680 if (mPendingWorkRemoteInputView != null) {
4681 final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
4682 // Expand notification panel and the notification row, then click on remote input view
4683 final Runnable clickPendingViewRunnable = new Runnable() {
4684 @Override
4685 public void run() {
4686 if (mPendingWorkRemoteInputView != null) {
4687 final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
4688 ViewParent p = pendingWorkRemoteInputView.getParent();
4689 while (p != null) {
4690 if (p instanceof ExpandableNotificationRow) {
4691 final ExpandableNotificationRow row = (ExpandableNotificationRow) p;
4692 ViewParent viewParent = row.getParent();
4693 if (viewParent instanceof NotificationStackScrollLayout) {
4694 final NotificationStackScrollLayout scrollLayout =
4695 (NotificationStackScrollLayout) viewParent;
4696 row.makeActionsVisibile();
4697 row.post(new Runnable() {
4698 @Override
4699 public void run() {
4700 final Runnable finishScrollingCallback = new Runnable()
4701 {
4702 @Override
4703 public void run() {
4704 mPendingWorkRemoteInputView.callOnClick();
4705 mPendingWorkRemoteInputView = null;
4706 scrollLayout.setFinishScrollingCallback(null);
4707 }
4708 };
4709 if (scrollLayout.scrollTo(row)) {
4710 // It scrolls! So call it when it's finished.
4711 scrollLayout.setFinishScrollingCallback(
4712 finishScrollingCallback);
4713 } else {
4714 // It does not scroll, so call it now!
4715 finishScrollingCallback.run();
4716 }
4717 }
4718 });
4719 }
4720 break;
4721 }
4722 p = p.getParent();
4723 }
4724 }
4725 }
4726 };
4727 mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener(
4728 new ViewTreeObserver.OnGlobalLayoutListener() {
4729 @Override
4730 public void onGlobalLayout() {
4731 if (mNotificationPanel.mStatusBar.getStatusBarWindow()
4732 .getHeight() != mNotificationPanel.mStatusBar
4733 .getStatusBarHeight()) {
4734 mNotificationPanel.getViewTreeObserver()
4735 .removeOnGlobalLayoutListener(this);
4736 mNotificationPanel.post(clickPendingViewRunnable);
4737 }
4738 }
4739 });
4740 instantExpandNotificationsPanel();
4741 }
4742 }
4743
4744 @Override
Selim Cinek31aada42015-12-18 17:51:15 -08004745 public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
4746 mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
Selim Cinek570981d2015-12-01 11:37:01 -08004747 if (mState == StatusBarState.KEYGUARD && nowExpanded) {
Selim Cinek31aada42015-12-18 17:51:15 -08004748 goToLockedShade(clickedEntry.row);
Selim Cinek570981d2015-12-01 11:37:01 -08004749 }
4750 }
4751
Adrian Roos5a46cd32014-04-03 16:51:58 +02004752 /**
Jorim Jaggi6539a832014-06-03 23:33:09 +02004753 * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
4754 */
4755 public void goToKeyguard() {
4756 if (mState == StatusBarState.SHADE_LOCKED) {
Selim Cinekd9acca52014-09-01 22:33:25 +02004757 mStackScroller.onGoToKeyguard();
Jorim Jaggi6539a832014-06-03 23:33:09 +02004758 setBarState(StatusBarState.KEYGUARD);
Jorim Jaggi98f85302014-08-07 17:45:04 +02004759 updateKeyguardState(false /* goingToFullShade */, true /* fromShadeLocked*/);
Jorim Jaggi6539a832014-06-03 23:33:09 +02004760 }
4761 }
4762
Jorim Jaggidbc3dce2014-08-01 01:16:36 +02004763 public long getKeyguardFadingAwayDelay() {
4764 return mKeyguardFadingAwayDelay;
4765 }
4766
4767 public long getKeyguardFadingAwayDuration() {
4768 return mKeyguardFadingAwayDuration;
4769 }
4770
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004771 @Override
4772 public void setBouncerShowing(boolean bouncerShowing) {
4773 super.setBouncerShowing(bouncerShowing);
Adrian Roosd0b2f7d2015-04-29 13:36:12 -07004774 mStatusBarView.setBouncerShowing(bouncerShowing);
Adrian Roos316bf542016-08-23 17:53:07 +02004775 recomputeDisableFlags(true /* animate */);
Jorim Jaggi44cf9192014-06-17 19:16:00 -07004776 }
4777
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004778 public void onStartedGoingToSleep() {
4779 mStartedGoingToSleep = true;
4780 }
4781
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004782 public void onFinishedGoingToSleep() {
Selim Cinek372d1bd2015-08-14 13:19:37 -07004783 mNotificationPanel.onAffordanceLaunchEnded();
4784 releaseGestureWakeLock();
4785 mLaunchCameraOnScreenTurningOn = false;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004786 mStartedGoingToSleep = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004787 mDeviceInteractive = false;
4788 mWakeUpComingFromTouch = false;
4789 mWakeUpTouchLocation = null;
Jorim Jaggi75c95042014-05-16 19:09:59 +02004790 mStackScroller.setAnimationsEnabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004791 updateVisibleToUser();
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004792 if (mLaunchCameraOnFinishedGoingToSleep) {
4793 mLaunchCameraOnFinishedGoingToSleep = false;
4794
4795 // This gets executed before we will show Keyguard, so post it in order that the state
4796 // is correct.
4797 mHandler.post(new Runnable() {
4798 @Override
4799 public void run() {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004800 onCameraLaunchGestureDetected(mLastCameraLaunchSource);
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004801 }
4802 });
4803 }
Jorim Jaggi75c95042014-05-16 19:09:59 +02004804 }
4805
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004806 public void onStartedWakingUp() {
4807 mDeviceInteractive = true;
Jorim Jaggi75c95042014-05-16 19:09:59 +02004808 mStackScroller.setAnimationsEnabled(true);
Jorim Jaggid41083a2014-09-12 02:54:40 +02004809 mNotificationPanel.setTouchDisabled(false);
Christoph Studere8e28652014-10-29 17:27:53 +01004810 updateVisibleToUser();
Jorim Jaggi75c95042014-05-16 19:09:59 +02004811 }
John Spurlockd08f91f2014-05-23 11:00:34 -04004812
Jorim Jaggi93739112015-08-13 15:53:14 -07004813 public void onScreenTurningOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004814 mScreenTurningOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004815 mFalsingManager.onScreenTurningOn();
Jorim Jaggi93739112015-08-13 15:53:14 -07004816 mNotificationPanel.onScreenTurningOn();
Selim Cinek372d1bd2015-08-14 13:19:37 -07004817 if (mLaunchCameraOnScreenTurningOn) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004818 mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004819 mLaunchCameraOnScreenTurningOn = false;
4820 }
Jorim Jaggi93739112015-08-13 15:53:14 -07004821 }
4822
Selim Cinek69ff8af2015-08-25 19:03:48 -07004823 private void vibrateForCameraGesture() {
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004824 // Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
Jorim Jaggi8ba1cb32016-06-24 17:33:01 -07004825 mVibrator.vibrate(new long[]{0, 400}, -1 /* repeat */);
Selim Cinek69ff8af2015-08-25 19:03:48 -07004826 }
4827
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004828 public void onScreenTurnedOn() {
Selim Cinek1b6f8192015-09-03 16:01:53 -07004829 mScreenTurningOn = false;
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004830 mDozeScrimController.onScreenTurnedOn();
4831 }
4832
Jason Monk815e0572014-08-12 17:26:36 -04004833 /**
Jorim Jaggi75b25972015-10-21 14:51:10 +02004834 * Handles long press for back button. This exits screen pinning.
Jason Monk815e0572014-08-12 17:26:36 -04004835 */
Jorim Jaggi75b25972015-10-21 14:51:10 +02004836 private boolean handleLongPressBack() {
Jason Monk62515be2014-05-21 16:06:19 -04004837 try {
4838 IActivityManager activityManager = ActivityManagerNative.getDefault();
Jorim Jaggi75b25972015-10-21 14:51:10 +02004839 if (activityManager.isInLockTaskMode()) {
Andrii Kulian0f051f52016-04-14 00:41:51 -07004840 activityManager.stopSystemLockTaskMode();
Jorim Jaggi75b25972015-10-21 14:51:10 +02004841
4842 // When exiting refresh disabled flags.
4843 mNavigationBarView.setDisabledFlags(mDisabled1, true);
4844 return true;
Jason Monk62515be2014-05-21 16:06:19 -04004845 }
4846 } catch (RemoteException e) {
Jason Monk815e0572014-08-12 17:26:36 -04004847 Log.d(TAG, "Unable to reach activity manager", e);
Jason Monk62515be2014-05-21 16:06:19 -04004848 }
Jorim Jaggi75b25972015-10-21 14:51:10 +02004849 return false;
Jason Monk62515be2014-05-21 16:06:19 -04004850 }
4851
Jason Monk5565cb42014-09-12 10:59:21 -04004852 @Override
Andrii Kulian0f051f52016-04-14 00:41:51 -07004853 public void showScreenPinningRequest(int taskId) {
Jason Monk18f99d92014-09-11 13:36:42 -04004854 if (mKeyguardMonitor.isShowing()) {
4855 // Don't allow apps to trigger this from keyguard.
4856 return;
4857 }
4858 // Show screen pinning request, since this comes from an app, show 'no thanks', button.
Andrii Kulian0f051f52016-04-14 00:41:51 -07004859 showScreenPinningRequest(taskId, true);
Jason Monk18f99d92014-09-11 13:36:42 -04004860 }
4861
Andrii Kulian0f051f52016-04-14 00:41:51 -07004862 public void showScreenPinningRequest(int taskId, boolean allowCancel) {
4863 mScreenPinningRequest.showPrompt(taskId, allowCancel);
Jason Monk5565cb42014-09-12 10:59:21 -04004864 }
4865
Christoph Studerc8db24b2014-07-25 17:50:30 +02004866 public boolean hasActiveNotifications() {
4867 return !mNotificationData.getActiveNotifications().isEmpty();
Jorim Jaggi48bc36a2014-07-25 23:16:04 +02004868 }
4869
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004870 public void wakeUpIfDozing(long time, MotionEvent event) {
Jorim Jaggi048af1f2014-11-11 22:51:10 +01004871 if (mDozing && mDozeScrimController.isPulsing()) {
John Spurlock8b12f222014-09-09 11:54:11 -04004872 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
Dianne Hackborn280a64e2015-07-13 14:48:08 -07004873 pm.wakeUp(time, "com.android.systemui:NODOZE");
Jorim Jaggi50ff3af2015-08-12 18:35:42 -07004874 mWakeUpComingFromTouch = true;
4875 mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
Jorim Jaggi2a5e4522014-11-24 21:45:20 +01004876 mNotificationPanel.setTouchDisabled(false);
Jorim Jaggi0d210f62015-07-10 14:24:44 -07004877 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07004878 mFalsingManager.onScreenOnFromTouch();
John Spurlock8b12f222014-09-09 11:54:11 -04004879 }
4880 }
4881
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004882 @Override
4883 public void appTransitionPending() {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004884
4885 // Use own timings when Keyguard is going away, see keyguardGoingAway and
4886 // setKeyguardFadingAway
4887 if (!mKeyguardFadingAway) {
4888 mIconController.appTransitionPending();
4889 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004890 }
4891
4892 @Override
4893 public void appTransitionCancelled() {
4894 mIconController.appTransitionCancelled();
Jorim Jaggi2adba072016-03-03 13:43:39 +01004895 EventBus.getDefault().send(new AppTransitionFinishedEvent());
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004896 }
4897
4898 @Override
4899 public void appTransitionStarting(long startTime, long duration) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004900
4901 // Use own timings when Keyguard is going away, see keyguardGoingAway and
Adrian Roos46df1ca2015-09-11 12:38:43 -07004902 // setKeyguardFadingAway.
4903 if (!mKeyguardGoingAway) {
Jorim Jaggi33ae80e2015-02-04 16:37:11 +01004904 mIconController.appTransitionStarting(startTime, duration);
4905 }
Kenny Guy3094d4a2015-04-01 19:14:10 +01004906 if (mIconPolicy != null) {
4907 mIconPolicy.appTransitionStarting(startTime, duration);
4908 }
Jorim Jaggi24bec7c2015-02-04 12:40:14 +01004909 }
4910
Selim Cinek372d1bd2015-08-14 13:19:37 -07004911 @Override
Jorim Jaggi2adba072016-03-03 13:43:39 +01004912 public void appTransitionFinished() {
4913 EventBus.getDefault().send(new AppTransitionFinishedEvent());
4914 }
4915
4916 @Override
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004917 public void onCameraLaunchGestureDetected(int source) {
4918 mLastCameraLaunchSource = source;
Jorim Jaggi18f18ae2015-09-10 15:48:21 -07004919 if (mStartedGoingToSleep) {
4920 mLaunchCameraOnFinishedGoingToSleep = true;
4921 return;
4922 }
Zhentao Sun04f97402015-08-26 17:37:30 -07004923 if (!mNotificationPanel.canCameraGestureBeLaunched(
4924 mStatusBarKeyguardViewManager.isShowing() && mExpandedVisible)) {
Selim Cinek372d1bd2015-08-14 13:19:37 -07004925 return;
4926 }
4927 if (!mDeviceInteractive) {
4928 PowerManager pm = mContext.getSystemService(PowerManager.class);
4929 pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE");
4930 mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
4931 }
Selim Cinek69ff8af2015-08-25 19:03:48 -07004932 vibrateForCameraGesture();
Selim Cinek372d1bd2015-08-14 13:19:37 -07004933 if (!mStatusBarKeyguardViewManager.isShowing()) {
4934 startActivity(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT,
4935 true /* dismissShade */);
4936 } else {
4937 if (!mDeviceInteractive) {
4938 // Avoid flickering of the scrim when we instant launch the camera and the bouncer
4939 // comes on.
4940 mScrimController.dontAnimateBouncerChangesUntilNextFrame();
4941 mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
4942 }
Selim Cinek1b6f8192015-09-03 16:01:53 -07004943 if (mScreenTurningOn || mStatusBarKeyguardViewManager.isScreenTurnedOn()) {
Jorim Jaggi40aa8812015-09-23 12:59:22 -07004944 mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
Selim Cinek372d1bd2015-08-14 13:19:37 -07004945 } else {
4946 // We need to defer the camera launch until the screen comes on, since otherwise
4947 // we will dismiss us too early since we are waiting on an activity to be drawn and
4948 // incorrectly get notified because of the screen on event (which resumes and pauses
4949 // some activities)
4950 mLaunchCameraOnScreenTurningOn = true;
4951 }
4952 }
4953 }
4954
Jaewan Kimc552b042016-01-18 16:08:45 +09004955 @Override
Jaewan Kimf0fd2182016-04-20 21:17:58 +09004956 public void showTvPictureInPictureMenu() {
Jaewan Kimc552b042016-01-18 16:08:45 +09004957 // no-op.
4958 }
4959
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004960 public void notifyFpAuthModeChanged() {
4961 updateDozing();
4962 }
4963
Jorim Jaggi83969702015-06-05 14:59:24 -07004964 private void updateDozing() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07004965 Trace.beginSection("PhoneStatusBar#updateDozing");
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07004966 // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
4967 mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
4968 || mFingerprintUnlockController.getMode()
4969 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
Jorim Jaggi83969702015-06-05 14:59:24 -07004970 updateDozingState();
Nick Desaulniers1d396752016-07-25 15:05:33 -07004971 Trace.endSection();
Jorim Jaggi83969702015-06-05 14:59:24 -07004972 }
4973
John Spurlockbf370992014-06-17 13:58:31 -04004974 private final class ShadeUpdates {
4975 private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
4976 private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
4977
4978 public void check() {
4979 mNewVisibleNotifications.clear();
Christoph Studerc8db24b2014-07-25 17:50:30 +02004980 ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
4981 for (int i = 0; i < activeNotifications.size(); i++) {
4982 final Entry entry = activeNotifications.get(i);
John Spurlockbf370992014-06-17 13:58:31 -04004983 final boolean visible = entry.row != null
4984 && entry.row.getVisibility() == View.VISIBLE;
4985 if (visible) {
4986 mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
4987 }
4988 }
4989 final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
4990 mVisibleNotifications.clear();
Dianne Hackborn497175b2014-07-01 12:56:08 -07004991 mVisibleNotifications.addAll(mNewVisibleNotifications);
John Spurlockbf370992014-06-17 13:58:31 -04004992
4993 // We have new notifications
4994 if (updates && mDozeServiceHost != null) {
4995 mDozeServiceHost.fireNewNotifications();
4996 }
4997 }
4998 }
4999
Selim Cinek99415392016-09-09 14:58:41 -07005000 private final class DozeServiceHost implements DozeHost {
John Spurlockbf370992014-06-17 13:58:31 -04005001 // Amount of time to allow to update the time shown on the screen before releasing
5002 // the wakelock. This timeout is design to compensate for the fact that we don't
5003 // currently have a way to know when time display contents have actually been
5004 // refreshed once we've finished rendering a new frame.
5005 private static final long PROCESSING_TIME = 500;
5006
5007 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
5008 private final H mHandler = new H();
5009
Christoph Studer1f32c652014-11-26 15:32:20 +01005010 // Keeps the last reported state by fireNotificationLight.
5011 private boolean mNotificationLightOn;
5012
John Spurlockc6eed842014-08-25 12:19:41 -04005013 @Override
5014 public String toString() {
Jeff Brown4d69e222014-09-18 15:27:50 -07005015 return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
John Spurlock8b12f222014-09-09 11:54:11 -04005016 }
5017
John Spurlockd96179e2014-08-21 16:43:45 -04005018 public void firePowerSaveChanged(boolean active) {
5019 for (Callback callback : mCallbacks) {
5020 callback.onPowerSaveChanged(active);
5021 }
5022 }
5023
John Spurlockcad57682014-07-26 17:09:56 -04005024 public void fireBuzzBeepBlinked() {
5025 for (Callback callback : mCallbacks) {
5026 callback.onBuzzBeepBlinked();
5027 }
5028 }
5029
John Spurlockcb566aa2014-08-03 22:58:28 -04005030 public void fireNotificationLight(boolean on) {
Christoph Studer1f32c652014-11-26 15:32:20 +01005031 mNotificationLightOn = on;
John Spurlockcb566aa2014-08-03 22:58:28 -04005032 for (Callback callback : mCallbacks) {
5033 callback.onNotificationLight(on);
5034 }
5035 }
5036
John Spurlockbf370992014-06-17 13:58:31 -04005037 public void fireNewNotifications() {
5038 for (Callback callback : mCallbacks) {
5039 callback.onNewNotifications();
5040 }
5041 }
5042
5043 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07005044 public void addCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04005045 mCallbacks.add(callback);
5046 }
5047
5048 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07005049 public void removeCallback(@NonNull Callback callback) {
John Spurlockbf370992014-06-17 13:58:31 -04005050 mCallbacks.remove(callback);
5051 }
5052
5053 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07005054 public void startDozing(@NonNull Runnable ready) {
5055 mHandler.obtainMessage(H.MSG_START_DOZING, ready).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04005056 }
5057
5058 @Override
John Spurlockeab28e62014-11-29 11:33:49 -05005059 public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
5060 mHandler.obtainMessage(H.MSG_PULSE_WHILE_DOZING, reason, 0, callback).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04005061 }
5062
5063 @Override
Jeff Brown4d69e222014-09-18 15:27:50 -07005064 public void stopDozing() {
5065 mHandler.obtainMessage(H.MSG_STOP_DOZING).sendToTarget();
John Spurlockbf370992014-06-17 13:58:31 -04005066 }
5067
John Spurlockd96179e2014-08-21 16:43:45 -04005068 @Override
5069 public boolean isPowerSaveActive() {
5070 return mBatteryController != null && mBatteryController.isPowerSave();
5071 }
5072
Christoph Studer1f32c652014-11-26 15:32:20 +01005073 @Override
Jorim Jaggi007f0e82015-08-14 13:56:01 -07005074 public boolean isPulsingBlocked() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -07005075 return mFingerprintUnlockController.getMode()
5076 == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
Jorim Jaggi007f0e82015-08-14 13:56:01 -07005077 }
5078
5079 @Override
Christoph Studer1f32c652014-11-26 15:32:20 +01005080 public boolean isNotificationLightOn() {
5081 return mNotificationLightOn;
5082 }
5083
Jeff Brown4d69e222014-09-18 15:27:50 -07005084 private void handleStartDozing(@NonNull Runnable ready) {
Jorim Jaggi83969702015-06-05 14:59:24 -07005085 if (!mDozingRequested) {
5086 mDozingRequested = true;
John Spurlock813552c2014-09-19 08:30:21 -04005087 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07005088 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04005089 }
Jeff Brown4d69e222014-09-18 15:27:50 -07005090 ready.run();
John Spurlockbf370992014-06-17 13:58:31 -04005091 }
5092
John Spurlockeab28e62014-11-29 11:33:49 -05005093 private void handlePulseWhileDozing(@NonNull PulseCallback callback, int reason) {
Selim Cinekcd5b22f2016-03-08 16:15:41 -08005094 mDozeScrimController.pulse(new PulseCallback() {
5095
5096 @Override
5097 public void onPulseStarted() {
5098 callback.onPulseStarted();
5099 mStackScroller.setPulsing(true);
5100 }
5101
5102 @Override
5103 public void onPulseFinished() {
5104 callback.onPulseFinished();
5105 mStackScroller.setPulsing(false);
5106 }
5107 }, reason);
John Spurlockbf370992014-06-17 13:58:31 -04005108 }
5109
Jeff Brown4d69e222014-09-18 15:27:50 -07005110 private void handleStopDozing() {
Jorim Jaggi83969702015-06-05 14:59:24 -07005111 if (mDozingRequested) {
5112 mDozingRequested = false;
John Spurlock813552c2014-09-19 08:30:21 -04005113 DozeLog.traceDozing(mContext, mDozing);
Jorim Jaggi83969702015-06-05 14:59:24 -07005114 updateDozing();
John Spurlockbf370992014-06-17 13:58:31 -04005115 }
5116 }
5117
5118 private final class H extends Handler {
Jeff Brown4d69e222014-09-18 15:27:50 -07005119 private static final int MSG_START_DOZING = 1;
5120 private static final int MSG_PULSE_WHILE_DOZING = 2;
5121 private static final int MSG_STOP_DOZING = 3;
John Spurlockbf370992014-06-17 13:58:31 -04005122
5123 @Override
5124 public void handleMessage(Message msg) {
Jeff Brown4d69e222014-09-18 15:27:50 -07005125 switch (msg.what) {
5126 case MSG_START_DOZING:
5127 handleStartDozing((Runnable) msg.obj);
5128 break;
5129 case MSG_PULSE_WHILE_DOZING:
John Spurlockeab28e62014-11-29 11:33:49 -05005130 handlePulseWhileDozing((PulseCallback) msg.obj, msg.arg1);
Jeff Brown4d69e222014-09-18 15:27:50 -07005131 break;
5132 case MSG_STOP_DOZING:
5133 handleStopDozing();
5134 break;
John Spurlockbf370992014-06-17 13:58:31 -04005135 }
5136 }
5137 }
5138 }
Romain Guy648342f2012-05-25 10:44:45 -07005139}